1
Fork 0

Use more targetted suggestion span for fully qualified path

This commit is contained in:
Esteban Küber 2022-04-23 12:44:52 -07:00
parent acee1f47ef
commit 1e1f33f584
5 changed files with 34 additions and 28 deletions

View file

@ -734,19 +734,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
if !impl_candidates.is_empty() && e.span.contains(span) if !impl_candidates.is_empty() && e.span.contains(span)
&& let Some(expr) = exprs.first() && let Some(expr) = exprs.first()
&& let ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind && let ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
&& let [path_segment] = path.segments && let [_] = path.segments
{ {
let mut eraser = TypeParamEraser(self.tcx); let mut eraser = TypeParamEraser(self.tcx);
let candidate_len = impl_candidates.len(); let candidate_len = impl_candidates.len();
let suggestions = impl_candidates.iter().map(|candidate| { let suggestions = impl_candidates.iter().map(|candidate| {
let candidate = candidate.super_fold_with(&mut eraser); let candidate = candidate.super_fold_with(&mut eraser);
format!( vec![
"{}::{}({})", (expr.span.shrink_to_lo(), format!("{}::{}(", candidate, segment.ident)),
candidate, segment.ident, path_segment.ident if exprs.len() == 1 {
) (expr.span.shrink_to_hi().with_hi(e.span.hi()), ")".to_string())
} else {
(expr.span.shrink_to_hi().with_hi(exprs[1].span.lo()), ", ".to_string())
},
]
}); });
err.span_suggestions( err.multipart_suggestions(
e.span,
&format!( &format!(
"use the fully qualified path for the potential candidate{}", "use the fully qualified path for the potential candidate{}",
pluralize!(candidate_len), pluralize!(candidate_len),

View file

@ -14,7 +14,6 @@ LL | let bar = foo_impl.into() * 1u32;
| | | | | |
| | cannot infer type for type parameter `T` declared on the trait `Into` | | cannot infer type for type parameter `T` declared on the trait `Into`
| this method call resolves to `T` | this method call resolves to `T`
| help: use the fully qualified path for the potential candidate: `<Impl as Into<u32>>::into(foo_impl)`
| |
note: multiple `impl`s satisfying `Impl: Into<_>` found note: multiple `impl`s satisfying `Impl: Into<_>` found
--> $DIR/E0283.rs:17:1 --> $DIR/E0283.rs:17:1
@ -24,6 +23,10 @@ LL | impl Into<u32> for Impl {
= note: and another `impl` found in the `core` crate: = note: and another `impl` found in the `core` crate:
- impl<T, U> Into<U> for T - impl<T, U> Into<U> for T
where U: From<T>; where U: From<T>;
help: use the fully qualified path for the potential candidate
|
LL | let bar = <Impl as Into<u32>>::into(foo_impl) * 1u32;
| ++++++++++++++++++++++++++ ~
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -1,20 +1,20 @@
struct Thing<X>(X); struct Thing<X>(X);
trait Method<T> { trait Method<T> {
fn method(self) -> T; fn method(self, _: i32) -> T;
} }
impl<X> Method<i32> for Thing<X> { impl<X> Method<i32> for Thing<X> {
fn method(self) -> i32 { 0 } fn method(self, _: i32) -> i32 { 0 }
} }
impl<X> Method<u32> for Thing<X> { impl<X> Method<u32> for Thing<X> {
fn method(self) -> u32 { 0 } fn method(self, _: i32) -> u32 { 0 }
} }
fn main() { fn main() {
let thing = Thing(true); let thing = Thing(true);
thing.method(); thing.method(42);
//~^ ERROR type annotations needed //~^ ERROR type annotations needed
//~| ERROR type annotations needed //~| ERROR type annotations needed
} }

View file

@ -1,8 +1,8 @@
error[E0282]: type annotations needed error[E0282]: type annotations needed
--> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:17:11 --> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:17:11
| |
LL | thing.method(); LL | thing.method(42);
| ------^^^^^^-- | ------^^^^^^----
| | | | | |
| | cannot infer type for type parameter `T` declared on the trait `Method` | | cannot infer type for type parameter `T` declared on the trait `Method`
| this method call resolves to `T` | this method call resolves to `T`
@ -10,8 +10,8 @@ LL | thing.method();
error[E0283]: type annotations needed error[E0283]: type annotations needed
--> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:17:11 --> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:17:11
| |
LL | thing.method(); LL | thing.method(42);
| ------^^^^^^-- | ------^^^^^^----
| | | | | |
| | cannot infer type for type parameter `T` declared on the trait `Method` | | cannot infer type for type parameter `T` declared on the trait `Method`
| this method call resolves to `T` | this method call resolves to `T`
@ -26,10 +26,10 @@ LL | impl<X> Method<u32> for Thing<X> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: use the fully qualified path for the potential candidates help: use the fully qualified path for the potential candidates
| |
LL | <Thing<_> as Method<i32>>::method(thing); LL | <Thing<_> as Method<i32>>::method(thing, 42);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ++++++++++++++++++++++++++++++++++ ~
LL | <Thing<_> as Method<u32>>::method(thing); LL | <Thing<_> as Method<u32>>::method(thing, 42);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ++++++++++++++++++++++++++++++++++ ~
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -36,14 +36,14 @@ LL | opts.get(opt.as_ref());
- impl AsRef<str> for String; - impl AsRef<str> for String;
help: use the fully qualified path for the potential candidates help: use the fully qualified path for the potential candidates
| |
LL | opts.get(<String as AsRef<OsStr>>::as_ref(opt)); LL | opts.get(<str as AsRef<Path>>::as_ref(opt));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +++++++++++++++++++++++++++++ ~
LL | opts.get(<String as AsRef<Path>>::as_ref(opt)); LL | opts.get(<str as AsRef<OsStr>>::as_ref(opt));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ++++++++++++++++++++++++++++++ ~
LL | opts.get(<String as AsRef<[u8]>>::as_ref(opt)); LL | opts.get(<str as AsRef<str>>::as_ref(opt));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ++++++++++++++++++++++++++++ ~
LL | opts.get(<String as AsRef<str>>::as_ref(opt)); LL | opts.get(<str as AsRef<[u8]>>::as_ref(opt));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +++++++++++++++++++++++++++++ ~
and 4 other candidates and 4 other candidates
error[E0283]: type annotations needed error[E0283]: type annotations needed