about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src')
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs3
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs3
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs9
-rw-r--r--compiler/rustc_middle/src/ty/region.rs81
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs18
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"),
+        }
     }
 }