Skip to content

Commit

Permalink
Auto merge of rust-lang#127382 - estebank:const-let, r=compiler-errors
Browse files Browse the repository at this point in the history
Use verbose style when suggesting changing `const` with `let`
  • Loading branch information
bors committed Jul 12, 2024
2 parents 5e311f9 + 4df7514 commit 4a31a6c
Show file tree
Hide file tree
Showing 25 changed files with 245 additions and 129 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ impl<'a> Parser<'a> {
self.dcx().struct_span_err(non_item_span, "non-item in item list");
self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes);
if is_let {
err.span_suggestion(
err.span_suggestion_verbose(
non_item_span,
"consider using `const` instead of `let` for associated const",
"const",
Expand Down
13 changes: 10 additions & 3 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
self.dcx().create_err(errs::CannotCaptureDynamicEnvironmentInFnItem { span })
}
ResolutionError::AttemptToUseNonConstantValueInConstant(ident, suggestion, current) => {
ResolutionError::AttemptToUseNonConstantValueInConstant {
ident,
suggestion,
current,
type_span,
} => {
// let foo =...
// ^^^ given this Span
// ------- get this Span to have an applicable suggestion
Expand All @@ -836,13 +841,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {

let ((with, with_label), without) = match sp {
Some(sp) if !self.tcx.sess.source_map().is_multiline(sp) => {
let sp = sp.with_lo(BytePos(sp.lo().0 - (current.len() as u32)));
let sp = sp
.with_lo(BytePos(sp.lo().0 - (current.len() as u32)))
.until(ident.span);
(
(Some(errs::AttemptToUseNonConstantValueInConstantWithSuggestion {
span: sp,
ident,
suggestion,
current,
type_span,
}), Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion {span})),
None,
)
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_resolve/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,16 +240,18 @@ pub(crate) struct AttemptToUseNonConstantValueInConstant<'a> {
}

#[derive(Subdiagnostic)]
#[suggestion(
#[multipart_suggestion(
resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion,
code = "{suggestion} {ident}",
applicability = "maybe-incorrect"
style = "verbose",
applicability = "has-placeholders"
)]
pub(crate) struct AttemptToUseNonConstantValueInConstantWithSuggestion<'a> {
#[primary_span]
// #[primary_span]
#[suggestion_part(code = "{suggestion} ")]
pub(crate) span: Span,
pub(crate) ident: Ident,
pub(crate) suggestion: &'a str,
#[suggestion_part(code = ": /* Type */")]
pub(crate) type_span: Option<Span>,
pub(crate) current: &'a str,
}

Expand Down
44 changes: 32 additions & 12 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1178,21 +1178,41 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Some(span) = finalize {
let (span, resolution_error) = match item {
None if rib_ident.as_str() == "self" => (span, LowercaseSelf),
None => (
rib_ident.span,
AttemptToUseNonConstantValueInConstant(
original_rib_ident_def,
"const",
"let",
),
),
None => {
// If we have a `let name = expr;`, we have the span for
// `name` and use that to see if it is followed by a type
// specifier. If not, then we know we need to suggest
// `const name: Ty = expr;`. This is a heuristic, it will
// break down in the presence of macros.
let sm = self.tcx.sess.source_map();
let type_span = match sm.span_look_ahead(
original_rib_ident_def.span,
":",
None,
) {
None => {
Some(original_rib_ident_def.span.shrink_to_hi())
}
Some(_) => None,
};
(
rib_ident.span,
AttemptToUseNonConstantValueInConstant {
ident: original_rib_ident_def,
suggestion: "const",
current: "let",
type_span,
},
)
}
Some((ident, kind)) => (
span,
AttemptToUseNonConstantValueInConstant(
AttemptToUseNonConstantValueInConstant {
ident,
"let",
kind.as_str(),
),
suggestion: "let",
current: kind.as_str(),
type_span: None,
},
),
};
self.report_error(span, resolution_error);
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,12 @@ enum ResolutionError<'a> {
/// Error E0434: can't capture dynamic environment in a fn item.
CannotCaptureDynamicEnvironmentInFnItem,
/// Error E0435: attempt to use a non-constant value in a constant.
AttemptToUseNonConstantValueInConstant(
Ident,
/* suggestion */ &'static str,
/* current */ &'static str,
),
AttemptToUseNonConstantValueInConstant {
ident: Ident,
suggestion: &'static str,
current: &'static str,
type_span: Option<Span>,
},
/// Error E0530: `X` bindings cannot shadow `Y`s.
BindingShadowsSomethingUnacceptable {
shadowing_binding: PatternSource,
Expand Down
64 changes: 40 additions & 24 deletions tests/ui/asm/aarch64/parse-error.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -313,74 +313,90 @@ LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:39:37
|
LL | let mut foo = 0;
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{}", options(), const foo);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const foo: /* Type */ = 0;
| ~~~~~ ++++++++++++

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:47:44
|
LL | let mut foo = 0;
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{}", clobber_abi("C"), const foo);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const foo: /* Type */ = 0;
| ~~~~~ ++++++++++++

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:50:55
|
LL | let mut foo = 0;
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{}", options(), clobber_abi("C"), const foo);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const foo: /* Type */ = 0;
| ~~~~~ ++++++++++++

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:52:31
|
LL | let mut foo = 0;
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{a}", a = const foo, a = const bar);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const foo: /* Type */ = 0;
| ~~~~~ ++++++++++++

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:52:46
|
LL | let mut bar = 0;
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{a}", a = const foo, a = const bar);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const bar: /* Type */ = 0;
| ~~~~~ ++++++++++++

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:59:45
|
LL | let mut bar = 0;
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{a}", in("x0") foo, a = const bar);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const bar: /* Type */ = 0;
| ~~~~~ ++++++++++++

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:61:45
|
LL | let mut bar = 0;
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{a}", in("x0") foo, a = const bar);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const bar: /* Type */ = 0;
| ~~~~~ ++++++++++++

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:63:41
|
LL | let mut bar = 0;
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{1}", in("x0") foo, const bar);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const bar: /* Type */ = 0;
| ~~~~~ ++++++++++++

error: aborting due to 57 previous errors

Expand Down
40 changes: 25 additions & 15 deletions tests/ui/asm/parse-error.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -371,47 +371,57 @@ LL | global_asm!("{}", label {});
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:39:37
|
LL | let mut foo = 0;
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{}", options(), const foo);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const foo: /* Type */ = 0;
| ~~~~~ ++++++++++++

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:71:44
|
LL | let mut foo = 0;
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{}", clobber_abi("C"), const foo);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const foo: /* Type */ = 0;
| ~~~~~ ++++++++++++

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

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:76:31
|
LL | let mut foo = 0;
| ----------- help: consider using `const` instead of `let`: `const foo`
...
LL | asm!("{a}", a = const foo, a = const bar);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const foo: /* Type */ = 0;
| ~~~~~ ++++++++++++

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:76:46
|
LL | let mut bar = 0;
| ----------- help: consider using `const` instead of `let`: `const bar`
...
LL | asm!("{a}", a = const foo, a = const bar);
| ^^^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const bar: /* Type */ = 0;
| ~~~~~ ++++++++++++

error: aborting due to 64 previous errors

Expand Down
24 changes: 15 additions & 9 deletions tests/ui/asm/type-check-1.stderr
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/type-check-1.rs:41:26
|
LL | let x = 0;
| ----- help: consider using `const` instead of `let`: `const x`
...
LL | asm!("{}", const x);
| ^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const x: /* Type */ = 0;
| ~~~~~ ++++++++++++

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

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

error: invalid `sym` operand
--> $DIR/type-check-1.rs:49:24
Expand Down
Loading

0 comments on commit 4a31a6c

Please sign in to comment.