@@ -21,11 +21,9 @@ use rustc_hir::lang_items::LangItem;
2121use rustc_hir:: { AsyncGeneratorKind , GeneratorKind , Node } ;
2222use rustc_middle:: hir:: map;
2323use rustc_middle:: ty:: {
24- self ,
25- subst:: { GenericArgKind , SubstsRef } ,
26- suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind , DefIdTree ,
27- GeneratorDiagnosticData , GeneratorInteriorTypeCause , Infer , InferTy , ToPredicate , Ty , TyCtxt ,
28- TypeFoldable ,
24+ self , suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind , DefIdTree ,
25+ GeneratorDiagnosticData , GeneratorInteriorTypeCause , Infer , InferTy , IsSuggestable ,
26+ ToPredicate , Ty , TyCtxt , TypeFoldable ,
2927} ;
3028use rustc_middle:: ty:: { TypeAndMut , TypeckResults } ;
3129use rustc_session:: Limit ;
@@ -358,11 +356,14 @@ fn suggest_restriction<'tcx>(
358356 ty:: Param ( param) => {
359357 // `fn foo(t: impl Trait)`
360358 // ^^^^^ get this string
361- param. name . as_str ( ) . strip_prefix ( "impl" ) . map ( |s| ( s. trim_start ( ) . to_string ( ) , sig) )
359+ param. name . as_str ( ) . strip_prefix ( "impl " ) . map ( |s| ( s. trim_start ( ) . to_string ( ) , sig) )
362360 }
363361 _ => None ,
364362 } )
365363 {
364+ if !trait_pred. is_suggestable_modulo_impl_trait ( tcx, & bound_str) {
365+ return ;
366+ }
366367 // We know we have an `impl Trait` that doesn't satisfy a required projection.
367368
368369 // Find all of the occurrences of `impl Trait` for `Trait` in the function arguments'
@@ -417,6 +418,9 @@ fn suggest_restriction<'tcx>(
417418 Applicability :: MaybeIncorrect ,
418419 ) ;
419420 } else {
421+ if !trait_pred. is_suggestable ( tcx) {
422+ return ;
423+ }
420424 // Trivial case: `T` needs an extra bound: `T: Bound`.
421425 let ( sp, suggestion) = match (
422426 generics
@@ -463,16 +467,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
463467 _ => ( false , None ) ,
464468 } ;
465469
466- let generic_args_have_impl_trait = |args : SubstsRef < ' tcx > | -> bool {
467- args. iter ( ) . any ( |arg| match arg. unpack ( ) {
468- GenericArgKind :: Type ( ty) => match ty. kind ( ) {
469- ty:: Param ( param) => param. name . as_str ( ) . starts_with ( "impl" ) ,
470- _ => false ,
471- } ,
472- _ => false ,
473- } )
474- } ;
475-
476470 // FIXME: Add check for trait bound that is already present, particularly `?Sized` so we
477471 // don't suggest `T: Sized + ?Sized`.
478472 let mut hir_id = body_id;
@@ -574,6 +568,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
574568 | hir:: Node :: ImplItem ( hir:: ImplItem { generics, .. } )
575569 if param_ty =>
576570 {
571+ if !trait_pred. skip_binder ( ) . trait_ref . substs [ 1 ..]
572+ . iter ( )
573+ . all ( |g| g. is_suggestable ( self . tcx ) )
574+ {
575+ return ;
576+ }
577577 // Missing generic type parameter bound.
578578 let param_name = self_ty. to_string ( ) ;
579579 let constraint = with_no_trimmed_paths ! (
@@ -603,13 +603,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
603603 | hir:: ItemKind :: TraitAlias ( generics, _)
604604 | hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy { generics, .. } ) ,
605605 ..
606- } ) if !param_ty
607- && !generic_args_have_impl_trait ( trait_pred. skip_binder ( ) . trait_ref . substs ) =>
608- {
606+ } ) if !param_ty => {
609607 // Missing generic type parameter bound.
610- let param_name = self_ty. to_string ( ) ;
611- let constraint = trait_pred. print_modifiers_and_trait_path ( ) . to_string ( ) ;
612- if suggest_arbitrary_trait_bound ( generics, & mut err, & param_name, & constraint) {
608+ if suggest_arbitrary_trait_bound ( self . tcx , generics, & mut err, trait_pred) {
613609 return ;
614610 }
615611 }
0 commit comments