1use std::fmt;
23use derive_where::derive_where;
4#[cfg(feature = "nightly")]
5use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher};
6#[cfg(feature = "nightly")]
7use rustc_macros::{Decodable_NoContext, Encodable_NoContext};
8use rustc_type_ir_macros::GenericTypeVisitable;
910use self::RegionKind::*;
11use crate::{BoundRegion, BoundVarIndexKind, Interner, LateParamRegion, PlaceholderRegion};
1213#[automatically_derived]
impl ::core::marker::Copy for RegionVid { }
impl RegionVid {
#[doc = r" Maximum value the index can take, as a `u32`."]
pub const MAX_AS_U32: u32 = 0xFFFF_FF00;
#[doc = r" Maximum value the index can take."]
pub const MAX: Self = Self::from_u32(0xFFFF_FF00);
#[doc = r" Zero value of the index."]
pub const ZERO: Self = Self::from_u32(0);
#[doc = r" Creates a new index from a given `usize`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" Will panic if `value` exceeds `MAX`."]
#[inline]
pub const fn from_usize(value: usize) -> Self {
if !(value <= (0xFFFF_FF00 as usize)) {
::core::panicking::panic("assertion failed: value <= (0xFFFF_FF00 as usize)")
};
unsafe { Self::from_u32_unchecked(value as u32) }
}
#[doc = r" Creates a new index from a given `u32`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" Will panic if `value` exceeds `MAX`."]
#[inline]
pub const fn from_u32(value: u32) -> Self {
if !(value <= 0xFFFF_FF00) {
::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
};
unsafe { Self::from_u32_unchecked(value) }
}
#[doc = r" Creates a new index from a given `u16`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" Will panic if `value` exceeds `MAX`."]
#[inline]
pub const fn from_u16(value: u16) -> Self {
let value = value as u32;
if !(value <= 0xFFFF_FF00) {
::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
};
unsafe { Self::from_u32_unchecked(value) }
}
#[doc = r" Creates a new index from a given `u32`."]
#[doc = r""]
#[doc = r" # Safety"]
#[doc = r""]
#[doc =
r" The provided value must be less than or equal to the maximum value for the newtype."]
#[doc =
r" Providing a value outside this range is undefined due to layout restrictions."]
#[doc = r""]
#[doc = r" Prefer using `from_u32`."]
#[inline]
pub const unsafe fn from_u32_unchecked(value: u32) -> Self {
Self {
private_use_as_methods_instead: unsafe {
std::mem::transmute(value)
},
}
}
#[doc = r" Extracts the value of this index as a `usize`."]
#[inline]
pub const fn index(self) -> usize { self.as_usize() }
#[doc = r" Extracts the value of this index as a `u32`."]
#[inline]
pub const fn as_u32(self) -> u32 {
unsafe { std::mem::transmute(self.private_use_as_methods_instead) }
}
#[doc = r" Extracts the value of this index as a `usize`."]
#[inline]
pub const fn as_usize(self) -> usize { self.as_u32() as usize }
}
impl std::ops::Add<usize> for RegionVid {
type Output = Self;
#[inline]
fn add(self, other: usize) -> Self {
Self::from_usize(self.index() + other)
}
}
impl std::ops::AddAssign<usize> for RegionVid {
#[inline]
fn add_assign(&mut self, other: usize) { *self = *self + other; }
}
impl rustc_index::Idx for RegionVid {
#[inline]
fn new(value: usize) -> Self { Self::from_usize(value) }
#[inline]
fn index(self) -> usize { self.as_usize() }
}
impl ::std::iter::Step for RegionVid {
#[inline]
fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
<usize as
::std::iter::Step>::steps_between(&Self::index(*start),
&Self::index(*end))
}
#[inline]
fn forward_checked(start: Self, u: usize) -> Option<Self> {
Self::index(start).checked_add(u).map(Self::from_usize)
}
#[inline]
fn backward_checked(start: Self, u: usize) -> Option<Self> {
Self::index(start).checked_sub(u).map(Self::from_usize)
}
#[inline]
fn forward_overflowing(start: Self, u: usize) -> (Self, bool) {
let (s, o) = Self::index(start).overflowing_add(u);
(Self::from_usize(s), o)
}
#[inline]
fn backward_overflowing(start: Self, u: usize) -> (Self, bool) {
let (s, o) = Self::index(start).overflowing_sub(u);
(Self::from_usize(s), o)
}
}
impl ::std::cmp::Ord for RegionVid {
#[inline]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_u32().cmp(&other.as_u32())
}
}
impl ::std::cmp::PartialOrd for RegionVid {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl ::rustc_data_structures::stable_hash::StableHash for RegionVid {
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
hcx: &mut __Hcx,
hasher: &mut ::rustc_data_structures::stable_hash::StableHasher) {
self.as_u32().stable_hash(hcx, hasher)
}
}
impl From<RegionVid> for u32 {
#[inline]
fn from(v: RegionVid) -> u32 { v.as_u32() }
}
impl From<RegionVid> for usize {
#[inline]
fn from(v: RegionVid) -> usize { v.as_usize() }
}
impl From<usize> for RegionVid {
#[inline]
fn from(value: usize) -> Self { Self::from_usize(value) }
}
impl From<u32> for RegionVid {
#[inline]
fn from(value: u32) -> Self { Self::from_u32(value) }
}
impl ::std::cmp::Eq for RegionVid {}
impl ::std::cmp::PartialEq for RegionVid {
fn eq(&self, other: &Self) -> bool { self.as_u32().eq(&other.as_u32()) }
}
impl ::std::marker::StructuralPartialEq for RegionVid { }
impl ::std::hash::Hash for RegionVid {
fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
self.as_u32().hash(state)
}
}
impl<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for
RegionVid {
fn decode(d: &mut D) -> Self { Self::from_u32(d.read_u32()) }
}
impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> for
RegionVid {
fn encode(&self, e: &mut E) { e.emit_u32(self.as_u32()); }
}
impl ::std::fmt::Debug for RegionVid {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
fmt.write_fmt(format_args!("\'?{0}", self.as_u32()))
}
}rustc_index::newtype_index! {
14/// A **region** **v**ariable **ID**.
15#[encodable]
16 #[orderable]
17 #[debug_format = "'?{}"]
18 #[gate_rustc_only]
19 #[stable_hash]
20pub struct RegionVid {}
21}2223/// Representation of regions. Note that the NLL checker uses a distinct
24/// representation of regions. For this reason, it internally replaces all the
25/// regions with inference variables -- the index of the variable is then used
26/// to index into internal NLL data structures. See `rustc_const_eval::borrow_check`
27/// module for more information.
28///
29/// Note: operations are on the wrapper `Region` type, which is interned,
30/// rather than this type.
31///
32/// ## The Region lattice within a given function
33///
34/// In general, the region lattice looks like
35///
36/// ```text
37/// empty(Un) -------- (smallest)
38/// | \
39/// ... \
40/// | \
41/// empty(U1) -- \
42/// | \ placeholder(Un)
43/// | \ |
44/// empty(root) placeholder(U1) |
45/// | | |
46/// | | |
47/// | | |
48/// param regions | |
49/// | | |
50/// static ----------+-----...------+ (greatest)
51/// ```
52///
53/// Lifetimes in scope from a function declaration are represented via
54/// [`RegionKind::ReEarlyParam`]/[`RegionKind::ReLateParam`]. They
55/// have relationships to one another and `'static` based on the
56/// declared relationships from the function.
57///
58/// Note that inference variables and bound regions are not included
59/// in this diagram. In the case of inference variables, they should
60/// be inferred to some other region from the diagram. In the case of
61/// bound regions, they are excluded because they don't make sense to
62/// include -- the diagram indicates the relationship between free
63/// regions.
64///
65/// You can read more about the distinction between early and late bound
66/// parameters in the rustc dev guide: [Early vs Late bound parameters].
67///
68/// A note on subtyping: If we assume that references take their region
69/// covariantly, and use that to define the subtyping relationship of regions,
70/// it may be somewhat surprising that `'empty` is Top and `'static` is Bottom,
71/// and that "`'a` is a subtype of `'b`" is defined as "`'a` is bigger than
72/// `'b`" - good to keep in mind.
73///
74/// ## Inference variables
75///
76/// During region inference, we sometimes create inference variables,
77/// represented as [`RegionKind::ReVar`]. These will be inferred by
78/// the code in `infer::lexical_region_resolve` to some free region
79/// from the lattice above (the minimal region that meets the
80/// constraints).
81///
82/// During NLL checking, where regions are defined differently, we
83/// also use [`RegionKind::ReVar`] -- in that case, the index is used
84/// to index into the NLL region checker's data structures. The
85/// variable may in fact represent either a free region or an
86/// inference variable, in that case.
87///
88/// ## Bound Regions
89///
90/// These are regions that are stored behind a binder and must be instantiated
91/// with some concrete region before being used. A type can be wrapped in a
92/// `Binder`, which introduces new type/const/lifetime variables (e.g., `for<'a>
93/// fn(&'a ())`). These parameters are referred to via [`RegionKind::ReBound`].
94/// You can instantiate them by the likes of `liberate_late_bound_regions`.
95///
96/// Unlike `Param`s, bound regions are not supposed to exist "in the wild"
97/// outside their binder, e.g., in types passed to type inference, and
98/// should first be instantiated (by placeholder regions, free regions,
99/// or region variables).
100///
101/// ## Placeholder and Free Regions
102///
103/// One often wants to work with bound regions without knowing their precise
104/// identity. For example, when checking a function, the lifetime of a borrow
105/// can end up being assigned to some region parameter. In these cases,
106/// it must be ensured that bounds on the region can't be accidentally
107/// assumed without being checked.
108///
109/// To do this, we replace the bound regions with placeholder markers,
110/// which don't satisfy any relation not explicitly provided.
111///
112/// There are two kinds of placeholder regions in rustc: `ReLateParam` and
113/// `RePlaceholder`. When checking an item's body, `ReLateParam` is supposed
114/// to be used. These also support explicit bounds: both the internally-stored
115/// *scope*, which the region is assumed to outlive, as well as other
116/// relations stored in the `FreeRegionMap`. Note that these relations
117/// aren't checked when you `make_subregion` (or `eq_types`), only by
118/// `resolve_regions_and_report_errors`.
119///
120/// When working with higher-ranked types, some region relations aren't
121/// yet known, so you can't just call `resolve_regions_and_report_errors`.
122/// `RePlaceholder` is designed for this purpose. In these contexts,
123/// there's also the risk that some inference variable laying around will
124/// get unified with your placeholder region: if you want to check whether
125/// `for<'a> Foo<'_>: 'a`, and you instantiate your bound region `'a`
126/// with a placeholder region `'%a`, the variable `'_` would just be
127/// instantiated to the placeholder region `'%a`, which is wrong because
128/// the inference variable is supposed to satisfy the relation
129/// *for every value of the placeholder region*. To ensure that doesn't
130/// happen, you can use `leak_check`. This is more clearly explained
131/// by the [rustc dev guide].
132///
133/// [Early vs Late bound parameters]: https://rustc-dev-guide.rust-lang.org/early-late-parameters.html
134/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
135#[automatically_derived]
impl<I: Interner> ::core::clone::Clone for RegionKind<I> where I: Interner {
#[inline]
fn clone(&self) -> Self { *self }
}
#[automatically_derived]
impl<I: Interner> ::core::marker::Copy for RegionKind<I> where I: Interner { }
#[automatically_derived]
impl<I: Interner> ::core::hash::Hash for RegionKind<I> where I: Interner {
fn hash<__H: ::core::hash::Hasher>(&self, __state: &mut __H) {
match self {
RegionKind::ReEarlyParam(ref __field_0) => {
::core::hash::Hash::hash(&::core::mem::discriminant(self),
__state);
::core::hash::Hash::hash(__field_0, __state);
}
RegionKind::ReBound(ref __field_0, ref __field_1) => {
::core::hash::Hash::hash(&::core::mem::discriminant(self),
__state);
::core::hash::Hash::hash(__field_0, __state);
::core::hash::Hash::hash(__field_1, __state);
}
RegionKind::ReLateParam(ref __field_0) => {
::core::hash::Hash::hash(&::core::mem::discriminant(self),
__state);
::core::hash::Hash::hash(__field_0, __state);
}
RegionKind::ReStatic => {
::core::hash::Hash::hash(&::core::mem::discriminant(self),
__state);
}
RegionKind::ReVar(ref __field_0) => {
::core::hash::Hash::hash(&::core::mem::discriminant(self),
__state);
::core::hash::Hash::hash(__field_0, __state);
}
RegionKind::RePlaceholder(ref __field_0) => {
::core::hash::Hash::hash(&::core::mem::discriminant(self),
__state);
::core::hash::Hash::hash(__field_0, __state);
}
RegionKind::ReErased => {
::core::hash::Hash::hash(&::core::mem::discriminant(self),
__state);
}
RegionKind::ReError(ref __field_0) => {
::core::hash::Hash::hash(&::core::mem::discriminant(self),
__state);
::core::hash::Hash::hash(__field_0, __state);
}
}
}
}
#[automatically_derived]
impl<I: Interner> ::core::cmp::PartialEq for RegionKind<I> where I: Interner {
#[inline]
fn eq(&self, __other: &Self) -> ::core::primitive::bool {
if ::core::mem::discriminant(self) ==
::core::mem::discriminant(__other) {
match (self, __other) {
(RegionKind::ReEarlyParam(ref __field_0),
RegionKind::ReEarlyParam(ref __other_field_0)) =>
true &&
::core::cmp::PartialEq::eq(__field_0, __other_field_0),
(RegionKind::ReBound(ref __field_0, ref __field_1),
RegionKind::ReBound(ref __other_field_0,
ref __other_field_1)) =>
true &&
::core::cmp::PartialEq::eq(__field_0, __other_field_0) &&
::core::cmp::PartialEq::eq(__field_1, __other_field_1),
(RegionKind::ReLateParam(ref __field_0),
RegionKind::ReLateParam(ref __other_field_0)) =>
true &&
::core::cmp::PartialEq::eq(__field_0, __other_field_0),
(RegionKind::ReVar(ref __field_0),
RegionKind::ReVar(ref __other_field_0)) =>
true &&
::core::cmp::PartialEq::eq(__field_0, __other_field_0),
(RegionKind::RePlaceholder(ref __field_0),
RegionKind::RePlaceholder(ref __other_field_0)) =>
true &&
::core::cmp::PartialEq::eq(__field_0, __other_field_0),
(RegionKind::ReError(ref __field_0),
RegionKind::ReError(ref __other_field_0)) =>
true &&
::core::cmp::PartialEq::eq(__field_0, __other_field_0),
_ => true,
}
} else { false }
}
}#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]136#[derive(const _: () =
{
unsafe impl<I: Interner, __V>
::rustc_type_ir::GenericTypeVisitable<__V> for RegionKind<I> where
I::EarlyParamRegion: ::rustc_type_ir::GenericTypeVisitable<__V>,
BoundVarIndexKind: ::rustc_type_ir::GenericTypeVisitable<__V>,
BoundRegion<I>: ::rustc_type_ir::GenericTypeVisitable<__V>,
LateParamRegion<I>: ::rustc_type_ir::GenericTypeVisitable<__V>,
RegionVid: ::rustc_type_ir::GenericTypeVisitable<__V>,
PlaceholderRegion<I>: ::rustc_type_ir::GenericTypeVisitable<__V>,
I::ErrorGuaranteed: ::rustc_type_ir::GenericTypeVisitable<__V> {
fn generic_visit_with(&self, __visitor: &mut __V) {
match *self {
RegionKind::ReEarlyParam(ref __binding_0) => {
{
::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
__visitor);
}
}
RegionKind::ReBound(ref __binding_0, ref __binding_1) => {
{
::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
__visitor);
}
{
::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_1,
__visitor);
}
}
RegionKind::ReLateParam(ref __binding_0) => {
{
::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
__visitor);
}
}
RegionKind::ReStatic => {}
RegionKind::ReVar(ref __binding_0) => {
{
::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
__visitor);
}
}
RegionKind::RePlaceholder(ref __binding_0) => {
{
::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
__visitor);
}
}
RegionKind::ReErased => {}
RegionKind::ReError(ref __binding_0) => {
{
::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
__visitor);
}
}
}
}
}
};GenericTypeVisitable)]
137#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<I: Interner, __E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for RegionKind<I> where
I::EarlyParamRegion: ::rustc_serialize::Encodable<__E>,
BoundRegion<I>: ::rustc_serialize::Encodable<__E>,
LateParamRegion<I>: ::rustc_serialize::Encodable<__E>,
PlaceholderRegion<I>: ::rustc_serialize::Encodable<__E>,
I::ErrorGuaranteed: ::rustc_serialize::Encodable<__E> {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
RegionKind::ReEarlyParam(ref __binding_0) => { 0usize }
RegionKind::ReBound(ref __binding_0, ref __binding_1) => {
1usize
}
RegionKind::ReLateParam(ref __binding_0) => { 2usize }
RegionKind::ReStatic => { 3usize }
RegionKind::ReVar(ref __binding_0) => { 4usize }
RegionKind::RePlaceholder(ref __binding_0) => { 5usize }
RegionKind::ReErased => { 6usize }
RegionKind::ReError(ref __binding_0) => { 7usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
RegionKind::ReEarlyParam(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
RegionKind::ReBound(ref __binding_0, ref __binding_1) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
RegionKind::ReLateParam(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
RegionKind::ReStatic => {}
RegionKind::ReVar(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
RegionKind::RePlaceholder(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
RegionKind::ReErased => {}
RegionKind::ReError(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<I: Interner, __D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for RegionKind<I> where
I::EarlyParamRegion: ::rustc_serialize::Decodable<__D>,
BoundRegion<I>: ::rustc_serialize::Decodable<__D>,
LateParamRegion<I>: ::rustc_serialize::Decodable<__D>,
PlaceholderRegion<I>: ::rustc_serialize::Decodable<__D>,
I::ErrorGuaranteed: ::rustc_serialize::Decodable<__D> {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
RegionKind::ReEarlyParam(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => {
RegionKind::ReBound(::rustc_serialize::Decodable::decode(__decoder),
::rustc_serialize::Decodable::decode(__decoder))
}
2usize => {
RegionKind::ReLateParam(::rustc_serialize::Decodable::decode(__decoder))
}
3usize => { RegionKind::ReStatic }
4usize => {
RegionKind::ReVar(::rustc_serialize::Decodable::decode(__decoder))
}
5usize => {
RegionKind::RePlaceholder(::rustc_serialize::Decodable::decode(__decoder))
}
6usize => { RegionKind::ReErased }
7usize => {
RegionKind::ReError(::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `RegionKind`, expected 0..8, actual {0}",
n));
}
}
}
}
};Decodable_NoContext))]
138pub enum RegionKind<I: Interner> {
139/// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`.
140 ///
141 /// There are some important differences between region and type parameters.
142 /// Not all region parameters in the source are represented via `ReEarlyParam`:
143 /// late-bound function parameters are instead lowered to a `ReBound`. Late-bound
144 /// regions get eagerly replaced with `ReLateParam` which behaves in the same way as
145 /// `ReEarlyParam`. Region parameters are also sometimes implicit,
146 /// e.g. in `impl Trait for &()`.
147ReEarlyParam(I::EarlyParamRegion),
148149/// A higher-ranked region. These represent either late-bound function parameters
150 /// or bound variables from a `for<'a>`-binder.
151 ///
152 /// While inside of a function, e.g. during typeck, the late-bound function parameters
153 /// can be converted to `ReLateParam` by calling `tcx.liberate_late_bound_regions`.
154 ///
155 /// Bound regions inside of types **must not** be erased, as they impact trait
156 /// selection and the `TypeId` of that type. `for<'a> fn(&'a ())` and
157 /// `fn(&'static ())` are different types and have to be treated as such.
158ReBound(BoundVarIndexKind, BoundRegion<I>),
159160/// Late-bound function parameters are represented using a `ReBound`. When
161 /// inside of a function, we convert these bound variables to placeholder
162 /// parameters via `tcx.liberate_late_bound_regions`. They are then treated
163 /// the same way as `ReEarlyParam` while inside of the function.
164 ///
165 /// See <https://rustc-dev-guide.rust-lang.org/early_late_parameters.html> for
166 /// more info about early and late bound lifetime parameters.
167ReLateParam(LateParamRegion<I>),
168169/// Static data that has an "infinite" lifetime. Bottom in the region lattice.
170ReStatic,
171172/// A region variable. Should not exist outside of type inference.
173ReVar(RegionVid),
174175/// A placeholder region -- the higher-ranked version of `ReLateParam`.
176 /// Should not exist outside of type inference.
177 ///
178 /// Used when instantiating a `forall` binder via `infcx.enter_forall`.
179RePlaceholder(PlaceholderRegion<I>),
180181/// Erased region, used by trait selection, in MIR and during codegen.
182ReErased,
183184/// A region that resulted from some other error. Used exclusively for diagnostics.
185ReError(I::ErrorGuaranteed),
186}
187188impl<I: Interner> Eqfor RegionKind<I> {}
189190impl<I: Interner> fmt::Debugfor RegionKind<I> {
191fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192match self {
193ReEarlyParam(data) => f.write_fmt(format_args!("{0:?}", data))write!(f, "{data:?}"),
194195ReBound(binder_id, bound_region) => {
196f.write_fmt(format_args!("\'"))write!(f, "'")?;
197crate::debug_bound_var(f, *binder_id, bound_region)
198 }
199200ReLateParam(fr) => f.write_fmt(format_args!("{0:?}", fr))write!(f, "{fr:?}"),
201202ReStatic => f.write_str("'static"),
203204ReVar(vid) => f.write_fmt(format_args!("{0:?}", vid))write!(f, "{vid:?}"),
205206RePlaceholder(placeholder) => f.write_fmt(format_args!("\'{0:?}", placeholder))write!(f, "'{placeholder:?}"),
207208// Use `'{erased}` as the output instead of `'erased` so that its more obviously distinct from
209 // a `ReEarlyParam` named `'erased`. Technically that would print as `'erased/#IDX` so this is
210 // not strictly necessary but *shrug*
211ReErased => f.write_str("'{erased}"),
212213ReError(_) => f.write_str("'{region error}"),
214 }
215 }
216}
217218// This impl could be derived with `StableHash_NoContext`, but we instead write it by hand in order
219// to panic on `ReVar`.
220#[cfg(feature = "nightly")]
221impl<I: Interner> StableHashfor RegionKind<I>
222where
223I::EarlyParamRegion: StableHash,
224 I::DefId: StableHash,
225 I::Symbol: StableHash,
226{
227#[inline]
228fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
229 std::mem::discriminant(self).stable_hash(hcx, hasher);
230match self {
231ReErased | ReStatic | ReError(_) => {
232// No variant fields to hash for these ...
233}
234ReBound(d, r) => {
235d.stable_hash(hcx, hasher);
236r.stable_hash(hcx, hasher);
237 }
238ReEarlyParam(r) => {
239r.stable_hash(hcx, hasher);
240 }
241ReLateParam(r) => {
242r.stable_hash(hcx, hasher);
243 }
244RePlaceholder(r) => {
245r.stable_hash(hcx, hasher);
246 }
247ReVar(_) => {
248{
::core::panicking::panic_fmt(format_args!("region variables should not be hashed: {0:?}",
self));
}panic!("region variables should not be hashed: {self:?}")249 }
250 }
251 }
252}