@@ -22,6 +22,7 @@ use std::cell::RefCell;
2222use std:: marker:: PhantomData ;
2323use std:: ops:: { ControlFlow , Deref } ;
2424
25+ use nll:: YieldComputeRegions ;
2526use root_cx:: BorrowCheckRootCtxt ;
2627use rustc_abi:: FieldIdx ;
2728use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
@@ -52,6 +53,7 @@ use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT};
5253use rustc_span:: { ErrorGuaranteed , Span , Symbol } ;
5354use smallvec:: SmallVec ;
5455use tracing:: { debug, instrument} ;
56+ use type_check:: Locations ;
5557
5658use crate :: borrow_set:: { BorrowData , BorrowSet } ;
5759use crate :: consumers:: { BodyWithBorrowckFacts , ConsumerOptions } ;
@@ -125,12 +127,8 @@ fn mir_borrowck(
125127 let opaque_types = ConcreteOpaqueTypes ( Default :: default ( ) ) ;
126128 Ok ( tcx. arena . alloc ( opaque_types) )
127129 } 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
134132 }
135133}
136134
@@ -142,6 +140,8 @@ struct PropagatedBorrowCheckResults<'tcx> {
142140 used_mut_upvars : SmallVec < [ FieldIdx ; 8 ] > ,
143141}
144142
143+ type DeferredClosureRequirements < ' tcx > = Vec < ( LocalDefId , ty:: GenericArgsRef < ' tcx > , Locations ) > ;
144+
145145/// After we borrow check a closure, we are left with various
146146/// requirements that we have inferred between the free regions that
147147/// appear in the closure's signature or on its field types. These
@@ -280,6 +280,17 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
280280 }
281281}
282282
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+
283294/// Perform the actual borrow checking.
284295///
285296/// Use `consumer_options: None` for the default behavior of returning
@@ -288,11 +299,11 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
288299///
289300/// For nested bodies this should only be called through `root_cx.get_or_insert_nested`.
290301#[ instrument( skip( root_cx) , level = "debug" ) ]
291- fn do_mir_borrowck < ' tcx > (
302+ fn start_do_mir_borrowck < ' tcx > (
292303 root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
293304 def : LocalDefId ,
294305 consumer_options : Option < ConsumerOptions > ,
295- ) -> ( PropagatedBorrowCheckResults < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
306+ ) -> YieldDoMirBorrowck < ' tcx > {
296307 let tcx = root_cx. tcx ;
297308 let infcx = BorrowckInferCtxt :: new ( tcx, def) ;
298309 let ( input_body, promoted) = tcx. mir_promoted ( def) ;
@@ -303,33 +314,13 @@ fn do_mir_borrowck<'tcx>(
303314 root_cx. set_tainted_by_errors ( e) ;
304315 }
305316
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-
326317 // Replace all regions with fresh inference variables. This
327318 // requires first making our own copy of the MIR. This copy will
328319 // be modified (in place) to contain non-lexical lifetimes. It
329320 // will have a lifetime tied to the inference context.
330321 let mut body_owned = input_body. clone ( ) ;
331322 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) ;
333324 let body = & body_owned; // no further changes
334325
335326 let location_table = PoloniusLocationTable :: new ( body) ;
@@ -343,6 +334,50 @@ fn do_mir_borrowck<'tcx>(
343334 let locals_are_invalidated_at_exit = tcx. hir_body_owner_kind ( def) . is_fn_or_closure ( ) ;
344335 let borrow_set = BorrowSet :: build ( tcx, body, locals_are_invalidated_at_exit, & move_data) ;
345336
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+
346381 // Compute non-lexical lifetimes.
347382 let nll:: NllOutput {
348383 regioncx,
@@ -351,17 +386,15 @@ fn do_mir_borrowck<'tcx>(
351386 opt_closure_req,
352387 nll_errors,
353388 polonius_diagnostics,
354- } = nll:: compute_regions (
389+ } = nll:: resume_compute_regions (
355390 root_cx,
356391 & infcx,
357- free_regions,
358392 body,
359- & promoted,
360393 & location_table,
361- flow_inits,
362394 & move_data,
363395 & borrow_set,
364396 consumer_options,
397+ yield_compute_regions,
365398 ) ;
366399
367400 // Dump MIR results into a file, if that is enabled. This lets us
@@ -376,14 +409,14 @@ fn do_mir_borrowck<'tcx>(
376409 let movable_coroutine =
377410 // The first argument is the coroutine type passed by value
378411 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+ } ;
387420
388421 // While promoteds should mostly be correct by construction, we need to check them for
389422 // invalid moves to detect moving out of arrays:`struct S; fn main() { &([S][0]); }`.
@@ -434,6 +467,26 @@ fn do_mir_borrowck<'tcx>(
434467 promoted_mbcx. report_move_errors ( ) ;
435468 }
436469
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+
437490 let mut mbcx = MirBorrowckCtxt {
438491 root_cx,
439492 infcx : & infcx,
0 commit comments