@@ -22,6 +22,7 @@ use std::cell::RefCell;
22
22
use std:: marker:: PhantomData ;
23
23
use std:: ops:: { ControlFlow , Deref } ;
24
24
25
+ use nll:: YieldComputeRegions ;
25
26
use root_cx:: BorrowCheckRootCtxt ;
26
27
use rustc_abi:: FieldIdx ;
27
28
use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
@@ -52,6 +53,7 @@ use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT};
52
53
use rustc_span:: { ErrorGuaranteed , Span , Symbol } ;
53
54
use smallvec:: SmallVec ;
54
55
use tracing:: { debug, instrument} ;
56
+ use type_check:: Locations ;
55
57
56
58
use crate :: borrow_set:: { BorrowData , BorrowSet } ;
57
59
use crate :: consumers:: { BodyWithBorrowckFacts , ConsumerOptions } ;
@@ -125,12 +127,8 @@ fn mir_borrowck(
125
127
let opaque_types = ConcreteOpaqueTypes ( Default :: default ( ) ) ;
126
128
Ok ( tcx. arena . alloc ( opaque_types) )
127
129
} else {
128
- let mut root_cx = BorrowCheckRootCtxt :: new ( tcx, def) ;
129
- let PropagatedBorrowCheckResults { closure_requirements, used_mut_upvars } =
130
- do_mir_borrowck ( & mut root_cx, def, None ) . 0 ;
131
- debug_assert ! ( closure_requirements. is_none( ) ) ;
132
- debug_assert ! ( used_mut_upvars. is_empty( ) ) ;
133
- root_cx. finalize ( )
130
+ let root_cx = BorrowCheckRootCtxt :: new ( tcx, def) ;
131
+ root_cx. borrowck_root ( None ) . 0
134
132
}
135
133
}
136
134
@@ -142,6 +140,8 @@ struct PropagatedBorrowCheckResults<'tcx> {
142
140
used_mut_upvars : SmallVec < [ FieldIdx ; 8 ] > ,
143
141
}
144
142
143
+ type DeferredClosureRequirements < ' tcx > = Vec < ( LocalDefId , ty:: GenericArgsRef < ' tcx > , Locations ) > ;
144
+
145
145
/// After we borrow check a closure, we are left with various
146
146
/// requirements that we have inferred between the free regions that
147
147
/// appear in the closure's signature or on its field types. These
@@ -280,6 +280,17 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
280
280
}
281
281
}
282
282
283
+ struct YieldDoMirBorrowck < ' tcx > {
284
+ infcx : BorrowckInferCtxt < ' tcx > ,
285
+ body_owned : Body < ' tcx > ,
286
+ promoted : IndexVec < Promoted , Body < ' tcx > > ,
287
+ move_data : MoveData < ' tcx > ,
288
+ locals_are_invalidated_at_exit : bool ,
289
+ borrow_set : BorrowSet < ' tcx > ,
290
+ location_table : PoloniusLocationTable ,
291
+ yield_compute_regions : YieldComputeRegions < ' tcx > ,
292
+ }
293
+
283
294
/// Perform the actual borrow checking.
284
295
///
285
296
/// Use `consumer_options: None` for the default behavior of returning
@@ -288,11 +299,11 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
288
299
///
289
300
/// For nested bodies this should only be called through `root_cx.get_or_insert_nested`.
290
301
#[ instrument( skip( root_cx) , level = "debug" ) ]
291
- fn do_mir_borrowck < ' tcx > (
302
+ fn start_do_mir_borrowck < ' tcx > (
292
303
root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
293
304
def : LocalDefId ,
294
305
consumer_options : Option < ConsumerOptions > ,
295
- ) -> ( PropagatedBorrowCheckResults < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
306
+ ) -> YieldDoMirBorrowck < ' tcx > {
296
307
let tcx = root_cx. tcx ;
297
308
let infcx = BorrowckInferCtxt :: new ( tcx, def) ;
298
309
let ( input_body, promoted) = tcx. mir_promoted ( def) ;
@@ -303,33 +314,13 @@ fn do_mir_borrowck<'tcx>(
303
314
root_cx. set_tainted_by_errors ( e) ;
304
315
}
305
316
306
- let mut local_names = IndexVec :: from_elem ( None , & input_body. local_decls ) ;
307
- for var_debug_info in & input_body. var_debug_info {
308
- if let VarDebugInfoContents :: Place ( place) = var_debug_info. value {
309
- if let Some ( local) = place. as_local ( ) {
310
- if let Some ( prev_name) = local_names[ local]
311
- && var_debug_info. name != prev_name
312
- {
313
- span_bug ! (
314
- var_debug_info. source_info. span,
315
- "local {:?} has many names (`{}` vs `{}`)" ,
316
- local,
317
- prev_name,
318
- var_debug_info. name
319
- ) ;
320
- }
321
- local_names[ local] = Some ( var_debug_info. name ) ;
322
- }
323
- }
324
- }
325
-
326
317
// Replace all regions with fresh inference variables. This
327
318
// requires first making our own copy of the MIR. This copy will
328
319
// be modified (in place) to contain non-lexical lifetimes. It
329
320
// will have a lifetime tied to the inference context.
330
321
let mut body_owned = input_body. clone ( ) ;
331
322
let mut promoted = input_promoted. to_owned ( ) ;
332
- let free_regions = nll:: replace_regions_in_mir ( & infcx, & mut body_owned, & mut promoted) ;
323
+ let universal_regions = nll:: replace_regions_in_mir ( & infcx, & mut body_owned, & mut promoted) ;
333
324
let body = & body_owned; // no further changes
334
325
335
326
let location_table = PoloniusLocationTable :: new ( body) ;
@@ -343,6 +334,50 @@ fn do_mir_borrowck<'tcx>(
343
334
let locals_are_invalidated_at_exit = tcx. hir_body_owner_kind ( def) . is_fn_or_closure ( ) ;
344
335
let borrow_set = BorrowSet :: build ( tcx, body, locals_are_invalidated_at_exit, & move_data) ;
345
336
337
+ let yield_compute_regions = nll:: compute_regions (
338
+ root_cx,
339
+ & infcx,
340
+ universal_regions,
341
+ body,
342
+ & promoted,
343
+ & location_table,
344
+ flow_inits,
345
+ & move_data,
346
+ & borrow_set,
347
+ consumer_options,
348
+ ) ;
349
+
350
+ YieldDoMirBorrowck {
351
+ infcx,
352
+ body_owned,
353
+ promoted,
354
+ move_data,
355
+ locals_are_invalidated_at_exit,
356
+ borrow_set,
357
+ location_table,
358
+ yield_compute_regions,
359
+ }
360
+ }
361
+
362
+ fn resume_do_mir_borrowck < ' tcx > (
363
+ root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
364
+ def : LocalDefId ,
365
+ consumer_options : Option < ConsumerOptions > ,
366
+ YieldDoMirBorrowck {
367
+ infcx,
368
+ body_owned,
369
+ promoted,
370
+ move_data,
371
+ locals_are_invalidated_at_exit,
372
+ borrow_set,
373
+ location_table,
374
+ yield_compute_regions,
375
+ } : YieldDoMirBorrowck < ' tcx > ,
376
+ ) -> ( PropagatedBorrowCheckResults < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
377
+ assert ! ( !infcx. has_opaque_types_in_storage( ) ) ;
378
+ let tcx = infcx. tcx ;
379
+ let body = & body_owned;
380
+
346
381
// Compute non-lexical lifetimes.
347
382
let nll:: NllOutput {
348
383
regioncx,
@@ -351,17 +386,15 @@ fn do_mir_borrowck<'tcx>(
351
386
opt_closure_req,
352
387
nll_errors,
353
388
polonius_diagnostics,
354
- } = nll:: compute_regions (
389
+ } = nll:: resume_compute_regions (
355
390
root_cx,
356
391
& infcx,
357
- free_regions,
358
392
body,
359
- & promoted,
360
393
& location_table,
361
- flow_inits,
362
394
& move_data,
363
395
& borrow_set,
364
396
consumer_options,
397
+ yield_compute_regions,
365
398
) ;
366
399
367
400
// Dump MIR results into a file, if that is enabled. This lets us
@@ -376,14 +409,14 @@ fn do_mir_borrowck<'tcx>(
376
409
let movable_coroutine =
377
410
// The first argument is the coroutine type passed by value
378
411
if let Some ( local) = body. local_decls . raw . get ( 1 )
379
- // Get the interior types and args which typeck computed
380
- && let ty:: Coroutine ( def_id, _) = * local. ty . kind ( )
381
- && tcx. coroutine_movability ( def_id) == hir:: Movability :: Movable
382
- {
383
- true
384
- } else {
385
- false
386
- } ;
412
+ // Get the interior types and args which typeck computed
413
+ && let ty:: Coroutine ( def_id, _) = * local. ty . kind ( )
414
+ && tcx. coroutine_movability ( def_id) == hir:: Movability :: Movable
415
+ {
416
+ true
417
+ } else {
418
+ false
419
+ } ;
387
420
388
421
// While promoteds should mostly be correct by construction, we need to check them for
389
422
// invalid moves to detect moving out of arrays:`struct S; fn main() { &([S][0]); }`.
@@ -434,6 +467,26 @@ fn do_mir_borrowck<'tcx>(
434
467
promoted_mbcx. report_move_errors ( ) ;
435
468
}
436
469
470
+ let mut local_names = IndexVec :: from_elem ( None , & body. local_decls ) ;
471
+ for var_debug_info in & body. var_debug_info {
472
+ if let VarDebugInfoContents :: Place ( place) = var_debug_info. value {
473
+ if let Some ( local) = place. as_local ( ) {
474
+ if let Some ( prev_name) = local_names[ local]
475
+ && var_debug_info. name != prev_name
476
+ {
477
+ span_bug ! (
478
+ var_debug_info. source_info. span,
479
+ "local {:?} has many names (`{}` vs `{}`)" ,
480
+ local,
481
+ prev_name,
482
+ var_debug_info. name
483
+ ) ;
484
+ }
485
+ local_names[ local] = Some ( var_debug_info. name ) ;
486
+ }
487
+ }
488
+ }
489
+
437
490
let mut mbcx = MirBorrowckCtxt {
438
491
root_cx,
439
492
infcx : & infcx,
0 commit comments