1 use proc_macro2::{self, Ident};
3 use syn::{self, parse_quote, Meta, NestedMeta};
8 project: Option<Ident>,
11 fn parse_attributes(field: &syn::Field) -> Attributes {
12 let mut attrs = Attributes { ignore: false, project: None };
13 for attr in &field.attrs {
14 if let Ok(meta) = attr.parse_meta() {
15 if !meta.path().is_ident("stable_hasher") {
18 let mut any_attr = false;
19 if let Meta::List(list) = meta {
20 for nested in list.nested.iter() {
21 if let NestedMeta::Meta(meta) = nested {
22 if meta.path().is_ident("ignore") {
26 if meta.path().is_ident("project") {
27 if let Meta::List(list) = meta {
28 if let Some(nested) = list.nested.iter().next() {
29 if let NestedMeta::Meta(meta) = nested {
30 attrs.project = meta.path().get_ident().cloned();
40 panic!("error parsing stable_hasher");
47 pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
48 let generic: syn::GenericParam = parse_quote!(__CTX);
49 s.add_bounds(synstructure::AddBounds::Generics);
50 s.add_impl_generic(generic);
51 s.add_where_predicate(parse_quote! { __CTX: crate::HashStableContext });
52 let body = s.each(|bi| {
53 let attrs = parse_attributes(bi.ast());
56 } else if let Some(project) = attrs.project {
58 &#bi.#project.hash_stable(__hcx, __hasher);
62 #bi.hash_stable(__hcx, __hasher);
67 let discriminant = match s.ast().data {
68 syn::Data::Enum(_) => quote! {
69 ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
71 syn::Data::Struct(_) => quote! {},
72 syn::Data::Union(_) => panic!("cannot derive on union"),
76 quote!(::rustc_data_structures::stable_hasher::HashStable<__CTX>),
81 __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) {
89 pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
90 let generic: syn::GenericParam = parse_quote!('__ctx);
91 s.add_bounds(synstructure::AddBounds::Generics);
92 s.add_impl_generic(generic);
93 let body = s.each(|bi| {
94 let attrs = parse_attributes(bi.ast());
97 } else if let Some(project) = attrs.project {
99 &#bi.#project.hash_stable(__hcx, __hasher);
103 #bi.hash_stable(__hcx, __hasher);
108 let discriminant = match s.ast().data {
109 syn::Data::Enum(_) => quote! {
110 ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
112 syn::Data::Struct(_) => quote! {},
113 syn::Data::Union(_) => panic!("cannot derive on union"),
118 ::rustc_data_structures::stable_hasher::HashStable<
119 ::rustc::ich::StableHashingContext<'__ctx>,
125 __hcx: &mut ::rustc::ich::StableHashingContext<'__ctx>,
126 __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) {
128 match *self { #body }