Skip to content

Commit db416ea

Browse files
authored
Rollup merge of #104898 - oli-obk:group_all_the_things, r=wesleywiser
Put all cached values into a central struct instead of just the stable hash cc `@nnethercote` this allows re-use of the type for Predicate without duplicating all the logic for the non-hash cached fields
2 parents b685242 + 14a9cf2 commit db416ea

File tree

10 files changed

+182
-254
lines changed

10 files changed

+182
-254
lines changed

compiler/rustc_data_structures/src/intern.rs

-83
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ use std::hash::{Hash, Hasher};
44
use std::ops::Deref;
55
use std::ptr;
66

7-
use crate::fingerprint::Fingerprint;
8-
97
mod private {
108
#[derive(Clone, Copy, Debug)]
119
pub struct PrivateZst;
@@ -110,86 +108,5 @@ where
110108
}
111109
}
112110

113-
/// A helper type that you can wrap round your own type in order to automatically
114-
/// cache the stable hash on creation and not recompute it whenever the stable hash
115-
/// of the type is computed.
116-
/// This is only done in incremental mode. You can also opt out of caching by using
117-
/// StableHash::ZERO for the hash, in which case the hash gets computed each time.
118-
/// This is useful if you have values that you intern but never (can?) use for stable
119-
/// hashing.
120-
#[derive(Copy, Clone)]
121-
pub struct WithStableHash<T> {
122-
pub internee: T,
123-
pub stable_hash: Fingerprint,
124-
}
125-
126-
impl<T: PartialEq> PartialEq for WithStableHash<T> {
127-
#[inline]
128-
fn eq(&self, other: &Self) -> bool {
129-
self.internee.eq(&other.internee)
130-
}
131-
}
132-
133-
impl<T: Eq> Eq for WithStableHash<T> {}
134-
135-
impl<T: Ord> PartialOrd for WithStableHash<T> {
136-
fn partial_cmp(&self, other: &WithStableHash<T>) -> Option<Ordering> {
137-
Some(self.internee.cmp(&other.internee))
138-
}
139-
}
140-
141-
impl<T: Ord> Ord for WithStableHash<T> {
142-
fn cmp(&self, other: &WithStableHash<T>) -> Ordering {
143-
self.internee.cmp(&other.internee)
144-
}
145-
}
146-
147-
impl<T> Deref for WithStableHash<T> {
148-
type Target = T;
149-
150-
#[inline]
151-
fn deref(&self) -> &T {
152-
&self.internee
153-
}
154-
}
155-
156-
impl<T: Hash> Hash for WithStableHash<T> {
157-
#[inline]
158-
fn hash<H: Hasher>(&self, s: &mut H) {
159-
if self.stable_hash != Fingerprint::ZERO {
160-
self.stable_hash.hash(s)
161-
} else {
162-
self.internee.hash(s)
163-
}
164-
}
165-
}
166-
167-
impl<T: HashStable<CTX>, CTX> HashStable<CTX> for WithStableHash<T> {
168-
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
169-
if self.stable_hash == Fingerprint::ZERO || cfg!(debug_assertions) {
170-
// No cached hash available. This can only mean that incremental is disabled.
171-
// We don't cache stable hashes in non-incremental mode, because they are used
172-
// so rarely that the performance actually suffers.
173-
174-
// We need to build the hash as if we cached it and then hash that hash, as
175-
// otherwise the hashes will differ between cached and non-cached mode.
176-
let stable_hash: Fingerprint = {
177-
let mut hasher = StableHasher::new();
178-
self.internee.hash_stable(hcx, &mut hasher);
179-
hasher.finish()
180-
};
181-
if cfg!(debug_assertions) && self.stable_hash != Fingerprint::ZERO {
182-
assert_eq!(
183-
stable_hash, self.stable_hash,
184-
"cached stable hash does not match freshly computed stable hash"
185-
);
186-
}
187-
stable_hash.hash_stable(hcx, hasher);
188-
} else {
189-
self.stable_hash.hash_stable(hcx, hasher);
190-
}
191-
}
192-
}
193-
194111
#[cfg(test)]
195112
mod tests;

compiler/rustc_lint/src/pass_by_value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ declare_tool_lint! {
1010
/// The `rustc_pass_by_value` lint marks a type with `#[rustc_pass_by_value]` requiring it to
1111
/// always be passed by value. This is usually used for types that are thin wrappers around
1212
/// references, so there is no benefit to an extra layer of indirection. (Example: `Ty` which
13-
/// is a reference to an `Interned<TyS>`)
13+
/// is a reference to an `Interned<TyKind>`)
1414
pub rustc::PASS_BY_VALUE,
1515
Warn,
1616
"pass by reference of a type flagged as `#[rustc_pass_by_value]`",

compiler/rustc_middle/src/arena.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(rustc::usage_of_ty_tykind)]
2+
13
/// This higher-order macro declares a list of types which can be allocated by `Arena`.
24
///
35
/// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]` where `T` is the type
@@ -89,8 +91,8 @@ macro_rules! arena_types {
8991
[] hir_id_set: rustc_hir::HirIdSet,
9092

9193
// Interned types
92-
[] tys: rustc_data_structures::intern::WithStableHash<rustc_middle::ty::TyS<'tcx>>,
93-
[] predicates: rustc_data_structures::intern::WithStableHash<rustc_middle::ty::PredicateS<'tcx>>,
94+
[] tys: rustc_type_ir::WithCachedTypeInfo<rustc_middle::ty::TyKind<'tcx>>,
95+
[] predicates: rustc_type_ir::WithCachedTypeInfo<rustc_middle::ty::PredicateKind<'tcx>>,
9496
[] consts: rustc_middle::ty::ConstS<'tcx>,
9597

9698
// Note that this deliberately duplicates items in the `rustc_hir::arena`,

compiler/rustc_middle/src/mir/interpret/allocation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl hash::Hash for Allocation {
103103
/// Interned types generally have an `Outer` type and an `Inner` type, where
104104
/// `Outer` is a newtype around `Interned<Inner>`, and all the operations are
105105
/// done on `Outer`, because all occurrences are interned. E.g. `Ty` is an
106-
/// outer type and `TyS` is its inner type.
106+
/// outer type and `TyKind` is its inner type.
107107
///
108108
/// Here things are different because only const allocations are interned. This
109109
/// means that both the inner type (`Allocation`) and the outer type

compiler/rustc_middle/src/ty/context.rs

+27-56
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Type context book-keeping.
22
3+
#![allow(rustc::usage_of_ty_tykind)]
4+
35
use crate::arena::Arena;
46
use crate::dep_graph::{DepGraph, DepKindStruct};
57
use crate::hir::place::Place as HirPlace;
@@ -19,15 +21,15 @@ use crate::ty::{
1921
self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
2022
ClosureSizeProfileData, Const, ConstS, DefIdTree, FloatTy, FloatVar, FloatVid,
2123
GenericParamDefKind, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy,
22-
PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy,
23-
Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut,
24-
UintTy, Visibility,
24+
PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, ProjectionTy, Region,
25+
RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, UintTy,
26+
Visibility,
2527
};
2628
use crate::ty::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef, UserSubsts};
2729
use rustc_ast as ast;
2830
use rustc_data_structures::fingerprint::Fingerprint;
2931
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
30-
use rustc_data_structures::intern::{Interned, WithStableHash};
32+
use rustc_data_structures::intern::Interned;
3133
use rustc_data_structures::memmap::Mmap;
3234
use rustc_data_structures::profiling::SelfProfilerRef;
3335
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
@@ -68,6 +70,7 @@ use rustc_span::{Span, DUMMY_SP};
6870
use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx};
6971
use rustc_target::spec::abi;
7072
use rustc_type_ir::sty::TyKind::*;
73+
use rustc_type_ir::WithCachedTypeInfo;
7174
use rustc_type_ir::{DynKind, InternAs, InternIteratorElement, Interner, TypeFlags};
7275

7376
use std::any::Any;
@@ -137,13 +140,13 @@ pub struct CtxtInterners<'tcx> {
137140

138141
// Specifically use a speedy hash algorithm for these hash sets, since
139142
// they're accessed quite often.
140-
type_: InternedSet<'tcx, WithStableHash<TyS<'tcx>>>,
143+
type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
141144
const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
142145
substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
143146
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
144147
region: InternedSet<'tcx, RegionKind<'tcx>>,
145148
poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
146-
predicate: InternedSet<'tcx, WithStableHash<PredicateS<'tcx>>>,
149+
predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
147150
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
148151
projs: InternedSet<'tcx, List<ProjectionKind>>,
149152
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
@@ -194,15 +197,12 @@ impl<'tcx> CtxtInterners<'tcx> {
194197
let stable_hash =
195198
self.stable_hash(&flags, sess, definitions, cstore, source_span, &kind);
196199

197-
let ty_struct = TyS {
198-
kind,
200+
InternedInSet(self.arena.alloc(WithCachedTypeInfo {
201+
internee: kind,
202+
stable_hash,
199203
flags: flags.flags,
200204
outer_exclusive_binder: flags.outer_exclusive_binder,
201-
};
202-
203-
InternedInSet(
204-
self.arena.alloc(WithStableHash { internee: ty_struct, stable_hash }),
205-
)
205+
}))
206206
})
207207
.0,
208208
))
@@ -246,16 +246,12 @@ impl<'tcx> CtxtInterners<'tcx> {
246246
let stable_hash =
247247
self.stable_hash(&flags, sess, definitions, cstore, source_span, &kind);
248248

249-
let predicate_struct = PredicateS {
250-
kind,
249+
InternedInSet(self.arena.alloc(WithCachedTypeInfo {
250+
internee: kind,
251+
stable_hash,
251252
flags: flags.flags,
252253
outer_exclusive_binder: flags.outer_exclusive_binder,
253-
};
254-
255-
InternedInSet(
256-
self.arena
257-
.alloc(WithStableHash { internee: predicate_struct, stable_hash }),
258-
)
254+
}))
259255
})
260256
.0,
261257
))
@@ -2104,7 +2100,7 @@ macro_rules! sty_debug_print {
21042100
let shards = tcx.interners.type_.lock_shards();
21052101
let types = shards.iter().flat_map(|shard| shard.keys());
21062102
for &InternedInSet(t) in types {
2107-
let variant = match t.kind {
2103+
let variant = match t.internee {
21082104
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
21092105
ty::Float(..) | ty::Str | ty::Never => continue,
21102106
ty::Error(_) => /* unimportant */ continue,
@@ -2214,51 +2210,26 @@ impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
22142210
}
22152211

22162212
#[allow(rustc::usage_of_ty_tykind)]
2217-
impl<'tcx> Borrow<TyKind<'tcx>> for InternedInSet<'tcx, WithStableHash<TyS<'tcx>>> {
2218-
fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
2219-
&self.0.kind
2220-
}
2221-
}
2222-
2223-
impl<'tcx> PartialEq for InternedInSet<'tcx, WithStableHash<TyS<'tcx>>> {
2224-
fn eq(&self, other: &InternedInSet<'tcx, WithStableHash<TyS<'tcx>>>) -> bool {
2225-
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2226-
// `x == y`.
2227-
self.0.kind == other.0.kind
2228-
}
2229-
}
2230-
2231-
impl<'tcx> Eq for InternedInSet<'tcx, WithStableHash<TyS<'tcx>>> {}
2232-
2233-
impl<'tcx> Hash for InternedInSet<'tcx, WithStableHash<TyS<'tcx>>> {
2234-
fn hash<H: Hasher>(&self, s: &mut H) {
2235-
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2236-
self.0.kind.hash(s)
2237-
}
2238-
}
2239-
2240-
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>>
2241-
for InternedInSet<'tcx, WithStableHash<PredicateS<'tcx>>>
2242-
{
2243-
fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
2244-
&self.0.kind
2213+
impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2214+
fn borrow<'a>(&'a self) -> &'a T {
2215+
&self.0.internee
22452216
}
22462217
}
22472218

2248-
impl<'tcx> PartialEq for InternedInSet<'tcx, WithStableHash<PredicateS<'tcx>>> {
2249-
fn eq(&self, other: &InternedInSet<'tcx, WithStableHash<PredicateS<'tcx>>>) -> bool {
2219+
impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2220+
fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
22502221
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
22512222
// `x == y`.
2252-
self.0.kind == other.0.kind
2223+
self.0.internee == other.0.internee
22532224
}
22542225
}
22552226

2256-
impl<'tcx> Eq for InternedInSet<'tcx, WithStableHash<PredicateS<'tcx>>> {}
2227+
impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
22572228

2258-
impl<'tcx> Hash for InternedInSet<'tcx, WithStableHash<PredicateS<'tcx>>> {
2229+
impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
22592230
fn hash<H: Hasher>(&self, s: &mut H) {
22602231
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2261-
self.0.kind.hash(s)
2232+
self.0.internee.hash(s)
22622233
}
22632234
}
22642235

0 commit comments

Comments
 (0)