1use std::cmp::Ordering;
2use std::hash::{Hash, Hasher};
3use std::ops::Deref;
45#[cfg(feature = "nightly")]
6use rustc_data_structures::stable_hasher::{StableHash, StableHashCtxt, StableHasher};
7use rustc_type_ir_macros::GenericTypeVisitable;
89use crate::{DebruijnIndex, TypeFlags};
1011/// 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> {
16pub internee: T,
1718/// 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.
23pub flags: TypeFlags,
2425/// 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).
45pub outer_exclusive_binder: DebruijnIndex,
46}
4748impl<T: PartialEq> PartialEqfor WithCachedTypeInfo<T> {
49#[inline]
50fn eq(&self, other: &Self) -> bool {
51self.internee.eq(&other.internee)
52 }
53}
5455impl<T: Eq> Eqfor WithCachedTypeInfo<T> {}
5657impl<T: Ord> PartialOrdfor WithCachedTypeInfo<T> {
58fn partial_cmp(&self, other: &WithCachedTypeInfo<T>) -> Option<Ordering> {
59Some(self.internee.cmp(&other.internee))
60 }
61}
6263impl<T: Ord> Ordfor WithCachedTypeInfo<T> {
64fn cmp(&self, other: &WithCachedTypeInfo<T>) -> Ordering {
65self.internee.cmp(&other.internee)
66 }
67}
6869impl<T> Dereffor WithCachedTypeInfo<T> {
70type Target = T;
7172#[inline]
73fn deref(&self) -> &T {
74&self.internee
75 }
76}
7778impl<T: Hash> Hashfor WithCachedTypeInfo<T> {
79#[inline]
80fn hash<H: Hasher>(&self, s: &mut H) {
81self.internee.hash(s)
82 }
83}
8485#[cfg(feature = "nightly")]
86impl<T: StableHash> StableHashfor WithCachedTypeInfo<T> {
87fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
88self.internee.stable_hash(hcx, hasher);
89 }
90}