Collect late-bound regions from all closure parents in closure_mapping

This commit is contained in:
Michael Goulet 2022-10-31 03:28:05 +00:00
parent 630dff6ba7
commit f27bdf1750
4 changed files with 91 additions and 40 deletions

View File

@ -2314,7 +2314,7 @@ fn apply_requirements(
tcx, tcx,
closure_substs, closure_substs,
self.num_external_vids, self.num_external_vids,
tcx.typeck_root_def_id(closure_def_id), closure_def_id.expect_local(),
); );
debug!("apply_requirements: closure_mapping={:?}", closure_mapping); debug!("apply_requirements: closure_mapping={:?}", closure_mapping);

View File

@ -243,7 +243,7 @@ pub fn closure_mapping(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
closure_substs: SubstsRef<'tcx>, closure_substs: SubstsRef<'tcx>,
expected_num_vars: usize, expected_num_vars: usize,
typeck_root_def_id: DefId, closure_def_id: LocalDefId,
) -> IndexVec<RegionVid, ty::Region<'tcx>> { ) -> IndexVec<RegionVid, ty::Region<'tcx>> {
let mut region_mapping = IndexVec::with_capacity(expected_num_vars); let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
region_mapping.push(tcx.lifetimes.re_static); region_mapping.push(tcx.lifetimes.re_static);
@ -251,9 +251,13 @@ pub fn closure_mapping(
region_mapping.push(fr); region_mapping.push(fr);
}); });
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| { for_each_late_bound_region_in_scope(
region_mapping.push(r); tcx,
}); tcx.local_parent(closure_def_id),
|r| {
region_mapping.push(r);
},
);
assert_eq!( assert_eq!(
region_mapping.len(), region_mapping.len(),
@ -341,9 +345,8 @@ pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
// tests, and the resulting print-outs include def-ids // tests, and the resulting print-outs include def-ids
// and other things that are not stable across tests! // and other things that are not stable across tests!
// So we just include the region-vid. Annoying. // So we just include the region-vid. Annoying.
let typeck_root_def_id = tcx.typeck_root_def_id(def_id); for_each_late_bound_region_in_scope(tcx, def_id.expect_local(), |r| {
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| { err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
}); });
} }
DefiningTy::Generator(def_id, substs, _) => { DefiningTy::Generator(def_id, substs, _) => {
@ -356,9 +359,8 @@ pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
// FIXME: As above, we'd like to print out the region // FIXME: As above, we'd like to print out the region
// `r` but doing so is not stable across architectures // `r` but doing so is not stable across architectures
// and so forth. // and so forth.
let typeck_root_def_id = tcx.typeck_root_def_id(def_id); for_each_late_bound_region_in_scope(tcx, def_id.expect_local(), |r| {
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| { err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
}); });
} }
DefiningTy::FnDef(def_id, substs) => { DefiningTy::FnDef(def_id, substs) => {
@ -749,28 +751,17 @@ fn replace_bound_regions_with_nll_infer_vars<T>(
#[instrument(skip(self, indices))] #[instrument(skip(self, indices))]
fn replace_late_bound_regions_with_nll_infer_vars( fn replace_late_bound_regions_with_nll_infer_vars(
&self, &self,
mut mir_def_id: LocalDefId, mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>, indices: &mut UniversalRegionIndices<'tcx>,
) { ) {
let typeck_root_def_id = self.tcx.typeck_root_def_id(mir_def_id.to_def_id()); for_each_late_bound_region_in_scope(self.tcx, mir_def_id, |r| {
debug!(?r);
// Walk up the tree, collecting late-bound regions until we hit the typeck root if !indices.indices.contains_key(&r) {
loop { let region_vid = self.next_nll_region_var(FR);
for_each_late_bound_region_defined_on(self.tcx, mir_def_id.to_def_id(), |r| { debug!(?region_vid);
debug!(?r); indices.insert_late_bound_region(r, region_vid.to_region_vid());
if !indices.indices.contains_key(&r) {
let region_vid = self.next_nll_region_var(FR);
debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid());
}
});
if mir_def_id.to_def_id() == typeck_root_def_id {
break;
} else {
mir_def_id = self.tcx.parent(mir_def_id.to_def_id()).expect_local();
} }
} });
} }
} }
@ -814,18 +805,31 @@ pub fn fold_to_region_vids<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
} }
} }
/// Iterates over the late-bound regions defined on fn_def_id and /// Iterates over the late-bound regions defined on fn_def_id and all of its
/// invokes `f` with the liberated form of each one. /// parents, up to the typeck root, and invokes `f` with the liberated form
fn for_each_late_bound_region_defined_on<'tcx>( /// of each one.
fn for_each_late_bound_region_in_scope<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
fn_def_id: DefId, mut mir_def_id: LocalDefId,
mut f: impl FnMut(ty::Region<'tcx>), mut f: impl FnMut(ty::Region<'tcx>),
) { ) {
for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(fn_def_id.expect_local())) let typeck_root_def_id = tcx.typeck_root_def_id(mir_def_id.to_def_id());
{
let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; }; // Walk up the tree, collecting late-bound regions until we hit the typeck root
let liberated_region = loop {
tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: fn_def_id, bound_region })); for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) {
f(liberated_region); let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; };
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
scope: mir_def_id.to_def_id(),
bound_region,
}));
f(liberated_region);
}
if mir_def_id.to_def_id() == typeck_root_def_id {
break;
} else {
mir_def_id = tcx.local_parent(mir_def_id);
}
} }
} }

View File

@ -0,0 +1,9 @@
// check-pass
#![feature(closure_lifetime_binder)]
#![feature(rustc_attrs)]
#[rustc_regions]
fn main() {
for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
}

View File

@ -0,0 +1,38 @@
note: external requirements
--> $DIR/nested-closures-regions.rs:8:24
|
LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: main::{closure#0}::{closure#0} with closure substs [
i8,
extern "rust-call" fn((&(),)),
(),
]
= note: late-bound region is '_#4r
= note: late-bound region is '_#2r
= note: number of external vids: 3
= note: where '_#1r: '_#2r
= note: where '_#2r: '_#1r
note: no external requirements
--> $DIR/nested-closures-regions.rs:8:5
|
LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
| ^^^^^^^^^^^^^^^^
|
= note: defining type: main::{closure#0} with closure substs [
i8,
extern "rust-call" fn(()),
(),
]
= note: late-bound region is '_#2r
note: no external requirements
--> $DIR/nested-closures-regions.rs:7:1
|
LL | fn main() {
| ^^^^^^^^^
|
= note: defining type: main