4457014398
The PR had some unforseen perf regressions that are not as easy to find. Revert the PR for now. This reverts commit 6ae8912a3e7d2c4c775024f58a7ba4b1aedc4073, reversing changes made to 86d6d2b7389fe1b339402c1798edae8b695fc9ef.
134 lines
4.4 KiB
Rust
134 lines
4.4 KiB
Rust
use proc_macro2::{self, Ident};
|
|
use quote::quote;
|
|
use syn::{self, parse_quote, Meta, NestedMeta};
|
|
|
|
struct Attributes {
|
|
ignore: bool,
|
|
project: Option<Ident>,
|
|
}
|
|
|
|
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.path().is_ident("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.path().is_ident("ignore") {
|
|
attrs.ignore = true;
|
|
any_attr = true;
|
|
}
|
|
if meta.path().is_ident("project") {
|
|
if let Meta::List(list) = meta {
|
|
if let Some(nested) = list.nested.iter().next() {
|
|
if let NestedMeta::Meta(meta) = nested {
|
|
attrs.project = meta.path().get_ident().cloned();
|
|
any_attr = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if !any_attr {
|
|
panic!("error parsing stable_hasher");
|
|
}
|
|
}
|
|
}
|
|
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);
|
|
s.add_where_predicate(parse_quote! { __CTX: crate::HashStableContext });
|
|
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! {
|
|
#[inline]
|
|
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);
|
|
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<
|
|
::rustc_query_system::ich::StableHashingContext<'__ctx>,
|
|
>
|
|
),
|
|
quote! {
|
|
#[inline]
|
|
fn hash_stable(
|
|
&self,
|
|
__hcx: &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
|
|
__hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) {
|
|
#discriminant
|
|
match *self { #body }
|
|
}
|
|
},
|
|
)
|
|
}
|