Skip to content

Commit ab56dfd

Browse files
committed
Account for let foo = expr; to suggest const foo: Ty = expr;
1 parent d9ed923 commit ab56dfd

13 files changed

+85
-56
lines changed

compiler/rustc_resolve/src/diagnostics.rs

+7-1
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
@@ -844,6 +849,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
844849
span: sp,
845850
suggestion,
846851
current,
852+
type_span,
847853
}), Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion {span})),
848854
None,
849855
)

compiler/rustc_resolve/src/errors.rs

+6-4
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} ",
246245
style = "verbose",
247-
applicability = "maybe-incorrect"
246+
applicability = "has-placeholders"
248247
)]
249248
pub(crate) struct AttemptToUseNonConstantValueInConstantWithSuggestion<'a> {
250-
#[primary_span]
249+
// #[primary_span]
250+
#[suggestion_part(code = "{suggestion} ")]
251251
pub(crate) span: Span,
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

+10-10
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,8 @@ LL | asm!("{}", options(), const foo);
376376
|
377377
help: consider using `const` instead of `let`
378378
|
379-
LL | const foo = 0;
380-
| ~~~~~
379+
LL | const foo: /* Type */ = 0;
380+
| ~~~~~ ++++++++++++
381381

382382
error[E0435]: attempt to use a non-constant value in a constant
383383
--> $DIR/parse-error.rs:71:44
@@ -387,8 +387,8 @@ LL | asm!("{}", clobber_abi("C"), const foo);
387387
|
388388
help: consider using `const` instead of `let`
389389
|
390-
LL | const foo = 0;
391-
| ~~~~~
390+
LL | const foo: /* Type */ = 0;
391+
| ~~~~~ ++++++++++++
392392

393393
error[E0435]: attempt to use a non-constant value in a constant
394394
--> $DIR/parse-error.rs:74:55
@@ -398,8 +398,8 @@ LL | asm!("{}", options(), clobber_abi("C"), const foo);
398398
|
399399
help: consider using `const` instead of `let`
400400
|
401-
LL | const foo = 0;
402-
| ~~~~~
401+
LL | const foo: /* Type */ = 0;
402+
| ~~~~~ ++++++++++++
403403

404404
error[E0435]: attempt to use a non-constant value in a constant
405405
--> $DIR/parse-error.rs:76:31
@@ -409,8 +409,8 @@ LL | asm!("{a}", a = const foo, a = const bar);
409409
|
410410
help: consider using `const` instead of `let`
411411
|
412-
LL | const foo = 0;
413-
| ~~~~~
412+
LL | const foo: /* Type */ = 0;
413+
| ~~~~~ ++++++++++++
414414

415415
error[E0435]: attempt to use a non-constant value in a constant
416416
--> $DIR/parse-error.rs:76:46
@@ -420,8 +420,8 @@ LL | asm!("{a}", a = const foo, a = const bar);
420420
|
421421
help: consider using `const` instead of `let`
422422
|
423-
LL | const bar = 0;
424-
| ~~~~~
423+
LL | const bar: /* Type */ = 0;
424+
| ~~~~~ ++++++++++++
425425

426426
error: aborting due to 64 previous errors
427427

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | asm!("{}", const x);
66
|
77
help: consider using `const` instead of `let`
88
|
9-
LL | const x = 0;
10-
| ~~~~~
9+
LL | const x: /* Type */ = 0;
10+
| ~~~~~ ++++++++++++
1111

1212
error[E0435]: attempt to use a non-constant value in a constant
1313
--> $DIR/type-check-1.rs:44:36
@@ -17,8 +17,8 @@ LL | asm!("{}", const const_foo(x));
1717
|
1818
help: consider using `const` instead of `let`
1919
|
20-
LL | const x = 0;
21-
| ~~~~~
20+
LL | const x: /* Type */ = 0;
21+
| ~~~~~ ++++++++++++
2222

2323
error[E0435]: attempt to use a non-constant value in a constant
2424
--> $DIR/type-check-1.rs:47:36
@@ -28,8 +28,8 @@ LL | asm!("{}", const const_bar(x));
2828
|
2929
help: consider using `const` instead of `let`
3030
|
31-
LL | const x = 0;
32-
| ~~~~~
31+
LL | const x: /* Type */ = 0;
32+
| ~~~~~ ++++++++++++
3333

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

tests/ui/asm/x86_64/x86_64_parse_error.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ LL | asm!("{a}", in("eax") foo, a = const bar);
2020
|
2121
help: consider using `const` instead of `let`
2222
|
23-
LL | const bar = 0;
24-
| ~~~~~
23+
LL | const bar: /* Type */ = 0;
24+
| ~~~~~ ++++++++++++
2525

2626
error[E0435]: attempt to use a non-constant value in a constant
2727
--> $DIR/x86_64_parse_error.rs:15:46
@@ -31,8 +31,8 @@ LL | asm!("{a}", in("eax") foo, a = const bar);
3131
|
3232
help: consider using `const` instead of `let`
3333
|
34-
LL | const bar = 0;
35-
| ~~~~~
34+
LL | const bar: /* Type */ = 0;
35+
| ~~~~~ ++++++++++++
3636

3737
error[E0435]: attempt to use a non-constant value in a constant
3838
--> $DIR/x86_64_parse_error.rs:17:42
@@ -42,8 +42,8 @@ LL | asm!("{1}", in("eax") foo, const bar);
4242
|
4343
help: consider using `const` instead of `let`
4444
|
45-
LL | const bar = 0;
46-
| ~~~~~
45+
LL | const bar: /* Type */ = 0;
46+
| ~~~~~ ++++++++++++
4747

4848
error: aborting due to 5 previous errors
4949

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | legacy_const_generics::foo(0, a, 2);
66
|
77
help: consider using `const` instead of `let`
88
|
9-
LL | const a = 1;
10-
| ~~~~~
9+
LL | const a: /* Type */ = 1;
10+
| ~~~~~ ++++++++++++
1111

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

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ LL | let _ = [0; x];
1717
|
1818
help: consider using `const` instead of `let`
1919
|
20-
LL | const x = 5;
21-
| ~~~~~
20+
LL | const x: /* Type */ = 5;
21+
| ~~~~~ ++++++++++++
2222

2323
error: aborting due to 2 previous errors
2424

tests/ui/issues/issue-27433.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ fn main() {
33
let foo = 42u32;
44
#[allow(unused_variables, non_snake_case)]
55
let FOO : u32 = foo;
6-
//~^ ERROR attempt to use a non-constant value in a constant
6+
//~^ ERROR attempt to use a non-constant value in a constant
77
}

tests/ui/issues/issue-27433.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ fn main() {
33
let foo = 42u32;
44
#[allow(unused_variables, non_snake_case)]
55
const FOO : u32 = foo;
6-
//~^ ERROR attempt to use a non-constant value in a constant
6+
//~^ ERROR attempt to use a non-constant value in a constant
77
}

tests/ui/repeat-expr/repeat_count.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | let a = [0; n];
66
|
77
help: consider using `const` instead of `let`
88
|
9-
LL | const n = 1;
10-
| ~~~~~
9+
LL | const n: /* Type */ = 1;
10+
| ~~~~~ ++++++++++++
1111

1212
error[E0308]: mismatched types
1313
--> $DIR/repeat_count.rs:7:17

tests/ui/typeof/issue-42060.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | let other: typeof(thing) = thing;
66
|
77
help: consider using `const` instead of `let`
88
|
9-
LL | const thing = ();
10-
| ~~~~~
9+
LL | const thing: /* Type */ = ();
10+
| ~~~~~ ++++++++++++
1111

1212
error[E0435]: attempt to use a non-constant value in a constant
1313
--> $DIR/issue-42060.rs:9:13
@@ -17,8 +17,8 @@ LL | <typeof(q)>::N
1717
|
1818
help: consider using `const` instead of `let`
1919
|
20-
LL | const q = 1;
21-
| ~~~~~
20+
LL | const q: /* Type */ = 1;
21+
| ~~~~~ ++++++++++++
2222

2323
error[E0516]: `typeof` is a reserved keyword but unimplemented
2424
--> $DIR/issue-42060.rs:3:16

0 commit comments

Comments
 (0)