@@ -33,6 +33,7 @@ enum ErrorKind {
33
33
ForbiddenType ,
34
34
MalformedAttrs ,
35
35
MissingPub ,
36
+ MissingRepr ,
36
37
MissingUnsafe ,
37
38
UnderscoreField ,
38
39
UnknownRepr ,
@@ -51,6 +52,7 @@ impl Display for ErrorKind {
51
52
Self :: ForbiddenType => "forbidden type" ,
52
53
Self :: MalformedAttrs => "malformed attribute contents" ,
53
54
Self :: MissingPub => "missing pub" ,
55
+ Self :: MissingRepr => "missing repr" ,
54
56
Self :: MissingUnsafe => "missing unsafe" ,
55
57
Self :: UnderscoreField => "field name starts with `_`" ,
56
58
Self :: UnknownRepr => "unknown repr" ,
@@ -106,18 +108,19 @@ fn is_pub(vis: &Visibility) -> bool {
106
108
matches ! ( vis, Visibility :: Public ( _) )
107
109
}
108
110
109
- /// Type repr. A type may have more than one of these (e.g. both `C` and `Packed `).
110
- #[ derive( Clone , Copy , Eq , PartialEq , Ord , PartialOrd ) ]
111
+ /// Type repr. A type may have more than one of these (e.g. both `C` and `packed `).
112
+ #[ derive( Debug , Clone , Copy , Eq , PartialEq , Ord , PartialOrd ) ]
111
113
enum Repr {
112
114
Align ( usize ) ,
113
115
C ,
114
116
Packed ,
117
+ Rust ,
115
118
Transparent ,
116
119
}
117
120
118
121
/// A restricted view of `Attribute`, limited to just the attributes that are
119
122
/// expected in `uefi-raw`.
120
- #[ derive( Clone , Copy ) ]
123
+ #[ derive( Debug , Clone , Copy ) ]
121
124
enum ParsedAttr {
122
125
Derive ,
123
126
Doc ,
@@ -141,6 +144,8 @@ fn parse_attrs(attrs: &[Attribute], src: &Path) -> Result<Vec<ParsedAttr>, Error
141
144
va. push ( ParsedAttr :: Repr ( Repr :: C ) ) ;
142
145
} else if meta. path . is_ident ( "packed" ) {
143
146
va. push ( ParsedAttr :: Repr ( Repr :: Packed ) ) ;
147
+ } else if meta. path . is_ident ( "Rust" ) {
148
+ va. push ( ParsedAttr :: Repr ( Repr :: Rust ) ) ;
144
149
} else if meta. path . is_ident ( "transparent" ) {
145
150
va. push ( ParsedAttr :: Repr ( Repr :: Transparent ) ) ;
146
151
} else if meta. path . is_ident ( "align" ) {
@@ -255,13 +260,16 @@ fn check_fields(fields: &Punctuated<Field, Comma>, src: &Path) -> Result<(), Err
255
260
Ok ( ( ) )
256
261
}
257
262
263
+ /// List with allowed combinations of representations (see [`Repr`]).
264
+ const ALLOWED_REPRS : & [ & [ Repr ] ] = & [ & [ Repr :: C ] , & [ Repr :: C , Repr :: Packed ] , & [ Repr :: Transparent ] ] ;
265
+
258
266
fn check_type_attrs ( attrs : & [ Attribute ] , spanned : & dyn Spanned , src : & Path ) -> Result < ( ) , Error > {
259
267
let attrs = parse_attrs ( attrs, src) ?;
260
268
let reprs = get_reprs ( & attrs) ;
261
269
262
- let allowed_reprs : & [ & [ Repr ] ] = & [ & [ Repr :: C ] , & [ Repr :: C , Repr :: Packed ] , & [ Repr :: Transparent ] ] ;
263
-
264
- if allowed_reprs . contains ( & reprs. as_slice ( ) ) {
270
+ if reprs . is_empty ( ) {
271
+ Err ( Error :: new ( ErrorKind :: MissingRepr , src , spanned ) )
272
+ } else if ALLOWED_REPRS . contains ( & reprs. as_slice ( ) ) {
265
273
Ok ( ( ) )
266
274
} else {
267
275
Err ( Error :: new ( ErrorKind :: ForbiddenRepr , src, spanned) )
@@ -410,6 +418,7 @@ mod tests {
410
418
Path :: new ( "test" )
411
419
}
412
420
421
+ #[ track_caller]
413
422
fn check_item_err ( item : Item , expected_error : ErrorKind ) {
414
423
assert_eq ! ( check_item( & item, src( ) ) . unwrap_err( ) . kind, expected_error) ;
415
424
}
@@ -547,9 +556,20 @@ mod tests {
547
556
ErrorKind :: UnderscoreField ,
548
557
) ;
549
558
559
+ // Missing `repr`.
560
+ check_item_err (
561
+ parse_quote ! {
562
+ pub struct S {
563
+ pub f: u32 ,
564
+ }
565
+ } ,
566
+ ErrorKind :: MissingRepr ,
567
+ ) ;
568
+
550
569
// Forbidden `repr`.
551
570
check_item_err (
552
571
parse_quote ! {
572
+ #[ repr( Rust ) ]
553
573
pub struct S {
554
574
pub f: u32 ,
555
575
}
@@ -625,7 +645,7 @@ mod tests {
625
645
pub f: u32 ,
626
646
}
627
647
} ,
628
- ErrorKind :: ForbiddenRepr ,
648
+ ErrorKind :: MissingRepr ,
629
649
) ;
630
650
}
631
651
}
0 commit comments