From 3d559d8b4149b94db612520998a97876ac0a4c00 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Sat, 28 Sep 2019 14:29:14 +1000 Subject: [PATCH] Robustify derive macro attribute parsing (#544) Missing whitespace in the implementation of `TokenStream::to_string` on beta and nightly was breaking our parsing of derive macro attributes. This change makes the parser ignore whitespace, and should make the beta and nightly builds succeed again. --- eth2/utils/compare_fields_derive/src/lib.rs | 10 ++++------ eth2/utils/ssz_derive/src/lib.rs | 18 ++++++------------ eth2/utils/test_random_derive/src/lib.rs | 9 +++------ eth2/utils/tree_hash_derive/src/lib.rs | 7 +++---- 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/eth2/utils/compare_fields_derive/src/lib.rs b/eth2/utils/compare_fields_derive/src/lib.rs index c4ca3d64c..15137efa3 100644 --- a/eth2/utils/compare_fields_derive/src/lib.rs +++ b/eth2/utils/compare_fields_derive/src/lib.rs @@ -6,12 +6,10 @@ use quote::quote; use syn::{parse_macro_input, DeriveInput}; fn is_slice(field: &syn::Field) -> bool { - for attr in &field.attrs { - if attr.tts.to_string() == "( as_slice )" { - return true; - } - } - false + field.attrs.iter().any(|attr| { + attr.path.is_ident("compare_fields") + && attr.tts.to_string().replace(" ", "") == "(as_slice)" + }) } #[proc_macro_derive(CompareFields, attributes(compare_fields))] diff --git a/eth2/utils/ssz_derive/src/lib.rs b/eth2/utils/ssz_derive/src/lib.rs index 5bdb9ca9d..bd367e039 100644 --- a/eth2/utils/ssz_derive/src/lib.rs +++ b/eth2/utils/ssz_derive/src/lib.rs @@ -53,12 +53,9 @@ fn get_serializable_field_types<'a>(struct_data: &'a syn::DataStruct) -> Vec<&'a /// /// The field attribute is: `#[ssz(skip_serializing)]` fn should_skip_serializing(field: &syn::Field) -> bool { - for attr in &field.attrs { - if attr.tts.to_string() == "( skip_serializing )" { - return true; - } - } - false + field.attrs.iter().any(|attr| { + attr.path.is_ident("ssz") && attr.tts.to_string().replace(" ", "") == "(skip_serializing)" + }) } /// Implements `ssz::Encode` for some `struct`. @@ -149,12 +146,9 @@ pub fn ssz_encode_derive(input: TokenStream) -> TokenStream { /// /// The field attribute is: `#[ssz(skip_deserializing)]` fn should_skip_deserializing(field: &syn::Field) -> bool { - for attr in &field.attrs { - if attr.tts.to_string() == "( skip_deserializing )" { - return true; - } - } - false + field.attrs.iter().any(|attr| { + attr.path.is_ident("ssz") && attr.tts.to_string().replace(" ", "") == "(skip_deserializing)" + }) } /// Implements `ssz::Decode` for some `struct`. diff --git a/eth2/utils/test_random_derive/src/lib.rs b/eth2/utils/test_random_derive/src/lib.rs index a268161dd..d6e3a0f95 100644 --- a/eth2/utils/test_random_derive/src/lib.rs +++ b/eth2/utils/test_random_derive/src/lib.rs @@ -9,12 +9,9 @@ use syn::{parse_macro_input, DeriveInput}; /// /// The field attribute is: `#[test_random(default)]` fn should_use_default(field: &syn::Field) -> bool { - for attr in &field.attrs { - if attr.tts.to_string() == "( default )" { - return true; - } - } - false + field.attrs.iter().any(|attr| { + attr.path.is_ident("test_random") && attr.tts.to_string().replace(" ", "") == "(default)" + }) } #[proc_macro_derive(TestRandom, attributes(test_random))] diff --git a/eth2/utils/tree_hash_derive/src/lib.rs b/eth2/utils/tree_hash_derive/src/lib.rs index c92595818..1e702c53c 100644 --- a/eth2/utils/tree_hash_derive/src/lib.rs +++ b/eth2/utils/tree_hash_derive/src/lib.rs @@ -31,10 +31,9 @@ fn get_hashable_named_field_idents<'a>(struct_data: &'a syn::DataStruct) -> Vec< /// /// The field attribute is: `#[tree_hash(skip_hashing)]` fn should_skip_hashing(field: &syn::Field) -> bool { - field - .attrs - .iter() - .any(|attr| attr.into_token_stream().to_string() == "# [ tree_hash ( skip_hashing ) ]") + field.attrs.iter().any(|attr| { + attr.path.is_ident("tree_hash") && attr.tts.to_string().replace(" ", "") == "(skip_hashing)" + }) } /// Implements `tree_hash::TreeHash` for some `struct`.