Skip to main content

rustc_type_ir/sty/
mod.rs

1use std::fmt;
2
3use derive_where::derive_where;
4#[cfg(feature = "nightly")]
5use rustc_macros::StableHash_NoContext;
6use rustc_type_ir_macros::{GenericTypeVisitable, Lift_Generic};
7use tracing::debug;
8
9use crate::inherent::*;
10use crate::intern::Interned;
11use crate::relate::{Relate, RelateResult, TypeRelation};
12use crate::{
13    BoundRegion, BoundRegionKind, BoundVar, BoundVarIndexKind, DebruijnIndex, FallibleTypeFolder,
14    Flags, Interner, PlaceholderRegion, RegionKind, RegionVid, TypeFlags, TypeFoldable, TypeFolder,
15    TypeVisitable, TypeVisitor,
16};
17
18/// Use this rather than `RegionKind`, whenever possible.
19#[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)]
20#[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))]
21#[cfg_attr(feature = "nightly", rustc_pass_by_value)]
22#[derive(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)]
23pub struct Region<I: Interner>(pub I::InternedRegionKind);
24
25// These are only the `inherent` trait methods that have been ported across
26impl<I: Interner> Region<I> {
27    #[inline]
28    pub fn new_bound(interner: I, debruijn: DebruijnIndex, bound_region: BoundRegion<I>) -> Self {
29        interner.intern_bound_region(debruijn, bound_region)
30    }
31
32    #[inline]
33    pub fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self {
34        Self::new_bound(interner, debruijn, BoundRegion { var, kind: BoundRegionKind::Anon })
35    }
36
37    #[inline]
38    pub fn new_canonical_bound(interner: I, var: BoundVar) -> Self {
39        interner.intern_canonical_bound(var)
40    }
41
42    #[inline]
43    pub fn new_placeholder(interner: I, placeholder: PlaceholderRegion<I>) -> Self {
44        interner.intern_region(RegionKind::RePlaceholder(placeholder))
45    }
46
47    #[inline]
48    pub fn new_static(interner: I) -> Self {
49        interner.get_re_static_lifetime()
50    }
51
52    #[inline]
53    pub fn is_bound(self) -> bool {
54        #[allow(non_exhaustive_omitted_patterns)] match self.0.get() {
    RegionKind::ReBound(..) => true,
    _ => false,
}matches!(self.0.get(), RegionKind::ReBound(..))
55    }
56
57    #[inline]
58    pub fn is_error(self) -> bool {
59        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::ReError(_) => true,
    _ => false,
}matches!(self.kind(), RegionKind::ReError(_))
60    }
61
62    #[inline]
63    pub fn is_static(self) -> bool {
64        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::ReStatic => true,
    _ => false,
}matches!(self.kind(), RegionKind::ReStatic)
65    }
66
67    #[inline]
68    pub fn is_erased(self) -> bool {
69        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::ReErased => true,
    _ => false,
}matches!(self.kind(), RegionKind::ReErased)
70    }
71
72    #[inline]
73    pub fn is_placeholder(self) -> bool {
74        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::RePlaceholder(..) => true,
    _ => false,
}matches!(self.kind(), RegionKind::RePlaceholder(..))
75    }
76
77    /// True for free regions other than `'static`.
78    pub fn is_param(self) -> bool {
79        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::ReEarlyParam(_) | RegionKind::ReLateParam(_) => true,
    _ => false,
}matches!(self.kind(), RegionKind::ReEarlyParam(_) | RegionKind::ReLateParam(_))
80    }
81
82    /// True for free region in the current context.
83    ///
84    /// This is the case for `'static` and param regions.
85    pub fn is_free(self) -> bool {
86        match self.kind() {
87            RegionKind::ReStatic | RegionKind::ReEarlyParam(..) | RegionKind::ReLateParam(..) => {
88                true
89            }
90            RegionKind::ReVar(..)
91            | RegionKind::RePlaceholder(..)
92            | RegionKind::ReBound(..)
93            | RegionKind::ReErased
94            | RegionKind::ReError(..) => false,
95        }
96    }
97
98    pub fn is_var(self) -> bool {
99        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    RegionKind::ReVar(_) => true,
    _ => false,
}matches!(self.kind(), RegionKind::ReVar(_))
100    }
101
102    pub fn as_var(self) -> RegionVid {
103        match self.kind() {
104            RegionKind::ReVar(vid) => vid,
105            _ => {
    ::core::panicking::panic_fmt(format_args!("expected region {0:?} to be of kind ReVar",
            self));
}panic!("expected region {:?} to be of kind ReVar", self),
106        }
107    }
108
109    // FIXME this should be made private and instead accessed via the
110    // trait Flags
111    #[inline]
112    pub fn type_flags(self) -> TypeFlags {
113        let mut flags = TypeFlags::empty();
114
115        match self.0.get() {
116            RegionKind::ReVar(..) => {
117                flags = flags | TypeFlags::HAS_FREE_REGIONS;
118                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
119                flags = flags | TypeFlags::HAS_RE_INFER;
120            }
121            RegionKind::RePlaceholder(..) => {
122                flags = flags | TypeFlags::HAS_FREE_REGIONS;
123                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
124                flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
125            }
126            RegionKind::ReEarlyParam(..) => {
127                flags = flags | TypeFlags::HAS_FREE_REGIONS;
128                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
129                flags = flags | TypeFlags::HAS_RE_PARAM;
130            }
131            RegionKind::ReLateParam { .. } => {
132                flags = flags | TypeFlags::HAS_FREE_REGIONS;
133                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
134            }
135            RegionKind::ReStatic => {
136                flags = flags | TypeFlags::HAS_FREE_REGIONS;
137            }
138            RegionKind::ReBound(BoundVarIndexKind::Canonical, _) => {
139                flags = flags | TypeFlags::HAS_RE_BOUND;
140                flags = flags | TypeFlags::HAS_CANONICAL_BOUND;
141            }
142            RegionKind::ReBound(BoundVarIndexKind::Bound(..), _) => {
143                flags = flags | TypeFlags::HAS_RE_BOUND;
144            }
145            RegionKind::ReErased => {
146                flags = flags | TypeFlags::HAS_RE_ERASED;
147            }
148            RegionKind::ReError(_) => {
149                flags = flags | TypeFlags::HAS_FREE_REGIONS;
150                flags = flags | TypeFlags::HAS_RE_ERROR;
151            }
152        }
153        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_type_ir/src/sty/mod.rs:153",
                        "rustc_type_ir::sty", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_type_ir/src/sty/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(153u32),
                        ::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);
154
155        flags
156    }
157
158    #[inline]
159    pub fn kind(self) -> RegionKind<I> {
160        self.0.get()
161    }
162}
163
164impl<I: Interner> Flags for Region<I> {
165    fn flags(&self) -> TypeFlags {
166        self.type_flags()
167    }
168
169    fn outer_exclusive_binder(&self) -> DebruijnIndex {
170        match self.kind() {
171            RegionKind::ReBound(BoundVarIndexKind::Bound(debruijn), _) => debruijn.shifted_in(1),
172            _ => crate::INNERMOST,
173        }
174    }
175}
176
177impl<I: Interner> IntoKind for Region<I> {
178    type Kind = RegionKind<I>;
179
180    fn kind(self) -> Self::Kind {
181        self.0.get()
182    }
183}
184
185impl<I: Interner> Relate<I> for Region<I> {
186    fn relate<R: TypeRelation<I>>(
187        relation: &mut R,
188        a: Region<I>,
189        b: Region<I>,
190    ) -> RelateResult<I, Region<I>> {
191        relation.regions(a, b)
192    }
193}
194
195impl<I: Interner> fmt::Debug for Region<I> {
196    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197        f.write_fmt(format_args!("{0:?}", self.kind()))write!(f, "{:?}", self.kind())
198    }
199}
200
201impl<I: Interner> TypeVisitable<I> for Region<I> {
202    fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
203        visitor.visit_region(*self)
204    }
205}
206
207impl<I: Interner> TypeFoldable<I> for Region<I> {
208    fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
209        folder.try_fold_region(self)
210    }
211
212    fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
213        folder.fold_region(self)
214    }
215}