From c1154708c4764cee92dcf52afa7b48f8e2b2b8d6 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 28 Jan 2022 18:01:14 -0500 Subject: [PATCH 01/18] Get some stuff compiling --- compiler/rustc_ast/src/ast.rs | 8 ++ compiler/rustc_ast/src/token.rs | 2 + compiler/rustc_ast/src/tokenstream.rs | 1 + .../src/stable_hasher.rs | 66 ++++++++++++ compiler/rustc_macros/src/hash_stable.rs | 101 +++++++++++++++++- compiler/rustc_macros/src/lib.rs | 1 + .../rustc_query_system/src/query/caches.rs | 32 +++--- .../rustc_query_system/src/query/plumbing.rs | 45 +++++--- compiler/rustc_span/src/def_id.rs | 8 +- compiler/rustc_span/src/hygiene.rs | 8 +- compiler/rustc_span/src/span_encoding.rs | 2 +- compiler/rustc_span/src/symbol.rs | 8 +- 12 files changed, 246 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index e9135b7163025..2ef2ada1969a0 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -521,6 +521,7 @@ pub struct Crate { /// /// E.g., the '..' in `#[name(..)]`. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum NestedMetaItem { /// A full MetaItem, for recursive meta items. MetaItem(MetaItem), @@ -534,6 +535,7 @@ pub enum NestedMetaItem { /// /// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct MetaItem { pub path: Path, pub kind: MetaItemKind, @@ -544,6 +546,7 @@ pub struct MetaItem { /// /// E.g., `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum MetaItemKind { /// Word meta item. /// @@ -1527,6 +1530,7 @@ impl MacCall { /// Arguments passed to an attribute or a function-like macro. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum MacArgs { /// No arguments - `#[attr]`. Empty, @@ -1602,6 +1606,7 @@ impl MacDelimiter { /// Represents a macro definition. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct MacroDef { pub body: P, /// `true` if macro was defined with `macro_rules`. @@ -1621,6 +1626,7 @@ pub enum StrStyle { /// An AST literal. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Lit { /// The original literal token as written in source code. pub token: token::Lit, @@ -2021,6 +2027,7 @@ bitflags::bitflags! { } #[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum InlineAsmTemplatePiece { String(String), Placeholder { operand_idx: usize, modifier: Option, span: Span }, @@ -2425,6 +2432,7 @@ impl rustc_serialize::Decodable for AttrId { } #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct AttrItem { pub path: Path, pub args: MacArgs, diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index db066d7c6a519..b65dc4083e9ca 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -178,6 +178,7 @@ fn ident_can_begin_type(name: Symbol, span: Span, is_raw: bool) -> bool { } #[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum TokenKind { /* Expression-operator symbols. */ Eq, @@ -246,6 +247,7 @@ pub enum TokenKind { rustc_data_structures::static_assert_size!(TokenKind, 16); #[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Token { pub kind: TokenKind, pub span: Span, diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 2174378a560d3..822b7ddf381a2 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -38,6 +38,7 @@ use std::{fmt, iter, mem}; /// The RHS of an MBE macro is the only place `SubstNt`s are substituted. /// Nothing special happens to misnamed or misplaced `SubstNt`s. #[derive(Debug, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum TokenTree { /// A single token. Token(Token), diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 31d6a42cf2884..5a855f32c0fd1 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -199,6 +199,10 @@ pub trait HashStable { fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher); } +pub trait HashStableEq { + fn hash_stable_eq(&self, other: &Self) -> bool; +} + /// Implement this for types that can be turned into stable keys like, for /// example, for DefId that can be converted to a DefPathHash. This is used for /// bringing maps into a predictable order before hashing them. @@ -218,6 +222,13 @@ macro_rules! impl_stable_hash_via_hash { ::std::hash::Hash::hash(self, hasher); } } + + impl $crate::stable_hasher::HashStableEq for $t { + #[inline] + fn hash_stable_eq(&self, other: &Self) -> bool { + self == other + } + } }; } @@ -322,6 +333,24 @@ where } } +impl HashStableEq for [T] { + fn hash_stable_eq(&self, other: &Self) -> bool { + for (first, second) in self.iter().zip(other.iter()) { + if !first.hash_stable_eq(second) { + return false; + } + } + true + } +} + +impl HashStableEq for [T; N] { + fn hash_stable_eq(&self, other: &Self) -> bool { + (self[..]).hash_stable_eq(other) + } +} + + impl, CTX> HashStable for [T] { default fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { self.len().hash_stable(ctx, hasher); @@ -331,6 +360,15 @@ impl, CTX> HashStable for [T] { } } +impl, CTX, const N: usize> HashStable for [T; N] { + default fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + self.len().hash_stable(ctx, hasher); + for item in self { + item.hash_stable(ctx, hasher); + } + } +} + impl HashStable for [u8] { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { self.len().hash_stable(ctx, hasher); @@ -405,6 +443,18 @@ impl, CTX> HashStable for ::std::sync::Arc { } } +impl HashStableEq for ::std::rc::Rc { + fn hash_stable_eq(&self, other: &Self) -> bool { + (**self).hash_stable_eq(other) + } +} + +impl HashStableEq for ::std::sync::Arc { + fn hash_stable_eq(&self, other: &Self) -> bool { + (**self).hash_stable_eq(other) + } +} + impl HashStable for str { #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { @@ -434,6 +484,22 @@ impl HashStable for bool { } } +impl HashStableEq for Option { + fn hash_stable_eq(&self, other: &Self) -> bool { + match (self, other) { + (Some(first), Some(second)) => first.hash_stable_eq(second), + (None, None) => true, + _ => false + } + } +} + +impl HashStableEq for bool { + fn hash_stable_eq(&self, other: &Self) -> bool { + self == other + } +} + impl HashStable for Option where T: HashStable, diff --git a/compiler/rustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs index 63bdcea87f817..6a7a8199a206b 100644 --- a/compiler/rustc_macros/src/hash_stable.rs +++ b/compiler/rustc_macros/src/hash_stable.rs @@ -41,7 +41,27 @@ fn parse_attributes(field: &syn::Field) -> Attributes { attrs } +fn no_hash_stable_eq(s: &synstructure::Structure<'_>) -> bool { + for attr in &s.ast().attrs { + if let Ok(meta) = attr.parse_meta() { + if !meta.path().is_ident("stable_hasher") { + continue; + } + let arg: syn::Ident = attr.parse_args().unwrap(); + if arg.to_string() == "no_hash_stable_eq" { + return true; + } else { + panic!("Unexpected argument {:?}", arg); + } + } + } + return false; +} + pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + let orig = s.clone(); + let no_eq = no_hash_stable_eq(&orig); + let generic: syn::GenericParam = parse_quote!(__CTX); s.add_bounds(synstructure::AddBounds::Generics); s.add_impl_generic(generic); @@ -61,6 +81,7 @@ pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_ma } }); + let discriminant = match s.ast().data { syn::Data::Enum(_) => quote! { ::std::mem::discriminant(self).hash_stable(__hcx, __hasher); @@ -69,7 +90,7 @@ pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_ma syn::Data::Union(_) => panic!("cannot derive on union"), }; - s.bound_impl( + let impl_body = s.bound_impl( quote!(::rustc_data_structures::stable_hasher::HashStable<__CTX>), quote! { #[inline] @@ -81,10 +102,72 @@ pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_ma match *self { #body } } }, - ) + ); + + if no_eq { + impl_body + } else { + let eq_impl = hash_stable_eq_derive(orig); + //println!("Eq impl:\n{}", eq_impl); + quote! { + #impl_body + #eq_impl + } + } +} + +pub fn hash_stable_eq_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + let mut other = s.clone(); + other.binding_name(|_bi, i| Ident::new(&format!("__binding_other_{}", i), proc_macro2::Span::call_site())); + + let eq_body: proc_macro2::TokenStream = s.variants().iter().zip(other.variants()).map(|(variant1, variant2)| { + + let first_pat = variant1.pat(); + let second_pat = variant2.pat(); + + let compare = std::iter::once(quote! { true }).chain(variant1.bindings().iter().zip(variant2.bindings()).map(|(binding1, binding2)| { + let attrs = parse_attributes(binding1.ast()); + if attrs.ignore { + quote! { true } + } else if let Some(project) = attrs.project { + quote! { + ::rustc_data_structures::stable_hasher::HashStableEq::hash_stable_eq( + #binding1.#project, #binding2.#project + ) + } + } else { + quote! { + ::rustc_data_structures::stable_hasher::HashStableEq::hash_stable_eq( + #binding1, #binding2 + ) + } + } + })); + quote! { + (#first_pat, #second_pat) => { + #(#compare)&&* + } + } + }).collect(); + + s.add_bounds(synstructure::AddBounds::Generics); + s.bound_impl( + quote!(::rustc_data_structures::stable_hasher::HashStableEq), + quote! { + fn hash_stable_eq(&self, other: &Self) -> bool { + match (self, other) { + #eq_body + _ => false + } + } + } + ) } pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + let orig = s.clone(); + let no_eq = no_hash_stable_eq(&orig); + let generic: syn::GenericParam = parse_quote!('__ctx); s.add_bounds(synstructure::AddBounds::Generics); s.add_impl_generic(generic); @@ -111,7 +194,7 @@ pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::To syn::Data::Union(_) => panic!("cannot derive on union"), }; - s.bound_impl( + let impl_body = s.bound_impl( quote!( ::rustc_data_structures::stable_hasher::HashStable< ::rustc_query_system::ich::StableHashingContext<'__ctx>, @@ -127,5 +210,15 @@ pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::To match *self { #body } } }, - ) + ); + + if no_eq { + impl_body + } else { + let eq_impl = hash_stable_eq_derive(orig); + quote! { + #impl_body + #eq_impl + } + } } diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 152ae159aed44..b3ce685ad7551 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -25,6 +25,7 @@ pub fn symbols(input: TokenStream) -> TokenStream { } decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive); +decl_derive!([HashStableEq, attributes(stable_hasher)] => hash_stable::hash_stable_eq_derive); decl_derive!( [HashStable_Generic, attributes(stable_hasher)] => hash_stable::hash_stable_generic_derive diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 011c2ceebb714..655c6efb117c1 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -1,10 +1,12 @@ use crate::dep_graph::DepNodeIndex; +use crate::query::HashStableKey; use crate::query::plumbing::{QueryCacheStore, QueryLookup}; use rustc_arena::TypedArena; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sharded::Sharded; use rustc_data_structures::sync::WorkerLocal; +use rustc_data_structures::stable_hasher::HashStableEq; use std::default::Default; use std::fmt::Debug; use std::hash::Hash; @@ -24,7 +26,7 @@ pub trait QueryStorage { } pub trait QueryCache: QueryStorage + Sized { - type Key: Hash + Eq + Clone + Debug; + type Key: Hash + HashStableEq + Clone + Debug; type Sharded: Default; /// Checks if the query is already computed and in the cache. @@ -58,7 +60,7 @@ pub trait QueryCache: QueryStorage + Sized { pub struct DefaultCacheSelector; -impl CacheSelector for DefaultCacheSelector { +impl CacheSelector for DefaultCacheSelector { type Cache = DefaultCache; } @@ -70,7 +72,7 @@ impl Default for DefaultCache { } } -impl QueryStorage for DefaultCache { +impl QueryStorage for DefaultCache { type Value = V; type Stored = V; @@ -83,11 +85,11 @@ impl QueryStorage for DefaultCache { impl QueryCache for DefaultCache where - K: Eq + Hash + Clone + Debug, + K: HashStableEq + Hash + Clone + Debug, V: Clone + Debug, { type Key = K; - type Sharded = FxHashMap; + type Sharded = FxHashMap, (V, DepNodeIndex)>; #[inline(always)] fn lookup<'s, R, OnHit>( @@ -100,7 +102,7 @@ where OnHit: FnOnce(&V, DepNodeIndex) -> R, { let (lookup, lock) = state.get_lookup(key); - let result = lock.raw_entry().from_key_hashed_nocheck(lookup.key_hash, key); + let result = lock.raw_entry().from_key_hashed_nocheck(lookup.key_hash, HashStableKey::from_ref(key)); if let Some((_, value)) = result { let hit_result = on_hit(&value.0, value.1); @@ -118,7 +120,7 @@ where value: V, index: DepNodeIndex, ) -> Self::Stored { - lock_sharded_storage.insert(key, (value.clone(), index)); + lock_sharded_storage.insert(HashStableKey(key), (value.clone(), index)); value } @@ -130,7 +132,7 @@ where let shards = shards.lock_shards(); for shard in shards.iter() { for (k, v) in shard.iter() { - f(k, &v.0, v.1); + f(&k.0, &v.0, v.1); } } } @@ -138,7 +140,7 @@ where pub struct ArenaCacheSelector<'tcx>(PhantomData<&'tcx ()>); -impl<'tcx, K: Eq + Hash, V: 'tcx> CacheSelector for ArenaCacheSelector<'tcx> { +impl<'tcx, K: HashStableEq + Hash, V: 'tcx> CacheSelector for ArenaCacheSelector<'tcx> { type Cache = ArenaCache<'tcx, K, V>; } @@ -153,7 +155,7 @@ impl<'tcx, K, V> Default for ArenaCache<'tcx, K, V> { } } -impl<'tcx, K: Eq + Hash, V: Debug + 'tcx> QueryStorage for ArenaCache<'tcx, K, V> { +impl<'tcx, K: HashStableEq + Hash, V: Debug + 'tcx> QueryStorage for ArenaCache<'tcx, K, V> { type Value = V; type Stored = &'tcx V; @@ -167,11 +169,11 @@ impl<'tcx, K: Eq + Hash, V: Debug + 'tcx> QueryStorage for ArenaCache<'tcx, K, V impl<'tcx, K, V: 'tcx> QueryCache for ArenaCache<'tcx, K, V> where - K: Eq + Hash + Clone + Debug, + K: HashStableEq + Hash + Clone + Debug, V: Debug, { type Key = K; - type Sharded = FxHashMap; + type Sharded = FxHashMap, &'tcx (V, DepNodeIndex)>; #[inline(always)] fn lookup<'s, R, OnHit>( @@ -184,7 +186,7 @@ where OnHit: FnOnce(&&'tcx V, DepNodeIndex) -> R, { let (lookup, lock) = state.get_lookup(key); - let result = lock.raw_entry().from_key_hashed_nocheck(lookup.key_hash, key); + let result = lock.raw_entry().from_key_hashed_nocheck(lookup.key_hash, HashStableKey::from_ref(key)); if let Some((_, value)) = result { let hit_result = on_hit(&&value.0, value.1); @@ -204,7 +206,7 @@ where ) -> Self::Stored { let value = self.arena.alloc((value, index)); let value = unsafe { &*(value as *const _) }; - lock_sharded_storage.insert(key, value); + lock_sharded_storage.insert(HashStableKey(key), value); &value.0 } @@ -216,7 +218,7 @@ where let shards = shards.lock_shards(); for shard in shards.iter() { for (k, v) in shard.iter() { - f(k, &v.0, v.1); + f(&k.0, &v.0, v.1); } } } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 77e1fd3f2ccbb..a2cf9cb8b4e9c 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -14,6 +14,7 @@ use rustc_data_structures::profiling::TimingGuard; use rustc_data_structures::sharded::{get_shard_index_by_hash, Sharded}; use rustc_data_structures::sync::{Lock, LockGuard}; use rustc_data_structures::thin_vec::ThinVec; +use rustc_data_structures::stable_hasher::HashStableEq; use rustc_errors::{DiagnosticBuilder, FatalError}; use rustc_session::Session; use rustc_span::{Span, DUMMY_SP}; @@ -70,6 +71,24 @@ struct QueryStateShard { active: FxHashMap, } +#[derive(Copy, Clone, Hash)] +#[repr(transparent)] +pub struct HashStableKey(pub K); + +impl HashStableKey { + pub fn from_ref(val: &K) -> &HashStableKey { + unsafe { std::mem::transmute(val) } + } +} + +impl PartialEq for HashStableKey { + fn eq(&self, other: &Self) -> bool { + self.0.hash_stable_eq(&other.0) + } +} + +impl Eq for HashStableKey {} + impl Default for QueryStateShard { fn default() -> QueryStateShard { QueryStateShard { active: Default::default() } @@ -92,7 +111,7 @@ enum QueryResult { impl QueryState where - K: Eq + Hash + Clone + Debug, + K: Clone + Debug, { pub fn all_inactive(&self) -> bool { let shards = self.shards.lock_shards(); @@ -111,7 +130,7 @@ where for shard in shards.iter() { for (k, v) in shard.active.iter() { if let QueryResult::Started(ref job) = *v { - let query = make_query(tcx, k.clone()); + let query = make_query(tcx, k.0.clone()); jobs.insert(job.id, QueryJobInfo { query, job: job.clone() }); } } @@ -131,7 +150,7 @@ impl Default for QueryState { /// This will poison the relevant query if dropped. struct JobOwner<'tcx, K> where - K: Eq + Hash + Clone, + K: HashStableEq + Hash + Clone, { state: &'tcx QueryState, key: K, @@ -158,7 +177,7 @@ where impl<'tcx, K> JobOwner<'tcx, K> where - K: Eq + Hash + Clone, + K: HashStableEq + Hash + Clone, { /// Either gets a `JobOwner` corresponding the query, allowing us to /// start executing the query, or returns with the result of the query. @@ -183,13 +202,13 @@ where let mut state_lock = state.shards.get_shard_by_index(shard).lock(); let lock = &mut *state_lock; - match lock.active.entry(key) { + match lock.active.entry(HashStableKey(key)) { Entry::Vacant(entry) => { let id = tcx.next_job_id(); let job = tcx.current_query_job(); let job = QueryJob::new(id, span, job); - let key = entry.key().clone(); + let key = entry.key().0.clone(); entry.insert(QueryResult::Started(job)); let owner = JobOwner { state, id, key }; @@ -256,11 +275,11 @@ where mem::forget(self); let (job, result) = { - let key_hash = hash_for_shard(&key); + let key_hash = hash_for_shard(HashStableKey::from_ref(&key)); let shard = get_shard_index_by_hash(key_hash); let job = { let mut lock = state.shards.get_shard_by_index(shard).lock(); - match lock.active.remove(&key).unwrap() { + match lock.active.remove(HashStableKey::from_ref(&key)).unwrap() { QueryResult::Started(job) => job, QueryResult::Poisoned => panic!(), } @@ -279,21 +298,21 @@ where impl<'tcx, K> Drop for JobOwner<'tcx, K> where - K: Eq + Hash + Clone, + K: HashStableEq + Hash + Clone, { #[inline(never)] #[cold] fn drop(&mut self) { // Poison the query so jobs waiting on it panic. let state = self.state; - let shard = state.shards.get_shard_by_value(&self.key); + let shard = state.shards.get_shard_by_value(HashStableKey::from_ref(&self.key)); let job = { let mut shard = shard.lock(); - let job = match shard.active.remove(&self.key).unwrap() { + let job = match shard.active.remove(HashStableKey::from_ref(&self.key)).unwrap() { QueryResult::Started(job) => job, QueryResult::Poisoned => panic!(), }; - shard.active.insert(self.key.clone(), QueryResult::Poisoned); + shard.active.insert(HashStableKey(self.key.clone()), QueryResult::Poisoned); job }; // Also signal the completion of the job, so waiters @@ -312,7 +331,7 @@ pub(crate) struct CycleError { /// The result of `try_start`. enum TryGetJob<'tcx, K> where - K: Eq + Hash + Clone, + K: HashStableEq + Hash + Clone, { /// The query is not yet started. Contains a guard to the cache eventually used to start it. NotYetStarted(JobOwner<'tcx, K>), diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 147c1f9e04339..ac757973e86fb 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -1,6 +1,6 @@ use crate::HashStableContext; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey, HashStableEq}; use rustc_data_structures::AtomicRef; use rustc_index::vec::Idx; use rustc_macros::HashStable_Generic; @@ -234,6 +234,12 @@ pub struct DefId { pub index: DefIndex, } +impl HashStableEq for DefId { + fn hash_stable_eq(&self, other: &Self) -> bool { + self == other + } +} + // On 64-bit systems, we can hash the whole `DefId` as one `u64` instead of two `u32`s. This // improves performance without impairing `FxHash` quality. So the below code gets compiled to a // noop on little endian systems because the memory layout of `DefId` is as follows: diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 8265eb23c3db4..5845c1bce324a 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -33,7 +33,7 @@ use crate::def_id::{CrateNum, DefId, StableCrateId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::HashingControls; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, HashStableEq}; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_data_structures::unhash::UnhashMap; use rustc_index::vec::IndexVec; @@ -74,6 +74,12 @@ pub struct ExpnId { pub local_id: ExpnIndex, } +impl HashStableEq for ExpnId { + fn hash_stable_eq(&self, other: &Self) -> bool { + self == other + } +} + impl fmt::Debug for ExpnId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Generate crate_::{{expn_}}. diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 61e4074a7c80b..cef7891cb44ba 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -60,7 +60,7 @@ use rustc_data_structures::fx::FxIndexSet; /// the dependency to the parent definition's span. This is performed /// using the callback `SPAN_TRACK` to access the query engine. /// -#[derive(Clone, Copy, Eq, PartialEq, Hash)] +#[derive(Clone, Copy, Eq, PartialEq, Hash, HashStableEq)] // FIXME(@lcnr): Enable this attribute once the bootstrap // compiler knows of `rustc_pass_by_value`. // diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 33140911f91c6..174cd6a0d7690 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -4,7 +4,7 @@ use rustc_arena::DroplessArena; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey, HashStableEq}; use rustc_data_structures::sync::Lock; use rustc_macros::HashStable_Generic; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -1710,6 +1710,12 @@ impl fmt::Display for MacroRulesNormalizedIdent { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Symbol(SymbolIndex); +impl HashStableEq for Symbol { + fn hash_stable_eq(&self, other: &Self) -> bool { + self == other + } +} + rustc_index::newtype_index! { struct SymbolIndex { .. } } From bb35981ef1526d9a0dfc26240ce20bba7d19a0e0 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 28 Jan 2022 18:11:24 -0500 Subject: [PATCH 02/18] Keep going --- .../src/stable_hasher.rs | 36 +++++++++++++++++++ compiler/rustc_target/src/abi/call/mod.rs | 2 ++ compiler/rustc_target/src/abi/mod.rs | 4 +++ 3 files changed, 42 insertions(+) diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 5a855f32c0fd1..0a5e1d7ba66ae 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -268,6 +268,12 @@ impl HashStable for ::std::num::NonZeroUsize { } } +impl HashStableEq for ::std::num::NonZeroUsize { + fn hash_stable_eq(&self, other: &Self) -> bool { + self.get().hash_stable_eq(&other.get()) + } +} + impl HashStable for f32 { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { let val: u32 = unsafe { ::std::mem::transmute(*self) }; @@ -335,6 +341,9 @@ where impl HashStableEq for [T] { fn hash_stable_eq(&self, other: &Self) -> bool { + if self.len() != other.len() { + return false; + } for (first, second) in self.iter().zip(other.iter()) { if !first.hash_stable_eq(second) { return false; @@ -383,6 +392,13 @@ impl, CTX> HashStable for Vec { } } +impl HashStableEq for Vec { + #[inline] + fn hash_stable_eq(&self, other: &Self) -> bool { + (&self[..]).hash_stable_eq(other) + } +} + impl HashStable for indexmap::IndexMap where K: HashStable + Eq + Hash, @@ -469,6 +485,20 @@ impl HashStable for String { } } +impl HashStableEq for str { + #[inline] + fn hash_stable_eq(&self, other: &Self) -> bool { + self.as_bytes().hash_stable_eq(other.as_bytes()) + } +} + +impl HashStableEq for String { + #[inline] + fn hash_stable_eq(&self, other: &Self) -> bool { + (&self[..]).hash_stable_eq(other) + } +} + impl ToStableHashKey for String { type KeyType = String; #[inline] @@ -570,6 +600,12 @@ where } } +impl HashStableEq for vec::IndexVec { + fn hash_stable_eq(&self, other: &Self) -> bool { + self.iter().as_slice().hash_stable_eq(other.iter().as_slice()) + } +} + impl HashStable for bit_set::BitSet { fn hash_stable(&self, _ctx: &mut CTX, hasher: &mut StableHasher) { ::std::hash::Hash::hash(self, hasher); diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 34324a582977d..1927e54c94c3c 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -462,6 +462,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { /// Information about how to pass an argument to, /// or return a value from, a function, under some ABI. #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct ArgAbi<'a, Ty> { pub layout: TyAndLayout<'a, Ty>, @@ -608,6 +609,7 @@ pub enum Conv { /// I will do my best to describe this structure, but these /// comments are reverse-engineered and may be inaccurate. -NDM #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct FnAbi<'a, Ty> { /// The LLVM types of each argument. pub args: Vec>, diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 7f1fd28b30df8..bc601634aceb1 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1027,6 +1027,7 @@ rustc_index::newtype_index! { } #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum Variants { /// Single enum variants, structs/tuples, unions, and all non-ADTs. Single { index: VariantIdx }, @@ -1046,6 +1047,7 @@ pub enum Variants { } #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum TagEncoding { /// The tag directly stores the discriminant, but possibly with a smaller layout /// (so converting the tag to the discriminant can require sign extension). @@ -1150,6 +1152,7 @@ impl Niche { } #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Layout { /// Says where the fields are located within the layout. pub fields: FieldsShape, @@ -1204,6 +1207,7 @@ impl Layout { /// layouts for which Rust types do not exist, such as enum variants /// or synthetic fields of enums (i.e., discriminants) and fat pointers. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct TyAndLayout<'a, Ty> { pub ty: Ty, pub layout: &'a Layout, From 34187e49d1eb07b047cef1ad9f1432b4558b0ee9 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 28 Jan 2022 18:31:53 -0500 Subject: [PATCH 03/18] Keep going --- compiler/rustc_ast/src/ptr.rs | 1 + .../src/stable_hasher.rs | 29 +++++++++++++++++++ compiler/rustc_hir/src/hir.rs | 24 +++++++-------- compiler/rustc_hir/src/lang_items.rs | 3 +- compiler/rustc_hir/src/stable_hash_impls.rs | 8 ++++- compiler/rustc_span/src/def_id.rs | 3 +- 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs index 70dbda8222445..6c3c2eb23b855 100644 --- a/compiler/rustc_ast/src/ptr.rs +++ b/compiler/rustc_ast/src/ptr.rs @@ -30,6 +30,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; /// An owned smart pointer. +#[derive(HashStableEq)] pub struct P { ptr: Box, } diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 0a5e1d7ba66ae..0458d6f84b66a 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -232,6 +232,17 @@ macro_rules! impl_stable_hash_via_hash { }; } +#[macro_export] +macro_rules! impl_hash_stable_eq_via_eq { + ($t:ty) => { + impl ::rustc_data_structures::stable_hasher::HashStableEq for $t { + fn hash_stable_eq(&self, other: &Self) -> bool { + self == other + } + } + } +} + impl_stable_hash_via_hash!(i8); impl_stable_hash_via_hash!(i16); impl_stable_hash_via_hash!(i32); @@ -294,6 +305,12 @@ impl HashStable for ::std::cmp::Ordering { } } +impl HashStableEq for (T1, T2) { + fn hash_stable_eq(&self, other: &Self) -> bool { + self.0.hash_stable_eq(&other.0) && self.1.hash_stable_eq(&other.1) + } +} + impl, CTX> HashStable for (T1,) { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { let (ref _0,) = *self; @@ -445,6 +462,12 @@ impl, CTX> HashStable for Box { } } +impl HashStableEq for Box { + fn hash_stable_eq(&self, other: &Self) -> bool { + (**self).hash_stable_eq(other) + } +} + impl, CTX> HashStable for ::std::rc::Rc { #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { @@ -570,6 +593,12 @@ where } } +impl<'a, T: HashStableEq + ?Sized> HashStableEq for &'a T { + fn hash_stable_eq(&self, other: &Self) -> bool { + (**self).hash_stable_eq(other) + } +} + impl HashStable for ::std::mem::Discriminant { #[inline] fn hash_stable(&self, _: &mut CTX, hasher: &mut StableHasher) { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 0961d0131d07c..430e845c717f2 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1243,7 +1243,7 @@ pub enum UnsafeSource { UserProvided, } -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug, HashStableEq)] pub struct BodyId { pub hir_id: HirId, } @@ -1476,7 +1476,7 @@ pub struct AnonConst { } /// An expression. -#[derive(Debug)] +#[derive(Debug, HashStableEq)] pub struct Expr<'hir> { pub hir_id: HirId, pub kind: ExprKind<'hir>, @@ -2029,7 +2029,7 @@ pub struct FnSig<'hir> { // The bodies for items are stored "out of line", in a separate // hashmap in the `Crate`. Here we just record the hir-id of the item // so it can fetched later. -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStableEq)] pub struct TraitItemId { pub def_id: LocalDefId, } @@ -2046,7 +2046,7 @@ impl TraitItemId { /// possibly including a default implementation. A trait item is /// either required (meaning it doesn't have an implementation, just a /// signature) or provided (meaning it has a default implementation). -#[derive(Debug)] +#[derive(Debug, HashStableEq)] pub struct TraitItem<'hir> { pub ident: Ident, pub def_id: LocalDefId, @@ -2092,7 +2092,7 @@ pub enum TraitItemKind<'hir> { // The bodies for items are stored "out of line", in a separate // hashmap in the `Crate`. Here we just record the hir-id of the item // so it can fetched later. -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStableEq)] pub struct ImplItemId { pub def_id: LocalDefId, } @@ -2106,7 +2106,7 @@ impl ImplItemId { } /// Represents anything within an `impl` block. -#[derive(Debug)] +#[derive(Debug, HashStableEq)] pub struct ImplItem<'hir> { pub ident: Ident, pub def_id: LocalDefId, @@ -2209,7 +2209,7 @@ impl TypeBinding<'_> { } } -#[derive(Debug)] +#[derive(Debug, HashStableEq)] pub struct Ty<'hir> { pub hir_id: HirId, pub kind: TyKind<'hir>, @@ -2607,7 +2607,7 @@ pub struct PolyTraitRef<'hir> { pub type Visibility<'hir> = Spanned>; -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, HashStableEq)] pub enum VisibilityKind<'hir> { Public, Crate(CrateSugar), @@ -2683,7 +2683,7 @@ impl<'hir> VariantData<'hir> { // The bodies for items are stored "out of line", in a separate // hashmap in the `Crate`. Here we just record the hir-id of the item // so it can fetched later. -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, Hash, HashStableEq)] pub struct ItemId { pub def_id: LocalDefId, } @@ -2699,7 +2699,7 @@ impl ItemId { /// An item /// /// The name might be a dummy name in case of anonymous items -#[derive(Debug)] +#[derive(Debug, HashStableEq)] pub struct Item<'hir> { pub ident: Ident, pub def_id: LocalDefId, @@ -2926,7 +2926,7 @@ pub enum AssocItemKind { // The bodies for items are stored "out of line", in a separate // hashmap in the `Crate`. Here we just record the hir-id of the item // so it can fetched later. -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStableEq)] pub struct ForeignItemId { pub def_id: LocalDefId, } @@ -2952,7 +2952,7 @@ pub struct ForeignItemRef { pub span: Span, } -#[derive(Debug)] +#[derive(Debug, HashStableEq)] pub struct ForeignItem<'hir> { pub ident: Ident, pub kind: ForeignItemKind<'hir>, diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index b299e71c9c4c4..71329b05a1560 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -44,7 +44,7 @@ macro_rules! language_item_table { enum_from_u32! { /// A representation of all the valid language items in Rust. - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, HashStableEq)] pub enum LangItem { $( #[doc = concat!("The `", stringify!($name), "` lang item.")] @@ -84,6 +84,7 @@ macro_rules! language_item_table { /// All of the language items, defined or not. /// Defined lang items can come from the current crate or its dependencies. #[derive(HashStable_Generic, Debug)] + #[stable_hasher(no_hash_stable_eq)] pub struct LanguageItems { /// Mappings from lang items to their possibly found [`DefId`]s. /// The index corresponds to the order in [`LangItem`]. diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 61f03442d61f2..199576fbb40bd 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey, HashStableEq}; use crate::hir::{ AttributeMap, BodyId, Crate, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, @@ -33,6 +33,12 @@ impl ToStableHashKey for HirId { } } +impl HashStableEq for HirId { + fn hash_stable_eq(&self, other: &HirId) -> bool { + self == other + } +} + impl ToStableHashKey for ItemLocalId { type KeyType = ItemLocalId; diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index ac757973e86fb..c167ec2bf3dcd 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -192,6 +192,7 @@ rustc_index::newtype_index! { /// A DefIndex is an index into the hir-map for a crate, identifying a /// particular definition. It should really be considered an interned /// shorthand for a particular DefPath. + #[derive(HashStableEq)] pub struct DefIndex { ENCODABLE = custom // (only encodable in metadata) @@ -333,7 +334,7 @@ rustc_data_structures::define_id_collections!(DefIdMap, DefIdSet, DefId); /// few cases where we know that only `DefId`s from the local crate are expected; /// a `DefId` from a different crate would signify a bug somewhere. This /// is when `LocalDefId` comes in handy. -#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStableEq)] pub struct LocalDefId { pub local_def_index: DefIndex, } From 5928308d1f516d3090223454cb95a21f2dbd9ef0 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 28 Jan 2022 23:36:41 -0500 Subject: [PATCH 04/18] Disable a bunch of impls --- compiler/rustc_hir/src/def.rs | 1 + compiler/rustc_hir/src/hir.rs | 92 +++++++++++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index e99f61d034fb8..0367b667acf7c 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -255,6 +255,7 @@ impl DefKind { // #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)] #[derive(HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum Res { /// Definition having a unique ID (`DefId`), corresponds to something defined in user code. /// diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 430e845c717f2..1c6c770365ffc 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -25,6 +25,7 @@ use smallvec::SmallVec; use std::fmt; #[derive(Copy, Clone, Encodable, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Lifetime { pub hir_id: HirId, pub span: Span, @@ -40,6 +41,7 @@ pub struct Lifetime { #[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)] #[derive(HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum ParamName { /// Some user-given name like `T` or `'x`. Plain(Ident), @@ -86,6 +88,7 @@ impl ParamName { #[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)] #[derive(HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum LifetimeName { /// User-given names or fresh (synthetic) names. Param(ParamName), @@ -186,6 +189,7 @@ impl Lifetime { /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers, /// along with a bunch of supporting information. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Path<'hir> { pub span: Span, /// The resolution for the path. @@ -203,6 +207,7 @@ impl Path<'_> { /// A segment of a path: an identifier, an optional lifetime, and a set of /// types. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct PathSegment<'hir> { /// The identifier portion of this path segment. pub ident: Ident, @@ -249,12 +254,14 @@ impl<'hir> PathSegment<'hir> { } #[derive(Encodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct ConstArg { pub value: AnonConst, pub span: Span, } #[derive(Encodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct InferArg { pub hir_id: HirId, pub span: Span, @@ -267,6 +274,7 @@ impl InferArg { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum GenericArg<'hir> { Lifetime(Lifetime), Type(Ty<'hir>), @@ -324,6 +332,7 @@ impl GenericArg<'_> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct GenericArgs<'hir> { /// The generic arguments for this path segment. pub args: &'hir [GenericArg<'hir>], @@ -435,6 +444,7 @@ pub enum TraitBoundModifier { /// the "special" built-in traits (see `middle::lang_items`) and /// detects `Copy`, `Send` and `Sync`. #[derive(Clone, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum GenericBound<'hir> { Trait(PolyTraitRef<'hir>, TraitBoundModifier), // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` @@ -465,6 +475,7 @@ impl GenericBound<'_> { pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>]; #[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum LifetimeParamKind { // Indicates that the lifetime definition was explicitly declared (e.g., in // `fn foo<'a>(x: &'a u8) -> &'a u8 { x }`). @@ -484,6 +495,7 @@ pub enum LifetimeParamKind { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum GenericParamKind<'hir> { /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`). Lifetime { @@ -501,6 +513,7 @@ pub enum GenericParamKind<'hir> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct GenericParam<'hir> { pub hir_id: HirId, pub name: ParamName, @@ -539,6 +552,7 @@ pub struct GenericParamCount { /// Represents lifetimes and type parameters attached to a declaration /// of a function, enum, trait, etc. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Generics<'hir> { pub params: &'hir [GenericParam<'hir>], pub where_clause: WhereClause<'hir>, @@ -574,6 +588,7 @@ impl<'hir> Generics<'hir> { /// A where-clause in a definition. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct WhereClause<'hir> { pub predicates: &'hir [WherePredicate<'hir>], // Only valid if predicates aren't empty. @@ -601,6 +616,7 @@ impl WhereClause<'_> { /// A single predicate in a where-clause. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum WherePredicate<'hir> { /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`). BoundPredicate(WhereBoundPredicate<'hir>), @@ -622,6 +638,7 @@ impl<'hir> WherePredicate<'hir> { /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct WhereBoundPredicate<'hir> { pub span: Span, /// Any generics from a `for` binding. @@ -649,6 +666,7 @@ impl<'hir> WhereBoundPredicate<'hir> { /// A lifetime predicate (e.g., `'a: 'b + 'c`). #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct WhereRegionPredicate<'hir> { pub span: Span, pub lifetime: Lifetime, @@ -657,6 +675,7 @@ pub struct WhereRegionPredicate<'hir> { /// An equality predicate (e.g., `T = int`); currently unsupported. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct WhereEqPredicate<'hir> { pub hir_id: HirId, pub span: Span, @@ -720,7 +739,7 @@ impl<'tcx> OwnerNodes<'tcx> { } /// Full information resulting from lowering an AST node. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug)] pub struct OwnerInfo<'hir> { /// Contents of the HIR. pub nodes: OwnerNodes<'hir>, @@ -788,6 +807,7 @@ pub struct Crate<'hir> { /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of /// the `rules` being anything but `DefaultBlock`. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Block<'hir> { /// Statements in a block. pub stmts: &'hir [Stmt<'hir>], @@ -806,6 +826,7 @@ pub struct Block<'hir> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Pat<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -887,6 +908,7 @@ impl<'hir> Pat<'hir> { /// are treated the same as` x: x, y: ref y, z: ref mut z`, /// except `is_shorthand` is true. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct PatField<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -902,6 +924,7 @@ pub struct PatField<'hir> { /// that this is not the final binding *mode* that we infer after type /// inference. #[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum BindingAnnotation { /// No binding annotation given: this means that the final binding mode /// will depend on whether we have skipped through a `&` reference @@ -938,6 +961,7 @@ impl fmt::Display for RangeEnd { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum PatKind<'hir> { /// Represents a wildcard pattern (i.e., `_`). Wild, @@ -994,6 +1018,7 @@ pub enum PatKind<'hir> { } #[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum BinOpKind { /// The `+` operator (addition). Add, @@ -1122,6 +1147,7 @@ impl Into for BinOpKind { pub type BinOp = Spanned; #[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum UnOp { /// The `*` operator (deferencing). Deref, @@ -1148,6 +1174,7 @@ impl UnOp { /// A statement. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Stmt<'hir> { pub hir_id: HirId, pub kind: StmtKind<'hir>, @@ -1156,6 +1183,7 @@ pub struct Stmt<'hir> { /// The contents of a statement. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum StmtKind<'hir> { /// A local (`let`) binding. Local(&'hir Local<'hir>), @@ -1172,6 +1200,7 @@ pub enum StmtKind<'hir> { /// Represents a `let` statement (i.e., `let : = ;`). #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Local<'hir> { pub pat: &'hir Pat<'hir>, /// Type annotation, if any (otherwise the type will be inferred). @@ -1188,6 +1217,7 @@ pub struct Local<'hir> { /// Represents a single arm of a `match` expression, e.g. /// ` (if ) => `. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Arm<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1206,6 +1236,7 @@ pub struct Arm<'hir> { /// In an if-let, imagine it as `if (let = ) { ... }`; in a let-else, it is part of the /// desugaring to if-let. Only let-else supports the type annotation at present. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Let<'hir> { pub hir_id: HirId, pub span: Span, @@ -1215,6 +1246,7 @@ pub struct Let<'hir> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum Guard<'hir> { If(&'hir Expr<'hir>), // FIXME use hir::Let for this. @@ -1222,6 +1254,7 @@ pub enum Guard<'hir> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct ExprField<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1232,12 +1265,14 @@ pub struct ExprField<'hir> { } #[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum BlockCheckMode { DefaultBlock, UnsafeBlock(UnsafeSource), } #[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum UnsafeSource { CompilerGenerated, UserProvided, @@ -1476,7 +1511,7 @@ pub struct AnonConst { } /// An expression. -#[derive(Debug, HashStableEq)] +#[derive(Debug)] pub struct Expr<'hir> { pub hir_id: HirId, pub kind: ExprKind<'hir>, @@ -1692,6 +1727,7 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum ExprKind<'hir> { /// A `box x` expression. Box(&'hir Expr<'hir>), @@ -1820,6 +1856,7 @@ pub enum ExprKind<'hir> { /// /// [`qpath_res`]: ../rustc_middle/ty/struct.TypeckResults.html#method.qpath_res #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum QPath<'hir> { /// Path to a definition, optionally "fully-qualified" with a `Self` /// type, if the path points to an associated item in a trait. @@ -2012,6 +2049,7 @@ impl From for YieldSource { // N.B., if you change this, you'll probably want to change the corresponding // type structure in middle/ty.rs as well. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct MutTy<'hir> { pub ty: &'hir Ty<'hir>, pub mutbl: Mutability, @@ -2020,6 +2058,7 @@ pub struct MutTy<'hir> { /// Represents a function's signature in a trait declaration, /// trait implementation, or a free function. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct FnSig<'hir> { pub header: FnHeader, pub decl: &'hir FnDecl<'hir>, @@ -2030,6 +2069,7 @@ pub struct FnSig<'hir> { // hashmap in the `Crate`. Here we just record the hir-id of the item // so it can fetched later. #[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStableEq)] +#[stable_hasher(no_hash_stable_eq)] pub struct TraitItemId { pub def_id: LocalDefId, } @@ -2046,7 +2086,7 @@ impl TraitItemId { /// possibly including a default implementation. A trait item is /// either required (meaning it doesn't have an implementation, just a /// signature) or provided (meaning it has a default implementation). -#[derive(Debug, HashStableEq)] +#[derive(Debug)] pub struct TraitItem<'hir> { pub ident: Ident, pub def_id: LocalDefId, @@ -2069,6 +2109,7 @@ impl TraitItem<'_> { /// Represents a trait method's body (or just argument names). #[derive(Encodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum TraitFn<'hir> { /// No default body in the trait, just a signature. Required(&'hir [Ident]), @@ -2079,6 +2120,7 @@ pub enum TraitFn<'hir> { /// Represents a trait method or associated constant or type #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum TraitItemKind<'hir> { /// An associated constant with an optional value (otherwise `impl`s must contain a value). Const(&'hir Ty<'hir>, Option), @@ -2092,7 +2134,7 @@ pub enum TraitItemKind<'hir> { // The bodies for items are stored "out of line", in a separate // hashmap in the `Crate`. Here we just record the hir-id of the item // so it can fetched later. -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStableEq)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug)] pub struct ImplItemId { pub def_id: LocalDefId, } @@ -2106,7 +2148,7 @@ impl ImplItemId { } /// Represents anything within an `impl` block. -#[derive(Debug, HashStableEq)] +#[derive(Debug)] pub struct ImplItem<'hir> { pub ident: Ident, pub def_id: LocalDefId, @@ -2130,6 +2172,7 @@ impl ImplItem<'_> { /// Represents various kinds of content within an `impl`. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum ImplItemKind<'hir> { /// An associated constant of the given type, set to the constant result /// of the expression. @@ -2159,6 +2202,7 @@ pub const FN_OUTPUT_NAME: Symbol = sym::Output; /// } /// ``` #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct TypeBinding<'hir> { pub hir_id: HirId, pub ident: Ident, @@ -2168,6 +2212,7 @@ pub struct TypeBinding<'hir> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum Term<'hir> { Ty(&'hir Ty<'hir>), Const(AnonConst), @@ -2187,6 +2232,7 @@ impl<'hir> From for Term<'hir> { // Represents the two kinds of type bindings. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum TypeBindingKind<'hir> { /// E.g., `Foo`. Constraint { bounds: &'hir [GenericBound<'hir>] }, @@ -2209,7 +2255,7 @@ impl TypeBinding<'_> { } } -#[derive(Debug, HashStableEq)] +#[derive(Debug)] pub struct Ty<'hir> { pub hir_id: HirId, pub kind: TyKind<'hir>, @@ -2219,6 +2265,7 @@ pub struct Ty<'hir> { /// Not represented directly in the AST; referred to by name through a `ty_path`. #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)] #[derive(HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum PrimTy { Int(IntTy), Uint(UintTy), @@ -2305,6 +2352,7 @@ impl PrimTy { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct BareFnTy<'hir> { pub unsafety: Unsafety, pub abi: Abi, @@ -2314,6 +2362,7 @@ pub struct BareFnTy<'hir> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct OpaqueTy<'hir> { pub generics: Generics<'hir>, pub bounds: GenericBounds<'hir>, @@ -2322,6 +2371,7 @@ pub struct OpaqueTy<'hir> { /// From whence the opaque type came. #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum OpaqueTyOrigin { /// `-> impl Trait` FnReturn(LocalDefId), @@ -2333,6 +2383,7 @@ pub enum OpaqueTyOrigin { /// The various kinds of types recognized by the compiler. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum TyKind<'hir> { /// A variable length slice (i.e., `[T]`). Slice(&'hir Ty<'hir>), @@ -2371,6 +2422,7 @@ pub enum TyKind<'hir> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum InlineAsmOperand<'hir> { In { reg: InlineAsmRegOrRegClass, @@ -2420,6 +2472,7 @@ impl<'hir> InlineAsmOperand<'hir> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct InlineAsm<'hir> { pub template: &'hir [InlineAsmTemplatePiece], pub template_strs: &'hir [(Symbol, Option, Span)], @@ -2430,6 +2483,7 @@ pub struct InlineAsm<'hir> { /// Represents a parameter in a function header. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Param<'hir> { pub hir_id: HirId, pub pat: &'hir Pat<'hir>, @@ -2439,6 +2493,7 @@ pub struct Param<'hir> { /// Represents the header (not the body) of a function declaration. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct FnDecl<'hir> { /// The types of the function's parameters. /// @@ -2504,6 +2559,7 @@ impl Defaultness { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum FnRetTy<'hir> { /// Return type is not specified. /// @@ -2526,6 +2582,7 @@ impl FnRetTy<'_> { } #[derive(Encodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Mod<'hir> { /// A span from the first token past `{` to the last token until `}`. /// For `mod foo;`, the inner span ranges from the first token @@ -2535,11 +2592,13 @@ pub struct Mod<'hir> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct EnumDef<'hir> { pub variants: &'hir [Variant<'hir>], } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Variant<'hir> { /// Name of the variant. pub ident: Ident, @@ -2554,6 +2613,7 @@ pub struct Variant<'hir> { } #[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum UseKind { /// One import, e.g., `use foo::bar` or `use foo::bar as baz`. /// Also produced for each element of a list `use`, e.g. @@ -2576,6 +2636,7 @@ pub enum UseKind { /// trait being referred to but just a unique `HirId` that serves as a key /// within the resolution map. #[derive(Clone, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct TraitRef<'hir> { pub path: &'hir Path<'hir>, // Don't hash the `ref_id`. It is tracked via the thing it is used to access. @@ -2595,6 +2656,7 @@ impl TraitRef<'_> { } #[derive(Clone, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct PolyTraitRef<'hir> { /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: &'hir [GenericParam<'hir>], @@ -2607,7 +2669,7 @@ pub struct PolyTraitRef<'hir> { pub type Visibility<'hir> = Spanned>; -#[derive(Copy, Clone, Debug, HashStableEq)] +#[derive(Copy, Clone, Debug)] pub enum VisibilityKind<'hir> { Public, Crate(CrateSugar), @@ -2629,6 +2691,7 @@ impl VisibilityKind<'_> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct FieldDef<'hir> { pub span: Span, pub ident: Ident, @@ -2647,6 +2710,7 @@ impl FieldDef<'_> { /// Fields and constructor IDs of enum variants and structs. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum VariantData<'hir> { /// A struct variant. /// @@ -2699,7 +2763,7 @@ impl ItemId { /// An item /// /// The name might be a dummy name in case of anonymous items -#[derive(Debug, HashStableEq)] +#[derive(Debug)] pub struct Item<'hir> { pub ident: Ident, pub def_id: LocalDefId, @@ -2780,6 +2844,7 @@ impl FnHeader { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum ItemKind<'hir> { /// An `extern crate` item, with optional *original* crate name if the crate was renamed. /// @@ -2827,6 +2892,7 @@ pub enum ItemKind<'hir> { } #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Impl<'hir> { pub unsafety: Unsafety, pub polarity: ImplPolarity, @@ -2906,6 +2972,7 @@ pub struct TraitItemRef { /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct ImplItemRef { pub id: ImplItemId, pub ident: Ident, @@ -2945,14 +3012,15 @@ impl ForeignItemId { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, HashStable_Generic) +]#[stable_hasher(no_hash_stable_eq)] pub struct ForeignItemRef { pub id: ForeignItemId, pub ident: Ident, pub span: Span, } -#[derive(Debug, HashStableEq)] +#[derive(Debug)] pub struct ForeignItem<'hir> { pub ident: Ident, pub kind: ForeignItemKind<'hir>, @@ -2975,6 +3043,7 @@ impl ForeignItem<'_> { /// An item within an `extern` block. #[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum ForeignItemKind<'hir> { /// A foreign function. Fn(&'hir FnDecl<'hir>, &'hir [Ident], Generics<'hir>), @@ -2986,6 +3055,7 @@ pub enum ForeignItemKind<'hir> { /// A variable captured by a closure. #[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Upvar { // First span where it is accessed (there can be multiple). pub span: Span, @@ -3001,6 +3071,7 @@ pub struct TraitCandidate { } #[derive(Copy, Clone, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum OwnerNode<'hir> { Item(&'hir Item<'hir>), ForeignItem(&'hir ForeignItem<'hir>), @@ -3140,6 +3211,7 @@ impl<'hir> Into> for OwnerNode<'hir> { } #[derive(Copy, Clone, Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum Node<'hir> { Param(&'hir Param<'hir>), Item(&'hir Item<'hir>), From 7c532ea4e939d8e9e1a7d72c90caf85f1ad4a37c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 28 Jan 2022 23:38:12 -0500 Subject: [PATCH 05/18] Keep going --- compiler/rustc_data_structures/src/stable_hasher.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 0458d6f84b66a..021719a8bb051 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -547,6 +547,16 @@ impl HashStableEq for Option { } } +impl HashStableEq for Result { + fn hash_stable_eq(&self, other: &Self) -> bool { + match (self, other) { + (Ok(first), Ok(second)) => first.hash_stable_eq(second), + (Err(first), Err(second)) => first.hash_stable_eq(second), + _ => false + } + } +} + impl HashStableEq for bool { fn hash_stable_eq(&self, other: &Self) -> bool { self == other From 3590961529d0835e21d89ce2597ac131fe958ba8 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 28 Jan 2022 23:41:26 -0500 Subject: [PATCH 06/18] Get to query key --- compiler/rustc_attr/src/builtin.rs | 3 +++ compiler/rustc_session/src/config.rs | 4 ++-- compiler/rustc_session/src/cstore.rs | 1 + compiler/rustc_span/src/def_id.rs | 1 + 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index dca7f5dd48769..ceee4806e501c 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -93,6 +93,7 @@ pub enum OptimizeAttr { /// - `#[unstable]` #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct Stability { pub level: StabilityLevel, pub feature: Symbol, @@ -101,6 +102,7 @@ pub struct Stability { /// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes. #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct ConstStability { pub level: StabilityLevel, pub feature: Symbol, @@ -111,6 +113,7 @@ pub struct ConstStability { /// The available stability levels. #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] #[derive(HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub enum StabilityLevel { // Reason for the current stability level and the relevant rust-lang issue Unstable { reason: Option, issue: Option, is_soft: bool }, diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 68e7cc3dc9874..eaf35aec7c440 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -397,7 +397,7 @@ pub enum TrimmedDefPaths { /// *Do not* switch `BTreeMap` out for an unsorted container type! That would break /// dependency tracking for command-line arguments. Also only hash keys, since tracking /// should only depend on the output types, not the paths they're written to. -#[derive(Clone, Debug, Hash)] +#[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct OutputTypes(BTreeMap>); impl OutputTypes { @@ -629,7 +629,7 @@ impl Input { } } -#[derive(Clone, Hash, Debug)] +#[derive(Clone, Hash, Debug, PartialEq, Eq)] pub struct OutputFilenames { pub out_directory: PathBuf, filestem: String, diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 281fc887633d9..1080a02e2af15 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -65,6 +65,7 @@ pub enum LinkagePreference { } #[derive(Debug, Encodable, Decodable, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct NativeLib { pub kind: NativeLibKind, pub name: Option, diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index c167ec2bf3dcd..326885f03f5c8 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -10,6 +10,7 @@ use std::fmt; use std::hash::{Hash, Hasher}; rustc_index::newtype_index! { + #[derive(HashStableEq)] pub struct CrateNum { ENCODABLE = custom DEBUG_FORMAT = "crate{}" From e27ca5af9428267e89c729c9cb0a7299cf7b7114 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 28 Jan 2022 23:44:43 -0500 Subject: [PATCH 07/18] Fix some stuff --- compiler/rustc_hir/src/hir.rs | 3 ++- compiler/rustc_middle/src/ty/mod.rs | 30 ++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 1c6c770365ffc..1cc55b8a761b3 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -739,7 +739,8 @@ impl<'tcx> OwnerNodes<'tcx> { } /// Full information resulting from lowering an AST node. -#[derive(Debug)] +#[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct OwnerInfo<'hir> { /// Contents of the HIR. pub nodes: OwnerNodes<'hir>, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f0b7f2a653f45..48fc953d1e871 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -28,9 +28,9 @@ use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::util::Discr; use rustc_ast as ast; use rustc_attr as attr; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::intern::Interned; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::stable_hasher::{HashStable, HashStableEq, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; @@ -444,7 +444,31 @@ static BOOL_TYS: TyS<'static> = TyS { outer_exclusive_binder: DebruijnIndex::from_usize(0), }; -impl<'a, 'tcx> HashStable> for Ty<'tcx> { +impl<'tcx> PartialEq for TyS<'tcx> { + #[inline] + fn eq(&self, other: &TyS<'tcx>) -> bool { + // Pointer equality implies equality (due to the unique contents + // assumption). + ptr::eq(self, other) + } +} +impl<'tcx> Eq for TyS<'tcx> {} + +impl<'tcx> HashStableEq for TyS<'tcx> { + fn hash_stable_eq(&self, other: Self) -> bool { + self == other + } +} + +impl<'tcx> Hash for TyS<'tcx> { + fn hash(&self, s: &mut H) { + // Pointer hashing is sufficient (due to the unique contents + // assumption). + (self as *const TyS<'_>).hash(s) + } +} + +impl<'a, 'tcx> HashStable> for TyS<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let TyS { ref kind, From e3db6dcd54afee5de06cfb845f2a398893ec9c0b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 28 Jan 2022 23:55:30 -0500 Subject: [PATCH 08/18] Get queries sort of compiling --- compiler/rustc_data_structures/src/stable_hasher.rs | 8 ++++++++ compiler/rustc_middle/src/ty/list.rs | 8 ++++++++ compiler/rustc_middle/src/ty/mod.rs | 10 ++++++++-- compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_middle/src/ty/subst.rs | 4 ++-- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 021719a8bb051..9bf2406f03858 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -311,6 +311,14 @@ impl HashStableEq for (T1, T2) { } } +impl HashStableEq for (T1, T2, T3) { + fn hash_stable_eq(&self, other: &Self) -> bool { + self.0.hash_stable_eq(&other.0) && self.1.hash_stable_eq(&other.1) + && self.2.hash_stable_eq(&other.2) + } +} + + impl, CTX> HashStable for (T1,) { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { let (ref _0,) = *self; diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index adba7d131592e..6a9d304e2491c 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -1,5 +1,6 @@ use crate::arena::Arena; use rustc_serialize::{Encodable, Encoder}; +use rustc_data_structures::stable_hasher::HashStableEq; use std::alloc::Layout; use std::cmp::Ordering; use std::fmt; @@ -134,6 +135,13 @@ impl PartialEq for List { } } +impl HashStableEq for List { + fn hash_stable_eq(&self, other: &Self) -> bool { + // FIXME - is this right? + self == other + } +} + impl Eq for List {} impl Ord for List diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 48fc953d1e871..cbdaec317f6a1 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -513,6 +513,12 @@ static_assert_size!(PredicateS<'_>, 56); #[cfg_attr(not(bootstrap), rustc_pass_by_value)] pub struct Predicate<'tcx>(Interned<'tcx, PredicateS<'tcx>>); +impl<'tcx> HashStableEq for Predicate<'tcx> { + fn hash_stable_eq(&self, other: &Self) -> bool { + self == other + } +} + impl<'tcx> Predicate<'tcx> { /// Gets the inner `Binder<'tcx, PredicateKind<'tcx>>`. #[inline] @@ -1289,7 +1295,7 @@ impl WithOptConstParam { /// When type checking, we use the `ParamEnv` to track /// details about the set of where-clauses that are in scope at this /// particular point. -#[derive(Copy, Clone, Hash, PartialEq, Eq)] +#[derive(Copy, Clone, Hash, PartialEq, Eq, HashStableEq)] pub struct ParamEnv<'tcx> { /// This packs both caller bounds and the reveal enum into one pointer. /// @@ -1524,7 +1530,7 @@ impl<'tcx> PolyTraitRef<'tcx> { } } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HashStableEq)] pub struct ParamEnvAnd<'tcx, T> { pub param_env: ParamEnv<'tcx>, pub value: T, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 9835211a74865..c876f1ac56c61 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1074,7 +1074,7 @@ pub enum BoundVariableKind { /// e.g., `liberate_late_bound_regions`). /// /// `Decodable` and `Encodable` are implemented for `Binder` using the `impl_binder_encode_decode!` macro. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, HashStableEq)] pub struct Binder<'tcx, T>(T, &'tcx List); impl<'tcx, T> Binder<'tcx, T> diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 7dccef5e3ef0f..19356c6518415 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -8,7 +8,7 @@ use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; use rustc_data_structures::intern::Interned; use rustc_hir::def_id::DefId; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, HashStableEq}; use rustc_serialize::{self, Decodable, Encodable}; use rustc_span::{Span, DUMMY_SP}; use smallvec::SmallVec; @@ -29,7 +29,7 @@ use std::ops::ControlFlow; /// /// Note: the `PartialEq`, `Eq` and `Hash` derives are only valid because `Ty`, /// `Region` and `Const` are all interned. -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStableEq)] pub struct GenericArg<'tcx> { ptr: NonZeroUsize, marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>, From 95c40b8e373d6b8e8bde7d96f47c49f3c1c77add Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 29 Jan 2022 17:15:00 -0500 Subject: [PATCH 09/18] Get rustc_middle compiling --- compiler/rustc_ast/src/ast.rs | 1 - compiler/rustc_attr/src/builtin.rs | 3 - .../rustc_data_structures/src/sorted_map.rs | 8 +- .../src/stable_hasher.rs | 80 +++++++++++++++++++ .../src/tagged_ptr/copy.rs | 12 ++- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_index/src/bit_set.rs | 2 +- compiler/rustc_middle/src/lint.rs | 3 + compiler/rustc_middle/src/metadata.rs | 1 + .../src/middle/codegen_fn_attrs.rs | 1 + .../src/mir/interpret/allocation.rs | 2 +- .../rustc_middle/src/mir/interpret/mod.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 4 + compiler/rustc_middle/src/mir/query.rs | 2 + .../src/traits/specialization_graph.rs | 1 + compiler/rustc_middle/src/ty/adt.rs | 8 +- compiler/rustc_middle/src/ty/assoc.rs | 1 + compiler/rustc_middle/src/ty/consts/int.rs | 3 +- compiler/rustc_middle/src/ty/fast_reject.rs | 2 +- compiler/rustc_middle/src/ty/list.rs | 3 +- compiler/rustc_middle/src/ty/mod.rs | 4 +- compiler/rustc_middle/src/ty/sty.rs | 8 +- compiler/rustc_type_ir/src/lib.rs | 22 +++-- 23 files changed, 148 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 2ef2ada1969a0..729827ea7b31c 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2027,7 +2027,6 @@ bitflags::bitflags! { } #[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)] -#[stable_hasher(no_hash_stable_eq)] pub enum InlineAsmTemplatePiece { String(String), Placeholder { operand_idx: usize, modifier: Option, span: Span }, diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index ceee4806e501c..dca7f5dd48769 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -93,7 +93,6 @@ pub enum OptimizeAttr { /// - `#[unstable]` #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(HashStable_Generic)] -#[stable_hasher(no_hash_stable_eq)] pub struct Stability { pub level: StabilityLevel, pub feature: Symbol, @@ -102,7 +101,6 @@ pub struct Stability { /// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes. #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(HashStable_Generic)] -#[stable_hasher(no_hash_stable_eq)] pub struct ConstStability { pub level: StabilityLevel, pub feature: Symbol, @@ -113,7 +111,6 @@ pub struct ConstStability { /// The available stability levels. #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] #[derive(HashStable_Generic)] -#[stable_hasher(no_hash_stable_eq)] pub enum StabilityLevel { // Reason for the current stability level and the relevant rust-lang issue Unstable { reason: Option, issue: Option, is_soft: bool }, diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index 9efea1228ab29..9bfb3ee6c9086 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs @@ -1,4 +1,4 @@ -use crate::stable_hasher::{HashStable, StableHasher}; +use crate::stable_hasher::{HashStable, HashStableEq, StableHasher}; use std::borrow::Borrow; use std::cmp::Ordering; use std::iter::FromIterator; @@ -298,5 +298,11 @@ impl, V: HashStable, CTX> HashStable for SortedMap< } } +impl HashStableEq for SortedMap { + fn hash_stable_eq(&self, other: &Self) -> bool { + self.data.hash_stable_eq(&other.data) + } +} + #[cfg(test)] mod tests; diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 9bf2406f03858..049be07aba973 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -285,6 +285,18 @@ impl HashStableEq for ::std::num::NonZeroUsize { } } +impl HashStableEq for ::std::num::NonZeroU32 { + fn hash_stable_eq(&self, other: &Self) -> bool { + self.get().hash_stable_eq(&other.get()) + } +} + +impl HashStableEq for ::std::num::NonZeroU64 { + fn hash_stable_eq(&self, other: &Self) -> bool { + self.get().hash_stable_eq(&other.get()) + } +} + impl HashStable for f32 { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { let val: u32 = unsafe { ::std::mem::transmute(*self) }; @@ -424,6 +436,25 @@ impl HashStableEq for Vec { } } +impl HashStableEq for indexmap::IndexMap { + fn hash_stable_eq(&self, other: &Self) -> bool { + if self.len() != other.len() { + return false; + } + // Equal maps will have equal iteration orders + // FIXME -is that actually right? + self.iter().zip(other.iter()).all(|(first, second)| { + first.hash_stable_eq(&second) + }) + } +} + +impl HashStableEq for std::marker::PhantomData { + fn hash_stable_eq(&self, other: &Self) -> bool { + true + } +} + impl HashStable for indexmap::IndexMap where K: HashStable + Eq + Hash, @@ -463,6 +494,12 @@ where } } +impl HashStableEq for SmallVec where ::Item: HashStableEq { + fn hash_stable_eq(&self, other: &Self) -> bool { + (&self[..]).hash_stable_eq(other) + } +} + impl, CTX> HashStable for Box { #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { @@ -693,6 +730,49 @@ where } } +impl HashStableEq for ::std::collections::HashMap +where + K: HashStableEq + Eq + Hash, + V: HashStableEq, + R: BuildHasher, +{ + fn hash_stable_eq(&self, other: &Self) -> bool { + if self.len() != other.len() { + return false; + } + self.iter().all(|(key, value)| { + match other.get_key_value(key) { + Some((other_key, other_value)) => { + // Compare the key, since the `PartailEq` impl + // used by the map may ignore information + key.hash_stable_eq(other_key) && value.hash_stable_eq(other_value) + } + _ => false, + } + }) + } +} + +impl HashStableEq for ::std::collections::HashSet +where + K: HashStableEq + Eq + Hash, + R: BuildHasher, +{ + fn hash_stable_eq(&self, other: &Self) -> bool { + if self.len() != other.len() { + return false; + } + self.iter().all(|key| { + match other.get(key) { + // Compare the key, since the `PartailEq` impl + // used by the map may ignore information + Some(other_key) => key.hash_stable_eq(other_key), + None => false, + } + }) + } +} + impl HashStable for ::std::collections::HashSet where K: ToStableHashKey + Eq, diff --git a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs index e1d3e0bd35a67..dc35f3cea1e68 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs @@ -1,5 +1,5 @@ use super::{Pointer, Tag}; -use crate::stable_hasher::{HashStable, StableHasher}; +use crate::stable_hasher::{HashStable, HashStableEq, StableHasher}; use std::fmt; use std::marker::PhantomData; use std::num::NonZeroUsize; @@ -161,6 +161,16 @@ where { } +impl HashStableEq for CopyTaggedPtr +where + P: Pointer, + T: Tag, +{ + fn hash_stable_eq(&self, other: &Self) -> bool { + self == other + } +} + impl std::hash::Hash for CopyTaggedPtr where P: Pointer, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 1cc55b8a761b3..caddbb680546c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2135,7 +2135,7 @@ pub enum TraitItemKind<'hir> { // The bodies for items are stored "out of line", in a separate // hashmap in the `Crate`. Here we just record the hir-id of the item // so it can fetched later. -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStableEq)] pub struct ImplItemId { pub def_id: LocalDefId, } diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index cf86c450a5bcc..3bcc39faa6313 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -7,7 +7,7 @@ use std::mem; use std::ops::{BitAnd, BitAndAssign, BitOrAssign, Bound, Not, Range, RangeBounds, Shl}; use std::slice; -use rustc_macros::{Decodable, Encodable}; +use rustc_macros::{Decodable, Encodable, HashStableEq}; #[cfg(test)] mod tests; diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 17c77c1bbd891..08479cdf108c0 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -53,6 +53,7 @@ impl LintLevelSource { pub type LevelAndSource = (Level, LintLevelSource); #[derive(Debug, HashStable)] +#[stable_hasher(no_hash_stable_eq)] pub struct LintLevelSets { pub list: IndexVec, pub lint_cap: Level, @@ -66,6 +67,8 @@ rustc_index::newtype_index! { } #[derive(Debug, HashStable)] +#[stable_hasher(no_hash_stable_eq)] +// FIXME - how is LintId implementing HashStable ? pub struct LintSet { // -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which // flag. diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs index 6dcdc58c72d82..a947472837613 100644 --- a/compiler/rustc_middle/src/metadata.rs +++ b/compiler/rustc_middle/src/metadata.rs @@ -11,6 +11,7 @@ use rustc_span::Span; /// Module child can be either a proper item or a reexport (including private imports). /// In case of reexport all the fields describe the reexport item itself, not what it refers to. #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] +#[stable_hasher(no_hash_stable_eq)] pub struct ModChild { /// Name of the item. pub ident: Ident, diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 54eb2dc9e2890..e145cdba96470 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -4,6 +4,7 @@ use rustc_span::symbol::Symbol; use rustc_target::spec::SanitizerSet; #[derive(Clone, TyEncodable, TyDecodable, HashStable, Debug)] +#[stable_hasher(no_hash_stable_eq)] pub struct CodegenFnAttrs { pub flags: CodegenFnAttrFlags, /// Parsed representation of the `#[inline]` attribute diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index a36c9b6ed7304..2a89057d6e426 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -496,7 +496,7 @@ impl Allocation { } /// "Relocations" stores the provenance information of pointers stored in memory. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable, HashStableEq)] pub struct Relocations(SortedMap); impl Relocations { diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 66f2c6e78a2e8..2a4a9c5b91d5b 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -177,7 +177,7 @@ pub enum LitToConstError { Reported, } -#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd, HashStableEq)] pub struct AllocId(pub NonZeroU64); // We want the `Debug` output to be readable as it is used by `derive(Debug)` for diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 7e5f8018dfc42..d844e943626ee 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -195,6 +195,7 @@ impl<'tcx> MirSource<'tcx> { } #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)] +#[stable_hasher(no_hash_stable_eq)] pub struct GeneratorInfo<'tcx> { /// The yield type of the function, if it is a generator. pub yield_ty: Option>, @@ -212,6 +213,7 @@ pub struct GeneratorInfo<'tcx> { /// The lowered representation of a single function. #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)] +#[stable_hasher(no_hash_stable_eq)] pub struct Body<'tcx> { /// A list of basic blocks. References to basic block use a newtyped index type [`BasicBlock`] /// that indexes into this vector. @@ -882,6 +884,7 @@ pub struct BlockTailInfo { /// This can be a binding declared by the user, a temporary inserted by the compiler, a function /// argument, or the return place. #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)] +#[stable_hasher(no_hash_stable_eq)] pub struct LocalDecl<'tcx> { /// Whether this is a mutable binding (i.e., `let x` or `let mut x`). /// @@ -1017,6 +1020,7 @@ static_assert_size!(LocalDecl<'_>, 56); /// Not used for non-StaticRef temporaries, the return place, or anonymous /// function parameters. #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)] +#[stable_hasher(no_hash_stable_eq)] pub enum LocalInfo<'tcx> { /// A user-defined local variable or function parameter /// diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 5c616425957df..366e43975d856 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -132,6 +132,7 @@ rustc_index::newtype_index! { /// The layout of generator state. #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable)] +#[stable_hasher(no_hash_stable_eq)] pub struct GeneratorLayout<'tcx> { /// The type of every local stored inside the generator. pub field_tys: IndexVec>, @@ -207,6 +208,7 @@ impl Debug for GeneratorLayout<'_> { } #[derive(Debug, TyEncodable, TyDecodable, HashStable)] +#[stable_hasher(no_hash_stable_eq)] pub struct BorrowCheckResult<'tcx> { /// All the opaque types that are restricted to concrete types /// by this function. Unlike the value in `TypeckResults`, this has diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 03a6daaf8aa4f..7fa420f45a9b6 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -22,6 +22,7 @@ use rustc_span::symbol::sym; /// default items amongst other things. In the simple "chain" rule, every impl /// has at most one parent. #[derive(TyEncodable, TyDecodable, HashStable, Debug)] +#[stable_hasher(no_hash_stable_eq)] pub struct Graph { /// All impls have a parent; the "root" impls have as their parent the `def_id` /// of the trait. diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 40fbea7c3d91f..f7997036b4a97 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -5,7 +5,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::HashingControls; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, HashStableEq, StableHasher}; use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; @@ -125,6 +125,12 @@ impl PartialEq for AdtDef { impl Eq for AdtDef {} +impl HashStableEq for AdtDef { + fn hash_stable_eq(&self, other: &Self) -> bool { + self == other + } +} + /// There should be only one AdtDef for each `did`, therefore /// it is fine to implement `Hash` only based on `did`. impl Hash for AdtDef { diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 49f846562a3cc..c109e9d9dddce 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -111,6 +111,7 @@ impl AssocKind { /// it is relatively expensive. Instead, items are indexed by `Symbol` and hygienic comparison is /// done only on items with the same name. #[derive(Debug, Clone, PartialEq, HashStable)] +#[stable_hasher(no_hash_stable_eq)] pub struct AssocItems<'tcx> { pub(super) items: SortedIndexMultiMap, } diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index de45e1bb851ac..b3b34b2309db8 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -117,7 +117,8 @@ impl std::fmt::Debug for ConstInt { /// /// This is a packed struct in order to allow this type to be optimally embedded in enums /// (like Scalar). -#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] +// FIXME - how are these impls correct if HashStable isnt'??? +#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, HashStableEq)] #[repr(packed)] pub struct ScalarInt { /// The first `size` bytes of `data` are the value. diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 983057bff95d6..f8f75d59736cc 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -17,7 +17,7 @@ pub type SimplifiedType = SimplifiedTypeGen; /// because we sometimes need to use SimplifiedTypeGen values as stable sorting /// keys (in which case we use a DefPathHash as id-type) but in the general case /// the non-stable but fast to construct DefId-version is the better choice. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable, HashStableEq)] pub enum SimplifiedTypeGen where D: Copy + Debug + Eq, diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index 6a9d304e2491c..a835380904721 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -137,8 +137,7 @@ impl PartialEq for List { impl HashStableEq for List { fn hash_stable_eq(&self, other: &Self) -> bool { - // FIXME - is this right? - self == other + (&self[..]).hash_stable_eq(other) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index cbdaec317f6a1..71b56bf045047 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -455,7 +455,7 @@ impl<'tcx> PartialEq for TyS<'tcx> { impl<'tcx> Eq for TyS<'tcx> {} impl<'tcx> HashStableEq for TyS<'tcx> { - fn hash_stable_eq(&self, other: Self) -> bool { + fn hash_stable_eq(&self, other: &Self) -> bool { self == other } } @@ -1134,7 +1134,7 @@ impl UniverseIndex { /// identified by both a universe, as well as a name residing within that universe. Distinct bound /// regions/types/consts within the same universe simply have an unknown relationship to one /// another. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord, HashStableEq)] pub struct Placeholder { pub universe: UniverseIndex, pub name: T, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c876f1ac56c61..1dc80d1504d08 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1518,7 +1518,7 @@ impl<'tcx> fmt::Debug for Region<'tcx> { /// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/ /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html -#[derive(Clone, PartialEq, Eq, Hash, Copy, TyEncodable, TyDecodable, PartialOrd, Ord)] +#[derive(Clone, PartialEq, Eq, Hash, Copy, TyEncodable, TyDecodable, PartialOrd, Ord, HashStableEq)] pub enum RegionKind { /// Region bound in a type or fn declaration which will be /// substituted 'early' -- that is, at the same time when type @@ -1556,7 +1556,7 @@ pub enum RegionKind { ReErased, } -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord, HashStableEq)] pub struct EarlyBoundRegion { pub def_id: DefId, pub index: u32, @@ -1564,7 +1564,7 @@ pub struct EarlyBoundRegion { } /// A **`const`** **v**ariable **ID**. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable, HashStableEq)] pub struct ConstVid<'tcx> { pub index: u32, pub phantom: PhantomData<&'tcx ()>, @@ -1572,6 +1572,7 @@ pub struct ConstVid<'tcx> { rustc_index::newtype_index! { /// A **region** (lifetime) **v**ariable **ID**. + #[derive(HashStableEq)] pub struct RegionVid { DEBUG_FORMAT = custom, } @@ -1584,6 +1585,7 @@ impl Atom for RegionVid { } rustc_index::newtype_index! { + #[derive(HashStableEq)] pub struct BoundVar { .. } } diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index e26f0033156bc..b343f4032336c 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -5,7 +5,7 @@ extern crate bitflags; #[macro_use] extern crate rustc_macros; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, HashStableEq, StableHasher}; use rustc_data_structures::unify::{EqUnifyValue, UnifyKey}; use std::fmt; use std::mem::discriminant; @@ -150,6 +150,7 @@ rustc_index::newtype_index! { /// is the outer fn. /// /// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index + #[derive(HashStableEq)] pub struct DebruijnIndex { DEBUG_FORMAT = "DebruijnIndex({})", const INNERMOST = 0, @@ -215,7 +216,7 @@ impl DebruijnIndex { } } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, HashStableEq)] #[derive(Encodable, Decodable)] pub enum IntTy { Isize, @@ -262,7 +263,7 @@ impl IntTy { } } -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug, HashStableEq)] #[derive(Encodable, Decodable)] pub enum UintTy { Usize, @@ -309,7 +310,7 @@ impl UintTy { } } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, HashStableEq)] #[derive(Encodable, Decodable)] pub enum FloatTy { F32, @@ -343,19 +344,20 @@ pub struct FloatVarValue(pub FloatTy); rustc_index::newtype_index! { /// A **ty**pe **v**ariable **ID**. + #[derive(HashStableEq)] pub struct TyVid { DEBUG_FORMAT = "_#{}t" } } /// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable, HashStableEq)] pub struct IntVid { pub index: u32, } /// An **float**ing-point (`f32` or `f64`) type **v**ariable **ID**. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable, HashStableEq)] pub struct FloatVid { pub index: u32, } @@ -365,7 +367,7 @@ pub struct FloatVid { /// E.g., if we have an empty array (`[]`), then we create a fresh /// type variable for the element type since we won't know until it's /// used what the element type is supposed to be. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable, HashStableEq)] pub enum InferTy { /// A type variable. TyVar(TyVid), @@ -558,6 +560,12 @@ impl HashStable for Variance { } } +impl HashStableEq for Variance { + fn hash_stable_eq(&self, other: &Self) -> bool { + self == other + } +} + impl fmt::Debug for IntVarValue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { From dfd183f417984618cb5df17ebb5227c0c029558d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 29 Jan 2022 17:34:31 -0500 Subject: [PATCH 10/18] Get it compiling --- compiler/rustc_codegen_ssa/src/lib.rs | 1 + compiler/rustc_middle/src/ty/consts/int.rs | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 9bb8db076a8d6..504fa688f8feb 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -107,6 +107,7 @@ bitflags::bitflags! { } #[derive(Clone, Debug, Encodable, Decodable, HashStable)] +#[stable_hasher(no_hash_stable_eq)] pub struct NativeLib { pub kind: NativeLibKind, pub name: Option, diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index b3b34b2309db8..b73e753105acb 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -2,6 +2,7 @@ use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_target::abi::Size; +use rustc_data_structures::stable_hasher::HashStableEq; use std::convert::{TryFrom, TryInto}; use std::fmt; @@ -118,7 +119,7 @@ impl std::fmt::Debug for ConstInt { /// This is a packed struct in order to allow this type to be optimally embedded in enums /// (like Scalar). // FIXME - how are these impls correct if HashStable isnt'??? -#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, HashStableEq)] +#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(packed)] pub struct ScalarInt { /// The first `size` bytes of `data` are the value. @@ -140,6 +141,13 @@ impl crate::ty::HashStable for ScalarInt { } } +impl HashStableEq for ScalarInt { + fn hash_stable_eq(&self, other: &Self) -> bool { + let other_data = other.data; + { self.data }.hash_stable_eq(&other_data) && self.size.hash_stable_eq(&other.size) + } +} + impl Encodable for ScalarInt { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u128(self.data)?; From 70441579c7bcdd1cd7ef3b232ff4e57795240ce5 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 29 Jan 2022 17:37:18 -0500 Subject: [PATCH 11/18] Run fmt --- .../src/stable_hasher.rs | 24 ++++--- compiler/rustc_hir/src/hir.rs | 4 +- compiler/rustc_hir/src/stable_hash_impls.rs | 4 +- compiler/rustc_macros/src/hash_stable.rs | 71 ++++++++++--------- .../src/mir/interpret/allocation.rs | 13 +++- compiler/rustc_middle/src/ty/consts/int.rs | 2 +- compiler/rustc_middle/src/ty/fast_reject.rs | 14 +++- compiler/rustc_middle/src/ty/list.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 14 +++- compiler/rustc_middle/src/ty/sty.rs | 14 +++- .../rustc_query_system/src/query/caches.rs | 10 +-- .../rustc_query_system/src/query/plumbing.rs | 2 +- compiler/rustc_span/src/def_id.rs | 4 +- compiler/rustc_span/src/hygiene.rs | 2 +- compiler/rustc_span/src/symbol.rs | 4 +- 15 files changed, 124 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 049be07aba973..68c2df762e283 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -240,7 +240,7 @@ macro_rules! impl_hash_stable_eq_via_eq { self == other } } - } + }; } impl_stable_hash_via_hash!(i8); @@ -325,12 +325,12 @@ impl HashStableEq for (T1, T2) { impl HashStableEq for (T1, T2, T3) { fn hash_stable_eq(&self, other: &Self) -> bool { - self.0.hash_stable_eq(&other.0) && self.1.hash_stable_eq(&other.1) + self.0.hash_stable_eq(&other.0) + && self.1.hash_stable_eq(&other.1) && self.2.hash_stable_eq(&other.2) } } - impl, CTX> HashStable for (T1,) { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { let (ref _0,) = *self; @@ -396,7 +396,6 @@ impl HashStableEq for [T; N] { } } - impl, CTX> HashStable for [T] { default fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { self.len().hash_stable(ctx, hasher); @@ -436,16 +435,16 @@ impl HashStableEq for Vec { } } -impl HashStableEq for indexmap::IndexMap { +impl HashStableEq + for indexmap::IndexMap +{ fn hash_stable_eq(&self, other: &Self) -> bool { if self.len() != other.len() { return false; } // Equal maps will have equal iteration orders // FIXME -is that actually right? - self.iter().zip(other.iter()).all(|(first, second)| { - first.hash_stable_eq(&second) - }) + self.iter().zip(other.iter()).all(|(first, second)| first.hash_stable_eq(&second)) } } @@ -494,7 +493,10 @@ where } } -impl HashStableEq for SmallVec where ::Item: HashStableEq { +impl HashStableEq for SmallVec +where + ::Item: HashStableEq, +{ fn hash_stable_eq(&self, other: &Self) -> bool { (&self[..]).hash_stable_eq(other) } @@ -587,7 +589,7 @@ impl HashStableEq for Option { match (self, other) { (Some(first), Some(second)) => first.hash_stable_eq(second), (None, None) => true, - _ => false + _ => false, } } } @@ -597,7 +599,7 @@ impl HashStableEq for Result { match (self, other) { (Ok(first), Ok(second)) => first.hash_stable_eq(second), (Err(first), Err(second)) => first.hash_stable_eq(second), - _ => false + _ => false, } } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index caddbb680546c..b547f7924b1c4 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3013,8 +3013,8 @@ impl ForeignItemId { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Debug, HashStable_Generic) -]#[stable_hasher(no_hash_stable_eq)] +#[derive(Debug, HashStable_Generic)] +#[stable_hasher(no_hash_stable_eq)] pub struct ForeignItemRef { pub id: ForeignItemId, pub ident: Ident, diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 199576fbb40bd..94acdaab23c22 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -1,4 +1,6 @@ -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey, HashStableEq}; +use rustc_data_structures::stable_hasher::{ + HashStable, HashStableEq, StableHasher, ToStableHashKey, +}; use crate::hir::{ AttributeMap, BodyId, Crate, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, diff --git a/compiler/rustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs index 6a7a8199a206b..d804846601481 100644 --- a/compiler/rustc_macros/src/hash_stable.rs +++ b/compiler/rustc_macros/src/hash_stable.rs @@ -81,7 +81,6 @@ pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_ma } }); - let discriminant = match s.ast().data { syn::Data::Enum(_) => quote! { ::std::mem::discriminant(self).hash_stable(__hcx, __hasher); @@ -118,37 +117,45 @@ pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_ma pub fn hash_stable_eq_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let mut other = s.clone(); - other.binding_name(|_bi, i| Ident::new(&format!("__binding_other_{}", i), proc_macro2::Span::call_site())); - - let eq_body: proc_macro2::TokenStream = s.variants().iter().zip(other.variants()).map(|(variant1, variant2)| { - - let first_pat = variant1.pat(); - let second_pat = variant2.pat(); - - let compare = std::iter::once(quote! { true }).chain(variant1.bindings().iter().zip(variant2.bindings()).map(|(binding1, binding2)| { - let attrs = parse_attributes(binding1.ast()); - if attrs.ignore { - quote! { true } - } else if let Some(project) = attrs.project { - quote! { - ::rustc_data_structures::stable_hasher::HashStableEq::hash_stable_eq( - #binding1.#project, #binding2.#project - ) - } - } else { - quote! { - ::rustc_data_structures::stable_hasher::HashStableEq::hash_stable_eq( - #binding1, #binding2 - ) + other.binding_name(|_bi, i| { + Ident::new(&format!("__binding_other_{}", i), proc_macro2::Span::call_site()) + }); + + let eq_body: proc_macro2::TokenStream = s + .variants() + .iter() + .zip(other.variants()) + .map(|(variant1, variant2)| { + let first_pat = variant1.pat(); + let second_pat = variant2.pat(); + + let compare = std::iter::once(quote! { true }).chain( + variant1.bindings().iter().zip(variant2.bindings()).map(|(binding1, binding2)| { + let attrs = parse_attributes(binding1.ast()); + if attrs.ignore { + quote! { true } + } else if let Some(project) = attrs.project { + quote! { + ::rustc_data_structures::stable_hasher::HashStableEq::hash_stable_eq( + #binding1.#project, #binding2.#project + ) + } + } else { + quote! { + ::rustc_data_structures::stable_hasher::HashStableEq::hash_stable_eq( + #binding1, #binding2 + ) + } + } + }), + ); + quote! { + (#first_pat, #second_pat) => { + #(#compare)&&* } } - })); - quote! { - (#first_pat, #second_pat) => { - #(#compare)&&* - } - } - }).collect(); + }) + .collect(); s.add_bounds(synstructure::AddBounds::Generics); s.bound_impl( @@ -160,8 +167,8 @@ pub fn hash_stable_eq_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: _ => false } } - } - ) + }, + ) } pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 2a89057d6e426..14591f5cda713 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -496,7 +496,18 @@ impl Allocation { } /// "Relocations" stores the provenance information of pointers stored in memory. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable, HashStableEq)] +#[derive( + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Debug, + TyEncodable, + TyDecodable, + HashStableEq +)] pub struct Relocations(SortedMap); impl Relocations { diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index b73e753105acb..69c57e977853e 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -1,8 +1,8 @@ use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; +use rustc_data_structures::stable_hasher::HashStableEq; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_target::abi::Size; -use rustc_data_structures::stable_hasher::HashStableEq; use std::convert::{TryFrom, TryInto}; use std::fmt; diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index f8f75d59736cc..da2010630bb3c 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -17,7 +17,19 @@ pub type SimplifiedType = SimplifiedTypeGen; /// because we sometimes need to use SimplifiedTypeGen values as stable sorting /// keys (in which case we use a DefPathHash as id-type) but in the general case /// the non-stable but fast to construct DefId-version is the better choice. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable, HashStableEq)] +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + TyEncodable, + TyDecodable, + HashStableEq +)] pub enum SimplifiedTypeGen where D: Copy + Debug + Eq, diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index a835380904721..702ec6cd0991a 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -1,6 +1,6 @@ use crate::arena::Arena; -use rustc_serialize::{Encodable, Encoder}; use rustc_data_structures::stable_hasher::HashStableEq; +use rustc_serialize::{Encodable, Encoder}; use std::alloc::Layout; use std::cmp::Ordering; use std::fmt; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 71b56bf045047..4e9579ba6e743 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1134,7 +1134,19 @@ impl UniverseIndex { /// identified by both a universe, as well as a name residing within that universe. Distinct bound /// regions/types/consts within the same universe simply have an unknown relationship to one /// another. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord, HashStableEq)] +#[derive( + Copy, + Clone, + Debug, + PartialEq, + Eq, + Hash, + TyEncodable, + TyDecodable, + PartialOrd, + Ord, + HashStableEq +)] pub struct Placeholder { pub universe: UniverseIndex, pub name: T, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 1dc80d1504d08..2fc066efdd65e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1556,7 +1556,19 @@ pub enum RegionKind { ReErased, } -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord, HashStableEq)] +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + TyEncodable, + TyDecodable, + Debug, + PartialOrd, + Ord, + HashStableEq +)] pub struct EarlyBoundRegion { pub def_id: DefId, pub index: u32, diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 655c6efb117c1..bba5394facbb6 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -1,12 +1,12 @@ use crate::dep_graph::DepNodeIndex; -use crate::query::HashStableKey; use crate::query::plumbing::{QueryCacheStore, QueryLookup}; +use crate::query::HashStableKey; use rustc_arena::TypedArena; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sharded::Sharded; -use rustc_data_structures::sync::WorkerLocal; use rustc_data_structures::stable_hasher::HashStableEq; +use rustc_data_structures::sync::WorkerLocal; use std::default::Default; use std::fmt::Debug; use std::hash::Hash; @@ -102,7 +102,8 @@ where OnHit: FnOnce(&V, DepNodeIndex) -> R, { let (lookup, lock) = state.get_lookup(key); - let result = lock.raw_entry().from_key_hashed_nocheck(lookup.key_hash, HashStableKey::from_ref(key)); + let result = + lock.raw_entry().from_key_hashed_nocheck(lookup.key_hash, HashStableKey::from_ref(key)); if let Some((_, value)) = result { let hit_result = on_hit(&value.0, value.1); @@ -186,7 +187,8 @@ where OnHit: FnOnce(&&'tcx V, DepNodeIndex) -> R, { let (lookup, lock) = state.get_lookup(key); - let result = lock.raw_entry().from_key_hashed_nocheck(lookup.key_hash, HashStableKey::from_ref(key)); + let result = + lock.raw_entry().from_key_hashed_nocheck(lookup.key_hash, HashStableKey::from_ref(key)); if let Some((_, value)) = result { let hit_result = on_hit(&&value.0, value.1); diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index a2cf9cb8b4e9c..9b489f07b25ef 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -12,9 +12,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHasher}; #[cfg(parallel_compiler)] use rustc_data_structures::profiling::TimingGuard; use rustc_data_structures::sharded::{get_shard_index_by_hash, Sharded}; +use rustc_data_structures::stable_hasher::HashStableEq; use rustc_data_structures::sync::{Lock, LockGuard}; use rustc_data_structures::thin_vec::ThinVec; -use rustc_data_structures::stable_hasher::HashStableEq; use rustc_errors::{DiagnosticBuilder, FatalError}; use rustc_session::Session; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 326885f03f5c8..2f0e0690f86d7 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -1,6 +1,8 @@ use crate::HashStableContext; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey, HashStableEq}; +use rustc_data_structures::stable_hasher::{ + HashStable, HashStableEq, StableHasher, ToStableHashKey, +}; use rustc_data_structures::AtomicRef; use rustc_index::vec::Idx; use rustc_macros::HashStable_Generic; diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 5845c1bce324a..929940188bb47 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -33,7 +33,7 @@ use crate::def_id::{CrateNum, DefId, StableCrateId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::HashingControls; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, HashStableEq}; +use rustc_data_structures::stable_hasher::{HashStable, HashStableEq, StableHasher}; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_data_structures::unhash::UnhashMap; use rustc_index::vec::IndexVec; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 174cd6a0d7690..c4fb8d176da50 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -4,7 +4,9 @@ use rustc_arena::DroplessArena; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey, HashStableEq}; +use rustc_data_structures::stable_hasher::{ + HashStable, HashStableEq, StableHasher, ToStableHashKey, +}; use rustc_data_structures::sync::Lock; use rustc_macros::HashStable_Generic; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; From 57231fde857b26445c5925d643e276daa635e7cd Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 29 Jan 2022 17:49:47 -0500 Subject: [PATCH 12/18] Fix warnings --- compiler/rustc_data_structures/src/stable_hasher.rs | 2 +- compiler/rustc_index/src/bit_set.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 68c2df762e283..9482c30912000 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -449,7 +449,7 @@ impl HashStableEq } impl HashStableEq for std::marker::PhantomData { - fn hash_stable_eq(&self, other: &Self) -> bool { + fn hash_stable_eq(&self, _other: &Self) -> bool { true } } diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 3bcc39faa6313..cf86c450a5bcc 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -7,7 +7,7 @@ use std::mem; use std::ops::{BitAnd, BitAndAssign, BitOrAssign, Bound, Not, Range, RangeBounds, Shl}; use std::slice; -use rustc_macros::{Decodable, Encodable, HashStableEq}; +use rustc_macros::{Decodable, Encodable}; #[cfg(test)] mod tests; From 64b6aa7c410ee464f5033bd35dc25bfa17efbc23 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 31 Jan 2022 15:48:43 -0500 Subject: [PATCH 13/18] Add #[inline] to derive `hash_stable_eq` --- compiler/rustc_macros/src/hash_stable.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs index d804846601481..dffb4530502b3 100644 --- a/compiler/rustc_macros/src/hash_stable.rs +++ b/compiler/rustc_macros/src/hash_stable.rs @@ -161,6 +161,7 @@ pub fn hash_stable_eq_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: s.bound_impl( quote!(::rustc_data_structures::stable_hasher::HashStableEq), quote! { + #[inline] fn hash_stable_eq(&self, other: &Self) -> bool { match (self, other) { #eq_body From 3a2ab93b7b711dd275a61f113c0b89cbde607f7d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 1 Feb 2022 23:08:49 -0500 Subject: [PATCH 14/18] Add another #[inline] --- compiler/rustc_data_structures/src/stable_hasher.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 9482c30912000..e62fe952dd2d7 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -236,6 +236,7 @@ macro_rules! impl_stable_hash_via_hash { macro_rules! impl_hash_stable_eq_via_eq { ($t:ty) => { impl ::rustc_data_structures::stable_hasher::HashStableEq for $t { + #[inline] fn hash_stable_eq(&self, other: &Self) -> bool { self == other } From 91d75eacb3741c0b77fffacb47e699abf48257de Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 8 Feb 2022 21:03:55 -0500 Subject: [PATCH 15/18] Switch more impls to derives (implicitly adding `#[inline]`) --- compiler/rustc_hir/src/hir_id.rs | 2 +- compiler/rustc_hir/src/stable_hash_impls.rs | 10 +--------- compiler/rustc_span/src/def_id.rs | 12 ++---------- compiler/rustc_type_ir/src/lib.rs | 10 ++-------- 4 files changed, 6 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index dee391b9cce21..74f9b9de62f92 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -11,7 +11,7 @@ use std::fmt; /// the `local_id` part of the `HirId` changing, which is a very useful property in /// incremental compilation where we have to persist things through changes to /// the code base. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStableEq)] #[derive(Encodable, Decodable)] pub struct HirId { pub owner: LocalDefId, diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 94acdaab23c22..61f03442d61f2 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -1,6 +1,4 @@ -use rustc_data_structures::stable_hasher::{ - HashStable, HashStableEq, StableHasher, ToStableHashKey, -}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use crate::hir::{ AttributeMap, BodyId, Crate, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, @@ -35,12 +33,6 @@ impl ToStableHashKey for HirId { } } -impl HashStableEq for HirId { - fn hash_stable_eq(&self, other: &HirId) -> bool { - self == other - } -} - impl ToStableHashKey for ItemLocalId { type KeyType = ItemLocalId; diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 2f0e0690f86d7..68a69d2002173 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -1,8 +1,6 @@ use crate::HashStableContext; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::stable_hasher::{ - HashStable, HashStableEq, StableHasher, ToStableHashKey, -}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_data_structures::AtomicRef; use rustc_index::vec::Idx; use rustc_macros::HashStable_Generic; @@ -222,7 +220,7 @@ impl Decodable for DefIndex { /// index and a def index. /// /// You can create a `DefId` from a `LocalDefId` using `local_def_id.to_def_id()`. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy, HashStableEq)] // On below-64 bit systems we can simply use the derived `Hash` impl #[cfg_attr(not(target_pointer_width = "64"), derive(Hash))] #[repr(C)] @@ -238,12 +236,6 @@ pub struct DefId { pub index: DefIndex, } -impl HashStableEq for DefId { - fn hash_stable_eq(&self, other: &Self) -> bool { - self == other - } -} - // On 64-bit systems, we can hash the whole `DefId` as one `u64` instead of two `u32`s. This // improves performance without impairing `FxHash` quality. So the below code gets compiled to a // noop on little endian systems because the memory layout of `DefId` is as follows: diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index b343f4032336c..edc2fc1ec760a 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -5,7 +5,7 @@ extern crate bitflags; #[macro_use] extern crate rustc_macros; -use rustc_data_structures::stable_hasher::{HashStable, HashStableEq, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::unify::{EqUnifyValue, UnifyKey}; use std::fmt; use std::mem::discriminant; @@ -449,7 +449,7 @@ impl UnifyKey for FloatVid { } } -#[derive(Copy, Clone, PartialEq, Decodable, Encodable, Hash)] +#[derive(Copy, Clone, PartialEq, Decodable, Encodable, Hash, HashStableEq)] pub enum Variance { Covariant, // T <: T iff A <: B -- e.g., function return type Invariant, // T <: T iff B == A -- e.g., type of mutable cell @@ -560,12 +560,6 @@ impl HashStable for Variance { } } -impl HashStableEq for Variance { - fn hash_stable_eq(&self, other: &Self) -> bool { - self == other - } -} - impl fmt::Debug for IntVarValue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { From f992e656163c5136f9c8b099307d893f7d34e41c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 15 Feb 2022 17:30:44 -0500 Subject: [PATCH 16/18] Some work --- compiler/rustc_middle/src/ty/mod.rs | 36 ++++++++----------- .../rustc_query_system/src/query/plumbing.rs | 2 +- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 4e9579ba6e743..888b9eb46e0d2 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -29,7 +29,7 @@ use crate::ty::util::Discr; use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::intern::Interned; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxHashSet}; use rustc_data_structures::stable_hasher::{HashStable, HashStableEq, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_hir as hir; @@ -43,7 +43,7 @@ use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::{sym, Span}; use rustc_target::abi::Align; -use std::hash::Hash; +use std::hash::{Hash, Hasher}; use std::ops::ControlFlow; use std::{fmt, str}; @@ -444,31 +444,23 @@ static BOOL_TYS: TyS<'static> = TyS { outer_exclusive_binder: DebruijnIndex::from_usize(0), }; -impl<'tcx> PartialEq for TyS<'tcx> { - #[inline] - fn eq(&self, other: &TyS<'tcx>) -> bool { - // Pointer equality implies equality (due to the unique contents - // assumption). - ptr::eq(self, other) - } -} -impl<'tcx> Eq for TyS<'tcx> {} - -impl<'tcx> HashStableEq for TyS<'tcx> { +impl<'tcx> HashStableEq for Ty<'tcx> { fn hash_stable_eq(&self, other: &Self) -> bool { - self == other - } -} + let TyS { + ref kind, + + // The other fields just provide fast access to information that is + // also contained in `kind`, so no need to compare them. + flags: _, + + outer_exclusive_binder: _, + } = self.0.0; -impl<'tcx> Hash for TyS<'tcx> { - fn hash(&self, s: &mut H) { - // Pointer hashing is sufficient (due to the unique contents - // assumption). - (self as *const TyS<'_>).hash(s) + kind.hash_stable_eq(other.kind()) } } -impl<'a, 'tcx> HashStable> for TyS<'tcx> { +impl<'a, 'tcx> HashStable> for Ty<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let TyS { ref kind, diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 9b489f07b25ef..b0672ed666278 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -68,7 +68,7 @@ impl QueryCacheStore { } struct QueryStateShard { - active: FxHashMap, + active: FxHashMap, QueryResult>, } #[derive(Copy, Clone, Hash)] From fbe0b2a21b3eb69b6ed45c994fd430395aea43a0 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 16 Feb 2022 17:25:29 -0500 Subject: [PATCH 17/18] Get it compiling again --- compiler/rustc_data_structures/src/intern.rs | 10 ++++++++++ compiler/rustc_middle/src/ty/mod.rs | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_data_structures/src/intern.rs b/compiler/rustc_data_structures/src/intern.rs index c79a5ebf0933b..7e50b0b785739 100644 --- a/compiler/rustc_data_structures/src/intern.rs +++ b/compiler/rustc_data_structures/src/intern.rs @@ -3,6 +3,8 @@ use std::hash::{Hash, Hasher}; use std::ops::Deref; use std::ptr; +use crate::stable_hasher::HashStableEq; + mod private { #[derive(Clone, Copy, Debug)] pub struct PrivateZst; @@ -52,6 +54,14 @@ impl<'a, T> Deref for Interned<'a, T> { } } +// FIXME - is this right? Should we try to enforce this somehow? +impl<'a, T: HashStableEq> HashStableEq for Interned<'a, T> { + fn hash_stable_eq(&self, other: &Self) -> bool { + // Pointer equality implies equality, due to the uniqueness constraint. + ptr::eq(self.0, other.0) + } +} + impl<'a, T> PartialEq for Interned<'a, T> { #[inline] fn eq(&self, other: &Self) -> bool { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 888b9eb46e0d2..f93dafb2e485b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -43,7 +43,7 @@ use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::{sym, Span}; use rustc_target::abi::Align; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; use std::ops::ControlFlow; use std::{fmt, str}; From 87333c4031f67ee5081a259568491ef94a6b7720 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 17 Feb 2022 16:27:38 -0500 Subject: [PATCH 18/18] Run fmt --- compiler/rustc_middle/src/ty/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f93dafb2e485b..22dfe8a9b11bb 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -28,8 +28,8 @@ use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::util::Discr; use rustc_ast as ast; use rustc_attr as attr; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::intern::Interned; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxHashSet}; use rustc_data_structures::stable_hasher::{HashStable, HashStableEq, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_hir as hir;