@@ -7,6 +7,7 @@ use core::u64;
7
7
use log:: warn;
8
8
use proc_macro2:: { Ident , Punct , Spacing , Span , TokenStream } ;
9
9
use quote:: { quote, ToTokens } ;
10
+ use std:: collections:: HashSet ;
10
11
use svd_parser:: expand:: {
11
12
derive_enumerated_values, derive_field, EnumPath , FieldPath , Index , RegisterPath ,
12
13
} ;
@@ -337,6 +338,12 @@ pub fn fields(
337
338
338
339
fields. sort_by_key ( |f| f. bit_offset ( ) ) ;
339
340
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
+
340
347
// TODO enumeratedValues
341
348
let inline = quote ! { #[ inline( always) ] } ;
342
349
for & f in fields. iter ( ) {
@@ -625,26 +632,32 @@ pub fn fields(
625
632
let base_field = util:: replace_suffix ( & base. field . name , "" ) ;
626
633
let base_constant_case = base_field. to_sanitized_constant_case ( ) ;
627
634
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) {
640
636
derive_from_base (
641
637
mod_items,
642
638
& base,
643
639
& fpath,
644
- & value_read_ty ,
645
- & value_read_ty ,
646
- & description ,
640
+ & reader_ty ,
641
+ & base_r ,
642
+ & field_reader_brief ,
647
643
) ?;
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
+ }
648
661
}
649
662
}
650
663
@@ -865,14 +878,17 @@ pub fn fields(
865
878
let writer_reader_different_enum = evs_r. as_ref ( ) != Some ( evs) ;
866
879
if writer_reader_different_enum {
867
880
// 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
+ }
876
892
}
877
893
} else {
878
894
// if base.register == None, derive write from the same module. This is allowed because both
@@ -884,14 +900,17 @@ pub fn fields(
884
900
let base_field = util:: replace_suffix ( & base. field . name , "" ) ;
885
901
let base_constant_case = base_field. to_sanitized_constant_case ( ) ;
886
902
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
+ }
895
914
}
896
915
}
897
916
0 commit comments