@@ -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 ;
@@ -356,11 +354,14 @@ fn suggest_restriction<'tcx>(
356354 ty:: Param ( param) => {
357355 // `fn foo(t: impl Trait)`
358356 // ^^^^^ get this string
359- param. name . as_str ( ) . strip_prefix ( "impl" ) . map ( |s| ( s. trim_start ( ) . to_string ( ) , sig) )
357+ param. name . as_str ( ) . strip_prefix ( "impl " ) . map ( |s| ( s. trim_start ( ) . to_string ( ) , sig) )
360358 }
361359 _ => None ,
362360 } )
363361 {
362+ if !trait_pred. is_suggestable_modulo_impl_trait ( tcx, & bound_str) {
363+ return ;
364+ }
364365 // We know we have an `impl Trait` that doesn't satisfy a required projection.
365366
366367 // Find all of the occurrences of `impl Trait` for `Trait` in the function arguments'
@@ -415,6 +416,9 @@ fn suggest_restriction<'tcx>(
415416 Applicability :: MaybeIncorrect ,
416417 ) ;
417418 } else {
419+ if !trait_pred. is_suggestable ( tcx) {
420+ return ;
421+ }
418422 // Trivial case: `T` needs an extra bound: `T: Bound`.
419423 let ( sp, suggestion) = match (
420424 generics
@@ -461,16 +465,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
461465 _ => ( false , None ) ,
462466 } ;
463467
464- let generic_args_have_impl_trait = |args : SubstsRef < ' tcx > | -> bool {
465- args. iter ( ) . any ( |arg| match arg. unpack ( ) {
466- GenericArgKind :: Type ( ty) => match ty. kind ( ) {
467- ty:: Param ( param) => param. name . as_str ( ) . starts_with ( "impl" ) ,
468- _ => false ,
469- } ,
470- _ => false ,
471- } )
472- } ;
473-
474468 // FIXME: Add check for trait bound that is already present, particularly `?Sized` so we
475469 // don't suggest `T: Sized + ?Sized`.
476470 let mut hir_id = body_id;
@@ -572,6 +566,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
572566 | hir:: Node :: ImplItem ( hir:: ImplItem { generics, .. } )
573567 if param_ty =>
574568 {
569+ if !trait_pred. skip_binder ( ) . trait_ref . substs [ 1 ..]
570+ . iter ( )
571+ . all ( |g| g. is_suggestable ( self . tcx ) )
572+ {
573+ return ;
574+ }
575575 // Missing generic type parameter bound.
576576 let param_name = self_ty. to_string ( ) ;
577577 let constraint = with_no_trimmed_paths ! (
@@ -601,13 +601,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
601601 | hir:: ItemKind :: TraitAlias ( generics, _)
602602 | hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy { generics, .. } ) ,
603603 ..
604- } ) if !param_ty
605- && !generic_args_have_impl_trait ( trait_pred. skip_binder ( ) . trait_ref . substs ) =>
606- {
604+ } ) if !param_ty => {
607605 // Missing generic type parameter bound.
608- let param_name = self_ty. to_string ( ) ;
609- let constraint = trait_pred. print_modifiers_and_trait_path ( ) . to_string ( ) ;
610- if suggest_arbitrary_trait_bound ( generics, & mut err, & param_name, & constraint) {
606+ if suggest_arbitrary_trait_bound ( self . tcx , generics, & mut err, trait_pred) {
611607 return ;
612608 }
613609 }
0 commit comments