14
14
15
15
use rustc:: middle:: ty;
16
16
use rustc:: mir:: repr:: * ;
17
- use rustc:: mir:: visit:: MutVisitor ;
18
- use mir_map:: MirMap ;
19
17
use transform:: MirPass ;
18
+ use mir_map:: MirMap ;
20
19
21
20
pub fn erase_regions < ' tcx > ( tcx : & ty:: ctxt < ' tcx > , mir_map : & mut MirMap < ' tcx > ) {
22
21
let mut eraser = EraseRegions :: new ( tcx) ;
@@ -30,105 +29,196 @@ pub struct EraseRegions<'a, 'tcx: 'a> {
30
29
tcx : & ' a ty:: ctxt < ' tcx > ,
31
30
}
32
31
32
+ impl < ' a , ' tcx > MirPass < ' tcx > for EraseRegions < ' a , ' tcx > {
33
+
34
+ fn run_on_mir ( & mut self , mir : & mut Mir < ' tcx > ) {
35
+
36
+ for basic_block in & mut mir. basic_blocks {
37
+ self . erase_regions_basic_block ( basic_block) ;
38
+ }
39
+
40
+ self . erase_regions_return_ty ( & mut mir. return_ty ) ;
41
+
42
+ self . erase_regions_tys ( mir. var_decls . iter_mut ( ) . map ( |d| & mut d. ty ) ) ;
43
+ self . erase_regions_tys ( mir. arg_decls . iter_mut ( ) . map ( |d| & mut d. ty ) ) ;
44
+ self . erase_regions_tys ( mir. temp_decls . iter_mut ( ) . map ( |d| & mut d. ty ) ) ;
45
+ }
46
+ }
47
+
33
48
impl < ' a , ' tcx > EraseRegions < ' a , ' tcx > {
49
+
34
50
pub fn new ( tcx : & ' a ty:: ctxt < ' tcx > ) -> EraseRegions < ' a , ' tcx > {
35
51
EraseRegions {
36
52
tcx : tcx
37
53
}
38
54
}
39
55
40
- fn erase_regions_return_ty ( & mut self , fn_output : & mut ty:: FnOutput < ' tcx > ) {
41
- match * fn_output {
42
- ty:: FnConverging ( ref mut ty) => {
43
- * ty = self . tcx . erase_regions ( ty) ;
44
- } ,
45
- ty:: FnDiverging => { }
56
+ fn erase_regions_basic_block ( & mut self ,
57
+ basic_block : & mut BasicBlockData < ' tcx > ) {
58
+ for statement in & mut basic_block. statements {
59
+ self . erase_regions_statement ( statement) ;
46
60
}
47
- }
48
-
49
- fn erase_regions_tys < ' b , T > ( & mut self , tys : T )
50
- where T : Iterator < Item = & ' b mut ty:: Ty < ' tcx > > ,
51
- ' tcx : ' b
52
- {
53
- for ty in tys {
54
- * ty = self . tcx . erase_regions ( ty) ;
55
- }
56
- }
57
- }
58
61
59
- impl < ' a , ' tcx > MirPass < ' tcx > for EraseRegions < ' a , ' tcx > {
60
- fn run_on_mir ( & mut self , mir : & mut Mir < ' tcx > ) {
61
- self . visit_mir ( mir) ;
62
+ self . erase_regions_terminator ( basic_block. terminator_mut ( ) ) ;
62
63
}
63
- }
64
64
65
- impl < ' a , ' tcx > MutVisitor < ' tcx > for EraseRegions < ' a , ' tcx > {
66
- fn visit_mir ( & mut self , mir : & mut Mir < ' tcx > ) {
67
- self . erase_regions_return_ty ( & mut mir. return_ty ) ;
68
- self . erase_regions_tys ( mir. var_decls . iter_mut ( ) . map ( |d| & mut d. ty ) ) ;
69
- self . erase_regions_tys ( mir. arg_decls . iter_mut ( ) . map ( |d| & mut d. ty ) ) ;
70
- self . erase_regions_tys ( mir. temp_decls . iter_mut ( ) . map ( |d| & mut d. ty ) ) ;
71
- self . super_mir ( mir) ;
65
+ fn erase_regions_statement ( & mut self ,
66
+ statement : & mut Statement < ' tcx > ) {
67
+ match statement. kind {
68
+ StatementKind :: Assign ( ref mut lvalue, ref mut rvalue) => {
69
+ self . erase_regions_lvalue ( lvalue) ;
70
+ self . erase_regions_rvalue ( rvalue) ;
71
+ }
72
+ }
72
73
}
73
74
74
- fn visit_terminator ( & mut self , bb : BasicBlock , terminator : & mut Terminator < ' tcx > ) {
75
+ fn erase_regions_terminator ( & mut self ,
76
+ terminator : & mut Terminator < ' tcx > ) {
75
77
match * terminator {
76
78
Terminator :: Goto { .. } |
77
79
Terminator :: Resume |
78
- Terminator :: Return |
79
- Terminator :: If { .. } |
80
- Terminator :: Switch { .. } |
81
- Terminator :: Drop { .. } |
82
- Terminator :: Call { .. } => {
80
+ Terminator :: Return => {
83
81
/* nothing to do */
84
- } ,
85
- Terminator :: SwitchInt { ref mut switch_ty, .. } => {
82
+ }
83
+ Terminator :: If { ref mut cond, .. } => {
84
+ self . erase_regions_operand ( cond) ;
85
+ }
86
+ Terminator :: Switch { ref mut discr, .. } => {
87
+ self . erase_regions_lvalue ( discr) ;
88
+ }
89
+ Terminator :: SwitchInt { ref mut discr, ref mut switch_ty, .. } => {
90
+ self . erase_regions_lvalue ( discr) ;
86
91
* switch_ty = self . tcx . erase_regions ( switch_ty) ;
87
92
} ,
93
+ Terminator :: Drop { ref mut value, .. } => {
94
+ self . erase_regions_lvalue ( value) ;
95
+ }
96
+ Terminator :: Call { ref mut func, ref mut args, ref mut destination, .. } => {
97
+ if let Some ( ( ref mut destination, _) ) = * destination {
98
+ self . erase_regions_lvalue ( destination) ;
99
+ }
100
+ self . erase_regions_operand ( func) ;
101
+ for arg in & mut * args {
102
+ self . erase_regions_operand ( arg) ;
103
+ }
104
+ }
88
105
}
89
- self . super_terminator ( bb, terminator) ;
90
106
}
91
107
92
- fn visit_rvalue ( & mut self , rvalue : & mut Rvalue < ' tcx > ) {
93
- match * rvalue {
94
- Rvalue :: Use ( _) |
95
- Rvalue :: Len ( _) |
96
- Rvalue :: BinaryOp ( _, _, _) |
97
- Rvalue :: UnaryOp ( _, _) |
98
- Rvalue :: Slice { input : _, from_start : _, from_end : _ } |
99
- Rvalue :: InlineAsm ( _) => { } ,
100
-
101
- Rvalue :: Repeat ( _, ref mut value) => value. ty = self . tcx . erase_regions ( & value. ty ) ,
102
- Rvalue :: Ref ( ref mut region, _, _) => * region = ty:: ReStatic ,
103
- Rvalue :: Cast ( _, _, ref mut ty) => * ty = self . tcx . erase_regions ( ty) ,
104
- Rvalue :: Box ( ref mut ty) => * ty = self . tcx . erase_regions ( ty) ,
108
+ fn erase_regions_operand ( & mut self , operand : & mut Operand < ' tcx > ) {
109
+ match * operand {
110
+ Operand :: Consume ( ref mut lvalue) => {
111
+ self . erase_regions_lvalue ( lvalue) ;
112
+ }
113
+ Operand :: Constant ( ref mut constant) => {
114
+ self . erase_regions_constant ( constant) ;
115
+ }
116
+ }
117
+ }
105
118
119
+ fn erase_regions_lvalue ( & mut self , lvalue : & mut Lvalue < ' tcx > ) {
120
+ match * lvalue {
121
+ Lvalue :: Var ( _) |
122
+ Lvalue :: Temp ( _) |
123
+ Lvalue :: Arg ( _) |
124
+ Lvalue :: Static ( _) |
125
+ Lvalue :: ReturnPointer => { }
126
+ Lvalue :: Projection ( ref mut lvalue_projection) => {
127
+ self . erase_regions_lvalue ( & mut lvalue_projection. base ) ;
128
+ match lvalue_projection. elem {
129
+ ProjectionElem :: Deref |
130
+ ProjectionElem :: Field ( _) |
131
+ ProjectionElem :: Downcast ( ..) |
132
+ ProjectionElem :: ConstantIndex { ..} => { /* nothing to do */ }
133
+ ProjectionElem :: Index ( ref mut index) => {
134
+ self . erase_regions_operand ( index) ;
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
106
140
107
- Rvalue :: Aggregate ( AggregateKind :: Vec , _) |
108
- Rvalue :: Aggregate ( AggregateKind :: Tuple , _) => { } ,
109
- Rvalue :: Aggregate ( AggregateKind :: Adt ( _, _, ref mut substs) , _) =>
110
- * substs = self . tcx . mk_substs ( self . tcx . erase_regions ( * substs) ) ,
111
- Rvalue :: Aggregate ( AggregateKind :: Closure ( def_id, ref mut closure_substs) , _) => {
112
- let cloned = Box :: new ( closure_substs. clone ( ) ) ;
113
- let ty = self . tcx . mk_closure_from_closure_substs ( def_id, cloned) ;
114
- let erased = self . tcx . erase_regions ( & ty) ;
115
- * closure_substs = match erased. sty {
116
- ty:: TyClosure ( _, ref closure_substs) => & * closure_substs,
117
- _ => unreachable ! ( )
118
- } ;
141
+ fn erase_regions_rvalue ( & mut self , rvalue : & mut Rvalue < ' tcx > ) {
142
+ match * rvalue {
143
+ Rvalue :: Use ( ref mut operand) => {
144
+ self . erase_regions_operand ( operand)
145
+ }
146
+ Rvalue :: Repeat ( ref mut operand, ref mut value) => {
147
+ self . erase_regions_operand ( operand) ;
148
+ value. ty = self . tcx . erase_regions ( & value. ty ) ;
149
+ }
150
+ Rvalue :: Ref ( ref mut region, _, ref mut lvalue) => {
151
+ * region = ty:: ReStatic ;
152
+ self . erase_regions_lvalue ( lvalue) ;
153
+ }
154
+ Rvalue :: Len ( ref mut lvalue) => self . erase_regions_lvalue ( lvalue) ,
155
+ Rvalue :: Cast ( _, ref mut operand, ref mut ty) => {
156
+ self . erase_regions_operand ( operand) ;
157
+ * ty = self . tcx . erase_regions ( ty) ;
158
+ }
159
+ Rvalue :: BinaryOp ( _, ref mut operand1, ref mut operand2) => {
160
+ self . erase_regions_operand ( operand1) ;
161
+ self . erase_regions_operand ( operand2) ;
162
+ }
163
+ Rvalue :: UnaryOp ( _, ref mut operand) => {
164
+ self . erase_regions_operand ( operand) ;
119
165
}
166
+ Rvalue :: Box ( ref mut ty) => * ty = self . tcx . erase_regions ( ty) ,
167
+ Rvalue :: Aggregate ( ref mut aggregate_kind, ref mut operands) => {
168
+ match * aggregate_kind {
169
+ AggregateKind :: Vec |
170
+ AggregateKind :: Tuple => { } ,
171
+ AggregateKind :: Adt ( _, _, ref mut substs) => {
172
+ let erased = self . tcx . erase_regions ( * substs) ;
173
+ * substs = self . tcx . mk_substs ( erased) ;
174
+ }
175
+ AggregateKind :: Closure ( def_id, ref mut closure_substs) => {
176
+ let cloned = Box :: new ( closure_substs. clone ( ) ) ;
177
+ let ty = self . tcx . mk_closure_from_closure_substs ( def_id,
178
+ cloned) ;
179
+ let erased = self . tcx . erase_regions ( & ty) ;
180
+ * closure_substs = match erased. sty {
181
+ ty:: TyClosure ( _, ref closure_substs) => & * closure_substs,
182
+ _ => unreachable ! ( )
183
+ } ;
184
+ }
185
+ }
186
+ for operand in & mut * operands {
187
+ self . erase_regions_operand ( operand) ;
188
+ }
189
+ }
190
+ Rvalue :: Slice { ref mut input, .. } => {
191
+ self . erase_regions_lvalue ( input) ;
192
+ }
193
+ Rvalue :: InlineAsm ( _) => { } ,
120
194
}
121
- self . super_rvalue ( rvalue) ;
122
195
}
123
196
124
- fn visit_constant ( & mut self , constant : & mut Constant < ' tcx > ) {
197
+ fn erase_regions_constant ( & mut self , constant : & mut Constant < ' tcx > ) {
125
198
constant. ty = self . tcx . erase_regions ( & constant. ty ) ;
126
199
match constant. literal {
127
200
Literal :: Item { ref mut substs, .. } => {
128
201
* substs = self . tcx . mk_substs ( self . tcx . erase_regions ( substs) ) ;
129
202
}
130
203
Literal :: Value { .. } => { /* nothing to do */ }
131
204
}
132
- self . super_constant ( constant) ;
205
+ }
206
+
207
+ fn erase_regions_return_ty ( & mut self , fn_output : & mut ty:: FnOutput < ' tcx > ) {
208
+ match * fn_output {
209
+ ty:: FnConverging ( ref mut ty) => {
210
+ * ty = self . tcx . erase_regions ( ty) ;
211
+ } ,
212
+ ty:: FnDiverging => { }
213
+ }
214
+ }
215
+
216
+ fn erase_regions_tys < ' b , T > ( & mut self , tys : T )
217
+ where T : Iterator < Item = & ' b mut ty:: Ty < ' tcx > > ,
218
+ ' tcx : ' b
219
+ {
220
+ for ty in tys {
221
+ * ty = self . tcx . erase_regions ( ty) ;
222
+ }
133
223
}
134
224
}
0 commit comments