about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <yuki.okushi@huawei.com>2021-06-16 06:32:22 +0900
committerYuki Okushi <yuki.okushi@huawei.com>2021-08-03 20:05:50 +0900
commit14e92d71160348d22ece30624b0843178cee23f1 (patch)
tree0ccc1daf7e794c2192351ede39236d642557c900
parent3354a44d2fa8d5ba6b8d6b40d2596de2c8292ec1 (diff)
downloadrust-14e92d71160348d22ece30624b0843178cee23f1.tar.gz
rust-14e92d71160348d22ece30624b0843178cee23f1.zip
Do not suggest impl traits as type arguments
-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--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
7 files changed, 71 insertions, 16 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/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`.