@@ -22,8 +22,10 @@ use std::ops::{ControlFlow, Deref};
22
22
use std:: rc:: Rc ;
23
23
24
24
use borrow_set:: LocalsStateAtExit ;
25
+ use polonius_engine:: AllFacts ;
25
26
use root_cx:: BorrowCheckRootCtxt ;
26
27
use rustc_abi:: FieldIdx ;
28
+ use rustc_data_structures:: frozen:: Frozen ;
27
29
use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
28
30
use rustc_data_structures:: graph:: dominators:: Dominators ;
29
31
use rustc_errors:: LintDiagnostic ;
@@ -32,6 +34,7 @@ use rustc_hir::CRATE_HIR_ID;
32
34
use rustc_hir:: def_id:: LocalDefId ;
33
35
use rustc_index:: bit_set:: MixedBitSet ;
34
36
use rustc_index:: { IndexSlice , IndexVec } ;
37
+ use rustc_infer:: infer:: outlives:: env:: RegionBoundPairs ;
35
38
use rustc_infer:: infer:: {
36
39
InferCtxt , NllRegionVariableOrigin , RegionVariableOrigin , TyCtxtInferExt ,
37
40
} ;
@@ -53,23 +56,25 @@ use smallvec::SmallVec;
53
56
use tracing:: { debug, instrument} ;
54
57
55
58
use crate :: borrow_set:: { BorrowData , BorrowSet } ;
56
- use crate :: consumers:: BodyWithBorrowckFacts ;
59
+ use crate :: consumers:: { BodyWithBorrowckFacts , RustcFacts } ;
57
60
use crate :: dataflow:: { BorrowIndex , Borrowck , BorrowckDomain , Borrows } ;
58
61
use crate :: diagnostics:: {
59
62
AccessKind , BorrowckDiagnosticsBuffer , IllegalMoveOriginKind , MoveError , RegionName ,
60
63
} ;
61
64
use crate :: path_utils:: * ;
62
65
use crate :: place_ext:: PlaceExt ;
63
66
use crate :: places_conflict:: { PlaceConflictBias , places_conflict} ;
64
- use crate :: polonius:: PoloniusDiagnosticsContext ;
65
67
use crate :: polonius:: legacy:: {
66
68
PoloniusFacts , PoloniusFactsExt , PoloniusLocationTable , PoloniusOutput ,
67
69
} ;
70
+ use crate :: polonius:: { PoloniusContext , PoloniusDiagnosticsContext } ;
68
71
use crate :: prefixes:: PrefixSet ;
69
72
use crate :: region_infer:: RegionInferenceContext ;
73
+ use crate :: region_infer:: opaque_types:: DeferredOpaqueTypeError ;
70
74
use crate :: renumber:: RegionCtxt ;
71
75
use 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 } ;
73
78
74
79
mod borrow_set;
75
80
mod borrowck_errors;
@@ -129,18 +134,7 @@ fn mir_borrowck(
129
134
Ok ( tcx. arena . alloc ( opaque_types) )
130
135
} else {
131
136
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 ( ) ;
144
138
root_cx. finalize ( )
145
139
}
146
140
}
@@ -153,6 +147,8 @@ struct PropagatedBorrowCheckResults<'tcx> {
153
147
used_mut_upvars : SmallVec < [ FieldIdx ; 8 ] > ,
154
148
}
155
149
150
+ type DeferredClosureRequirements < ' tcx > = Vec < ( LocalDefId , ty:: GenericArgsRef < ' tcx > , Locations ) > ;
151
+
156
152
/// After we borrow check a closure, we are left with various
157
153
/// requirements that we have inferred between the free regions that
158
154
/// appear in the closure's signature or on its field types. These
@@ -291,14 +287,31 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
291
287
}
292
288
}
293
289
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
+
308
+ /// Start borrow checking by collecting the region constraints for
309
+ /// the current body. This initializes the relevant data structures
310
+ /// and then type checks the MIR body.
311
+ fn borrowck_collect_region_constraints < ' tcx > (
299
312
root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
300
313
def : LocalDefId ,
301
- ) -> PropagatedBorrowCheckResults < ' tcx > {
314
+ ) -> CollectRegionConstraintsResult < ' tcx > {
302
315
let tcx = root_cx. tcx ;
303
316
let infcx = BorrowckInferCtxt :: new ( tcx, def, root_cx. root_def_id ( ) ) ;
304
317
let ( input_body, promoted) = tcx. mir_promoted ( def) ;
@@ -334,10 +347,11 @@ fn do_mir_borrowck<'tcx>(
334
347
335
348
// Run the MIR type-checker.
336
349
let MirTypeckResults {
337
- mut constraints,
350
+ constraints,
338
351
universal_region_relations,
339
352
region_bound_pairs,
340
353
known_type_outlives_obligations,
354
+ deferred_closure_requirements,
341
355
polonius_context,
342
356
} = type_check:: type_check (
343
357
root_cx,
@@ -352,16 +366,53 @@ fn do_mir_borrowck<'tcx>(
352
366
Rc :: clone ( & location_map) ,
353
367
) ;
354
368
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
- ) ;
369
+ CollectRegionConstraintsResult {
370
+ infcx,
371
+ body_owned,
372
+ promoted,
373
+ move_data,
374
+ borrow_set,
375
+ location_table,
376
+ location_map,
377
+ universal_region_relations,
378
+ region_bound_pairs,
379
+ known_type_outlives_obligations,
380
+ constraints,
381
+ deferred_closure_requirements,
382
+ deferred_opaque_type_errors : Default :: default ( ) ,
383
+ polonius_facts,
384
+ polonius_context,
385
+ }
386
+ }
387
+
388
+ /// Using the region constraints computed by [borrowck_collect_region_constraints]
389
+ /// and the additional constraints from [BorrowCheckRootCtxt::handle_opaque_type_uses],
390
+ /// compute the region graph and actually check for any borrowck errors.
391
+ fn borrowck_check_region_constraints < ' tcx > (
392
+ root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
393
+ CollectRegionConstraintsResult {
394
+ infcx,
395
+ body_owned,
396
+ promoted,
397
+ move_data,
398
+ borrow_set,
399
+ location_table,
400
+ location_map,
401
+ universal_region_relations,
402
+ region_bound_pairs : _,
403
+ known_type_outlives_obligations : _,
404
+ constraints,
405
+ deferred_closure_requirements,
406
+ deferred_opaque_type_errors,
407
+ polonius_facts,
408
+ polonius_context,
409
+ } : CollectRegionConstraintsResult < ' tcx > ,
410
+ ) -> PropagatedBorrowCheckResults < ' tcx > {
411
+ assert ! ( !infcx. has_opaque_types_in_storage( ) ) ;
412
+ assert ! ( deferred_closure_requirements. is_empty( ) ) ;
413
+ let tcx = root_cx. tcx ;
414
+ let body = & body_owned;
415
+ let def = body. source . def_id ( ) . expect_local ( ) ;
365
416
366
417
// Compute non-lexical lifetimes using the constraints computed
367
418
// by typechecking the MIR body.
@@ -481,7 +532,7 @@ fn do_mir_borrowck<'tcx>(
481
532
482
533
// Compute and report region errors, if any.
483
534
if nll_errors. is_empty ( ) {
484
- mbcx. report_opaque_type_errors ( opaque_type_errors ) ;
535
+ mbcx. report_opaque_type_errors ( deferred_opaque_type_errors ) ;
485
536
} else {
486
537
mbcx. report_region_errors ( nll_errors) ;
487
538
}
0 commit comments