Skip to content

Commit 2fea2c7

Browse files
authored
Rollup merge of rust-lang#127382 - estebank:const-let, r=compiler-errors
Use verbose style when suggesting changing `const` with `let`
2 parents a557e18 + ab56dfd commit 2fea2c7

24 files changed

+205
-105
lines changed

compiler/rustc_parse/src/parser/item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ impl<'a> Parser<'a> {
796796
self.dcx().struct_span_err(non_item_span, "non-item in item list");
797797
self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes);
798798
if is_let {
799-
err.span_suggestion(
799+
err.span_suggestion_verbose(
800800
non_item_span,
801801
"consider using `const` instead of `let` for associated const",
802802
"const",

compiler/rustc_resolve/src/diagnostics.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
819819
ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
820820
self.dcx().create_err(errs::CannotCaptureDynamicEnvironmentInFnItem { span })
821821
}
822-
ResolutionError::AttemptToUseNonConstantValueInConstant(ident, suggestion, current) => {
822+
ResolutionError::AttemptToUseNonConstantValueInConstant {
823+
ident,
824+
suggestion,
825+
current,
826+
type_span,
827+
} => {
823828
// let foo =...
824829
// ^^^ given this Span
825830
// ------- get this Span to have an applicable suggestion
@@ -836,13 +841,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
836841

837842
let ((with, with_label), without) = match sp {
838843
Some(sp) if !self.tcx.sess.source_map().is_multiline(sp) => {
839-
let sp = sp.with_lo(BytePos(sp.lo().0 - (current.len() as u32)));
844+
let sp = sp
845+
.with_lo(BytePos(sp.lo().0 - (current.len() as u32)))
846+
.until(ident.span);
840847
(
841848
(Some(errs::AttemptToUseNonConstantValueInConstantWithSuggestion {
842849
span: sp,
843-
ident,
844850
suggestion,
845851
current,
852+
type_span,
846853
}), Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion {span})),
847854
None,
848855
)

compiler/rustc_resolve/src/errors.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -240,16 +240,18 @@ pub(crate) struct AttemptToUseNonConstantValueInConstant<'a> {
240240
}
241241

242242
#[derive(Subdiagnostic)]
243-
#[suggestion(
243+
#[multipart_suggestion(
244244
resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion,
245-
code = "{suggestion} {ident}",
246-
applicability = "maybe-incorrect"
245+
style = "verbose",
246+
applicability = "has-placeholders"
247247
)]
248248
pub(crate) struct AttemptToUseNonConstantValueInConstantWithSuggestion<'a> {
249-
#[primary_span]
249+
// #[primary_span]
250+
#[suggestion_part(code = "{suggestion} ")]
250251
pub(crate) span: Span,
251-
pub(crate) ident: Ident,
252252
pub(crate) suggestion: &'a str,
253+
#[suggestion_part(code = ": /* Type */")]
254+
pub(crate) type_span: Option<Span>,
253255
pub(crate) current: &'a str,
254256
}
255257

compiler/rustc_resolve/src/ident.rs

+32-12
Original file line numberDiff line numberDiff line change
@@ -1178,21 +1178,41 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
11781178
if let Some(span) = finalize {
11791179
let (span, resolution_error) = match item {
11801180
None if rib_ident.as_str() == "self" => (span, LowercaseSelf),
1181-
None => (
1182-
rib_ident.span,
1183-
AttemptToUseNonConstantValueInConstant(
1184-
original_rib_ident_def,
1185-
"const",
1186-
"let",
1187-
),
1188-
),
1181+
None => {
1182+
// If we have a `let name = expr;`, we have the span for
1183+
// `name` and use that to see if it is followed by a type
1184+
// specifier. If not, then we know we need to suggest
1185+
// `const name: Ty = expr;`. This is a heuristic, it will
1186+
// break down in the presence of macros.
1187+
let sm = self.tcx.sess.source_map();
1188+
let type_span = match sm.span_look_ahead(
1189+
original_rib_ident_def.span,
1190+
":",
1191+
None,
1192+
) {
1193+
None => {
1194+
Some(original_rib_ident_def.span.shrink_to_hi())
1195+
}
1196+
Some(_) => None,
1197+
};
1198+
(
1199+
rib_ident.span,
1200+
AttemptToUseNonConstantValueInConstant {
1201+
ident: original_rib_ident_def,
1202+
suggestion: "const",
1203+
current: "let",
1204+
type_span,
1205+
},
1206+
)
1207+
}
11891208
Some((ident, kind)) => (
11901209
span,
1191-
AttemptToUseNonConstantValueInConstant(
1210+
AttemptToUseNonConstantValueInConstant {
11921211
ident,
1193-
"let",
1194-
kind.as_str(),
1195-
),
1212+
suggestion: "let",
1213+
current: kind.as_str(),
1214+
type_span: None,
1215+
},
11961216
),
11971217
};
11981218
self.report_error(span, resolution_error);

compiler/rustc_resolve/src/lib.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,12 @@ enum ResolutionError<'a> {
236236
/// Error E0434: can't capture dynamic environment in a fn item.
237237
CannotCaptureDynamicEnvironmentInFnItem,
238238
/// Error E0435: attempt to use a non-constant value in a constant.
239-
AttemptToUseNonConstantValueInConstant(
240-
Ident,
241-
/* suggestion */ &'static str,
242-
/* current */ &'static str,
243-
),
239+
AttemptToUseNonConstantValueInConstant {
240+
ident: Ident,
241+
suggestion: &'static str,
242+
current: &'static str,
243+
type_span: Option<Span>,
244+
},
244245
/// Error E0530: `X` bindings cannot shadow `Y`s.
245246
BindingShadowsSomethingUnacceptable {
246247
shadowing_binding: PatternSource,

tests/ui/asm/parse-error.stderr

+25-15
Original file line numberDiff line numberDiff line change
@@ -371,47 +371,57 @@ LL | global_asm!("{}", label {});
371371
error[E0435]: attempt to use a non-constant value in a constant
372372
--> $DIR/parse-error.rs:39:37
373373
|
374-
LL | let mut foo = 0;
375-
| ----------- help: consider using `const` instead of `let`: `const foo`
376-
...
377374
LL | asm!("{}", options(), const foo);
378375
| ^^^ non-constant value
376+
|
377+
help: consider using `const` instead of `let`
378+
|
379+
LL | const foo: /* Type */ = 0;
380+
| ~~~~~ ++++++++++++
379381

380382
error[E0435]: attempt to use a non-constant value in a constant
381383
--> $DIR/parse-error.rs:71:44
382384
|
383-
LL | let mut foo = 0;
384-
| ----------- help: consider using `const` instead of `let`: `const foo`
385-
...
386385
LL | asm!("{}", clobber_abi("C"), const foo);
387386
| ^^^ non-constant value
387+
|
388+
help: consider using `const` instead of `let`
389+
|
390+
LL | const foo: /* Type */ = 0;
391+
| ~~~~~ ++++++++++++
388392

389393
error[E0435]: attempt to use a non-constant value in a constant
390394
--> $DIR/parse-error.rs:74:55
391395
|
392-
LL | let mut foo = 0;
393-
| ----------- help: consider using `const` instead of `let`: `const foo`
394-
...
395396
LL | asm!("{}", options(), clobber_abi("C"), const foo);
396397
| ^^^ non-constant value
398+
|
399+
help: consider using `const` instead of `let`
400+
|
401+
LL | const foo: /* Type */ = 0;
402+
| ~~~~~ ++++++++++++
397403

398404
error[E0435]: attempt to use a non-constant value in a constant
399405
--> $DIR/parse-error.rs:76:31
400406
|
401-
LL | let mut foo = 0;
402-
| ----------- help: consider using `const` instead of `let`: `const foo`
403-
...
404407
LL | asm!("{a}", a = const foo, a = const bar);
405408
| ^^^ non-constant value
409+
|
410+
help: consider using `const` instead of `let`
411+
|
412+
LL | const foo: /* Type */ = 0;
413+
| ~~~~~ ++++++++++++
406414

407415
error[E0435]: attempt to use a non-constant value in a constant
408416
--> $DIR/parse-error.rs:76:46
409417
|
410-
LL | let mut bar = 0;
411-
| ----------- help: consider using `const` instead of `let`: `const bar`
412-
...
413418
LL | asm!("{a}", a = const foo, a = const bar);
414419
| ^^^ non-constant value
420+
|
421+
help: consider using `const` instead of `let`
422+
|
423+
LL | const bar: /* Type */ = 0;
424+
| ~~~~~ ++++++++++++
415425

416426
error: aborting due to 64 previous errors
417427

tests/ui/asm/type-check-1.stderr

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,35 @@
11
error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/type-check-1.rs:41:26
33
|
4-
LL | let x = 0;
5-
| ----- help: consider using `const` instead of `let`: `const x`
6-
...
74
LL | asm!("{}", const x);
85
| ^ non-constant value
6+
|
7+
help: consider using `const` instead of `let`
8+
|
9+
LL | const x: /* Type */ = 0;
10+
| ~~~~~ ++++++++++++
911

1012
error[E0435]: attempt to use a non-constant value in a constant
1113
--> $DIR/type-check-1.rs:44:36
1214
|
13-
LL | let x = 0;
14-
| ----- help: consider using `const` instead of `let`: `const x`
15-
...
1615
LL | asm!("{}", const const_foo(x));
1716
| ^ non-constant value
17+
|
18+
help: consider using `const` instead of `let`
19+
|
20+
LL | const x: /* Type */ = 0;
21+
| ~~~~~ ++++++++++++
1822

1923
error[E0435]: attempt to use a non-constant value in a constant
2024
--> $DIR/type-check-1.rs:47:36
2125
|
22-
LL | let x = 0;
23-
| ----- help: consider using `const` instead of `let`: `const x`
24-
...
2526
LL | asm!("{}", const const_bar(x));
2627
| ^ non-constant value
28+
|
29+
help: consider using `const` instead of `let`
30+
|
31+
LL | const x: /* Type */ = 0;
32+
| ~~~~~ ++++++++++++
2733

2834
error: invalid `sym` operand
2935
--> $DIR/type-check-1.rs:49:24

tests/ui/asm/x86_64/x86_64_parse_error.stderr

+15-9
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,35 @@ LL | asm!("{1}", in("eax") foo, const bar);
1515
error[E0435]: attempt to use a non-constant value in a constant
1616
--> $DIR/x86_64_parse_error.rs:13:46
1717
|
18-
LL | let mut bar = 0;
19-
| ----------- help: consider using `const` instead of `let`: `const bar`
20-
...
2118
LL | asm!("{a}", in("eax") foo, a = const bar);
2219
| ^^^ non-constant value
20+
|
21+
help: consider using `const` instead of `let`
22+
|
23+
LL | const bar: /* Type */ = 0;
24+
| ~~~~~ ++++++++++++
2325

2426
error[E0435]: attempt to use a non-constant value in a constant
2527
--> $DIR/x86_64_parse_error.rs:15:46
2628
|
27-
LL | let mut bar = 0;
28-
| ----------- help: consider using `const` instead of `let`: `const bar`
29-
...
3029
LL | asm!("{a}", in("eax") foo, a = const bar);
3130
| ^^^ non-constant value
31+
|
32+
help: consider using `const` instead of `let`
33+
|
34+
LL | const bar: /* Type */ = 0;
35+
| ~~~~~ ++++++++++++
3236

3337
error[E0435]: attempt to use a non-constant value in a constant
3438
--> $DIR/x86_64_parse_error.rs:17:42
3539
|
36-
LL | let mut bar = 0;
37-
| ----------- help: consider using `const` instead of `let`: `const bar`
38-
...
3940
LL | asm!("{1}", in("eax") foo, const bar);
4041
| ^^^ non-constant value
42+
|
43+
help: consider using `const` instead of `let`
44+
|
45+
LL | const bar: /* Type */ = 0;
46+
| ~~~~~ ++++++++++++
4147

4248
error: aborting due to 5 previous errors
4349

tests/ui/const-generics/legacy-const-generics-bad.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/legacy-const-generics-bad.rs:7:35
33
|
4-
LL | let a = 1;
5-
| ----- help: consider using `const` instead of `let`: `const a`
64
LL | legacy_const_generics::foo(0, a, 2);
75
| ^ non-constant value
6+
|
7+
help: consider using `const` instead of `let`
8+
|
9+
LL | const a: /* Type */ = 1;
10+
| ~~~~~ ++++++++++++
811

912
error: generic parameters may not be used in const operations
1013
--> $DIR/legacy-const-generics-bad.rs:12:35

tests/ui/consts/issue-3521.stderr

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/issue-3521.rs:8:15
33
|
4-
LL | let foo: isize = 100;
5-
| ------- help: consider using `const` instead of `let`: `const foo`
6-
...
74
LL | Bar = foo
85
| ^^^ non-constant value
6+
|
7+
help: consider using `const` instead of `let`
8+
|
9+
LL | const foo: isize = 100;
10+
| ~~~~~
911

1012
error: aborting due to 1 previous error
1113

tests/ui/consts/issue-91560.stderr

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/issue-91560.rs:10:19
33
|
4-
LL | let mut length: usize = 2;
5-
| -------------- help: consider using `const` instead of `let`: `const length`
6-
LL |
74
LL | let arr = [0; length];
85
| ^^^^^^ non-constant value
6+
|
7+
help: consider using `const` instead of `let`
8+
|
9+
LL | const length: usize = 2;
10+
| ~~~~~
911

1012
error[E0435]: attempt to use a non-constant value in a constant
1113
--> $DIR/issue-91560.rs:17:19
1214
|
13-
LL | let length: usize = 2;
14-
| ------------ help: consider using `const` instead of `let`: `const length`
15-
LL |
1615
LL | let arr = [0; length];
1716
| ^^^^^^ non-constant value
17+
|
18+
help: consider using `const` instead of `let`
19+
|
20+
LL | const length: usize = 2;
21+
| ~~~~~
1822

1923
error: aborting due to 2 previous errors
2024

tests/ui/consts/non-const-value-in-const.stderr

+11-6
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,23 @@ error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/non-const-value-in-const.rs:3:20
33
|
44
LL | const Y: i32 = x;
5-
| ------- ^ non-constant value
6-
| |
7-
| help: consider using `let` instead of `const`: `let Y`
5+
| ^ non-constant value
6+
|
7+
help: consider using `let` instead of `const`
8+
|
9+
LL | let Y: i32 = x;
10+
| ~~~
811

912
error[E0435]: attempt to use a non-constant value in a constant
1013
--> $DIR/non-const-value-in-const.rs:6:17
1114
|
12-
LL | let x = 5;
13-
| ----- help: consider using `const` instead of `let`: `const x`
14-
...
1515
LL | let _ = [0; x];
1616
| ^ non-constant value
17+
|
18+
help: consider using `const` instead of `let`
19+
|
20+
LL | const x: /* Type */ = 5;
21+
| ~~~~~ ++++++++++++
1722

1823
error: aborting due to 2 previous errors
1924

0 commit comments

Comments
 (0)