diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 4f07d0076f140..9b5a69e4bb220 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -443,6 +443,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { ); } } + // Try Levenshtein algorithm. + let typo_sugg = self.lookup_typo_candidate(path, ns, is_expected); if path.len() == 1 && self.self_type_is_available() { if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) { let self_is_available = self.self_value_is_available(path[0].ident.span); @@ -452,7 +454,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion( span, "you might have meant to use the available field", - format!("self.{}", path_str), + format!("self.{path_str}"), Applicability::MachineApplicable, ); } else { @@ -463,7 +465,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion( span, "you might have meant to call the method", - format!("self.{}", path_str), + format!("self.{path_str}"), Applicability::MachineApplicable, ); } @@ -474,11 +476,12 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion( span, &format!("you might have meant to {}", candidate.action()), - format!("Self::{}", path_str), + format!("Self::{path_str}"), Applicability::MachineApplicable, ); } } + self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span); return (err, candidates); } @@ -493,16 +496,14 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion( call_span, - &format!("try calling `{}` as a method", ident), - format!("self.{}({})", path_str, args_snippet), + &format!("try calling `{ident}` as a method"), + format!("self.{path_str}({args_snippet})"), Applicability::MachineApplicable, ); return (err, candidates); } } - // Try Levenshtein algorithm. - let typo_sugg = self.lookup_typo_candidate(path, ns, is_expected); // Try context-dependent help if relaxed lookup didn't work. if let Some(res) = res { if self.smart_resolve_context_dependent_help( diff --git a/src/test/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs b/src/test/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs new file mode 100644 index 0000000000000..ecd3f58811904 --- /dev/null +++ b/src/test/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs @@ -0,0 +1,46 @@ +struct A { + config: String, +} + +impl A { + fn new(cofig: String) -> Self { + Self { config } //~ Error cannot find value `config` in this scope + } + + fn do_something(cofig: String) { + println!("{config}"); //~ Error cannot find value `config` in this scope + } + + fn self_is_available(self, cofig: String) { + println!("{config}"); //~ Error cannot find value `config` in this scope + } +} + +trait B { + const BAR: u32 = 3; + type Baz; + fn bar(&self); + fn baz(&self) {} + fn bah() {} +} + +impl B for Box { + type Baz = String; + fn bar(&self) { + // let baz = 3; + baz(); + //~^ ERROR cannot find function `baz` + bah; + //~^ ERROR cannot find value `bah` + BAR; + //~^ ERROR cannot find value `BAR` in this scope + let foo: Baz = "".to_string(); + //~^ ERROR cannot find type `Baz` in this scope + } +} + +fn ba() {} +const BARR: u32 = 3; +type Bar = String; + +fn main() {} diff --git a/src/test/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/src/test/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr new file mode 100644 index 0000000000000..0b0a37f246c93 --- /dev/null +++ b/src/test/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -0,0 +1,109 @@ +error[E0425]: cannot find value `config` in this scope + --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:7:16 + | +LL | Self { config } + | ^^^^^^ + | | + | a field by this name exists in `Self` + | help: a local variable with a similar name exists: `cofig` + +error[E0425]: cannot find value `config` in this scope + --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:11:20 + | +LL | println!("{config}"); + | ^^^^^^ + | | + | a field by this name exists in `Self` + | help: a local variable with a similar name exists: `cofig` + +error[E0425]: cannot find value `config` in this scope + --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:15:20 + | +LL | println!("{config}"); + | ^^^^^^ + | +help: you might have meant to use the available field + | +LL | println!("{self.config}"); + | ~~~~~~~~~~~ +help: a local variable with a similar name exists + | +LL | println!("{cofig}"); + | ~~~~~ + +error[E0425]: cannot find function `baz` in this scope + --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:31:9 + | +LL | baz(); + | ^^^ +... +LL | fn ba() {} + | ------- similarly named function `ba` defined here + | +help: you might have meant to call the method + | +LL | self.baz(); + | ~~~~~~~~ +help: a function with a similar name exists + | +LL | ba(); + | ~~ + +error[E0425]: cannot find value `bah` in this scope + --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:33:9 + | +LL | bah; + | ^^^ +... +LL | fn ba() {} + | ------- similarly named function `ba` defined here + | +help: you might have meant to call the associated function + | +LL | Self::bah; + | ~~~~~~~~~ +help: a function with a similar name exists + | +LL | ba; + | ~~ + +error[E0425]: cannot find value `BAR` in this scope + --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:35:9 + | +LL | BAR; + | ^^^ +... +LL | const BARR: u32 = 3; + | -------------------- similarly named constant `BARR` defined here + | +help: you might have meant to use the associated `const` + | +LL | Self::BAR; + | ~~~~~~~~~ +help: a constant with a similar name exists + | +LL | BARR; + | ~~~~ + +error[E0412]: cannot find type `Baz` in this scope + --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:37:18 + | +LL | let foo: Baz = "".to_string(); + | ^^^ +... +LL | type Bar = String; + | ------------------ similarly named type alias `Bar` defined here + | +help: you might have meant to use the associated type + | +LL | let foo: Self::Baz = "".to_string(); + | ~~~~~~~~~ +help: a type alias with a similar name exists + | +LL | let foo: Bar = "".to_string(); + | ~~~ + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0412, E0425. +For more information about an error, try `rustc --explain E0412`.