diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/fold.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/print/pretty.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/region.rs | 81 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/structural_impls.rs | 18 |
6 files changed, 102 insertions, 14 deletions
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 54ee582f4de..977e62becf1 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3091,7 +3091,7 @@ impl<'tcx> TyCtxt<'tcx> { return ty::Region::new_late_param( self, new_parent.to_def_id(), - ty::BoundRegionKind::Named( + ty::LateParamRegionKind::Named( lbv.to_def_id(), self.item_name(lbv.to_def_id()), ), diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 1b073d3c466..067516917ef 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -270,7 +270,8 @@ impl<'tcx> TyCtxt<'tcx> { T: TypeFoldable<TyCtxt<'tcx>>, { self.instantiate_bound_regions_uncached(value, |br| { - ty::Region::new_late_param(self, all_outlive_scope, br.kind) + let kind = ty::LateParamRegionKind::from_bound(br.var, br.kind); + ty::Region::new_late_param(self, all_outlive_scope, kind) }) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 25d0d7b71da..9845598a64b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -83,7 +83,8 @@ pub use self::predicate::{ TypeOutlivesPredicate, }; pub use self::region::{ - BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, Region, RegionKind, RegionVid, + BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, LateParamRegionKind, Region, + RegionKind, RegionVid, }; pub use self::rvalue_scopes::RvalueScopes; pub use self::sty::{ diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 83508d97cf8..a089eac5d7e 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2374,8 +2374,8 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { match *region { ty::ReEarlyParam(ref data) => data.has_name(), + ty::ReLateParam(ty::LateParamRegion { kind, .. }) => kind.is_named(), ty::ReBound(_, ty::BoundRegion { kind: br, .. }) - | ty::ReLateParam(ty::LateParamRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { bound: ty::BoundRegion { kind: br, .. }, .. }) => { @@ -2448,8 +2448,13 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { return Ok(()); } } + ty::ReLateParam(ty::LateParamRegion { kind, .. }) => { + if let Some(name) = kind.get_name() { + p!(write("{}", name)); + return Ok(()); + } + } ty::ReBound(_, ty::BoundRegion { kind: br, .. }) - | ty::ReLateParam(ty::LateParamRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { bound: ty::BoundRegion { kind: br, .. }, .. }) => { diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 0eb2aafdf2e..14a2e5befe6 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -69,9 +69,10 @@ impl<'tcx> Region<'tcx> { pub fn new_late_param( tcx: TyCtxt<'tcx>, scope: DefId, - bound_region: ty::BoundRegionKind, + kind: LateParamRegionKind, ) -> Region<'tcx> { - tcx.intern_region(ty::ReLateParam(ty::LateParamRegion { scope, bound_region })) + let data = LateParamRegion { scope, kind }; + tcx.intern_region(ty::ReLateParam(data)) } #[inline] @@ -124,8 +125,8 @@ impl<'tcx> Region<'tcx> { match kind { ty::ReEarlyParam(region) => Region::new_early_param(tcx, region), ty::ReBound(debruijn, region) => Region::new_bound(tcx, debruijn, region), - ty::ReLateParam(ty::LateParamRegion { scope, bound_region }) => { - Region::new_late_param(tcx, scope, bound_region) + ty::ReLateParam(ty::LateParamRegion { scope, kind }) => { + Region::new_late_param(tcx, scope, kind) } ty::ReStatic => tcx.lifetimes.re_static, ty::ReVar(vid) => Region::new_var(tcx, vid), @@ -165,7 +166,7 @@ impl<'tcx> Region<'tcx> { match *self { ty::ReEarlyParam(ebr) => Some(ebr.name), ty::ReBound(_, br) => br.kind.get_name(), - ty::ReLateParam(fr) => fr.bound_region.get_name(), + ty::ReLateParam(fr) => fr.kind.get_name(), ty::ReStatic => Some(kw::StaticLifetime), ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(), _ => None, @@ -187,7 +188,7 @@ impl<'tcx> Region<'tcx> { match *self { ty::ReEarlyParam(ebr) => ebr.has_name(), ty::ReBound(_, br) => br.kind.is_named(), - ty::ReLateParam(fr) => fr.bound_region.is_named(), + ty::ReLateParam(fr) => fr.kind.is_named(), ty::ReStatic => true, ty::ReVar(..) => false, ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(), @@ -310,7 +311,7 @@ impl<'tcx> Region<'tcx> { Some(tcx.generics_of(binding_item).region_param(ebr, tcx).def_id) } ty::ReLateParam(ty::LateParamRegion { - bound_region: ty::BoundRegionKind::Named(def_id, _), + kind: ty::LateParamRegionKind::Named(def_id, _), .. }) => Some(def_id), _ => None, @@ -358,7 +359,71 @@ impl std::fmt::Debug for EarlyParamRegion { /// different parameters apart. pub struct LateParamRegion { pub scope: DefId, - pub bound_region: BoundRegionKind, + pub kind: LateParamRegionKind, +} + +/// When liberating bound regions, we map their [`BoundRegionKind`] +/// to this as we need to track the index of anonymous regions. We +/// otherwise end up liberating multiple bound regions to the same +/// late-bound region. +#[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Copy)] +#[derive(HashStable)] +pub enum LateParamRegionKind { + /// An anonymous region parameter for a given fn (&T) + /// + /// Unlike [`BoundRegionKind::Anon`], this tracks the index of the + /// liberated bound region. + /// + /// We should ideally never liberate anonymous regions, but do so for the + /// sake of diagnostics in `FnCtxt::sig_of_closure_with_expectation`. + Anon(u32), + + /// Named region parameters for functions (a in &'a T) + /// + /// The `DefId` is needed to distinguish free regions in + /// the event of shadowing. + Named(DefId, Symbol), + + /// Anonymous region for the implicit env pointer parameter + /// to a closure + ClosureEnv, +} + +impl LateParamRegionKind { + pub fn from_bound(var: BoundVar, br: BoundRegionKind) -> LateParamRegionKind { + match br { + BoundRegionKind::Anon => LateParamRegionKind::Anon(var.as_u32()), + BoundRegionKind::Named(def_id, name) => LateParamRegionKind::Named(def_id, name), + BoundRegionKind::ClosureEnv => LateParamRegionKind::ClosureEnv, + } + } + + pub fn is_named(&self) -> bool { + match *self { + LateParamRegionKind::Named(_, name) => { + name != kw::UnderscoreLifetime && name != kw::Empty + } + _ => false, + } + } + + pub fn get_name(&self) -> Option<Symbol> { + if self.is_named() { + match *self { + LateParamRegionKind::Named(_, name) => return Some(name), + _ => unreachable!(), + } + } + + None + } + + pub fn get_id(&self) -> Option<DefId> { + match *self { + LateParamRegionKind::Named(id, _) => Some(id), + _ => None, + } + } } #[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Copy)] diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index ec4fb93bdb3..f38454ceac0 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -77,7 +77,23 @@ impl fmt::Debug for ty::BoundRegionKind { impl fmt::Debug for ty::LateParamRegion { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ReLateParam({:?}, {:?})", self.scope, self.bound_region) + write!(f, "ReLateParam({:?}, {:?})", self.scope, self.kind) + } +} + +impl fmt::Debug for ty::LateParamRegionKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::LateParamRegionKind::Anon(idx) => write!(f, "BrAnon({idx})"), + ty::LateParamRegionKind::Named(did, name) => { + if did.is_crate_root() { + write!(f, "BrNamed({name})") + } else { + write!(f, "BrNamed({did:?}, {name})") + } + } + ty::LateParamRegionKind::ClosureEnv => write!(f, "BrEnv"), + } } } |
