diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 6a181dbab5af7..03b66a3f7b306 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -398,20 +398,30 @@ impl<'a> Resolver<'a> { err.help("use the `|| { ... }` closure form instead"); err } - ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg) => { + ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg, current) => { let mut err = struct_span_err!( self.session, span, E0435, "attempt to use a non-constant value in a constant" ); - err.span_suggestion( - ident.span, - &sugg, - "".to_string(), - Applicability::MaybeIncorrect, - ); - err.span_label(span, "non-constant value"); + // let foo =... + // ^^^ given this Span + // ------- get this Span to have an applicable suggestion + let sp = + self.session.source_map().span_extend_to_prev_str(ident.span, current, true); + if sp.lo().0 == 0 { + err.span_label(ident.span, &format!("this would need to be a `{}`", sugg)); + } else { + let sp = sp.with_lo(BytePos(sp.lo().0 - current.len() as u32)); + err.span_suggestion( + sp, + &format!("consider using `{}` instead of `{}`", sugg, current), + format!("{} {}", sugg, ident), + Applicability::MaybeIncorrect, + ); + err.span_label(span, "non-constant value"); + } err } ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index a6d0240b6fdcf..2c68e0418589b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -210,7 +210,11 @@ 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, String), + AttemptToUseNonConstantValueInConstant( + Ident, + /* suggestion */ &'static str, + /* current */ &'static str, + ), /// Error E0530: `X` bindings cannot shadow `Y`s. BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>), /// Error E0128: type parameters with a default cannot use forward-declared identifiers. @@ -2614,18 +2618,19 @@ impl<'a> Resolver<'a> { ConstantItemKind::Const => "const", ConstantItemKind::Static => "static", }; - let sugg = format!( - "consider using `let` instead of `{}`", - kind_str - ); - (span, AttemptToUseNonConstantValueInConstant(ident, sugg)) + ( + span, + AttemptToUseNonConstantValueInConstant( + ident, "let", kind_str, + ), + ) } else { - let sugg = "consider using `const` instead of `let`"; ( rib_ident.span, AttemptToUseNonConstantValueInConstant( original_rib_ident_def, - sugg.to_string(), + "const", + "let", ), ) }; diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index fefc0cb48ddd8..6635d44496c03 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -671,7 +671,9 @@ impl SourceMap { let pat = pat.to_owned() + ws; if let Ok(prev_source) = self.span_to_prev_source(sp) { let prev_source = prev_source.rsplit(&pat).next().unwrap_or("").trim_start(); - if !prev_source.is_empty() && (!prev_source.contains('\n') || accept_newlines) { + if prev_source.is_empty() && sp.lo().0 != 0 { + return sp.with_lo(BytePos(sp.lo().0 - 1)); + } else if !prev_source.contains('\n') || accept_newlines { return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32)); } } diff --git a/src/test/ui/error-codes/E0435.fixed b/src/test/ui/error-codes/E0435.fixed new file mode 100644 index 0000000000000..fdf896d2dbbbd --- /dev/null +++ b/src/test/ui/error-codes/E0435.fixed @@ -0,0 +1,6 @@ +// run-rustfix +fn main () { + #[allow(non_upper_case_globals)] + const foo: usize = 42; + let _: [u8; foo]; //~ ERROR E0435 +} diff --git a/src/test/ui/error-codes/E0435.rs b/src/test/ui/error-codes/E0435.rs index 620dd30a23bc9..d9354efb8fdc4 100644 --- a/src/test/ui/error-codes/E0435.rs +++ b/src/test/ui/error-codes/E0435.rs @@ -1,4 +1,6 @@ +// run-rustfix fn main () { - let foo = 42u32; + #[allow(non_upper_case_globals)] + let foo: usize = 42; let _: [u8; foo]; //~ ERROR E0435 } diff --git a/src/test/ui/error-codes/E0435.stderr b/src/test/ui/error-codes/E0435.stderr index 21827d1fd8743..fc08fade91cee 100644 --- a/src/test/ui/error-codes/E0435.stderr +++ b/src/test/ui/error-codes/E0435.stderr @@ -1,8 +1,8 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/E0435.rs:3:17 + --> $DIR/E0435.rs:5:17 | -LL | let foo = 42u32; - | --- help: consider using `const` instead of `let` +LL | let foo: usize = 42; + | ------- help: consider using `const` instead of `let`: `const foo` LL | let _: [u8; foo]; | ^^^ non-constant value diff --git a/src/test/ui/impl-trait/bindings.stderr b/src/test/ui/impl-trait/bindings.stderr index ad5f13d067230..4da49f4dc7db1 100644 --- a/src/test/ui/impl-trait/bindings.stderr +++ b/src/test/ui/impl-trait/bindings.stderr @@ -2,33 +2,33 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:5:29 | LL | const foo: impl Clone = x; - | --- ^ non-constant value - | | - | help: consider using `let` instead of `const` + | --------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let foo` error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:11:33 | LL | const foo: impl Clone = x; - | --- ^ non-constant value - | | - | help: consider using `let` instead of `const` + | --------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let foo` error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:18:33 | LL | const foo: impl Clone = x; - | --- ^ non-constant value - | | - | help: consider using `let` instead of `const` + | --------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let foo` error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:25:33 | LL | const foo: impl Clone = x; - | --- ^ non-constant value - | | - | help: consider using `let` instead of `const` + | --------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let foo` warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/bindings.rs:1:12 diff --git a/src/test/ui/issues/issue-27433.fixed b/src/test/ui/issues/issue-27433.fixed new file mode 100644 index 0000000000000..ce31f6bea4bdd --- /dev/null +++ b/src/test/ui/issues/issue-27433.fixed @@ -0,0 +1,7 @@ +// run-rustfix +fn main() { + let foo = 42u32; + #[allow(unused_variables, non_snake_case)] + let FOO : u32 = foo; + //~^ ERROR attempt to use a non-constant value in a constant +} diff --git a/src/test/ui/issues/issue-27433.rs b/src/test/ui/issues/issue-27433.rs index 156ae68efe2c5..01411a51c1372 100644 --- a/src/test/ui/issues/issue-27433.rs +++ b/src/test/ui/issues/issue-27433.rs @@ -1,5 +1,7 @@ +// run-rustfix fn main() { let foo = 42u32; + #[allow(unused_variables, non_snake_case)] const FOO : u32 = foo; //~^ ERROR attempt to use a non-constant value in a constant } diff --git a/src/test/ui/issues/issue-27433.stderr b/src/test/ui/issues/issue-27433.stderr index 201b7e8549cb1..da751a6495736 100644 --- a/src/test/ui/issues/issue-27433.stderr +++ b/src/test/ui/issues/issue-27433.stderr @@ -1,10 +1,10 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-27433.rs:3:23 + --> $DIR/issue-27433.rs:5:23 | LL | const FOO : u32 = foo; - | --- ^^^ non-constant value - | | - | help: consider using `let` instead of `const` + | --------- ^^^ non-constant value + | | + | help: consider using `let` instead of `const`: `let FOO` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3521-2.fixed b/src/test/ui/issues/issue-3521-2.fixed new file mode 100644 index 0000000000000..140c24b9395ca --- /dev/null +++ b/src/test/ui/issues/issue-3521-2.fixed @@ -0,0 +1,9 @@ +// run-rustfix +fn main() { + let foo = 100; + + let y: isize = foo + 1; + //~^ ERROR attempt to use a non-constant value in a constant + + println!("{}", y); +} diff --git a/src/test/ui/issues/issue-3521-2.rs b/src/test/ui/issues/issue-3521-2.rs index 871394f9eaeb9..f66efec45e549 100644 --- a/src/test/ui/issues/issue-3521-2.rs +++ b/src/test/ui/issues/issue-3521-2.rs @@ -1,3 +1,4 @@ +// run-rustfix fn main() { let foo = 100; diff --git a/src/test/ui/issues/issue-3521-2.stderr b/src/test/ui/issues/issue-3521-2.stderr index ba29d1becb85a..84c7a9efa35bb 100644 --- a/src/test/ui/issues/issue-3521-2.stderr +++ b/src/test/ui/issues/issue-3521-2.stderr @@ -1,10 +1,10 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-3521-2.rs:4:23 + --> $DIR/issue-3521-2.rs:5:23 | LL | static y: isize = foo + 1; - | - ^^^ non-constant value - | | - | help: consider using `let` instead of `static` + | -------- ^^^ non-constant value + | | + | help: consider using `let` instead of `static`: `let y` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3521.fixed b/src/test/ui/issues/issue-3521.fixed new file mode 100644 index 0000000000000..f76106dfff187 --- /dev/null +++ b/src/test/ui/issues/issue-3521.fixed @@ -0,0 +1,13 @@ +// run-rustfix +fn main() { + #[allow(non_upper_case_globals)] + const foo: isize = 100; + + #[derive(Debug)] + enum Stuff { + Bar = foo + //~^ ERROR attempt to use a non-constant value in a constant + } + + println!("{:?}", Stuff::Bar); +} diff --git a/src/test/ui/issues/issue-3521.rs b/src/test/ui/issues/issue-3521.rs index 9e72dd29a408e..c425a22df9173 100644 --- a/src/test/ui/issues/issue-3521.rs +++ b/src/test/ui/issues/issue-3521.rs @@ -1,5 +1,7 @@ +// run-rustfix fn main() { - let foo = 100; + #[allow(non_upper_case_globals)] + let foo: isize = 100; #[derive(Debug)] enum Stuff { diff --git a/src/test/ui/issues/issue-3521.stderr b/src/test/ui/issues/issue-3521.stderr index 8473526006c5c..aa42772f12d8a 100644 --- a/src/test/ui/issues/issue-3521.stderr +++ b/src/test/ui/issues/issue-3521.stderr @@ -1,8 +1,8 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-3521.rs:6:15 + --> $DIR/issue-3521.rs:8:15 | -LL | let foo = 100; - | --- help: consider using `const` instead of `let` +LL | let foo: isize = 100; + | ------- help: consider using `const` instead of `let`: `const foo` ... LL | Bar = foo | ^^^ non-constant value diff --git a/src/test/ui/issues/issue-3668-2.fixed b/src/test/ui/issues/issue-3668-2.fixed new file mode 100644 index 0000000000000..a95781c6edc82 --- /dev/null +++ b/src/test/ui/issues/issue-3668-2.fixed @@ -0,0 +1,8 @@ +// run-rustfix +#![allow(unused_variables, dead_code)] +fn f(x:isize) { + let child: isize = x + 1; + //~^ ERROR attempt to use a non-constant value in a constant +} + +fn main() {} diff --git a/src/test/ui/issues/issue-3668-2.rs b/src/test/ui/issues/issue-3668-2.rs index 525f6f5684e70..8aa0897ecb4dc 100644 --- a/src/test/ui/issues/issue-3668-2.rs +++ b/src/test/ui/issues/issue-3668-2.rs @@ -1,3 +1,5 @@ +// run-rustfix +#![allow(unused_variables, dead_code)] fn f(x:isize) { static child: isize = x + 1; //~^ ERROR attempt to use a non-constant value in a constant diff --git a/src/test/ui/issues/issue-3668-2.stderr b/src/test/ui/issues/issue-3668-2.stderr index 7cee497b0bced..ba96510415435 100644 --- a/src/test/ui/issues/issue-3668-2.stderr +++ b/src/test/ui/issues/issue-3668-2.stderr @@ -1,10 +1,10 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-3668-2.rs:2:27 + --> $DIR/issue-3668-2.rs:4:27 | LL | static child: isize = x + 1; - | ----- ^ non-constant value - | | - | help: consider using `let` instead of `static` + | ------------ ^ non-constant value + | | + | help: consider using `let` instead of `static`: `let child` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3668.stderr b/src/test/ui/issues/issue-3668.stderr index e45472929ab31..edc49979c10a0 100644 --- a/src/test/ui/issues/issue-3668.stderr +++ b/src/test/ui/issues/issue-3668.stderr @@ -2,9 +2,9 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-3668.rs:8:34 | LL | static childVal: Box
= self.child.get();
- | -------- ^^^^ non-constant value
- | |
- | help: consider using `let` instead of `static`
+ | --------------- ^^^^ non-constant value
+ | |
+ | help: consider using `let` instead of `static`: `let childVal`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-42060.stderr b/src/test/ui/issues/issue-42060.stderr
index dc089b856bb23..effcbe4d7f3e8 100644
--- a/src/test/ui/issues/issue-42060.stderr
+++ b/src/test/ui/issues/issue-42060.stderr
@@ -2,7 +2,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/issue-42060.rs:3:23
|
LL | let thing = ();
- | ----- help: consider using `const` instead of `let`
+ | --------- help: consider using `const` instead of `let`: `const thing`
LL | let other: typeof(thing) = thing;
| ^^^^^ non-constant value
@@ -10,7 +10,7 @@ error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/issue-42060.rs:9:13
|
LL | let q = 1;
- | - help: consider using `const` instead of `let`
+ | ----- help: consider using `const` instead of `let`: `const q`
LL |