Skip to content

Commit 4bbb163

Browse files
committed
Point to shadowed name when it exists.
1 parent 6d947e6 commit 4bbb163

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

compiler/rustc_resolve/src/late/diagnostics.rs

+40-5
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,22 @@ struct BaseError {
141141
suggestion: Option<(Span, &'static str, String)>,
142142
}
143143

144+
#[derive(Debug)]
145+
enum TypoCandidate {
146+
Typo(TypoSuggestion),
147+
Shadowed(Res),
148+
None,
149+
}
150+
151+
impl TypoCandidate {
152+
fn to_opt_suggestion(self) -> Option<TypoSuggestion> {
153+
match self {
154+
TypoCandidate::Typo(sugg) => Some(sugg),
155+
TypoCandidate::Shadowed(_) | TypoCandidate::None => None,
156+
}
157+
}
158+
}
159+
144160
impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
145161
fn def_span(&self, def_id: DefId) -> Option<Span> {
146162
match def_id.krate {
@@ -497,7 +513,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
497513
}
498514

499515
// Try Levenshtein algorithm.
500-
let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected);
516+
let typo_sugg =
517+
self.lookup_typo_candidate(path, source.namespace(), is_expected).to_opt_suggestion();
501518
if path.len() == 1 && self.self_type_is_available() {
502519
if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) {
503520
let self_is_available = self.self_value_is_available(path[0].ident.span);
@@ -661,7 +678,18 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
661678
let is_expected = &|res| source.is_expected(res);
662679
let ident_span = path.last().map_or(span, |ident| ident.ident.span);
663680
let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected);
681+
if let TypoCandidate::Shadowed(res) = typo_sugg
682+
&& let Some(id) = res.opt_def_id()
683+
&& let Some(sugg_span) = self.r.opt_span(id)
684+
{
685+
err.span_label(
686+
sugg_span,
687+
format!("you might have meant to refer to this {}", res.descr()),
688+
);
689+
return true;
690+
}
664691
let mut fallback = false;
692+
let typo_sugg = typo_sugg.to_opt_suggestion();
665693
if !self.r.add_typo_suggestion(err, typo_sugg, ident_span) {
666694
fallback = true;
667695
match self.diagnostic_metadata.current_let_binding {
@@ -1582,7 +1610,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
15821610
path: &[Segment],
15831611
ns: Namespace,
15841612
filter_fn: &impl Fn(Res) -> bool,
1585-
) -> Option<TypoSuggestion> {
1613+
) -> TypoCandidate {
15861614
let mut names = Vec::new();
15871615
if path.len() == 1 {
15881616
let mut ctxt = path.last().unwrap().ident.span.ctxt();
@@ -1671,10 +1699,17 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
16711699
name,
16721700
None,
16731701
) {
1674-
Some(found) if found != name => {
1675-
names.into_iter().find(|suggestion| suggestion.candidate == found)
1702+
Some(found) => {
1703+
let Some(sugg) = names.into_iter().find(|suggestion| suggestion.candidate == found) else {
1704+
return TypoCandidate::None;
1705+
};
1706+
if found == name {
1707+
TypoCandidate::Shadowed(sugg.res)
1708+
} else {
1709+
TypoCandidate::Typo(sugg)
1710+
}
16761711
}
1677-
_ => None,
1712+
_ => TypoCandidate::None,
16781713
}
16791714
}
16801715

src/test/ui/lexical-scopes.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
error[E0574]: expected struct, variant or union type, found type parameter `T`
22
--> $DIR/lexical-scopes.rs:3:13
33
|
4+
LL | struct T { i: i32 }
5+
| ------------------- you might have meant to refer to this struct
46
LL | fn f<T>() {
57
| - found this type parameter
68
LL | let t = T { i: 0 };

src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
error[E0574]: expected struct, variant or union type, found type parameter `Baz`
22
--> $DIR/point-at-type-parameter-shadowing-another-type.rs:16:13
33
|
4-
LL | impl<Baz> Foo<Baz> for Bar {
5-
| --- found this type parameter
4+
LL | / struct Baz {
5+
LL | | num: usize,
6+
LL | | }
7+
| |_- you might have meant to refer to this struct
8+
LL |
9+
LL | impl<Baz> Foo<Baz> for Bar {
10+
| --- found this type parameter
611
...
7-
LL | Baz { num } => num,
8-
| ^^^ not a struct, variant or union type
12+
LL | Baz { num } => num,
13+
| ^^^ not a struct, variant or union type
914

1015
error: aborting due to previous error
1116

0 commit comments

Comments
 (0)