Remove TyS

This commit is contained in:
Oli Scherer 2022-11-25 16:55:25 +00:00
parent 87a04f51ba
commit 147b854ded
6 changed files with 65 additions and 97 deletions

View file

@ -1,3 +1,5 @@
#![allow(rustc::usage_of_ty_tykind)]
/// This higher-order macro declares a list of types which can be allocated by `Arena`.
///
/// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]` where `T` is the type
@ -88,7 +90,7 @@ macro_rules! arena_types {
[] hir_id_set: rustc_hir::HirIdSet,
// Interned types
[] tys: rustc_type_ir::WithCachedTypeInfo<rustc_middle::ty::TyS<'tcx>>,
[] tys: rustc_type_ir::WithCachedTypeInfo<rustc_middle::ty::TyKind<'tcx>>,
[] predicates: rustc_type_ir::WithCachedTypeInfo<rustc_middle::ty::PredicateS<'tcx>>,
[] consts: rustc_middle::ty::ConstS<'tcx>,

View file

@ -1,5 +1,7 @@
//! Type context book-keeping.
#![allow(rustc::usage_of_ty_tykind)]
use crate::arena::Arena;
use crate::dep_graph::{DepGraph, DepKindStruct};
use crate::hir::place::Place as HirPlace;
@ -20,7 +22,7 @@ use crate::ty::{
ClosureSizeProfileData, Const, ConstS, DefIdTree, FloatTy, FloatVar, FloatVid,
GenericParamDefKind, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy,
PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy,
Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut,
Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut,
UintTy, Visibility,
};
use crate::ty::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef, UserSubsts};
@ -137,7 +139,7 @@ pub struct CtxtInterners<'tcx> {
// Specifically use a speedy hash algorithm for these hash sets, since
// they're accessed quite often.
type_: InternedSet<'tcx, WithCachedTypeInfo<TyS<'tcx>>>,
type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
@ -194,15 +196,12 @@ impl<'tcx> CtxtInterners<'tcx> {
let stable_hash =
self.stable_hash(&flags, sess, definitions, cstore, source_span, &kind);
let ty_struct = TyS {
kind,
InternedInSet(self.arena.alloc(WithCachedTypeInfo {
internee: kind,
stable_hash,
flags: flags.flags,
outer_exclusive_binder: flags.outer_exclusive_binder,
};
InternedInSet(
self.arena.alloc(WithCachedTypeInfo { internee: ty_struct, stable_hash }),
)
}))
})
.0,
))
@ -2058,7 +2057,7 @@ macro_rules! sty_debug_print {
let shards = tcx.interners.type_.lock_shards();
let types = shards.iter().flat_map(|shard| shard.keys());
for &InternedInSet(t) in types {
let variant = match t.kind {
let variant = match t.internee {
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
ty::Float(..) | ty::Str | ty::Never => continue,
ty::Error(_) => /* unimportant */ continue,
@ -2168,26 +2167,26 @@ impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
}
#[allow(rustc::usage_of_ty_tykind)]
impl<'tcx> Borrow<TyKind<'tcx>> for InternedInSet<'tcx, WithCachedTypeInfo<TyS<'tcx>>> {
impl<'tcx> Borrow<TyKind<'tcx>> for InternedInSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
&self.0.kind
&self.0.internee
}
}
impl<'tcx> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<TyS<'tcx>>> {
fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<TyS<'tcx>>>) -> bool {
impl<'tcx> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>> {
fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>) -> bool {
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
// `x == y`.
self.0.kind == other.0.kind
self.0.internee == other.0.internee
}
}
impl<'tcx> Eq for InternedInSet<'tcx, WithCachedTypeInfo<TyS<'tcx>>> {}
impl<'tcx> Eq for InternedInSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>> {}
impl<'tcx> Hash for InternedInSet<'tcx, WithCachedTypeInfo<TyS<'tcx>>> {
impl<'tcx> Hash for InternedInSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>> {
fn hash<H: Hasher>(&self, s: &mut H) {
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
self.0.kind.hash(s)
self.0.internee.hash(s)
}
}

View file

@ -9,6 +9,8 @@
//!
//! ["The `ty` module: representing types"]: https://rustc-dev-guide.rust-lang.org/ty.html
#![allow(rustc::usage_of_ty_tykind)]
pub use self::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
pub use self::AssocItemContainer::*;
@ -446,89 +448,24 @@ pub struct CReaderCacheKey {
pub pos: usize,
}
/// Represents a type.
///
/// IMPORTANT:
/// - This is a very "dumb" struct (with no derives and no `impls`).
/// - Values of this type are always interned and thus unique, and are stored
/// as an `Interned<TyS>`.
/// - `Ty` (which contains a reference to a `Interned<TyS>`) or `Interned<TyS>`
/// should be used everywhere instead of `TyS`. In particular, `Ty` has most
/// of the relevant methods.
#[derive(PartialEq, Eq, PartialOrd, Ord)]
#[allow(rustc::usage_of_ty_tykind)]
pub(crate) struct TyS<'tcx> {
/// This field shouldn't be used directly and may be removed in the future.
/// Use `Ty::kind()` instead.
kind: TyKind<'tcx>,
/// This field provides fast access to information that is also contained
/// in `kind`.
///
/// This field shouldn't be used directly and may be removed in the future.
/// Use `Ty::flags()` instead.
flags: TypeFlags,
/// This field provides fast access to information that is also contained
/// in `kind`.
///
/// This is a kind of confusing thing: it stores the smallest
/// binder such that
///
/// (a) the binder itself captures nothing but
/// (b) all the late-bound things within the type are captured
/// by some sub-binder.
///
/// So, for a type without any late-bound things, like `u32`, this
/// will be *innermost*, because that is the innermost binder that
/// captures nothing. But for a type `&'D u32`, where `'D` is a
/// late-bound region with De Bruijn index `D`, this would be `D + 1`
/// -- the binder itself does not capture `D`, but `D` is captured
/// by an inner binder.
///
/// We call this concept an "exclusive" binder `D` because all
/// De Bruijn indices within the type are contained within `0..D`
/// (exclusive).
outer_exclusive_binder: ty::DebruijnIndex,
}
/// Use this rather than `TyS`, whenever possible.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
#[rustc_diagnostic_item = "Ty"]
#[rustc_pass_by_value]
pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyS<'tcx>>>);
pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>);
impl<'tcx> TyCtxt<'tcx> {
/// A "bool" type used in rustc_mir_transform unit tests when we
/// have not spun up a TyCtxt.
pub const BOOL_TY_FOR_UNIT_TESTING: Ty<'tcx> =
Ty(Interned::new_unchecked(&WithCachedTypeInfo {
internee: TyS {
kind: ty::Bool,
flags: TypeFlags::empty(),
outer_exclusive_binder: DebruijnIndex::from_usize(0),
},
internee: ty::Bool,
stable_hash: Fingerprint::ZERO,
flags: TypeFlags::empty(),
outer_exclusive_binder: DebruijnIndex::from_usize(0),
}));
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TyS<'tcx> {
#[inline]
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
let TyS {
kind,
// The other fields just provide fast access to information that is
// also contained in `kind`, so no need to hash them.
flags: _,
outer_exclusive_binder: _,
} = self;
kind.hash_stable(hcx, hasher)
}
}
impl ty::EarlyBoundRegion {
/// Does this early bound region have a name? Early bound regions normally
/// always have names except when using anonymous lifetimes (`'_`).
@ -1030,7 +967,7 @@ impl<'tcx> Term<'tcx> {
unsafe {
match ptr & TAG_MASK {
TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyS<'tcx>>),
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>),
))),
CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
&*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>),
@ -1074,7 +1011,7 @@ impl<'tcx> TermKind<'tcx> {
TermKind::Ty(ty) => {
// Ensure we can use the tag bits.
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
(TYPE_TAG, ty.0.0 as *const WithCachedTypeInfo<ty::TyS<'tcx>> as usize)
(TYPE_TAG, ty.0.0 as *const WithCachedTypeInfo<ty::TyKind<'tcx>> as usize)
}
TermKind::Const(ct) => {
// Ensure we can use the tag bits.
@ -2695,7 +2632,6 @@ mod size_asserts {
use rustc_data_structures::static_assert_size;
// tidy-alphabetical-start
static_assert_size!(PredicateS<'_>, 48);
static_assert_size!(TyS<'_>, 40);
static_assert_size!(WithCachedTypeInfo<TyS<'_>>, 56);
static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 56);
// tidy-alphabetical-end
}

View file

@ -1602,7 +1602,7 @@ impl<'tcx> Region<'tcx> {
impl<'tcx> Ty<'tcx> {
#[inline(always)]
pub fn kind(self) -> &'tcx TyKind<'tcx> {
&self.0.0.kind
&self.0.0
}
#[inline(always)]

View file

@ -85,7 +85,7 @@ impl<'tcx> GenericArgKind<'tcx> {
GenericArgKind::Type(ty) => {
// Ensure we can use the tag bits.
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
(TYPE_TAG, ty.0.0 as *const WithCachedTypeInfo<ty::TyS<'tcx>> as usize)
(TYPE_TAG, ty.0.0 as *const WithCachedTypeInfo<ty::TyKind<'tcx>> as usize)
}
GenericArgKind::Const(ct) => {
// Ensure we can use the tag bits.
@ -163,7 +163,7 @@ impl<'tcx> GenericArg<'tcx> {
&*((ptr & !TAG_MASK) as *const ty::RegionKind<'tcx>),
))),
TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyS<'tcx>>),
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>),
))),
CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
&*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>),

View file

@ -9,9 +9,11 @@ use rustc_data_structures::{
stable_hasher::{HashStable, StableHasher},
};
use crate::{DebruijnIndex, TypeFlags};
/// A helper type that you can wrap round your own type in order to automatically
/// cache the stable hash on creation and not recompute it whenever the stable hash
/// of the type is computed.
/// cache the stable hash, type flags and debruijn index on creation and
/// not recompute it whenever the information is needed.
/// This is only done in incremental mode. You can also opt out of caching by using
/// StableHash::ZERO for the hash, in which case the hash gets computed each time.
/// This is useful if you have values that you intern but never (can?) use for stable
@ -20,6 +22,35 @@ use rustc_data_structures::{
pub struct WithCachedTypeInfo<T> {
pub internee: T,
pub stable_hash: Fingerprint,
/// This field provides fast access to information that is also contained
/// in `kind`.
///
/// This field shouldn't be used directly and may be removed in the future.
/// Use `Ty::flags()` instead.
pub flags: TypeFlags,
/// This field provides fast access to information that is also contained
/// in `kind`.
///
/// This is a kind of confusing thing: it stores the smallest
/// binder such that
///
/// (a) the binder itself captures nothing but
/// (b) all the late-bound things within the type are captured
/// by some sub-binder.
///
/// So, for a type without any late-bound things, like `u32`, this
/// will be *innermost*, because that is the innermost binder that
/// captures nothing. But for a type `&'D u32`, where `'D` is a
/// late-bound region with De Bruijn index `D`, this would be `D + 1`
/// -- the binder itself does not capture `D`, but `D` is captured
/// by an inner binder.
///
/// We call this concept an "exclusive" binder `D` because all
/// De Bruijn indices within the type are contained within `0..D`
/// (exclusive).
pub outer_exclusive_binder: DebruijnIndex,
}
impl<T: PartialEq> PartialEq for WithCachedTypeInfo<T> {