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