mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 15:32:06 +00:00
Auto merge of #117580 - compiler-errors:hash-stable-simplify-rustc_type_ir, r=jackh726
Add `HashStable_NoContext` to simplify `HashStable` implementations in `rustc_type_ir` adds `derive(HashStable_NoContext)` which is a derived `HashStable` implementation that has no `HashStableContext` bound, and which adds `where` bounds for `HashStable` based off of *fields* and not generics. This means we can `derive(HashStable_NoContext)` in more places in `rustc_type_ir` rather than having to hand-roll implementations.
This commit is contained in:
commit
7bd385dc37
@ -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);
|
||||
}
|
||||
|
||||
|
@ -38,51 +38,80 @@ fn parse_attributes(field: &syn::Field) -> Attributes {
|
||||
attrs
|
||||
}
|
||||
|
||||
pub(crate) fn hash_stable_generic_derive(
|
||||
mut s: synstructure::Structure<'_>,
|
||||
) -> proc_macro2::TokenStream {
|
||||
let generic: syn::GenericParam = parse_quote!(__CTX);
|
||||
s.add_bounds(synstructure::AddBounds::Generics);
|
||||
s.add_impl_generic(generic);
|
||||
s.add_where_predicate(parse_quote! { __CTX: crate::HashStableContext });
|
||||
|
||||
let discriminant = hash_stable_discriminant(&mut s);
|
||||
let body = hash_stable_body(&mut s);
|
||||
|
||||
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(s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
|
||||
hash_stable_derive_with_mode(s, HashStableMode::Normal)
|
||||
}
|
||||
|
||||
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);
|
||||
pub(crate) fn hash_stable_generic_derive(
|
||||
s: synstructure::Structure<'_>,
|
||||
) -> proc_macro2::TokenStream {
|
||||
hash_stable_derive_with_mode(s, HashStableMode::Generic)
|
||||
}
|
||||
|
||||
pub(crate) fn hash_stable_no_context_derive(
|
||||
s: synstructure::Structure<'_>,
|
||||
) -> proc_macro2::TokenStream {
|
||||
hash_stable_derive_with_mode(s, HashStableMode::NoContext)
|
||||
}
|
||||
|
||||
enum HashStableMode {
|
||||
// Use the query-system aware stable hashing context.
|
||||
Normal,
|
||||
// Emit a generic implementation that uses a crate-local `StableHashingContext`
|
||||
// trait, when the crate is upstream of `rustc_middle`.
|
||||
Generic,
|
||||
// Emit a hash-stable implementation that takes no context,
|
||||
// and emits per-field where clauses for (almost-)perfect derives.
|
||||
NoContext,
|
||||
}
|
||||
|
||||
fn hash_stable_derive_with_mode(
|
||||
mut s: synstructure::Structure<'_>,
|
||||
mode: HashStableMode,
|
||||
) -> proc_macro2::TokenStream {
|
||||
let generic: syn::GenericParam = match mode {
|
||||
HashStableMode::Normal => parse_quote!('__ctx),
|
||||
HashStableMode::Generic | HashStableMode::NoContext => parse_quote!(__CTX),
|
||||
};
|
||||
|
||||
// no_context impl is able to derive by-field, which is closer to a perfect derive.
|
||||
s.add_bounds(match mode {
|
||||
HashStableMode::Normal | HashStableMode::Generic => synstructure::AddBounds::Generics,
|
||||
HashStableMode::NoContext => synstructure::AddBounds::Fields,
|
||||
});
|
||||
|
||||
// For generic impl, add `where __CTX: HashStableContext`.
|
||||
match mode {
|
||||
HashStableMode::Normal => {}
|
||||
HashStableMode::Generic => {
|
||||
s.add_where_predicate(parse_quote! { __CTX: crate::HashStableContext });
|
||||
}
|
||||
HashStableMode::NoContext => {}
|
||||
}
|
||||
|
||||
s.add_impl_generic(generic);
|
||||
|
||||
let discriminant = hash_stable_discriminant(&mut s);
|
||||
let body = hash_stable_body(&mut s);
|
||||
|
||||
let context: syn::Type = match mode {
|
||||
HashStableMode::Normal => {
|
||||
parse_quote!(::rustc_query_system::ich::StableHashingContext<'__ctx>)
|
||||
}
|
||||
HashStableMode::Generic | HashStableMode::NoContext => parse_quote!(__CTX),
|
||||
};
|
||||
|
||||
s.bound_impl(
|
||||
quote!(
|
||||
::rustc_data_structures::stable_hasher::HashStable<
|
||||
::rustc_query_system::ich::StableHashingContext<'__ctx>,
|
||||
#context
|
||||
>
|
||||
),
|
||||
quote! {
|
||||
#[inline]
|
||||
fn hash_stable(
|
||||
&self,
|
||||
__hcx: &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
|
||||
__hcx: &mut #context,
|
||||
__hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) {
|
||||
#discriminant
|
||||
match *self { #body }
|
||||
|
@ -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);
|
||||
|
@ -123,5 +123,3 @@ impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> rustc_type_ir::HashStableContext for StableHashingContext<'ctx> {}
|
||||
|
@ -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<I: Interner, V> {
|
||||
pub value: V,
|
||||
pub max_universe: UniverseIndex,
|
||||
@ -61,19 +58,6 @@ impl<I: Interner, V> Canonical<I, V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<CTX: crate::HashStableContext, I: Interner, V: HashStable<CTX>> HashStable<CTX>
|
||||
for Canonical<I, V>
|
||||
where
|
||||
I::CanonicalVars: HashStable<CTX>,
|
||||
{
|
||||
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<I: Interner, V: Eq> Eq for Canonical<I, V> {}
|
||||
|
||||
impl<I: Interner, V: PartialEq> PartialEq for Canonical<I, V> {
|
||||
|
@ -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<I: Interner> {
|
||||
/// A const generic parameter.
|
||||
Param(I::ParamConst),
|
||||
@ -47,49 +47,6 @@ pub enum ConstKind<I: Interner> {
|
||||
Expr(I::ExprConst),
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
const fn const_kind_discriminant<I: Interner>(value: &ConstKind<I>) -> usize {
|
||||
match value {
|
||||
Param(_) => 0,
|
||||
Infer(_) => 1,
|
||||
Bound(_, _) => 2,
|
||||
Placeholder(_) => 3,
|
||||
Unevaluated(_) => 4,
|
||||
Value(_) => 5,
|
||||
Error(_) => 6,
|
||||
Expr(_) => 7,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for ConstKind<I>
|
||||
where
|
||||
I::ParamConst: HashStable<CTX>,
|
||||
I::BoundConst: HashStable<CTX>,
|
||||
I::PlaceholderConst: HashStable<CTX>,
|
||||
I::AliasConst: HashStable<CTX>,
|
||||
I::ValueConst: HashStable<CTX>,
|
||||
I::ErrorGuaranteed: HashStable<CTX>,
|
||||
I::ExprConst: HashStable<CTX>,
|
||||
{
|
||||
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<I: Interner> PartialEq for ConstKind<I> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
|
@ -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<T: std::fmt::Write>(
|
||||
}
|
||||
|
||||
#[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<A> <: T<B> 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 {}
|
||||
|
@ -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<I: Interner> {
|
||||
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
|
||||
/// the `Self` type of the trait reference and `A`, `B`, and `C`
|
||||
@ -68,47 +66,6 @@ impl<I: Interner> PartialEq for ClauseKind<I> {
|
||||
|
||||
impl<I: Interner> Eq for ClauseKind<I> {}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
fn clause_kind_discriminant<I: Interner>(value: &ClauseKind<I>) -> 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<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for ClauseKind<I>
|
||||
where
|
||||
I::Ty: HashStable<CTX>,
|
||||
I::Const: HashStable<CTX>,
|
||||
I::GenericArg: HashStable<CTX>,
|
||||
I::TraitPredicate: HashStable<CTX>,
|
||||
I::ProjectionPredicate: HashStable<CTX>,
|
||||
I::TypeOutlivesPredicate: HashStable<CTX>,
|
||||
I::RegionOutlivesPredicate: HashStable<CTX>,
|
||||
{
|
||||
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<I: Interner> TypeFoldable<I> for ClauseKind<I>
|
||||
where
|
||||
I::Ty: TypeFoldable<I>,
|
||||
@ -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<I: Interner> {
|
||||
/// Prove a clause
|
||||
Clause(ClauseKind<I>),
|
||||
@ -242,58 +199,6 @@ impl<I: Interner> PartialEq for PredicateKind<I> {
|
||||
|
||||
impl<I: Interner> Eq for PredicateKind<I> {}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
fn predicate_kind_discriminant<I: Interner>(value: &PredicateKind<I>) -> 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<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for PredicateKind<I>
|
||||
where
|
||||
I::DefId: HashStable<CTX>,
|
||||
I::Const: HashStable<CTX>,
|
||||
I::GenericArgs: HashStable<CTX>,
|
||||
I::Term: HashStable<CTX>,
|
||||
I::CoercePredicate: HashStable<CTX>,
|
||||
I::SubtypePredicate: HashStable<CTX>,
|
||||
I::ClosureKind: HashStable<CTX>,
|
||||
ClauseKind<I>: HashStable<CTX>,
|
||||
{
|
||||
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<I: Interner> TypeFoldable<I> for PredicateKind<I>
|
||||
where
|
||||
I::DefId: TypeFoldable<I>,
|
||||
@ -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,
|
||||
|
@ -263,7 +263,7 @@ impl<I: Interner> fmt::Debug for RegionKind<I> {
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
// This is not a derived impl because a derive would require `I: HashStable`
|
||||
impl<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for RegionKind<I>
|
||||
impl<CTX, I: Interner> HashStable<CTX> for RegionKind<I>
|
||||
where
|
||||
I::EarlyParamRegion: HashStable<CTX>,
|
||||
I::BoundRegion: HashStable<CTX>,
|
||||
|
@ -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 `<Type as Trait>::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<I: Interner> {
|
||||
/// The primitive boolean type. Written as `bool`.
|
||||
Bool,
|
||||
@ -472,120 +472,8 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
|
||||
}
|
||||
}
|
||||
|
||||
// This is not a derived impl because a derive would require `I: HashStable`
|
||||
#[cfg(feature = "nightly")]
|
||||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
impl<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for TyKind<I>
|
||||
where
|
||||
I::AdtDef: HashStable<CTX>,
|
||||
I::DefId: HashStable<CTX>,
|
||||
I::GenericArgs: HashStable<CTX>,
|
||||
I::Ty: HashStable<CTX>,
|
||||
I::Const: HashStable<CTX>,
|
||||
I::TypeAndMut: HashStable<CTX>,
|
||||
I::PolyFnSig: HashStable<CTX>,
|
||||
I::BoundExistentialPredicates: HashStable<CTX>,
|
||||
I::Region: HashStable<CTX>,
|
||||
I::Tys: HashStable<CTX>,
|
||||
I::AliasTy: HashStable<CTX>,
|
||||
I::BoundTy: HashStable<CTX>,
|
||||
I::ParamTy: HashStable<CTX>,
|
||||
I::PlaceholderTy: HashStable<CTX>,
|
||||
I::ErrorGuaranteed: HashStable<CTX>,
|
||||
{
|
||||
#[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,
|
||||
|
Loading…
Reference in New Issue
Block a user