@@ -2,49 +2,34 @@ use std::{iter, mem::replace};
2
2
3
3
use chalk_engine:: fallible:: Fallible ;
4
4
use chalk_ir:: {
5
+ cast:: Cast ,
5
6
fold:: { shift:: Shift , Fold , Folder , SuperFold } ,
6
7
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 , AliasTy , Binders , BoundVar , DebruijnIndex , Goal , GoalData , Goals , ParameterKind ,
9
+ ParameterKinds , ProgramClause , ProgramClauseData , ProgramClauseImplication , QuantifierKind , Ty ,
10
+ TyData ,
10
11
} ;
11
12
12
- pub fn syn_eq_lower < I : Interner > ( interner : & I , clause : & ProgramClause < I > ) -> ProgramClause < I > {
13
+ pub fn syn_eq_lower < I : Interner , T : Fold < I > > ( interner : & I , clause : & T ) -> < T as Fold < I > > :: Result {
13
14
let mut folder = SynEqFolder {
14
15
interner,
15
16
new_params : vec ! [ ] ,
17
+ new_goals : vec ! [ ] ,
16
18
binders_len : 0 ,
17
19
} ;
18
20
19
- clause. fold_with ( & mut folder, DebruijnIndex :: INNERMOST ) . unwrap ( )
21
+ clause
22
+ . fold_with ( & mut folder, DebruijnIndex :: INNERMOST )
23
+ . unwrap ( )
20
24
}
21
25
22
26
struct SynEqFolder < ' i , I : Interner > {
23
27
interner : & ' i I ,
24
- new_params : Vec < Parameter < I > > ,
28
+ new_params : Vec < ParameterKind < ( ) > > ,
29
+ new_goals : Vec < Goal < I > > ,
25
30
binders_len : usize ,
26
31
}
27
32
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
-
48
33
impl < ' i , I : Interner > Folder < ' i , I > for SynEqFolder < ' i , I > {
49
34
fn as_dyn ( & mut self ) -> & mut dyn Folder < ' i , I > {
50
35
self
@@ -54,14 +39,23 @@ impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
54
39
let interner = self . interner ;
55
40
let bound_var = BoundVar :: new ( DebruijnIndex :: INNERMOST , self . binders_len ) ;
56
41
57
- let folded = ty. super_fold_with ( self , outer_binder) ?;
58
- match folded. data ( interner) {
59
- TyData :: Apply ( ApplicationTy { name : TypeName :: AssociatedType ( _) , .. } ) => {
60
- self . new_params . push ( ParameterKind :: Ty ( ty. clone ( ) ) . intern ( interner) ) ;
42
+ let new_ty = TyData :: BoundVar ( bound_var) . intern ( interner) ;
43
+ match ty. data ( interner) {
44
+ TyData :: Alias ( alias @ AliasTy :: Projection ( _) ) => {
45
+ self . new_params . push ( ParameterKind :: Ty ( ( ) ) ) ;
46
+ self . new_goals . push (
47
+ AliasEq {
48
+ alias : alias. clone ( ) ,
49
+ ty : new_ty. clone ( ) ,
50
+ }
51
+ . cast ( interner) ,
52
+ ) ;
61
53
self . binders_len += 1 ;
62
- Ok ( TyData :: BoundVar ( bound_var) . intern ( interner) )
54
+ ty. super_fold_with ( self , outer_binder) ?;
55
+ Ok ( new_ty)
63
56
}
64
- _ => ty. super_fold_with ( self , outer_binder) ,
57
+ TyData :: Function ( _) => Ok ( ty. clone ( ) ) ,
58
+ _ => Ok ( ty. super_fold_with ( self , outer_binder) ?) ,
65
59
}
66
60
}
67
61
@@ -73,42 +67,46 @@ impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
73
67
let interner = self . interner ;
74
68
75
69
let ( ( binders, implication) , in_binders) = match clause. data ( interner) {
76
- ProgramClauseData :: ForAll ( for_all) => {
77
- ( for_all. clone ( ) . into ( ) , true )
78
- }
70
+ ProgramClauseData :: ForAll ( for_all) => ( for_all. clone ( ) . into ( ) , true ) ,
79
71
// introduce a dummy binder and shift implication through it
80
- ProgramClauseData :: Implies ( implication) => ( ( ParameterKinds :: new ( interner) , implication. shifted_in ( interner) ) , false ) ,
72
+ ProgramClauseData :: Implies ( implication) => (
73
+ (
74
+ ParameterKinds :: new ( interner) ,
75
+ implication. shifted_in ( interner) ,
76
+ ) ,
77
+ false ,
78
+ ) ,
81
79
} ;
82
80
let mut binders: Vec < _ > = binders. as_slice ( interner) . clone ( ) . into ( ) ;
83
-
81
+
84
82
let outer_binder = outer_binder. shifted_in ( ) ;
85
83
86
84
self . binders_len = binders. len ( ) ;
87
85
let consequence = implication. consequence . fold_with ( self , outer_binder) ?;
88
86
// Immediately move `new_params` out of of the folder struct so it's safe
89
87
// to call `.fold_with` again
90
88
let new_params = replace ( & mut self . new_params , vec ! [ ] ) ;
91
-
89
+ let new_goals = replace ( & mut self . new_goals , vec ! [ ] ) ;
90
+
92
91
let mut conditions = implication. conditions . fold_with ( self , outer_binder) ?;
93
92
if new_params. is_empty ( ) && !in_binders {
94
93
// 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) ?)
94
+ return Ok ( ProgramClauseData :: Implies (
95
+ ProgramClauseImplication {
96
+ consequence,
97
+ conditions,
98
+ priority : implication. priority ,
99
+ }
100
+ . shifted_out ( interner) ?,
101
+ )
100
102
. intern ( interner) ) ;
101
103
}
102
104
103
- let old_len = binders. len ( ) ;
104
- binders. extend ( new_params. iter ( ) . map ( |p| p. data ( interner) . anonymize ( ) ) ) ;
105
+ binders. extend ( new_params. into_iter ( ) ) ;
105
106
106
107
conditions = Goals :: from (
107
108
interner,
108
- conditions
109
- . iter ( interner)
110
- . cloned ( )
111
- . chain ( self . to_eq_goals ( new_params, old_len) ) ,
109
+ conditions. iter ( interner) . cloned ( ) . chain ( new_goals) ,
112
110
) ;
113
111
114
112
Ok ( ProgramClauseData :: ForAll ( Binders :: new (
@@ -126,37 +124,35 @@ impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
126
124
assert ! ( self . new_params. is_empty( ) , true ) ;
127
125
128
126
let interner = self . interner ;
129
- let domain_goal = match goal. data ( interner) {
130
- GoalData :: DomainGoal ( dg ) => dg ,
127
+ match goal. data ( interner) {
128
+ GoalData :: DomainGoal ( _ ) | GoalData :: EqGoal ( _ ) => ( ) ,
131
129
_ => return goal. super_fold_with ( self , outer_binder) ,
132
130
} ;
133
131
134
132
self . binders_len = 0 ;
135
133
// shifted in because we introduce a new binder
136
134
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) ;
135
+ let syn_goal = goal
136
+ . shifted_in ( interner)
137
+ . super_fold_with ( self , outer_binder) ?;
139
138
let new_params = replace ( & mut self . new_params , vec ! [ ] ) ;
139
+ let new_goals = replace ( & mut self . new_goals , vec ! [ ] ) ;
140
140
141
- let binders: Vec < _ > = new_params
142
- . iter ( )
143
- . map ( |p| p. data ( interner) . anonymize ( ) )
144
- . collect ( ) ;
145
-
146
- if binders. is_empty ( ) {
141
+ if new_params. is_empty ( ) {
147
142
return Ok ( goal. clone ( ) ) ;
148
143
}
149
144
150
145
let goal = GoalData :: All ( Goals :: from (
151
146
interner,
152
- iter:: once ( domain_goal ) . chain ( self . to_eq_goals ( new_params , 0 ) ) ,
147
+ iter:: once ( syn_goal ) . into_iter ( ) . chain ( new_goals ) ,
153
148
) )
154
149
. intern ( interner) ;
155
150
156
- Ok (
157
- GoalData :: Quantified ( QuantifierKind :: Exists , Binders :: new ( ParameterKinds :: from ( interner , binders ) , goal ) )
158
- . intern ( interner) ,
151
+ Ok ( GoalData :: Quantified (
152
+ QuantifierKind :: Exists ,
153
+ Binders :: new ( ParameterKinds :: from ( interner, new_params ) , goal ) ,
159
154
)
155
+ . intern ( interner) )
160
156
}
161
157
162
158
fn interner ( & self ) -> & ' i I {
0 commit comments