@@ -7,6 +7,7 @@ use core::u64;
77use log:: warn;
88use proc_macro2:: { Ident , Punct , Spacing , Span , TokenStream } ;
99use quote:: { quote, ToTokens } ;
10+ use std:: collections:: HashSet ;
1011use svd_parser:: expand:: {
1112 derive_enumerated_values, derive_field, EnumPath , FieldPath , Index , RegisterPath ,
1213} ;
@@ -337,6 +338,12 @@ pub fn fields(
337338
338339 fields. sort_by_key ( |f| f. bit_offset ( ) ) ;
339340
341+ // Hack for #625
342+ let mut enum_derives = HashSet :: new ( ) ;
343+ let mut reader_derives = HashSet :: new ( ) ;
344+ let mut writer_enum_derives = HashSet :: new ( ) ;
345+ let mut writer_derives = HashSet :: new ( ) ;
346+
340347 // TODO enumeratedValues
341348 let inline = quote ! { #[ inline( always) ] } ;
342349 for & f in fields. iter ( ) {
@@ -625,26 +632,32 @@ pub fn fields(
625632 let base_field = util:: replace_suffix ( & base. field . name , "" ) ;
626633 let base_constant_case = base_field. to_sanitized_constant_case ( ) ;
627634 let base_r = Ident :: new ( & ( base_constant_case + "_R" ) , span) ;
628- derive_from_base (
629- mod_items,
630- & base,
631- & fpath,
632- & reader_ty,
633- & base_r,
634- & field_reader_brief,
635- ) ?;
636- // only pub use enum when base.register != None. if base.register == None, it emits
637- // pub use enum from same module which is not expected
638- if base. register ( ) != fpath. register ( ) {
639- // use the same enum structure name
635+ if !reader_derives. contains ( & reader_ty) {
640636 derive_from_base (
641637 mod_items,
642638 & base,
643639 & fpath,
644- & value_read_ty ,
645- & value_read_ty ,
646- & description ,
640+ & reader_ty ,
641+ & base_r ,
642+ & field_reader_brief ,
647643 ) ?;
644+ reader_derives. insert ( reader_ty. clone ( ) ) ;
645+ }
646+ // only pub use enum when base.register != None. if base.register == None, it emits
647+ // pub use enum from same module which is not expected
648+ if base. register ( ) != fpath. register ( ) {
649+ // use the same enum structure name
650+ if !enum_derives. contains ( & value_read_ty) {
651+ derive_from_base (
652+ mod_items,
653+ & base,
654+ & fpath,
655+ & value_read_ty,
656+ & value_read_ty,
657+ & description,
658+ ) ?;
659+ enum_derives. insert ( value_read_ty. clone ( ) ) ;
660+ }
648661 }
649662 }
650663
@@ -865,14 +878,17 @@ pub fn fields(
865878 let writer_reader_different_enum = evs_r. as_ref ( ) != Some ( evs) ;
866879 if writer_reader_different_enum {
867880 // use the same enum structure name
868- derive_from_base (
869- mod_items,
870- & base,
871- & fpath,
872- & value_write_ty,
873- & value_write_ty,
874- & description,
875- ) ?;
881+ if !writer_enum_derives. contains ( & value_write_ty) {
882+ derive_from_base (
883+ mod_items,
884+ & base,
885+ & fpath,
886+ & value_write_ty,
887+ & value_write_ty,
888+ & description,
889+ ) ?;
890+ writer_enum_derives. insert ( value_write_ty. clone ( ) ) ;
891+ }
876892 }
877893 } else {
878894 // if base.register == None, derive write from the same module. This is allowed because both
@@ -884,14 +900,17 @@ pub fn fields(
884900 let base_field = util:: replace_suffix ( & base. field . name , "" ) ;
885901 let base_constant_case = base_field. to_sanitized_constant_case ( ) ;
886902 let base_w = Ident :: new ( & ( base_constant_case + "_W" ) , span) ;
887- derive_from_base (
888- mod_items,
889- & base,
890- & fpath,
891- & writer_ty,
892- & base_w,
893- & field_writer_brief,
894- ) ?;
903+ if !writer_derives. contains ( & writer_ty) {
904+ derive_from_base (
905+ mod_items,
906+ & base,
907+ & fpath,
908+ & writer_ty,
909+ & base_w,
910+ & field_writer_brief,
911+ ) ?;
912+ writer_derives. insert ( writer_ty. clone ( ) ) ;
913+ }
895914 }
896915 }
897916
0 commit comments