1- use quote:: quote;
21use std:: collections:: HashSet ;
2+
3+ use quote:: quote;
34use syn:: spanned:: Spanned ;
45
56use crate :: blacklist:: Blacklist ;
6- use crate :: { is_phantom_data , Mode } ;
7- use crate :: { add_bound_to_type_params, collect_type_params , is_cow, is_option, is_str, is_byte_slice} ;
8- use crate :: { add_typeparam, gen_ctx_param, add_bound_to_matching_type_params } ;
7+ use crate :: { collect_type_params , Mode } ;
8+ use crate :: { add_bound_to_type_params, is_cow, is_option, is_str, is_byte_slice} ;
9+ use crate :: { add_typeparam, gen_ctx_param} ;
910use crate :: attrs:: { Attributes , CustomCodec , Encoding , Level } ;
1011use crate :: fields:: { Field , Fields } ;
1112use crate :: variants:: Variants ;
@@ -34,33 +35,39 @@ fn on_struct(inp: &mut syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream
3435 unreachable ! ( "`derive_from` matched against `syn::Data::Struct`" )
3536 } ;
3637
37- let name = & inp. ident ;
38- let attrs = Attributes :: try_from_iter ( Level :: Struct , inp. attrs . iter ( ) ) ?;
39- let fields = Fields :: try_from ( name. span ( ) , data. fields . iter ( ) , & [ & attrs] ) ?;
40- let blacklist = Blacklist :: new ( Mode :: Decode , & fields, & inp. generics ) ;
38+ let name = & inp. ident ;
39+ let attrs = Attributes :: try_from_iter ( Level :: Struct , inp. attrs . iter ( ) ) ?;
40+ let fields = Fields :: try_from ( name. span ( ) , data. fields . iter ( ) , & [ & attrs] ) ?;
4141
42- let mut lifetime = gen_lifetime ( ) ? ;
42+ let mut lifetime = gen_lifetime ( ) ;
4343 for l in lifetimes_to_constrain ( fields. fields ( ) . map ( |f| ( & f. index , f. attrs . borrow ( ) , & f. typ ) ) ) {
4444 if !lifetime. bounds . iter ( ) . any ( |b| * b == l) {
4545 lifetime. bounds . push ( l. clone ( ) )
4646 }
4747 }
4848
49- // Collect type parameters which require a `Default` bound.
50- let default_types =
51- collect_type_params ( & inp. generics , fields. fields ( ) . chain ( fields. skipped ( ) ) . filter ( |f| {
52- ( f. attrs . default ( ) || f. attrs . skip ( ) || f. attrs . skip_if_codec ( ) ) && !is_phantom_data ( & f. typ )
53- } ) )
54- . into_iter ( )
55- . collect ( ) ;
56-
57- let bound = gen_decode_bound ( ) ?;
49+ let blacklist = Blacklist :: new ( Mode :: Decode , & fields, & inp. generics ) ;
50+ let bound = gen_decode_bound ( ) ;
5851 let params = inp. generics . type_params_mut ( ) ;
59- add_bound_to_type_params ( bound, params, & blacklist, fields. fields ( ) . attributes ( ) , Mode :: Decode ) ;
52+ add_bound_to_type_params ( Mode :: Decode , bound, params, & blacklist, fields. fields ( ) . attributes ( ) ) ;
6053
61- let bound = gen_default_bound ( ) ?;
62- let params = inp. generics . type_params_mut ( ) ;
63- add_bound_to_matching_type_params ( bound, params, & default_types) ;
54+ // Collect type parameters which require a `Default` bound.
55+ let default_types: HashSet < syn:: Ident > =
56+ collect_type_params ( & inp. generics , fields. fields ( ) . chain ( fields. skipped ( ) ) . filter ( |f| {
57+ f. attrs . default ( ) || f. attrs . skip ( ) || f. attrs . skip_if_codec ( )
58+ } ) ) ;
59+
60+ let blacklist = Blacklist :: empty ( )
61+ . with_mode ( Mode :: Decode , & fields, & inp. generics )
62+ . with_phantoms ( & fields, & inp. generics ) ;
63+
64+ let bound = gen_default_bound ( ) ;
65+ let params = inp. generics . type_params_mut ( ) . filter ( |p| default_types. contains ( & p. ident ) ) ;
66+ add_bound_to_type_params ( Mode :: Decode , bound, params, & blacklist,
67+ fields. fields ( ) . chain ( fields. skipped ( ) ) . filter_map ( |f| {
68+ ( f. attrs . default ( ) || f. attrs . skip ( ) || f. attrs . skip_if_codec ( ) ) . then_some ( & f. attrs )
69+ } )
70+ ) ;
6471
6572 let generics = add_lifetime ( & inp. generics , lifetime) ;
6673 let generics = add_typeparam ( & generics, gen_ctx_param ( ) ?, attrs. context_bound ( ) ) ;
@@ -140,10 +147,12 @@ fn on_enum(inp: &mut syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream>
140147 let flat = enum_attrs. flat ( ) ;
141148 let variants = Variants :: try_from ( name. span ( ) , data. variants . iter ( ) , & enum_attrs) ?;
142149
143- let mut blacklist = Blacklist :: default ( ) ;
144- let mut defaults = HashSet :: new ( ) ;
150+ let mut decode_blacklist = Blacklist :: empty ( ) ;
145151 let mut field_attrs = Vec :: new ( ) ;
146- let mut lifetime = gen_lifetime ( ) ?;
152+ let mut default_blacklist = Blacklist :: empty ( ) ;
153+ let mut defaults = HashSet :: new ( ) ;
154+ let mut default_attrs = Vec :: new ( ) ;
155+ let mut lifetime = gen_lifetime ( ) ;
147156 let mut rows = Vec :: new ( ) ;
148157 for ( ( var, idx) , attrs) in data. variants . iter ( ) . zip ( variants. indices . iter ( ) ) . zip ( & variants. attrs ) {
149158 let fields = Fields :: try_from ( var. ident . span ( ) , var. fields . iter ( ) , & [ attrs, & enum_attrs] ) ?;
@@ -166,13 +175,14 @@ fn on_enum(inp: &mut syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream>
166175 lifetime. bounds . push ( l. clone ( ) )
167176 }
168177 }
169- blacklist. merge ( Mode :: Decode , & fields, & inp. generics ) ;
170- // Collect type parameters which require a `Default` bound.
178+ decode_blacklist. merge ( & fields, & inp. generics , Blacklist :: new ( Mode :: Decode , & fields, & inp. generics ) ) ;
179+ default_blacklist. merge ( & fields, & inp. generics , Blacklist :: empty ( )
180+ . with_mode ( Mode :: Decode , & fields, & inp. generics )
181+ . with_phantoms ( & fields, & inp. generics ) ) ;
171182 defaults. extend (
172183 collect_type_params ( & inp. generics , fields. fields ( ) . chain ( fields. skipped ( ) ) . filter ( |f| {
173- ( f. attrs . default ( ) || f. attrs . skip ( ) || f. attrs . skip_if_codec ( ) ) && ! is_phantom_data ( & f . typ )
184+ f. attrs . default ( ) || f. attrs . skip ( ) || f. attrs . skip_if_codec ( )
174185 } ) )
175- . into_iter ( )
176186 ) ;
177187 let statements = gen_statements ( & fields, encoding, flat) ?;
178188 if let syn:: Fields :: Named ( _) = var. fields {
@@ -213,16 +223,21 @@ fn on_enum(inp: &mut syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream>
213223 }
214224 } ;
215225 field_attrs. extend ( fields. fields ( ) . attributes ( ) . cloned ( ) ) ;
226+ default_attrs. extend ( fields. fields ( ) . attributes ( ) . chain ( fields. skipped ( ) . attributes ( ) ) . cloned ( ) ) ;
216227 rows. push ( row)
217228 }
218229
219- let bound = gen_decode_bound ( ) ? ;
230+ let bound = gen_decode_bound ( ) ;
220231 let params = inp. generics . type_params_mut ( ) ;
221- add_bound_to_type_params ( bound, params, & blacklist , & field_attrs, Mode :: Decode ) ;
232+ add_bound_to_type_params ( Mode :: Decode , bound, params, & decode_blacklist , & field_attrs) ;
222233
223- let bound = gen_default_bound ( ) ?;
224- let params = inp. generics . type_params_mut ( ) ;
225- add_bound_to_matching_type_params ( bound, params, & defaults) ;
234+ let bound = gen_default_bound ( ) ;
235+ let params = inp. generics . type_params_mut ( ) . filter ( |p| defaults. contains ( & p. ident ) ) ;
236+ add_bound_to_type_params ( Mode :: Decode , bound, params, & default_blacklist,
237+ default_attrs. iter ( ) . filter ( |a| {
238+ a. default ( ) || a. skip ( ) || a. skip_if_codec ( )
239+ } )
240+ ) ;
226241
227242 let generics = add_lifetime ( & inp. generics , lifetime) ;
228243 let generics = add_typeparam ( & generics, gen_ctx_param ( ) ?, enum_attrs. context_bound ( ) ) ;
@@ -527,12 +542,12 @@ fn make_transparent_impl
527542 } )
528543}
529544
530- fn gen_decode_bound ( ) -> syn:: Result < syn :: TypeParamBound > {
531- syn:: parse_str ( " minicbor::Decode<'bytes, Ctx>" )
545+ fn gen_decode_bound ( ) -> syn:: TypeParamBound {
546+ syn:: parse_quote! ( minicbor:: Decode <' bytes, Ctx >)
532547}
533548
534- fn gen_default_bound ( ) -> syn:: Result < syn :: TypeParamBound > {
535- syn:: parse_str ( " Default" )
549+ fn gen_default_bound ( ) -> syn:: TypeParamBound {
550+ syn:: parse_quote! ( Default )
536551}
537552
538553fn defs < ' a , T > ( fields : T ) -> Vec < proc_macro2:: TokenStream >
0 commit comments