@@ -21,11 +21,15 @@ use std::borrow::Cow;
21
21
use std:: cell:: RefCell ;
22
22
use std:: marker:: PhantomData ;
23
23
use std:: ops:: { ControlFlow , Deref } ;
24
+ use std:: rc:: Rc ;
24
25
25
26
use borrow_set:: LocalsStateAtExit ;
26
27
use diagnostics:: RegionErrors ;
28
+ use polonius_engine:: AllFacts ;
29
+ use region_infer:: opaque_types:: DeferredOpaqueTypeError ;
27
30
use root_cx:: BorrowCheckRootCtxt ;
28
31
use rustc_abi:: FieldIdx ;
32
+ use rustc_data_structures:: frozen:: Frozen ;
29
33
use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
30
34
use rustc_data_structures:: graph:: dominators:: Dominators ;
31
35
use rustc_errors:: LintDiagnostic ;
@@ -34,6 +38,7 @@ use rustc_hir::CRATE_HIR_ID;
34
38
use rustc_hir:: def_id:: LocalDefId ;
35
39
use rustc_index:: bit_set:: { DenseBitSet , MixedBitSet } ;
36
40
use rustc_index:: { IndexSlice , IndexVec } ;
41
+ use rustc_infer:: infer:: outlives:: env:: RegionBoundPairs ;
37
42
use rustc_infer:: infer:: {
38
43
InferCtxt , NllRegionVariableOrigin , RegionVariableOrigin , TyCtxtInferExt ,
39
44
} ;
@@ -49,23 +54,28 @@ use rustc_mir_dataflow::impls::{
49
54
use rustc_mir_dataflow:: move_paths:: {
50
55
InitIndex , InitLocation , LookupResult , MoveData , MovePathIndex ,
51
56
} ;
57
+ use rustc_mir_dataflow:: points:: DenseLocationMap ;
52
58
use rustc_mir_dataflow:: { Analysis , EntryStates , Results , ResultsVisitor , visit_results} ;
53
59
use rustc_session:: lint:: builtin:: { TAIL_EXPR_DROP_ORDER , UNUSED_MUT } ;
54
60
use rustc_span:: { ErrorGuaranteed , Span , Symbol } ;
55
61
use smallvec:: SmallVec ;
56
62
use tracing:: { debug, instrument} ;
63
+ use type_check:: free_region_relations:: UniversalRegionRelations ;
64
+ use type_check:: { Locations , MirTypeckRegionConstraints , MirTypeckResults } ;
57
65
58
66
use crate :: borrow_set:: { BorrowData , BorrowSet } ;
59
- use crate :: consumers:: { BodyWithBorrowckFacts , ConsumerOptions } ;
67
+ use crate :: consumers:: { BodyWithBorrowckFacts , ConsumerOptions , RustcFacts } ;
60
68
use crate :: dataflow:: { BorrowIndex , Borrowck , BorrowckDomain , Borrows } ;
61
69
use crate :: diagnostics:: {
62
70
AccessKind , BorrowckDiagnosticsBuffer , IllegalMoveOriginKind , MoveError , RegionName ,
63
71
} ;
64
72
use crate :: path_utils:: * ;
65
73
use crate :: place_ext:: PlaceExt ;
66
74
use crate :: places_conflict:: { PlaceConflictBias , places_conflict} ;
67
- use crate :: polonius:: PoloniusDiagnosticsContext ;
68
- use crate :: polonius:: legacy:: { PoloniusLocationTable , PoloniusOutput } ;
75
+ use crate :: polonius:: legacy:: {
76
+ PoloniusFacts , PoloniusFactsExt , PoloniusLocationTable , PoloniusOutput ,
77
+ } ;
78
+ use crate :: polonius:: { PoloniusContext , PoloniusDiagnosticsContext } ;
69
79
use crate :: prefixes:: PrefixSet ;
70
80
use crate :: region_infer:: RegionInferenceContext ;
71
81
use crate :: renumber:: RegionCtxt ;
@@ -127,12 +137,8 @@ fn mir_borrowck(
127
137
let opaque_types = ConcreteOpaqueTypes ( Default :: default ( ) ) ;
128
138
Ok ( tcx. arena . alloc ( opaque_types) )
129
139
} else {
130
- let mut root_cx = BorrowCheckRootCtxt :: new ( tcx, def) ;
131
- let PropagatedBorrowCheckResults { closure_requirements, used_mut_upvars } =
132
- do_mir_borrowck ( & mut root_cx, def, None ) . 0 ;
133
- debug_assert ! ( closure_requirements. is_none( ) ) ;
134
- debug_assert ! ( used_mut_upvars. is_empty( ) ) ;
135
- root_cx. finalize ( )
140
+ let root_cx = BorrowCheckRootCtxt :: new ( tcx, def) ;
141
+ root_cx. borrowck_root ( None ) . 0
136
142
}
137
143
}
138
144
@@ -144,6 +150,8 @@ struct PropagatedBorrowCheckResults<'tcx> {
144
150
used_mut_upvars : SmallVec < [ FieldIdx ; 8 ] > ,
145
151
}
146
152
153
+ type DeferredClosureRequirements < ' tcx > = Vec < ( LocalDefId , ty:: GenericArgsRef < ' tcx > , Locations ) > ;
154
+
147
155
/// After we borrow check a closure, we are left with various
148
156
/// requirements that we have inferred between the free regions that
149
157
/// appear in the closure's signature or on its field types. These
@@ -282,6 +290,24 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
282
290
}
283
291
}
284
292
293
+ struct BorrowckState < ' tcx > {
294
+ infcx : BorrowckInferCtxt < ' tcx > ,
295
+ body_owned : Body < ' tcx > ,
296
+ promoted : IndexVec < Promoted , Body < ' tcx > > ,
297
+ move_data : MoveData < ' tcx > ,
298
+ borrow_set : BorrowSet < ' tcx > ,
299
+ location_table : PoloniusLocationTable ,
300
+ location_map : Rc < DenseLocationMap > ,
301
+ universal_region_relations : Frozen < UniversalRegionRelations < ' tcx > > ,
302
+ region_bound_pairs : Frozen < RegionBoundPairs < ' tcx > > ,
303
+ known_type_outlives_obligations : Frozen < Vec < ty:: PolyTypeOutlivesPredicate < ' tcx > > > ,
304
+ constraints : MirTypeckRegionConstraints < ' tcx > ,
305
+ deferred_closure_requirements : DeferredClosureRequirements < ' tcx > ,
306
+ deferred_opaque_type_errors : Vec < DeferredOpaqueTypeError < ' tcx > > ,
307
+ polonius_facts : Option < AllFacts < RustcFacts > > ,
308
+ polonius_context : Option < PoloniusContext > ,
309
+ }
310
+
285
311
/// Perform the actual borrow checking.
286
312
///
287
313
/// Use `consumer_options: None` for the default behavior of returning
@@ -290,11 +316,11 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
290
316
///
291
317
/// For nested bodies this should only be called through `root_cx.get_or_insert_nested`.
292
318
#[ instrument( skip( root_cx) , level = "debug" ) ]
293
- fn do_mir_borrowck < ' tcx > (
319
+ fn start_do_mir_borrowck < ' tcx > (
294
320
root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
295
321
def : LocalDefId ,
296
322
consumer_options : Option < ConsumerOptions > ,
297
- ) -> ( PropagatedBorrowCheckResults < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
323
+ ) -> BorrowckState < ' tcx > {
298
324
let tcx = root_cx. tcx ;
299
325
let infcx = BorrowckInferCtxt :: new ( tcx, def) ;
300
326
let ( input_body, promoted) = tcx. mir_promoted ( def) ;
@@ -315,6 +341,7 @@ fn do_mir_borrowck<'tcx>(
315
341
let body = & body_owned; // no further changes
316
342
317
343
let location_table = PoloniusLocationTable :: new ( body) ;
344
+ let location_map = Rc :: new ( DenseLocationMap :: new ( body) ) ;
318
345
319
346
let move_data = MoveData :: gather_moves ( body, tcx, |_| true ) ;
320
347
@@ -325,6 +352,78 @@ fn do_mir_borrowck<'tcx>(
325
352
let locals_are_invalidated_at_exit = tcx. hir_body_owner_kind ( def) . is_fn_or_closure ( ) ;
326
353
let borrow_set = BorrowSet :: build ( tcx, body, locals_are_invalidated_at_exit, & move_data) ;
327
354
355
+ let is_polonius_legacy_enabled = infcx. tcx . sess . opts . unstable_opts . polonius . is_legacy_enabled ( ) ;
356
+ let polonius_input = consumer_options. map ( |c| c. polonius_input ( ) ) . unwrap_or_default ( )
357
+ || is_polonius_legacy_enabled;
358
+ let mut polonius_facts =
359
+ ( polonius_input || PoloniusFacts :: enabled ( infcx. tcx ) ) . then_some ( PoloniusFacts :: default ( ) ) ;
360
+
361
+ // Run the MIR type-checker.
362
+ let MirTypeckResults {
363
+ constraints,
364
+ universal_region_relations,
365
+ region_bound_pairs,
366
+ known_type_outlives_obligations,
367
+ deferred_closure_requirements,
368
+ polonius_context,
369
+ } = type_check:: type_check (
370
+ root_cx,
371
+ & infcx,
372
+ & body,
373
+ & promoted,
374
+ universal_regions,
375
+ & location_table,
376
+ & borrow_set,
377
+ & mut polonius_facts,
378
+ flow_inits,
379
+ & move_data,
380
+ Rc :: clone ( & location_map) ,
381
+ ) ;
382
+
383
+ BorrowckState {
384
+ infcx,
385
+ body_owned,
386
+ promoted,
387
+ move_data,
388
+ borrow_set,
389
+ location_table,
390
+ location_map,
391
+ universal_region_relations,
392
+ region_bound_pairs,
393
+ known_type_outlives_obligations,
394
+ constraints,
395
+ deferred_closure_requirements,
396
+ deferred_opaque_type_errors : Default :: default ( ) ,
397
+ polonius_facts,
398
+ polonius_context,
399
+ }
400
+ }
401
+
402
+ fn resume_do_mir_borrowck < ' tcx > (
403
+ root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
404
+ consumer_options : Option < ConsumerOptions > ,
405
+ BorrowckState {
406
+ infcx,
407
+ body_owned,
408
+ promoted,
409
+ move_data,
410
+ borrow_set,
411
+ location_table,
412
+ location_map,
413
+ universal_region_relations,
414
+ region_bound_pairs : _,
415
+ known_type_outlives_obligations : _,
416
+ constraints,
417
+ deferred_closure_requirements,
418
+ deferred_opaque_type_errors,
419
+ polonius_facts,
420
+ polonius_context,
421
+ } : BorrowckState < ' tcx > ,
422
+ ) -> ( PropagatedBorrowCheckResults < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
423
+ assert ! ( !infcx. has_opaque_types_in_storage( ) ) ;
424
+ assert ! ( deferred_closure_requirements. is_empty( ) ) ;
425
+ let body = & body_owned;
426
+
328
427
// Compute non-lexical lifetimes.
329
428
let nll:: NllOutput {
330
429
regioncx,
@@ -336,14 +435,17 @@ fn do_mir_borrowck<'tcx>(
336
435
} = nll:: compute_regions (
337
436
root_cx,
338
437
& infcx,
339
- universal_regions,
340
438
body,
341
- & promoted,
342
439
& location_table,
343
- flow_inits,
344
440
& move_data,
345
441
& borrow_set,
442
+ location_map,
346
443
consumer_options,
444
+ universal_region_relations,
445
+ constraints,
446
+ deferred_opaque_type_errors,
447
+ polonius_facts,
448
+ polonius_context,
347
449
) ;
348
450
349
451
// Dump MIR results into a file, if that is enabled. This lets us
0 commit comments