@@ -21,11 +21,15 @@ use std::borrow::Cow;
2121use std:: cell:: RefCell ;
2222use std:: marker:: PhantomData ;
2323use std:: ops:: { ControlFlow , Deref } ;
24+ use std:: rc:: Rc ;
2425
2526use borrow_set:: LocalsStateAtExit ;
2627use diagnostics:: RegionErrors ;
28+ use polonius_engine:: AllFacts ;
29+ use region_infer:: opaque_types:: DeferredOpaqueTypeError ;
2730use root_cx:: BorrowCheckRootCtxt ;
2831use rustc_abi:: FieldIdx ;
32+ use rustc_data_structures:: frozen:: Frozen ;
2933use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
3034use rustc_data_structures:: graph:: dominators:: Dominators ;
3135use rustc_errors:: LintDiagnostic ;
@@ -34,6 +38,7 @@ use rustc_hir::CRATE_HIR_ID;
3438use rustc_hir:: def_id:: LocalDefId ;
3539use rustc_index:: bit_set:: { DenseBitSet , MixedBitSet } ;
3640use rustc_index:: { IndexSlice , IndexVec } ;
41+ use rustc_infer:: infer:: outlives:: env:: RegionBoundPairs ;
3742use rustc_infer:: infer:: {
3843 InferCtxt , NllRegionVariableOrigin , RegionVariableOrigin , TyCtxtInferExt ,
3944} ;
@@ -49,23 +54,28 @@ use rustc_mir_dataflow::impls::{
4954use rustc_mir_dataflow:: move_paths:: {
5055 InitIndex , InitLocation , LookupResult , MoveData , MovePathIndex ,
5156} ;
57+ use rustc_mir_dataflow:: points:: DenseLocationMap ;
5258use rustc_mir_dataflow:: { Analysis , EntryStates , Results , ResultsVisitor , visit_results} ;
5359use rustc_session:: lint:: builtin:: { TAIL_EXPR_DROP_ORDER , UNUSED_MUT } ;
5460use rustc_span:: { ErrorGuaranteed , Span , Symbol } ;
5561use smallvec:: SmallVec ;
5662use tracing:: { debug, instrument} ;
63+ use type_check:: free_region_relations:: UniversalRegionRelations ;
64+ use type_check:: { Locations , MirTypeckRegionConstraints , MirTypeckResults } ;
5765
5866use crate :: borrow_set:: { BorrowData , BorrowSet } ;
59- use crate :: consumers:: { BodyWithBorrowckFacts , ConsumerOptions } ;
67+ use crate :: consumers:: { BodyWithBorrowckFacts , ConsumerOptions , RustcFacts } ;
6068use crate :: dataflow:: { BorrowIndex , Borrowck , BorrowckDomain , Borrows } ;
6169use crate :: diagnostics:: {
6270 AccessKind , BorrowckDiagnosticsBuffer , IllegalMoveOriginKind , MoveError , RegionName ,
6371} ;
6472use crate :: path_utils:: * ;
6573use crate :: place_ext:: PlaceExt ;
6674use 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 } ;
6979use crate :: prefixes:: PrefixSet ;
7080use crate :: region_infer:: RegionInferenceContext ;
7181use crate :: renumber:: RegionCtxt ;
@@ -127,12 +137,8 @@ fn mir_borrowck(
127137 let opaque_types = ConcreteOpaqueTypes ( Default :: default ( ) ) ;
128138 Ok ( tcx. arena . alloc ( opaque_types) )
129139 } 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
136142 }
137143}
138144
@@ -144,6 +150,8 @@ struct PropagatedBorrowCheckResults<'tcx> {
144150 used_mut_upvars : SmallVec < [ FieldIdx ; 8 ] > ,
145151}
146152
153+ type DeferredClosureRequirements < ' tcx > = Vec < ( LocalDefId , ty:: GenericArgsRef < ' tcx > , Locations ) > ;
154+
147155/// After we borrow check a closure, we are left with various
148156/// requirements that we have inferred between the free regions that
149157/// appear in the closure's signature or on its field types. These
@@ -282,6 +290,24 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
282290 }
283291}
284292
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+
285311/// Perform the actual borrow checking.
286312///
287313/// Use `consumer_options: None` for the default behavior of returning
@@ -290,11 +316,11 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
290316///
291317/// For nested bodies this should only be called through `root_cx.get_or_insert_nested`.
292318#[ instrument( skip( root_cx) , level = "debug" ) ]
293- fn do_mir_borrowck < ' tcx > (
319+ fn start_do_mir_borrowck < ' tcx > (
294320 root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
295321 def : LocalDefId ,
296322 consumer_options : Option < ConsumerOptions > ,
297- ) -> ( PropagatedBorrowCheckResults < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
323+ ) -> BorrowckState < ' tcx > {
298324 let tcx = root_cx. tcx ;
299325 let infcx = BorrowckInferCtxt :: new ( tcx, def) ;
300326 let ( input_body, promoted) = tcx. mir_promoted ( def) ;
@@ -315,6 +341,7 @@ fn do_mir_borrowck<'tcx>(
315341 let body = & body_owned; // no further changes
316342
317343 let location_table = PoloniusLocationTable :: new ( body) ;
344+ let location_map = Rc :: new ( DenseLocationMap :: new ( body) ) ;
318345
319346 let move_data = MoveData :: gather_moves ( body, tcx, |_| true ) ;
320347
@@ -325,6 +352,78 @@ fn do_mir_borrowck<'tcx>(
325352 let locals_are_invalidated_at_exit = tcx. hir_body_owner_kind ( def) . is_fn_or_closure ( ) ;
326353 let borrow_set = BorrowSet :: build ( tcx, body, locals_are_invalidated_at_exit, & move_data) ;
327354
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+
328427 // Compute non-lexical lifetimes.
329428 let nll:: NllOutput {
330429 regioncx,
@@ -336,14 +435,17 @@ fn do_mir_borrowck<'tcx>(
336435 } = nll:: compute_regions (
337436 root_cx,
338437 & infcx,
339- universal_regions,
340438 body,
341- & promoted,
342439 & location_table,
343- flow_inits,
344440 & move_data,
345441 & borrow_set,
442+ location_map,
346443 consumer_options,
444+ universal_region_relations,
445+ constraints,
446+ deferred_opaque_type_errors,
447+ polonius_facts,
448+ polonius_context,
347449 ) ;
348450
349451 // Dump MIR results into a file, if that is enabled. This lets us
0 commit comments