@@ -768,6 +768,24 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
768
768
/// `AliasEq` to fallback *or* normalize it. So instead we
769
769
/// handle this kind of reasoning through the `FromEnv` predicate.
770
770
///
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
+ ///
771
789
/// We also generate rules specific to WF requirements and implied bounds:
772
790
///
773
791
/// ```notrust
@@ -818,11 +836,11 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
818
836
819
837
// Construct an application from the projection. So if we have `<T as Iterator>::Item`,
820
838
// 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) ;
822
840
823
841
let projection_eq = AliasEq {
824
842
alias : AliasTy :: Projection ( projection. clone ( ) ) ,
825
- ty : ty . clone ( ) ,
843
+ ty : placeholder_ty . clone ( ) ,
826
844
} ;
827
845
828
846
// Fallback rule. The solver uses this to move between the projection
@@ -839,7 +857,7 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
839
857
// WellFormed((Foo::Assoc)<Self>) :- WellFormed(Self: Foo), WellFormed(WC).
840
858
// }
841
859
builder. push_clause (
842
- WellFormed :: Ty ( ty . clone ( ) ) ,
860
+ WellFormed :: Ty ( placeholder_ty . clone ( ) ) ,
843
861
iter:: once ( WellFormed :: Trait ( trait_ref. clone ( ) ) . cast :: < Goal < _ > > ( interner) )
844
862
. chain (
845
863
where_clauses
@@ -856,7 +874,10 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
856
874
// forall<Self> {
857
875
// FromEnv(Self: Foo) :- FromEnv((Foo::Assoc)<Self>).
858
876
// }
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
+ ) ;
860
881
861
882
// Reverse rule for where clauses.
862
883
//
@@ -869,18 +890,18 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
869
890
builder. push_binders ( qwc. clone ( ) , |builder, wc| {
870
891
builder. push_clause (
871
892
wc. into_from_env_goal ( interner) ,
872
- Some ( FromEnv :: Ty ( ty . clone ( ) ) ) ,
893
+ Some ( FromEnv :: Ty ( placeholder_ty . clone ( ) ) ) ,
873
894
) ;
874
895
} ) ;
875
896
}
876
897
877
- // Reverse rule for implied bounds.
878
- //
879
- // forall<Self> {
880
- // FromEnv(<Self as Foo>::Assoc: Bounds) :- FromEnv(Self: Foo), WC
881
- // }
882
898
for quantified_bound in bounds {
883
899
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
+ // }
884
905
for wc in bound. into_where_clauses ( interner, projection_ty. clone ( ) ) {
885
906
builder. push_clause (
886
907
wc. into_from_env_goal ( interner) ,
@@ -890,6 +911,18 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
890
911
. chain ( where_clauses. iter ( ) . cloned ( ) . casted ( interner) ) ,
891
912
) ;
892
913
}
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
+ }
893
926
} ) ;
894
927
}
895
928
0 commit comments