diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-12-16 04:44:12 +0100 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2019-03-05 00:36:25 +0100 |
| commit | 10d2008c510f088186234dbd2e43c2ba77b5e954 (patch) | |
| tree | d6533a4b216d5e8f15a6dd8c4e8b29adfa29b3ce | |
| parent | 70156fbb752d5c8726c6c47104922575164a92e3 (diff) | |
| download | rust-10d2008c510f088186234dbd2e43c2ba77b5e954.tar.gz rust-10d2008c510f088186234dbd2e43c2ba77b5e954.zip | |
Add ignore and project attributes
| -rw-r--r-- | src/librustc_macros/src/hash_stable.rs | 64 | ||||
| -rw-r--r-- | src/librustc_macros/src/lib.rs | 2 |
2 files changed, 61 insertions, 5 deletions
diff --git a/src/librustc_macros/src/hash_stable.rs b/src/librustc_macros/src/hash_stable.rs index 86ac0b353e5..585f5505f1f 100644 --- a/src/librustc_macros/src/hash_stable.rs +++ b/src/librustc_macros/src/hash_stable.rs @@ -1,13 +1,69 @@ use synstructure; -use syn; -use proc_macro2; +use syn::{self, Meta, NestedMeta}; +use proc_macro2::{self, Ident, Span}; + +struct Attributes { + ignore: bool, + project: Option<String>, +} + +fn parse_attributes(field: &syn::Field) -> Attributes { + let mut attrs = Attributes { + ignore: false, + project: None, + }; + for attr in &field.attrs { + if let Ok(meta) = attr.parse_meta() { + if &meta.name().to_string() != "stable_hasher" { + continue; + } + let mut any_attr = false; + if let Meta::List(list) = meta { + for nested in list.nested.iter() { + if let NestedMeta::Meta(meta) = nested { + if &meta.name().to_string() == "ignore" { + attrs.ignore = true; + any_attr = true; + } + if &meta.name().to_string() == "project" { + if let Meta::List(list) = meta { + if let Some(nested) = list.nested.iter().next() { + if let NestedMeta::Meta(meta) = nested { + attrs.project = Some(meta.name().to_string()); + any_attr = true; + } + } + } + } + } + } + } + if !any_attr { + panic!("error parsing stable_hasher"); + } + } + } + attrs +} 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 body = s.each(|bi| { + let attrs = parse_attributes(bi.ast()); + if attrs.ignore { + quote!{} + } else if let Some(project) = attrs.project { + let project = Ident::new(&project, Span::call_site()); + quote!{ + &#bi.#project.hash_stable(__hcx, __hasher); + } + } else { + quote!{ + #bi.hash_stable(__hcx, __hasher); + } + } }); let discriminant = match s.ast().data { diff --git a/src/librustc_macros/src/lib.rs b/src/librustc_macros/src/lib.rs index 8dcf2b76fad..460b415c537 100644 --- a/src/librustc_macros/src/lib.rs +++ b/src/librustc_macros/src/lib.rs @@ -11,4 +11,4 @@ extern crate proc_macro2; mod hash_stable; -decl_derive!([HashStable] => hash_stable::hash_stable_derive); +decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive); |
