about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-08-03 13:23:31 +0000
committerbors <bors@rust-lang.org>2021-08-03 13:23:31 +0000
commitd5fd37f00f1ec5e4a4b0d87f5af0b93f36aab271 (patch)
tree7d3d9a9d7e67c6a10ad608d9a75ac650e3cbbb5f
parent2939249f294dd54a9ce78a8ee1f2922a44e7fb7c (diff)
parentb84d08d1e46df54ee3a2729296697e0b1ecc6097 (diff)
downloadrust-d5fd37f00f1ec5e4a4b0d87f5af0b93f36aab271.tar.gz
rust-d5fd37f00f1ec5e4a4b0d87f5af0b93f36aab271.zip
Auto merge of #86338 - JohnTitor:issue-86162, r=estebank
Do not suggest impl traits as type arguments

Fixes #86162
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs20
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_typeck/src/astconv/generics.rs12
-rw-r--r--src/test/ui/inference/issue-86162-1.rs9
-rw-r--r--src/test/ui/inference/issue-86162-1.stderr14
-rw-r--r--src/test/ui/inference/issue-86162-2.rs14
-rw-r--r--src/test/ui/inference/issue-86162-2.stderr14
8 files changed, 72 insertions, 27 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 a15eecd2414..c2025f3fe4d 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
@@ -753,23 +753,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             if let (UnderspecifiedArgKind::Const { .. }, Some(parent_data)) =
                 (&arg_data.kind, &arg_data.parent)
             {
-                let has_impl_trait =
-                    self.tcx.generics_of(parent_data.def_id).params.iter().any(|param| {
-                        matches!(
-                            param.kind,
-                            ty::GenericParamDefKind::Type {
-                                synthetic: Some(
-                                    hir::SyntheticTyParamKind::ImplTrait
-                                        | hir::SyntheticTyParamKind::FromAttr,
-                                ),
-                                ..
-                            }
-                        )
-                    });
-
                 // (#83606): Do not emit a suggestion if the parent has an `impl Trait`
                 // as an argument otherwise it will cause the E0282 error.
-                if !has_impl_trait || self.tcx.features().explicit_generic_args_with_impl_trait {
+                if !self.tcx.generics_of(parent_data.def_id).has_impl_trait()
+                    || self.tcx.features().explicit_generic_args_with_impl_trait
+                {
                     err.span_suggestion_verbose(
                         span,
                         "consider specifying the const argument",
@@ -814,7 +802,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             let borrow = typeck_results.borrow();
             if let Some((DefKind::AssocFn, did)) = borrow.type_dependent_def(e.hir_id) {
                 let generics = self.tcx.generics_of(did);
-                if !generics.params.is_empty() {
+                if !generics.params.is_empty() && !generics.has_impl_trait() {
                     err.span_suggestion_verbose(
                         segment.ident.span.shrink_to_hi(),
                         &format!(
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 4e3f475a915..0f89581ae66 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -198,6 +198,21 @@ impl<'tcx> Generics {
             _ => bug!("expected const parameter, but found another generic parameter"),
         }
     }
+
+    /// Returns `true` if `params` has `impl Trait`.
+    pub fn has_impl_trait(&'tcx self) -> bool {
+        self.params.iter().any(|param| {
+            matches!(
+                param.kind,
+                ty::GenericParamDefKind::Type {
+                    synthetic: Some(
+                        hir::SyntheticTyParamKind::ImplTrait | hir::SyntheticTyParamKind::FromAttr,
+                    ),
+                    ..
+                }
+            )
+        })
+    }
 }
 
 /// Bounds on generics.
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index c134af44992..f46fae1326c 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1603,6 +1603,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
                     let generics = self.tcx.generics_of(*def_id);
                     if generics.params.iter().any(|p| p.name != kw::SelfUpper)
                         && !snippet.ends_with('>')
+                        && !generics.has_impl_trait()
                     {
                         // FIXME: To avoid spurious suggestions in functions where type arguments
                         // where already supplied, we check the snippet to make sure it doesn't
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index 9e700d9e8d8..0cfdde26c2b 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -647,17 +647,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             return false;
         }
 
-        let impl_trait = generics.params.iter().any(|param| {
-            matches!(
-                param.kind,
-                ty::GenericParamDefKind::Type {
-                    synthetic: Some(
-                        hir::SyntheticTyParamKind::ImplTrait | hir::SyntheticTyParamKind::FromAttr,
-                    ),
-                    ..
-                }
-            )
-        });
+        let impl_trait = generics.has_impl_trait();
 
         if impl_trait {
             let spans = seg
diff --git a/src/test/ui/inference/issue-86162-1.rs b/src/test/ui/inference/issue-86162-1.rs
new file mode 100644
index 00000000000..5a547eb38d1
--- /dev/null
+++ b/src/test/ui/inference/issue-86162-1.rs
@@ -0,0 +1,9 @@
+// Regression test of #86162.
+
+fn foo(x: impl Clone) {}
+fn gen<T>() -> T { todo!() }
+
+fn main() {
+    foo(gen()); //<- Do not suggest `foo::<impl Clone>()`!
+    //~^ ERROR: type annotations needed
+}
diff --git a/src/test/ui/inference/issue-86162-1.stderr b/src/test/ui/inference/issue-86162-1.stderr
new file mode 100644
index 00000000000..f4e2161d7b8
--- /dev/null
+++ b/src/test/ui/inference/issue-86162-1.stderr
@@ -0,0 +1,14 @@
+error[E0283]: type annotations needed
+  --> $DIR/issue-86162-1.rs:7:5
+   |
+LL | fn foo(x: impl Clone) {}
+   |                ----- required by this bound in `foo`
+...
+LL |     foo(gen()); //<- Do not suggest `foo::<impl Clone>()`!
+   |     ^^^ cannot infer type for type parameter `impl Clone` declared on the function `foo`
+   |
+   = note: cannot satisfy `_: Clone`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/src/test/ui/inference/issue-86162-2.rs b/src/test/ui/inference/issue-86162-2.rs
new file mode 100644
index 00000000000..b8c75dd7728
--- /dev/null
+++ b/src/test/ui/inference/issue-86162-2.rs
@@ -0,0 +1,14 @@
+// Regression test of #86162.
+
+fn gen<T>() -> T { todo!() }
+
+struct Foo;
+
+impl Foo {
+    fn bar(x: impl Clone) {}
+}
+
+fn main() {
+    Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
+    //~^ ERROR: type annotations needed
+}
diff --git a/src/test/ui/inference/issue-86162-2.stderr b/src/test/ui/inference/issue-86162-2.stderr
new file mode 100644
index 00000000000..19f741e1cf6
--- /dev/null
+++ b/src/test/ui/inference/issue-86162-2.stderr
@@ -0,0 +1,14 @@
+error[E0283]: type annotations needed
+  --> $DIR/issue-86162-2.rs:12:5
+   |
+LL |     fn bar(x: impl Clone) {}
+   |                    ----- required by this bound in `Foo::bar`
+...
+LL |     Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
+   |     ^^^^^^^^ cannot infer type for type parameter `impl Clone` declared on the associated function `bar`
+   |
+   = note: cannot satisfy `_: Clone`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.