about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTakayuki Maeda <41065217+TaKO8Ki@users.noreply.github.com>2022-06-02 20:50:01 +0900
committerTakayuki Maeda <41065217+TaKO8Ki@users.noreply.github.com>2022-06-02 20:50:01 +0900
commit28988902a2d1410ff2f8f13bb146420a128c5754 (patch)
tree158cdb1ec9dcac19dd43301da28a362e78f411bd
parente838059d66296a3874e85685637aac10c888b240 (diff)
downloadrust-28988902a2d1410ff2f8f13bb146420a128c5754.tar.gz
rust-28988902a2d1410ff2f8f13bb146420a128c5754.zip
fix wrong suggestion for adding where clauses
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs18
-rw-r--r--src/test/ui/traits/issue-97576.rs13
-rw-r--r--src/test/ui/traits/issue-97576.stderr11
3 files changed, 40 insertions, 2 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index a51e6e58f67..d0f20022bfb 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -21,7 +21,9 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
 use rustc_middle::hir::map;
 use rustc_middle::ty::{
-    self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
+    self,
+    subst::{GenericArgKind, SubstsRef},
+    suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
     GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, ToPredicate, Ty, TyCtxt,
     TypeFoldable,
 };
@@ -458,6 +460,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             _ => (false, None),
         };
 
+        let generic_args_have_impl_trait = |args: SubstsRef<'tcx>| -> bool {
+            args.iter().any(|arg| match arg.unpack() {
+                GenericArgKind::Type(ty) => match ty.kind() {
+                    ty::Param(param) => param.name.as_str().starts_with("impl"),
+                    _ => false,
+                },
+                _ => false,
+            })
+        };
+
         // FIXME: Add check for trait bound that is already present, particularly `?Sized` so we
         //        don't suggest `T: Sized + ?Sized`.
         let mut hir_id = body_id;
@@ -588,7 +600,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         | hir::ItemKind::TraitAlias(generics, _)
                         | hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }),
                     ..
-                }) if !param_ty => {
+                }) if !param_ty
+                    && !generic_args_have_impl_trait(trait_pred.skip_binder().trait_ref.substs) =>
+                {
                     // Missing generic type parameter bound.
                     let param_name = self_ty.to_string();
                     let constraint = trait_pred.print_modifiers_and_trait_path().to_string();
diff --git a/src/test/ui/traits/issue-97576.rs b/src/test/ui/traits/issue-97576.rs
new file mode 100644
index 00000000000..fdc85e9fa89
--- /dev/null
+++ b/src/test/ui/traits/issue-97576.rs
@@ -0,0 +1,13 @@
+struct Foo {
+    bar: String,
+}
+
+impl Foo {
+    pub fn new(bar: impl ToString) -> Self {
+        Self {
+            bar: bar.into(), //~ ERROR the trait bound `String: From<impl ToString>` is not satisfied
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/issue-97576.stderr b/src/test/ui/traits/issue-97576.stderr
new file mode 100644
index 00000000000..bdee073d6e3
--- /dev/null
+++ b/src/test/ui/traits/issue-97576.stderr
@@ -0,0 +1,11 @@
+error[E0277]: the trait bound `String: From<impl ToString>` is not satisfied
+  --> $DIR/issue-97576.rs:8:22
+   |
+LL |             bar: bar.into(),
+   |                      ^^^^ the trait `From<impl ToString>` is not implemented for `String`
+   |
+   = note: required because of the requirements on the impl of `Into<String>` for `impl ToString`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.