@@ -2,49 +2,34 @@ use std::{iter, mem::replace};
22
33use chalk_engine:: fallible:: Fallible ;
44use chalk_ir:: {
5+ cast:: Cast ,
56 fold:: { shift:: Shift , Fold , Folder , SuperFold } ,
67 interner:: Interner ,
7- Binders , BoundVar , DebruijnIndex , EqGoal , Goal , GoalData , Goals , Parameter , ProgramClause ,
8- ProgramClauseData , ProgramClauseImplication , QuantifierKind , Ty , TyData , ParameterKind , ApplicationTy , TypeName ,
9- ParameterKinds ,
8+ AliasEq , Binders , BoundVar , DebruijnIndex , Goal , GoalData , Goals , ParameterKind ,
9+ ParameterKinds , ProgramClause , ProgramClauseData , ProgramClauseImplication , QuantifierKind , Ty ,
10+ TyData ,
1011} ;
1112
1213pub fn syn_eq_lower < I : Interner > ( interner : & I , clause : & ProgramClause < I > ) -> ProgramClause < I > {
1314 let mut folder = SynEqFolder {
1415 interner,
1516 new_params : vec ! [ ] ,
17+ new_goals : vec ! [ ] ,
1618 binders_len : 0 ,
1719 } ;
1820
19- clause. fold_with ( & mut folder, DebruijnIndex :: INNERMOST ) . unwrap ( )
21+ clause
22+ . fold_with ( & mut folder, DebruijnIndex :: INNERMOST )
23+ . unwrap ( )
2024}
2125
2226struct SynEqFolder < ' i , I : Interner > {
2327 interner : & ' i I ,
24- new_params : Vec < Parameter < I > > ,
28+ new_params : Vec < ParameterKind < ( ) > > ,
29+ new_goals : Vec < Goal < I > > ,
2530 binders_len : usize ,
2631}
2732
28- impl < ' i , I : Interner > SynEqFolder < ' i , I >
29- where
30- I : ' i ,
31- {
32- fn to_eq_goals ( & self , new_params : Vec < Parameter < I > > , old_len : usize ) -> impl Iterator < Item = Goal < I > > + ' i {
33- let interner = self . interner ;
34- new_params. into_iter ( ) . enumerate ( ) . map ( move |( i, p) | {
35- let var = BoundVar {
36- debruijn : DebruijnIndex :: INNERMOST ,
37- index : i + old_len,
38- } ;
39- GoalData :: EqGoal ( EqGoal {
40- a : p. replace_bound ( var, interner) ,
41- b : p,
42- } )
43- . intern ( interner)
44- } )
45- }
46- }
47-
4833impl < ' i , I : Interner > Folder < ' i , I > for SynEqFolder < ' i , I > {
4934 fn as_dyn ( & mut self ) -> & mut dyn Folder < ' i , I > {
5035 self
@@ -54,14 +39,22 @@ impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
5439 let interner = self . interner ;
5540 let bound_var = BoundVar :: new ( DebruijnIndex :: INNERMOST , self . binders_len ) ;
5641
42+ let new_ty = TyData :: BoundVar ( bound_var) . intern ( interner) ;
5743 let folded = ty. super_fold_with ( self , outer_binder) ?;
5844 match folded. data ( interner) {
59- TyData :: Apply ( ApplicationTy { name : TypeName :: AssociatedType ( _) , .. } ) => {
60- self . new_params . push ( ParameterKind :: Ty ( ty. clone ( ) ) . intern ( interner) ) ;
45+ TyData :: Alias ( alias) => {
46+ self . new_params . push ( ParameterKind :: Ty ( ( ) ) ) ;
47+ self . new_goals . push (
48+ AliasEq {
49+ alias : alias. clone ( ) ,
50+ ty : new_ty. clone ( ) ,
51+ }
52+ . cast ( interner) ,
53+ ) ;
6154 self . binders_len += 1 ;
62- Ok ( TyData :: BoundVar ( bound_var ) . intern ( interner ) )
55+ Ok ( new_ty )
6356 }
64- _ => ty . super_fold_with ( self , outer_binder ) ,
57+ _ => Ok ( folded ) ,
6558 }
6659 }
6760
@@ -73,42 +66,46 @@ impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
7366 let interner = self . interner ;
7467
7568 let ( ( binders, implication) , in_binders) = match clause. data ( interner) {
76- ProgramClauseData :: ForAll ( for_all) => {
77- ( for_all. clone ( ) . into ( ) , true )
78- }
69+ ProgramClauseData :: ForAll ( for_all) => ( for_all. clone ( ) . into ( ) , true ) ,
7970 // introduce a dummy binder and shift implication through it
80- ProgramClauseData :: Implies ( implication) => ( ( ParameterKinds :: new ( interner) , implication. shifted_in ( interner) ) , false ) ,
71+ ProgramClauseData :: Implies ( implication) => (
72+ (
73+ ParameterKinds :: new ( interner) ,
74+ implication. shifted_in ( interner) ,
75+ ) ,
76+ false ,
77+ ) ,
8178 } ;
8279 let mut binders: Vec < _ > = binders. as_slice ( interner) . clone ( ) . into ( ) ;
83-
80+
8481 let outer_binder = outer_binder. shifted_in ( ) ;
8582
8683 self . binders_len = binders. len ( ) ;
8784 let consequence = implication. consequence . fold_with ( self , outer_binder) ?;
8885 // Immediately move `new_params` out of of the folder struct so it's safe
8986 // to call `.fold_with` again
9087 let new_params = replace ( & mut self . new_params , vec ! [ ] ) ;
91-
88+ let new_goals = replace ( & mut self . new_goals , vec ! [ ] ) ;
89+
9290 let mut conditions = implication. conditions . fold_with ( self , outer_binder) ?;
9391 if new_params. is_empty ( ) && !in_binders {
9492 // shift the clause out since we didn't use the dummy binder
95- return Ok ( ProgramClauseData :: Implies ( ProgramClauseImplication {
96- consequence,
97- conditions,
98- priority : implication. priority ,
99- } . shifted_out ( interner) ?)
93+ return Ok ( ProgramClauseData :: Implies (
94+ ProgramClauseImplication {
95+ consequence,
96+ conditions,
97+ priority : implication. priority ,
98+ }
99+ . shifted_out ( interner) ?,
100+ )
100101 . intern ( interner) ) ;
101102 }
102103
103- let old_len = binders. len ( ) ;
104- binders. extend ( new_params. iter ( ) . map ( |p| p. data ( interner) . anonymize ( ) ) ) ;
104+ binders. extend ( new_params. into_iter ( ) ) ;
105105
106106 conditions = Goals :: from (
107107 interner,
108- conditions
109- . iter ( interner)
110- . cloned ( )
111- . chain ( self . to_eq_goals ( new_params, old_len) ) ,
108+ conditions. iter ( interner) . cloned ( ) . chain ( new_goals) ,
112109 ) ;
113110
114111 Ok ( ProgramClauseData :: ForAll ( Binders :: new (
@@ -134,29 +131,30 @@ impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
134131 self . binders_len = 0 ;
135132 // shifted in because we introduce a new binder
136133 let outer_binder = outer_binder. shifted_in ( ) ;
137- let domain_goal =
138- GoalData :: DomainGoal ( domain_goal. shifted_in ( interner) . fold_with ( self , outer_binder) ?) . intern ( interner) ;
134+ let domain_goal = GoalData :: DomainGoal (
135+ domain_goal
136+ . shifted_in ( interner)
137+ . fold_with ( self , outer_binder) ?,
138+ )
139+ . intern ( interner) ;
139140 let new_params = replace ( & mut self . new_params , vec ! [ ] ) ;
141+ let new_goals = replace ( & mut self . new_goals , vec ! [ ] ) ;
140142
141- let binders: Vec < _ > = new_params
142- . iter ( )
143- . map ( |p| p. data ( interner) . anonymize ( ) )
144- . collect ( ) ;
145-
146- if binders. is_empty ( ) {
143+ if new_params. is_empty ( ) {
147144 return Ok ( goal. clone ( ) ) ;
148145 }
149146
150147 let goal = GoalData :: All ( Goals :: from (
151148 interner,
152- iter:: once ( domain_goal) . chain ( self . to_eq_goals ( new_params , 0 ) ) ,
149+ iter:: once ( domain_goal) . chain ( new_goals ) ,
153150 ) )
154151 . intern ( interner) ;
155152
156- Ok (
157- GoalData :: Quantified ( QuantifierKind :: Exists , Binders :: new ( ParameterKinds :: from ( interner , binders ) , goal ) )
158- . intern ( interner) ,
153+ Ok ( GoalData :: Quantified (
154+ QuantifierKind :: Exists ,
155+ Binders :: new ( ParameterKinds :: from ( interner, new_params ) , goal ) ,
159156 )
157+ . intern ( interner) )
160158 }
161159
162160 fn interner ( & self ) -> & ' i I {
0 commit comments