@@ -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 ;
@@ -358,11 +356,14 @@ fn suggest_restriction<'tcx>(
358
356
ty:: Param ( param) => {
359
357
// `fn foo(t: impl Trait)`
360
358
// ^^^^^ 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) )
362
360
}
363
361
_ => None ,
364
362
} )
365
363
{
364
+ if !trait_pred. is_suggestable_modulo_impl_trait ( tcx, & bound_str) {
365
+ return ;
366
+ }
366
367
// We know we have an `impl Trait` that doesn't satisfy a required projection.
367
368
368
369
// Find all of the occurrences of `impl Trait` for `Trait` in the function arguments'
@@ -417,6 +418,9 @@ fn suggest_restriction<'tcx>(
417
418
Applicability :: MaybeIncorrect ,
418
419
) ;
419
420
} else {
421
+ if !trait_pred. is_suggestable ( tcx) {
422
+ return ;
423
+ }
420
424
// Trivial case: `T` needs an extra bound: `T: Bound`.
421
425
let ( sp, suggestion) = match (
422
426
generics
@@ -463,16 +467,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
463
467
_ => ( false , None ) ,
464
468
} ;
465
469
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
-
476
470
// FIXME: Add check for trait bound that is already present, particularly `?Sized` so we
477
471
// don't suggest `T: Sized + ?Sized`.
478
472
let mut hir_id = body_id;
@@ -574,6 +568,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
574
568
| hir:: Node :: ImplItem ( hir:: ImplItem { generics, .. } )
575
569
if param_ty =>
576
570
{
571
+ if !trait_pred. skip_binder ( ) . trait_ref . substs [ 1 ..]
572
+ . iter ( )
573
+ . all ( |g| g. is_suggestable ( self . tcx ) )
574
+ {
575
+ return ;
576
+ }
577
577
// Missing generic type parameter bound.
578
578
let param_name = self_ty. to_string ( ) ;
579
579
let constraint = with_no_trimmed_paths ! (
@@ -603,13 +603,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
603
603
| hir:: ItemKind :: TraitAlias ( generics, _)
604
604
| hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy { generics, .. } ) ,
605
605
..
606
- } ) if !param_ty
607
- && !generic_args_have_impl_trait ( trait_pred. skip_binder ( ) . trait_ref . substs ) =>
608
- {
606
+ } ) if !param_ty => {
609
607
// 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) {
613
609
return ;
614
610
}
615
611
}
0 commit comments