@@ -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,30 @@ 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
+ /// 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 > (
299
311
root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
300
312
def : LocalDefId ,
301
- ) -> PropagatedBorrowCheckResults < ' tcx > {
313
+ ) -> CollectRegionConstraintsResult < ' tcx > {
302
314
let tcx = root_cx. tcx ;
303
315
let infcx = BorrowckInferCtxt :: new ( tcx, def, root_cx. root_def_id ( ) ) ;
304
316
let ( input_body, promoted) = tcx. mir_promoted ( def) ;
@@ -334,10 +346,11 @@ fn do_mir_borrowck<'tcx>(
334
346
335
347
// Run the MIR type-checker.
336
348
let MirTypeckResults {
337
- mut constraints,
349
+ constraints,
338
350
universal_region_relations,
339
351
region_bound_pairs,
340
352
known_type_outlives_obligations,
353
+ deferred_closure_requirements,
341
354
polonius_context,
342
355
} = type_check:: type_check (
343
356
root_cx,
@@ -352,16 +365,53 @@ fn do_mir_borrowck<'tcx>(
352
365
Rc :: clone ( & location_map) ,
353
366
) ;
354
367
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 ( ) ;
365
415
366
416
// Compute non-lexical lifetimes using the constraints computed
367
417
// by typechecking the MIR body.
@@ -481,7 +531,7 @@ fn do_mir_borrowck<'tcx>(
481
531
482
532
// Compute and report region errors, if any.
483
533
if nll_errors. is_empty ( ) {
484
- mbcx. report_opaque_type_errors ( opaque_type_errors ) ;
534
+ mbcx. report_opaque_type_errors ( deferred_opaque_type_errors ) ;
485
535
} else {
486
536
mbcx. report_region_errors ( nll_errors) ;
487
537
}
0 commit comments