@@ -21,11 +21,9 @@ use rustc_hir::lang_items::LangItem;
21
21
use rustc_hir:: { AsyncGeneratorKind , GeneratorKind , Node } ;
22
22
use rustc_middle:: hir:: map;
23
23
use 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 ,
29
27
} ;
30
28
use rustc_middle:: ty:: { TypeAndMut , TypeckResults } ;
31
29
use rustc_session:: Limit ;
@@ -356,11 +354,14 @@ fn suggest_restriction<'tcx>(
356
354
ty:: Param ( param) => {
357
355
// `fn foo(t: impl Trait)`
358
356
// ^^^^^ 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) )
360
358
}
361
359
_ => None ,
362
360
} )
363
361
{
362
+ if !trait_pred. is_suggestable_modulo_impl_trait ( tcx, & bound_str) {
363
+ return ;
364
+ }
364
365
// We know we have an `impl Trait` that doesn't satisfy a required projection.
365
366
366
367
// Find all of the occurrences of `impl Trait` for `Trait` in the function arguments'
@@ -415,6 +416,9 @@ fn suggest_restriction<'tcx>(
415
416
Applicability :: MaybeIncorrect ,
416
417
) ;
417
418
} else {
419
+ if !trait_pred. is_suggestable ( tcx) {
420
+ return ;
421
+ }
418
422
// Trivial case: `T` needs an extra bound: `T: Bound`.
419
423
let ( sp, suggestion) = match (
420
424
generics
@@ -461,16 +465,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
461
465
_ => ( false , None ) ,
462
466
} ;
463
467
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
-
474
468
// FIXME: Add check for trait bound that is already present, particularly `?Sized` so we
475
469
// don't suggest `T: Sized + ?Sized`.
476
470
let mut hir_id = body_id;
@@ -572,6 +566,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
572
566
| hir:: Node :: ImplItem ( hir:: ImplItem { generics, .. } )
573
567
if param_ty =>
574
568
{
569
+ if !trait_pred. skip_binder ( ) . trait_ref . substs [ 1 ..]
570
+ . iter ( )
571
+ . all ( |g| g. is_suggestable ( self . tcx ) )
572
+ {
573
+ return ;
574
+ }
575
575
// Missing generic type parameter bound.
576
576
let param_name = self_ty. to_string ( ) ;
577
577
let constraint = with_no_trimmed_paths ! (
@@ -601,13 +601,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
601
601
| hir:: ItemKind :: TraitAlias ( generics, _)
602
602
| hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy { generics, .. } ) ,
603
603
..
604
- } ) if !param_ty
605
- && !generic_args_have_impl_trait ( trait_pred. skip_binder ( ) . trait_ref . substs ) =>
606
- {
604
+ } ) if !param_ty => {
607
605
// 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) {
611
607
return ;
612
608
}
613
609
}
0 commit comments