Collect late-bound regions from all closure parents in closure_mapping
This commit is contained in:
parent
630dff6ba7
commit
f27bdf1750
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
src/test/ui/closures/binder/nested-closures-regions.rs
Normal file
9
src/test/ui/closures/binder/nested-closures-regions.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(closure_lifetime_binder)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
|
#[rustc_regions]
|
||||||
|
fn main() {
|
||||||
|
for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
|
||||||
|
}
|
38
src/test/ui/closures/binder/nested-closures-regions.stderr
Normal file
38
src/test/ui/closures/binder/nested-closures-regions.stderr
Normal 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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user