@@ -33,6 +33,7 @@ enum ErrorKind {
3333 ForbiddenType ,
3434 MalformedAttrs ,
3535 MissingPub ,
36+ MissingRepr ,
3637 MissingUnsafe ,
3738 UnderscoreField ,
3839 UnknownRepr ,
@@ -51,6 +52,7 @@ impl Display for ErrorKind {
5152 Self :: ForbiddenType => "forbidden type" ,
5253 Self :: MalformedAttrs => "malformed attribute contents" ,
5354 Self :: MissingPub => "missing pub" ,
55+ Self :: MissingRepr => "missing repr" ,
5456 Self :: MissingUnsafe => "missing unsafe" ,
5557 Self :: UnderscoreField => "field name starts with `_`" ,
5658 Self :: UnknownRepr => "unknown repr" ,
@@ -106,18 +108,19 @@ fn is_pub(vis: &Visibility) -> bool {
106108 matches ! ( vis, Visibility :: Public ( _) )
107109}
108110
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 ) ]
111113enum Repr {
112114 Align ( usize ) ,
113115 C ,
114116 Packed ,
117+ Rust ,
115118 Transparent ,
116119}
117120
118121/// A restricted view of `Attribute`, limited to just the attributes that are
119122/// expected in `uefi-raw`.
120- #[ derive( Clone , Copy ) ]
123+ #[ derive( Debug , Clone , Copy ) ]
121124enum ParsedAttr {
122125 Derive ,
123126 Doc ,
@@ -141,6 +144,8 @@ fn parse_attrs(attrs: &[Attribute], src: &Path) -> Result<Vec<ParsedAttr>, Error
141144 va. push ( ParsedAttr :: Repr ( Repr :: C ) ) ;
142145 } else if meta. path . is_ident ( "packed" ) {
143146 va. push ( ParsedAttr :: Repr ( Repr :: Packed ) ) ;
147+ } else if meta. path . is_ident ( "Rust" ) {
148+ va. push ( ParsedAttr :: Repr ( Repr :: Rust ) ) ;
144149 } else if meta. path . is_ident ( "transparent" ) {
145150 va. push ( ParsedAttr :: Repr ( Repr :: Transparent ) ) ;
146151 } else if meta. path . is_ident ( "align" ) {
@@ -255,13 +260,16 @@ fn check_fields(fields: &Punctuated<Field, Comma>, src: &Path) -> Result<(), Err
255260 Ok ( ( ) )
256261}
257262
263+ /// List with allowed combinations of representations (see [`Repr`]).
264+ const ALLOWED_REPRS : & [ & [ Repr ] ] = & [ & [ Repr :: C ] , & [ Repr :: C , Repr :: Packed ] , & [ Repr :: Transparent ] ] ;
265+
258266fn check_type_attrs ( attrs : & [ Attribute ] , spanned : & dyn Spanned , src : & Path ) -> Result < ( ) , Error > {
259267 let attrs = parse_attrs ( attrs, src) ?;
260268 let reprs = get_reprs ( & attrs) ;
261269
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 ( ) ) {
265273 Ok ( ( ) )
266274 } else {
267275 Err ( Error :: new ( ErrorKind :: ForbiddenRepr , src, spanned) )
@@ -410,6 +418,7 @@ mod tests {
410418 Path :: new ( "test" )
411419 }
412420
421+ #[ track_caller]
413422 fn check_item_err ( item : Item , expected_error : ErrorKind ) {
414423 assert_eq ! ( check_item( & item, src( ) ) . unwrap_err( ) . kind, expected_error) ;
415424 }
@@ -547,9 +556,20 @@ mod tests {
547556 ErrorKind :: UnderscoreField ,
548557 ) ;
549558
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+
550569 // Forbidden `repr`.
551570 check_item_err (
552571 parse_quote ! {
572+ #[ repr( Rust ) ]
553573 pub struct S {
554574 pub f: u32 ,
555575 }
@@ -625,7 +645,7 @@ mod tests {
625645 pub f: u32 ,
626646 }
627647 } ,
628- ErrorKind :: ForbiddenRepr ,
648+ ErrorKind :: MissingRepr ,
629649 ) ;
630650 }
631651}
0 commit comments