From daeec7e22de6a99a5440ddf401f3fc16756cd64a Mon Sep 17 00:00:00 2001 From: Takayuki Maeda <41065217+TaKO8Ki@users.noreply.github.com> Date: Wed, 11 May 2022 19:18:02 +0900 Subject: [PATCH] stop suggesting non-existing fully qualified paths --- .../infer/error_reporting/need_type_info.rs | 27 ++++++++------ ...ggest-non-existing-fully-qualified-path.rs | 24 +++++++++++++ ...t-non-existing-fully-qualified-path.stderr | 35 +++++++++++++++++++ 3 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.rs create mode 100644 src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 78e0864d918..62edfc6495c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -739,7 +739,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { { let mut eraser = TypeParamEraser(self.tcx); 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 .associated_items(candidate.def_id) .find_by_name_and_kind( @@ -748,6 +748,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ty::AssocKind::Fn, candidate.def_id ); + if trait_item.is_none() { + return None; + } let prefix = if let Some(trait_item) = trait_item && 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 @@ -761,24 +764,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "" }; let candidate = candidate.super_fold_with(&mut eraser); - vec![ + Some(vec![ (expr.span.shrink_to_lo(), format!("{}::{}({}", candidate, segment.ident, prefix)), 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()) }, - ] + ]) }).collect(); suggestions.sort_by(|a, b| a[0].1.cmp(&b[0].1)); - err.multipart_suggestions( - &format!( - "use the fully qualified path for the potential candidate{}", - pluralize!(candidate_len), - ), - suggestions.into_iter(), - Applicability::MaybeIncorrect, - ); + if !suggestions.is_empty() { + err.multipart_suggestions( + &format!( + "use the fully qualified path for the potential candidate{}", + pluralize!(candidate_len), + ), + suggestions.into_iter(), + Applicability::MaybeIncorrect, + ); + } } // Suggest specifying type params or point out the return type of the call: // diff --git a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.rs b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.rs new file mode 100644 index 00000000000..538e74ee1b0 --- /dev/null +++ b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.rs @@ -0,0 +1,24 @@ +struct A(T); +struct B; + +trait I {} +impl I for B {} +impl I for B {} + +trait V { + fn method(self) -> U; +} + +impl V for A +where + T: I, +{ + fn method(self) -> U { unimplemented!() } +} + +fn main() { + let a = A(B); + a.method(); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed +} diff --git a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr new file mode 100644 index 00000000000..65f2d99417f --- /dev/null +++ b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr @@ -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 for B {} + | ^^^^^^^^^^^^^^^^^ +LL | impl I for B {} + | ^^^^^^^^^^^^^^^^^ +note: required because of the requirements on the impl of `V<_>` for `A` + --> $DIR/not-suggest-non-existing-fully-qualified-path.rs:12:12 + | +LL | impl V for A + | ^^^^ ^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0283. +For more information about an error, try `rustc --explain E0282`.