From c1154708c4764cee92dcf52afa7b48f8e2b2b8d6 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
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<MacArgs>,
     /// `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<char>, span: Span },
@@ -2425,6 +2432,7 @@ impl<D: Decoder> rustc_serialize::Decodable<D> 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<CTX> {
     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<T: HashStableEq> 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<T: HashStableEq, const N: usize> HashStableEq for [T; N] {
+    fn hash_stable_eq(&self, other: &Self) -> bool {
+        (self[..]).hash_stable_eq(other)
+    }
+}
+
+
 impl<T: HashStable<CTX>, CTX> HashStable<CTX> for [T] {
     default fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
         self.len().hash_stable(ctx, hasher);
@@ -331,6 +360,15 @@ impl<T: HashStable<CTX>, CTX> HashStable<CTX> for [T] {
     }
 }
 
+impl<T: HashStable<CTX>, CTX, const N: usize> HashStable<CTX> 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<CTX> HashStable<CTX> for [u8] {
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
         self.len().hash_stable(ctx, hasher);
@@ -405,6 +443,18 @@ impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::std::sync::Arc<T> {
     }
 }
 
+impl<T: ?Sized + HashStableEq> HashStableEq for ::std::rc::Rc<T> {
+    fn hash_stable_eq(&self, other: &Self) -> bool {
+        (**self).hash_stable_eq(other)
+    }
+}
+
+impl<T: ?Sized + HashStableEq> HashStableEq for ::std::sync::Arc<T> {
+    fn hash_stable_eq(&self, other: &Self) -> bool {
+        (**self).hash_stable_eq(other)
+    }
+}
+
 impl<CTX> HashStable<CTX> for str {
     #[inline]
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
@@ -434,6 +484,22 @@ impl<CTX> HashStable<CTX> for bool {
     }
 }
 
+impl<T: HashStableEq> HashStableEq for Option<T> {
+    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<T, CTX> HashStable<CTX> for Option<T>
 where
     T: HashStable<CTX>,
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<K: Eq + Hash, V: Clone> CacheSelector<K, V> for DefaultCacheSelector {
+impl<K: HashStableEq + Hash, V: Clone> CacheSelector<K, V> for DefaultCacheSelector {
     type Cache = DefaultCache<K, V>;
 }
 
@@ -70,7 +72,7 @@ impl<K, V> Default for DefaultCache<K, V> {
     }
 }
 
-impl<K: Eq + Hash, V: Clone + Debug> QueryStorage for DefaultCache<K, V> {
+impl<K: HashStableEq + Hash, V: Clone + Debug> QueryStorage for DefaultCache<K, V> {
     type Value = V;
     type Stored = V;
 
@@ -83,11 +85,11 @@ impl<K: Eq + Hash, V: Clone + Debug> QueryStorage for DefaultCache<K, V> {
 
 impl<K, V> QueryCache for DefaultCache<K, V>
 where
-    K: Eq + Hash + Clone + Debug,
+    K: HashStableEq + Hash + Clone + Debug,
     V: Clone + Debug,
 {
     type Key = K;
-    type Sharded = FxHashMap<K, (V, DepNodeIndex)>;
+    type Sharded = FxHashMap<HashStableKey<K>, (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<K, V> for ArenaCacheSelector<'tcx> {
+impl<'tcx, K: HashStableEq + Hash, V: 'tcx> CacheSelector<K, V> 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<K, &'tcx (V, DepNodeIndex)>;
+    type Sharded = FxHashMap<HashStableKey<K>, &'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<K> {
     active: FxHashMap<K, QueryResult>,
 }
 
+#[derive(Copy, Clone, Hash)]
+#[repr(transparent)]
+pub struct HashStableKey<K>(pub K);
+
+impl<K> HashStableKey<K> {
+    pub fn from_ref(val: &K) -> &HashStableKey<K> {
+        unsafe { std::mem::transmute(val) }
+    }
+}
+
+impl<K: HashStableEq + Hash> PartialEq for HashStableKey<K> {
+    fn eq(&self, other: &Self) -> bool {
+        self.0.hash_stable_eq(&other.0)
+    }
+}
+
+impl<K: HashStableEq + Hash> Eq for HashStableKey<K> {}
+
 impl<K> Default for QueryStateShard<K> {
     fn default() -> QueryStateShard<K> {
         QueryStateShard { active: Default::default() }
@@ -92,7 +111,7 @@ enum QueryResult {
 
 impl<K> QueryState<K>
 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<K> Default for QueryState<K> {
 /// This will poison the relevant query if dropped.
 struct JobOwner<'tcx, K>
 where
-    K: Eq + Hash + Clone,
+    K: HashStableEq + Hash + Clone,
 {
     state: &'tcx QueryState<K>,
     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 <aa1ronham@gmail.com>
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<CTX> HashStable<CTX> 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<CTX> HashStable<CTX> 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<T: HashStableEq> 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<T: HashStable<CTX>, CTX> HashStable<CTX> for Vec<T> {
     }
 }
 
+impl<T: HashStableEq> HashStableEq for Vec<T> {
+    #[inline]
+    fn hash_stable_eq(&self, other: &Self) -> bool {
+        (&self[..]).hash_stable_eq(other)
+    }
+}
+
 impl<K, V, R, CTX> HashStable<CTX> for indexmap::IndexMap<K, V, R>
 where
     K: HashStable<CTX> + Eq + Hash,
@@ -469,6 +485,20 @@ impl<CTX> HashStable<CTX> 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<HCX> ToStableHashKey<HCX> for String {
     type KeyType = String;
     #[inline]
@@ -570,6 +600,12 @@ where
     }
 }
 
+impl<I: vec::Idx, T: HashStableEq> HashStableEq for vec::IndexVec<I, T> {
+    fn hash_stable_eq(&self, other: &Self) -> bool {
+        self.iter().as_slice().hash_stable_eq(other.iter().as_slice())
+    }
+}
+
 impl<I: vec::Idx, CTX> HashStable<CTX> for bit_set::BitSet<I> {
     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<ArgAbi<'a, Ty>>,
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 <aa1ronham@gmail.com>
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<T: ?Sized> {
     ptr: Box<T>,
 }
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<CTX> HashStable<CTX> for ::std::cmp::Ordering {
     }
 }
 
+impl<T1: HashStableEq, T2: HashStableEq> 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<T1: HashStable<CTX>, CTX> HashStable<CTX> for (T1,) {
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
         let (ref _0,) = *self;
@@ -445,6 +462,12 @@ impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for Box<T> {
     }
 }
 
+impl<T: ?Sized + HashStableEq> HashStableEq for Box<T> {
+    fn hash_stable_eq(&self, other: &Self) -> bool {
+        (**self).hash_stable_eq(other)
+    }
+}
+
 impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::std::rc::Rc<T> {
     #[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<T, CTX> HashStable<CTX> for ::std::mem::Discriminant<T> {
     #[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<VisibilityKind<'hir>>;
 
-#[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<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
     }
 }
 
+impl HashStableEq for HirId {
+    fn hash_stable_eq(&self, other: &HirId) -> bool {
+        self == other
+    }
+}
+
 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> 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 <aa1ronham@gmail.com>
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<Id = hir::HirId> {
     /// 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<ast::BinOpKind> for BinOpKind {
 pub type BinOp = Spanned<BinOpKind>;
 
 #[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 <pat>:<ty> = <expr>;`).
 #[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.
 /// `<pat> (if <guard>) => <body>`.
 #[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 <pat> = <expr>) { ... }`; 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<GeneratorKind> 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<BodyId>),
@@ -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<AnonConst> 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<Bar: Send>`.
     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<Symbol>, 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<VisibilityKind<'hir>>;
 
-#[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<Node<'hir>> 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 <aa1ronham@gmail.com>
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<T: HashStableEq> HashStableEq for Option<T> {
     }
 }
 
+impl<T: HashStableEq, E: HashStableEq> HashStableEq for Result<T, E> {
+    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 <aa1ronham@gmail.com>
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<Symbol>, issue: Option<NonZeroU32>, 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<OutputType, Option<PathBuf>>);
 
 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<Symbol>,
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 <aa1ronham@gmail.com>
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<StableHashingContext<'a>> 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<H: Hasher>(&self, s: &mut H) {
+        // Pointer hashing is sufficient (due to the unique contents
+        // assumption).
+        (self as *const TyS<'_>).hash(s)
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> 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 <aa1ronham@gmail.com>
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<T1: HashStableEq, T2: HashStableEq> HashStableEq for (T1, T2) {
     }
 }
 
+impl<T1: HashStableEq, T2: HashStableEq, T3: HashStableEq> 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<T1: HashStable<CTX>, CTX> HashStable<CTX> 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<T: PartialEq> PartialEq for List<T> {
     }
 }
 
+impl<T: HashStableEq> HashStableEq for List<T> {
+    fn hash_stable_eq(&self, other: &Self) -> bool {
+        // FIXME - is this right?
+        self == other
+    }
+}
+
 impl<T: Eq> Eq for List<T> {}
 
 impl<T> Ord for List<T>
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<DefId> {
 /// 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<T>` 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<BoundVariableKind>);
 
 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 <aa1ronham@gmail.com>
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<char>, 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<Symbol>, issue: Option<NonZeroU32>, 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<K: HashStable<CTX>, V: HashStable<CTX>, CTX> HashStable<CTX> for SortedMap<
     }
 }
 
+impl<K: HashStableEq, V: HashStableEq> HashStableEq for SortedMap<K, V> {
+    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<CTX> HashStable<CTX> 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<T: HashStableEq> HashStableEq for Vec<T> {
     }
 }
 
+impl<K: HashStableEq + Eq + Hash, V: HashStableEq, R: BuildHasher> HashStableEq for indexmap::IndexMap<K, V, R> {
+    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<T> HashStableEq for std::marker::PhantomData<T> {
+    fn hash_stable_eq(&self, other: &Self) -> bool {
+        true
+    }
+}
+
 impl<K, V, R, CTX> HashStable<CTX> for indexmap::IndexMap<K, V, R>
 where
     K: HashStable<CTX> + Eq + Hash,
@@ -463,6 +494,12 @@ where
     }
 }
 
+impl<A: smallvec::Array> HashStableEq for SmallVec<A> where <A as smallvec::Array>::Item: HashStableEq {
+    fn hash_stable_eq(&self, other: &Self) -> bool {
+        (&self[..]).hash_stable_eq(other)
+    }
+}
+
 impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for Box<T> {
     #[inline]
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
@@ -693,6 +730,49 @@ where
     }
 }
 
+impl<K, V, R> HashStableEq for ::std::collections::HashMap<K, V, R>
+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<K, R> HashStableEq for ::std::collections::HashSet<K, R>
+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<K, R, HCX> HashStable<HCX> for ::std::collections::HashSet<K, R>
 where
     K: ToStableHashKey<HCX> + 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<P, T> HashStableEq for CopyTaggedPtr<P, T, true>
+where
+    P: Pointer,
+    T: Tag,
+{
+    fn hash_stable_eq(&self, other: &Self) -> bool {
+        self == other
+    }
+}
+
 impl<P, T> std::hash::Hash for CopyTaggedPtr<P, T, true>
 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<LintStackIndex, LintSet>,
     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<Tag: Copy, Extra> Allocation<Tag, Extra> {
 }
 
 /// "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<Tag = AllocId>(SortedMap<Size, Tag>);
 
 impl<Tag> Relocations<Tag> {
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<Ty<'tcx>>,
@@ -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<GeneratorSavedLocal, Ty<'tcx>>,
@@ -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<u32, Symbol, &'tcx ty::AssocItem>,
 }
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<DefId>;
 /// 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<D>
 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<T: PartialEq> PartialEq for List<T> {
 
 impl<T: HashStableEq> HashStableEq for List<T> {
     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<T> {
     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<CTX> HashStable<CTX> 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 <aa1ronham@gmail.com>
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<Symbol>,
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<CTX> crate::ty::HashStable<CTX> 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<S: Encoder> Encodable<S> 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 <aa1ronham@gmail.com>
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<T1: HashStableEq, T2: HashStableEq> HashStableEq for (T1, T2) {
 
 impl<T1: HashStableEq, T2: HashStableEq, T3: HashStableEq> 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<T1: HashStable<CTX>, CTX> HashStable<CTX> for (T1,) {
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
         let (ref _0,) = *self;
@@ -396,7 +396,6 @@ impl<T: HashStableEq, const N: usize> HashStableEq for [T; N] {
     }
 }
 
-
 impl<T: HashStable<CTX>, CTX> HashStable<CTX> for [T] {
     default fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
         self.len().hash_stable(ctx, hasher);
@@ -436,16 +435,16 @@ impl<T: HashStableEq> HashStableEq for Vec<T> {
     }
 }
 
-impl<K: HashStableEq + Eq + Hash, V: HashStableEq, R: BuildHasher> HashStableEq for indexmap::IndexMap<K, V, R> {
+impl<K: HashStableEq + Eq + Hash, V: HashStableEq, R: BuildHasher> HashStableEq
+    for indexmap::IndexMap<K, V, R>
+{
     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<A: smallvec::Array> HashStableEq for SmallVec<A> where <A as smallvec::Array>::Item: HashStableEq {
+impl<A: smallvec::Array> HashStableEq for SmallVec<A>
+where
+    <A as smallvec::Array>::Item: HashStableEq,
+{
     fn hash_stable_eq(&self, other: &Self) -> bool {
         (&self[..]).hash_stable_eq(other)
     }
@@ -587,7 +589,7 @@ impl<T: HashStableEq> HashStableEq for Option<T> {
         match (self, other) {
             (Some(first), Some(second)) => first.hash_stable_eq(second),
             (None, None) => true,
-            _ => false
+            _ => false,
         }
     }
 }
@@ -597,7 +599,7 @@ impl<T: HashStableEq, E: HashStableEq> HashStableEq for Result<T, E> {
         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<Tag: Copy, Extra> Allocation<Tag, Extra> {
 }
 
 /// "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<Tag = AllocId>(SortedMap<Size, Tag>);
 
 impl<Tag> Relocations<Tag> {
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<DefId>;
 /// 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<D>
 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<T> {
     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 <aa1ronham@gmail.com>
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<K: HashStableEq + Eq + Hash, V: HashStableEq, R: BuildHasher> HashStableEq
 }
 
 impl<T> HashStableEq for std::marker::PhantomData<T> {
-    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 <aa1ronham@gmail.com>
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 <aa1ronham@gmail.com>
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 <aa1ronham@gmail.com>
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<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
     }
 }
 
-impl HashStableEq for HirId {
-    fn hash_stable_eq(&self, other: &HirId) -> bool {
-        self == other
-    }
-}
-
 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> 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<D: Decoder> Decodable<D> 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<A> <: T<B> iff A <: B -- e.g., function return type
     Invariant,     // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
@@ -560,12 +560,6 @@ impl<CTX> HashStable<CTX> 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 <aa1ronham@gmail.com>
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<H: Hasher>(&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<StableHashingContext<'a>> for TyS<'tcx> {
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> 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<C: QueryCache> QueryCacheStore<C> {
 }
 
 struct QueryStateShard<K> {
-    active: FxHashMap<K, QueryResult>,
+    active: FxHashMap<HashStableKey<K>, QueryResult>,
 }
 
 #[derive(Copy, Clone, Hash)]

From fbe0b2a21b3eb69b6ed45c994fd430395aea43a0 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
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 <aa1ronham@gmail.com>
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;