about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTakayuki Maeda <41065217+TaKO8Ki@users.noreply.github.com>2022-05-11 19:18:02 +0900
committerTakayuki Maeda <41065217+TaKO8Ki@users.noreply.github.com>2022-05-11 19:18:02 +0900
commitdaeec7e22de6a99a5440ddf401f3fc16756cd64a (patch)
treef2bc4c636631782bf0b1cc9488d8328f34d6eb13
parentcb121987158d69bb894ba1bcc21dc45d1e0a488f (diff)
downloadrust-daeec7e22de6a99a5440ddf401f3fc16756cd64a.tar.gz
rust-daeec7e22de6a99a5440ddf401f3fc16756cd64a.zip
stop suggesting non-existing fully qualified paths
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs27
-rw-r--r--src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.rs24
-rw-r--r--src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr35
3 files changed, 75 insertions, 11 deletions
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>(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
+}
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<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`.