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/middle/region.rs92
-rw-r--r--compiler/rustc_middle/src/ty/context.rs5
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs9
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs105
-rw-r--r--compiler/rustc_middle/src/ty/region.rs112
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs26
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs4
7 files changed, 111 insertions, 242 deletions
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 92eab59dd02..0f5b63f5c1d 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -7,7 +7,6 @@
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
 
 use std::fmt;
-use std::ops::Deref;
 
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::unord::UnordMap;
@@ -228,82 +227,6 @@ pub struct ScopeTree {
     /// This information is used later for linting to identify locals and
     /// temporary values that will receive backwards-incompatible drop orders.
     pub backwards_incompatible_scope: UnordMap<hir::ItemLocalId, Scope>,
-
-    /// If there are any `yield` nested within a scope, this map
-    /// stores the `Span` of the last one and its index in the
-    /// postorder of the Visitor traversal on the HIR.
-    ///
-    /// HIR Visitor postorder indexes might seem like a peculiar
-    /// thing to care about. but it turns out that HIR bindings
-    /// and the temporary results of HIR expressions are never
-    /// storage-live at the end of HIR nodes with postorder indexes
-    /// lower than theirs, and therefore don't need to be suspended
-    /// at yield-points at these indexes.
-    ///
-    /// For an example, suppose we have some code such as:
-    /// ```rust,ignore (example)
-    ///     foo(f(), yield y, bar(g()))
-    /// ```
-    ///
-    /// With the HIR tree (calls numbered for expository purposes)
-    ///
-    /// ```text
-    ///     Call#0(foo, [Call#1(f), Yield(y), Call#2(bar, Call#3(g))])
-    /// ```
-    ///
-    /// Obviously, the result of `f()` was created before the yield
-    /// (and therefore needs to be kept valid over the yield) while
-    /// the result of `g()` occurs after the yield (and therefore
-    /// doesn't). If we want to infer that, we can look at the
-    /// postorder traversal:
-    /// ```plain,ignore
-    ///     `foo` `f` Call#1 `y` Yield `bar` `g` Call#3 Call#2 Call#0
-    /// ```
-    ///
-    /// In which we can easily see that `Call#1` occurs before the yield,
-    /// and `Call#3` after it.
-    ///
-    /// To see that this method works, consider:
-    ///
-    /// Let `D` be our binding/temporary and `U` be our other HIR node, with
-    /// `HIR-postorder(U) < HIR-postorder(D)`. Suppose, as in our example,
-    /// U is the yield and D is one of the calls.
-    /// Let's show that `D` is storage-dead at `U`.
-    ///
-    /// Remember that storage-live/storage-dead refers to the state of
-    /// the *storage*, and does not consider moves/drop flags.
-    ///
-    /// Then:
-    ///
-    ///   1. From the ordering guarantee of HIR visitors (see
-    ///   `rustc_hir::intravisit`), `D` does not dominate `U`.
-    ///
-    ///   2. Therefore, `D` is *potentially* storage-dead at `U` (because
-    ///   we might visit `U` without ever getting to `D`).
-    ///
-    ///   3. However, we guarantee that at each HIR point, each
-    ///   binding/temporary is always either always storage-live
-    ///   or always storage-dead. This is what is being guaranteed
-    ///   by `terminating_scopes` including all blocks where the
-    ///   count of executions is not guaranteed.
-    ///
-    ///   4. By `2.` and `3.`, `D` is *statically* storage-dead at `U`,
-    ///   QED.
-    ///
-    /// This property ought to not on (3) in an essential way -- it
-    /// is probably still correct even if we have "unrestricted" terminating
-    /// scopes. However, why use the complicated proof when a simple one
-    /// works?
-    ///
-    /// A subtle thing: `box` expressions, such as `box (&x, yield 2, &y)`. It
-    /// might seem that a `box` expression creates a `Box<T>` temporary
-    /// when it *starts* executing, at `HIR-preorder(BOX-EXPR)`. That might
-    /// be true in the MIR desugaring, but it is not important in the semantics.
-    ///
-    /// The reason is that semantically, until the `box` expression returns,
-    /// the values are still owned by their containing expressions. So
-    /// we'll see that `&x`.
-    pub yield_in_scope: UnordMap<Scope, Vec<YieldData>>,
 }
 
 /// See the `rvalue_candidates` field for more information on rvalue
@@ -316,15 +239,6 @@ pub struct RvalueCandidate {
     pub lifetime: Option<Scope>,
 }
 
-#[derive(Debug, Copy, Clone, HashStable)]
-pub struct YieldData {
-    /// The `Span` of the yield.
-    pub span: Span,
-    /// The number of expressions and patterns appearing before the `yield` in the body, plus one.
-    pub expr_and_pat_count: usize,
-    pub source: hir::YieldSource,
-}
-
 impl ScopeTree {
     pub fn record_scope_parent(&mut self, child: Scope, parent: Option<Scope>) {
         debug!("{:?}.parent = {:?}", child, parent);
@@ -380,10 +294,4 @@ impl ScopeTree {
 
         true
     }
-
-    /// Checks whether the given scope contains a `yield`. If so,
-    /// returns `Some(YieldData)`. If not, returns `None`.
-    pub fn yield_in_scope(&self, scope: Scope) -> Option<&[YieldData]> {
-        self.yield_in_scope.get(&scope).map(Deref::deref)
-    }
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index e8b15b76fd8..98b2ce01d89 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -3279,10 +3279,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     return ty::Region::new_late_param(
                         self,
                         new_parent.to_def_id(),
-                        ty::LateParamRegionKind::Named(
-                            lbv.to_def_id(),
-                            self.item_name(lbv.to_def_id()),
-                        ),
+                        ty::LateParamRegionKind::Named(lbv.to_def_id()),
                     );
                 }
                 resolve_bound_vars::ResolvedArg::Error(guar) => {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index a92d6fe3916..b780b1c5776 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -474,7 +474,7 @@ impl<'tcx> rustc_type_ir::Flags for Ty<'tcx> {
 impl EarlyParamRegion {
     /// Does this early bound region have a name? Early bound regions normally
     /// always have names except when using anonymous lifetimes (`'_`).
-    pub fn has_name(&self) -> bool {
+    pub fn is_named(&self) -> bool {
         self.name != kw::UnderscoreLifetime
     }
 }
@@ -1525,7 +1525,8 @@ impl<'tcx> TyCtxt<'tcx> {
             field_shuffle_seed ^= user_seed;
         }
 
-        if let Some(reprs) = attr::find_attr!(self.get_all_attrs(did), AttributeKind::Repr(r) => r)
+        if let Some(reprs) =
+            attr::find_attr!(self.get_all_attrs(did), AttributeKind::Repr { reprs, .. } => reprs)
         {
             for (r, _) in reprs {
                 flags.insert(match *r {
@@ -1566,10 +1567,6 @@ impl<'tcx> TyCtxt<'tcx> {
                         max_align = max_align.max(Some(align));
                         ReprFlags::empty()
                     }
-                    attr::ReprEmpty => {
-                        /* skip these, they're just for diagnostics */
-                        ReprFlags::empty()
-                    }
                 });
             }
         }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 19f2258fe99..4e078847815 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -11,7 +11,7 @@ use rustc_data_structures::unord::UnordMap;
 use rustc_hir as hir;
 use rustc_hir::LangItem;
 use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
-use rustc_hir::def_id::{CRATE_DEF_ID, DefIdMap, DefIdSet, LOCAL_CRATE, ModDefId};
+use rustc_hir::def_id::{DefIdMap, DefIdSet, LOCAL_CRATE, ModDefId};
 use rustc_hir::definitions::{DefKey, DefPathDataName};
 use rustc_macros::{Lift, extension};
 use rustc_session::Limit;
@@ -795,9 +795,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 ty::BoundTyKind::Anon => {
                     rustc_type_ir::debug_bound_var(self, debruijn, bound_ty.var)?
                 }
-                ty::BoundTyKind::Param(_, s) => match self.should_print_verbose() {
+                ty::BoundTyKind::Param(def_id) => match self.should_print_verbose() {
                     true => p!(write("{:?}", ty.kind())),
-                    false => p!(write("{s}")),
+                    false => p!(write("{}", self.tcx().item_name(def_id))),
                 },
             },
             ty::Adt(def, args) => {
@@ -822,13 +822,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             ty::Alias(ty::Projection | ty::Inherent | ty::Free, ref data) => {
                 p!(print(data))
             }
-            ty::Placeholder(placeholder) => match placeholder.bound.kind {
-                ty::BoundTyKind::Anon => p!(write("{placeholder:?}")),
-                ty::BoundTyKind::Param(_, name) => match self.should_print_verbose() {
-                    true => p!(write("{:?}", ty.kind())),
-                    false => p!(write("{name}")),
-                },
-            },
+            ty::Placeholder(placeholder) => p!(print(placeholder)),
             ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
                 // We use verbose printing in 'NO_QUERIES' mode, to
                 // avoid needing to call `predicates_of`. This should
@@ -2551,14 +2545,14 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
         let identify_regions = self.tcx.sess.opts.unstable_opts.identify_regions;
 
         match region.kind() {
-            ty::ReEarlyParam(ref data) => data.has_name(),
+            ty::ReEarlyParam(ref data) => data.is_named(),
 
-            ty::ReLateParam(ty::LateParamRegion { kind, .. }) => kind.is_named(),
+            ty::ReLateParam(ty::LateParamRegion { kind, .. }) => kind.is_named(self.tcx),
             ty::ReBound(_, ty::BoundRegion { kind: br, .. })
             | ty::RePlaceholder(ty::Placeholder {
                 bound: ty::BoundRegion { kind: br, .. }, ..
             }) => {
-                if br.is_named() {
+                if br.is_named(self.tcx) {
                     return true;
                 }
 
@@ -2626,7 +2620,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                 return Ok(());
             }
             ty::ReLateParam(ty::LateParamRegion { kind, .. }) => {
-                if let Some(name) = kind.get_name() {
+                if let Some(name) = kind.get_name(self.tcx) {
                     p!(write("{}", name));
                     return Ok(());
                 }
@@ -2635,9 +2629,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
             | ty::RePlaceholder(ty::Placeholder {
                 bound: ty::BoundRegion { kind: br, .. }, ..
             }) => {
-                if let ty::BoundRegionKind::Named(_, name) = br
-                    && br.is_named()
-                {
+                if let Some(name) = br.get_name(self.tcx) {
                     p!(write("{}", name));
                     return Ok(());
                 }
@@ -2844,55 +2836,22 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
             let mut name = |lifetime_idx: Option<ty::DebruijnIndex>,
                             binder_level_idx: ty::DebruijnIndex,
                             br: ty::BoundRegion| {
-                let (name, kind) = match br.kind {
-                    ty::BoundRegionKind::Anon | ty::BoundRegionKind::ClosureEnv => {
-                        let name = next_name(self);
-
-                        if let Some(lt_idx) = lifetime_idx {
-                            if lt_idx > binder_level_idx {
-                                let kind =
-                                    ty::BoundRegionKind::Named(CRATE_DEF_ID.to_def_id(), name);
-                                return ty::Region::new_bound(
-                                    tcx,
-                                    ty::INNERMOST,
-                                    ty::BoundRegion { var: br.var, kind },
-                                );
-                            }
-                        }
-
-                        (name, ty::BoundRegionKind::Named(CRATE_DEF_ID.to_def_id(), name))
-                    }
-                    ty::BoundRegionKind::Named(def_id, kw::UnderscoreLifetime) => {
-                        let name = next_name(self);
-
-                        if let Some(lt_idx) = lifetime_idx {
-                            if lt_idx > binder_level_idx {
-                                let kind = ty::BoundRegionKind::Named(def_id, name);
-                                return ty::Region::new_bound(
-                                    tcx,
-                                    ty::INNERMOST,
-                                    ty::BoundRegion { var: br.var, kind },
-                                );
-                            }
-                        }
-
-                        (name, ty::BoundRegionKind::Named(def_id, name))
-                    }
-                    ty::BoundRegionKind::Named(_, name) => {
-                        if let Some(lt_idx) = lifetime_idx {
-                            if lt_idx > binder_level_idx {
-                                let kind = br.kind;
-                                return ty::Region::new_bound(
-                                    tcx,
-                                    ty::INNERMOST,
-                                    ty::BoundRegion { var: br.var, kind },
-                                );
-                            }
-                        }
+                let (name, kind) = if let Some(name) = br.kind.get_name(tcx) {
+                    (name, br.kind)
+                } else {
+                    let name = next_name(self);
+                    (name, ty::BoundRegionKind::NamedAnon(name))
+                };
 
-                        (name, br.kind)
+                if let Some(lt_idx) = lifetime_idx {
+                    if lt_idx > binder_level_idx {
+                        return ty::Region::new_bound(
+                            tcx,
+                            ty::INNERMOST,
+                            ty::BoundRegion { var: br.var, kind },
+                        );
                     }
-                };
+                }
 
                 // Unconditionally render `unsafe<>`.
                 if !trim_path || mode == WrapBinderMode::Unsafe {
@@ -2960,13 +2919,15 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
         struct RegionNameCollector<'tcx> {
+            tcx: TyCtxt<'tcx>,
             used_region_names: FxHashSet<Symbol>,
             type_collector: SsoHashSet<Ty<'tcx>>,
         }
 
         impl<'tcx> RegionNameCollector<'tcx> {
-            fn new() -> Self {
+            fn new(tcx: TyCtxt<'tcx>) -> Self {
                 RegionNameCollector {
+                    tcx,
                     used_region_names: Default::default(),
                     type_collector: SsoHashSet::new(),
                 }
@@ -2980,7 +2941,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                 // Collect all named lifetimes. These allow us to prevent duplication
                 // of already existing lifetime names when introducing names for
                 // anonymous late-bound regions.
-                if let Some(name) = r.get_name() {
+                if let Some(name) = r.get_name(self.tcx) {
                     self.used_region_names.insert(name);
                 }
             }
@@ -2995,7 +2956,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
             }
         }
 
-        let mut collector = RegionNameCollector::new();
+        let mut collector = RegionNameCollector::new(self.tcx());
         value.visit_with(&mut collector);
         self.used_region_names = collector.used_region_names;
         self.region_index = 0;
@@ -3406,6 +3367,16 @@ define_print_and_forward_display! {
         p!(write("{}", self.name))
     }
 
+    ty::PlaceholderType {
+        match self.bound.kind {
+            ty::BoundTyKind::Anon => p!(write("{self:?}")),
+            ty::BoundTyKind::Param(def_id) => match cx.should_print_verbose() {
+                true => p!(write("{self:?}")),
+                false => p!(write("{}", cx.tcx().item_name(def_id))),
+            },
+        }
+    }
+
     ty::ParamConst {
         p!(write("{}", self.name))
     }
diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs
index cc25cd16567..51be93d9a72 100644
--- a/compiler/rustc_middle/src/ty/region.rs
+++ b/compiler/rustc_middle/src/ty/region.rs
@@ -163,37 +163,33 @@ impl<'tcx> Region<'tcx> {
         *self.0.0
     }
 
-    pub fn get_name(self) -> Option<Symbol> {
-        if self.has_name() {
-            match self.kind() {
-                ty::ReEarlyParam(ebr) => Some(ebr.name),
-                ty::ReBound(_, br) => br.kind.get_name(),
-                ty::ReLateParam(fr) => fr.kind.get_name(),
-                ty::ReStatic => Some(kw::StaticLifetime),
-                ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(),
-                _ => None,
-            }
-        } else {
-            None
+    pub fn get_name(self, tcx: TyCtxt<'tcx>) -> Option<Symbol> {
+        match self.kind() {
+            ty::ReEarlyParam(ebr) => ebr.is_named().then_some(ebr.name),
+            ty::ReBound(_, br) => br.kind.get_name(tcx),
+            ty::ReLateParam(fr) => fr.kind.get_name(tcx),
+            ty::ReStatic => Some(kw::StaticLifetime),
+            ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(tcx),
+            _ => None,
         }
     }
 
-    pub fn get_name_or_anon(self) -> Symbol {
-        match self.get_name() {
+    pub fn get_name_or_anon(self, tcx: TyCtxt<'tcx>) -> Symbol {
+        match self.get_name(tcx) {
             Some(name) => name,
             None => sym::anon,
         }
     }
 
     /// Is this region named by the user?
-    pub fn has_name(self) -> bool {
+    pub fn is_named(self, tcx: TyCtxt<'tcx>) -> bool {
         match self.kind() {
-            ty::ReEarlyParam(ebr) => ebr.has_name(),
-            ty::ReBound(_, br) => br.kind.is_named(),
-            ty::ReLateParam(fr) => fr.kind.is_named(),
+            ty::ReEarlyParam(ebr) => ebr.is_named(),
+            ty::ReBound(_, br) => br.kind.is_named(tcx),
+            ty::ReLateParam(fr) => fr.kind.is_named(tcx),
             ty::ReStatic => true,
             ty::ReVar(..) => false,
-            ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(),
+            ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(tcx),
             ty::ReErased => false,
             ty::ReError(_) => false,
         }
@@ -313,7 +309,7 @@ impl<'tcx> Region<'tcx> {
                 Some(tcx.generics_of(binding_item).region_param(ebr, tcx).def_id)
             }
             ty::ReLateParam(ty::LateParamRegion {
-                kind: ty::LateParamRegionKind::Named(def_id, _),
+                kind: ty::LateParamRegionKind::Named(def_id),
                 ..
             }) => Some(def_id),
             _ => None,
@@ -371,11 +367,13 @@ pub enum LateParamRegionKind {
     /// sake of diagnostics in `FnCtxt::sig_of_closure_with_expectation`.
     Anon(u32),
 
-    /// Named region parameters for functions (a in &'a T)
+    /// An anonymous region parameter with a `Symbol` name.
     ///
-    /// The `DefId` is needed to distinguish free regions in
-    /// the event of shadowing.
-    Named(DefId, Symbol),
+    /// Used to give late-bound regions names for things like pretty printing.
+    NamedAnon(u32, Symbol),
+
+    /// Late-bound regions that appear in the AST.
+    Named(DefId),
 
     /// Anonymous region for the implicit env pointer parameter
     /// to a closure
@@ -386,32 +384,30 @@ 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::Named(def_id) => LateParamRegionKind::Named(def_id),
             BoundRegionKind::ClosureEnv => LateParamRegionKind::ClosureEnv,
+            BoundRegionKind::NamedAnon(name) => LateParamRegionKind::NamedAnon(var.as_u32(), name),
         }
     }
 
-    pub fn is_named(&self) -> bool {
-        match *self {
-            LateParamRegionKind::Named(_, name) => name != kw::UnderscoreLifetime,
-            _ => false,
-        }
+    pub fn is_named(&self, tcx: TyCtxt<'_>) -> bool {
+        self.get_name(tcx).is_some()
     }
 
-    pub fn get_name(&self) -> Option<Symbol> {
-        if self.is_named() {
-            match *self {
-                LateParamRegionKind::Named(_, name) => return Some(name),
-                _ => unreachable!(),
+    pub fn get_name(&self, tcx: TyCtxt<'_>) -> Option<Symbol> {
+        match *self {
+            LateParamRegionKind::Named(def_id) => {
+                let name = tcx.item_name(def_id);
+                if name != kw::UnderscoreLifetime { Some(name) } else { None }
             }
+            LateParamRegionKind::NamedAnon(_, name) => Some(name),
+            _ => None,
         }
-
-        None
     }
 
     pub fn get_id(&self) -> Option<DefId> {
         match *self {
-            LateParamRegionKind::Named(id, _) => Some(id),
+            LateParamRegionKind::Named(id) => Some(id),
             _ => None,
         }
     }
@@ -423,11 +419,13 @@ pub enum BoundRegionKind {
     /// An anonymous region parameter for a given fn (&T)
     Anon,
 
-    /// Named region parameters for functions (a in &'a T)
+    /// An anonymous region parameter with a `Symbol` name.
     ///
-    /// The `DefId` is needed to distinguish free regions in
-    /// the event of shadowing.
-    Named(DefId, Symbol),
+    /// Used to give late-bound regions names for things like pretty printing.
+    NamedAnon(Symbol),
+
+    /// Late-bound regions that appear in the AST.
+    Named(DefId),
 
     /// Anonymous region for the implicit env pointer parameter
     /// to a closure
@@ -456,35 +454,35 @@ impl core::fmt::Debug for BoundRegion {
         match self.kind {
             BoundRegionKind::Anon => write!(f, "{:?}", self.var),
             BoundRegionKind::ClosureEnv => write!(f, "{:?}.Env", self.var),
-            BoundRegionKind::Named(def, symbol) => {
-                write!(f, "{:?}.Named({:?}, {:?})", self.var, def, symbol)
+            BoundRegionKind::Named(def) => {
+                write!(f, "{:?}.Named({:?})", self.var, def)
+            }
+            BoundRegionKind::NamedAnon(symbol) => {
+                write!(f, "{:?}.NamedAnon({:?})", self.var, symbol)
             }
         }
     }
 }
 
 impl BoundRegionKind {
-    pub fn is_named(&self) -> bool {
-        match *self {
-            BoundRegionKind::Named(_, name) => name != kw::UnderscoreLifetime,
-            _ => false,
-        }
+    pub fn is_named(&self, tcx: TyCtxt<'_>) -> bool {
+        self.get_name(tcx).is_some()
     }
 
-    pub fn get_name(&self) -> Option<Symbol> {
-        if self.is_named() {
-            match *self {
-                BoundRegionKind::Named(_, name) => return Some(name),
-                _ => unreachable!(),
+    pub fn get_name(&self, tcx: TyCtxt<'_>) -> Option<Symbol> {
+        match *self {
+            BoundRegionKind::Named(def_id) => {
+                let name = tcx.item_name(def_id);
+                if name != kw::UnderscoreLifetime { Some(name) } else { None }
             }
+            BoundRegionKind::NamedAnon(name) => Some(name),
+            _ => None,
         }
-
-        None
     }
 
     pub fn get_id(&self) -> Option<DefId> {
         match *self {
-            BoundRegionKind::Named(id, _) => Some(id),
+            BoundRegionKind::Named(id) => Some(id),
             _ => None,
         }
     }
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 1214731a3b2..af9c98bd87d 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -69,12 +69,11 @@ impl fmt::Debug for ty::BoundRegionKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             ty::BoundRegionKind::Anon => write!(f, "BrAnon"),
-            ty::BoundRegionKind::Named(did, name) => {
-                if did.is_crate_root() {
-                    write!(f, "BrNamed({name})")
-                } else {
-                    write!(f, "BrNamed({did:?}, {name})")
-                }
+            ty::BoundRegionKind::NamedAnon(name) => {
+                write!(f, "BrNamedAnon({name})")
+            }
+            ty::BoundRegionKind::Named(did) => {
+                write!(f, "BrNamed({did:?})")
             }
             ty::BoundRegionKind::ClosureEnv => write!(f, "BrEnv"),
         }
@@ -91,12 +90,11 @@ impl fmt::Debug for ty::LateParamRegionKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             ty::LateParamRegionKind::Anon(idx) => write!(f, "LateAnon({idx})"),
-            ty::LateParamRegionKind::Named(did, name) => {
-                if did.is_crate_root() {
-                    write!(f, "LateNamed({name})")
-                } else {
-                    write!(f, "LateNamed({did:?}, {name})")
-                }
+            ty::LateParamRegionKind::NamedAnon(idx, name) => {
+                write!(f, "LateNamedAnon({idx:?}, {name})")
+            }
+            ty::LateParamRegionKind::Named(did) => {
+                write!(f, "LateNamed({did:?})")
             }
             ty::LateParamRegionKind::ClosureEnv => write!(f, "LateEnv"),
         }
@@ -185,7 +183,7 @@ impl fmt::Debug for ty::BoundTy {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self.kind {
             ty::BoundTyKind::Anon => write!(f, "{:?}", self.var),
-            ty::BoundTyKind::Param(_, sym) => write!(f, "{sym:?}"),
+            ty::BoundTyKind::Param(def_id) => write!(f, "{def_id:?}"),
         }
     }
 }
@@ -274,7 +272,6 @@ TrivialTypeTraversalImpls! {
     crate::ty::BoundVar,
     crate::ty::InferConst,
     crate::ty::Placeholder<crate::ty::BoundRegion>,
-    crate::ty::Placeholder<crate::ty::BoundTy>,
     crate::ty::Placeholder<ty::BoundVar>,
     crate::ty::UserTypeAnnotationIndex,
     crate::ty::ValTree<'tcx>,
@@ -305,6 +302,7 @@ TrivialTypeTraversalAndLiftImpls! {
     // tidy-alphabetical-start
     crate::ty::ParamConst,
     crate::ty::ParamTy,
+    crate::ty::Placeholder<crate::ty::BoundTy>,
     crate::ty::instance::ReifyReason,
     rustc_hir::def_id::DefId,
     // tidy-alphabetical-end
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 7a1890226c9..8bb3b3f1263 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -400,7 +400,7 @@ impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundTy {
 #[derive(HashStable)]
 pub enum BoundTyKind {
     Anon,
-    Param(DefId, Symbol),
+    Param(DefId),
 }
 
 impl From<BoundVar> for BoundTy {
@@ -2032,7 +2032,7 @@ mod size_asserts {
 
     use super::*;
     // tidy-alphabetical-start
-    static_assert_size!(ty::RegionKind<'_>, 24);
+    static_assert_size!(ty::RegionKind<'_>, 20);
     static_assert_size!(ty::TyKind<'_>, 24);
     // tidy-alphabetical-end
 }