Skip to content

Commit f27bdf1

Browse files
Collect late-bound regions from all closure parents in closure_mapping
1 parent 630dff6 commit f27bdf1

File tree

4 files changed

+91
-40
lines changed

4 files changed

+91
-40
lines changed

compiler/rustc_borrowck/src/region_infer/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2314,7 +2314,7 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx
23142314
tcx,
23152315
closure_substs,
23162316
self.num_external_vids,
2317-
tcx.typeck_root_def_id(closure_def_id),
2317+
closure_def_id.expect_local(),
23182318
);
23192319
debug!("apply_requirements: closure_mapping={:?}", closure_mapping);
23202320

compiler/rustc_borrowck/src/universal_regions.rs

+43-39
Original file line numberDiff line numberDiff line change
@@ -243,17 +243,21 @@ impl<'tcx> UniversalRegions<'tcx> {
243243
tcx: TyCtxt<'tcx>,
244244
closure_substs: SubstsRef<'tcx>,
245245
expected_num_vars: usize,
246-
typeck_root_def_id: DefId,
246+
closure_def_id: LocalDefId,
247247
) -> IndexVec<RegionVid, ty::Region<'tcx>> {
248248
let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
249249
region_mapping.push(tcx.lifetimes.re_static);
250250
tcx.for_each_free_region(&closure_substs, |fr| {
251251
region_mapping.push(fr);
252252
});
253253

254-
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
255-
region_mapping.push(r);
256-
});
254+
for_each_late_bound_region_in_scope(
255+
tcx,
256+
tcx.local_parent(closure_def_id),
257+
|r| {
258+
region_mapping.push(r);
259+
},
260+
);
257261

258262
assert_eq!(
259263
region_mapping.len(),
@@ -341,9 +345,8 @@ impl<'tcx> UniversalRegions<'tcx> {
341345
// tests, and the resulting print-outs include def-ids
342346
// and other things that are not stable across tests!
343347
// So we just include the region-vid. Annoying.
344-
let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
345-
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
346-
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
348+
for_each_late_bound_region_in_scope(tcx, def_id.expect_local(), |r| {
349+
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
347350
});
348351
}
349352
DefiningTy::Generator(def_id, substs, _) => {
@@ -356,9 +359,8 @@ impl<'tcx> UniversalRegions<'tcx> {
356359
// FIXME: As above, we'd like to print out the region
357360
// `r` but doing so is not stable across architectures
358361
// and so forth.
359-
let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
360-
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
361-
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
362+
for_each_late_bound_region_in_scope(tcx, def_id.expect_local(), |r| {
363+
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
362364
});
363365
}
364366
DefiningTy::FnDef(def_id, substs) => {
@@ -749,28 +751,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
749751
#[instrument(skip(self, indices))]
750752
fn replace_late_bound_regions_with_nll_infer_vars(
751753
&self,
752-
mut mir_def_id: LocalDefId,
754+
mir_def_id: LocalDefId,
753755
indices: &mut UniversalRegionIndices<'tcx>,
754756
) {
755-
let typeck_root_def_id = self.tcx.typeck_root_def_id(mir_def_id.to_def_id());
756-
757-
// Walk up the tree, collecting late-bound regions until we hit the typeck root
758-
loop {
759-
for_each_late_bound_region_defined_on(self.tcx, mir_def_id.to_def_id(), |r| {
760-
debug!(?r);
761-
if !indices.indices.contains_key(&r) {
762-
let region_vid = self.next_nll_region_var(FR);
763-
debug!(?region_vid);
764-
indices.insert_late_bound_region(r, region_vid.to_region_vid());
765-
}
766-
});
767-
768-
if mir_def_id.to_def_id() == typeck_root_def_id {
769-
break;
770-
} else {
771-
mir_def_id = self.tcx.parent(mir_def_id.to_def_id()).expect_local();
757+
for_each_late_bound_region_in_scope(self.tcx, mir_def_id, |r| {
758+
debug!(?r);
759+
if !indices.indices.contains_key(&r) {
760+
let region_vid = self.next_nll_region_var(FR);
761+
debug!(?region_vid);
762+
indices.insert_late_bound_region(r, region_vid.to_region_vid());
772763
}
773-
}
764+
});
774765
}
775766
}
776767

@@ -814,18 +805,31 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
814805
}
815806
}
816807

817-
/// Iterates over the late-bound regions defined on fn_def_id and
818-
/// invokes `f` with the liberated form of each one.
819-
fn for_each_late_bound_region_defined_on<'tcx>(
808+
/// Iterates over the late-bound regions defined on fn_def_id and all of its
809+
/// parents, up to the typeck root, and invokes `f` with the liberated form
810+
/// of each one.
811+
fn for_each_late_bound_region_in_scope<'tcx>(
820812
tcx: TyCtxt<'tcx>,
821-
fn_def_id: DefId,
813+
mut mir_def_id: LocalDefId,
822814
mut f: impl FnMut(ty::Region<'tcx>),
823815
) {
824-
for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(fn_def_id.expect_local()))
825-
{
826-
let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; };
827-
let liberated_region =
828-
tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: fn_def_id, bound_region }));
829-
f(liberated_region);
816+
let typeck_root_def_id = tcx.typeck_root_def_id(mir_def_id.to_def_id());
817+
818+
// Walk up the tree, collecting late-bound regions until we hit the typeck root
819+
loop {
820+
for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) {
821+
let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; };
822+
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
823+
scope: mir_def_id.to_def_id(),
824+
bound_region,
825+
}));
826+
f(liberated_region);
827+
}
828+
829+
if mir_def_id.to_def_id() == typeck_root_def_id {
830+
break;
831+
} else {
832+
mir_def_id = tcx.local_parent(mir_def_id);
833+
}
830834
}
831835
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// check-pass
2+
3+
#![feature(closure_lifetime_binder)]
4+
#![feature(rustc_attrs)]
5+
6+
#[rustc_regions]
7+
fn main() {
8+
for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
note: external requirements
2+
--> $DIR/nested-closures-regions.rs:8:24
3+
|
4+
LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: defining type: main::{closure#0}::{closure#0} with closure substs [
8+
i8,
9+
extern "rust-call" fn((&(),)),
10+
(),
11+
]
12+
= note: late-bound region is '_#4r
13+
= note: late-bound region is '_#2r
14+
= note: number of external vids: 3
15+
= note: where '_#1r: '_#2r
16+
= note: where '_#2r: '_#1r
17+
18+
note: no external requirements
19+
--> $DIR/nested-closures-regions.rs:8:5
20+
|
21+
LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
22+
| ^^^^^^^^^^^^^^^^
23+
|
24+
= note: defining type: main::{closure#0} with closure substs [
25+
i8,
26+
extern "rust-call" fn(()),
27+
(),
28+
]
29+
= note: late-bound region is '_#2r
30+
31+
note: no external requirements
32+
--> $DIR/nested-closures-regions.rs:7:1
33+
|
34+
LL | fn main() {
35+
| ^^^^^^^^^
36+
|
37+
= note: defining type: main
38+

0 commit comments

Comments
 (0)