Skip to content

Commit

Permalink
fix(#102): Fixed shift error on >64 bit enums (#103)
Browse files Browse the repository at this point in the history
Large enums realistically will never be naturally exhaustive due to their size. The shift is now done as a checked shift and when the shift fails it will default to not naturally exhaustive, requiring the default attribute, even if it were exhaustive. (I want to meet the person who manages to write down 2^64 enum values or more)
  • Loading branch information
mlgiraud committed Feb 16, 2023
1 parent 476ef4b commit d5a4caa
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
20 changes: 20 additions & 0 deletions num_enum/tests/from_primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,26 @@ mod core {}
mod num_enum {}
mod std {}

#[test]
fn has_from_primitive_number_u64() {
#[derive(Debug, Eq, PartialEq, FromPrimitive)]
#[repr(u64)]
enum Enum {
Zero = 0,
#[num_enum(default)]
NonZero = 1,
}

let zero = Enum::from_primitive(0_u64);
assert_eq!(zero, Enum::Zero);

let one = Enum::from_primitive(1_u64);
assert_eq!(one, Enum::NonZero);

let two = Enum::from_primitive(2_u64);
assert_eq!(two, Enum::NonZero);
}

#[test]
fn has_from_primitive_number() {
#[derive(Debug, Eq, PartialEq, FromPrimitive)]
Expand Down
5 changes: 3 additions & 2 deletions num_enum_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,9 @@ impl EnumInfo {
.strip_prefix('i')
.or_else(|| repr_str.strip_prefix('u'));
if let Some(suffix) = suffix {
if let Ok(bits) = suffix.parse::<u8>() {
return Ok(1 << bits == self.variants.len());
if let Ok(bits) = suffix.parse::<u32>() {
let variants = 1usize.checked_shl(bits);
return Ok(variants.map_or(false, |v| v == self.variants.len()));
}
}
}
Expand Down

0 comments on commit d5a4caa

Please sign in to comment.