From 28988902a2d1410ff2f8f13bb146420a128c5754 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda <41065217+TaKO8Ki@users.noreply.github.com> Date: Thu, 2 Jun 2022 20:50:01 +0900 Subject: [PATCH] fix wrong suggestion for adding where clauses --- .../src/traits/error_reporting/suggestions.rs | 18 ++++++++++++++++-- src/test/ui/traits/issue-97576.rs | 13 +++++++++++++ src/test/ui/traits/issue-97576.stderr | 11 +++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/traits/issue-97576.rs create mode 100644 src/test/ui/traits/issue-97576.stderr 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` 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` is not satisfied + --> $DIR/issue-97576.rs:8:22 + | +LL | bar: bar.into(), + | ^^^^ the trait `From` is not implemented for `String` + | + = note: required because of the requirements on the impl of `Into` for `impl ToString` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.