Skip to content

Commit ad6c287

Browse files
committed
introduce LateParamRegionKind
1 parent 6f5bf6c commit ad6c287

File tree

19 files changed

+168
-59
lines changed

19 files changed

+168
-59
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
189189
/// Returns `true` if a closure is inferred to be an `FnMut` closure.
190190
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
191191
if let Some(ty::ReLateParam(late_param)) = self.to_error_region(fr).as_deref()
192-
&& let ty::BoundRegionKind::ClosureEnv = late_param.bound_region
192+
&& let ty::LateParamRegionKind::ClosureEnv = late_param.kind
193193
&& let DefiningTy::Closure(_, args) = self.regioncx.universal_regions().defining_ty
194194
{
195195
return args.as_closure().kind() == ty::ClosureKind::FnMut;

compiler/rustc_borrowck/src/diagnostics/region_name.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -300,17 +300,17 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
300300
Some(RegionName { name: kw::StaticLifetime, source: RegionNameSource::Static })
301301
}
302302

303-
ty::ReLateParam(late_param) => match late_param.bound_region {
304-
ty::BoundRegionKind::Named(region_def_id, name) => {
303+
ty::ReLateParam(late_param) => match late_param.kind {
304+
ty::LateParamRegionKind::Named(region_def_id, name) => {
305305
// Get the span to point to, even if we don't use the name.
306306
let span = tcx.hir().span_if_local(region_def_id).unwrap_or(DUMMY_SP);
307307
debug!(
308308
"bound region named: {:?}, is_named: {:?}",
309309
name,
310-
late_param.bound_region.is_named()
310+
late_param.kind.is_named()
311311
);
312312

313-
if late_param.bound_region.is_named() {
313+
if late_param.kind.is_named() {
314314
// A named region that is actually named.
315315
Some(RegionName {
316316
name,
@@ -332,7 +332,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
332332
}
333333
}
334334

335-
ty::BoundRegionKind::ClosureEnv => {
335+
ty::LateParamRegionKind::ClosureEnv => {
336336
let def_ty = self.regioncx.universal_regions().defining_ty;
337337

338338
let closure_kind = match def_ty {
@@ -369,7 +369,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
369369
})
370370
}
371371

372-
ty::BoundRegionKind::Anon => None,
372+
ty::LateParamRegionKind::Anon(_) => None,
373373
},
374374

375375
ty::ReBound(..)

compiler/rustc_borrowck/src/universal_regions.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
844844
let (value, _map) = self.tcx.instantiate_bound_regions(value, |br| {
845845
debug!(?br);
846846
let liberated_region =
847-
ty::Region::new_late_param(self.tcx, all_outlive_scope.to_def_id(), br.kind);
847+
ty::Region::new_late_param_from_bound(self.tcx, all_outlive_scope.to_def_id(), br);
848848
let region_vid = {
849849
let name = match br.kind.get_name() {
850850
Some(name) => name,
@@ -942,12 +942,14 @@ fn for_each_late_bound_region_in_item<'tcx>(
942942
return;
943943
}
944944

945-
for bound_var in tcx.late_bound_vars(tcx.local_def_id_to_hir_id(mir_def_id)) {
946-
let ty::BoundVariableKind::Region(bound_region) = bound_var else {
947-
continue;
948-
};
949-
let liberated_region =
950-
ty::Region::new_late_param(tcx, mir_def_id.to_def_id(), bound_region);
951-
f(liberated_region);
945+
for (idx, bound_var) in
946+
tcx.late_bound_vars(tcx.local_def_id_to_hir_id(mir_def_id)).iter().enumerate()
947+
{
948+
if let ty::BoundVariableKind::Region(kind) = bound_var {
949+
let bound = ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind };
950+
let liberated_region =
951+
ty::Region::new_late_param_from_bound(tcx, mir_def_id.to_def_id(), bound);
952+
f(liberated_region);
953+
}
952954
}
953955
}

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -430,12 +430,12 @@ fn compare_method_predicate_entailment<'tcx>(
430430
Ok(())
431431
}
432432

433-
struct RemapLateBound<'a, 'tcx> {
433+
struct RemapLateParam<'a, 'tcx> {
434434
tcx: TyCtxt<'tcx>,
435-
mapping: &'a FxIndexMap<ty::BoundRegionKind, ty::BoundRegionKind>,
435+
mapping: &'a FxIndexMap<ty::LateParamRegionKind, ty::LateParamRegionKind>,
436436
}
437437

438-
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
438+
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'_, 'tcx> {
439439
fn cx(&self) -> TyCtxt<'tcx> {
440440
self.tcx
441441
}
@@ -445,7 +445,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
445445
ty::Region::new_late_param(
446446
self.tcx,
447447
fr.scope,
448-
self.mapping.get(&fr.bound_region).copied().unwrap_or(fr.bound_region),
448+
self.mapping.get(&fr.kind).copied().unwrap_or(fr.kind),
449449
)
450450
} else {
451451
r

compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -289,19 +289,24 @@ fn report_mismatched_rpitit_signature<'tcx>(
289289
tcx.fn_sig(trait_m_def_id).skip_binder().bound_vars(),
290290
tcx.fn_sig(impl_m_def_id).skip_binder().bound_vars(),
291291
)
292-
.filter_map(|(impl_bv, trait_bv)| {
292+
.enumerate()
293+
.filter_map(|(idx, (impl_bv, trait_bv))| {
293294
if let ty::BoundVariableKind::Region(impl_bv) = impl_bv
294295
&& let ty::BoundVariableKind::Region(trait_bv) = trait_bv
295296
{
296-
Some((impl_bv, trait_bv))
297+
let var = ty::BoundVar::from_usize(idx);
298+
Some((
299+
ty::LateParamRegionKind::from_bound(var, impl_bv),
300+
ty::LateParamRegionKind::from_bound(var, trait_bv),
301+
))
297302
} else {
298303
None
299304
}
300305
})
301306
.collect();
302307

303308
let mut return_ty =
304-
trait_m_sig.output().fold_with(&mut super::RemapLateBound { tcx, mapping: &mapping });
309+
trait_m_sig.output().fold_with(&mut super::RemapLateParam { tcx, mapping: &mapping });
305310

306311
if tcx.asyncness(impl_m_def_id).is_async() && tcx.asyncness(trait_m_def_id).is_async() {
307312
let ty::Alias(ty::Projection, future_ty) = return_ty.kind() else {

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -2296,9 +2296,13 @@ fn lint_redundant_lifetimes<'tcx>(
22962296
);
22972297
// If we are in a function, add its late-bound lifetimes too.
22982298
if matches!(def_kind, DefKind::Fn | DefKind::AssocFn) {
2299-
for var in tcx.fn_sig(owner_id).instantiate_identity().bound_vars() {
2299+
for (idx, var) in
2300+
tcx.fn_sig(owner_id).instantiate_identity().bound_vars().iter().enumerate()
2301+
{
23002302
let ty::BoundVariableKind::Region(kind) = var else { continue };
2301-
lifetimes.push(ty::Region::new_late_param(tcx, owner_id.to_def_id(), kind));
2303+
let bound: ty::BoundRegion =
2304+
ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind };
2305+
lifetimes.push(ty::Region::new_late_param_from_bound(tcx, owner_id.to_def_id(), bound));
23022306
}
23032307
}
23042308
lifetimes.retain(|candidate| candidate.has_name());

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
350350
ty::Region::new_late_param(
351351
tcx,
352352
scope.to_def_id(),
353-
ty::BoundRegionKind::Named(id.to_def_id(), name),
353+
ty::LateParamRegionKind::Named(id.to_def_id(), name),
354354
)
355355

356356
// (*) -- not late-bound, won't change

compiler/rustc_lint/src/impl_trait_overcaptures.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ where
325325
ParamKind::Free(def_id, name) => ty::Region::new_late_param(
326326
self.tcx,
327327
self.parent_def_id.to_def_id(),
328-
ty::BoundRegionKind::Named(def_id, name),
328+
ty::LateParamRegionKind::Named(def_id, name),
329329
),
330330
// Totally ignore late bound args from binders.
331331
ParamKind::Late => return true,
@@ -475,7 +475,7 @@ fn extract_def_id_from_arg<'tcx>(
475475
)
476476
| ty::ReLateParam(ty::LateParamRegion {
477477
scope: _,
478-
bound_region: ty::BoundRegionKind::Named(def_id, ..),
478+
kind: ty::LateParamRegionKind::Named(def_id, ..),
479479
}) => def_id,
480480
_ => unreachable!(),
481481
},
@@ -544,7 +544,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for FunctionalVariances<'tcx> {
544544
)
545545
| ty::ReLateParam(ty::LateParamRegion {
546546
scope: _,
547-
bound_region: ty::BoundRegionKind::Named(def_id, ..),
547+
kind: ty::LateParamRegionKind::Named(def_id, ..),
548548
}) => def_id,
549549
_ => {
550550
return Ok(a);

compiler/rustc_middle/src/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3098,7 +3098,7 @@ impl<'tcx> TyCtxt<'tcx> {
30983098
return ty::Region::new_late_param(
30993099
self,
31003100
new_parent.to_def_id(),
3101-
ty::BoundRegionKind::Named(
3101+
ty::LateParamRegionKind::Named(
31023102
lbv.to_def_id(),
31033103
self.item_name(lbv.to_def_id()),
31043104
),

compiler/rustc_middle/src/ty/fold.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ impl<'tcx> TyCtxt<'tcx> {
270270
T: TypeFoldable<TyCtxt<'tcx>>,
271271
{
272272
self.instantiate_bound_regions_uncached(value, |br| {
273-
ty::Region::new_late_param(self, all_outlive_scope, br.kind)
273+
ty::Region::new_late_param_from_bound(self, all_outlive_scope, br)
274274
})
275275
}
276276

compiler/rustc_middle/src/ty/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ pub use self::predicate::{
8484
TypeOutlivesPredicate,
8585
};
8686
pub use self::region::{
87-
BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, Region, RegionKind, RegionVid,
87+
BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, LateParamRegionKind, Region,
88+
RegionKind, RegionVid,
8889
};
8990
pub use self::rvalue_scopes::RvalueScopes;
9091
pub use self::sty::{

compiler/rustc_middle/src/ty/print/pretty.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -2375,8 +2375,8 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
23752375
match *region {
23762376
ty::ReEarlyParam(ref data) => data.has_name(),
23772377

2378+
ty::ReLateParam(ty::LateParamRegion { kind, .. }) => kind.is_named(),
23782379
ty::ReBound(_, ty::BoundRegion { kind: br, .. })
2379-
| ty::ReLateParam(ty::LateParamRegion { bound_region: br, .. })
23802380
| ty::RePlaceholder(ty::Placeholder {
23812381
bound: ty::BoundRegion { kind: br, .. }, ..
23822382
}) => {
@@ -2449,8 +2449,13 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
24492449
return Ok(());
24502450
}
24512451
}
2452+
ty::ReLateParam(ty::LateParamRegion { kind, .. }) => {
2453+
if let Some(name) = kind.get_name() {
2454+
p!(write("{}", name));
2455+
return Ok(());
2456+
}
2457+
}
24522458
ty::ReBound(_, ty::BoundRegion { kind: br, .. })
2453-
| ty::ReLateParam(ty::LateParamRegion { bound_region: br, .. })
24542459
| ty::RePlaceholder(ty::Placeholder {
24552460
bound: ty::BoundRegion { kind: br, .. }, ..
24562461
}) => {

compiler/rustc_middle/src/ty/region.rs

+84-8
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,21 @@ impl<'tcx> Region<'tcx> {
7070
pub fn new_late_param(
7171
tcx: TyCtxt<'tcx>,
7272
scope: DefId,
73-
bound_region: ty::BoundRegionKind,
73+
kind: LateParamRegionKind,
7474
) -> Region<'tcx> {
75-
tcx.intern_region(ty::ReLateParam(ty::LateParamRegion { scope, bound_region }))
75+
let data = LateParamRegion { scope, kind };
76+
tcx.intern_region(ty::ReLateParam(data))
77+
}
78+
79+
#[inline]
80+
pub fn new_late_param_from_bound(
81+
tcx: TyCtxt<'tcx>,
82+
scope: DefId,
83+
bound: BoundRegion,
84+
) -> Region<'tcx> {
85+
let data =
86+
LateParamRegion { scope, kind: LateParamRegionKind::from_bound(bound.var, bound.kind) };
87+
tcx.intern_region(ty::ReLateParam(data))
7688
}
7789

7890
#[inline]
@@ -125,8 +137,8 @@ impl<'tcx> Region<'tcx> {
125137
match kind {
126138
ty::ReEarlyParam(region) => Region::new_early_param(tcx, region),
127139
ty::ReBound(debruijn, region) => Region::new_bound(tcx, debruijn, region),
128-
ty::ReLateParam(ty::LateParamRegion { scope, bound_region }) => {
129-
Region::new_late_param(tcx, scope, bound_region)
140+
ty::ReLateParam(ty::LateParamRegion { scope, kind }) => {
141+
Region::new_late_param(tcx, scope, kind)
130142
}
131143
ty::ReStatic => tcx.lifetimes.re_static,
132144
ty::ReVar(vid) => Region::new_var(tcx, vid),
@@ -166,7 +178,7 @@ impl<'tcx> Region<'tcx> {
166178
match *self {
167179
ty::ReEarlyParam(ebr) => Some(ebr.name),
168180
ty::ReBound(_, br) => br.kind.get_name(),
169-
ty::ReLateParam(fr) => fr.bound_region.get_name(),
181+
ty::ReLateParam(fr) => fr.kind.get_name(),
170182
ty::ReStatic => Some(kw::StaticLifetime),
171183
ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(),
172184
_ => None,
@@ -188,7 +200,7 @@ impl<'tcx> Region<'tcx> {
188200
match *self {
189201
ty::ReEarlyParam(ebr) => ebr.has_name(),
190202
ty::ReBound(_, br) => br.kind.is_named(),
191-
ty::ReLateParam(fr) => fr.bound_region.is_named(),
203+
ty::ReLateParam(fr) => fr.kind.is_named(),
192204
ty::ReStatic => true,
193205
ty::ReVar(..) => false,
194206
ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(),
@@ -311,7 +323,7 @@ impl<'tcx> Region<'tcx> {
311323
Some(tcx.generics_of(binding_item).region_param(ebr, tcx).def_id)
312324
}
313325
ty::ReLateParam(ty::LateParamRegion {
314-
bound_region: ty::BoundRegionKind::Named(def_id, _),
326+
kind: ty::LateParamRegionKind::Named(def_id, _),
315327
..
316328
}) => Some(def_id),
317329
_ => None,
@@ -359,7 +371,71 @@ impl std::fmt::Debug for EarlyParamRegion {
359371
/// different parameters apart.
360372
pub struct LateParamRegion {
361373
pub scope: DefId,
362-
pub bound_region: BoundRegionKind,
374+
pub kind: LateParamRegionKind,
375+
}
376+
377+
/// When liberating bound regions, we map their [`BoundRegionKind`]
378+
/// to this as we need to track the index of anonymous regions. We
379+
/// otherwise end up liberating multiple bound regions to the same
380+
/// late-bound region.
381+
#[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Copy)]
382+
#[derive(HashStable)]
383+
pub enum LateParamRegionKind {
384+
/// An anonymous region parameter for a given fn (&T)
385+
///
386+
/// Unlike [`BoundRegionKind::Anon`], this tracks the index of the
387+
/// liberated bound region.
388+
///
389+
/// We should ideally never liberate anonymous regions, but do so for the
390+
/// sake of diagnostics in `FnCtxt::sig_of_closure_with_expectation`.
391+
Anon(u32),
392+
393+
/// Named region parameters for functions (a in &'a T)
394+
///
395+
/// The `DefId` is needed to distinguish free regions in
396+
/// the event of shadowing.
397+
Named(DefId, Symbol),
398+
399+
/// Anonymous region for the implicit env pointer parameter
400+
/// to a closure
401+
ClosureEnv,
402+
}
403+
404+
impl LateParamRegionKind {
405+
pub fn from_bound(var: BoundVar, br: BoundRegionKind) -> LateParamRegionKind {
406+
match br {
407+
BoundRegionKind::Anon => LateParamRegionKind::Anon(var.as_u32()),
408+
BoundRegionKind::Named(def_id, name) => LateParamRegionKind::Named(def_id, name),
409+
BoundRegionKind::ClosureEnv => LateParamRegionKind::ClosureEnv,
410+
}
411+
}
412+
413+
pub fn is_named(&self) -> bool {
414+
match *self {
415+
LateParamRegionKind::Named(_, name) => {
416+
name != kw::UnderscoreLifetime && name != kw::Empty
417+
}
418+
_ => false,
419+
}
420+
}
421+
422+
pub fn get_name(&self) -> Option<Symbol> {
423+
if self.is_named() {
424+
match *self {
425+
LateParamRegionKind::Named(_, name) => return Some(name),
426+
_ => unreachable!(),
427+
}
428+
}
429+
430+
None
431+
}
432+
433+
pub fn get_id(&self) -> Option<DefId> {
434+
match *self {
435+
LateParamRegionKind::Named(id, _) => Some(id),
436+
_ => None,
437+
}
438+
}
363439
}
364440

365441
#[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Copy)]

compiler/rustc_middle/src/ty/structural_impls.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,23 @@ impl fmt::Debug for ty::BoundRegionKind {
7777

7878
impl fmt::Debug for ty::LateParamRegion {
7979
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80-
write!(f, "ReLateParam({:?}, {:?})", self.scope, self.bound_region)
80+
write!(f, "ReLateParam({:?}, {:?})", self.scope, self.kind)
81+
}
82+
}
83+
84+
impl fmt::Debug for ty::LateParamRegionKind {
85+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86+
match *self {
87+
ty::LateParamRegionKind::Anon(idx) => write!(f, "BrAnon({idx})"),
88+
ty::LateParamRegionKind::Named(did, name) => {
89+
if did.is_crate_root() {
90+
write!(f, "BrNamed({name})")
91+
} else {
92+
write!(f, "BrNamed({did:?}, {name})")
93+
}
94+
}
95+
ty::LateParamRegionKind::ClosureEnv => write!(f, "BrEnv"),
96+
}
8197
}
8298
}
8399

0 commit comments

Comments
 (0)