9
9
// except according to those terms.
10
10
11
11
use hair:: cx:: Cx ;
12
- use rustc:: middle:: region:: CodeExtent ;
12
+ use rustc:: middle:: region:: { CodeExtent , CodeExtentData } ;
13
13
use rustc:: middle:: ty:: { FnOutput , Ty } ;
14
14
use rustc:: mir:: repr:: * ;
15
15
use rustc_data_structures:: fnv:: FnvHashMap ;
@@ -153,12 +153,14 @@ macro_rules! unpack {
153
153
154
154
pub fn construct < ' a , ' tcx > ( hir : Cx < ' a , ' tcx > ,
155
155
span : Span ,
156
+ fn_id : ast:: NodeId ,
157
+ body_id : ast:: NodeId ,
156
158
implicit_arguments : Vec < Ty < ' tcx > > ,
157
159
explicit_arguments : Vec < ( Ty < ' tcx > , & ' tcx hir:: Pat ) > ,
158
- argument_extent : CodeExtent ,
159
160
return_ty : FnOutput < ' tcx > ,
160
161
ast_block : & ' tcx hir:: Block )
161
162
-> ( Mir < ' tcx > , ScopeAuxiliaryVec ) {
163
+ let tcx = hir. tcx ( ) ;
162
164
let cfg = CFG { basic_blocks : vec ! [ ] } ;
163
165
164
166
let mut builder = Builder {
@@ -178,27 +180,41 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>,
178
180
assert_eq ! ( builder. cfg. start_new_block( ) , START_BLOCK ) ;
179
181
assert_eq ! ( builder. cfg. start_new_block( ) , END_BLOCK ) ;
180
182
181
- let mut block = START_BLOCK ;
182
- let ( arg_decls, arg_scope_id) =
183
- unpack ! ( block = builder. args_and_body( block,
184
- implicit_arguments,
185
- explicit_arguments,
186
- argument_extent,
187
- ast_block) ) ;
188
183
189
- builder. cfg . terminate ( block, arg_scope_id, span,
190
- TerminatorKind :: Goto { target : END_BLOCK } ) ;
191
- builder. cfg . terminate ( END_BLOCK , arg_scope_id, span,
192
- TerminatorKind :: Return ) ;
184
+ let mut arg_decls = None ; // assigned to `Some` in closures below
185
+ let call_site_extent =
186
+ tcx. region_maps . lookup_code_extent (
187
+ CodeExtentData :: CallSiteScope { fn_id : fn_id, body_id : body_id } ) ;
188
+ let _ = builder. in_scope ( call_site_extent, START_BLOCK , |builder, call_site_scope_id| {
189
+ let mut block = START_BLOCK ;
190
+ let arg_extent =
191
+ tcx. region_maps . lookup_code_extent (
192
+ CodeExtentData :: ParameterScope { fn_id : fn_id, body_id : body_id } ) ;
193
+ unpack ! ( block = builder. in_scope( arg_extent, block, |builder, arg_scope_id| {
194
+ arg_decls = Some ( unpack!( block = builder. args_and_body( block,
195
+ implicit_arguments,
196
+ explicit_arguments,
197
+ arg_scope_id,
198
+ ast_block) ) ) ;
199
+ block. unit( )
200
+ } ) ) ;
201
+
202
+ builder. cfg . terminate ( block, call_site_scope_id, span,
203
+ TerminatorKind :: Goto { target : END_BLOCK } ) ;
204
+ builder. cfg . terminate ( END_BLOCK , call_site_scope_id, span,
205
+ TerminatorKind :: Return ) ;
206
+
207
+ END_BLOCK . unit ( )
208
+ } ) ;
193
209
194
210
assert ! (
195
211
builder. cfg. basic_blocks
196
212
. iter( )
197
213
. enumerate( )
198
214
. all( |( index, block) | {
199
215
if block. terminator. is_none( ) {
200
- panic!( "no terminator on block {:?} in {:?}" ,
201
- index, argument_extent )
216
+ panic!( "no terminator on block {:?} in fn {:?}" ,
217
+ index, fn_id )
202
218
}
203
219
true
204
220
} ) ) ;
@@ -208,7 +224,7 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>,
208
224
basic_blocks : builder. cfg . basic_blocks ,
209
225
scopes : builder. scope_datas ,
210
226
var_decls : builder. var_decls ,
211
- arg_decls : arg_decls,
227
+ arg_decls : arg_decls. take ( ) . expect ( "args never built?" ) ,
212
228
temp_decls : builder. temp_decls ,
213
229
return_ty : return_ty,
214
230
span : span
@@ -222,39 +238,40 @@ impl<'a,'tcx> Builder<'a,'tcx> {
222
238
mut block : BasicBlock ,
223
239
implicit_arguments : Vec < Ty < ' tcx > > ,
224
240
explicit_arguments : Vec < ( Ty < ' tcx > , & ' tcx hir:: Pat ) > ,
225
- argument_extent : CodeExtent ,
241
+ argument_scope_id : ScopeId ,
226
242
ast_block : & ' tcx hir:: Block )
227
- -> BlockAnd < ( Vec < ArgDecl < ' tcx > > , ScopeId ) >
243
+ -> BlockAnd < Vec < ArgDecl < ' tcx > > >
228
244
{
229
- self . in_scope ( argument_extent, block, |this, argument_scope_id| {
230
- // to start, translate the argument patterns and collect the argument types.
231
- let implicits = implicit_arguments. into_iter ( ) . map ( |ty| ( ty, None ) ) ;
232
- let explicits = explicit_arguments. into_iter ( ) . map ( |( ty, pat) | ( ty, Some ( pat) ) ) ;
245
+ // to start, translate the argument patterns and collect the argument types.
246
+ let implicits = implicit_arguments. into_iter ( ) . map ( |ty| ( ty, None ) ) ;
247
+ let explicits = explicit_arguments. into_iter ( ) . map ( |( ty, pat) | ( ty, Some ( pat) ) ) ;
233
248
let arg_decls =
234
- implicits
235
- . chain ( explicits)
236
- . enumerate ( )
237
- . map ( |( index, ( ty, pattern) ) | {
238
- let lvalue = Lvalue :: Arg ( index as u32 ) ;
239
- if let Some ( pattern) = pattern {
240
- let pattern = this. hir . irrefutable_pat ( pattern) ;
241
- unpack ! ( block = this. lvalue_into_pattern( block,
242
- argument_scope_id,
243
- pattern,
244
- & lvalue) ) ;
245
- }
246
- // Make sure we drop (parts of) the argument even when not matched on.
247
- this. schedule_drop ( pattern. as_ref ( ) . map_or ( ast_block. span , |pat| pat. span ) ,
248
- argument_extent, & lvalue, ty) ;
249
- ArgDecl { ty : ty, spread : false }
250
- } )
251
- . collect ( ) ;
252
-
253
- // start the first basic block and translate the body
254
- unpack ! ( block = this. ast_block( & Lvalue :: ReturnPointer , block, ast_block) ) ;
255
-
256
- block. and ( ( arg_decls, argument_scope_id) )
257
- } )
249
+ implicits
250
+ . chain ( explicits)
251
+ . enumerate ( )
252
+ . map ( |( index, ( ty, pattern) ) | {
253
+ let lvalue = Lvalue :: Arg ( index as u32 ) ;
254
+ if let Some ( pattern) = pattern {
255
+ let pattern = self . hir . irrefutable_pat ( pattern) ;
256
+ unpack ! ( block = self . lvalue_into_pattern( block,
257
+ argument_scope_id,
258
+ pattern,
259
+ & lvalue) ) ;
260
+ }
261
+
262
+ // Make sure we drop (parts of) the argument even when not matched on.
263
+ let argument_extent = self . scope_auxiliary [ argument_scope_id] . extent ;
264
+ self . schedule_drop ( pattern. as_ref ( ) . map_or ( ast_block. span , |pat| pat. span ) ,
265
+ argument_extent, & lvalue, ty) ;
266
+
267
+ ArgDecl { ty : ty, spread : false }
268
+ } )
269
+ . collect ( ) ;
270
+
271
+ // start the first basic block and translate the body
272
+ unpack ! ( block = self . ast_block( & Lvalue :: ReturnPointer , block, ast_block) ) ;
273
+
274
+ block. and ( arg_decls)
258
275
}
259
276
260
277
fn get_unit_temp ( & mut self ) -> Lvalue < ' tcx > {
0 commit comments