1 use proc_macro2::{self, Ident};
3 use syn::{self, parse_quote, Meta, NestedMeta};
7 project: Option<Ident>,
10 fn parse_attributes(field: &syn::Field) -> Attributes {
11 let mut attrs = Attributes { ignore: false, project: None };
12 for attr in &field.attrs {
13 if let Ok(meta) = attr.parse_meta() {
14 if !meta.path().is_ident("stable_hasher") {
17 let mut any_attr = false;
18 if let Meta::List(list) = meta {
19 for nested in list.nested.iter() {
20 if let NestedMeta::Meta(meta) = nested {
21 if meta.path().is_ident("ignore") {
25 if meta.path().is_ident("project") {
26 if let Meta::List(list) = meta {
27 if let Some(NestedMeta::Meta(meta)) = list.nested.iter().next() {
28 attrs.project = meta.path().get_ident().cloned();
37 panic!("error parsing stable_hasher");
44 pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
45 let generic: syn::GenericParam = parse_quote!(__CTX);
46 s.add_bounds(synstructure::AddBounds::Generics);
47 s.add_impl_generic(generic);
48 s.add_where_predicate(parse_quote! { __CTX: crate::HashStableContext });
49 let body = s.each(|bi| {
50 let attrs = parse_attributes(bi.ast());
53 } else if let Some(project) = attrs.project {
55 (&#bi.#project).hash_stable(__hcx, __hasher);
59 #bi.hash_stable(__hcx, __hasher);
64 let discriminant = match s.ast().data {
65 syn::Data::Enum(_) => quote! {
66 ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
68 syn::Data::Struct(_) => quote! {},
69 syn::Data::Union(_) => panic!("cannot derive on union"),
73 quote!(::rustc_data_structures::stable_hasher::HashStable<__CTX>),
79 __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) {
87 pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
88 let generic: syn::GenericParam = parse_quote!('__ctx);
89 s.add_bounds(synstructure::AddBounds::Generics);
90 s.add_impl_generic(generic);
91 let body = s.each(|bi| {
92 let attrs = parse_attributes(bi.ast());
95 } else if let Some(project) = attrs.project {
97 (&#bi.#project).hash_stable(__hcx, __hasher);
101 #bi.hash_stable(__hcx, __hasher);
106 let discriminant = match s.ast().data {
107 syn::Data::Enum(_) => quote! {
108 ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
110 syn::Data::Struct(_) => quote! {},
111 syn::Data::Union(_) => panic!("cannot derive on union"),
116 ::rustc_data_structures::stable_hasher::HashStable<
117 ::rustc_query_system::ich::StableHashingContext<'__ctx>,
124 __hcx: &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
125 __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) {
127 match *self { #body }