diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 26a27ea88e2..31e10c19c7a 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -24,6 +24,7 @@ rustc-rayon = "0.1.2" rustc-rayon-core = "0.1.2" rustc_apfloat = { path = "../librustc_apfloat" } rustc_target = { path = "../librustc_target" } +rustc_macros = { path = "../librustc_macros" } rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } serialize = { path = "../libserialize" } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 2d0296aa38c..4b5670af138 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -32,6 +32,7 @@ use crate::ty::query::Providers; use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync}; use rustc_data_structures::thin_vec::ThinVec; +use rustc_macros::HashStable; use serialize::{self, Encoder, Encodable, Decoder, Decodable}; use std::collections::{BTreeSet, BTreeMap}; @@ -149,7 +150,7 @@ pub const DUMMY_HIR_ID: HirId = HirId { pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX; -#[derive(Clone, RustcEncodable, RustcDecodable, Copy)] +#[derive(Clone, RustcEncodable, RustcDecodable, Copy, HashStable)] pub struct Lifetime { pub hir_id: HirId, pub span: Span, diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 0803816fb03..d8d4157e20e 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -157,12 +157,6 @@ impl_stable_hash_for!(struct ast::Label { ident }); -impl_stable_hash_for!(struct hir::Lifetime { - hir_id, - span, - name -}); - impl_stable_hash_for!(struct hir::Path { span, def, diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 205ea6126fc..e1f6e1caeae 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -148,6 +148,7 @@ pub mod util { #[doc(hidden)] mod rustc { pub use crate::lint; + pub use crate::ich; } // FIXME(#27438): right now the unit tests of librustc don't refer to any actual diff --git a/src/librustc_macros/Cargo.toml b/src/librustc_macros/Cargo.toml new file mode 100644 index 00000000000..c5e01e9e0a7 --- /dev/null +++ b/src/librustc_macros/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "rustc_macros" +version = "0.1.0" +authors = ["The Rust Project Developers"] + +[lib] +proc-macro = true + +[dependencies] +synstructure = "0.10.1" +syn = { version = "0.15.22", features = ["full"] } +proc-macro2 = "0.4.24" +quote = "0.6.10" \ No newline at end of file diff --git a/src/librustc_macros/src/hash_stable.rs b/src/librustc_macros/src/hash_stable.rs new file mode 100644 index 00000000000..86ac0b353e5 --- /dev/null +++ b/src/librustc_macros/src/hash_stable.rs @@ -0,0 +1,31 @@ +use synstructure; +use syn; +use proc_macro2; + +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); + s.add_impl_generic(generic); + let body = s.each(|bi| quote!{ + ::rustc_data_structures::stable_hasher::HashStable::hash_stable(#bi, __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 + <::rustc::ich::StableHashingContext<'__ctx>>), quote!{ + fn hash_stable<__W: ::rustc_data_structures::stable_hasher::StableHasherResult>( + &self, + __hcx: &mut ::rustc::ich::StableHashingContext<'__ctx>, + __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<__W>) { + #discriminant + match *self { #body } + } + }) +} diff --git a/src/librustc_macros/src/lib.rs b/src/librustc_macros/src/lib.rs new file mode 100644 index 00000000000..8dcf2b76fad --- /dev/null +++ b/src/librustc_macros/src/lib.rs @@ -0,0 +1,14 @@ +#![feature(proc_macro_hygiene)] + +#[macro_use] +extern crate syn; +#[macro_use] +extern crate synstructure; +#[macro_use] +extern crate quote; +extern crate proc_macro; +extern crate proc_macro2; + +mod hash_stable; + +decl_derive!([HashStable] => hash_stable::hash_stable_derive); diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index f581ce1f5a3..d7683aae841 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -137,6 +137,7 @@ const WHITELIST: &[Crate<'_>] = &[ Crate("smallvec"), Crate("stable_deref_trait"), Crate("syn"), + Crate("synstructure"), Crate("tempfile"), Crate("termcolor"), Crate("terminon"),