@@ -125,7 +125,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
125
125
// on a trait we need to add in the supertrait bounds and bounds found on
126
126
// associated types.
127
127
if let Some ( _trait_ref) = is_trait {
128
- predicates. extend ( tcx. super_predicates_of ( def_id) . predicates . iter ( ) . cloned ( ) ) ;
128
+ predicates. extend ( tcx. implied_predicates_of ( def_id) . predicates . iter ( ) . cloned ( ) ) ;
129
129
}
130
130
131
131
// In default impls, we can assume that the self type implements
@@ -534,31 +534,62 @@ pub(super) fn explicit_predicates_of<'tcx>(
534
534
}
535
535
}
536
536
537
+ #[ derive( Copy , Clone , Debug ) ]
538
+ pub enum PredicateFilter {
539
+ /// All predicates may be implied by the trait
540
+ All ,
541
+
542
+ /// Only traits that reference `Self: ..` are implied by the trait
543
+ SelfOnly ,
544
+
545
+ /// Only traits that reference `Self: ..` and define an associated type
546
+ /// with the given ident are implied by the trait
547
+ SelfThatDefines ( Ident ) ,
548
+ }
549
+
537
550
/// Ensures that the super-predicates of the trait with a `DefId`
538
551
/// of `trait_def_id` are converted and stored. This also ensures that
539
552
/// the transitive super-predicates are converted.
540
553
pub ( super ) fn super_predicates_of (
541
554
tcx : TyCtxt < ' _ > ,
542
555
trait_def_id : LocalDefId ,
543
556
) -> ty:: GenericPredicates < ' _ > {
544
- tcx. super_predicates_that_define_assoc_type ( ( trait_def_id. to_def_id ( ) , None ) )
557
+ implied_predicates_with_filter ( tcx, trait_def_id. to_def_id ( ) , PredicateFilter :: SelfOnly )
558
+ }
559
+
560
+ pub ( super ) fn super_predicates_that_define_assoc_type (
561
+ tcx : TyCtxt < ' _ > ,
562
+ ( trait_def_id, assoc_name) : ( DefId , Ident ) ,
563
+ ) -> ty:: GenericPredicates < ' _ > {
564
+ implied_predicates_with_filter ( tcx, trait_def_id, PredicateFilter :: SelfThatDefines ( assoc_name) )
565
+ }
566
+
567
+ pub ( super ) fn implied_predicates_of (
568
+ tcx : TyCtxt < ' _ > ,
569
+ trait_def_id : LocalDefId ,
570
+ ) -> ty:: GenericPredicates < ' _ > {
571
+ if tcx. is_trait_alias ( trait_def_id. to_def_id ( ) ) {
572
+ implied_predicates_with_filter ( tcx, trait_def_id. to_def_id ( ) , PredicateFilter :: All )
573
+ } else {
574
+ tcx. super_predicates_of ( trait_def_id)
575
+ }
545
576
}
546
577
547
578
/// Ensures that the super-predicates of the trait with a `DefId`
548
579
/// of `trait_def_id` are converted and stored. This also ensures that
549
580
/// the transitive super-predicates are converted.
550
- pub ( super ) fn super_predicates_that_define_assoc_type (
581
+ pub ( super ) fn implied_predicates_with_filter (
551
582
tcx : TyCtxt < ' _ > ,
552
- ( trait_def_id, assoc_name) : ( DefId , Option < Ident > ) ,
583
+ trait_def_id : DefId ,
584
+ filter : PredicateFilter ,
553
585
) -> ty:: GenericPredicates < ' _ > {
554
586
let Some ( trait_def_id) = trait_def_id. as_local ( ) else {
555
587
// if `assoc_name` is None, then the query should've been redirected to an
556
588
// external provider
557
- assert ! ( assoc_name . is_some ( ) ) ;
589
+ assert ! ( matches! ( filter , PredicateFilter :: SelfThatDefines ( _ ) ) ) ;
558
590
return tcx. super_predicates_of ( trait_def_id) ;
559
591
} ;
560
592
561
- debug ! ( "local trait" ) ;
562
593
let trait_hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( trait_def_id) ;
563
594
564
595
let Node :: Item ( item) = tcx. hir ( ) . get ( trait_hir_id) else {
@@ -573,48 +604,66 @@ pub(super) fn super_predicates_that_define_assoc_type(
573
604
574
605
let icx = ItemCtxt :: new ( tcx, trait_def_id) ;
575
606
576
- // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
577
607
let self_param_ty = tcx. types . self_param ;
578
- let superbounds1 = if let Some ( assoc_name) = assoc_name {
579
- icx. astconv ( ) . compute_bounds_that_match_assoc_type ( self_param_ty, bounds, assoc_name)
580
- } else {
581
- icx. astconv ( ) . compute_bounds ( self_param_ty, bounds)
608
+ let ( superbounds, where_bounds_that_match) = match filter {
609
+ PredicateFilter :: All => (
610
+ // Convert the bounds that follow the colon (or equal in trait aliases)
611
+ icx. astconv ( ) . compute_bounds ( self_param_ty, bounds) ,
612
+ // Also include all where clause bounds
613
+ icx. type_parameter_bounds_in_generics (
614
+ generics,
615
+ item. owner_id . def_id ,
616
+ self_param_ty,
617
+ OnlySelfBounds ( false ) ,
618
+ None ,
619
+ ) ,
620
+ ) ,
621
+ PredicateFilter :: SelfOnly => (
622
+ // Convert the bounds that follow the colon (or equal in trait aliases)
623
+ icx. astconv ( ) . compute_bounds ( self_param_ty, bounds) ,
624
+ // Include where clause bounds for `Self`
625
+ icx. type_parameter_bounds_in_generics (
626
+ generics,
627
+ item. owner_id . def_id ,
628
+ self_param_ty,
629
+ OnlySelfBounds ( true ) ,
630
+ None ,
631
+ ) ,
632
+ ) ,
633
+ PredicateFilter :: SelfThatDefines ( assoc_name) => (
634
+ // Convert the bounds that follow the colon (or equal) that reference the associated name
635
+ icx. astconv ( ) . compute_bounds_that_match_assoc_type ( self_param_ty, bounds, assoc_name) ,
636
+ // Include where clause bounds for `Self` that reference the associated name
637
+ icx. type_parameter_bounds_in_generics (
638
+ generics,
639
+ item. owner_id . def_id ,
640
+ self_param_ty,
641
+ OnlySelfBounds ( true ) ,
642
+ Some ( assoc_name) ,
643
+ ) ,
644
+ ) ,
582
645
} ;
583
646
584
- let superbounds1 = superbounds1. predicates ( ) ;
585
-
586
- // Convert any explicit superbounds in the where-clause,
587
- // e.g., `trait Foo where Self: Bar`.
588
- // In the case of trait aliases, however, we include all bounds in the where-clause,
589
- // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
590
- // as one of its "superpredicates".
591
- let is_trait_alias = tcx. is_trait_alias ( trait_def_id. to_def_id ( ) ) ;
592
- let superbounds2 = icx. type_parameter_bounds_in_generics (
593
- generics,
594
- item. owner_id . def_id ,
595
- self_param_ty,
596
- OnlySelfBounds ( !is_trait_alias) ,
597
- assoc_name,
598
- ) ;
599
-
600
647
// Combine the two lists to form the complete set of superbounds:
601
- let superbounds = & * tcx. arena . alloc_from_iter ( superbounds1. into_iter ( ) . chain ( superbounds2) ) ;
602
- debug ! ( ?superbounds) ;
648
+ let implied_bounds = & * tcx
649
+ . arena
650
+ . alloc_from_iter ( superbounds. predicates ( ) . into_iter ( ) . chain ( where_bounds_that_match) ) ;
651
+ debug ! ( ?implied_bounds) ;
603
652
604
653
// Now require that immediate supertraits are converted,
605
654
// which will, in turn, reach indirect supertraits.
606
- if assoc_name . is_none ( ) {
655
+ if matches ! ( filter , PredicateFilter :: SelfOnly ) {
607
656
// Now require that immediate supertraits are converted,
608
657
// which will, in turn, reach indirect supertraits.
609
- for & ( pred, span) in superbounds {
658
+ for & ( pred, span) in implied_bounds {
610
659
debug ! ( "superbound: {:?}" , pred) ;
611
660
if let ty:: PredicateKind :: Clause ( ty:: Clause :: Trait ( bound) ) = pred. kind ( ) . skip_binder ( ) {
612
661
tcx. at ( span) . super_predicates_of ( bound. def_id ( ) ) ;
613
662
}
614
663
}
615
664
}
616
665
617
- ty:: GenericPredicates { parent : None , predicates : superbounds }
666
+ ty:: GenericPredicates { parent : None , predicates : implied_bounds }
618
667
}
619
668
620
669
/// Returns the predicates defined on `item_def_id` of the form
0 commit comments