1
1
// Generate docs from readme
2
2
#![ doc = include_str ! ( "../README.md" ) ]
3
-
4
3
#![ warn( clippy:: unwrap_used) ]
5
4
6
5
use proc_macro as pc;
@@ -29,8 +28,8 @@ use syn::Token;
29
28
/// - the number of bits
30
29
/// - `access` to specify the access mode (RW, RO, WO, None)
31
30
/// - `default` to set a default value
32
- /// - `into` to specify a conversion from the underlying type to the field type
33
- /// - `from` to specify a conversion from the field type to the underlying type
31
+ /// - `into` to specify a conversion function from the field type to the bitfield type
32
+ /// - `from` to specify a conversion function from the bitfield type to the field type
34
33
#[ proc_macro_attribute]
35
34
pub fn bitfield ( args : pc:: TokenStream , input : pc:: TokenStream ) -> pc:: TokenStream {
36
35
match bitfield_inner ( args. into ( ) , input. into ( ) ) {
@@ -51,7 +50,6 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
51
50
52
51
let span = input. fields . span ( ) ;
53
52
let name = input. ident ;
54
- let name_str = name. to_string ( ) ;
55
53
let vis = input. vis ;
56
54
let attrs: TokenStream = input. attrs . iter ( ) . map ( ToTokens :: to_token_stream) . collect ( ) ;
57
55
@@ -91,7 +89,7 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
91
89
quote ! {
92
90
impl core:: fmt:: Debug for #name {
93
91
fn fmt( & self , f: & mut core:: fmt:: Formatter <' _>) -> core:: fmt:: Result {
94
- f. debug_struct( #name_str )
92
+ f. debug_struct( stringify! ( #name ) )
95
93
#( #debug_fields ) *
96
94
. finish( )
97
95
}
@@ -484,49 +482,52 @@ fn parse_field(
484
482
}
485
483
ret. bits = bits;
486
484
}
487
- // padding
488
- if ignore && ( into. is_some ( ) || from. is_some ( ) ) {
489
- return Err ( syn:: Error :: new (
490
- default. span ( ) ,
491
- "'into' and 'from' are not supported on padding" ,
492
- ) ) ;
493
- }
494
485
495
- // Ensure padding fields remain inaccesible
496
- if ignore && access. is_some_and ( |mode| mode != Access :: None ) {
497
- return Err ( syn:: Error :: new (
498
- default. span ( ) ,
499
- "'access' may only be 'None' (or unset) for padding" ,
500
- ) ) ;
486
+ // read/write access
487
+ if let Some ( access) = access {
488
+ if ignore {
489
+ return Err ( syn:: Error :: new (
490
+ tokens. span ( ) ,
491
+ "'access' is not supported for padding" ,
492
+ ) ) ;
493
+ }
494
+ ret. access = access;
501
495
}
502
496
503
497
// conversion
504
498
if let Some ( into) = into {
499
+ if ret. access == Access :: None {
500
+ return Err ( syn:: Error :: new (
501
+ into. span ( ) ,
502
+ "'into' and 'from' are not supported on padding" ,
503
+ ) ) ;
504
+ }
505
505
ret. into = quote ! ( #into( this) ) ;
506
506
}
507
507
if let Some ( from) = from {
508
+ if ret. access == Access :: None {
509
+ return Err ( syn:: Error :: new (
510
+ from. span ( ) ,
511
+ "'into' and 'from' are not supported on padding" ,
512
+ ) ) ;
513
+ }
508
514
ret. from = quote ! ( #from( this) ) ;
509
515
}
510
516
if let Some ( default) = default {
511
517
ret. default = default. into_token_stream ( ) ;
512
518
}
513
-
514
- // read/write access
515
- if let Some ( access) = access {
516
- ret. access = access;
517
- }
518
519
}
519
520
}
520
521
521
522
if ret. bits == 0 {
522
523
return Err ( syn:: Error :: new (
523
524
ty. span ( ) ,
524
- "Custom types and isize/usize require the size in the #[bits] attribute " ,
525
+ "Custom types and isize/usize require an explicit bit size " ,
525
526
) ) ;
526
527
}
527
528
528
529
// Signed integers need some special handling...
529
- if !ignore && class == TypeClass :: SInt {
530
+ if !ignore && ret . access != Access :: None && class == TypeClass :: SInt {
530
531
let bits = ret. bits as u32 ;
531
532
let mask = u128:: MAX >> ( u128:: BITS - ret. bits as u32 ) ;
532
533
let mask = syn:: LitInt :: new ( & format ! ( "0x{mask:x}" ) , Span :: mixed_site ( ) ) ;
@@ -627,7 +628,7 @@ impl Parse for Access {
627
628
} else {
628
629
Err ( syn:: Error :: new (
629
630
mode. span ( ) ,
630
- "Invalid access mode, only RW/RO/WO/ None are allowed" ,
631
+ "Invalid access mode, only RW, RO, WO, or None are allowed" ,
631
632
) )
632
633
}
633
634
}
0 commit comments