diff --git a/Cargo.lock b/Cargo.lock index d5d66f8998710..2fab6f8a05b38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3837,6 +3837,7 @@ dependencies = [ "log", "rustc_data_structures", "rustc_index", + "rustc_macros", "serialize", "syntax_pos", ] @@ -4404,6 +4405,7 @@ dependencies = [ "rustc_errors", "rustc_index", "rustc_lexer", + "rustc_macros", "scoped-tls", "serialize", "smallvec 1.0.0", diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 816e93698bce9..39d1f850f45ef 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -213,11 +213,6 @@ impl<'a> HashStable> for hir::ImplItem { } } -impl_stable_hash_for!(enum ast::CrateSugar { - JustCrate, - PubCrate, -}); - impl<'a> HashStable> for hir::VisibilityKind { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); diff --git a/src/librustc/ich/impls_misc.rs b/src/librustc/ich/impls_misc.rs deleted file mode 100644 index 417305139e472..0000000000000 --- a/src/librustc/ich/impls_misc.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! This module contains `HashStable` implementations for various data types -//! that don't fit into any of the other impls_xxx modules. - -impl_stable_hash_for!(enum ::rustc_target::spec::PanicStrategy { - Abort, - Unwind -}); diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index b3d82e5522cf2..f8bf8f4ab8a2f 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -10,135 +10,12 @@ use syntax::ast; use syntax::feature_gate; use syntax::token; use syntax::tokenstream; -use syntax_pos::symbol::SymbolStr; use syntax_pos::SourceFile; use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX}; use smallvec::SmallVec; -use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher}; - -impl<'a> HashStable> for SymbolStr { - #[inline] - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let str = self as &str; - str.hash_stable(hcx, hasher) - } -} - -impl<'a> ToStableHashKey> for SymbolStr { - type KeyType = SymbolStr; - - #[inline] - fn to_stable_hash_key(&self, - _: &StableHashingContext<'a>) - -> SymbolStr { - self.clone() - } -} - -impl<'a> HashStable> for ast::Name { - #[inline] - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - self.as_str().hash_stable(hcx, hasher); - } -} - -impl<'a> ToStableHashKey> for ast::Name { - type KeyType = SymbolStr; - - #[inline] - fn to_stable_hash_key(&self, - _: &StableHashingContext<'a>) - -> SymbolStr { - self.as_str() - } -} - -impl_stable_hash_for!(enum ::syntax::ast::AsmDialect { - Att, - Intel -}); - -impl_stable_hash_for!(enum ::syntax_pos::hygiene::MacroKind { - Bang, - Attr, - Derive, -}); - - -impl_stable_hash_for!(enum ::rustc_target::spec::abi::Abi { - Cdecl, - Stdcall, - Fastcall, - Vectorcall, - Thiscall, - Aapcs, - Win64, - SysV64, - PtxKernel, - Msp430Interrupt, - X86Interrupt, - AmdGpuKernel, - EfiApi, - Rust, - C, - System, - RustIntrinsic, - RustCall, - PlatformIntrinsic, - Unadjusted -}); - -impl_stable_hash_for!(struct ::syntax::attr::Deprecation { since, note }); -impl_stable_hash_for!(struct ::syntax::attr::Stability { - level, - feature, - rustc_depr, - promotable, - allow_const_fn_ptr, - const_stability -}); - -impl_stable_hash_for!(enum ::syntax::edition::Edition { - Edition2015, - Edition2018, -}); - -impl<'a> HashStable> -for ::syntax::attr::StabilityLevel { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - mem::discriminant(self).hash_stable(hcx, hasher); - match *self { - ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue, ref is_soft } => { - reason.hash_stable(hcx, hasher); - issue.hash_stable(hcx, hasher); - is_soft.hash_stable(hcx, hasher); - } - ::syntax::attr::StabilityLevel::Stable { ref since } => { - since.hash_stable(hcx, hasher); - } - } - } -} - -impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason, suggestion }); - -impl_stable_hash_for!(enum ::syntax::attr::IntType { - SignedInt(int_ty), - UnsignedInt(uint_ty) -}); - -impl_stable_hash_for!(enum ::syntax::ast::LitIntType { - Signed(int_ty), - Unsigned(int_ty), - Unsuffixed -}); - -impl_stable_hash_for!(enum ::syntax::ast::LitFloatType { - Suffixed(float_ty), - Unsuffixed -}); +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; impl_stable_hash_for!(struct ::syntax::ast::Lit { kind, @@ -146,32 +23,9 @@ impl_stable_hash_for!(struct ::syntax::ast::Lit { span }); -impl_stable_hash_for!(enum ::syntax::ast::LitKind { - Str(value, style), - ByteStr(value), - Byte(value), - Char(value), - Int(value, lit_int_type), - Float(value, lit_float_type), - Bool(value), - Err(value) -}); - impl_stable_hash_for_spanned!(::syntax::ast::LitKind); -impl_stable_hash_for!(enum ::syntax::ast::IntTy { Isize, I8, I16, I32, I64, I128 }); -impl_stable_hash_for!(enum ::syntax::ast::UintTy { Usize, U8, U16, U32, U64, U128 }); -impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 }); -impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal }); -impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst }); -impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final }); impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, ident }); -impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) }); -impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner }); -impl_stable_hash_for!(enum ::syntax::ast::Movability { Static, Movable }); -impl_stable_hash_for!(enum ::syntax::ast::CaptureBy { Value, Ref }); -impl_stable_hash_for!(enum ::syntax::ast::IsAuto { Yes, No }); -impl_stable_hash_for!(enum ::syntax::ast::ImplPolarity { Positive, Negative }); impl<'a> HashStable> for [ast::Attribute] { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { @@ -255,25 +109,6 @@ for tokenstream::TokenStream { } } -impl_stable_hash_for!(enum token::LitKind { - Bool, - Byte, - Char, - Integer, - Float, - Str, - ByteStr, - StrRaw(n), - ByteStrRaw(n), - Err -}); - -impl_stable_hash_for!(struct token::Lit { - kind, - symbol, - suffix -}); - impl<'a> HashStable> for token::TokenKind { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); @@ -359,12 +194,6 @@ impl_stable_hash_for!(enum ::syntax::ast::MetaItemKind { NameValue(lit) }); -impl_stable_hash_for!(enum ::syntax_pos::hygiene::Transparency { - Transparent, - SemiTransparent, - Opaque, -}); - impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData { kind, parent -> _, @@ -376,43 +205,6 @@ impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData { edition }); -impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnKind { - Root, - Macro(kind, descr), - AstPass(kind), - Desugaring(kind) -}); - -impl_stable_hash_for!(enum ::syntax_pos::hygiene::AstPass { - StdImports, - TestHarness, - ProcMacroHarness, - PluginMacroDefs, -}); - -impl_stable_hash_for!(enum ::syntax_pos::hygiene::DesugaringKind { - CondTemporary, - Async, - Await, - QuestionMark, - OpaqueTy, - ForLoop, - TryBlock -}); - -impl_stable_hash_for!(enum ::syntax_pos::FileName { - Real(pb), - Macros(s), - QuoteExpansion(s), - Anon(s), - MacroExpansion(s), - ProcMacroSourceCode(s), - CliCrateAttr(s), - CfgSpec(s), - Custom(s), - DocTest(pb, line), -}); - impl<'a> HashStable> for SourceFile { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let SourceFile { diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index c643baf11254c..7f50d859cde3a 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -159,11 +159,6 @@ where } } -impl_stable_hash_for!(enum ::syntax::ast::Mutability { - Immutable, - Mutable -}); - impl<'a> ToStableHashKey> for region::Scope { type KeyType = region::Scope; diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index f3fc7ec8fda15..9e985ffb14ca7 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -10,7 +10,6 @@ mod caching_source_map_view; mod hcx; mod impls_hir; -mod impls_misc; mod impls_ty; mod impls_syntax; diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 972452601ddd5..1400d5fb899ab 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -2327,158 +2327,6 @@ where } } -impl<'a> HashStable> for Variants { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use crate::ty::layout::Variants::*; - mem::discriminant(self).hash_stable(hcx, hasher); - - match *self { - Single { index } => { - index.hash_stable(hcx, hasher); - } - Multiple { - ref discr, - ref discr_kind, - discr_index, - ref variants, - } => { - discr.hash_stable(hcx, hasher); - discr_kind.hash_stable(hcx, hasher); - discr_index.hash_stable(hcx, hasher); - variants.hash_stable(hcx, hasher); - } - } - } -} - -impl<'a> HashStable> for DiscriminantKind { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use crate::ty::layout::DiscriminantKind::*; - mem::discriminant(self).hash_stable(hcx, hasher); - - match *self { - Tag => {} - Niche { - dataful_variant, - ref niche_variants, - niche_start, - } => { - dataful_variant.hash_stable(hcx, hasher); - niche_variants.start().hash_stable(hcx, hasher); - niche_variants.end().hash_stable(hcx, hasher); - niche_start.hash_stable(hcx, hasher); - } - } - } -} - -impl<'a> HashStable> for FieldPlacement { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use crate::ty::layout::FieldPlacement::*; - mem::discriminant(self).hash_stable(hcx, hasher); - - match *self { - Union(count) => { - count.hash_stable(hcx, hasher); - } - Array { count, stride } => { - count.hash_stable(hcx, hasher); - stride.hash_stable(hcx, hasher); - } - Arbitrary { ref offsets, ref memory_index } => { - offsets.hash_stable(hcx, hasher); - memory_index.hash_stable(hcx, hasher); - } - } - } -} - -impl<'a> HashStable> for VariantIdx { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - self.as_u32().hash_stable(hcx, hasher) - } -} - -impl<'a> HashStable> for Abi { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use crate::ty::layout::Abi::*; - mem::discriminant(self).hash_stable(hcx, hasher); - - match *self { - Uninhabited => {} - Scalar(ref value) => { - value.hash_stable(hcx, hasher); - } - ScalarPair(ref a, ref b) => { - a.hash_stable(hcx, hasher); - b.hash_stable(hcx, hasher); - } - Vector { ref element, count } => { - element.hash_stable(hcx, hasher); - count.hash_stable(hcx, hasher); - } - Aggregate { sized } => { - sized.hash_stable(hcx, hasher); - } - } - } -} - -impl<'a> HashStable> for Scalar { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let Scalar { value, ref valid_range } = *self; - value.hash_stable(hcx, hasher); - valid_range.start().hash_stable(hcx, hasher); - valid_range.end().hash_stable(hcx, hasher); - } -} - -impl_stable_hash_for!(struct crate::ty::layout::Niche { - offset, - scalar -}); - -impl_stable_hash_for!(struct crate::ty::layout::LayoutDetails { - variants, - fields, - abi, - largest_niche, - size, - align -}); - -impl_stable_hash_for!(enum crate::ty::layout::Integer { - I8, - I16, - I32, - I64, - I128 -}); - -impl_stable_hash_for!(enum crate::ty::layout::Primitive { - Int(integer, signed), - F32, - F64, - Pointer -}); - -impl_stable_hash_for!(struct crate::ty::layout::AbiAndPrefAlign { - abi, - pref -}); - -impl<'tcx> HashStable> for Align { - fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) { - self.bytes().hash_stable(hcx, hasher); - } -} - -impl<'tcx> HashStable> for Size { - fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) { - self.bytes().hash_stable(hcx, hasher); - } -} - impl<'a, 'tcx> HashStable> for LayoutError<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { use crate::ty::layout::LayoutError::*; diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index 092208cfe1db7..ce62021ac1711 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -429,6 +429,16 @@ impl HashStable for ::std::mem::Discriminant { } } +impl HashStable for ::std::ops::RangeInclusive + where T: HashStable +{ + #[inline] + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + self.start().hash_stable(ctx, hasher); + self.end().hash_stable(ctx, hasher); + } +} + impl HashStable for vec::IndexVec where T: HashStable, { diff --git a/src/librustc_macros/src/hash_stable.rs b/src/librustc_macros/src/hash_stable.rs index 735cfb11b365c..3fb252cbf8d9c 100644 --- a/src/librustc_macros/src/hash_stable.rs +++ b/src/librustc_macros/src/hash_stable.rs @@ -47,6 +47,44 @@ fn parse_attributes(field: &syn::Field) -> Attributes { attrs } +pub 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); + 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!{ + fn hash_stable( + &self, + __hcx: &mut __CTX, + __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { + #discriminant + match *self { #body } + } + }) +} + pub 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/src/librustc_macros/src/lib.rs b/src/librustc_macros/src/lib.rs index dce3820d2842c..eee634ffebd92 100644 --- a/src/librustc_macros/src/lib.rs +++ b/src/librustc_macros/src/lib.rs @@ -25,5 +25,10 @@ pub fn symbols(input: TokenStream) -> TokenStream { } decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive); +decl_derive!( + [HashStable_Generic, attributes(stable_hasher)] => + hash_stable::hash_stable_generic_derive +); + decl_derive!([TypeFoldable, attributes(type_foldable)] => type_foldable::type_foldable_derive); decl_derive!([Lift, attributes(lift)] => lift::lift_derive); diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml index c73d0adea38da..0e0732490fbbd 100644 --- a/src/librustc_target/Cargo.toml +++ b/src/librustc_target/Cargo.toml @@ -12,6 +12,7 @@ path = "lib.rs" bitflags = "1.2.1" log = "0.4" rustc_data_structures = { path = "../librustc_data_structures" } +rustc_macros = { path = "../librustc_macros" } rustc_serialize = { path = "../libserialize", package = "serialize" } syntax_pos = { path = "../libsyntax_pos" } rustc_index = { path = "../librustc_index" } diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 2d7e05037ba0d..ac781819cc35e 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -6,6 +6,7 @@ use crate::spec::Target; use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive}; use rustc_index::vec::{Idx, IndexVec}; +use rustc_macros::HashStable_Generic; use syntax_pos::Span; pub mod call; @@ -242,6 +243,7 @@ pub enum Endian { /// Size of a type in bytes. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(HashStable_Generic)] pub struct Size { raw: u64 } @@ -365,6 +367,7 @@ impl AddAssign for Size { /// Alignment of a type in bytes (always a power of two). #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(HashStable_Generic)] pub struct Align { pow2: u8, } @@ -423,6 +426,7 @@ impl Align { /// A pair of aligments, ABI-mandated and preferred. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(HashStable_Generic)] pub struct AbiAndPrefAlign { pub abi: Align, pub pref: Align, @@ -452,7 +456,7 @@ impl AbiAndPrefAlign { } /// Integers, also used for enum discriminants. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, HashStable_Generic)] pub enum Integer { I8, I16, @@ -533,7 +537,7 @@ impl Integer { } /// Fundamental unit of memory access and layout. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum Primitive { /// The `bool` is the signedness of the `Integer` type. /// @@ -588,6 +592,7 @@ impl Primitive { /// Information about one scalar component of a Rust type. #[derive(Clone, PartialEq, Eq, Hash, Debug)] +#[derive(HashStable_Generic)] pub struct Scalar { pub value: Primitive, @@ -636,7 +641,7 @@ impl Scalar { } /// Describes how the fields of a type are located in memory. -#[derive(PartialEq, Eq, Hash, Debug)] +#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum FieldPlacement { /// All fields start at no offset. The `usize` is the field count. /// @@ -752,7 +757,7 @@ impl FieldPlacement { /// Describes how values of the type are passed by target ABIs, /// in terms of categories of C types there are ABI rules for. -#[derive(Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum Abi { Uninhabited, Scalar(Scalar), @@ -800,10 +805,12 @@ impl Abi { } rustc_index::newtype_index! { - pub struct VariantIdx { .. } + pub struct VariantIdx { + derive [HashStable_Generic] + } } -#[derive(PartialEq, Eq, Hash, Debug)] +#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum Variants { /// Single enum variants, structs/tuples, unions, and all non-ADTs. Single { @@ -821,7 +828,7 @@ pub enum Variants { }, } -#[derive(PartialEq, Eq, Hash, Debug)] +#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum DiscriminantKind { /// Integer tag holding the discriminant value itself. Tag, @@ -842,7 +849,7 @@ pub enum DiscriminantKind { }, } -#[derive(Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub struct Niche { pub offset: Size, pub scalar: Scalar, @@ -906,7 +913,7 @@ impl Niche { } } -#[derive(PartialEq, Eq, Hash, Debug)] +#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub struct LayoutDetails { pub variants: Variants, pub fields: FieldPlacement, diff --git a/src/librustc_target/spec/abi.rs b/src/librustc_target/spec/abi.rs index 3a24d30966f63..736358a995b64 100644 --- a/src/librustc_target/spec/abi.rs +++ b/src/librustc_target/spec/abi.rs @@ -1,9 +1,12 @@ use std::fmt; +use rustc_macros::HashStable_Generic; + #[cfg(test)] mod tests; -#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, + Clone, Copy, Debug, HashStable_Generic)] pub enum Abi { // N.B., this ordering MUST match the AbiDatas array below. // (This is ensured by the test indices_are_correct().) diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 4cd2f13d09cbd..716aef056a35b 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -42,6 +42,8 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use crate::spec::abi::{Abi, lookup as lookup_abi}; +use rustc_macros::HashStable_Generic; + pub mod abi; mod android_base; mod apple_base; @@ -153,7 +155,7 @@ flavor_mappings! { ((LinkerFlavor::Lld(LldFlavor::Link)), "lld-link"), } -#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable, HashStable_Generic)] pub enum PanicStrategy { Unwind, Abort, diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index d96b5b7a3dde4..dff23076c82e6 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -20,5 +20,6 @@ errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_index = { path = "../librustc_index" } rustc_lexer = { path = "../librustc_lexer" } +rustc_macros = { path = "../librustc_macros" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_error_codes = { path = "../librustc_error_codes" } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bbf00825acb33..a9f03e4af5b65 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -37,6 +37,7 @@ use rustc_data_structures::sync::Lrc; use rustc_data_structures::thin_vec::ThinVec; use rustc_index::vec::Idx; use rustc_serialize::{self, Decoder, Encoder}; +use rustc_macros::HashStable_Generic; use std::fmt; @@ -722,9 +723,8 @@ pub enum PatKind { Mac(Mac), } -#[derive( - Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug, Copy, -)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, + RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)] pub enum Mutability { Mutable, Immutable, @@ -1328,7 +1328,7 @@ pub struct QSelf { } /// A capture clause used in closures and `async` blocks. -#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum CaptureBy { /// `move |x| y + x`. Value, @@ -1339,7 +1339,7 @@ pub enum CaptureBy { /// The movability of a generator / closure literal: /// whether a generator contains self-references, causing it to be `!Unpin`. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, - RustcEncodable, RustcDecodable, Debug, Copy)] + RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)] pub enum Movability { /// May contain self-references, `!Unpin`. Static, @@ -1400,7 +1400,7 @@ impl MacroDef { } // Clippy uses Hash and PartialEq -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)] +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq, HashStable_Generic)] pub enum StrStyle { /// A regular string, like `"foo"`. Cooked, @@ -1451,7 +1451,7 @@ impl StrLit { // Clippy uses Hash and PartialEq /// Type of the integer literal based on provided suffix. -#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)] +#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq, HashStable_Generic)] pub enum LitIntType { /// e.g. `42_i32`. Signed(IntTy), @@ -1462,7 +1462,7 @@ pub enum LitIntType { } /// Type of the float literal based on provided suffix. -#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)] +#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq, HashStable_Generic)] pub enum LitFloatType { /// A float literal with a suffix (`1f32` or `1E10f32`). Suffixed(FloatTy), @@ -1474,7 +1474,7 @@ pub enum LitFloatType { /// /// E.g., `"foo"`, `42`, `12.34`, or `bool`. // Clippy uses Hash and PartialEq -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)] +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq, HashStable_Generic)] pub enum LitKind { /// A string literal (`"foo"`). Str(Symbol, StrStyle), @@ -1609,7 +1609,8 @@ pub enum ImplItemKind { Macro(Mac), } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic, + RustcEncodable, RustcDecodable, Debug)] pub enum FloatTy { F32, F64, @@ -1638,7 +1639,8 @@ impl FloatTy { } } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic, + RustcEncodable, RustcDecodable, Debug)] pub enum IntTy { Isize, I8, @@ -1690,7 +1692,8 @@ impl IntTy { } } -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy, Debug)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic, + RustcEncodable, RustcDecodable, Copy, Debug)] pub enum UintTy { Usize, U8, @@ -1863,7 +1866,7 @@ pub enum TraitObjectSyntax { /// Inline assembly dialect. /// /// E.g., `"intel"` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`. -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] +#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)] pub enum AsmDialect { Att, Intel, @@ -2021,14 +2024,14 @@ impl FnDecl { } /// Is the trait definition an auto trait? -#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum IsAuto { Yes, No, } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, - RustcEncodable, RustcDecodable, Debug)] + RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum Unsafety { Unsafe, Normal, @@ -2085,7 +2088,7 @@ impl IsAsync { } } -#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum Constness { Const, NotConst, @@ -2093,13 +2096,13 @@ pub enum Constness { /// Item defaultness. /// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532). -#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum Defaultness { Default, Final, } -#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable_Generic)] pub enum ImplPolarity { /// `impl Trait for Type` Positive, @@ -2233,7 +2236,7 @@ impl UseTree { /// Distinguishes between `Attribute`s that decorate items and Attributes that /// are contained as statements within items. These two cases need to be /// distinguished for pretty-printing. -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] +#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)] pub enum AttrStyle { Outer, Inner, @@ -2331,7 +2334,7 @@ impl PolyTraitRef { } } -#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum CrateSugar { /// Source is `pub(crate)`. PubCrate, diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 767fcabc017ed..c10541c8c7e75 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -9,6 +9,7 @@ use errors::{Applicability, Handler}; use std::num::NonZeroU32; use syntax_pos::hygiene::Transparency; use syntax_pos::{symbol::Symbol, symbol::sym, Span}; +use rustc_macros::HashStable_Generic; use super::{mark_used, MetaItemKind}; @@ -141,7 +142,8 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op } /// Represents the #[stable], #[unstable], #[rustc_{deprecated,const_unstable}] attributes. -#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Debug, + PartialEq, Eq, Hash, HashStable_Generic)] pub struct Stability { pub level: StabilityLevel, pub feature: Symbol, @@ -157,7 +159,8 @@ pub struct Stability { } /// The available stability levels. -#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)] +#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, + Copy, Clone, Debug, Eq, Hash, HashStable_Generic)] pub enum StabilityLevel { // Reason for the current stability level and the relevant rust-lang issue Unstable { reason: Option, issue: Option, is_soft: bool }, @@ -181,7 +184,8 @@ impl StabilityLevel { } } -#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)] +#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, + Copy, Clone, Debug, Eq, Hash, HashStable_Generic)] pub struct RustcDeprecation { pub since: Symbol, pub reason: Symbol, @@ -636,7 +640,7 @@ pub fn eval_condition(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F) } } -#[derive(RustcEncodable, RustcDecodable, Clone)] +#[derive(RustcEncodable, RustcDecodable, Clone, HashStable_Generic)] pub struct Deprecation { pub since: Option, pub note: Option, @@ -763,7 +767,7 @@ pub enum ReprAttr { ReprAlign(u32), } -#[derive(Eq, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)] +#[derive(Eq, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone, HashStable_Generic)] pub enum IntType { SignedInt(ast::IntTy), UnsignedInt(ast::UintTy) diff --git a/src/libsyntax/token.rs b/src/libsyntax/token.rs index ab798e93d67fc..fd1623384a443 100644 --- a/src/libsyntax/token.rs +++ b/src/libsyntax/token.rs @@ -15,6 +15,7 @@ use syntax_pos::{self, Span, DUMMY_SP}; use std::fmt; use std::mem; use rustc_data_structures::sync::Lrc; +use rustc_macros::HashStable_Generic; #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] pub enum BinOpToken { @@ -53,7 +54,7 @@ impl DelimToken { } } -#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum LitKind { Bool, // AST only, must never appear in a `Token` Byte, @@ -68,7 +69,7 @@ pub enum LitKind { } /// A literal token. -#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub struct Lit { pub kind: LitKind, pub symbol: Symbol, diff --git a/src/libsyntax_pos/edition.rs b/src/libsyntax_pos/edition.rs index 00cd00f283784..727aad546f5f1 100644 --- a/src/libsyntax_pos/edition.rs +++ b/src/libsyntax_pos/edition.rs @@ -2,8 +2,11 @@ use crate::symbol::{Symbol, sym}; use std::fmt; use std::str::FromStr; +use rustc_macros::HashStable_Generic; + /// The edition of the compiler (RFC 2052) -#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, RustcEncodable, RustcDecodable, Eq)] +#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, + RustcEncodable, RustcDecodable, Eq, HashStable_Generic)] pub enum Edition { // editions must be kept in order, oldest to newest diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 2a48f8e44aa12..eb420454f03d3 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -30,6 +30,7 @@ use crate::{Span, DUMMY_SP}; use crate::edition::Edition; use crate::symbol::{kw, sym, Symbol}; +use rustc_macros::HashStable_Generic; use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; @@ -58,7 +59,8 @@ pub struct ExpnId(u32); /// A property of a macro expansion that determines how identifiers /// produced by that expansion are resolved. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Hash, Debug, + RustcEncodable, RustcDecodable, HashStable_Generic)] pub enum Transparency { /// Identifier produced by a transparent expansion is always resolved at call-site. /// Call-site spans in procedural macros, hygiene opt-out in `macro` should use this. @@ -683,7 +685,7 @@ impl ExpnData { } /// Expansion kind. -#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable_Generic)] pub enum ExpnKind { /// No expansion, aka root expansion. Only `ExpnId::root()` has this kind. Root, @@ -707,7 +709,8 @@ impl ExpnKind { } /// The kind of macro invocation or definition. -#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, + Hash, Debug, HashStable_Generic)] pub enum MacroKind { /// A bang macro `foo!()`. Bang, @@ -742,7 +745,7 @@ impl MacroKind { } /// The kind of AST transform. -#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable_Generic)] pub enum AstPass { StdImports, TestHarness, @@ -762,7 +765,7 @@ impl AstPass { } /// The kind of compiler desugaring. -#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable_Generic)] pub enum DesugaringKind { /// We desugar `if c { i } else { e }` to `match $ExprKind::Use(c) { true => i, _ => e }`. /// However, we do not want to blame `c` for unreachability but rather say that `i` diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index b88d6dbc3f379..720ace90324b9 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -15,6 +15,7 @@ #![feature(step_trait)] use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; +use rustc_macros::HashStable_Generic; pub mod source_map; @@ -66,7 +67,8 @@ impl Globals { scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals); /// Differentiates between real files and common virtual files. -#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)] +#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, + RustcDecodable, RustcEncodable, HashStable_Generic)] pub enum FileName { Real(PathBuf), /// A macro. This includes the full name of the macro, so that there are no clashes. diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 1139bf67a36d0..b5587303b0729 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -8,6 +8,7 @@ use rustc_index::vec::Idx; use rustc_macros::symbols; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable}; +use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher}; use std::cmp::{PartialEq, PartialOrd, Ord}; use std::fmt; @@ -940,6 +941,22 @@ impl Decodable for Symbol { } } +impl HashStable for Symbol { + #[inline] + fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + self.as_str().hash_stable(hcx, hasher); + } +} + +impl ToStableHashKey for Symbol { + type KeyType = SymbolStr; + + #[inline] + fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr { + self.as_str() + } +} + // The `&'static str`s in this type actually point into the arena. #[derive(Default)] pub struct Interner { @@ -1137,3 +1154,19 @@ impl fmt::Display for SymbolStr { fmt::Display::fmt(self.string, f) } } + +impl HashStable for SymbolStr { + #[inline] + fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + self.string.hash_stable(hcx, hasher) + } +} + +impl ToStableHashKey for SymbolStr { + type KeyType = SymbolStr; + + #[inline] + fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr { + self.clone() + } +}