@@ -22,8 +22,10 @@ use std::ops::{ControlFlow, Deref};
2222use std:: rc:: Rc ;
2323
2424use borrow_set:: LocalsStateAtExit ;
25+ use polonius_engine:: AllFacts ;
2526use root_cx:: BorrowCheckRootCtxt ;
2627use rustc_abi:: FieldIdx ;
28+ use rustc_data_structures:: frozen:: Frozen ;
2729use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
2830use rustc_data_structures:: graph:: dominators:: Dominators ;
2931use rustc_errors:: LintDiagnostic ;
@@ -32,6 +34,7 @@ use rustc_hir::CRATE_HIR_ID;
3234use rustc_hir:: def_id:: LocalDefId ;
3335use rustc_index:: bit_set:: MixedBitSet ;
3436use rustc_index:: { IndexSlice , IndexVec } ;
37+ use rustc_infer:: infer:: outlives:: env:: RegionBoundPairs ;
3538use rustc_infer:: infer:: {
3639 InferCtxt , NllRegionVariableOrigin , RegionVariableOrigin , TyCtxtInferExt ,
3740} ;
@@ -53,23 +56,25 @@ use smallvec::SmallVec;
5356use tracing:: { debug, instrument} ;
5457
5558use crate :: borrow_set:: { BorrowData , BorrowSet } ;
56- use crate :: consumers:: BodyWithBorrowckFacts ;
59+ use crate :: consumers:: { BodyWithBorrowckFacts , RustcFacts } ;
5760use crate :: dataflow:: { BorrowIndex , Borrowck , BorrowckDomain , Borrows } ;
5861use crate :: diagnostics:: {
5962 AccessKind , BorrowckDiagnosticsBuffer , IllegalMoveOriginKind , MoveError , RegionName ,
6063} ;
6164use crate :: path_utils:: * ;
6265use crate :: place_ext:: PlaceExt ;
6366use crate :: places_conflict:: { PlaceConflictBias , places_conflict} ;
64- use crate :: polonius:: PoloniusDiagnosticsContext ;
6567use crate :: polonius:: legacy:: {
6668 PoloniusFacts , PoloniusFactsExt , PoloniusLocationTable , PoloniusOutput ,
6769} ;
70+ use crate :: polonius:: { PoloniusContext , PoloniusDiagnosticsContext } ;
6871use crate :: prefixes:: PrefixSet ;
6972use crate :: region_infer:: RegionInferenceContext ;
73+ use crate :: region_infer:: opaque_types:: DeferredOpaqueTypeError ;
7074use crate :: renumber:: RegionCtxt ;
7175use crate :: session_diagnostics:: VarNeedNotMut ;
72- use crate :: type_check:: MirTypeckResults ;
76+ use crate :: type_check:: free_region_relations:: UniversalRegionRelations ;
77+ use crate :: type_check:: { Locations , MirTypeckRegionConstraints , MirTypeckResults } ;
7378
7479mod borrow_set;
7580mod borrowck_errors;
@@ -129,18 +134,7 @@ fn mir_borrowck(
129134 Ok ( tcx. arena . alloc ( opaque_types) )
130135 } else {
131136 let mut root_cx = BorrowCheckRootCtxt :: new ( tcx, def, None ) ;
132- // We need to manually borrowck all nested bodies from the HIR as
133- // we do not generate MIR for dead code. Not doing so causes us to
134- // never check closures in dead code.
135- let nested_bodies = tcx. nested_bodies_within ( def) ;
136- for def_id in nested_bodies {
137- root_cx. get_or_insert_nested ( def_id) ;
138- }
139-
140- let PropagatedBorrowCheckResults { closure_requirements, used_mut_upvars } =
141- do_mir_borrowck ( & mut root_cx, def) ;
142- debug_assert ! ( closure_requirements. is_none( ) ) ;
143- debug_assert ! ( used_mut_upvars. is_empty( ) ) ;
137+ root_cx. do_mir_borrowck ( ) ;
144138 root_cx. finalize ( )
145139 }
146140}
@@ -153,6 +147,8 @@ struct PropagatedBorrowCheckResults<'tcx> {
153147 used_mut_upvars : SmallVec < [ FieldIdx ; 8 ] > ,
154148}
155149
150+ type DeferredClosureRequirements < ' tcx > = Vec < ( LocalDefId , ty:: GenericArgsRef < ' tcx > , Locations ) > ;
151+
156152/// After we borrow check a closure, we are left with various
157153/// requirements that we have inferred between the free regions that
158154/// appear in the closure's signature or on its field types. These
@@ -291,14 +287,30 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
291287 }
292288}
293289
294- /// Perform the actual borrow checking.
295- ///
296- /// For nested bodies this should only be called through `root_cx.get_or_insert_nested`.
297- #[ instrument( skip( root_cx) , level = "debug" ) ]
298- fn do_mir_borrowck < ' tcx > (
290+ struct CollectRegionConstraintsResult < ' tcx > {
291+ infcx : BorrowckInferCtxt < ' tcx > ,
292+ body_owned : Body < ' tcx > ,
293+ promoted : IndexVec < Promoted , Body < ' tcx > > ,
294+ move_data : MoveData < ' tcx > ,
295+ borrow_set : BorrowSet < ' tcx > ,
296+ location_table : PoloniusLocationTable ,
297+ location_map : Rc < DenseLocationMap > ,
298+ universal_region_relations : Frozen < UniversalRegionRelations < ' tcx > > ,
299+ region_bound_pairs : Frozen < RegionBoundPairs < ' tcx > > ,
300+ known_type_outlives_obligations : Frozen < Vec < ty:: PolyTypeOutlivesPredicate < ' tcx > > > ,
301+ constraints : MirTypeckRegionConstraints < ' tcx > ,
302+ deferred_closure_requirements : DeferredClosureRequirements < ' tcx > ,
303+ deferred_opaque_type_errors : Vec < DeferredOpaqueTypeError < ' tcx > > ,
304+ polonius_facts : Option < AllFacts < RustcFacts > > ,
305+ polonius_context : Option < PoloniusContext > ,
306+ }
307+ /// Start borrow checking by collecting the region constraints for
308+ /// the current body. This initializes the relevant data structures
309+ /// and then type checks the MIR body.
310+ fn borrowck_collect_region_constraints < ' tcx > (
299311 root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
300312 def : LocalDefId ,
301- ) -> PropagatedBorrowCheckResults < ' tcx > {
313+ ) -> CollectRegionConstraintsResult < ' tcx > {
302314 let tcx = root_cx. tcx ;
303315 let infcx = BorrowckInferCtxt :: new ( tcx, def, root_cx. root_def_id ( ) ) ;
304316 let ( input_body, promoted) = tcx. mir_promoted ( def) ;
@@ -334,10 +346,11 @@ fn do_mir_borrowck<'tcx>(
334346
335347 // Run the MIR type-checker.
336348 let MirTypeckResults {
337- mut constraints,
349+ constraints,
338350 universal_region_relations,
339351 region_bound_pairs,
340352 known_type_outlives_obligations,
353+ deferred_closure_requirements,
341354 polonius_context,
342355 } = type_check:: type_check (
343356 root_cx,
@@ -352,16 +365,53 @@ fn do_mir_borrowck<'tcx>(
352365 Rc :: clone ( & location_map) ,
353366 ) ;
354367
355- let opaque_type_errors = region_infer:: opaque_types:: handle_opaque_type_uses (
356- root_cx,
357- & infcx,
358- & body,
359- & universal_region_relations,
360- & region_bound_pairs,
361- & known_type_outlives_obligations,
362- & location_map,
363- & mut constraints,
364- ) ;
368+ CollectRegionConstraintsResult {
369+ infcx,
370+ body_owned,
371+ promoted,
372+ move_data,
373+ borrow_set,
374+ location_table,
375+ location_map,
376+ universal_region_relations,
377+ region_bound_pairs,
378+ known_type_outlives_obligations,
379+ constraints,
380+ deferred_closure_requirements,
381+ deferred_opaque_type_errors : Default :: default ( ) ,
382+ polonius_facts,
383+ polonius_context,
384+ }
385+ }
386+
387+ /// Using the region constraints computed by [borrowck_collect_region_constraints]
388+ /// and the additional constraints from [handle_opaque_type_uses] TODO, compute
389+ /// the region graph and actually check for any borrowck errors.
390+ fn borrowck_check_region_constraints < ' tcx > (
391+ root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
392+ CollectRegionConstraintsResult {
393+ infcx,
394+ body_owned,
395+ promoted,
396+ move_data,
397+ borrow_set,
398+ location_table,
399+ location_map,
400+ universal_region_relations,
401+ region_bound_pairs : _,
402+ known_type_outlives_obligations : _,
403+ constraints,
404+ deferred_closure_requirements,
405+ deferred_opaque_type_errors,
406+ polonius_facts,
407+ polonius_context,
408+ } : CollectRegionConstraintsResult < ' tcx > ,
409+ ) -> PropagatedBorrowCheckResults < ' tcx > {
410+ assert ! ( !infcx. has_opaque_types_in_storage( ) ) ;
411+ assert ! ( deferred_closure_requirements. is_empty( ) ) ;
412+ let tcx = root_cx. tcx ;
413+ let body = & body_owned;
414+ let def = body. source . def_id ( ) . expect_local ( ) ;
365415
366416 // Compute non-lexical lifetimes using the constraints computed
367417 // by typechecking the MIR body.
@@ -481,7 +531,7 @@ fn do_mir_borrowck<'tcx>(
481531
482532 // Compute and report region errors, if any.
483533 if nll_errors. is_empty ( ) {
484- mbcx. report_opaque_type_errors ( opaque_type_errors ) ;
534+ mbcx. report_opaque_type_errors ( deferred_opaque_type_errors ) ;
485535 } else {
486536 mbcx. report_region_errors ( nll_errors) ;
487537 }
0 commit comments