stop suggesting non-existing fully qualified paths

This commit is contained in:
Takayuki Maeda 2022-05-11 19:18:02 +09:00
parent cb12198715
commit daeec7e22d
3 changed files with 75 additions and 11 deletions

View File

@ -739,7 +739,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
{ {
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 mut suggestions: Vec<_> = impl_candidates.iter().map(|candidate| { let mut suggestions: Vec<_> = impl_candidates.iter().filter_map(|candidate| {
let trait_item = self.tcx let trait_item = self.tcx
.associated_items(candidate.def_id) .associated_items(candidate.def_id)
.find_by_name_and_kind( .find_by_name_and_kind(
@ -748,6 +748,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
ty::AssocKind::Fn, ty::AssocKind::Fn,
candidate.def_id candidate.def_id
); );
if trait_item.is_none() {
return None;
}
let prefix = if let Some(trait_item) = trait_item let prefix = if let Some(trait_item) = trait_item
&& let Some(trait_m) = trait_item.def_id.as_local() && let Some(trait_m) = trait_item.def_id.as_local()
&& let hir::TraitItemKind::Fn(fn_, _) = &self.tcx.hir().trait_item(hir::TraitItemId { def_id: trait_m }).kind && let hir::TraitItemKind::Fn(fn_, _) = &self.tcx.hir().trait_item(hir::TraitItemId { def_id: trait_m }).kind
@ -761,24 +764,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"" ""
}; };
let candidate = candidate.super_fold_with(&mut eraser); let candidate = candidate.super_fold_with(&mut eraser);
vec![ Some(vec![
(expr.span.shrink_to_lo(), format!("{}::{}({}", candidate, segment.ident, prefix)), (expr.span.shrink_to_lo(), format!("{}::{}({}", candidate, segment.ident, prefix)),
if exprs.len() == 1 { if exprs.len() == 1 {
(expr.span.shrink_to_hi().with_hi(e.span.hi()), ")".to_string()) (expr.span.shrink_to_hi().with_hi(e.span.hi()), ")".to_string())
} else { } else {
(expr.span.shrink_to_hi().with_hi(exprs[1].span.lo()), ", ".to_string()) (expr.span.shrink_to_hi().with_hi(exprs[1].span.lo()), ", ".to_string())
}, },
] ])
}).collect(); }).collect();
suggestions.sort_by(|a, b| a[0].1.cmp(&b[0].1)); suggestions.sort_by(|a, b| a[0].1.cmp(&b[0].1));
err.multipart_suggestions( if !suggestions.is_empty() {
&format!( err.multipart_suggestions(
"use the fully qualified path for the potential candidate{}", &format!(
pluralize!(candidate_len), "use the fully qualified path for the potential candidate{}",
), pluralize!(candidate_len),
suggestions.into_iter(), ),
Applicability::MaybeIncorrect, suggestions.into_iter(),
); Applicability::MaybeIncorrect,
);
}
} }
// Suggest specifying type params or point out the return type of the call: // Suggest specifying type params or point out the return type of the call:
// //

View File

@ -0,0 +1,24 @@
struct A<T>(T);
struct B;
trait I<T> {}
impl I<i32> for B {}
impl I<u32> for B {}
trait V<U> {
fn method(self) -> U;
}
impl<T, U> V<U> for A<T>
where
T: I<U>,
{
fn method(self) -> U { unimplemented!() }
}
fn main() {
let a = A(B);
a.method();
//~^ ERROR type annotations needed
//~| ERROR type annotations needed
}

View File

@ -0,0 +1,35 @@
error[E0282]: type annotations needed
--> $DIR/not-suggest-non-existing-fully-qualified-path.rs:21:7
|
LL | a.method();
| --^^^^^^--
| | |
| | cannot infer type for type parameter `U` declared on the trait `V`
| this method call resolves to `U`
error[E0283]: type annotations needed
--> $DIR/not-suggest-non-existing-fully-qualified-path.rs:21:7
|
LL | a.method();
| --^^^^^^--
| | |
| | cannot infer type for type parameter `U`
| this method call resolves to `U`
|
note: multiple `impl`s satisfying `B: I<_>` found
--> $DIR/not-suggest-non-existing-fully-qualified-path.rs:5:1
|
LL | impl I<i32> for B {}
| ^^^^^^^^^^^^^^^^^
LL | impl I<u32> for B {}
| ^^^^^^^^^^^^^^^^^
note: required because of the requirements on the impl of `V<_>` for `A<B>`
--> $DIR/not-suggest-non-existing-fully-qualified-path.rs:12:12
|
LL | impl<T, U> V<U> for A<T>
| ^^^^ ^^^^
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0282, E0283.
For more information about an error, try `rustc --explain E0282`.