@@ -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 , Binders , BoundVar , DebruijnIndex , Goal , GoalData , Goals , ParameterKind ,
9
+ ParameterKinds , ProgramClause , ProgramClauseData , ProgramClauseImplication , QuantifierKind , Ty ,
10
+ TyData ,
10
11
} ;
11
12
12
13
pub fn syn_eq_lower < I : Interner > ( interner : & I , clause : & ProgramClause < I > ) -> ProgramClause < I > {
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,22 @@ 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
42
+ let new_ty = TyData :: BoundVar ( bound_var) . intern ( interner) ;
57
43
let folded = ty. super_fold_with ( self , outer_binder) ?;
58
44
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
+ ) ;
61
54
self . binders_len += 1 ;
62
- Ok ( TyData :: BoundVar ( bound_var ) . intern ( interner ) )
55
+ Ok ( new_ty )
63
56
}
64
- _ => ty . super_fold_with ( self , outer_binder ) ,
57
+ _ => Ok ( folded ) ,
65
58
}
66
59
}
67
60
@@ -73,42 +66,46 @@ impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
73
66
let interner = self . interner ;
74
67
75
68
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 ) ,
79
70
// 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
+ ) ,
81
78
} ;
82
79
let mut binders: Vec < _ > = binders. as_slice ( interner) . clone ( ) . into ( ) ;
83
-
80
+
84
81
let outer_binder = outer_binder. shifted_in ( ) ;
85
82
86
83
self . binders_len = binders. len ( ) ;
87
84
let consequence = implication. consequence . fold_with ( self , outer_binder) ?;
88
85
// Immediately move `new_params` out of of the folder struct so it's safe
89
86
// to call `.fold_with` again
90
87
let new_params = replace ( & mut self . new_params , vec ! [ ] ) ;
91
-
88
+ let new_goals = replace ( & mut self . new_goals , vec ! [ ] ) ;
89
+
92
90
let mut conditions = implication. conditions . fold_with ( self , outer_binder) ?;
93
91
if new_params. is_empty ( ) && !in_binders {
94
92
// 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
+ )
100
101
. intern ( interner) ) ;
101
102
}
102
103
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 ( ) ) ;
105
105
106
106
conditions = Goals :: from (
107
107
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) ,
112
109
) ;
113
110
114
111
Ok ( ProgramClauseData :: ForAll ( Binders :: new (
@@ -134,29 +131,30 @@ impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
134
131
self . binders_len = 0 ;
135
132
// shifted in because we introduce a new binder
136
133
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) ;
139
140
let new_params = replace ( & mut self . new_params , vec ! [ ] ) ;
141
+ let new_goals = replace ( & mut self . new_goals , vec ! [ ] ) ;
140
142
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 ( ) {
147
144
return Ok ( goal. clone ( ) ) ;
148
145
}
149
146
150
147
let goal = GoalData :: All ( Goals :: from (
151
148
interner,
152
- iter:: once ( domain_goal) . chain ( self . to_eq_goals ( new_params , 0 ) ) ,
149
+ iter:: once ( domain_goal) . chain ( new_goals ) ,
153
150
) )
154
151
. intern ( interner) ;
155
152
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 ) ,
159
156
)
157
+ . intern ( interner) )
160
158
}
161
159
162
160
fn interner ( & self ) -> & ' i I {
0 commit comments