suggestion: Option<(Span, &'static str, String)>,
}
+#[derive(Debug)]
+enum TypoCandidate {
+ Typo(TypoSuggestion),
+ Shadowed(Res),
+ None,
+}
+
+impl TypoCandidate {
+ fn to_opt_suggestion(self) -> Option<TypoSuggestion> {
+ 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<Span> {
match def_id.krate {
}
// 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);
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 {
path: &[Segment],
ns: Namespace,
filter_fn: &impl Fn(Res) -> bool,
- ) -> Option<TypoSuggestion> {
+ ) -> TypoCandidate {
let mut names = Vec::new();
if path.len() == 1 {
let mut ctxt = path.last().unwrap().ident.span.ctxt();
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,
}
}
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<Baz> Foo<Baz> 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<Baz> Foo<Baz> 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