Skip to main content

rustc_type_ir/sty/
mod.rs

1pub use consts::*;
2mod consts;
3
4use std::fmt;
5
6use derive_where::derive_where;
7#[cfg(feature = "nightly")]
8use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext};
9use rustc_type_ir_macros::{GenericTypeVisitable, Lift_Generic};
10use tracing::debug;
11
12use crate::inherent::*;
13use crate::intern::Interned;
14use crate::relate::{Relate, RelateResult, TypeRelation};
15use crate::{
16    BoundRegion, BoundRegionKind, BoundVar, BoundVarIndexKind, DebruijnIndex, FallibleTypeFolder,
17    Flags, Interner, PlaceholderRegion, RegionKind, RegionVid, TypeFlags, TypeFoldable, TypeFolder,
18    TypeVisitable, TypeVisitor,
19};
20
21/// Use this rather than `RegionKind`, whenever possible.
22#[automatically_derived]
impl<I: Interner> ::core::clone::Clone for Region<I> where I: Interner {
    #[inline]
    fn clone(&self) -> Self { *self }
}
#[automatically_derived]
impl<I: Interner> ::core::marker::Copy for Region<I> where I: Interner { }
#[automatically_derived]
impl<I: Interner> ::core::cmp::PartialEq for Region<I> where I: Interner {
    #[inline]
    fn eq(&self, __other: &Self) -> ::core::primitive::bool {
        match (self, __other) {
            (Region(ref __field_0), Region(ref __other_field_0)) =>
                true &&
                    ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
        }
    }
}
const _: () =
    {
        trait DeriveWhereAssertEq {
            fn assert(&self);
        }
        impl<I: Interner> DeriveWhereAssertEq for Region<I> where I: Interner
            {
            fn assert(&self) {
                struct __AssertEq<__T: ::core::cmp::Eq +
                    ?::core::marker::Sized>(::core::marker::PhantomData<__T>);
                let _: __AssertEq<I::InternedRegionKind>;
            }
        }
    };
#[automatically_derived]
impl<I: Interner> ::core::cmp::Eq for Region<I> where I: Interner { }
#[automatically_derived]
impl<I: Interner> ::core::hash::Hash for Region<I> where I: Interner {
    fn hash<__H: ::core::hash::Hasher>(&self, __state: &mut __H) {
        match self {
            Region(ref __field_0) => {
                ::core::hash::Hash::hash(__field_0, __state);
            }
        }
    }
}#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
23#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<I: Interner> ::rustc_data_structures::stable_hash::StableHash for
            Region<I> where
            I::InternedRegionKind: ::rustc_data_structures::stable_hash::StableHash
            {
            #[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 {
                    Region(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext))]
24#[cfg_attr(feature = "nightly", rustc_pass_by_value)]
25#[derive(const _: () =
    {
        unsafe impl<I: Interner, __V>
            ::rustc_type_ir::GenericTypeVisitable<__V> for Region<I> where
            I::InternedRegionKind: ::rustc_type_ir::GenericTypeVisitable<__V>
            {
            fn generic_visit_with(&self, __visitor: &mut __V) {
                match *self {
                    Region(ref __binding_0) => {
                        {
                            ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
                                __visitor);
                        }
                    }
                }
            }
        }
    };GenericTypeVisitable, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for Region<I>
            where J: Interner, I: ::rustc_type_ir::LiftInto<J> {
            type Lifted = Region<J>;
            fn lift_to_interner(self, interner: J) -> Self::Lifted {
                match self {
                    Region(__binding_0) => {
                        Region(__binding_0.lift_to_interner(interner))
                    }
                }
            }
        }
    };Lift_Generic)]
26pub struct Region<I: Interner>(pub I::InternedRegionKind);
27
28// These are only the `inherent` trait methods that have been ported across
29impl<I: Interner> Region<I> {
30    #[inline]
31    pub fn new_var(interner: I, v: RegionVid) -> Self {
32        interner.intern_re_var(v)
33    }
34
35    pub fn get_name(self, interner: I) -> Option<I::Symbol> {
36        match self.kind() {
37            RegionKind::ReEarlyParam(ebr) => ebr.get_name(interner),
38            RegionKind::ReBound(_, br) => br.kind.get_name(interner),
39            RegionKind::ReLateParam(fr) => fr.kind.get_name(interner),
40            RegionKind::ReStatic => Some(I::Symbol::KW_STATIC_LIFETIME),
41            RegionKind::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(interner),
42            _ => None,
43        }
44    }
45
46    pub fn get_name_or_anon(self, interner: I) -> I::Symbol {
47        match self.get_name(interner) {
48            Some(name) => name,
49            None => I::Symbol::SYM_ANON,
50        }
51    }
52
53    /// Given some item `binding_item`, check if this region is a generic parameter introduced by it
54    /// or one of the parent generics. Returns the `DefId` of the parameter definition if so.
55    pub fn opt_param_def_id(self, interner: I, binding_item: I::DefId) -> Option<I::DefId> {
56        match self.kind() {
57            RegionKind::ReEarlyParam(ebr) => {
58                Some(interner.generics_of(binding_item).param_region_def_id(interner, ebr))
59            }
60            RegionKind::ReLateParam(param) => param.kind.get_def_id(),
61            _ => None,
62        }
63    }
64
65    /// Is this region named by the user?
66    pub fn is_named(self, interner: I) -> bool {
67        match self.kind() {
68            RegionKind::ReEarlyParam(ebr) => ebr.is_named(interner),
69            RegionKind::ReBound(_, br) => br.kind.is_named(interner),
70            RegionKind::ReLateParam(fr) => fr.kind.is_named(interner),
71            RegionKind::ReStatic => true,
72            RegionKind::ReVar(..) => false,
73            RegionKind::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(interner),
74            RegionKind::ReErased => false,
75            RegionKind::ReError(_) => false,
76        }
77    }
78
79    /// Constructs a `RegionKind::ReError` region and registers a delayed bug to ensure it gets
80    /// used.
81    #[track_caller]
82    pub fn new_error_misc(interner: I) -> Self {
83        Self::new_error_with_message(
84            interner,
85            I::Span::dummy(),
86            "RegionKind::ReError constructed but no error reported",
87        )
88    }
89
90    /// Constructs a `RegionKind::ReError` region and registers a delayed bug with the given `msg`
91    /// to ensure it gets used.
92    #[track_caller]
93    pub fn new_error_with_message(interner: I, span: I::Span, msg: impl ToString) -> Self {
94        let reported = interner.span_delayed_bug(span, msg);
95        Self::new_error(interner, reported)
96    }
97
98    #[inline]
99    pub fn new_late_param(interner: I, scope: I::DefId, kind: I::LateParamRegionKind) -> Self {
100        interner.intern_region(RegionKind::ReLateParam(LateParamRegion { scope, kind }))
101    }
102
103    #[inline]
104    pub fn new_early_param(interner: I, early_bound_region: I::EarlyParamRegion) -> Self {
105        interner.intern_region(RegionKind::ReEarlyParam(early_bound_region))
106    }
107
108    /// Constructs a `RegionKind::ReError` region.
109    #[track_caller]
110    pub fn new_error(interner: I, guar: I::ErrorGuaranteed) -> Self {
111        interner.intern_region(RegionKind::ReError(guar))
112    }
113
114    #[inline]
115    pub fn new_bound(interner: I, debruijn: DebruijnIndex, bound_region: BoundRegion<I>) -> Self {
116        interner.intern_bound_region(debruijn, bound_region)
117    }
118
119    #[inline]
120    pub fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self {
121        Self::new_bound(interner, debruijn, BoundRegion { var, kind: BoundRegionKind::Anon })
122    }
123
124    #[inline]
125    pub fn new_canonical_bound(interner: I, var: BoundVar) -> Self {
126        interner.intern_canonical_bound(var)
127    }
128
129    #[inline]
130    pub fn new_placeholder(interner: I, placeholder: PlaceholderRegion<I>) -> Self {
131        interner.intern_region(RegionKind::RePlaceholder(placeholder))
132    }
133
134    #[inline]
135    pub fn new_static(interner: I) -> Self {
136        interner.get_re_static_lifetime()
137    }
138
139    #[inline]
140    pub fn is_bound(self) -> bool {
141        #[allow(non_exhaustive_omitted_patterns)] match self.0.get() {
    RegionKind::ReBound(..) => true,
    _ => false,
}matches!(self.0.get(), RegionKind::ReBound(..))
142    }
143
144    #[inline]
145    pub fn is_error(self) -> bool {
146        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::ReError(_) => true,
    _ => false,
}matches!(self.kind(), RegionKind::ReError(_))
147    }
148
149    #[inline]
150    pub fn is_static(self) -> bool {
151        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::ReStatic => true,
    _ => false,
}matches!(self.kind(), RegionKind::ReStatic)
152    }
153
154    #[inline]
155    pub fn is_erased(self) -> bool {
156        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::ReErased => true,
    _ => false,
}matches!(self.kind(), RegionKind::ReErased)
157    }
158
159    #[inline]
160    pub fn is_placeholder(self) -> bool {
161        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::RePlaceholder(..) => true,
    _ => false,
}matches!(self.kind(), RegionKind::RePlaceholder(..))
162    }
163
164    /// True for free regions other than `'static`.
165    pub fn is_param(self) -> bool {
166        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::ReEarlyParam(_) | RegionKind::ReLateParam(_) => true,
    _ => false,
}matches!(self.kind(), RegionKind::ReEarlyParam(_) | RegionKind::ReLateParam(_))
167    }
168
169    /// True for free region in the current context.
170    ///
171    /// This is the case for `'static` and param regions.
172    pub fn is_free(self) -> bool {
173        match self.kind() {
174            RegionKind::ReStatic | RegionKind::ReEarlyParam(..) | RegionKind::ReLateParam(..) => {
175                true
176            }
177            RegionKind::ReVar(..)
178            | RegionKind::RePlaceholder(..)
179            | RegionKind::ReBound(..)
180            | RegionKind::ReErased
181            | RegionKind::ReError(..) => false,
182        }
183    }
184
185    pub fn is_var(self) -> bool {
186        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::ReVar(_) => true,
    _ => false,
}matches!(self.kind(), RegionKind::ReVar(_))
187    }
188
189    pub fn as_var(self) -> RegionVid {
190        match self.kind() {
191            RegionKind::ReVar(vid) => vid,
192            _ => {
    ::core::panicking::panic_fmt(format_args!("expected region {0:?} to be of kind ReVar",
            self));
}panic!("expected region {:?} to be of kind ReVar", self),
193        }
194    }
195
196    // FIXME this should be made private and instead accessed via the
197    // trait Flags
198    #[inline]
199    pub fn type_flags(self) -> TypeFlags {
200        let mut flags = TypeFlags::empty();
201
202        match self.0.get() {
203            RegionKind::ReVar(..) => {
204                flags = flags | TypeFlags::HAS_FREE_REGIONS;
205                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
206                flags = flags | TypeFlags::HAS_RE_INFER;
207            }
208            RegionKind::RePlaceholder(..) => {
209                flags = flags | TypeFlags::HAS_FREE_REGIONS;
210                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
211                flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
212            }
213            RegionKind::ReEarlyParam(..) => {
214                flags = flags | TypeFlags::HAS_FREE_REGIONS;
215                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
216                flags = flags | TypeFlags::HAS_RE_PARAM;
217            }
218            RegionKind::ReLateParam { .. } => {
219                flags = flags | TypeFlags::HAS_FREE_REGIONS;
220                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
221            }
222            RegionKind::ReStatic => {
223                flags = flags | TypeFlags::HAS_FREE_REGIONS;
224            }
225            RegionKind::ReBound(BoundVarIndexKind::Canonical, _) => {
226                flags = flags | TypeFlags::HAS_RE_BOUND;
227                flags = flags | TypeFlags::HAS_CANONICAL_BOUND;
228            }
229            RegionKind::ReBound(BoundVarIndexKind::Bound(..), _) => {
230                flags = flags | TypeFlags::HAS_RE_BOUND;
231            }
232            RegionKind::ReErased => {
233                flags = flags | TypeFlags::HAS_RE_ERASED;
234            }
235            RegionKind::ReError(_) => {
236                flags = flags | TypeFlags::HAS_FREE_REGIONS;
237                flags = flags | TypeFlags::HAS_RE_ERROR;
238            }
239        }
240        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_type_ir/src/sty/mod.rs:240",
                        "rustc_type_ir::sty", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_type_ir/src/sty/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(240u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_type_ir::sty"),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("type_flags({0:?}) = {1:?}",
                                                    self, flags) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("type_flags({:?}) = {:?}", self, flags);
241
242        flags
243    }
244
245    #[inline]
246    pub fn kind(self) -> RegionKind<I> {
247        self.0.get()
248    }
249
250    #[inline]
251    pub fn bound_at_or_above_binder(self, index: DebruijnIndex) -> bool {
252        match self.kind() {
253            RegionKind::ReBound(BoundVarIndexKind::Bound(debruijn), _) => debruijn >= index,
254            _ => false,
255        }
256    }
257}
258
259impl<I: Interner> Flags for Region<I> {
260    fn flags(&self) -> TypeFlags {
261        self.type_flags()
262    }
263
264    fn outer_exclusive_binder(&self) -> DebruijnIndex {
265        match self.kind() {
266            RegionKind::ReBound(BoundVarIndexKind::Bound(debruijn), _) => debruijn.shifted_in(1),
267            _ => crate::INNERMOST,
268        }
269    }
270}
271
272impl<I: Interner> IntoKind for Region<I> {
273    type Kind = RegionKind<I>;
274
275    fn kind(self) -> Self::Kind {
276        self.0.get()
277    }
278}
279
280impl<I: Interner> Relate<I> for Region<I> {
281    fn relate<R: TypeRelation<I>>(
282        relation: &mut R,
283        a: Region<I>,
284        b: Region<I>,
285    ) -> RelateResult<I, Region<I>> {
286        relation.regions(a, b)
287    }
288}
289
290impl<I: Interner> fmt::Debug for Region<I> {
291    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
292        f.write_fmt(format_args!("{0:?}", self.kind()))write!(f, "{:?}", self.kind())
293    }
294}
295
296impl<I: Interner> TypeVisitable<I> for Region<I> {
297    fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
298        visitor.visit_region(*self)
299    }
300}
301
302impl<I: Interner> TypeFoldable<I> for Region<I> {
303    fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
304        folder.try_fold_region(self)
305    }
306
307    fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
308        folder.fold_region(self)
309    }
310}
311
312#[automatically_derived]
impl<I: Interner> ::core::clone::Clone for LateParamRegion<I> where
    I: Interner {
    #[inline]
    fn clone(&self) -> Self { *self }
}
#[automatically_derived]
impl<I: Interner> ::core::marker::Copy for LateParamRegion<I> where
    I: Interner {
}
#[automatically_derived]
impl<I: Interner> ::core::cmp::PartialEq for LateParamRegion<I> where
    I: Interner {
    #[inline]
    fn eq(&self, __other: &Self) -> ::core::primitive::bool {
        match (self, __other) {
            (LateParamRegion {
                scope: ref __field_scope, kind: ref __field_kind },
                LateParamRegion {
                scope: ref __other_field_scope, kind: ref __other_field_kind
                }) =>
                true &&
                        ::core::cmp::PartialEq::eq(__field_scope,
                            __other_field_scope) &&
                    ::core::cmp::PartialEq::eq(__field_kind,
                        __other_field_kind),
        }
    }
}
const _: () =
    {
        trait DeriveWhereAssertEq {
            fn assert(&self);
        }
        impl<I: Interner> DeriveWhereAssertEq for LateParamRegion<I> where
            I: Interner {
            fn assert(&self) {
                struct __AssertEq<__T: ::core::cmp::Eq +
                    ?::core::marker::Sized>(::core::marker::PhantomData<__T>);
                let _: __AssertEq<I::DefId>;
                let _: __AssertEq<I::LateParamRegionKind>;
            }
        }
    };
#[automatically_derived]
impl<I: Interner> ::core::cmp::Eq for LateParamRegion<I> where I: Interner { }
#[automatically_derived]
impl<I: Interner> ::core::hash::Hash for LateParamRegion<I> where I: Interner
    {
    fn hash<__H: ::core::hash::Hasher>(&self, __state: &mut __H) {
        match self {
            LateParamRegion { scope: ref __field_scope, kind: ref __field_kind
                } => {
                ::core::hash::Hash::hash(__field_scope, __state);
                ::core::hash::Hash::hash(__field_kind, __state);
            }
        }
    }
}#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
313#[cfg_attr(
314    feature = "nightly",
315    derive(const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for LateParamRegion<I> where
            I::DefId: ::rustc_serialize::Encodable<__E>,
            I::LateParamRegionKind: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                let LateParamRegion {
                        scope: ref __binding_0, kind: ref __binding_1 } = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for LateParamRegion<I> where
            I::DefId: ::rustc_serialize::Decodable<__D>,
            I::LateParamRegionKind: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                LateParamRegion {
                    scope: ::rustc_serialize::Decodable::decode(__decoder),
                    kind: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner> ::rustc_data_structures::stable_hash::StableHash for
            LateParamRegion<I> where
            I::DefId: ::rustc_data_structures::stable_hash::StableHash,
            I::LateParamRegionKind: ::rustc_data_structures::stable_hash::StableHash
            {
            #[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_NoContext)
316)]
317/// The parameter representation of late-bound function parameters, "some region
318/// at least as big as the scope `fr.scope`".
319///
320/// Similar to a placeholder region as we create `LateParam` regions when entering a binder
321/// except they are always in the root universe and instead of using a boundvar to distinguish
322/// between others we use the `DefId` of the parameter. For this reason the `bound_region` field
323/// should basically always be `BoundRegionKind::Named` as otherwise there is no way of telling
324/// different parameters apart.
325pub struct LateParamRegion<I: Interner> {
326    pub scope: I::DefId,
327    pub kind: I::LateParamRegionKind,
328}
329
330impl<I: Interner> fmt::Debug for LateParamRegion<I> {
331    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
332        f.write_fmt(format_args!("ReLateParam({0:?}, {1:?})", self.scope, self.kind))write!(f, "ReLateParam({:?}, {:?})", self.scope, self.kind)
333    }
334}