@@ -724,34 +724,38 @@ fn push_alias_implemented_clause<I: Interner>(
724
724
TyKind :: Alias ( alias. clone( ) )
725
725
) ;
726
726
727
- let binders = Binders :: with_fresh_type_var ( interner, |ty_var| ty_var) ;
728
-
729
- // forall<..., T> {
730
- // <X as Y>::Z: Trait :- T: Trait, <X as Y>::Z == T
731
- // }
732
- builder. push_binders ( & binders, |builder, bound_var| {
733
- let fresh_self_subst = Substitution :: from_iter (
734
- interner,
735
- std:: iter:: once ( bound_var. clone ( ) . cast ( interner) ) . chain (
736
- trait_ref. substitution . as_slice ( interner) [ 1 ..]
737
- . iter ( )
738
- . cloned ( ) ,
739
- ) ,
740
- ) ;
741
- let fresh_self_trait_ref = TraitRef {
742
- trait_id : trait_ref. trait_id ,
743
- substitution : fresh_self_subst,
744
- } ;
745
- builder. push_clause (
746
- DomainGoal :: Holds ( WhereClause :: Implemented ( trait_ref. clone ( ) ) ) ,
747
- & [
748
- DomainGoal :: Holds ( WhereClause :: Implemented ( fresh_self_trait_ref) ) ,
749
- DomainGoal :: Holds ( WhereClause :: AliasEq ( AliasEq {
750
- alias : alias. clone ( ) ,
751
- ty : bound_var,
752
- } ) ) ,
753
- ] ,
754
- ) ;
727
+ // TODO: instead generate clauses without reference to the specific type parameters of the goal?
728
+ let generalized = generalize:: Generalize :: apply ( interner, & ( trait_ref, alias) ) ;
729
+ builder. push_binders ( & generalized, |builder, ( trait_ref, alias) | {
730
+ let binders = Binders :: with_fresh_type_var ( interner, |ty_var| ty_var) ;
731
+
732
+ // forall<..., T> {
733
+ // <X as Y>::Z: Trait :- T: Trait, <X as Y>::Z == T
734
+ // }
735
+ builder. push_binders ( & binders, |builder, bound_var| {
736
+ let fresh_self_subst = Substitution :: from_iter (
737
+ interner,
738
+ std:: iter:: once ( bound_var. clone ( ) . cast ( interner) ) . chain (
739
+ trait_ref. substitution . as_slice ( interner) [ 1 ..]
740
+ . iter ( )
741
+ . cloned ( ) ,
742
+ ) ,
743
+ ) ;
744
+ let fresh_self_trait_ref = TraitRef {
745
+ trait_id : trait_ref. trait_id ,
746
+ substitution : fresh_self_subst,
747
+ } ;
748
+ builder. push_clause (
749
+ DomainGoal :: Holds ( WhereClause :: Implemented ( trait_ref. clone ( ) ) ) ,
750
+ & [
751
+ DomainGoal :: Holds ( WhereClause :: Implemented ( fresh_self_trait_ref) ) ,
752
+ DomainGoal :: Holds ( WhereClause :: AliasEq ( AliasEq {
753
+ alias : alias. clone ( ) ,
754
+ ty : bound_var,
755
+ } ) ) ,
756
+ ] ,
757
+ ) ;
758
+ } ) ;
755
759
} ) ;
756
760
}
757
761
@@ -767,40 +771,44 @@ fn push_alias_alias_eq_clause<I: Interner>(
767
771
TyKind :: Alias ( alias. clone( ) )
768
772
) ;
769
773
770
- let binders = Binders :: with_fresh_type_var ( interner, |ty_var| ty_var) ;
771
-
772
- // forall<..., T> {
773
- // <<X as Y>::A as Z>::B == U :- <T as Z>::B == U, <X as Y>::A == T
774
- // }
775
- builder. push_binders ( & binders, |builder, bound_var| {
776
- let fresh_self_subst = Substitution :: from_iter (
777
- interner,
778
- std:: iter:: once ( bound_var. clone ( ) . cast ( interner) ) . chain (
779
- projection_ty. substitution . as_slice ( interner) [ 1 ..]
780
- . iter ( )
781
- . cloned ( ) ,
782
- ) ,
783
- ) ;
784
- let fresh_alias = AliasTy :: Projection ( ProjectionTy {
785
- associated_ty_id : projection_ty. associated_ty_id ,
786
- substitution : fresh_self_subst,
787
- } ) ;
788
- builder. push_clause (
789
- DomainGoal :: Holds ( WhereClause :: AliasEq ( AliasEq {
790
- alias : AliasTy :: Projection ( projection_ty. clone ( ) ) ,
791
- ty : ty. clone ( ) ,
792
- } ) ) ,
793
- & [
774
+ // TODO: instead generate clauses without reference to the specific type parameters of the goal?
775
+ let generalized = generalize:: Generalize :: apply ( interner, & ( projection_ty, ty, alias) ) ;
776
+ builder. push_binders ( & generalized, |builder, ( projection_ty, ty, alias) | {
777
+ let binders = Binders :: with_fresh_type_var ( interner, |ty_var| ty_var) ;
778
+
779
+ // forall<..., T> {
780
+ // <<X as Y>::A as Z>::B == U :- <T as Z>::B == U, <X as Y>::A == T
781
+ // }
782
+ builder. push_binders ( & binders, |builder, bound_var| {
783
+ let fresh_self_subst = Substitution :: from_iter (
784
+ interner,
785
+ std:: iter:: once ( bound_var. clone ( ) . cast ( interner) ) . chain (
786
+ projection_ty. substitution . as_slice ( interner) [ 1 ..]
787
+ . iter ( )
788
+ . cloned ( ) ,
789
+ ) ,
790
+ ) ;
791
+ let fresh_alias = AliasTy :: Projection ( ProjectionTy {
792
+ associated_ty_id : projection_ty. associated_ty_id ,
793
+ substitution : fresh_self_subst,
794
+ } ) ;
795
+ builder. push_clause (
794
796
DomainGoal :: Holds ( WhereClause :: AliasEq ( AliasEq {
795
- alias : fresh_alias ,
797
+ alias : AliasTy :: Projection ( projection_ty . clone ( ) ) ,
796
798
ty : ty. clone ( ) ,
797
799
} ) ) ,
798
- DomainGoal :: Holds ( WhereClause :: AliasEq ( AliasEq {
799
- alias : alias. clone ( ) ,
800
- ty : bound_var,
801
- } ) ) ,
802
- ] ,
803
- ) ;
800
+ & [
801
+ DomainGoal :: Holds ( WhereClause :: AliasEq ( AliasEq {
802
+ alias : fresh_alias,
803
+ ty : ty. clone ( ) ,
804
+ } ) ) ,
805
+ DomainGoal :: Holds ( WhereClause :: AliasEq ( AliasEq {
806
+ alias : alias. clone ( ) ,
807
+ ty : bound_var,
808
+ } ) ) ,
809
+ ] ,
810
+ ) ;
811
+ } ) ;
804
812
} ) ;
805
813
}
806
814
0 commit comments