2 use syn
::{self, Meta, NestedMeta, parse_quote}
;
3 use proc_macro2
::{self, Ident}
;
8 project
: Option
<Ident
>,
11 fn parse_attributes(field
: &syn
::Field
) -> Attributes
{
12 let mut attrs
= Attributes
{
16 for attr
in &field
.attrs
{
17 if let Ok(meta
) = attr
.parse_meta() {
18 if !meta
.path().is_ident("stable_hasher") {
21 let mut any_attr
= false;
22 if let Meta
::List(list
) = meta
{
23 for nested
in list
.nested
.iter() {
24 if let NestedMeta
::Meta(meta
) = nested
{
25 if meta
.path().is_ident("ignore") {
29 if meta
.path().is_ident("project") {
30 if let Meta
::List(list
) = meta
{
31 if let Some(nested
) = list
.nested
.iter().next() {
32 if let NestedMeta
::Meta(meta
) = nested
{
33 attrs
.project
= meta
.path().get_ident().cloned();
43 panic
!("error parsing stable_hasher");
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 s
.add_where_predicate(parse_quote
!{ __CTX: crate::HashStableContext }
);
55 let body
= s
.each(|bi
| {
56 let attrs
= parse_attributes(bi
.ast());
59 } else if let Some(project
) = attrs
.project
{
61 &#bi.#project.hash_stable(__hcx, __hasher);
65 #bi.hash_stable(__hcx, __hasher);
70 let discriminant
= match s
.ast().data
{
71 syn
::Data
::Enum(_
) => quote
! {
72 ::std
::mem
::discriminant(self).hash_stable(__hcx
, __hasher
);
74 syn
::Data
::Struct(_
) => quote
! {}
,
75 syn
::Data
::Union(_
) => panic
!("cannot derive on union"),
78 s
.bound_impl(quote
!(::rustc_data_structures
::stable_hasher
::HashStable
<__CTX
>), quote
!{
82 __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"),
116 s
.bound_impl(quote
!(::rustc_data_structures
::stable_hasher
::HashStable
117 <::rustc
::ich
::StableHashingContext
<'__ctx
>>), quote
!{
120 __hcx
: &mut ::rustc
::ich
::StableHashingContext
<'__ctx
>,
121 __hasher
: &mut ::rustc_data_structures
::stable_hasher
::StableHasher
) {
123 match *self { #body }