@@ -25,7 +25,9 @@ use rustc_hir as hir;
25
25
use rustc_hir:: def_id:: LocalDefId ;
26
26
use rustc_index:: bit_set:: ChunkedBitSet ;
27
27
use rustc_index:: vec:: IndexVec ;
28
- use rustc_infer:: infer:: { DefiningAnchor , InferCtxt , TyCtxtInferExt } ;
28
+ use rustc_infer:: infer:: {
29
+ DefiningAnchor , InferCtxt , NllRegionVariableOrigin , RegionVariableOrigin , TyCtxtInferExt ,
30
+ } ;
29
31
use rustc_middle:: mir:: {
30
32
traversal, Body , ClearCrossCrate , Local , Location , Mutability , NonDivergingIntrinsic , Operand ,
31
33
Place , PlaceElem , PlaceRef , VarDebugInfoContents ,
@@ -43,6 +45,7 @@ use smallvec::SmallVec;
43
45
use std:: cell:: OnceCell ;
44
46
use std:: cell:: RefCell ;
45
47
use std:: collections:: BTreeMap ;
48
+ use std:: ops:: Deref ;
46
49
use std:: rc:: Rc ;
47
50
48
51
use rustc_mir_dataflow:: impls:: {
@@ -94,6 +97,7 @@ use nll::{PoloniusOutput, ToRegionVid};
94
97
use place_ext:: PlaceExt ;
95
98
use places_conflict:: { places_conflict, PlaceConflictBias } ;
96
99
use region_infer:: RegionInferenceContext ;
100
+ use renumber:: RegionCtxt ;
97
101
98
102
// FIXME(eddyb) perhaps move this somewhere more centrally.
99
103
#[ derive( Debug ) ]
@@ -167,10 +171,10 @@ fn do_mir_borrowck<'tcx>(
167
171
return_body_with_facts : bool ,
168
172
) -> ( BorrowCheckResult < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
169
173
let def = input_body. source . with_opt_param ( ) . as_local ( ) . unwrap ( ) ;
170
-
171
174
debug ! ( ?def) ;
172
175
173
176
let tcx = infcx. tcx ;
177
+ let infcx = BorrowckInferCtxt :: new ( infcx) ;
174
178
let param_env = tcx. param_env ( def. did ) ;
175
179
176
180
let mut local_names = IndexVec :: from_elem ( None , & input_body. local_decls ) ;
@@ -218,7 +222,7 @@ fn do_mir_borrowck<'tcx>(
218
222
let mut body_owned = input_body. clone ( ) ;
219
223
let mut promoted = input_promoted. clone ( ) ;
220
224
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) ;
222
226
let body = & body_owned; // no further changes
223
227
224
228
let location_table_owned = LocationTable :: new ( body) ;
@@ -256,7 +260,7 @@ fn do_mir_borrowck<'tcx>(
256
260
opt_closure_req,
257
261
nll_errors,
258
262
} = nll:: compute_regions (
259
- infcx,
263
+ & infcx,
260
264
free_regions,
261
265
body,
262
266
& promoted,
@@ -271,12 +275,12 @@ fn do_mir_borrowck<'tcx>(
271
275
272
276
// Dump MIR results into a file, if that is enabled. This let us
273
277
// 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) ;
275
279
276
280
// We also have a `#[rustc_regions]` annotation that causes us to dump
277
281
// information.
278
282
nll:: dump_annotation (
279
- infcx,
283
+ & infcx,
280
284
& body,
281
285
& regioncx,
282
286
& opt_closure_req,
@@ -320,7 +324,7 @@ fn do_mir_borrowck<'tcx>(
320
324
321
325
if let Err ( ( move_data, move_errors) ) = move_data_results {
322
326
let mut promoted_mbcx = MirBorrowckCtxt {
323
- infcx,
327
+ infcx : & infcx ,
324
328
param_env,
325
329
body : promoted_body,
326
330
move_data : & move_data,
@@ -349,7 +353,7 @@ fn do_mir_borrowck<'tcx>(
349
353
}
350
354
351
355
let mut mbcx = MirBorrowckCtxt {
352
- infcx,
356
+ infcx : & infcx ,
353
357
param_env,
354
358
body,
355
359
move_data : & mdpe. move_data ,
@@ -481,8 +485,84 @@ pub struct BodyWithBorrowckFacts<'tcx> {
481
485
pub location_table : LocationTable ,
482
486
}
483
487
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
+
484
564
struct MirBorrowckCtxt < ' cx , ' tcx > {
485
- infcx : & ' cx InferCtxt < ' tcx > ,
565
+ infcx : & ' cx BorrowckInferCtxt < ' cx , ' tcx > ,
486
566
param_env : ParamEnv < ' tcx > ,
487
567
body : & ' cx Body < ' tcx > ,
488
568
move_data : & ' cx MoveData < ' tcx > ,
0 commit comments