Skip to content

Commit 5b0e702

Browse files
committed
Create a generic HashStable derive.
1 parent d801458 commit 5b0e702

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

src/librustc_macros/src/hash_stable.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,44 @@ fn parse_attributes(field: &syn::Field) -> Attributes {
4747
attrs
4848
}
4949

50+
pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
51+
let generic: syn::GenericParam = parse_quote!(__CTX);
52+
s.add_bounds(synstructure::AddBounds::Generics);
53+
s.add_impl_generic(generic);
54+
let body = s.each(|bi| {
55+
let attrs = parse_attributes(bi.ast());
56+
if attrs.ignore {
57+
quote!{}
58+
} else if let Some(project) = attrs.project {
59+
quote!{
60+
&#bi.#project.hash_stable(__hcx, __hasher);
61+
}
62+
} else {
63+
quote!{
64+
#bi.hash_stable(__hcx, __hasher);
65+
}
66+
}
67+
});
68+
69+
let discriminant = match s.ast().data {
70+
syn::Data::Enum(_) => quote! {
71+
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
72+
},
73+
syn::Data::Struct(_) => quote! {},
74+
syn::Data::Union(_) => panic!("cannot derive on union"),
75+
};
76+
77+
s.bound_impl(quote!(::rustc_data_structures::stable_hasher::HashStable<__CTX>), quote!{
78+
fn hash_stable(
79+
&self,
80+
__hcx: &mut __CTX,
81+
__hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) {
82+
#discriminant
83+
match *self { #body }
84+
}
85+
})
86+
}
87+
5088
pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
5189
let generic: syn::GenericParam = parse_quote!('__ctx);
5290
s.add_bounds(synstructure::AddBounds::Generics);

src/librustc_macros/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,9 @@ pub fn symbols(input: TokenStream) -> TokenStream {
2424
}
2525

2626
decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
27+
decl_derive!(
28+
[HashStable_Generic, attributes(stable_hasher)] =>
29+
hash_stable::hash_stable_generic_derive
30+
);
31+
2732
decl_derive!([TypeFoldable, attributes(type_foldable)] => type_foldable::type_foldable_derive);

0 commit comments

Comments
 (0)