1
Fork 0

Add Span in TypoSuggestion and TypoCandidate

This commit is contained in:
Byron Zhong 2022-10-25 01:14:39 -05:00
parent 6365e5ad9f
commit be61f0237b
2 changed files with 39 additions and 30 deletions

View file

@ -58,16 +58,32 @@ pub(crate) enum SuggestionTarget {
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct TypoSuggestion { pub(crate) struct TypoSuggestion {
pub candidate: Symbol, pub candidate: Symbol,
/// The source location where the name is defined; None if the name is not defined
/// in source e.g. primitives
pub span: Option<Span>,
pub res: Res, pub res: Res,
pub target: SuggestionTarget, pub target: SuggestionTarget,
} }
impl TypoSuggestion { impl TypoSuggestion {
pub(crate) fn typo_from_res(candidate: Symbol, res: Res) -> TypoSuggestion { pub(crate) fn typo_from_ident(ident: Ident, res: Res) -> TypoSuggestion {
Self { candidate, res, target: SuggestionTarget::SimilarlyNamed } Self {
candidate: ident.name,
span: Some(ident.span),
res,
target: SuggestionTarget::SimilarlyNamed,
}
} }
pub(crate) fn single_item_from_res(candidate: Symbol, res: Res) -> TypoSuggestion { pub(crate) fn typo_from_name(candidate: Symbol, res: Res) -> TypoSuggestion {
Self { candidate, res, target: SuggestionTarget::SingleItem } Self { candidate, span: None, res, target: SuggestionTarget::SimilarlyNamed }
}
pub(crate) fn single_item_from_ident(ident: Ident, res: Res) -> TypoSuggestion {
Self {
candidate: ident.name,
span: Some(ident.span),
res,
target: SuggestionTarget::SingleItem,
}
} }
} }
@ -490,7 +506,7 @@ impl<'a> Resolver<'a> {
if let Some(binding) = resolution.borrow().binding { if let Some(binding) = resolution.borrow().binding {
let res = binding.res(); let res = binding.res();
if filter_fn(res) && ctxt.map_or(true, |ctxt| ctxt == key.ident.span.ctxt()) { if filter_fn(res) && ctxt.map_or(true, |ctxt| ctxt == key.ident.span.ctxt()) {
names.push(TypoSuggestion::typo_from_res(key.ident.name, res)); names.push(TypoSuggestion::typo_from_ident(key.ident, res));
} }
} }
} }
@ -1145,7 +1161,7 @@ impl<'a> Resolver<'a> {
.get(&expn_id) .get(&expn_id)
.into_iter() .into_iter()
.flatten() .flatten()
.map(|ident| TypoSuggestion::typo_from_res(ident.name, res)), .map(|ident| TypoSuggestion::typo_from_ident(*ident, res)),
); );
} }
} }
@ -1164,7 +1180,7 @@ impl<'a> Resolver<'a> {
suggestions.extend( suggestions.extend(
ext.helper_attrs ext.helper_attrs
.iter() .iter()
.map(|name| TypoSuggestion::typo_from_res(*name, res)), .map(|name| TypoSuggestion::typo_from_name(*name, res)),
); );
} }
} }
@ -1174,8 +1190,8 @@ impl<'a> Resolver<'a> {
if let MacroRulesScope::Binding(macro_rules_binding) = macro_rules_scope.get() { if let MacroRulesScope::Binding(macro_rules_binding) = macro_rules_scope.get() {
let res = macro_rules_binding.binding.res(); let res = macro_rules_binding.binding.res();
if filter_fn(res) { if filter_fn(res) {
suggestions.push(TypoSuggestion::typo_from_res( suggestions.push(TypoSuggestion::typo_from_ident(
macro_rules_binding.ident.name, macro_rules_binding.ident,
res, res,
)) ))
} }
@ -1193,7 +1209,7 @@ impl<'a> Resolver<'a> {
suggestions.extend(this.macro_use_prelude.iter().filter_map( suggestions.extend(this.macro_use_prelude.iter().filter_map(
|(name, binding)| { |(name, binding)| {
let res = binding.res(); let res = binding.res();
filter_fn(res).then_some(TypoSuggestion::typo_from_res(*name, res)) filter_fn(res).then_some(TypoSuggestion::typo_from_name(*name, res))
}, },
)); ));
} }
@ -1203,14 +1219,14 @@ impl<'a> Resolver<'a> {
suggestions.extend( suggestions.extend(
BUILTIN_ATTRIBUTES BUILTIN_ATTRIBUTES
.iter() .iter()
.map(|attr| TypoSuggestion::typo_from_res(attr.name, res)), .map(|attr| TypoSuggestion::typo_from_name(attr.name, res)),
); );
} }
} }
Scope::ExternPrelude => { Scope::ExternPrelude => {
suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| { suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| {
let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id()); let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
filter_fn(res).then_some(TypoSuggestion::typo_from_res(ident.name, res)) filter_fn(res).then_some(TypoSuggestion::typo_from_ident(*ident, res))
})); }));
} }
Scope::ToolPrelude => { Scope::ToolPrelude => {
@ -1218,7 +1234,7 @@ impl<'a> Resolver<'a> {
suggestions.extend( suggestions.extend(
this.registered_tools this.registered_tools
.iter() .iter()
.map(|ident| TypoSuggestion::typo_from_res(ident.name, res)), .map(|ident| TypoSuggestion::typo_from_ident(*ident, res)),
); );
} }
Scope::StdLibPrelude => { Scope::StdLibPrelude => {
@ -1235,7 +1251,8 @@ impl<'a> Resolver<'a> {
Scope::BuiltinTypes => { Scope::BuiltinTypes => {
suggestions.extend(PrimTy::ALL.iter().filter_map(|prim_ty| { suggestions.extend(PrimTy::ALL.iter().filter_map(|prim_ty| {
let res = Res::PrimTy(*prim_ty); let res = Res::PrimTy(*prim_ty);
filter_fn(res).then_some(TypoSuggestion::typo_from_res(prim_ty.name(), res)) filter_fn(res)
.then_some(TypoSuggestion::typo_from_name(prim_ty.name(), res))
})) }))
} }
} }

View file

@ -150,7 +150,7 @@ struct BaseError {
#[derive(Debug)] #[derive(Debug)]
enum TypoCandidate { enum TypoCandidate {
Typo(TypoSuggestion), Typo(TypoSuggestion),
Shadowed(Res), Shadowed(Res, Option<Span>),
None, None,
} }
@ -158,7 +158,7 @@ impl TypoCandidate {
fn to_opt_suggestion(self) -> Option<TypoSuggestion> { fn to_opt_suggestion(self) -> Option<TypoSuggestion> {
match self { match self {
TypoCandidate::Typo(sugg) => Some(sugg), TypoCandidate::Typo(sugg) => Some(sugg),
TypoCandidate::Shadowed(_) | TypoCandidate::None => None, TypoCandidate::Shadowed(_, _) | TypoCandidate::None => None,
} }
} }
} }
@ -691,10 +691,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
let is_expected = &|res| source.is_expected(res); let is_expected = &|res| source.is_expected(res);
let ident_span = path.last().map_or(span, |ident| ident.ident.span); let ident_span = path.last().map_or(span, |ident| ident.ident.span);
let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected); let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected);
if let TypoCandidate::Shadowed(res) = typo_sugg if let TypoCandidate::Shadowed(res, Some(sugg_span)) = typo_sugg {
&& let Some(id) = res.opt_def_id()
&& let Some(sugg_span) = self.r.opt_span(id)
{
err.span_label( err.span_label(
sugg_span, sugg_span,
format!("you might have meant to refer to this {}", res.descr()), format!("you might have meant to refer to this {}", res.descr()),
@ -973,10 +970,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
.collect(); .collect();
if targets.len() == 1 { if targets.len() == 1 {
let target = targets[0]; let target = targets[0];
return Some(TypoSuggestion::single_item_from_res( return Some(TypoSuggestion::single_item_from_ident(target.0.ident, target.1));
target.0.ident.name,
target.1,
));
} }
} }
} }
@ -1618,7 +1612,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
// Locals and type parameters // Locals and type parameters
for (ident, &res) in &rib.bindings { for (ident, &res) in &rib.bindings {
if filter_fn(res) && ident.span.ctxt() == rib_ctxt { if filter_fn(res) && ident.span.ctxt() == rib_ctxt {
names.push(TypoSuggestion::typo_from_res(ident.name, res)); names.push(TypoSuggestion::typo_from_ident(*ident, res));
} }
} }
@ -1647,9 +1641,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
Res::Def(DefKind::Mod, crate_id.as_def_id()); Res::Def(DefKind::Mod, crate_id.as_def_id());
if filter_fn(crate_mod) { if filter_fn(crate_mod) {
Some(TypoSuggestion::typo_from_res( Some(TypoSuggestion::typo_from_ident(*ident, crate_mod))
ident.name, crate_mod,
))
} else { } else {
None None
} }
@ -1668,7 +1660,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
// Add primitive types to the mix // Add primitive types to the mix
if filter_fn(Res::PrimTy(PrimTy::Bool)) { if filter_fn(Res::PrimTy(PrimTy::Bool)) {
names.extend(PrimTy::ALL.iter().map(|prim_ty| { names.extend(PrimTy::ALL.iter().map(|prim_ty| {
TypoSuggestion::typo_from_res(prim_ty.name(), Res::PrimTy(*prim_ty)) TypoSuggestion::typo_from_name(prim_ty.name(), Res::PrimTy(*prim_ty))
})) }))
} }
} else { } else {
@ -1695,7 +1687,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
return TypoCandidate::None; return TypoCandidate::None;
}; };
if found == name { if found == name {
TypoCandidate::Shadowed(sugg.res) TypoCandidate::Shadowed(sugg.res, sugg.span)
} else { } else {
TypoCandidate::Typo(sugg) TypoCandidate::Typo(sugg)
} }