diff options
| -rw-r--r-- | compiler/rustc_data_structures/src/intern.rs | 83 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/arena.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/subst.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_type_ir/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_type_ir/src/ty_info.rs | 91 |
7 files changed, 101 insertions, 88 deletions
diff --git a/compiler/rustc_data_structures/src/intern.rs b/compiler/rustc_data_structures/src/intern.rs index 9985aeaab57..7a320b10b60 100644 --- a/compiler/rustc_data_structures/src/intern.rs +++ b/compiler/rustc_data_structures/src/intern.rs @@ -4,8 +4,6 @@ use std::hash::{Hash, Hasher}; use std::ops::Deref; use std::ptr; -use crate::fingerprint::Fingerprint; - mod private { #[derive(Clone, Copy, Debug)] pub struct PrivateZst; @@ -110,86 +108,5 @@ where } } -/// 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. -/// 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 -/// hashing. -#[derive(Copy, Clone)] -pub struct WithCachedTypeInfo<T> { - pub internee: T, - pub stable_hash: Fingerprint, -} - -impl<T: PartialEq> PartialEq for WithCachedTypeInfo<T> { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.internee.eq(&other.internee) - } -} - -impl<T: Eq> Eq for WithCachedTypeInfo<T> {} - -impl<T: Ord> PartialOrd for WithCachedTypeInfo<T> { - fn partial_cmp(&self, other: &WithCachedTypeInfo<T>) -> Option<Ordering> { - Some(self.internee.cmp(&other.internee)) - } -} - -impl<T: Ord> Ord for WithCachedTypeInfo<T> { - fn cmp(&self, other: &WithCachedTypeInfo<T>) -> Ordering { - self.internee.cmp(&other.internee) - } -} - -impl<T> Deref for WithCachedTypeInfo<T> { - type Target = T; - - #[inline] - fn deref(&self) -> &T { - &self.internee - } -} - -impl<T: Hash> Hash for WithCachedTypeInfo<T> { - #[inline] - fn hash<H: Hasher>(&self, s: &mut H) { - if self.stable_hash != Fingerprint::ZERO { - self.stable_hash.hash(s) - } else { - self.internee.hash(s) - } - } -} - -impl<T: HashStable<CTX>, CTX> HashStable<CTX> for WithCachedTypeInfo<T> { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - if self.stable_hash == Fingerprint::ZERO || cfg!(debug_assertions) { - // No cached hash available. This can only mean that incremental is disabled. - // We don't cache stable hashes in non-incremental mode, because they are used - // so rarely that the performance actually suffers. - - // We need to build the hash as if we cached it and then hash that hash, as - // otherwise the hashes will differ between cached and non-cached mode. - let stable_hash: Fingerprint = { - let mut hasher = StableHasher::new(); - self.internee.hash_stable(hcx, &mut hasher); - hasher.finish() - }; - if cfg!(debug_assertions) && self.stable_hash != Fingerprint::ZERO { - assert_eq!( - stable_hash, self.stable_hash, - "cached stable hash does not match freshly computed stable hash" - ); - } - stable_hash.hash_stable(hcx, hasher); - } else { - self.stable_hash.hash_stable(hcx, hasher); - } - } -} - #[cfg(test)] mod tests; diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 3f3d92d68e3..2cbc381a11a 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -88,8 +88,8 @@ macro_rules! arena_types { [] hir_id_set: rustc_hir::HirIdSet, // Interned types - [] tys: rustc_data_structures::intern::WithCachedTypeInfo<rustc_middle::ty::TyS<'tcx>>, - [] predicates: rustc_data_structures::intern::WithCachedTypeInfo<rustc_middle::ty::PredicateS<'tcx>>, + [] tys: rustc_type_ir::WithCachedTypeInfo<rustc_middle::ty::TyS<'tcx>>, + [] predicates: rustc_type_ir::WithCachedTypeInfo<rustc_middle::ty::PredicateS<'tcx>>, [] consts: rustc_middle::ty::ConstS<'tcx>, // Note that this deliberately duplicates items in the `rustc_hir::arena`, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 3af3444b86c..e1834f1f57a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -27,7 +27,7 @@ use crate::ty::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef, UserSubst use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::intern::{Interned, WithCachedTypeInfo}; +use rustc_data_structures::intern::Interned; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; @@ -67,6 +67,7 @@ use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx}; use rustc_target::spec::abi; use rustc_type_ir::sty::TyKind::*; +use rustc_type_ir::WithCachedTypeInfo; use rustc_type_ir::{DynKind, InternAs, InternIteratorElement, Interner, TypeFlags}; use std::any::Any; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d3cbd2e03cf..c56e1b6e5a0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -32,7 +32,7 @@ use rustc_ast::node_id::NodeMap; use rustc_attr as attr; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_data_structures::intern::{Interned, WithCachedTypeInfo}; +use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_hir as hir; @@ -50,6 +50,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{ExpnId, Span}; use rustc_target::abi::{Align, Integer, IntegerType, VariantIdx}; pub use rustc_target::abi::{ReprFlags, ReprOptions}; +use rustc_type_ir::WithCachedTypeInfo; pub use subst::*; pub use vtable::*; diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index f69035f619f..13fab0068d6 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -6,10 +6,11 @@ use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; use crate::ty::visit::{TypeVisitable, TypeVisitor}; use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; -use rustc_data_structures::intern::{Interned, WithCachedTypeInfo}; +use rustc_data_structures::intern::Interned; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; use rustc_serialize::{self, Decodable, Encodable}; +use rustc_type_ir::WithCachedTypeInfo; use smallvec::SmallVec; use core::intrinsics; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 581993ba7d8..e3f7a1bd033 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -19,9 +19,11 @@ use std::mem::discriminant; pub mod codec; pub mod sty; +pub mod ty_info; pub use codec::*; pub use sty::*; +pub use ty_info::*; /// Needed so we can use #[derive(HashStable_Generic)] pub trait HashStableContext {} diff --git a/compiler/rustc_type_ir/src/ty_info.rs b/compiler/rustc_type_ir/src/ty_info.rs new file mode 100644 index 00000000000..815237a06c0 --- /dev/null +++ b/compiler/rustc_type_ir/src/ty_info.rs @@ -0,0 +1,91 @@ +use std::{ + cmp::Ordering, + hash::{Hash, Hasher}, + ops::Deref, +}; + +use rustc_data_structures::{ + fingerprint::Fingerprint, + stable_hasher::{HashStable, StableHasher}, +}; + +/// 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. +/// 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 +/// hashing. +#[derive(Copy, Clone)] +pub struct WithCachedTypeInfo<T> { + pub internee: T, + pub stable_hash: Fingerprint, +} + +impl<T: PartialEq> PartialEq for WithCachedTypeInfo<T> { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.internee.eq(&other.internee) + } +} + +impl<T: Eq> Eq for WithCachedTypeInfo<T> {} + +impl<T: Ord> PartialOrd for WithCachedTypeInfo<T> { + fn partial_cmp(&self, other: &WithCachedTypeInfo<T>) -> Option<Ordering> { + Some(self.internee.cmp(&other.internee)) + } +} + +impl<T: Ord> Ord for WithCachedTypeInfo<T> { + fn cmp(&self, other: &WithCachedTypeInfo<T>) -> Ordering { + self.internee.cmp(&other.internee) + } +} + +impl<T> Deref for WithCachedTypeInfo<T> { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + &self.internee + } +} + +impl<T: Hash> Hash for WithCachedTypeInfo<T> { + #[inline] + fn hash<H: Hasher>(&self, s: &mut H) { + if self.stable_hash != Fingerprint::ZERO { + self.stable_hash.hash(s) + } else { + self.internee.hash(s) + } + } +} + +impl<T: HashStable<CTX>, CTX> HashStable<CTX> for WithCachedTypeInfo<T> { + fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + if self.stable_hash == Fingerprint::ZERO || cfg!(debug_assertions) { + // No cached hash available. This can only mean that incremental is disabled. + // We don't cache stable hashes in non-incremental mode, because they are used + // so rarely that the performance actually suffers. + + // We need to build the hash as if we cached it and then hash that hash, as + // otherwise the hashes will differ between cached and non-cached mode. + let stable_hash: Fingerprint = { + let mut hasher = StableHasher::new(); + self.internee.hash_stable(hcx, &mut hasher); + hasher.finish() + }; + if cfg!(debug_assertions) && self.stable_hash != Fingerprint::ZERO { + assert_eq!( + stable_hash, self.stable_hash, + "cached stable hash does not match freshly computed stable hash" + ); + } + stable_hash.hash_stable(hcx, hasher); + } else { + self.stable_hash.hash_stable(hcx, hasher); + } + } +} |
