Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4a31a6c

Browse files
committedJul 12, 2024
Auto merge of #127382 - estebank:const-let, r=compiler-errors
Use verbose style when suggesting changing `const` with `let`
2 parents 5e311f9 + 4df7514 commit 4a31a6c

25 files changed

+245
-129
lines changed
 

‎compiler/rustc_parse/src/parser/item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ impl<'a> Parser<'a> {
810810
self.dcx().struct_span_err(non_item_span, "non-item in item list");
811811
self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes);
812812
if is_let {
813-
err.span_suggestion(
813+
err.span_suggestion_verbose(
814814
non_item_span,
815815
"consider using `const` instead of `let` for associated const",
816816
"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/aarch64/parse-error.stderr

+40-24
Original file line numberDiff line numberDiff line change
@@ -313,74 +313,90 @@ LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
313313
error[E0435]: attempt to use a non-constant value in a constant
314314
--> $DIR/parse-error.rs:39:37
315315
|
316-
LL | let mut foo = 0;
317-
| ----------- help: consider using `const` instead of `let`: `const foo`
318-
...
319316
LL | asm!("{}", options(), const foo);
320317
| ^^^ non-constant value
318+
|
319+
help: consider using `const` instead of `let`
320+
|
321+
LL | const foo: /* Type */ = 0;
322+
| ~~~~~ ++++++++++++
321323

322324
error[E0435]: attempt to use a non-constant value in a constant
323325
--> $DIR/parse-error.rs:47:44
324326
|
325-
LL | let mut foo = 0;
326-
| ----------- help: consider using `const` instead of `let`: `const foo`
327-
...
328327
LL | asm!("{}", clobber_abi("C"), const foo);
329328
| ^^^ non-constant value
329+
|
330+
help: consider using `const` instead of `let`
331+
|
332+
LL | const foo: /* Type */ = 0;
333+
| ~~~~~ ++++++++++++
330334

331335
error[E0435]: attempt to use a non-constant value in a constant
332336
--> $DIR/parse-error.rs:50:55
333337
|
334-
LL | let mut foo = 0;
335-
| ----------- help: consider using `const` instead of `let`: `const foo`
336-
...
337338
LL | asm!("{}", options(), clobber_abi("C"), const foo);
338339
| ^^^ non-constant value
340+
|
341+
help: consider using `const` instead of `let`
342+
|
343+
LL | const foo: /* Type */ = 0;
344+
| ~~~~~ ++++++++++++
339345

340346
error[E0435]: attempt to use a non-constant value in a constant
341347
--> $DIR/parse-error.rs:52:31
342348
|
343-
LL | let mut foo = 0;
344-
| ----------- help: consider using `const` instead of `let`: `const foo`
345-
...
346349
LL | asm!("{a}", a = const foo, a = const bar);
347350
| ^^^ non-constant value
351+
|
352+
help: consider using `const` instead of `let`
353+
|
354+
LL | const foo: /* Type */ = 0;
355+
| ~~~~~ ++++++++++++
348356

349357
error[E0435]: attempt to use a non-constant value in a constant
350358
--> $DIR/parse-error.rs:52:46
351359
|
352-
LL | let mut bar = 0;
353-
| ----------- help: consider using `const` instead of `let`: `const bar`
354-
...
355360
LL | asm!("{a}", a = const foo, a = const bar);
356361
| ^^^ non-constant value
362+
|
363+
help: consider using `const` instead of `let`
364+
|
365+
LL | const bar: /* Type */ = 0;
366+
| ~~~~~ ++++++++++++
357367

358368
error[E0435]: attempt to use a non-constant value in a constant
359369
--> $DIR/parse-error.rs:59:45
360370
|
361-
LL | let mut bar = 0;
362-
| ----------- help: consider using `const` instead of `let`: `const bar`
363-
...
364371
LL | asm!("{a}", in("x0") foo, a = const bar);
365372
| ^^^ non-constant value
373+
|
374+
help: consider using `const` instead of `let`
375+
|
376+
LL | const bar: /* Type */ = 0;
377+
| ~~~~~ ++++++++++++
366378

367379
error[E0435]: attempt to use a non-constant value in a constant
368380
--> $DIR/parse-error.rs:61:45
369381
|
370-
LL | let mut bar = 0;
371-
| ----------- help: consider using `const` instead of `let`: `const bar`
372-
...
373382
LL | asm!("{a}", in("x0") foo, a = const bar);
374383
| ^^^ non-constant value
384+
|
385+
help: consider using `const` instead of `let`
386+
|
387+
LL | const bar: /* Type */ = 0;
388+
| ~~~~~ ++++++++++++
375389

376390
error[E0435]: attempt to use a non-constant value in a constant
377391
--> $DIR/parse-error.rs:63:41
378392
|
379-
LL | let mut bar = 0;
380-
| ----------- help: consider using `const` instead of `let`: `const bar`
381-
...
382393
LL | asm!("{1}", in("x0") foo, const bar);
383394
| ^^^ non-constant value
395+
|
396+
help: consider using `const` instead of `let`
397+
|
398+
LL | const bar: /* Type */ = 0;
399+
| ~~~~~ ++++++++++++
384400

385401
error: aborting due to 57 previous errors
386402

‎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
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.