@@ -25,7 +25,9 @@ use rustc_hir as hir;
2525use rustc_hir:: def_id:: LocalDefId ;
2626use rustc_index:: bit_set:: ChunkedBitSet ;
2727use rustc_index:: vec:: IndexVec ;
28- use rustc_infer:: infer:: { DefiningAnchor , InferCtxt , TyCtxtInferExt } ;
28+ use rustc_infer:: infer:: {
29+ DefiningAnchor , InferCtxt , NllRegionVariableOrigin , RegionVariableOrigin , TyCtxtInferExt ,
30+ } ;
2931use rustc_middle:: mir:: {
3032 traversal, Body , ClearCrossCrate , Local , Location , Mutability , NonDivergingIntrinsic , Operand ,
3133 Place , PlaceElem , PlaceRef , VarDebugInfoContents ,
@@ -43,6 +45,7 @@ use smallvec::SmallVec;
4345use std:: cell:: OnceCell ;
4446use std:: cell:: RefCell ;
4547use std:: collections:: BTreeMap ;
48+ use std:: ops:: Deref ;
4649use std:: rc:: Rc ;
4750
4851use rustc_mir_dataflow:: impls:: {
@@ -94,6 +97,7 @@ use nll::{PoloniusOutput, ToRegionVid};
9497use place_ext:: PlaceExt ;
9598use places_conflict:: { places_conflict, PlaceConflictBias } ;
9699use region_infer:: RegionInferenceContext ;
100+ use renumber:: RegionCtxt ;
97101
98102// FIXME(eddyb) perhaps move this somewhere more centrally.
99103#[ derive( Debug ) ]
@@ -167,10 +171,10 @@ fn do_mir_borrowck<'tcx>(
167171 return_body_with_facts : bool ,
168172) -> ( BorrowCheckResult < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
169173 let def = input_body. source . with_opt_param ( ) . as_local ( ) . unwrap ( ) ;
170-
171174 debug ! ( ?def) ;
172175
173176 let tcx = infcx. tcx ;
177+ let infcx = BorrowckInferCtxt :: new ( infcx) ;
174178 let param_env = tcx. param_env ( def. did ) ;
175179
176180 let mut local_names = IndexVec :: from_elem ( None , & input_body. local_decls ) ;
@@ -218,7 +222,7 @@ fn do_mir_borrowck<'tcx>(
218222 let mut body_owned = input_body. clone ( ) ;
219223 let mut promoted = input_promoted. clone ( ) ;
220224 let free_regions =
221- nll:: replace_regions_in_mir ( infcx, param_env, & mut body_owned, & mut promoted) ;
225+ nll:: replace_regions_in_mir ( & infcx, param_env, & mut body_owned, & mut promoted) ;
222226 let body = & body_owned; // no further changes
223227
224228 let location_table_owned = LocationTable :: new ( body) ;
@@ -256,7 +260,7 @@ fn do_mir_borrowck<'tcx>(
256260 opt_closure_req,
257261 nll_errors,
258262 } = nll:: compute_regions (
259- infcx,
263+ & infcx,
260264 free_regions,
261265 body,
262266 & promoted,
@@ -271,12 +275,12 @@ fn do_mir_borrowck<'tcx>(
271275
272276 // Dump MIR results into a file, if that is enabled. This let us
273277 // write unit-tests, as well as helping with debugging.
274- nll:: dump_mir_results ( infcx, & body, & regioncx, & opt_closure_req) ;
278+ nll:: dump_mir_results ( & infcx, & body, & regioncx, & opt_closure_req) ;
275279
276280 // We also have a `#[rustc_regions]` annotation that causes us to dump
277281 // information.
278282 nll:: dump_annotation (
279- infcx,
283+ & infcx,
280284 & body,
281285 & regioncx,
282286 & opt_closure_req,
@@ -320,7 +324,7 @@ fn do_mir_borrowck<'tcx>(
320324
321325 if let Err ( ( move_data, move_errors) ) = move_data_results {
322326 let mut promoted_mbcx = MirBorrowckCtxt {
323- infcx,
327+ infcx : & infcx ,
324328 param_env,
325329 body : promoted_body,
326330 move_data : & move_data,
@@ -349,7 +353,7 @@ fn do_mir_borrowck<'tcx>(
349353 }
350354
351355 let mut mbcx = MirBorrowckCtxt {
352- infcx,
356+ infcx : & infcx ,
353357 param_env,
354358 body,
355359 move_data : & mdpe. move_data ,
@@ -481,8 +485,84 @@ pub struct BodyWithBorrowckFacts<'tcx> {
481485 pub location_table : LocationTable ,
482486}
483487
488+ pub struct BorrowckInferCtxt < ' cx , ' tcx > {
489+ pub ( crate ) infcx : & ' cx InferCtxt < ' tcx > ,
490+ pub ( crate ) reg_var_to_origin : RefCell < FxHashMap < ty:: RegionVid , RegionCtxt > > ,
491+ }
492+
493+ impl < ' cx , ' tcx > BorrowckInferCtxt < ' cx , ' tcx > {
494+ pub ( crate ) fn new ( infcx : & ' cx InferCtxt < ' tcx > ) -> Self {
495+ BorrowckInferCtxt { infcx, reg_var_to_origin : RefCell :: new ( Default :: default ( ) ) }
496+ }
497+
498+ pub ( crate ) fn next_region_var < F > (
499+ & self ,
500+ origin : RegionVariableOrigin ,
501+ get_ctxt_fn : F ,
502+ ) -> ty:: Region < ' tcx >
503+ where
504+ F : Fn ( ) -> RegionCtxt ,
505+ {
506+ let next_region = self . infcx . next_region_var ( origin) ;
507+ let vid = next_region
508+ . as_var ( )
509+ . unwrap_or_else ( || bug ! ( "expected RegionKind::RegionVar on {:?}" , next_region) ) ;
510+
511+ if cfg ! ( debug_assertions) {
512+ debug ! ( "inserting vid {:?} with origin {:?} into var_to_origin" , vid, origin) ;
513+ let ctxt = get_ctxt_fn ( ) ;
514+ let mut var_to_origin = self . reg_var_to_origin . borrow_mut ( ) ;
515+ let prev = var_to_origin. insert ( vid, ctxt) ;
516+
517+ // This only makes sense if not called in a canonicalization context. If this
518+ // ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
519+ // or modify how we track nll region vars for that map.
520+ assert ! ( matches!( prev, None ) ) ;
521+ }
522+
523+ next_region
524+ }
525+
526+ #[ instrument( skip( self , get_ctxt_fn) , level = "debug" ) ]
527+ pub ( crate ) fn next_nll_region_var < F > (
528+ & self ,
529+ origin : NllRegionVariableOrigin ,
530+ get_ctxt_fn : F ,
531+ ) -> ty:: Region < ' tcx >
532+ where
533+ F : Fn ( ) -> RegionCtxt ,
534+ {
535+ let next_region = self . infcx . next_nll_region_var ( origin. clone ( ) ) ;
536+ let vid = next_region
537+ . as_var ( )
538+ . unwrap_or_else ( || bug ! ( "expected RegionKind::RegionVar on {:?}" , next_region) ) ;
539+
540+ if cfg ! ( debug_assertions) {
541+ debug ! ( "inserting vid {:?} with origin {:?} into var_to_origin" , vid, origin) ;
542+ let ctxt = get_ctxt_fn ( ) ;
543+ let mut var_to_origin = self . reg_var_to_origin . borrow_mut ( ) ;
544+ let prev = var_to_origin. insert ( vid, ctxt) ;
545+
546+ // This only makes sense if not called in a canonicalization context. If this
547+ // ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
548+ // or modify how we track nll region vars for that map.
549+ assert ! ( matches!( prev, None ) ) ;
550+ }
551+
552+ next_region
553+ }
554+ }
555+
556+ impl < ' cx , ' tcx > Deref for BorrowckInferCtxt < ' cx , ' tcx > {
557+ type Target = InferCtxt < ' tcx > ;
558+
559+ fn deref ( & self ) -> & ' cx Self :: Target {
560+ self . infcx
561+ }
562+ }
563+
484564struct MirBorrowckCtxt < ' cx , ' tcx > {
485- infcx : & ' cx InferCtxt < ' tcx > ,
565+ infcx : & ' cx BorrowckInferCtxt < ' cx , ' tcx > ,
486566 param_env : ParamEnv < ' tcx > ,
487567 body : & ' cx Body < ' tcx > ,
488568 move_data : & ' cx MoveData < ' tcx > ,
0 commit comments