When suggesting to import an item, also suggest changing the path if appropriate

When we don't find an item we search all of them for an appropriate
import and suggest `use`ing it. This is sometimes done for expressions
that have paths with more than one segment. We now also suggest changing
that path to work with the `use`.

Fix #95413
This commit is contained in:
Esteban Küber 2022-04-23 16:41:36 -07:00 committed by Esteban Kuber
parent 3d0ac7ea23
commit 57967269e9
14 changed files with 149 additions and 17 deletions

View file

@ -117,7 +117,7 @@ impl<'a> Resolver<'a> {
}
fn report_with_use_injections(&mut self, krate: &Crate) {
for UseError { mut err, candidates, def_id, instead, suggestion } in
for UseError { mut err, candidates, def_id, instead, suggestion, path } in
self.use_injections.drain(..)
{
let (span, found_use) = if let Some(def_id) = def_id.as_local() {
@ -135,6 +135,7 @@ impl<'a> Resolver<'a> {
if instead { Instead::Yes } else { Instead::No },
found_use,
IsPattern::No,
path,
);
} else if let Some((span, msg, sugg, appl)) = suggestion {
err.span_suggestion(span, msg, sugg, appl);
@ -702,6 +703,7 @@ impl<'a> Resolver<'a> {
Instead::No,
FoundUse::Yes,
IsPattern::Yes,
vec![],
);
}
err
@ -1482,6 +1484,7 @@ impl<'a> Resolver<'a> {
Instead::No,
FoundUse::Yes,
IsPattern::No,
vec![],
);
if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
@ -2448,6 +2451,7 @@ fn show_candidates(
instead: Instead,
found_use: FoundUse,
is_pattern: IsPattern,
path: Vec<Segment>,
) {
if candidates.is_empty() {
return;
@ -2480,14 +2484,15 @@ fn show_candidates(
("one of these", "items", String::new())
};
let tail = if path.len() > 1 { "..." } else { "" };
let instead = if let Instead::Yes = instead { " instead" } else { "" };
let mut msg = if let IsPattern::Yes = is_pattern {
format!(
"if you meant to match on {}{}{}, use the full path in the pattern",
kind, instead, name
"if you meant to match on {}{}{}, use the full path in the pattern{}",
kind, instead, name, tail
)
} else {
format!("consider importing {} {}{}", determiner, kind, instead)
format!("consider importing {} {}{}{}", determiner, kind, instead, tail)
};
for note in accessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) {
@ -2515,6 +2520,14 @@ fn show_candidates(
accessible_path_strings.into_iter().map(|a| a.0),
Applicability::MaybeIncorrect,
);
if let [first, .., last] = &path[..] {
err.span_suggestion_verbose(
first.ident.span.until(last.ident.span),
"...and refer to it directly",
String::new(),
Applicability::Unspecified,
);
}
} else {
msg.push(':');