@@ -45,7 +45,13 @@ pub fn const_eval_check_variant_indexes(
45
45
let mut recurse_indices = vec ! [ ] ;
46
46
for ( ident, index) in recurse_variant_indices {
47
47
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
+ } ) ;
49
55
}
50
56
let len = recurse_indices. len ( ) ;
51
57
@@ -55,11 +61,12 @@ pub fn const_eval_check_variant_indexes(
55
61
56
62
quote ! {
57
63
const _: ( ) = {
58
- const indices: [ ( usize , & ' static str ) ; #len] = [ #( #recurse_indices , ) * ] ;
64
+ #[ allow( clippy:: unnecessary_cast) ]
65
+ const indices: [ ( u8 , & ' static str ) ; #len] = [ #( #recurse_indices , ) * ] ;
59
66
60
67
// 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;
63
70
let mut i = 0 ;
64
71
while i < len {
65
72
let mut j = i + 1 ;
@@ -97,7 +104,7 @@ pub fn const_eval_check_variant_indexes(
97
104
/// is found, fall back to the discriminant or just the variant index.
98
105
pub fn variant_index ( v : & Variant , i : usize ) -> TokenStream {
99
106
// 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| {
101
108
if let Meta :: NameValue ( ref nv) = meta {
102
109
if nv. path . is_ident ( "index" ) {
103
110
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 {
112
119
None
113
120
} ) ;
114
121
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
+ } )
130
129
}
131
130
132
131
/// Look for a `#[codec(encoded_as = "SomeType")]` outer attribute on the given
@@ -394,12 +393,6 @@ pub fn check_attributes(input: &DeriveInput) -> syn::Result<()> {
394
393
check_field_attribute ( attr) ?;
395
394
}
396
395
}
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
- }
403
396
} ,
404
397
Data :: Union ( _) => ( ) ,
405
398
}
@@ -479,21 +472,6 @@ fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> {
479
472
}
480
473
}
481
474
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
-
497
475
// Only `#[codec(dumb_trait_bound)]` is accepted as top attribute
498
476
fn check_top_attribute ( attr : & Attribute ) -> syn:: Result < ( ) > {
499
477
let top_error = "Invalid attribute: only `#[codec(dumb_trait_bound)]`, \
0 commit comments