Skip to main content

rustc_type_ir/
ty_info.rs

1use std::cmp::Ordering;
2use std::hash::{Hash, Hasher};
3use std::ops::Deref;
4
5#[cfg(feature = "nightly")]
6use rustc_data_structures::stable_hasher::{HashStable, HashStableContext, StableHasher};
7use rustc_type_ir_macros::GenericTypeVisitable;
8
9use crate::{DebruijnIndex, TypeFlags};
10
11/// A helper type that you can wrap round your own type in order to automatically
12/// cache the type flags and debruijn index on creation and not recompute it
13/// whenever the information is needed.
14#[derive(#[automatically_derived]
impl<T: ::core::marker::Copy> ::core::marker::Copy for WithCachedTypeInfo<T> {
}Copy, #[automatically_derived]
impl<T: ::core::clone::Clone> ::core::clone::Clone for WithCachedTypeInfo<T> {
    #[inline]
    fn clone(&self) -> WithCachedTypeInfo<T> {
        WithCachedTypeInfo {
            internee: ::core::clone::Clone::clone(&self.internee),
            flags: ::core::clone::Clone::clone(&self.flags),
            outer_exclusive_binder: ::core::clone::Clone::clone(&self.outer_exclusive_binder),
        }
    }
}Clone, GenericTypeVisitable)]
15pub struct WithCachedTypeInfo<T> {
16    pub internee: T,
17
18    /// This field provides fast access to information that is also contained
19    /// in `kind`.
20    ///
21    /// This field shouldn't be used directly and may be removed in the future.
22    /// Use `Ty::flags()` instead.
23    pub flags: TypeFlags,
24
25    /// This field provides fast access to information that is also contained
26    /// in `kind`.
27    ///
28    /// This is a kind of confusing thing: it stores the smallest
29    /// binder such that
30    ///
31    /// (a) the binder itself captures nothing but
32    /// (b) all the late-bound things within the type are captured
33    ///     by some sub-binder.
34    ///
35    /// So, for a type without any late-bound things, like `u32`, this
36    /// will be *innermost*, because that is the innermost binder that
37    /// captures nothing. But for a type `&'D u32`, where `'D` is a
38    /// late-bound region with De Bruijn index `D`, this would be `D + 1`
39    /// -- the binder itself does not capture `D`, but `D` is captured
40    /// by an inner binder.
41    ///
42    /// We call this concept an "exclusive" binder `D` because all
43    /// De Bruijn indices within the type are contained within `0..D`
44    /// (exclusive).
45    pub outer_exclusive_binder: DebruijnIndex,
46}
47
48impl<T: PartialEq> PartialEq for WithCachedTypeInfo<T> {
49    #[inline]
50    fn eq(&self, other: &Self) -> bool {
51        self.internee.eq(&other.internee)
52    }
53}
54
55impl<T: Eq> Eq for WithCachedTypeInfo<T> {}
56
57impl<T: Ord> PartialOrd for WithCachedTypeInfo<T> {
58    fn partial_cmp(&self, other: &WithCachedTypeInfo<T>) -> Option<Ordering> {
59        Some(self.internee.cmp(&other.internee))
60    }
61}
62
63impl<T: Ord> Ord for WithCachedTypeInfo<T> {
64    fn cmp(&self, other: &WithCachedTypeInfo<T>) -> Ordering {
65        self.internee.cmp(&other.internee)
66    }
67}
68
69impl<T> Deref for WithCachedTypeInfo<T> {
70    type Target = T;
71
72    #[inline]
73    fn deref(&self) -> &T {
74        &self.internee
75    }
76}
77
78impl<T: Hash> Hash for WithCachedTypeInfo<T> {
79    #[inline]
80    fn hash<H: Hasher>(&self, s: &mut H) {
81        self.internee.hash(s)
82    }
83}
84
85#[cfg(feature = "nightly")]
86impl<T: HashStable> HashStable for WithCachedTypeInfo<T> {
87    fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
88        self.internee.hash_stable(hcx, hasher);
89    }
90}