Skip to content

Commit 5ba1556

Browse files
Create NLL infer vars for late-bound regions from closures
1 parent 9f28de5 commit 5ba1556

File tree

2 files changed

+36
-30
lines changed

2 files changed

+36
-30
lines changed

compiler/rustc_borrowck/src/universal_regions.rs

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ use rustc_hir::{BodyOwnerKind, HirId};
2222
use rustc_index::vec::{Idx, IndexVec};
2323
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
2424
use rustc_middle::ty::fold::TypeFoldable;
25-
use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt};
25+
use rustc_middle::ty::{
26+
self, DefIdTree, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt,
27+
};
2628
use rustc_middle::ty::{InternalSubsts, SubstsRef};
2729
use std::iter;
2830

@@ -421,13 +423,15 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
421423
first_extern_index
422424
} else {
423425
// If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing
424-
// function are actually external regions to us. For example, here, 'a is not local
426+
// function/closures are actually external regions to us. For example, here, 'a is not local
425427
// to the closure c (although it is local to the fn foo):
426428
// fn foo<'a>() {
427429
// let c = || { let x: &'a u32 = ...; }
428430
// }
429-
self.infcx
430-
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices);
431+
self.infcx.replace_late_bound_regions_with_nll_infer_vars(
432+
self.infcx.tcx.local_parent(self.mir_def.did),
433+
&mut indices,
434+
);
431435
// Any regions created during the execution of `defining_ty` or during the above
432436
// late-bound region replacement are all considered 'extern' regions
433437
self.infcx.num_region_vars()
@@ -444,12 +448,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
444448
bound_inputs_and_output,
445449
&mut indices,
446450
);
447-
// Converse of above, if this is a function then the late-bound regions declared on its
448-
// signature are local to the fn.
449-
if self.mir_def.did.to_def_id() == typeck_root_def_id {
450-
self.infcx
451-
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices);
452-
}
451+
// Converse of above, if this is a function/closure then the late-bound regions declared on its
452+
// signature are local.
453+
self.infcx.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices);
453454

454455
let (unnormalized_output_ty, mut unnormalized_input_tys) =
455456
inputs_and_output.split_last().unwrap();
@@ -748,18 +749,28 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
748749
#[instrument(skip(self, indices))]
749750
fn replace_late_bound_regions_with_nll_infer_vars(
750751
&self,
751-
mir_def_id: LocalDefId,
752+
mut mir_def_id: LocalDefId,
752753
indices: &mut UniversalRegionIndices<'tcx>,
753754
) {
754755
let typeck_root_def_id = self.tcx.typeck_root_def_id(mir_def_id.to_def_id());
755-
for_each_late_bound_region_defined_on(self.tcx, typeck_root_def_id, |r| {
756-
debug!(?r);
757-
if !indices.indices.contains_key(&r) {
758-
let region_vid = self.next_nll_region_var(FR);
759-
debug!(?region_vid);
760-
indices.insert_late_bound_region(r, region_vid.to_region_vid());
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();
761772
}
762-
});
773+
}
763774
}
764775
}
765776

@@ -810,14 +821,11 @@ fn for_each_late_bound_region_defined_on<'tcx>(
810821
fn_def_id: DefId,
811822
mut f: impl FnMut(ty::Region<'tcx>),
812823
) {
813-
if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
814-
for &region_def_id in late_bounds.iter() {
815-
let name = tcx.item_name(region_def_id.to_def_id());
816-
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
817-
scope: fn_def_id,
818-
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
819-
}));
820-
f(liberated_region);
821-
}
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);
822830
}
823831
}

compiler/rustc_middle/src/ty/context.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,9 +2895,7 @@ impl<'tcx> TyCtxt<'tcx> {
28952895
self.mk_bound_variable_kinds(
28962896
self.late_bound_vars_map(id.owner)
28972897
.and_then(|map| map.get(&id.local_id).cloned())
2898-
.unwrap_or_else(|| {
2899-
bug!("No bound vars found for {:?} ({:?})", self.hir().node_to_string(id), id)
2900-
})
2898+
.unwrap_or_default()
29012899
.iter(),
29022900
)
29032901
}

0 commit comments

Comments
 (0)