@@ -532,15 +532,20 @@ pub(super) fn explicit_predicates_of<'tcx>(
532532
533533#[ derive( Copy , Clone , Debug ) ]
534534pub enum PredicateFilter {
535- /// All predicates may be implied by the trait
535+ /// All predicates may be implied by the trait.
536536 All ,
537537
538- /// Only traits that reference `Self: ..` are implied by the trait
538+ /// Only traits that reference `Self: ..` are implied by the trait.
539539 SelfOnly ,
540540
541541 /// Only traits that reference `Self: ..` and define an associated type
542- /// with the given ident are implied by the trait
542+ /// with the given ident are implied by the trait.
543543 SelfThatDefines ( Ident ) ,
544+
545+ /// Only traits that reference `Self: ..` and their associated type bounds.
546+ /// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
547+ /// and `<Self as Tr>::A: B`.
548+ SelfAndAssociatedTypeBounds ,
544549}
545550
546551/// Ensures that the super-predicates of the trait with a `DefId`
@@ -564,11 +569,15 @@ pub(super) fn implied_predicates_of(
564569 tcx : TyCtxt < ' _ > ,
565570 trait_def_id : LocalDefId ,
566571) -> ty:: GenericPredicates < ' _ > {
567- if tcx. is_trait_alias ( trait_def_id. to_def_id ( ) ) {
568- implied_predicates_with_filter ( tcx, trait_def_id. to_def_id ( ) , PredicateFilter :: All )
569- } else {
570- tcx. super_predicates_of ( trait_def_id)
571- }
572+ implied_predicates_with_filter (
573+ tcx,
574+ trait_def_id. to_def_id ( ) ,
575+ if tcx. is_trait_alias ( trait_def_id. to_def_id ( ) ) {
576+ PredicateFilter :: All
577+ } else {
578+ PredicateFilter :: SelfAndAssociatedTypeBounds
579+ } ,
580+ )
572581}
573582
574583/// Ensures that the super-predicates of the trait with a `DefId`
@@ -601,45 +610,28 @@ pub(super) fn implied_predicates_with_filter(
601610 let icx = ItemCtxt :: new ( tcx, trait_def_id) ;
602611
603612 let self_param_ty = tcx. types . self_param ;
604- let ( superbounds, where_bounds_that_match) = match filter {
605- PredicateFilter :: All => (
606- // Convert the bounds that follow the colon (or equal in trait aliases)
607- icx. astconv ( ) . compute_bounds ( self_param_ty, bounds, OnlySelfBounds ( false ) ) ,
608- // Also include all where clause bounds
609- icx. type_parameter_bounds_in_generics (
610- generics,
611- item. owner_id . def_id ,
612- self_param_ty,
613- OnlySelfBounds ( false ) ,
614- None ,
615- ) ,
616- ) ,
617- PredicateFilter :: SelfOnly => (
618- // Convert the bounds that follow the colon (or equal in trait aliases)
619- icx. astconv ( ) . compute_bounds ( self_param_ty, bounds, OnlySelfBounds ( true ) ) ,
620- // Include where clause bounds for `Self`
621- icx. type_parameter_bounds_in_generics (
622- generics,
623- item. owner_id . def_id ,
624- self_param_ty,
625- OnlySelfBounds ( true ) ,
626- None ,
627- ) ,
628- ) ,
629- PredicateFilter :: SelfThatDefines ( assoc_name) => (
630- // Convert the bounds that follow the colon (or equal) that reference the associated name
631- icx. astconv ( ) . compute_bounds_that_match_assoc_item ( self_param_ty, bounds, assoc_name) ,
632- // Include where clause bounds for `Self` that reference the associated name
633- icx. type_parameter_bounds_in_generics (
634- generics,
635- item. owner_id . def_id ,
636- self_param_ty,
637- OnlySelfBounds ( true ) ,
638- Some ( assoc_name) ,
639- ) ,
640- ) ,
613+ let superbounds = match filter {
614+ // Should imply both "real" supertraits, and also associated type bounds
615+ // from the supertraits position.
616+ PredicateFilter :: All | PredicateFilter :: SelfAndAssociatedTypeBounds => {
617+ icx. astconv ( ) . compute_bounds ( self_param_ty, bounds, OnlySelfBounds ( false ) )
618+ }
619+ // Should only imply "real" supertraits, i.e. predicates with the self type `Self`.
620+ PredicateFilter :: SelfOnly => {
621+ icx. astconv ( ) . compute_bounds ( self_param_ty, bounds, OnlySelfBounds ( true ) )
622+ }
623+ PredicateFilter :: SelfThatDefines ( assoc_name) => {
624+ icx. astconv ( ) . compute_bounds_that_match_assoc_item ( self_param_ty, bounds, assoc_name)
625+ }
641626 } ;
642627
628+ let where_bounds_that_match = icx. type_parameter_bounds_in_generics (
629+ generics,
630+ item. owner_id . def_id ,
631+ self_param_ty,
632+ filter,
633+ ) ;
634+
643635 // Combine the two lists to form the complete set of superbounds:
644636 let implied_bounds =
645637 & * tcx. arena . alloc_from_iter ( superbounds. clauses ( ) . chain ( where_bounds_that_match) ) ;
@@ -743,8 +735,7 @@ pub(super) fn type_param_predicates(
743735 ast_generics,
744736 def_id,
745737 ty,
746- OnlySelfBounds ( true ) ,
747- Some ( assoc_name) ,
738+ PredicateFilter :: SelfThatDefines ( assoc_name) ,
748739 )
749740 . into_iter ( )
750741 . filter ( |( predicate, _) | match predicate. kind ( ) . skip_binder ( ) {
@@ -768,8 +759,7 @@ impl<'tcx> ItemCtxt<'tcx> {
768759 ast_generics : & ' tcx hir:: Generics < ' tcx > ,
769760 param_def_id : LocalDefId ,
770761 ty : Ty < ' tcx > ,
771- only_self_bounds : OnlySelfBounds ,
772- assoc_name : Option < Ident > ,
762+ filter : PredicateFilter ,
773763 ) -> Vec < ( ty:: Clause < ' tcx > , Span ) > {
774764 let mut bounds = Bounds :: default ( ) ;
775765
@@ -778,9 +768,23 @@ impl<'tcx> ItemCtxt<'tcx> {
778768 continue ;
779769 } ;
780770
771+ let ( only_self_bounds, assoc_name) = match filter {
772+ PredicateFilter :: All | PredicateFilter :: SelfAndAssociatedTypeBounds => {
773+ ( OnlySelfBounds ( false ) , None )
774+ }
775+ PredicateFilter :: SelfOnly => ( OnlySelfBounds ( true ) , None ) ,
776+ PredicateFilter :: SelfThatDefines ( assoc_name) => {
777+ ( OnlySelfBounds ( true ) , Some ( assoc_name) )
778+ }
779+ } ;
780+
781+ // Subtle: If we're collecting `SelfAndAssociatedTypeBounds`, then we
782+ // want to only consider predicates with `Self: ...`, but we don't want
783+ // `OnlySelfBounds(true)` since we want to collect the nested associated
784+ // type bound as well.
781785 let bound_ty = if predicate. is_param_bound ( param_def_id. to_def_id ( ) ) {
782786 ty
783- } else if !only_self_bounds . 0 {
787+ } else if matches ! ( filter , PredicateFilter :: All ) {
784788 self . to_ty ( predicate. bounded_ty )
785789 } else {
786790 continue ;
0 commit comments