@@ -106,7 +106,7 @@ fn collect_flags<'a>(variants: impl Iterator<Item=&'a syn::Variant>)
106106/// Given a list of attributes, find the `repr`, if any, and return the integer
107107/// type specified.
108108fn extract_repr ( attrs : & [ syn:: Attribute ] )
109- -> Result < Option < syn :: Ident > , syn:: Error >
109+ -> Result < Option < Ident > , syn:: Error >
110110{
111111 use syn:: { Meta , NestedMeta } ;
112112 attrs. iter ( )
@@ -132,6 +132,29 @@ fn extract_repr(attrs: &[syn::Attribute])
132132 . transpose ( )
133133}
134134
135+ /// Check the repr and return the number of bits available
136+ fn type_bits ( ty : & Ident ) -> Result < u8 , syn:: Error > {
137+ // This would be so much easier if we could just match on an Ident...
138+ if ty == "usize" {
139+ Err ( syn:: Error :: new_spanned ( ty,
140+ "#[repr(usize)] is not supported. Use u32 or u64 instead." ) )
141+ }
142+ else if ty == "i8" || ty == "i16" || ty == "i32"
143+ || ty == "i64" || ty == "i128" || ty == "isize" {
144+ Err ( syn:: Error :: new_spanned ( ty,
145+ "Signed types in a repr are not supported." ) )
146+ }
147+ else if ty == "u8" { Ok ( 8 ) }
148+ else if ty == "u16" { Ok ( 16 ) }
149+ else if ty == "u32" { Ok ( 32 ) }
150+ else if ty == "u64" { Ok ( 64 ) }
151+ else if ty == "u128" { Ok ( 128 ) }
152+ else {
153+ Err ( syn:: Error :: new_spanned ( ty,
154+ "repr must be an integer type for #[bitflags]." ) )
155+ }
156+ }
157+
135158/// Returns deferred checks
136159fn check_flag (
137160 type_name : & Ident ,
@@ -193,6 +216,7 @@ fn gen_enumflags(ident: &Ident, item: &DeriveInput, data: &DataEnum)
193216 let ty = extract_repr ( & item. attrs ) ?
194217 . ok_or_else ( || syn:: Error :: new_spanned ( & ident,
195218 "repr attribute missing. Add #[repr(u64)] or a similar attribute to specify the size of the bitfield." ) ) ?;
219+ type_bits ( & ty) ?;
196220 let std_path = quote_spanned ! ( span => :: enumflags2:: _internal:: core) ;
197221
198222 Ok ( quote_spanned ! {
0 commit comments