From 6d947e6d489269124067fb91504f25f61187858e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 16 Oct 2022 08:51:11 +0000 Subject: Account for hygiene when suggesting typos. --- src/test/ui/hygiene/globs.stderr | 18 ++++++++++++++++-- src/test/ui/hygiene/rustc-macro-transparency.stderr | 8 +------- src/test/ui/macros/macro-context.stderr | 2 +- src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr | 4 ++-- src/test/ui/proc-macro/mixed-site-span.stderr | 4 ++-- 5 files changed, 22 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/test/ui/hygiene/globs.stderr b/src/test/ui/hygiene/globs.stderr index bcfcc28adf7..1f2a96a4c41 100644 --- a/src/test/ui/hygiene/globs.stderr +++ b/src/test/ui/hygiene/globs.stderr @@ -1,9 +1,16 @@ error[E0425]: cannot find function `f` in this scope --> $DIR/globs.rs:22:9 | +LL | pub fn g() {} + | ---------- similarly named function `g` defined here +... LL | f(); - | ^ not found in this scope + | ^ + | +help: a function with a similar name exists | +LL | g(); + | ~ help: consider importing this function | LL | use foo::f; @@ -12,8 +19,11 @@ LL | use foo::f; error[E0425]: cannot find function `g` in this scope --> $DIR/globs.rs:15:5 | +LL | pub fn f() {} + | ---------- similarly named function `f` defined here +... LL | g(); - | ^ not found in this scope + | ^ ... LL | / m! { LL | | use bar::*; @@ -23,6 +33,10 @@ LL | | } | |_____- in this macro invocation | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a function with a similar name exists + | +LL | f(); + | ~ help: consider importing this function | LL | use bar::g; diff --git a/src/test/ui/hygiene/rustc-macro-transparency.stderr b/src/test/ui/hygiene/rustc-macro-transparency.stderr index 17d05dd0963..1d2a1e12498 100644 --- a/src/test/ui/hygiene/rustc-macro-transparency.stderr +++ b/src/test/ui/hygiene/rustc-macro-transparency.stderr @@ -19,14 +19,8 @@ LL | semitransparent; error[E0423]: expected value, found macro `opaque` --> $DIR/rustc-macro-transparency.rs:30:5 | -LL | struct Opaque; - | -------------- similarly named unit struct `Opaque` defined here -... LL | opaque; - | ^^^^^^ - | | - | not a value - | help: a unit struct with a similar name exists (notice the capitalization): `Opaque` + | ^^^^^^ not a value error: aborting due to 3 previous errors diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr index 2a2e0c6c66a..f597c398b7c 100644 --- a/src/test/ui/macros/macro-context.stderr +++ b/src/test/ui/macros/macro-context.stderr @@ -57,7 +57,7 @@ error[E0425]: cannot find value `i` in this scope --> $DIR/macro-context.rs:3:13 | LL | () => ( i ; typeof ); - | ^ help: a local variable with a similar name exists: `a` + | ^ not found in this scope ... LL | let i = m!(); | ---- in this macro invocation diff --git a/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr b/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr index 6060f872f22..df7c4f72eb0 100644 --- a/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr +++ b/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr @@ -13,7 +13,7 @@ error[E0425]: cannot find value `local_use` in this scope --> $DIR/gen-macro-rules-hygiene.rs:12:1 | LL | gen_macro_rules!(); - | ^^^^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def` ... LL | generated!(); | ------------ in this macro invocation @@ -24,7 +24,7 @@ error[E0425]: cannot find value `local_def` in this scope --> $DIR/gen-macro-rules-hygiene.rs:21:9 | LL | local_def; - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ help: a local variable with a similar name exists: `local_use` error: aborting due to 3 previous errors diff --git a/src/test/ui/proc-macro/mixed-site-span.stderr b/src/test/ui/proc-macro/mixed-site-span.stderr index eab4317ded8..13786080124 100644 --- a/src/test/ui/proc-macro/mixed-site-span.stderr +++ b/src/test/ui/proc-macro/mixed-site-span.stderr @@ -10,7 +10,7 @@ error[E0425]: cannot find value `local_use` in this scope --> $DIR/mixed-site-span.rs:13:9 | LL | proc_macro_rules!(); - | ^^^^^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def` | = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -18,7 +18,7 @@ error[E0425]: cannot find value `local_def` in this scope --> $DIR/mixed-site-span.rs:17:9 | LL | local_def; - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ help: a local variable with a similar name exists: `local_use` error[E0412]: cannot find type `ItemUse` in crate `$crate` --> $DIR/mixed-site-span.rs:24:1 -- cgit 1.4.1-3-g733a5 From 4bbb163b5d248bef036670d952f1c00dd812a7e2 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 16 Oct 2022 08:59:28 +0000 Subject: Point to shadowed name when it exists. --- compiler/rustc_resolve/src/late/diagnostics.rs | 45 +++++++++++++++++++--- src/test/ui/lexical-scopes.stderr | 2 + ...at-type-parameter-shadowing-another-type.stderr | 13 +++++-- 3 files changed, 51 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 3c82c760ed7..ffa7cb0c9d2 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -141,6 +141,22 @@ struct BaseError { suggestion: Option<(Span, &'static str, String)>, } +#[derive(Debug)] +enum TypoCandidate { + Typo(TypoSuggestion), + Shadowed(Res), + None, +} + +impl TypoCandidate { + fn to_opt_suggestion(self) -> Option { + match self { + TypoCandidate::Typo(sugg) => Some(sugg), + TypoCandidate::Shadowed(_) | TypoCandidate::None => None, + } + } +} + impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { fn def_span(&self, def_id: DefId) -> Option { match def_id.krate { @@ -497,7 +513,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } // Try Levenshtein algorithm. - let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected); + let typo_sugg = + self.lookup_typo_candidate(path, source.namespace(), is_expected).to_opt_suggestion(); 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); @@ -661,7 +678,18 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let is_expected = &|res| source.is_expected(res); let ident_span = path.last().map_or(span, |ident| ident.ident.span); let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected); + if let TypoCandidate::Shadowed(res) = typo_sugg + && let Some(id) = res.opt_def_id() + && let Some(sugg_span) = self.r.opt_span(id) + { + err.span_label( + sugg_span, + format!("you might have meant to refer to this {}", res.descr()), + ); + return true; + } let mut fallback = false; + let typo_sugg = typo_sugg.to_opt_suggestion(); if !self.r.add_typo_suggestion(err, typo_sugg, ident_span) { fallback = true; match self.diagnostic_metadata.current_let_binding { @@ -1582,7 +1610,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { path: &[Segment], ns: Namespace, filter_fn: &impl Fn(Res) -> bool, - ) -> Option { + ) -> TypoCandidate { let mut names = Vec::new(); if path.len() == 1 { let mut ctxt = path.last().unwrap().ident.span.ctxt(); @@ -1671,10 +1699,17 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { name, None, ) { - Some(found) if found != name => { - names.into_iter().find(|suggestion| suggestion.candidate == found) + Some(found) => { + let Some(sugg) = names.into_iter().find(|suggestion| suggestion.candidate == found) else { + return TypoCandidate::None; + }; + if found == name { + TypoCandidate::Shadowed(sugg.res) + } else { + TypoCandidate::Typo(sugg) + } } - _ => None, + _ => TypoCandidate::None, } } diff --git a/src/test/ui/lexical-scopes.stderr b/src/test/ui/lexical-scopes.stderr index 08e4be2c0c3..53598545223 100644 --- a/src/test/ui/lexical-scopes.stderr +++ b/src/test/ui/lexical-scopes.stderr @@ -1,6 +1,8 @@ error[E0574]: expected struct, variant or union type, found type parameter `T` --> $DIR/lexical-scopes.rs:3:13 | +LL | struct T { i: i32 } + | ------------------- you might have meant to refer to this struct LL | fn f() { | - found this type parameter LL | let t = T { i: 0 }; diff --git a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr index af9f4612ab3..eb26cd9cabb 100644 --- a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr +++ b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr @@ -1,11 +1,16 @@ error[E0574]: expected struct, variant or union type, found type parameter `Baz` --> $DIR/point-at-type-parameter-shadowing-another-type.rs:16:13 | -LL | impl Foo for Bar { - | --- found this type parameter +LL | / struct Baz { +LL | | num: usize, +LL | | } + | |_- you might have meant to refer to this struct +LL | +LL | impl Foo for Bar { + | --- found this type parameter ... -LL | Baz { num } => num, - | ^^^ not a struct, variant or union type +LL | Baz { num } => num, + | ^^^ not a struct, variant or union type error: aborting due to previous error -- cgit 1.4.1-3-g733a5