Skip to main content

rustc_middle/ty/
region.rs

1use rustc_errors::MultiSpan;
2use rustc_hir::def_id::DefId;
3use rustc_macros::{StableHash, TyDecodable, TyEncodable, extension};
4use rustc_span::{DUMMY_SP, ErrorGuaranteed, Symbol, kw, sym};
5pub use rustc_type_ir::RegionVid;
6use rustc_type_ir::{Region as IrRegion, RegionKind as IrRegionKind};
7
8use crate::ty::{self, BoundVar, TyCtxt};
9
10pub type Region<'tcx> = IrRegion<TyCtxt<'tcx>>;
11pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
12
13impl<'tcx> RegionExt<'tcx> for Region<'tcx> {
    #[inline]
    fn new_early_param(tcx: TyCtxt<'tcx>,
        early_bound_region: ty::EarlyParamRegion) -> Region<'tcx> {
        tcx.intern_region(ty::ReEarlyParam(early_bound_region))
    }
    #[inline]
    fn new_late_param(tcx: TyCtxt<'tcx>, scope: DefId,
        kind: LateParamRegionKind) -> Region<'tcx> {
        let data = LateParamRegion { scope, kind };
        tcx.intern_region(ty::ReLateParam(data))
    }
    #[inline]
    fn new_var(tcx: TyCtxt<'tcx>, v: ty::RegionVid) -> Region<'tcx> {
        tcx.lifetimes.re_vars.get(v.as_usize()).copied().unwrap_or_else(||
                tcx.intern_region(ty::ReVar(v)))
    }
    #[doc = " Constructs a `RegionKind::ReError` region."]
    #[track_caller]
    fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Region<'tcx> {
        tcx.intern_region(ty::ReError(guar))
    }
    #[doc =
    " Constructs a `RegionKind::ReError` region and registers a delayed bug to ensure it gets"]
    #[doc = " used."]
    #[track_caller]
    fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> {
        Region::new_error_with_message(tcx, DUMMY_SP,
            "RegionKind::ReError constructed but no error reported")
    }
    #[doc =
    " Constructs a `RegionKind::ReError` region and registers a delayed bug with the given `msg`"]
    #[doc = " to ensure it gets used."]
    #[track_caller]
    fn new_error_with_message<S: Into<MultiSpan>>(tcx: TyCtxt<'tcx>, span: S,
        msg: &'static str) -> Region<'tcx> {
        let reported = tcx.dcx().span_delayed_bug(span, msg);
        Region::new_error(tcx, reported)
    }
    #[doc =
    " Avoid this in favour of more specific `new_*` methods, where possible,"]
    #[doc = " to avoid the cost of the `match`."]
    fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>)
        -> Region<'tcx> {
        match kind {
            ty::ReEarlyParam(region) => Region::new_early_param(tcx, region),
            ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), region) => {
                Region::new_bound(tcx, debruijn, region)
            }
            ty::ReBound(ty::BoundVarIndexKind::Canonical, region) => {
                Region::new_canonical_bound(tcx, region.var)
            }
            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),
            ty::RePlaceholder(region) => Region::new_placeholder(tcx, region),
            ty::ReErased => tcx.lifetimes.re_erased,
            ty::ReError(reported) => Region::new_error(tcx, reported),
        }
    }
}#[extension(pub trait RegionExt<'tcx>)]
14impl<'tcx> Region<'tcx> {
15    #[inline]
16    fn new_early_param(
17        tcx: TyCtxt<'tcx>,
18        early_bound_region: ty::EarlyParamRegion,
19    ) -> Region<'tcx> {
20        tcx.intern_region(ty::ReEarlyParam(early_bound_region))
21    }
22
23    #[inline]
24    fn new_late_param(tcx: TyCtxt<'tcx>, scope: DefId, kind: LateParamRegionKind) -> Region<'tcx> {
25        let data = LateParamRegion { scope, kind };
26        tcx.intern_region(ty::ReLateParam(data))
27    }
28
29    #[inline]
30    fn new_var(tcx: TyCtxt<'tcx>, v: ty::RegionVid) -> Region<'tcx> {
31        // Use a pre-interned one when possible.
32        tcx.lifetimes
33            .re_vars
34            .get(v.as_usize())
35            .copied()
36            .unwrap_or_else(|| tcx.intern_region(ty::ReVar(v)))
37    }
38
39    /// Constructs a `RegionKind::ReError` region.
40    #[track_caller]
41    fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Region<'tcx> {
42        tcx.intern_region(ty::ReError(guar))
43    }
44
45    /// Constructs a `RegionKind::ReError` region and registers a delayed bug to ensure it gets
46    /// used.
47    #[track_caller]
48    fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> {
49        Region::new_error_with_message(
50            tcx,
51            DUMMY_SP,
52            "RegionKind::ReError constructed but no error reported",
53        )
54    }
55
56    /// Constructs a `RegionKind::ReError` region and registers a delayed bug with the given `msg`
57    /// to ensure it gets used.
58    #[track_caller]
59    fn new_error_with_message<S: Into<MultiSpan>>(
60        tcx: TyCtxt<'tcx>,
61        span: S,
62        msg: &'static str,
63    ) -> Region<'tcx> {
64        let reported = tcx.dcx().span_delayed_bug(span, msg);
65        Region::new_error(tcx, reported)
66    }
67
68    /// Avoid this in favour of more specific `new_*` methods, where possible,
69    /// to avoid the cost of the `match`.
70    fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
71        match kind {
72            ty::ReEarlyParam(region) => Region::new_early_param(tcx, region),
73            ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), region) => {
74                Region::new_bound(tcx, debruijn, region)
75            }
76            ty::ReBound(ty::BoundVarIndexKind::Canonical, region) => {
77                Region::new_canonical_bound(tcx, region.var)
78            }
79            ty::ReLateParam(ty::LateParamRegion { scope, kind }) => {
80                Region::new_late_param(tcx, scope, kind)
81            }
82            ty::ReStatic => tcx.lifetimes.re_static,
83            ty::ReVar(vid) => Region::new_var(tcx, vid),
84            ty::RePlaceholder(region) => Region::new_placeholder(tcx, region),
85            ty::ReErased => tcx.lifetimes.re_erased,
86            ty::ReError(reported) => Region::new_error(tcx, reported),
87        }
88    }
89}
90
91/// Region utilities
92impl<'tcx> RegionUtilitiesExt<'tcx> for Region<'tcx> {
    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,
        }
    }
    fn get_name_or_anon(self, tcx: TyCtxt<'tcx>) -> Symbol {
        match self.get_name(tcx) { Some(name) => name, None => sym::anon, }
    }
    #[doc = " Is this region named by the user?"]
    fn is_named(self, tcx: TyCtxt<'tcx>) -> bool {
        match self.kind() {
            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(tcx),
            ty::ReErased => false,
            ty::ReError(_) => false,
        }
    }
    #[inline]
    fn is_error(self) -> bool {

        #[allow(non_exhaustive_omitted_patterns)]
        match self.kind() { ty::ReError(_) => true, _ => false, }
    }
    #[inline]
    fn is_static(self) -> bool {

        #[allow(non_exhaustive_omitted_patterns)]
        match self.kind() { ty::ReStatic => true, _ => false, }
    }
    #[inline]
    fn is_erased(self) -> bool {

        #[allow(non_exhaustive_omitted_patterns)]
        match self.kind() { ty::ReErased => true, _ => false, }
    }
    #[inline]
    fn is_placeholder(self) -> bool {

        #[allow(non_exhaustive_omitted_patterns)]
        match self.kind() { ty::RePlaceholder(..) => true, _ => false, }
    }
    #[inline]
    fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
        match self.kind() {
            ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) =>
                debruijn >= index,
            _ => false,
        }
    }
    #[doc = " True for free regions other than `\'static`."]
    fn is_param(self) -> bool {

        #[allow(non_exhaustive_omitted_patterns)]
        match self.kind() {
            ty::ReEarlyParam(_) | ty::ReLateParam(_) => true,
            _ => false,
        }
    }
    #[doc = " True for free region in the current context."]
    #[doc = ""]
    #[doc = " This is the case for `\'static` and param regions."]
    fn is_free(self) -> bool {
        match self.kind() {
            ty::ReStatic | ty::ReEarlyParam(..) | ty::ReLateParam(..) => true,
            ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReBound(..) |
                ty::ReErased | ty::ReError(..) => false,
        }
    }
    fn is_var(self) -> bool {

        #[allow(non_exhaustive_omitted_patterns)]
        match self.kind() { ty::ReVar(_) => true, _ => false, }
    }
    fn as_var(self) -> RegionVid {
        match self.kind() {
            ty::ReVar(vid) => vid,
            _ =>
                crate::util::bug::bug_fmt(format_args!("expected region {0:?} to be of kind ReVar",
                        self)),
        }
    }
    #[doc =
    " Given some item `binding_item`, check if this region is a generic parameter introduced by it"]
    #[doc =
    " or one of the parent generics. Returns the `DefId` of the parameter definition if so."]
    fn opt_param_def_id(self, tcx: TyCtxt<'tcx>, binding_item: DefId)
        -> Option<DefId> {
        match self.kind() {
            ty::ReEarlyParam(ebr) => {
                Some(tcx.generics_of(binding_item).region_param(ebr,
                            tcx).def_id)
            }
            ty::ReLateParam(ty::LateParamRegion {
                kind: ty::LateParamRegionKind::Named(def_id), .. }) =>
                Some(def_id),
            _ => None,
        }
    }
}#[extension(pub trait RegionUtilitiesExt<'tcx>)]
93impl<'tcx> Region<'tcx> {
94    fn get_name(self, tcx: TyCtxt<'tcx>) -> Option<Symbol> {
95        match self.kind() {
96            ty::ReEarlyParam(ebr) => ebr.is_named().then_some(ebr.name),
97            ty::ReBound(_, br) => br.kind.get_name(tcx),
98            ty::ReLateParam(fr) => fr.kind.get_name(tcx),
99            ty::ReStatic => Some(kw::StaticLifetime),
100            ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(tcx),
101            _ => None,
102        }
103    }
104
105    fn get_name_or_anon(self, tcx: TyCtxt<'tcx>) -> Symbol {
106        match self.get_name(tcx) {
107            Some(name) => name,
108            None => sym::anon,
109        }
110    }
111
112    /// Is this region named by the user?
113    fn is_named(self, tcx: TyCtxt<'tcx>) -> bool {
114        match self.kind() {
115            ty::ReEarlyParam(ebr) => ebr.is_named(),
116            ty::ReBound(_, br) => br.kind.is_named(tcx),
117            ty::ReLateParam(fr) => fr.kind.is_named(tcx),
118            ty::ReStatic => true,
119            ty::ReVar(..) => false,
120            ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(tcx),
121            ty::ReErased => false,
122            ty::ReError(_) => false,
123        }
124    }
125
126    #[inline]
127    fn is_error(self) -> bool {
128        matches!(self.kind(), ty::ReError(_))
129    }
130
131    #[inline]
132    fn is_static(self) -> bool {
133        matches!(self.kind(), ty::ReStatic)
134    }
135
136    #[inline]
137    fn is_erased(self) -> bool {
138        matches!(self.kind(), ty::ReErased)
139    }
140
141    #[inline]
142    fn is_placeholder(self) -> bool {
143        matches!(self.kind(), ty::RePlaceholder(..))
144    }
145
146    #[inline]
147    fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
148        match self.kind() {
149            ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) => debruijn >= index,
150            _ => false,
151        }
152    }
153
154    /// True for free regions other than `'static`.
155    fn is_param(self) -> bool {
156        matches!(self.kind(), ty::ReEarlyParam(_) | ty::ReLateParam(_))
157    }
158
159    /// True for free region in the current context.
160    ///
161    /// This is the case for `'static` and param regions.
162    fn is_free(self) -> bool {
163        match self.kind() {
164            ty::ReStatic | ty::ReEarlyParam(..) | ty::ReLateParam(..) => true,
165            ty::ReVar(..)
166            | ty::RePlaceholder(..)
167            | ty::ReBound(..)
168            | ty::ReErased
169            | ty::ReError(..) => false,
170        }
171    }
172
173    fn is_var(self) -> bool {
174        matches!(self.kind(), ty::ReVar(_))
175    }
176
177    fn as_var(self) -> RegionVid {
178        match self.kind() {
179            ty::ReVar(vid) => vid,
180            _ => bug!("expected region {:?} to be of kind ReVar", self),
181        }
182    }
183
184    /// Given some item `binding_item`, check if this region is a generic parameter introduced by it
185    /// or one of the parent generics. Returns the `DefId` of the parameter definition if so.
186    fn opt_param_def_id(self, tcx: TyCtxt<'tcx>, binding_item: DefId) -> Option<DefId> {
187        match self.kind() {
188            ty::ReEarlyParam(ebr) => {
189                Some(tcx.generics_of(binding_item).region_param(ebr, tcx).def_id)
190            }
191            ty::ReLateParam(ty::LateParamRegion {
192                kind: ty::LateParamRegionKind::Named(def_id),
193                ..
194            }) => Some(def_id),
195            _ => None,
196        }
197    }
198}
199
200#[derive(#[automatically_derived]
impl ::core::marker::Copy for EarlyParamRegion { }Copy, #[automatically_derived]
impl ::core::clone::Clone for EarlyParamRegion {
    #[inline]
    fn clone(&self) -> EarlyParamRegion {
        let _: ::core::clone::AssertParamIsClone<u32>;
        let _: ::core::clone::AssertParamIsClone<Symbol>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for EarlyParamRegion {
    #[inline]
    fn eq(&self, other: &EarlyParamRegion) -> bool {
        self.index == other.index && self.name == other.name
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for EarlyParamRegion {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u32>;
        let _: ::core::cmp::AssertParamIsEq<Symbol>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for EarlyParamRegion {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.index, state);
        ::core::hash::Hash::hash(&self.name, state)
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for EarlyParamRegion {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    EarlyParamRegion {
                        index: ref __binding_0, name: ref __binding_1 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for EarlyParamRegion {
            fn decode(__decoder: &mut __D) -> Self {
                EarlyParamRegion {
                    index: ::rustc_serialize::Decodable::decode(__decoder),
                    name: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable)]
201#[derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            EarlyParamRegion {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    EarlyParamRegion {
                        index: ref __binding_0, name: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
202pub struct EarlyParamRegion {
203    pub index: u32,
204    pub name: Symbol,
205}
206
207impl EarlyParamRegion {
208    /// Does this early bound region have a name? Early bound regions normally
209    /// always have names except when using anonymous lifetimes (`'_`).
210    pub fn is_named(&self) -> bool {
211        self.name != kw::UnderscoreLifetime
212    }
213}
214
215impl rustc_type_ir::inherent::ParamLike for EarlyParamRegion {
216    fn index(self) -> u32 {
217        self.index
218    }
219}
220
221impl std::fmt::Debug for EarlyParamRegion {
222    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223        f.write_fmt(format_args!("{0}/#{1}", self.name, self.index))write!(f, "{}/#{}", self.name, self.index)
224    }
225}
226
227#[derive(#[automatically_derived]
impl ::core::clone::Clone for LateParamRegion {
    #[inline]
    fn clone(&self) -> LateParamRegion {
        let _: ::core::clone::AssertParamIsClone<DefId>;
        let _: ::core::clone::AssertParamIsClone<LateParamRegionKind>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LateParamRegion {
    #[inline]
    fn eq(&self, other: &LateParamRegion) -> bool {
        self.scope == other.scope && self.kind == other.kind
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for LateParamRegion {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<DefId>;
        let _: ::core::cmp::AssertParamIsEq<LateParamRegionKind>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for LateParamRegion {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.scope, state);
        ::core::hash::Hash::hash(&self.kind, state)
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for LateParamRegion {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    LateParamRegion {
                        scope: ref __binding_0, kind: ref __binding_1 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for LateParamRegion {
            fn decode(__decoder: &mut __D) -> Self {
                LateParamRegion {
                    scope: ::rustc_serialize::Decodable::decode(__decoder),
                    kind: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, #[automatically_derived]
impl ::core::marker::Copy for LateParamRegion { }Copy)]
228#[derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            LateParamRegion {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    LateParamRegion {
                        scope: ref __binding_0, kind: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
229/// The parameter representation of late-bound function parameters, "some region
230/// at least as big as the scope `fr.scope`".
231///
232/// Similar to a placeholder region as we create `LateParam` regions when entering a binder
233/// except they are always in the root universe and instead of using a boundvar to distinguish
234/// between others we use the `DefId` of the parameter. For this reason the `bound_region` field
235/// should basically always be `BoundRegionKind::Named` as otherwise there is no way of telling
236/// different parameters apart.
237pub struct LateParamRegion {
238    pub scope: DefId,
239    pub kind: LateParamRegionKind,
240}
241
242/// When liberating bound regions, we map their [`ty::BoundRegionKind`]
243/// to this as we need to track the index of anonymous regions. We
244/// otherwise end up liberating multiple bound regions to the same
245/// late-bound region.
246#[derive(#[automatically_derived]
impl ::core::clone::Clone for LateParamRegionKind {
    #[inline]
    fn clone(&self) -> LateParamRegionKind {
        let _: ::core::clone::AssertParamIsClone<u32>;
        let _: ::core::clone::AssertParamIsClone<Symbol>;
        let _: ::core::clone::AssertParamIsClone<DefId>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LateParamRegionKind {
    #[inline]
    fn eq(&self, other: &LateParamRegionKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (LateParamRegionKind::Anon(__self_0),
                    LateParamRegionKind::Anon(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (LateParamRegionKind::NamedAnon(__self_0, __self_1),
                    LateParamRegionKind::NamedAnon(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (LateParamRegionKind::Named(__self_0),
                    LateParamRegionKind::Named(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for LateParamRegionKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u32>;
        let _: ::core::cmp::AssertParamIsEq<Symbol>;
        let _: ::core::cmp::AssertParamIsEq<DefId>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for LateParamRegionKind {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            LateParamRegionKind::Anon(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            LateParamRegionKind::NamedAnon(__self_0, __self_1) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            LateParamRegionKind::Named(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for LateParamRegionKind {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        LateParamRegionKind::Anon(ref __binding_0) => { 0usize }
                        LateParamRegionKind::NamedAnon(ref __binding_0,
                            ref __binding_1) => {
                            1usize
                        }
                        LateParamRegionKind::Named(ref __binding_0) => { 2usize }
                        LateParamRegionKind::ClosureEnv => { 3usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    LateParamRegionKind::Anon(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    LateParamRegionKind::NamedAnon(ref __binding_0,
                        ref __binding_1) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                    LateParamRegionKind::Named(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    LateParamRegionKind::ClosureEnv => {}
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for LateParamRegionKind {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        LateParamRegionKind::Anon(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => {
                        LateParamRegionKind::NamedAnon(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    2usize => {
                        LateParamRegionKind::Named(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    3usize => { LateParamRegionKind::ClosureEnv }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `LateParamRegionKind`, expected 0..4, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, #[automatically_derived]
impl ::core::marker::Copy for LateParamRegionKind { }Copy)]
247#[derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            LateParamRegionKind {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    LateParamRegionKind::Anon(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    LateParamRegionKind::NamedAnon(ref __binding_0,
                        ref __binding_1) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    LateParamRegionKind::Named(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    LateParamRegionKind::ClosureEnv => {}
                }
            }
        }
    };StableHash)]
248pub enum LateParamRegionKind {
249    /// An anonymous region parameter for a given fn (&T)
250    ///
251    /// Unlike [`ty::BoundRegionKind::Anon`], this tracks the index of the
252    /// liberated bound region.
253    ///
254    /// We should ideally never liberate anonymous regions, but do so for the
255    /// sake of diagnostics in `FnCtxt::sig_of_closure_with_expectation`.
256    Anon(u32),
257
258    /// An anonymous region parameter with a `Symbol` name.
259    ///
260    /// Used to give late-bound regions names for things like pretty printing.
261    NamedAnon(u32, Symbol),
262
263    /// Late-bound regions that appear in the AST.
264    Named(DefId),
265
266    /// Anonymous region for the implicit env pointer parameter
267    /// to a closure
268    ClosureEnv,
269}
270
271impl LateParamRegionKind {
272    pub fn from_bound(var: BoundVar, br: ty::BoundRegionKind<'_>) -> LateParamRegionKind {
273        match br {
274            ty::BoundRegionKind::Anon => LateParamRegionKind::Anon(var.as_u32()),
275            ty::BoundRegionKind::Named(def_id) => LateParamRegionKind::Named(def_id),
276            ty::BoundRegionKind::ClosureEnv => LateParamRegionKind::ClosureEnv,
277            ty::BoundRegionKind::NamedForPrinting(name) => {
278                LateParamRegionKind::NamedAnon(var.as_u32(), name)
279            }
280        }
281    }
282
283    pub fn is_named(&self, tcx: TyCtxt<'_>) -> bool {
284        self.get_name(tcx).is_some()
285    }
286
287    pub fn get_name(&self, tcx: TyCtxt<'_>) -> Option<Symbol> {
288        match *self {
289            LateParamRegionKind::Named(def_id) => {
290                let name = tcx.item_name(def_id);
291                if name != kw::UnderscoreLifetime { Some(name) } else { None }
292            }
293            LateParamRegionKind::NamedAnon(_, name) => Some(name),
294            _ => None,
295        }
296    }
297
298    pub fn get_id(&self) -> Option<DefId> {
299        match *self {
300            LateParamRegionKind::Named(id) => Some(id),
301            _ => None,
302        }
303    }
304}
305
306// Some types are used a lot. Make sure they don't unintentionally get bigger.
307#[cfg(target_pointer_width = "64")]
308mod size_asserts {
309    use rustc_data_structures::static_assert_size;
310
311    use super::*;
312    // tidy-alphabetical-start
313    const _: [(); 20] = [(); ::std::mem::size_of::<RegionKind<'_>>()];static_assert_size!(RegionKind<'_>, 20);
314    const _: [(); 28] =
    [(); ::std::mem::size_of::<ty::WithCachedTypeInfo<RegionKind<'_>>>()];static_assert_size!(ty::WithCachedTypeInfo<RegionKind<'_>>, 28);
315    // tidy-alphabetical-end
316}