From 426bc70ad661e6edd66949f3d938c0c07571dbc5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 4 Nov 2023 17:02:54 +0000 Subject: [PATCH] Add HashStable_NoContext to simplify HashStable implementations in rustc_type_ir --- compiler/rustc_ast/src/lib.rs | 4 +- compiler/rustc_macros/src/hash_stable.rs | 44 ++++++ compiler/rustc_macros/src/lib.rs | 7 + .../src/ich/impls_syntax.rs | 2 - compiler/rustc_type_ir/src/canonical.rs | 18 +-- compiler/rustc_type_ir/src/const_kind.rs | 45 +----- compiler/rustc_type_ir/src/lib.rs | 9 +- compiler/rustc_type_ir/src/predicate_kind.rs | 101 +------------- compiler/rustc_type_ir/src/region_kind.rs | 2 +- compiler/rustc_type_ir/src/ty_kind.rs | 128 ++---------------- 10 files changed, 69 insertions(+), 291 deletions(-) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 34303cbbc9a..7e713a49a8c 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -59,9 +59,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro /// instead of implementing everything in `rustc_middle`. -pub trait HashStableContext: - rustc_type_ir::HashStableContext + rustc_span::HashStableContext -{ +pub trait HashStableContext: rustc_span::HashStableContext { fn hash_attr(&mut self, _: &ast::Attribute, hasher: &mut StableHasher); } diff --git a/compiler/rustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs index 6d23b9ac99d..564e3a1edfa 100644 --- a/compiler/rustc_macros/src/hash_stable.rs +++ b/compiler/rustc_macros/src/hash_stable.rs @@ -64,6 +64,50 @@ pub(crate) fn hash_stable_generic_derive( ) } +pub(crate) fn hash_stable_no_context_derive( + mut s: synstructure::Structure<'_>, +) -> proc_macro2::TokenStream { + let generic: syn::GenericParam = parse_quote!(__CTX); + s.add_bounds(synstructure::AddBounds::Fields); + s.add_impl_generic(generic); + let body = s.each(|bi| { + let attrs = parse_attributes(bi.ast()); + if attrs.ignore { + quote! {} + } else if let Some(project) = attrs.project { + quote! { + (&#bi.#project).hash_stable(__hcx, __hasher); + } + } else { + quote! { + #bi.hash_stable(__hcx, __hasher); + } + } + }); + + let discriminant = match s.ast().data { + syn::Data::Enum(_) => quote! { + ::std::mem::discriminant(self).hash_stable(__hcx, __hasher); + }, + syn::Data::Struct(_) => quote! {}, + syn::Data::Union(_) => panic!("cannot derive on union"), + }; + + s.bound_impl( + quote!(::rustc_data_structures::stable_hasher::HashStable<__CTX>), + quote! { + #[inline] + fn hash_stable( + &self, + __hcx: &mut __CTX, + __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { + #discriminant + match *self { #body } + } + }, + ) +} + pub(crate) fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let generic: syn::GenericParam = parse_quote!('__ctx); s.add_bounds(synstructure::AddBounds::Generics); diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 2775bd5f629..f558b74be9a 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -48,6 +48,13 @@ decl_derive!( [HashStable_Generic, attributes(stable_hasher)] => hash_stable::hash_stable_generic_derive ); +decl_derive!( + [HashStable_NoContext] => + /// `HashStable` implementation that has no `HashStableContext` bound and + /// which adds `where` bounds for `HashStable` based off of fields and not + /// generics. This is suitable for use in crates like `rustc_type_ir`. + hash_stable::hash_stable_no_context_derive +); decl_derive!([Decodable] => serialize::decodable_derive); decl_derive!([Encodable] => serialize::encodable_derive); diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index b2177be0e36..81a7eb604f5 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -123,5 +123,3 @@ impl<'tcx> HashStable> for rustc_feature::Features { }); } } - -impl<'ctx> rustc_type_ir::HashStableContext for StableHashingContext<'ctx> {} diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index a0e4b4ecbfc..9f170c5b4db 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -2,9 +2,6 @@ use std::fmt; use std::hash::Hash; use std::ops::ControlFlow; -#[cfg(feature = "nightly")] -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; - use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::visit::{TypeVisitable, TypeVisitor}; use crate::{Interner, UniverseIndex}; @@ -14,7 +11,7 @@ use crate::{Interner, UniverseIndex}; /// numbered starting from 0 in order of first appearance. #[derive(derivative::Derivative)] #[derivative(Clone(bound = "V: Clone"), Hash(bound = "V: Hash"))] -#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub struct Canonical { pub value: V, pub max_universe: UniverseIndex, @@ -61,19 +58,6 @@ impl Canonical { } } -#[cfg(feature = "nightly")] -impl> HashStable - for Canonical -where - I::CanonicalVars: HashStable, -{ - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - self.value.hash_stable(hcx, hasher); - self.max_universe.hash_stable(hcx, hasher); - self.variables.hash_stable(hcx, hasher); - } -} - impl Eq for Canonical {} impl PartialEq for Canonical { diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 1cdd51d68dc..a5f90421de5 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -16,7 +16,7 @@ use self::ConstKind::*; Ord = "feature_allow_slow_enum", Hash(bound = "") )] -#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum ConstKind { /// A const generic parameter. Param(I::ParamConst), @@ -47,49 +47,6 @@ pub enum ConstKind { Expr(I::ExprConst), } -#[cfg(feature = "nightly")] -const fn const_kind_discriminant(value: &ConstKind) -> usize { - match value { - Param(_) => 0, - Infer(_) => 1, - Bound(_, _) => 2, - Placeholder(_) => 3, - Unevaluated(_) => 4, - Value(_) => 5, - Error(_) => 6, - Expr(_) => 7, - } -} - -#[cfg(feature = "nightly")] -impl HashStable for ConstKind -where - I::ParamConst: HashStable, - I::BoundConst: HashStable, - I::PlaceholderConst: HashStable, - I::AliasConst: HashStable, - I::ValueConst: HashStable, - I::ErrorGuaranteed: HashStable, - I::ExprConst: HashStable, -{ - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - const_kind_discriminant(self).hash_stable(hcx, hasher); - match self { - Param(p) => p.hash_stable(hcx, hasher), - Infer(i) => i.hash_stable(hcx, hasher), - Bound(d, b) => { - d.hash_stable(hcx, hasher); - b.hash_stable(hcx, hasher); - } - Placeholder(p) => p.hash_stable(hcx, hasher), - Unevaluated(u) => u.hash_stable(hcx, hasher), - Value(v) => v.hash_stable(hcx, hasher), - Error(e) => e.hash_stable(hcx, hasher), - Expr(e) => e.hash_stable(hcx, hasher), - } - } -} - impl PartialEq for ConstKind { fn eq(&self, other: &Self) -> bool { match (self, other) { diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index ba558aa3418..acea7aa46f6 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -51,9 +51,6 @@ pub use region_kind::*; pub use ty_info::*; pub use ty_kind::*; -/// Needed so we can use #[derive(HashStable_Generic)] -pub trait HashStableContext {} - rustc_index::newtype_index! { /// A [De Bruijn index][dbi] is a standard means of representing /// regions (and perhaps later types) in a higher-ranked setting. In @@ -94,7 +91,7 @@ rustc_index::newtype_index! { /// is the outer fn. /// /// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index - #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] + #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] #[debug_format = "DebruijnIndex({})"] #[gate_rustc_only] pub struct DebruijnIndex { @@ -179,7 +176,7 @@ pub fn debug_bound_var( } #[derive(Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "nightly", derive(Decodable, Encodable, Hash, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Decodable, Encodable, Hash, HashStable_NoContext))] #[cfg_attr(feature = "nightly", rustc_pass_by_value)] pub enum Variance { Covariant, // T <: T iff A <: B -- e.g., function return type @@ -295,7 +292,7 @@ rustc_index::newtype_index! { /// declared, but a type name in a non-zero universe is a placeholder /// type -- an idealized representative of "types in general" that we /// use for checking generic functions. - #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] + #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] #[debug_format = "U{}"] #[gate_rustc_only] pub struct UniverseIndex {} diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index c2ba6afc8d0..da041ab1f35 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -1,5 +1,3 @@ -#[cfg(feature = "nightly")] -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use std::fmt; use std::ops::ControlFlow; @@ -11,7 +9,7 @@ use crate::Interner; /// by implied bounds. #[derive(derivative::Derivative)] #[derivative(Clone(bound = ""), Hash(bound = ""))] -#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum ClauseKind { /// Corresponds to `where Foo: Bar`. `Foo` here would be /// the `Self` type of the trait reference and `A`, `B`, and `C` @@ -68,47 +66,6 @@ impl PartialEq for ClauseKind { impl Eq for ClauseKind {} -#[cfg(feature = "nightly")] -fn clause_kind_discriminant(value: &ClauseKind) -> usize { - match value { - ClauseKind::Trait(_) => 0, - ClauseKind::RegionOutlives(_) => 1, - ClauseKind::TypeOutlives(_) => 2, - ClauseKind::Projection(_) => 3, - ClauseKind::ConstArgHasType(_, _) => 4, - ClauseKind::WellFormed(_) => 5, - ClauseKind::ConstEvaluatable(_) => 6, - } -} - -#[cfg(feature = "nightly")] -impl HashStable for ClauseKind -where - I::Ty: HashStable, - I::Const: HashStable, - I::GenericArg: HashStable, - I::TraitPredicate: HashStable, - I::ProjectionPredicate: HashStable, - I::TypeOutlivesPredicate: HashStable, - I::RegionOutlivesPredicate: HashStable, -{ - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - clause_kind_discriminant(self).hash_stable(hcx, hasher); - match self { - ClauseKind::Trait(p) => p.hash_stable(hcx, hasher), - ClauseKind::RegionOutlives(p) => p.hash_stable(hcx, hasher), - ClauseKind::TypeOutlives(p) => p.hash_stable(hcx, hasher), - ClauseKind::Projection(p) => p.hash_stable(hcx, hasher), - ClauseKind::ConstArgHasType(c, t) => { - c.hash_stable(hcx, hasher); - t.hash_stable(hcx, hasher); - } - ClauseKind::WellFormed(t) => t.hash_stable(hcx, hasher), - ClauseKind::ConstEvaluatable(c) => c.hash_stable(hcx, hasher), - } - } -} - impl TypeFoldable for ClauseKind where I::Ty: TypeFoldable, @@ -164,7 +121,7 @@ where #[derive(derivative::Derivative)] #[derivative(Clone(bound = ""), Hash(bound = ""))] -#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum PredicateKind { /// Prove a clause Clause(ClauseKind), @@ -242,58 +199,6 @@ impl PartialEq for PredicateKind { impl Eq for PredicateKind {} -#[cfg(feature = "nightly")] -fn predicate_kind_discriminant(value: &PredicateKind) -> usize { - match value { - PredicateKind::Clause(_) => 0, - PredicateKind::ObjectSafe(_) => 1, - PredicateKind::ClosureKind(_, _, _) => 2, - PredicateKind::Subtype(_) => 3, - PredicateKind::Coerce(_) => 4, - PredicateKind::ConstEquate(_, _) => 5, - PredicateKind::Ambiguous => 6, - PredicateKind::AliasRelate(_, _, _) => 7, - } -} - -#[cfg(feature = "nightly")] -impl HashStable for PredicateKind -where - I::DefId: HashStable, - I::Const: HashStable, - I::GenericArgs: HashStable, - I::Term: HashStable, - I::CoercePredicate: HashStable, - I::SubtypePredicate: HashStable, - I::ClosureKind: HashStable, - ClauseKind: HashStable, -{ - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - predicate_kind_discriminant(self).hash_stable(hcx, hasher); - match self { - PredicateKind::Clause(p) => p.hash_stable(hcx, hasher), - PredicateKind::ObjectSafe(d) => d.hash_stable(hcx, hasher), - PredicateKind::ClosureKind(d, g, k) => { - d.hash_stable(hcx, hasher); - g.hash_stable(hcx, hasher); - k.hash_stable(hcx, hasher); - } - PredicateKind::Subtype(p) => p.hash_stable(hcx, hasher), - PredicateKind::Coerce(p) => p.hash_stable(hcx, hasher), - PredicateKind::ConstEquate(c1, c2) => { - c1.hash_stable(hcx, hasher); - c2.hash_stable(hcx, hasher); - } - PredicateKind::Ambiguous => {} - PredicateKind::AliasRelate(t1, t2, r) => { - t1.hash_stable(hcx, hasher); - t2.hash_stable(hcx, hasher); - r.hash_stable(hcx, hasher); - } - } - } -} - impl TypeFoldable for PredicateKind where I::DefId: TypeFoldable, @@ -366,7 +271,7 @@ where } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] -#[cfg_attr(feature = "nightly", derive(HashStable_Generic, Encodable, Decodable))] +#[cfg_attr(feature = "nightly", derive(HashStable_NoContext, Encodable, Decodable))] pub enum AliasRelationDirection { Equate, Subtype, diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index ddd10db1c6c..4157d49287c 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -263,7 +263,7 @@ impl fmt::Debug for RegionKind { #[cfg(feature = "nightly")] // This is not a derived impl because a derive would require `I: HashStable` -impl HashStable for RegionKind +impl HashStable for RegionKind where I::EarlyParamRegion: HashStable, I::BoundRegion: HashStable, diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 53446c41f31..494eeaf3dc8 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -14,7 +14,7 @@ use self::TyKind::*; /// The movability of a coroutine / closure literal: /// whether a coroutine contains self-references, causing it to be `!Unpin`. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] pub enum Movability { /// May contain self-references, `!Unpin`. Static, @@ -23,7 +23,7 @@ pub enum Movability { } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] pub enum Mutability { // N.B. Order is deliberate, so that Not < Mut Not, @@ -75,7 +75,7 @@ impl Mutability { /// Specifies how a trait object is represented. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] pub enum DynKind { /// An unsized `dyn Trait` object Dyn, @@ -89,7 +89,7 @@ pub enum DynKind { } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] pub enum AliasKind { /// A projection `::AssocType`. /// Can get normalized away if monomorphic enough. @@ -119,7 +119,7 @@ pub enum AliasKind { Ord = "feature_allow_slow_enum", Hash(bound = "") )] -#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum TyKind { /// The primitive boolean type. Written as `bool`. Bool, @@ -472,120 +472,8 @@ impl fmt::Debug for TyKind { } } -// This is not a derived impl because a derive would require `I: HashStable` -#[cfg(feature = "nightly")] -#[allow(rustc::usage_of_ty_tykind)] -impl HashStable for TyKind -where - I::AdtDef: HashStable, - I::DefId: HashStable, - I::GenericArgs: HashStable, - I::Ty: HashStable, - I::Const: HashStable, - I::TypeAndMut: HashStable, - I::PolyFnSig: HashStable, - I::BoundExistentialPredicates: HashStable, - I::Region: HashStable, - I::Tys: HashStable, - I::AliasTy: HashStable, - I::BoundTy: HashStable, - I::ParamTy: HashStable, - I::PlaceholderTy: HashStable, - I::ErrorGuaranteed: HashStable, -{ - #[inline] - fn hash_stable(&self, __hcx: &mut CTX, __hasher: &mut StableHasher) { - std::mem::discriminant(self).hash_stable(__hcx, __hasher); - match self { - Bool => {} - Char => {} - Int(i) => { - i.hash_stable(__hcx, __hasher); - } - Uint(u) => { - u.hash_stable(__hcx, __hasher); - } - Float(f) => { - f.hash_stable(__hcx, __hasher); - } - Adt(adt, args) => { - adt.hash_stable(__hcx, __hasher); - args.hash_stable(__hcx, __hasher); - } - Foreign(def_id) => { - def_id.hash_stable(__hcx, __hasher); - } - Str => {} - Array(t, c) => { - t.hash_stable(__hcx, __hasher); - c.hash_stable(__hcx, __hasher); - } - Slice(t) => { - t.hash_stable(__hcx, __hasher); - } - RawPtr(tam) => { - tam.hash_stable(__hcx, __hasher); - } - Ref(r, t, m) => { - r.hash_stable(__hcx, __hasher); - t.hash_stable(__hcx, __hasher); - m.hash_stable(__hcx, __hasher); - } - FnDef(def_id, args) => { - def_id.hash_stable(__hcx, __hasher); - args.hash_stable(__hcx, __hasher); - } - FnPtr(polyfnsig) => { - polyfnsig.hash_stable(__hcx, __hasher); - } - Dynamic(l, r, repr) => { - l.hash_stable(__hcx, __hasher); - r.hash_stable(__hcx, __hasher); - repr.hash_stable(__hcx, __hasher); - } - Closure(def_id, args) => { - def_id.hash_stable(__hcx, __hasher); - args.hash_stable(__hcx, __hasher); - } - Coroutine(def_id, args, m) => { - def_id.hash_stable(__hcx, __hasher); - args.hash_stable(__hcx, __hasher); - m.hash_stable(__hcx, __hasher); - } - CoroutineWitness(def_id, args) => { - def_id.hash_stable(__hcx, __hasher); - args.hash_stable(__hcx, __hasher); - } - Never => {} - Tuple(args) => { - args.hash_stable(__hcx, __hasher); - } - Alias(k, p) => { - k.hash_stable(__hcx, __hasher); - p.hash_stable(__hcx, __hasher); - } - Param(p) => { - p.hash_stable(__hcx, __hasher); - } - Bound(d, b) => { - d.hash_stable(__hcx, __hasher); - b.hash_stable(__hcx, __hasher); - } - Placeholder(p) => { - p.hash_stable(__hcx, __hasher); - } - Infer(i) => { - i.hash_stable(__hcx, __hasher); - } - Error(d) => { - d.hash_stable(__hcx, __hasher); - } - } - } -} - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] pub enum IntTy { Isize, I8, @@ -643,7 +531,7 @@ impl IntTy { } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] pub enum UintTy { Usize, U8, @@ -701,7 +589,7 @@ impl UintTy { } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] pub enum FloatTy { F32, F64,