@@ -12,12 +12,14 @@ use syn::{
1212 Ident , Item , ItemEnum , Token ,
1313} ;
1414
15+ #[ derive( Debug ) ]
1516struct Flag {
1617 name : Ident ,
1718 span : Span ,
1819 value : FlagValue ,
1920}
2021
22+ #[ derive( Debug ) ]
2123enum FlagValue {
2224 Literal ( u128 ) ,
2325 Deferred ,
@@ -88,6 +90,9 @@ fn fold_expr(expr: &syn::Expr) -> Option<u128> {
8890 _ => None ,
8991 }
9092 }
93+ Expr :: Paren ( syn:: ExprParen { expr, .. } ) | Expr :: Group ( syn:: ExprGroup { expr, .. } ) => {
94+ fold_expr ( & expr)
95+ }
9196 _ => None ,
9297 }
9398}
@@ -187,7 +192,7 @@ fn type_bits(ty: &Ident) -> Result<u8, syn::Error> {
187192}
188193
189194/// Returns deferred checks
190- fn check_flag ( type_name : & Ident , flag : & Flag ) -> Result < Option < TokenStream > , syn:: Error > {
195+ fn check_flag ( type_name : & Ident , flag : & Flag , bits : u8 ) -> Result < Option < TokenStream > , syn:: Error > {
191196 use FlagValue :: * ;
192197 match flag. value {
193198 Literal ( n) => {
@@ -196,6 +201,11 @@ fn check_flag(type_name: &Ident, flag: &Flag) -> Result<Option<TokenStream>, syn
196201 flag. span ,
197202 "Flags must have exactly one set bit" ,
198203 ) )
204+ } else if bits < 128 && n >= 1 << bits {
205+ Err ( syn:: Error :: new (
206+ flag. span ,
207+ format ! ( "Flag value out of range for u{}" , bits) ,
208+ ) )
199209 } else {
200210 Ok ( None )
201211 }
@@ -235,17 +245,17 @@ fn gen_enumflags(ast: &ItemEnum, default: Vec<Ident>) -> Result<TokenStream, syn
235245 let variant_names = ast. variants . iter ( ) . map ( |v| & v. ident ) . collect :: < Vec < _ > > ( ) ;
236246 let repeated_name = vec ! [ & ident; ast. variants. len( ) ] ;
237247
238- let variants = collect_flags ( ast. variants . iter ( ) ) ?;
239- let deferred = variants
240- . iter ( )
241- . flat_map ( |variant| check_flag ( ident, variant) . transpose ( ) )
242- . collect :: < Result < Vec < _ > , _ > > ( ) ?;
243-
244248 let ty = extract_repr ( & ast. attrs ) ?
245249 . ok_or_else ( || syn:: Error :: new_spanned ( & ident,
246250 "repr attribute missing. Add #[repr(u64)] or a similar attribute to specify the size of the bitfield." ) ) ?;
247251 let bits = type_bits ( & ty) ?;
248252
253+ let variants = collect_flags ( ast. variants . iter ( ) ) ?;
254+ let deferred = variants
255+ . iter ( )
256+ . flat_map ( |variant| check_flag ( ident, variant, bits) . transpose ( ) )
257+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
258+
249259 if ( bits as usize ) < variants. len ( ) {
250260 return Err ( syn:: Error :: new_spanned (
251261 & ty,
0 commit comments