@@ -31,6 +31,7 @@ enum ErrorKind {
31
31
ForbiddenType ,
32
32
MalformedAttrs ,
33
33
MissingPub ,
34
+ MissingRepr ,
34
35
MissingUnsafe ,
35
36
UnderscoreField ,
36
37
UnknownRepr ,
@@ -49,6 +50,7 @@ impl Display for ErrorKind {
49
50
Self :: ForbiddenType => "forbidden type" ,
50
51
Self :: MalformedAttrs => "malformed attribute contents" ,
51
52
Self :: MissingPub => "missing pub" ,
53
+ Self :: MissingRepr => "missing repr" ,
52
54
Self :: MissingUnsafe => "missing unsafe" ,
53
55
Self :: UnderscoreField => "field name starts with `_`" ,
54
56
Self :: UnknownRepr => "unknown repr" ,
@@ -105,17 +107,18 @@ fn is_pub(vis: &Visibility) -> bool {
105
107
}
106
108
107
109
/// Type repr. A type may have more than one of these (e.g. both `C` and `Packed`).
108
- #[ derive( Clone , Copy , Eq , PartialEq , Ord , PartialOrd ) ]
110
+ #[ derive( Debug , Clone , Copy , Eq , PartialEq , Ord , PartialOrd ) ]
109
111
enum Repr {
110
112
Align ( usize ) ,
111
113
C ,
114
+ Rust ,
112
115
Packed ,
113
116
Transparent ,
114
117
}
115
118
116
119
/// A restricted view of `Attribute`, limited to just the attributes that are
117
120
/// expected in `uefi-raw`.
118
- #[ derive( Clone , Copy ) ]
121
+ #[ derive( Debug , Clone , Copy ) ]
119
122
enum ParsedAttr {
120
123
Derive ,
121
124
Doc ,
@@ -137,6 +140,8 @@ fn parse_attrs(attrs: &[Attribute], src: &Path) -> Result<Vec<ParsedAttr>, Error
137
140
attr. parse_nested_meta ( |meta| {
138
141
if meta. path . is_ident ( "C" ) {
139
142
va. push ( ParsedAttr :: Repr ( Repr :: C ) ) ;
143
+ } else if meta. path . is_ident ( "Rust" ) {
144
+ va. push ( ParsedAttr :: Repr ( Repr :: Rust ) ) ;
140
145
} else if meta. path . is_ident ( "packed" ) {
141
146
va. push ( ParsedAttr :: Repr ( Repr :: Packed ) ) ;
142
147
} else if meta. path . is_ident ( "transparent" ) {
@@ -259,7 +264,9 @@ fn check_type_attrs(attrs: &[Attribute], spanned: &dyn Spanned, src: &Path) -> R
259
264
260
265
let allowed_reprs: & [ & [ Repr ] ] = & [ & [ Repr :: C ] , & [ Repr :: C , Repr :: Packed ] , & [ Repr :: Transparent ] ] ;
261
266
262
- if allowed_reprs. contains ( & reprs. as_slice ( ) ) {
267
+ if reprs. is_empty ( ) {
268
+ Err ( Error :: new ( ErrorKind :: MissingRepr , src, spanned) )
269
+ } else if allowed_reprs. contains ( & reprs. as_slice ( ) ) {
263
270
Ok ( ( ) )
264
271
} else {
265
272
Err ( Error :: new ( ErrorKind :: ForbiddenRepr , src, spanned) )
@@ -408,6 +415,7 @@ mod tests {
408
415
Path :: new ( "test" )
409
416
}
410
417
418
+ #[ track_caller]
411
419
fn check_item_err ( item : Item , expected_error : ErrorKind ) {
412
420
assert_eq ! ( check_item( & item, src( ) ) . unwrap_err( ) . kind, expected_error) ;
413
421
}
@@ -545,9 +553,20 @@ mod tests {
545
553
ErrorKind :: UnderscoreField ,
546
554
) ;
547
555
556
+ // Missing `repr`.
557
+ check_item_err (
558
+ parse_quote ! {
559
+ pub struct S {
560
+ pub f: u32 ,
561
+ }
562
+ } ,
563
+ ErrorKind :: MissingRepr ,
564
+ ) ;
565
+
548
566
// Forbidden `repr`.
549
567
check_item_err (
550
568
parse_quote ! {
569
+ #[ repr( Rust ) ]
551
570
pub struct S {
552
571
pub f: u32 ,
553
572
}
@@ -623,7 +642,7 @@ mod tests {
623
642
pub f: u32 ,
624
643
}
625
644
} ,
626
- ErrorKind :: ForbiddenRepr ,
645
+ ErrorKind :: MissingRepr ,
627
646
) ;
628
647
}
629
648
}
0 commit comments