@@ -45,7 +45,13 @@ pub fn const_eval_check_variant_indexes(
4545 let mut recurse_indices = vec ! [ ] ;
4646 for ( ident, index) in recurse_variant_indices {
4747 let ident_str = ident. to_string ( ) ;
48- recurse_indices. push ( quote ! { ( #index, #ident_str) } ) ;
48+ // We convert to u8 same as in the generated code.
49+ recurse_indices. push ( quote_spanned ! { ident. span( ) =>
50+ (
51+ ( #index) as :: core:: primitive:: u8 ,
52+ #ident_str
53+ )
54+ } ) ;
4955 }
5056 let len = recurse_indices. len ( ) ;
5157
@@ -55,11 +61,12 @@ pub fn const_eval_check_variant_indexes(
5561
5662 quote ! {
5763 const _: ( ) = {
58- const indices: [ ( usize , & ' static str ) ; #len] = [ #( #recurse_indices , ) * ] ;
64+ #[ allow( clippy:: unnecessary_cast) ]
65+ const indices: [ ( u8 , & ' static str ) ; #len] = [ #( #recurse_indices , ) * ] ;
5966
6067 // Returns if there is duplicate, and if there is some the duplicate indexes.
61- const fn duplicate_info( array: & [ ( usize , & ' static str ) ; #len] ) -> ( bool , usize , usize ) {
62- let len = array . len( ) ;
68+ const fn duplicate_info( array: & [ ( u8 , & ' static str ) ; #len] ) -> ( bool , usize , usize ) {
69+ let len = # len;
6370 let mut i = 0 ;
6471 while i < len {
6572 let mut j = i + 1 ;
@@ -97,7 +104,7 @@ pub fn const_eval_check_variant_indexes(
97104/// is found, fall back to the discriminant or just the variant index.
98105pub fn variant_index ( v : & Variant , i : usize ) -> TokenStream {
99106 // first look for an attribute
100- let mut index = find_meta_item ( v. attrs . iter ( ) , |meta| {
107+ let index = find_meta_item ( v. attrs . iter ( ) , |meta| {
101108 if let Meta :: NameValue ( ref nv) = meta {
102109 if nv. path . is_ident ( "index" ) {
103110 if let Expr :: Lit ( ExprLit { lit : Lit :: Int ( ref v) , .. } ) = nv. value {
@@ -112,21 +119,13 @@ pub fn variant_index(v: &Variant, i: usize) -> TokenStream {
112119 None
113120 } ) ;
114121
115- // if no attribute, we fall back to an explicit discriminant (ie 'enum A { Foo = 1u32 }').
116- if index. is_none ( ) {
117- if let Some ( ( _, Expr :: Lit ( ExprLit { lit : Lit :: Int ( disc_lit) , .. } ) ) ) = & v. discriminant {
118- index = disc_lit. base10_parse :: < usize > ( ) . ok ( )
119- }
120- }
121-
122- // fall back to the variant index if no attribute or explicit discriminant is found.
123- let index = index. unwrap_or ( i) ;
124-
125- // output the index with no suffix (ie 1 rather than 1usize) so that these can be quoted into
126- // an array of usizes and will work regardless of what type the discriminant values actually
127- // are.
128- let s = proc_macro2:: Literal :: usize_unsuffixed ( index) ;
129- quote ! { #s }
122+ // then fallback to discriminant or just index
123+ index. map ( |i| quote ! { #i } ) . unwrap_or_else ( || {
124+ v. discriminant
125+ . as_ref ( )
126+ . map ( |( _, expr) | quote ! { #expr } )
127+ . unwrap_or_else ( || quote ! { #i } )
128+ } )
130129}
131130
132131/// Look for a `#[codec(encoded_as = "SomeType")]` outer attribute on the given
@@ -394,12 +393,6 @@ pub fn check_attributes(input: &DeriveInput) -> syn::Result<()> {
394393 check_field_attribute ( attr) ?;
395394 }
396395 }
397- // While we're checking things, also ensure that
398- // any explicit discriminants are within 0..=255
399- let discriminant = variant. discriminant . as_ref ( ) . map ( |( _, d) | d) ;
400- if let Some ( expr) = discriminant {
401- check_variant_discriminant ( expr) ?;
402- }
403396 } ,
404397 Data :: Union ( _) => ( ) ,
405398 }
@@ -479,21 +472,6 @@ fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> {
479472 }
480473}
481474
482- // Ensure a variant discriminant, if provided, can be parsed into
483- // something in the range 0..255.
484- fn check_variant_discriminant ( discriminant : & Expr ) -> syn:: Result < ( ) > {
485- if let Expr :: Lit ( ExprLit { lit : Lit :: Int ( lit_int) , .. } ) = discriminant {
486- lit_int. base10_parse :: < u8 > ( ) . map ( |_| ( ) ) . map_err ( |_| {
487- syn:: Error :: new ( lit_int. span ( ) , "Discriminant index must be in the range 0..255" )
488- } )
489- } else {
490- Err ( syn:: Error :: new (
491- discriminant. span ( ) ,
492- "Discriminant must be an integer literal in the range 0..255" ,
493- ) )
494- }
495- }
496-
497475// Only `#[codec(dumb_trait_bound)]` is accepted as top attribute
498476fn check_top_attribute ( attr : & Attribute ) -> syn:: Result < ( ) > {
499477 let top_error = "Invalid attribute: only `#[codec(dumb_trait_bound)]`, \
0 commit comments