Auto merge of #66460 - cjgillot:hashstable_generic, r=Zoxc

Add a proc-macro to derive HashStable in librustc dependencies

A second proc-macro is added to derive HashStable for crates librustc depends on.
This proc-macro HashStable_Generic (to bikeshed) allows to decouple code and some librustc's boilerplate.

Not everything is migrated, because `Span` and `TokenKind` require to be placed inside librustc.
Types using them stay there too.

Split out of #66279
r? @Zoxc
This commit is contained in:
bors 2019-11-22 13:54:41 +00:00
commit 083b5a0a1b
22 changed files with 164 additions and 424 deletions

View File

@ -3838,6 +3838,7 @@ dependencies = [
"log",
"rustc_data_structures",
"rustc_index",
"rustc_macros",
"serialize",
"syntax_pos",
]
@ -4405,6 +4406,7 @@ dependencies = [
"rustc_errors",
"rustc_index",
"rustc_lexer",
"rustc_macros",
"scoped-tls",
"serialize",
"smallvec 1.0.0",

View File

@ -213,11 +213,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
}
}
impl_stable_hash_for!(enum ast::CrateSugar {
JustCrate,
PubCrate,
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
mem::discriminant(self).hash_stable(hcx, hasher);

View File

@ -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
});

View File

@ -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<StableHashingContext<'a>> 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<StableHashingContext<'a>> for SymbolStr {
type KeyType = SymbolStr;
#[inline]
fn to_stable_hash_key(&self,
_: &StableHashingContext<'a>)
-> SymbolStr {
self.clone()
}
}
impl<'a> HashStable<StableHashingContext<'a>> 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<StableHashingContext<'a>> 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<StableHashingContext<'a>>
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<StableHashingContext<'a>> 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<StableHashingContext<'a>> 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<StableHashingContext<'a>> for SourceFile {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
let SourceFile {

View File

@ -159,11 +159,6 @@ where
}
}
impl_stable_hash_for!(enum ::syntax::ast::Mutability {
Immutable,
Mutable
});
impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
type KeyType = region::Scope;

View File

@ -10,7 +10,6 @@ mod caching_source_map_view;
mod hcx;
mod impls_hir;
mod impls_misc;
mod impls_ty;
mod impls_syntax;

View File

@ -2327,158 +2327,6 @@ where
}
}
impl<'a> HashStable<StableHashingContext<'a>> 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<StableHashingContext<'a>> 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<StableHashingContext<'a>> 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<StableHashingContext<'a>> for VariantIdx {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
self.as_u32().hash_stable(hcx, hasher)
}
}
impl<'a> HashStable<StableHashingContext<'a>> 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<StableHashingContext<'a>> 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<StableHashingContext<'tcx>> for Align {
fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
self.bytes().hash_stable(hcx, hasher);
}
}
impl<'tcx> HashStable<StableHashingContext<'tcx>> for Size {
fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
self.bytes().hash_stable(hcx, hasher);
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for LayoutError<'tcx> {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
use crate::ty::layout::LayoutError::*;

View File

@ -429,6 +429,16 @@ impl<T, CTX> HashStable<CTX> for ::std::mem::Discriminant<T> {
}
}
impl<T, CTX> HashStable<CTX> for ::std::ops::RangeInclusive<T>
where T: HashStable<CTX>
{
#[inline]
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.start().hash_stable(ctx, hasher);
self.end().hash_stable(ctx, hasher);
}
}
impl<I: vec::Idx, T, CTX> HashStable<CTX> for vec::IndexVec<I, T>
where T: HashStable<CTX>,
{

View File

@ -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);

View File

@ -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);

View File

@ -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" }

View File

@ -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,

View File

@ -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().)

View File

@ -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,

View File

@ -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" }

View File

@ -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,

View File

@ -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<Symbol>, issue: Option<NonZeroU32>, 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<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
}
}
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(RustcEncodable, RustcDecodable, Clone, HashStable_Generic)]
pub struct Deprecation {
pub since: Option<Symbol>,
pub note: Option<Symbol>,
@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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`

View File

@ -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.

View File

@ -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;
@ -941,6 +942,22 @@ impl Decodable for Symbol {
}
}
impl<CTX> HashStable<CTX> for Symbol {
#[inline]
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
self.as_str().hash_stable(hcx, hasher);
}
}
impl<CTX> ToStableHashKey<CTX> 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 {
@ -1138,3 +1155,19 @@ impl fmt::Display for SymbolStr {
fmt::Display::fmt(self.string, f)
}
}
impl<CTX> HashStable<CTX> for SymbolStr {
#[inline]
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
self.string.hash_stable(hcx, hasher)
}
}
impl<CTX> ToStableHashKey<CTX> for SymbolStr {
type KeyType = SymbolStr;
#[inline]
fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
self.clone()
}
}