Skip to content

Commit c7cfa23

Browse files
committed
thread through an implicit region body of the fn body
1 parent 154cd94 commit c7cfa23

20 files changed

+135
-45
lines changed

src/librustc_mir/borrow_check/nll/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,13 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
7878
// Run the MIR type-checker.
7979
let mir_node_id = infcx.tcx.hir.as_local_node_id(def_id).unwrap();
8080
let liveness = &LivenessResults::compute(mir);
81+
let fr_fn_body = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
8182
let constraint_sets = &type_check::type_check(
8283
infcx,
8384
mir_node_id,
8485
param_env,
8586
mir,
87+
fr_fn_body,
8688
&liveness,
8789
flow_inits,
8890
move_data,

src/librustc_mir/borrow_check/nll/region_infer/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
439439
/// have no evidence that `'b` outlives `'a`, so we want to report
440440
/// an error.
441441
fn check_type_tests(&self, infcx: &InferCtxt<'_, '_, 'tcx>, mir: &Mir<'tcx>) {
442+
let tcx = infcx.tcx;
443+
442444
for type_test in &self.type_tests {
443445
debug!("check_type_test: {:?}", type_test);
444446

@@ -452,7 +454,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
452454
}
453455

454456
// Oh the humanity. Obviously we will do better than this error eventually.
455-
infcx.tcx.sess.span_err(
457+
tcx.sess.span_err(
456458
type_test.span,
457459
&format!("failed type test: {:?}", type_test),
458460
);

src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,30 @@ pub(crate) fn type_check<'gcx, 'tcx>(
5151
body_id: ast::NodeId,
5252
param_env: ty::ParamEnv<'gcx>,
5353
mir: &Mir<'tcx>,
54+
implicit_region_bound: ty::Region<'tcx>,
5455
liveness: &LivenessResults,
5556
flow_inits: &mut FlowAtLocation<MaybeInitializedLvals<'_, 'gcx, 'tcx>>,
5657
move_data: &MoveData<'tcx>,
5758
) -> MirTypeckRegionConstraints<'tcx> {
58-
type_check_internal(infcx, body_id, param_env, mir, &mut |cx| {
59-
liveness::generate(cx, mir, liveness, flow_inits, move_data)
60-
})
59+
type_check_internal(
60+
infcx,
61+
body_id,
62+
param_env,
63+
mir,
64+
Some(implicit_region_bound),
65+
&mut |cx| liveness::generate(cx, mir, liveness, flow_inits, move_data),
66+
)
6167
}
6268

6369
fn type_check_internal<'gcx, 'tcx>(
6470
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
6571
body_id: ast::NodeId,
6672
param_env: ty::ParamEnv<'gcx>,
6773
mir: &Mir<'tcx>,
74+
implicit_region_bound: Option<ty::Region<'tcx>>,
6875
extra: &mut FnMut(&mut TypeChecker<'_, 'gcx, 'tcx>),
6976
) -> MirTypeckRegionConstraints<'tcx> {
70-
let mut checker = TypeChecker::new(infcx, body_id, param_env);
77+
let mut checker = TypeChecker::new(infcx, body_id, param_env, implicit_region_bound);
7178
let errors_reported = {
7279
let mut verifier = TypeVerifier::new(&mut checker, mir);
7380
verifier.visit_mir(mir);
@@ -535,6 +542,7 @@ struct TypeChecker<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
535542
param_env: ty::ParamEnv<'gcx>,
536543
last_span: Span,
537544
body_id: ast::NodeId,
545+
implicit_region_bound: Option<ty::Region<'tcx>>,
538546
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
539547
constraints: MirTypeckRegionConstraints<'tcx>,
540548
}
@@ -588,12 +596,14 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
588596
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
589597
body_id: ast::NodeId,
590598
param_env: ty::ParamEnv<'gcx>,
599+
implicit_region_bound: Option<ty::Region<'tcx>>,
591600
) -> Self {
592601
TypeChecker {
593602
infcx,
594603
last_span: DUMMY_SP,
595604
body_id,
596605
param_env,
606+
implicit_region_bound,
597607
reported_errors: FxHashSet(),
598608
constraints: MirTypeckRegionConstraints::default(),
599609
}
@@ -618,8 +628,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
618628
span_mirbug!(self, "", "errors selecting obligation: {:?}", e);
619629
}
620630

621-
self.infcx
622-
.process_registered_region_obligations(&[], None, self.param_env, self.body_id);
631+
self.infcx.process_registered_region_obligations(
632+
&[],
633+
self.implicit_region_bound,
634+
self.param_env,
635+
self.body_id,
636+
);
623637

624638
let data = self.infcx.take_and_reset_region_constraints();
625639
if !data.is_empty() {
@@ -1501,7 +1515,7 @@ impl MirPass for TypeckMir {
15011515
}
15021516
let param_env = tcx.param_env(def_id);
15031517
tcx.infer_ctxt().enter(|infcx| {
1504-
let _ = type_check_internal(&infcx, id, param_env, mir, &mut |_| ());
1518+
let _ = type_check_internal(&infcx, id, param_env, mir, None, &mut |_| ());
15051519

15061520
// For verification purposes, we just ignore the resulting
15071521
// region constraint sets. Not our problem. =)

src/librustc_mir/borrow_check/nll/universal_regions.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ pub struct UniversalRegions<'tcx> {
4545
/// The vid assigned to `'static`
4646
pub fr_static: RegionVid,
4747

48+
/// A special region vid created to represent the current MIR fn
49+
/// body. It will outlive the entire CFG but it will not outlive
50+
/// any other universal regions.
51+
pub fr_fn_body: RegionVid,
52+
4853
/// We create region variables such that they are ordered by their
4954
/// `RegionClassification`. The first block are globals, then
5055
/// externals, then locals. So things from:
@@ -408,6 +413,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
408413
let first_local_index = self.infcx.num_region_vars();
409414
let inputs_and_output = self.infcx
410415
.replace_bound_regions_with_nll_infer_vars(FR, &bound_inputs_and_output);
416+
let fr_fn_body = self.infcx.next_nll_region_var(FR).to_region_vid();
411417
let num_universals = self.infcx.num_region_vars();
412418

413419
// Insert the facts we know from the predicates. Why? Why not.
@@ -419,12 +425,16 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
419425
self.add_implied_bounds(&indices, ty);
420426
}
421427

422-
// Finally, outlives is reflexive, and static outlives every
423-
// other free region.
428+
// Finally:
429+
// - outlives is reflexive, so `'r: 'r` for every region `'r`
430+
// - `'static: 'r` for every region `'r`
431+
// - `'r: 'fn_body` for every (other) universally quantified
432+
// region `'r`, all of which are provided by our caller
424433
for fr in (FIRST_GLOBAL_INDEX..num_universals).map(RegionVid::new) {
425434
debug!("build: relating free region {:?} to itself and to 'static", fr);
426435
self.relations.relate_universal_regions(fr, fr);
427436
self.relations.relate_universal_regions(fr_static, fr);
437+
self.relations.relate_universal_regions(fr, fr_fn_body);
428438
}
429439

430440
let (output_ty, input_tys) = inputs_and_output.split_last().unwrap();
@@ -445,6 +455,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
445455
UniversalRegions {
446456
indices,
447457
fr_static,
458+
fr_fn_body,
448459
first_extern_index,
449460
first_local_index,
450461
num_universals,

src/test/mir-opt/nll/named-lifetimes-basic.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,18 @@ fn main() {
2727
// END RUST SOURCE
2828
// START rustc.use_x.nll.0.mir
2929
// | Free Region Mapping
30-
// | '_#0r | Global | ['_#2r, '_#1r, '_#0r, '_#3r]
31-
// | '_#1r | External | ['_#1r]
32-
// | '_#2r | External | ['_#2r, '_#1r]
33-
// | '_#3r | Local | ['_#3r]
30+
// | '_#0r | Global | ['_#2r, '_#1r, '_#0r, '_#4r, '_#3r]
31+
// | '_#1r | External | ['_#1r, '_#4r]
32+
// | '_#2r | External | ['_#2r, '_#1r, '_#4r]
33+
// | '_#3r | Local | ['_#4r, '_#3r]
34+
// | '_#4r | Local | ['_#4r]
3435
// |
3536
// | Inferred Region Values
3637
// | '_#0r | {'_#0r, bb0[0], bb0[1]}
3738
// | '_#1r | {'_#1r, bb0[0], bb0[1]}
3839
// | '_#2r | {'_#2r, bb0[0], bb0[1]}
3940
// | '_#3r | {'_#3r, bb0[0], bb0[1]}
41+
// | '_#4r | {'_#4r, bb0[0], bb0[1]}
4042
// |
4143
// ...
4244
// fn use_x(_1: &'_#1r mut i32, _2: &'_#2r u32, _3: &'_#1r u32, _4: &'_#3r u32) -> bool {

src/test/mir-opt/nll/reborrow-basic.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ fn main() {
2828

2929
// END RUST SOURCE
3030
// START rustc.main.nll.0.mir
31-
// | '_#6r | {bb0[6], bb0[7], bb0[8], bb0[9], bb0[10], bb0[11], bb0[12], bb0[13], bb0[14]}
31+
// | '_#7r | {bb0[6], bb0[7], bb0[8], bb0[9], bb0[10], bb0[11], bb0[12], bb0[13], bb0[14]}
3232
// ...
33-
// | '_#8r | {bb0[11], bb0[12], bb0[13], bb0[14]}
33+
// | '_#9r | {bb0[11], bb0[12], bb0[13], bb0[14]}
3434
// ...
35-
// let _2: &'_#6r mut i32;
35+
// let _2: &'_#7r mut i32;
3636
// ...
37-
// let _4: &'_#8r mut i32;
37+
// let _4: &'_#9r mut i32;
3838
// END rustc.main.nll.0.mir

src/test/mir-opt/nll/region-liveness-basic.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ fn main() {
3131

3232
// END RUST SOURCE
3333
// START rustc.main.nll.0.mir
34-
// | '_#1r | {bb2[0], bb2[1], bb3[0], bb3[1]}
35-
// | '_#2r | {bb2[1], bb3[0], bb3[1]}
34+
// | '_#2r | {bb2[0], bb2[1], bb3[0], bb3[1]}
35+
// | '_#3r | {bb2[1], bb3[0], bb3[1]}
3636
// ...
37-
// let _2: &'_#2r usize;
37+
// let _2: &'_#3r usize;
3838
// END rustc.main.nll.0.mir
3939
// START rustc.main.nll.0.mir
4040
// bb2: {
4141
// | Live variables on entry to bb2[0]: [_1, _3]
42-
// _2 = &'_#1r _1[_3];
42+
// _2 = &'_#2r _1[_3];
4343
// | Live variables on entry to bb2[1]: [_2]
4444
// switchInt(const true) -> [0u8: bb4, otherwise: bb3];
4545
// }

src/test/mir-opt/nll/region-liveness-drop-may-dangle.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,7 @@ unsafe impl<#[may_dangle] T> Drop for Wrap<T> {
4444

4545
// END RUST SOURCE
4646
// START rustc.main.nll.0.mir
47-
// | '_#5r | {bb2[3], bb2[4], bb2[5], bb3[0], bb3[1]}
47+
// | '_#6r | {bb2[3], bb2[4], bb2[5], bb3[0], bb3[1]}
48+
// ...
49+
// let _2: Wrap<&'_#6r usize>;
4850
// END rustc.main.nll.0.mir

src/test/mir-opt/nll/region-liveness-drop-no-may-dangle.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,7 @@ impl<T> Drop for Wrap<T> {
4646

4747
// END RUST SOURCE
4848
// START rustc.main.nll.0.mir
49-
// | '_#5r | {bb2[3], bb2[4], bb2[5], bb3[0], bb3[1], bb3[2], bb4[0], bb5[0], bb5[1], bb5[2], bb6[0], bb7[0], bb7[1], bb8[0]}
49+
// | '_#6r | {bb2[3], bb2[4], bb2[5], bb3[0], bb3[1], bb3[2], bb4[0], bb5[0], bb5[1], bb5[2], bb6[0], bb7[0], bb7[1], bb8[0]}
50+
// ...
51+
// let _2: Wrap<&'_#6r usize>;
5052
// END rustc.main.nll.0.mir

src/test/mir-opt/nll/region-liveness-two-disjoint-uses.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ fn main() {
3636

3737
// END RUST SOURCE
3838
// START rustc.main.nll.0.mir
39-
// | '_#1r | {bb2[0], bb2[1], bb3[0], bb3[1]}
39+
// | '_#2r | {bb2[0], bb2[1], bb3[0], bb3[1]}
4040
// ...
41-
// | '_#3r | {bb8[1], bb8[2], bb8[3], bb8[4]}
42-
// | '_#4r | {bb2[1], bb3[0], bb3[1], bb8[2], bb8[3], bb8[4]}
41+
// | '_#4r | {bb8[1], bb8[2], bb8[3], bb8[4]}
42+
// | '_#5r | {bb2[1], bb3[0], bb3[1], bb8[2], bb8[3], bb8[4]}
4343
// ...
44-
// let mut _2: &'_#4r usize;
44+
// let mut _2: &'_#5r usize;
4545
// ...
46-
// _2 = &'_#1r _1[_3];
46+
// _2 = &'_#2r _1[_3];
4747
// ...
48-
// _2 = &'_#3r (*_10);
48+
// _2 = &'_#4r (*_10);
4949
// END rustc.main.nll.0.mir

0 commit comments

Comments
 (0)