@@ -31,6 +31,7 @@ enum ErrorKind {
3131 ForbiddenType ,
3232 MalformedAttrs ,
3333 MissingPub ,
34+ MissingRepr ,
3435 MissingUnsafe ,
3536 UnderscoreField ,
3637 UnknownRepr ,
@@ -49,6 +50,7 @@ impl Display for ErrorKind {
4950 Self :: ForbiddenType => "forbidden type" ,
5051 Self :: MalformedAttrs => "malformed attribute contents" ,
5152 Self :: MissingPub => "missing pub" ,
53+ Self :: MissingRepr => "missing repr" ,
5254 Self :: MissingUnsafe => "missing unsafe" ,
5355 Self :: UnderscoreField => "field name starts with `_`" ,
5456 Self :: UnknownRepr => "unknown repr" ,
@@ -105,17 +107,18 @@ fn is_pub(vis: &Visibility) -> bool {
105107}
106108
107109/// 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 ) ]
109111enum Repr {
110112 Align ( usize ) ,
111113 C ,
114+ Rust ,
112115 Packed ,
113116 Transparent ,
114117}
115118
116119/// A restricted view of `Attribute`, limited to just the attributes that are
117120/// expected in `uefi-raw`.
118- #[ derive( Clone , Copy ) ]
121+ #[ derive( Debug , Clone , Copy ) ]
119122enum ParsedAttr {
120123 Derive ,
121124 Doc ,
@@ -137,6 +140,8 @@ fn parse_attrs(attrs: &[Attribute], src: &Path) -> Result<Vec<ParsedAttr>, Error
137140 attr. parse_nested_meta ( |meta| {
138141 if meta. path . is_ident ( "C" ) {
139142 va. push ( ParsedAttr :: Repr ( Repr :: C ) ) ;
143+ } else if meta. path . is_ident ( "Rust" ) {
144+ va. push ( ParsedAttr :: Repr ( Repr :: Rust ) ) ;
140145 } else if meta. path . is_ident ( "packed" ) {
141146 va. push ( ParsedAttr :: Repr ( Repr :: Packed ) ) ;
142147 } else if meta. path . is_ident ( "transparent" ) {
@@ -259,7 +264,9 @@ fn check_type_attrs(attrs: &[Attribute], spanned: &dyn Spanned, src: &Path) -> R
259264
260265 let allowed_reprs: & [ & [ Repr ] ] = & [ & [ Repr :: C ] , & [ Repr :: C , Repr :: Packed ] , & [ Repr :: Transparent ] ] ;
261266
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 ( ) ) {
263270 Ok ( ( ) )
264271 } else {
265272 Err ( Error :: new ( ErrorKind :: ForbiddenRepr , src, spanned) )
@@ -408,6 +415,7 @@ mod tests {
408415 Path :: new ( "test" )
409416 }
410417
418+ #[ track_caller]
411419 fn check_item_err ( item : Item , expected_error : ErrorKind ) {
412420 assert_eq ! ( check_item( & item, src( ) ) . unwrap_err( ) . kind, expected_error) ;
413421 }
@@ -545,9 +553,20 @@ mod tests {
545553 ErrorKind :: UnderscoreField ,
546554 ) ;
547555
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+
548566 // Forbidden `repr`.
549567 check_item_err (
550568 parse_quote ! {
569+ #[ repr( Rust ) ]
551570 pub struct S {
552571 pub f: u32 ,
553572 }
@@ -623,7 +642,7 @@ mod tests {
623642 pub f: u32 ,
624643 }
625644 } ,
626- ErrorKind :: ForbiddenRepr ,
645+ ErrorKind :: MissingRepr ,
627646 ) ;
628647 }
629648}
0 commit comments