From 9a5dcaab673b5b5a2842b689daeb0b2968fec476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Jan 2021 16:44:08 -0800 Subject: [PATCH] Use correct span for structured suggestion On structured suggestion for `let` -> `const` and `const` -> `let`, use a proper `Span` and update tests to check the correct application. Follow up to #80012. --- compiler/rustc_resolve/src/diagnostics.rs | 26 +++++++++++++------ compiler/rustc_resolve/src/lib.rs | 21 +++++++++------ compiler/rustc_span/src/source_map.rs | 4 ++- src/test/ui/error-codes/E0435.fixed | 6 +++++ src/test/ui/error-codes/E0435.rs | 4 ++- src/test/ui/error-codes/E0435.stderr | 6 ++--- src/test/ui/impl-trait/bindings.stderr | 24 ++++++++--------- src/test/ui/issues/issue-27433.fixed | 7 +++++ src/test/ui/issues/issue-27433.rs | 2 ++ src/test/ui/issues/issue-27433.stderr | 8 +++--- src/test/ui/issues/issue-3521-2.fixed | 9 +++++++ src/test/ui/issues/issue-3521-2.rs | 1 + src/test/ui/issues/issue-3521-2.stderr | 8 +++--- src/test/ui/issues/issue-3521.fixed | 13 ++++++++++ src/test/ui/issues/issue-3521.rs | 4 ++- src/test/ui/issues/issue-3521.stderr | 6 ++--- src/test/ui/issues/issue-3668-2.fixed | 8 ++++++ src/test/ui/issues/issue-3668-2.rs | 2 ++ src/test/ui/issues/issue-3668-2.stderr | 8 +++--- src/test/ui/issues/issue-3668.stderr | 6 ++--- src/test/ui/issues/issue-42060.stderr | 4 +-- src/test/ui/issues/issue-44239.fixed | 11 ++++++++ src/test/ui/issues/issue-44239.rs | 4 ++- src/test/ui/issues/issue-44239.stderr | 6 ++--- .../ui/non-constant-expr-for-arr-len.stderr | 4 +-- src/test/ui/repeat_count.stderr | 2 +- .../type-dependent-def-issue-49241.stderr | 6 ++--- 27 files changed, 146 insertions(+), 64 deletions(-) create mode 100644 src/test/ui/error-codes/E0435.fixed create mode 100644 src/test/ui/issues/issue-27433.fixed create mode 100644 src/test/ui/issues/issue-3521-2.fixed create mode 100644 src/test/ui/issues/issue-3521.fixed create mode 100644 src/test/ui/issues/issue-3668-2.fixed create mode 100644 src/test/ui/issues/issue-44239.fixed 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 | ::N | ^ non-constant value diff --git a/src/test/ui/issues/issue-44239.fixed b/src/test/ui/issues/issue-44239.fixed new file mode 100644 index 0000000000000..e6c29cee97d2f --- /dev/null +++ b/src/test/ui/issues/issue-44239.fixed @@ -0,0 +1,11 @@ +// run-rustfix +#![allow(dead_code, non_upper_case_globals)] +fn main() { + const n: usize = 0; + + struct Foo; + impl Foo { + const N: usize = n; + //~^ ERROR attempt to use a non-constant value + } +} diff --git a/src/test/ui/issues/issue-44239.rs b/src/test/ui/issues/issue-44239.rs index 99a865f75a498..482ed194c7a1c 100644 --- a/src/test/ui/issues/issue-44239.rs +++ b/src/test/ui/issues/issue-44239.rs @@ -1,5 +1,7 @@ +// run-rustfix +#![allow(dead_code, non_upper_case_globals)] fn main() { - let n = 0; + let n: usize = 0; struct Foo; impl Foo { diff --git a/src/test/ui/issues/issue-44239.stderr b/src/test/ui/issues/issue-44239.stderr index bbd3d116c9634..2a245c92c4868 100644 --- a/src/test/ui/issues/issue-44239.stderr +++ b/src/test/ui/issues/issue-44239.stderr @@ -1,8 +1,8 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-44239.rs:6:26 + --> $DIR/issue-44239.rs:8:26 | -LL | let n = 0; - | - help: consider using `const` instead of `let` +LL | let n: usize = 0; + | ----- help: consider using `const` instead of `let`: `const n` ... LL | const N: usize = n; | ^ non-constant value diff --git a/src/test/ui/non-constant-expr-for-arr-len.stderr b/src/test/ui/non-constant-expr-for-arr-len.stderr index 01da6bcf49aaa..d684b8eaabdfe 100644 --- a/src/test/ui/non-constant-expr-for-arr-len.stderr +++ b/src/test/ui/non-constant-expr-for-arr-len.stderr @@ -2,9 +2,9 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/non-constant-expr-for-arr-len.rs:5:22 | LL | fn bar(n: usize) { - | - help: consider using `const` instead of `let` + | - this would need to be a `const` LL | let _x = [0; n]; - | ^ non-constant value + | ^ error: aborting due to previous error diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index aa1b2e60d51f8..e90754e9118d2 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -2,7 +2,7 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/repeat_count.rs:5:17 | LL | let n = 1; - | - help: consider using `const` instead of `let` + | ----- help: consider using `const` instead of `let`: `const n` LL | let a = [0; n]; | ^ non-constant value diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr index df791435e88b9..64c7687f7a882 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.stderr +++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr @@ -2,9 +2,9 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/type-dependent-def-issue-49241.rs:3:22 | LL | const l: usize = v.count(); - | - ^ non-constant value - | | - | help: consider using `let` instead of `const` + | ------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let l` error: aborting due to previous error