@@ -21,10 +21,14 @@ 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 ;
27+ use polonius_engine:: AllFacts ;
28+ use region_infer:: opaque_types:: DeferredOpaqueTypeError ;
2629use root_cx:: BorrowCheckRootCtxt ;
2730use rustc_abi:: FieldIdx ;
31+ use rustc_data_structures:: frozen:: Frozen ;
2832use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
2933use rustc_data_structures:: graph:: dominators:: Dominators ;
3034use rustc_errors:: LintDiagnostic ;
@@ -33,6 +37,7 @@ use rustc_hir::CRATE_HIR_ID;
3337use rustc_hir:: def_id:: LocalDefId ;
3438use rustc_index:: bit_set:: { DenseBitSet , MixedBitSet } ;
3539use rustc_index:: { IndexSlice , IndexVec } ;
40+ use rustc_infer:: infer:: outlives:: env:: RegionBoundPairs ;
3641use rustc_infer:: infer:: {
3742 InferCtxt , NllRegionVariableOrigin , RegionVariableOrigin , TyCtxtInferExt ,
3843} ;
@@ -48,23 +53,28 @@ use rustc_mir_dataflow::impls::{
4853use rustc_mir_dataflow:: move_paths:: {
4954 InitIndex , InitLocation , LookupResult , MoveData , MovePathIndex ,
5055} ;
56+ use rustc_mir_dataflow:: points:: DenseLocationMap ;
5157use rustc_mir_dataflow:: { Analysis , EntryStates , Results , ResultsVisitor , visit_results} ;
5258use rustc_session:: lint:: builtin:: { TAIL_EXPR_DROP_ORDER , UNUSED_MUT } ;
5359use rustc_span:: { ErrorGuaranteed , Span , Symbol } ;
5460use smallvec:: SmallVec ;
5561use tracing:: { debug, instrument} ;
62+ use type_check:: free_region_relations:: UniversalRegionRelations ;
63+ use type_check:: { Locations , MirTypeckRegionConstraints , MirTypeckResults } ;
5664
5765use crate :: borrow_set:: { BorrowData , BorrowSet } ;
58- use crate :: consumers:: { BodyWithBorrowckFacts , ConsumerOptions } ;
66+ use crate :: consumers:: { BodyWithBorrowckFacts , ConsumerOptions , RustcFacts } ;
5967use crate :: dataflow:: { BorrowIndex , Borrowck , BorrowckDomain , Borrows } ;
6068use crate :: diagnostics:: {
6169 AccessKind , BorrowckDiagnosticsBuffer , IllegalMoveOriginKind , MoveError , RegionName ,
6270} ;
6371use crate :: path_utils:: * ;
6472use crate :: place_ext:: PlaceExt ;
6573use 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 } ;
6878use crate :: prefixes:: PrefixSet ;
6979use crate :: region_infer:: RegionInferenceContext ;
7080use crate :: renumber:: RegionCtxt ;
@@ -126,12 +136,8 @@ fn mir_borrowck(
126136 let opaque_types = ConcreteOpaqueTypes ( Default :: default ( ) ) ;
127137 Ok ( tcx. arena . alloc ( opaque_types) )
128138 } 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
135141 }
136142}
137143
@@ -143,6 +149,8 @@ struct PropagatedBorrowCheckResults<'tcx> {
143149 used_mut_upvars : SmallVec < [ FieldIdx ; 8 ] > ,
144150}
145151
152+ type DeferredClosureRequirements < ' tcx > = Vec < ( LocalDefId , ty:: GenericArgsRef < ' tcx > , Locations ) > ;
153+
146154/// After we borrow check a closure, we are left with various
147155/// requirements that we have inferred between the free regions that
148156/// appear in the closure's signature or on its field types. These
@@ -281,6 +289,24 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
281289 }
282290}
283291
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+
284310/// Perform the actual borrow checking.
285311///
286312/// Use `consumer_options: None` for the default behavior of returning
@@ -289,11 +315,11 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
289315///
290316/// For nested bodies this should only be called through `root_cx.get_or_insert_nested`.
291317#[ instrument( skip( root_cx) , level = "debug" ) ]
292- fn do_mir_borrowck < ' tcx > (
318+ fn start_do_mir_borrowck < ' tcx > (
293319 root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
294320 def : LocalDefId ,
295321 consumer_options : Option < ConsumerOptions > ,
296- ) -> ( PropagatedBorrowCheckResults < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
322+ ) -> BorrowckState < ' tcx > {
297323 let tcx = root_cx. tcx ;
298324 let infcx = BorrowckInferCtxt :: new ( tcx, def) ;
299325 let ( input_body, promoted) = tcx. mir_promoted ( def) ;
@@ -314,6 +340,7 @@ fn do_mir_borrowck<'tcx>(
314340 let body = & body_owned; // no further changes
315341
316342 let location_table = PoloniusLocationTable :: new ( body) ;
343+ let location_map = Rc :: new ( DenseLocationMap :: new ( body) ) ;
317344
318345 let move_data = MoveData :: gather_moves ( body, tcx, |_| true ) ;
319346
@@ -324,6 +351,80 @@ fn do_mir_borrowck<'tcx>(
324351 let locals_are_invalidated_at_exit = tcx. hir_body_owner_kind ( def) . is_fn_or_closure ( ) ;
325352 let borrow_set = BorrowSet :: build ( tcx, body, locals_are_invalidated_at_exit, & move_data) ;
326353
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+
327428 // Compute non-lexical lifetimes.
328429 let nll:: NllOutput {
329430 regioncx,
@@ -333,18 +434,23 @@ fn do_mir_borrowck<'tcx>(
333434 nll_errors,
334435 polonius_diagnostics,
335436 } = nll:: compute_regions (
336- root_cx,
337437 & infcx,
338- universal_regions,
339438 body,
340- & promoted,
341439 & location_table,
342- flow_inits,
343440 & move_data,
344441 & borrow_set,
442+ location_map,
345443 consumer_options,
444+ universal_region_relations,
445+ constraints,
446+ polonius_facts,
447+ polonius_context,
346448 ) ;
347449
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+
348454 // Dump MIR results into a file, if that is enabled. This lets us
349455 // write unit-tests, as well as helping with debugging.
350456 nll:: dump_nll_mir ( & infcx, body, & regioncx, & opt_closure_req, & borrow_set) ;
0 commit comments