rustc_middle/ty/
region.rs

1use rustc_data_structures::intern::Interned;
2use rustc_errors::MultiSpan;
3use rustc_hir::def_id::DefId;
4use rustc_macros::{HashStable, TyDecodable, TyEncodable};
5use rustc_span::{DUMMY_SP, ErrorGuaranteed, Symbol, kw, sym};
6use rustc_type_ir::RegionKind as IrRegionKind;
7pub use rustc_type_ir::RegionVid;
8use tracing::debug;
9
10use crate::ty::{self, BoundVar, TyCtxt, TypeFlags};
11
12pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
13
14/// Use this rather than `RegionKind`, whenever possible.
15#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for Region<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for Region<'tcx> {
    #[inline]
    fn clone(&self) -> Region<'tcx> {
        let _:
                ::core::clone::AssertParamIsClone<Interned<'tcx,
                RegionKind<'tcx>>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for Region<'tcx> {
    #[inline]
    fn eq(&self, other: &Region<'tcx>) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for Region<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<Interned<'tcx, RegionKind<'tcx>>>;
    }
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for Region<'tcx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for Region<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Region(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
16#[rustc_pass_by_value]
17pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
18
19impl<'tcx> rustc_type_ir::inherent::IntoKind for Region<'tcx> {
20    type Kind = RegionKind<'tcx>;
21
22    fn kind(self) -> RegionKind<'tcx> {
23        *self.0.0
24    }
25}
26
27impl<'tcx> rustc_type_ir::Flags for Region<'tcx> {
28    fn flags(&self) -> TypeFlags {
29        self.type_flags()
30    }
31
32    fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
33        match self.kind() {
34            ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) => debruijn.shifted_in(1),
35            _ => ty::INNERMOST,
36        }
37    }
38}
39
40impl<'tcx> Region<'tcx> {
41    #[inline]
42    pub fn new_early_param(
43        tcx: TyCtxt<'tcx>,
44        early_bound_region: ty::EarlyParamRegion,
45    ) -> Region<'tcx> {
46        tcx.intern_region(ty::ReEarlyParam(early_bound_region))
47    }
48
49    #[inline]
50    pub fn new_bound(
51        tcx: TyCtxt<'tcx>,
52        debruijn: ty::DebruijnIndex,
53        bound_region: ty::BoundRegion,
54    ) -> Region<'tcx> {
55        // Use a pre-interned one when possible.
56        if let ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon } = bound_region
57            && let Some(inner) = tcx.lifetimes.anon_re_bounds.get(debruijn.as_usize())
58            && let Some(re) = inner.get(var.as_usize()).copied()
59        {
60            re
61        } else {
62            tcx.intern_region(ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), bound_region))
63        }
64    }
65
66    #[inline]
67    pub fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: ty::BoundVar) -> Region<'tcx> {
68        // Use a pre-interned one when possible.
69        if let Some(re) = tcx.lifetimes.anon_re_canonical_bounds.get(var.as_usize()).copied() {
70            re
71        } else {
72            tcx.intern_region(ty::ReBound(
73                ty::BoundVarIndexKind::Canonical,
74                ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon },
75            ))
76        }
77    }
78
79    #[inline]
80    pub fn new_late_param(
81        tcx: TyCtxt<'tcx>,
82        scope: DefId,
83        kind: LateParamRegionKind,
84    ) -> Region<'tcx> {
85        let data = LateParamRegion { scope, kind };
86        tcx.intern_region(ty::ReLateParam(data))
87    }
88
89    #[inline]
90    pub fn new_var(tcx: TyCtxt<'tcx>, v: ty::RegionVid) -> Region<'tcx> {
91        // Use a pre-interned one when possible.
92        tcx.lifetimes
93            .re_vars
94            .get(v.as_usize())
95            .copied()
96            .unwrap_or_else(|| tcx.intern_region(ty::ReVar(v)))
97    }
98
99    #[inline]
100    pub fn new_placeholder(
101        tcx: TyCtxt<'tcx>,
102        placeholder: ty::PlaceholderRegion<'tcx>,
103    ) -> Region<'tcx> {
104        tcx.intern_region(ty::RePlaceholder(placeholder))
105    }
106
107    /// Constructs a `RegionKind::ReError` region.
108    #[track_caller]
109    pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Region<'tcx> {
110        tcx.intern_region(ty::ReError(guar))
111    }
112
113    /// Constructs a `RegionKind::ReError` region and registers a delayed bug to ensure it gets
114    /// used.
115    #[track_caller]
116    pub fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> {
117        Region::new_error_with_message(
118            tcx,
119            DUMMY_SP,
120            "RegionKind::ReError constructed but no error reported",
121        )
122    }
123
124    /// Constructs a `RegionKind::ReError` region and registers a delayed bug with the given `msg`
125    /// to ensure it gets used.
126    #[track_caller]
127    pub fn new_error_with_message<S: Into<MultiSpan>>(
128        tcx: TyCtxt<'tcx>,
129        span: S,
130        msg: &'static str,
131    ) -> Region<'tcx> {
132        let reported = tcx.dcx().span_delayed_bug(span, msg);
133        Region::new_error(tcx, reported)
134    }
135
136    /// Avoid this in favour of more specific `new_*` methods, where possible,
137    /// to avoid the cost of the `match`.
138    pub fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
139        match kind {
140            ty::ReEarlyParam(region) => Region::new_early_param(tcx, region),
141            ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), region) => {
142                Region::new_bound(tcx, debruijn, region)
143            }
144            ty::ReBound(ty::BoundVarIndexKind::Canonical, region) => {
145                Region::new_canonical_bound(tcx, region.var)
146            }
147            ty::ReLateParam(ty::LateParamRegion { scope, kind }) => {
148                Region::new_late_param(tcx, scope, kind)
149            }
150            ty::ReStatic => tcx.lifetimes.re_static,
151            ty::ReVar(vid) => Region::new_var(tcx, vid),
152            ty::RePlaceholder(region) => Region::new_placeholder(tcx, region),
153            ty::ReErased => tcx.lifetimes.re_erased,
154            ty::ReError(reported) => Region::new_error(tcx, reported),
155        }
156    }
157}
158
159impl<'tcx> rustc_type_ir::inherent::Region<TyCtxt<'tcx>> for Region<'tcx> {
160    fn new_bound(
161        interner: TyCtxt<'tcx>,
162        debruijn: ty::DebruijnIndex,
163        var: ty::BoundRegion,
164    ) -> Self {
165        Region::new_bound(interner, debruijn, var)
166    }
167
168    fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
169        Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon })
170    }
171
172    fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: rustc_type_ir::BoundVar) -> Self {
173        Region::new_canonical_bound(tcx, var)
174    }
175
176    fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderRegion<'tcx>) -> Self {
177        Region::new_placeholder(tcx, placeholder)
178    }
179
180    fn new_static(tcx: TyCtxt<'tcx>) -> Self {
181        tcx.lifetimes.re_static
182    }
183}
184
185/// Region utilities
186impl<'tcx> Region<'tcx> {
187    pub fn kind(self) -> RegionKind<'tcx> {
188        *self.0.0
189    }
190
191    pub fn get_name(self, tcx: TyCtxt<'tcx>) -> Option<Symbol> {
192        match self.kind() {
193            ty::ReEarlyParam(ebr) => ebr.is_named().then_some(ebr.name),
194            ty::ReBound(_, br) => br.kind.get_name(tcx),
195            ty::ReLateParam(fr) => fr.kind.get_name(tcx),
196            ty::ReStatic => Some(kw::StaticLifetime),
197            ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(tcx),
198            _ => None,
199        }
200    }
201
202    pub fn get_name_or_anon(self, tcx: TyCtxt<'tcx>) -> Symbol {
203        match self.get_name(tcx) {
204            Some(name) => name,
205            None => sym::anon,
206        }
207    }
208
209    /// Is this region named by the user?
210    pub fn is_named(self, tcx: TyCtxt<'tcx>) -> bool {
211        match self.kind() {
212            ty::ReEarlyParam(ebr) => ebr.is_named(),
213            ty::ReBound(_, br) => br.kind.is_named(tcx),
214            ty::ReLateParam(fr) => fr.kind.is_named(tcx),
215            ty::ReStatic => true,
216            ty::ReVar(..) => false,
217            ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(tcx),
218            ty::ReErased => false,
219            ty::ReError(_) => false,
220        }
221    }
222
223    #[inline]
224    pub fn is_error(self) -> bool {
225        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::ReError(_) => true,
    _ => false,
}matches!(self.kind(), ty::ReError(_))
226    }
227
228    #[inline]
229    pub fn is_static(self) -> bool {
230        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::ReStatic => true,
    _ => false,
}matches!(self.kind(), ty::ReStatic)
231    }
232
233    #[inline]
234    pub fn is_erased(self) -> bool {
235        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::ReErased => true,
    _ => false,
}matches!(self.kind(), ty::ReErased)
236    }
237
238    #[inline]
239    pub fn is_bound(self) -> bool {
240        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::ReBound(..) => true,
    _ => false,
}matches!(self.kind(), ty::ReBound(..))
241    }
242
243    #[inline]
244    pub fn is_placeholder(self) -> bool {
245        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::RePlaceholder(..) => true,
    _ => false,
}matches!(self.kind(), ty::RePlaceholder(..))
246    }
247
248    #[inline]
249    pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
250        match self.kind() {
251            ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) => debruijn >= index,
252            _ => false,
253        }
254    }
255
256    pub fn type_flags(self) -> TypeFlags {
257        let mut flags = TypeFlags::empty();
258
259        match self.kind() {
260            ty::ReVar(..) => {
261                flags = flags | TypeFlags::HAS_FREE_REGIONS;
262                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
263                flags = flags | TypeFlags::HAS_RE_INFER;
264            }
265            ty::RePlaceholder(..) => {
266                flags = flags | TypeFlags::HAS_FREE_REGIONS;
267                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
268                flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
269            }
270            ty::ReEarlyParam(..) => {
271                flags = flags | TypeFlags::HAS_FREE_REGIONS;
272                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
273                flags = flags | TypeFlags::HAS_RE_PARAM;
274            }
275            ty::ReLateParam { .. } => {
276                flags = flags | TypeFlags::HAS_FREE_REGIONS;
277                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
278            }
279            ty::ReStatic => {
280                flags = flags | TypeFlags::HAS_FREE_REGIONS;
281            }
282            ty::ReBound(ty::BoundVarIndexKind::Canonical, _) => {
283                flags = flags | TypeFlags::HAS_RE_BOUND;
284                flags = flags | TypeFlags::HAS_CANONICAL_BOUND;
285            }
286            ty::ReBound(ty::BoundVarIndexKind::Bound(..), _) => {
287                flags = flags | TypeFlags::HAS_RE_BOUND;
288            }
289            ty::ReErased => {
290                flags = flags | TypeFlags::HAS_RE_ERASED;
291            }
292            ty::ReError(_) => {
293                flags = flags | TypeFlags::HAS_FREE_REGIONS;
294                flags = flags | TypeFlags::HAS_ERROR;
295            }
296        }
297
298        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/ty/region.rs:298",
                        "rustc_middle::ty::region", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/region.rs"),
                        ::tracing_core::__macro_support::Option::Some(298u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_middle::ty::region"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("type_flags({0:?}) = {1:?}",
                                                    self, flags) as &dyn Value))])
            });
    } else { ; }
};debug!("type_flags({:?}) = {:?}", self, flags);
299
300        flags
301    }
302
303    /// True for free regions other than `'static`.
304    pub fn is_param(self) -> bool {
305        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::ReEarlyParam(_) | ty::ReLateParam(_) => true,
    _ => false,
}matches!(self.kind(), ty::ReEarlyParam(_) | ty::ReLateParam(_))
306    }
307
308    /// True for free region in the current context.
309    ///
310    /// This is the case for `'static` and param regions.
311    pub fn is_free(self) -> bool {
312        match self.kind() {
313            ty::ReStatic | ty::ReEarlyParam(..) | ty::ReLateParam(..) => true,
314            ty::ReVar(..)
315            | ty::RePlaceholder(..)
316            | ty::ReBound(..)
317            | ty::ReErased
318            | ty::ReError(..) => false,
319        }
320    }
321
322    pub fn is_var(self) -> bool {
323        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::ReVar(_) => true,
    _ => false,
}matches!(self.kind(), ty::ReVar(_))
324    }
325
326    pub fn as_var(self) -> RegionVid {
327        match self.kind() {
328            ty::ReVar(vid) => vid,
329            _ => crate::util::bug::bug_fmt(format_args!("expected region {0:?} to be of kind ReVar",
        self))bug!("expected region {:?} to be of kind ReVar", self),
330        }
331    }
332
333    /// Given some item `binding_item`, check if this region is a generic parameter introduced by it
334    /// or one of the parent generics. Returns the `DefId` of the parameter definition if so.
335    pub fn opt_param_def_id(self, tcx: TyCtxt<'tcx>, binding_item: DefId) -> Option<DefId> {
336        match self.kind() {
337            ty::ReEarlyParam(ebr) => {
338                Some(tcx.generics_of(binding_item).region_param(ebr, tcx).def_id)
339            }
340            ty::ReLateParam(ty::LateParamRegion {
341                kind: ty::LateParamRegionKind::Named(def_id),
342                ..
343            }) => Some(def_id),
344            _ => None,
345        }
346    }
347}
348
349#[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_receiver_is_total_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)]
350#[derive(const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for EarlyParamRegion {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    EarlyParamRegion {
                        index: ref __binding_0, name: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
351pub struct EarlyParamRegion {
352    pub index: u32,
353    pub name: Symbol,
354}
355
356impl EarlyParamRegion {
357    /// Does this early bound region have a name? Early bound regions normally
358    /// always have names except when using anonymous lifetimes (`'_`).
359    pub fn is_named(&self) -> bool {
360        self.name != kw::UnderscoreLifetime
361    }
362}
363
364impl rustc_type_ir::inherent::ParamLike for EarlyParamRegion {
365    fn index(self) -> u32 {
366        self.index
367    }
368}
369
370impl std::fmt::Debug for EarlyParamRegion {
371    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
372        f.write_fmt(format_args!("{0}/#{1}", self.name, self.index))write!(f, "{}/#{}", self.name, self.index)
373    }
374}
375
376#[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_receiver_is_total_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)]
377#[derive(const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for LateParamRegion {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    LateParamRegion {
                        scope: ref __binding_0, kind: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
378/// The parameter representation of late-bound function parameters, "some region
379/// at least as big as the scope `fr.scope`".
380///
381/// Similar to a placeholder region as we create `LateParam` regions when entering a binder
382/// except they are always in the root universe and instead of using a boundvar to distinguish
383/// between others we use the `DefId` of the parameter. For this reason the `bound_region` field
384/// should basically always be `BoundRegionKind::Named` as otherwise there is no way of telling
385/// different parameters apart.
386pub struct LateParamRegion {
387    pub scope: DefId,
388    pub kind: LateParamRegionKind,
389}
390
391/// When liberating bound regions, we map their [`BoundRegionKind`]
392/// to this as we need to track the index of anonymous regions. We
393/// otherwise end up liberating multiple bound regions to the same
394/// late-bound region.
395#[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_receiver_is_total_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)]
396#[derive(const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for LateParamRegionKind {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    LateParamRegionKind::Anon(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    LateParamRegionKind::NamedAnon(ref __binding_0,
                        ref __binding_1) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    LateParamRegionKind::Named(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    LateParamRegionKind::ClosureEnv => {}
                }
            }
        }
    };HashStable)]
397pub enum LateParamRegionKind {
398    /// An anonymous region parameter for a given fn (&T)
399    ///
400    /// Unlike [`BoundRegionKind::Anon`], this tracks the index of the
401    /// liberated bound region.
402    ///
403    /// We should ideally never liberate anonymous regions, but do so for the
404    /// sake of diagnostics in `FnCtxt::sig_of_closure_with_expectation`.
405    Anon(u32),
406
407    /// An anonymous region parameter with a `Symbol` name.
408    ///
409    /// Used to give late-bound regions names for things like pretty printing.
410    NamedAnon(u32, Symbol),
411
412    /// Late-bound regions that appear in the AST.
413    Named(DefId),
414
415    /// Anonymous region for the implicit env pointer parameter
416    /// to a closure
417    ClosureEnv,
418}
419
420impl LateParamRegionKind {
421    pub fn from_bound(var: BoundVar, br: BoundRegionKind) -> LateParamRegionKind {
422        match br {
423            BoundRegionKind::Anon => LateParamRegionKind::Anon(var.as_u32()),
424            BoundRegionKind::Named(def_id) => LateParamRegionKind::Named(def_id),
425            BoundRegionKind::ClosureEnv => LateParamRegionKind::ClosureEnv,
426            BoundRegionKind::NamedAnon(name) => LateParamRegionKind::NamedAnon(var.as_u32(), name),
427        }
428    }
429
430    pub fn is_named(&self, tcx: TyCtxt<'_>) -> bool {
431        self.get_name(tcx).is_some()
432    }
433
434    pub fn get_name(&self, tcx: TyCtxt<'_>) -> Option<Symbol> {
435        match *self {
436            LateParamRegionKind::Named(def_id) => {
437                let name = tcx.item_name(def_id);
438                if name != kw::UnderscoreLifetime { Some(name) } else { None }
439            }
440            LateParamRegionKind::NamedAnon(_, name) => Some(name),
441            _ => None,
442        }
443    }
444
445    pub fn get_id(&self) -> Option<DefId> {
446        match *self {
447            LateParamRegionKind::Named(id) => Some(id),
448            _ => None,
449        }
450    }
451}
452
453#[derive(#[automatically_derived]
impl ::core::clone::Clone for BoundRegionKind {
    #[inline]
    fn clone(&self) -> BoundRegionKind {
        let _: ::core::clone::AssertParamIsClone<Symbol>;
        let _: ::core::clone::AssertParamIsClone<DefId>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for BoundRegionKind {
    #[inline]
    fn eq(&self, other: &BoundRegionKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (BoundRegionKind::NamedAnon(__self_0),
                    BoundRegionKind::NamedAnon(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (BoundRegionKind::Named(__self_0),
                    BoundRegionKind::Named(__arg1_0)) => __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for BoundRegionKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<Symbol>;
        let _: ::core::cmp::AssertParamIsEq<DefId>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for BoundRegionKind {
    #[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 {
            BoundRegionKind::NamedAnon(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            BoundRegionKind::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 BoundRegionKind {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        BoundRegionKind::Anon => { 0usize }
                        BoundRegionKind::NamedAnon(ref __binding_0) => { 1usize }
                        BoundRegionKind::Named(ref __binding_0) => { 2usize }
                        BoundRegionKind::ClosureEnv => { 3usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    BoundRegionKind::Anon => {}
                    BoundRegionKind::NamedAnon(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    BoundRegionKind::Named(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    BoundRegionKind::ClosureEnv => {}
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for BoundRegionKind {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { BoundRegionKind::Anon }
                    1usize => {
                        BoundRegionKind::NamedAnon(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    2usize => {
                        BoundRegionKind::Named(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    3usize => { BoundRegionKind::ClosureEnv }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `BoundRegionKind`, expected 0..4, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, #[automatically_derived]
impl ::core::marker::Copy for BoundRegionKind { }Copy)]
454#[derive(const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for BoundRegionKind {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    BoundRegionKind::Anon => {}
                    BoundRegionKind::NamedAnon(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    BoundRegionKind::Named(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    BoundRegionKind::ClosureEnv => {}
                }
            }
        }
    };HashStable)]
455pub enum BoundRegionKind {
456    /// An anonymous region parameter for a given fn (&T)
457    Anon,
458
459    /// An anonymous region parameter with a `Symbol` name.
460    ///
461    /// Used to give late-bound regions names for things like pretty printing.
462    NamedAnon(Symbol),
463
464    /// Late-bound regions that appear in the AST.
465    Named(DefId),
466
467    /// Anonymous region for the implicit env pointer parameter
468    /// to a closure
469    ClosureEnv,
470}
471
472#[derive(#[automatically_derived]
impl ::core::marker::Copy for BoundRegion { }Copy, #[automatically_derived]
impl ::core::clone::Clone for BoundRegion {
    #[inline]
    fn clone(&self) -> BoundRegion {
        let _: ::core::clone::AssertParamIsClone<BoundVar>;
        let _: ::core::clone::AssertParamIsClone<BoundRegionKind>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for BoundRegion {
    #[inline]
    fn eq(&self, other: &BoundRegion) -> bool {
        self.var == other.var && self.kind == other.kind
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for BoundRegion {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<BoundVar>;
        let _: ::core::cmp::AssertParamIsEq<BoundRegionKind>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for BoundRegion {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
        ::core::hash::Hash::hash(&self.var, state);
        ::core::hash::Hash::hash(&self.kind, state)
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for BoundRegion {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    BoundRegion { var: 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 BoundRegion {
            fn decode(__decoder: &mut __D) -> Self {
                BoundRegion {
                    var: ::rustc_serialize::Decodable::decode(__decoder),
                    kind: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable)]
473#[derive(const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for BoundRegion {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    BoundRegion { var: ref __binding_0, kind: ref __binding_1 }
                        => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
474pub struct BoundRegion {
475    pub var: BoundVar,
476    pub kind: BoundRegionKind,
477}
478
479impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundRegion {
480    fn var(self) -> BoundVar {
481        self.var
482    }
483
484    fn assert_eq(self, var: ty::BoundVariableKind) {
485        match (&self.kind, &var.expect_region()) {
    (left_val, right_val) => {
        if !(*left_val == *right_val) {
            let kind = ::core::panicking::AssertKind::Eq;
            ::core::panicking::assert_failed(kind, &*left_val, &*right_val,
                ::core::option::Option::None);
        }
    }
}assert_eq!(self.kind, var.expect_region())
486    }
487}
488
489impl core::fmt::Debug for BoundRegion {
490    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
491        match self.kind {
492            BoundRegionKind::Anon => f.write_fmt(format_args!("{0:?}", self.var))write!(f, "{:?}", self.var),
493            BoundRegionKind::ClosureEnv => f.write_fmt(format_args!("{0:?}.Env", self.var))write!(f, "{:?}.Env", self.var),
494            BoundRegionKind::Named(def) => {
495                f.write_fmt(format_args!("{0:?}.Named({1:?})", self.var, def))write!(f, "{:?}.Named({:?})", self.var, def)
496            }
497            BoundRegionKind::NamedAnon(symbol) => {
498                f.write_fmt(format_args!("{0:?}.NamedAnon({1:?})", self.var, symbol))write!(f, "{:?}.NamedAnon({:?})", self.var, symbol)
499            }
500        }
501    }
502}
503
504impl BoundRegionKind {
505    pub fn is_named(&self, tcx: TyCtxt<'_>) -> bool {
506        self.get_name(tcx).is_some()
507    }
508
509    pub fn get_name(&self, tcx: TyCtxt<'_>) -> Option<Symbol> {
510        match *self {
511            BoundRegionKind::Named(def_id) => {
512                let name = tcx.item_name(def_id);
513                if name != kw::UnderscoreLifetime { Some(name) } else { None }
514            }
515            BoundRegionKind::NamedAnon(name) => Some(name),
516            _ => None,
517        }
518    }
519
520    pub fn get_id(&self) -> Option<DefId> {
521        match *self {
522            BoundRegionKind::Named(id) => Some(id),
523            _ => None,
524        }
525    }
526}
527
528// Some types are used a lot. Make sure they don't unintentionally get bigger.
529#[cfg(target_pointer_width = "64")]
530mod size_asserts {
531    use rustc_data_structures::static_assert_size;
532
533    use super::*;
534    // tidy-alphabetical-start
535    const _: [(); 20] = [(); ::std::mem::size_of::<RegionKind<'_>>()];static_assert_size!(RegionKind<'_>, 20);
536    const _: [(); 48] =
    [(); ::std::mem::size_of::<ty::WithCachedTypeInfo<RegionKind<'_>>>()];static_assert_size!(ty::WithCachedTypeInfo<RegionKind<'_>>, 48);
537    // tidy-alphabetical-end
538}