@@ -768,6 +768,24 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
768768 /// `AliasEq` to fallback *or* normalize it. So instead we
769769 /// handle this kind of reasoning through the `FromEnv` predicate.
770770 ///
771+ /// Another set of clauses we generate for each associated type is about placeholder associated
772+ /// types (i.e. `TyKind::AssociatedType`). Given
773+ ///
774+ /// ```notrust
775+ /// trait Foo {
776+ /// type Assoc<'a, T>: Bar<U = Ty> where WC;
777+ /// }
778+ /// ```
779+ ///
780+ /// we generate
781+ ///
782+ /// ```notrust
783+ /// forall<Self, 'a, T> {
784+ /// Implemented((Foo::Assoc<'a, T>)<Self>: Bar) :- WC.
785+ /// AliasEq(<<(Foo::Assoc<'a, T>)<Self>> as Bar>::U = Ty) :- WC.
786+ /// }
787+ /// ```
788+ ///
771789 /// We also generate rules specific to WF requirements and implied bounds:
772790 ///
773791 /// ```notrust
@@ -818,11 +836,11 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
818836
819837 // Construct an application from the projection. So if we have `<T as Iterator>::Item`,
820838 // we would produce `(Iterator::Item)<T>`.
821- let ty = TyKind :: AssociatedType ( self . id , substitution) . intern ( interner) ;
839+ let placeholder_ty = TyKind :: AssociatedType ( self . id , substitution) . intern ( interner) ;
822840
823841 let projection_eq = AliasEq {
824842 alias : AliasTy :: Projection ( projection. clone ( ) ) ,
825- ty : ty . clone ( ) ,
843+ ty : placeholder_ty . clone ( ) ,
826844 } ;
827845
828846 // Fallback rule. The solver uses this to move between the projection
@@ -839,7 +857,7 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
839857 // WellFormed((Foo::Assoc)<Self>) :- WellFormed(Self: Foo), WellFormed(WC).
840858 // }
841859 builder. push_clause (
842- WellFormed :: Ty ( ty . clone ( ) ) ,
860+ WellFormed :: Ty ( placeholder_ty . clone ( ) ) ,
843861 iter:: once ( WellFormed :: Trait ( trait_ref. clone ( ) ) . cast :: < Goal < _ > > ( interner) )
844862 . chain (
845863 where_clauses
@@ -856,7 +874,10 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
856874 // forall<Self> {
857875 // FromEnv(Self: Foo) :- FromEnv((Foo::Assoc)<Self>).
858876 // }
859- builder. push_clause ( FromEnv :: Trait ( trait_ref. clone ( ) ) , Some ( ty. from_env ( ) ) ) ;
877+ builder. push_clause (
878+ FromEnv :: Trait ( trait_ref. clone ( ) ) ,
879+ Some ( placeholder_ty. from_env ( ) ) ,
880+ ) ;
860881
861882 // Reverse rule for where clauses.
862883 //
@@ -869,18 +890,18 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
869890 builder. push_binders ( qwc. clone ( ) , |builder, wc| {
870891 builder. push_clause (
871892 wc. into_from_env_goal ( interner) ,
872- Some ( FromEnv :: Ty ( ty . clone ( ) ) ) ,
893+ Some ( FromEnv :: Ty ( placeholder_ty . clone ( ) ) ) ,
873894 ) ;
874895 } ) ;
875896 }
876897
877- // Reverse rule for implied bounds.
878- //
879- // forall<Self> {
880- // FromEnv(<Self as Foo>::Assoc: Bounds) :- FromEnv(Self: Foo), WC
881- // }
882898 for quantified_bound in bounds {
883899 builder. push_binders ( quantified_bound, |builder, bound| {
900+ // Reverse rule for implied bounds.
901+ //
902+ // forall<Self> {
903+ // FromEnv(<Self as Foo>::Assoc: Bounds) :- FromEnv(Self: Foo), WC
904+ // }
884905 for wc in bound. into_where_clauses ( interner, projection_ty. clone ( ) ) {
885906 builder. push_clause (
886907 wc. into_from_env_goal ( interner) ,
@@ -890,6 +911,18 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
890911 . chain ( where_clauses. iter ( ) . cloned ( ) . casted ( interner) ) ,
891912 ) ;
892913 }
914+
915+ // Rules for the corresponding placeholder type.
916+ //
917+ // When `Foo::Assoc` has a bound `type Assoc: Trait<T = Ty>`, we generate:
918+ //
919+ // forall<Self> {
920+ // Implemented((Foo::Assoc)<Self>: Trait) :- WC
921+ // AliasEq(<(Foo::Assoc)<Self> as Trait>::T = Ty) :- WC
922+ // }
923+ for wc in bound. into_where_clauses ( interner, placeholder_ty. clone ( ) ) {
924+ builder. push_clause ( wc, where_clauses. iter ( ) . cloned ( ) ) ;
925+ }
893926 } ) ;
894927 }
895928
0 commit comments