Skip to content

Commit

Permalink
Underline the correct alternative variant in case of error. (#98)
Browse files Browse the repository at this point in the history
Fix #97.

Small PR to underline the correct alternative variant when they are not written in order.
  • Loading branch information
GilShoshan94 authored Jan 16, 2023
1 parent ea9c4f0 commit 483e933
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#[derive(num_enum::TryFromPrimitive)]
#[repr(u8)]
enum Numbers {
Zero = 0,
#[num_enum(alternatives = [3,1,4])]
One = 1,
Two = 2,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
error: '1' in the alternative values is already attributed as the discriminant of this variant
--> tests/try_build/compile_fail/alternative_clashes_with_its_discriminant.rs:5:34
|
5 | #[num_enum(alternatives = [3,1,4])]
| ^
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#[derive(num_enum::TryFromPrimitive)]
#[repr(u8)]
enum Numbers {
Zero = 0,
#[num_enum(alternatives = [5,7,0,3])]
One = 1,
Two = 2,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
error: '0' in the alternative values is already attributed to a previous variant
--> tests/try_build/compile_fail/alternative_clashes_with_variant_out_of_order.rs:5:36
|
5 | #[num_enum(alternatives = [5,7,0,3])]
| ^
12 changes: 7 additions & 5 deletions num_enum_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ impl Parse for EnumInfo {
debug_assert_eq!(alternate_values.len(), raw_alternative_values.len());

if !alternate_values.is_empty() {
let mut sorted_alternate_int_values = alternate_values
let alternate_int_values = alternate_values
.into_iter()
.map(|v| {
match v {
Expand All @@ -480,13 +480,15 @@ impl Parse for EnumInfo {
}
})
.collect::<Result<Vec<i128>>>()?;
let mut sorted_alternate_int_values = alternate_int_values.clone();
sorted_alternate_int_values.sort_unstable();
let sorted_alternate_int_values = sorted_alternate_int_values;

// Check if the current discriminant is not in the alternative values.
if let DiscriminantValue::Literal(canonical_value_int) = discriminant_value {
if let Ok(index) =
sorted_alternate_int_values.binary_search(&canonical_value_int)
if let Some(index) = alternate_int_values
.iter()
.position(|&x| x == canonical_value_int)
{
die!(&raw_alternative_values[index] => format!("'{}' in the alternative values is already attributed as the discriminant of this variant", canonical_value_int));
}
Expand All @@ -503,9 +505,9 @@ impl Parse for EnumInfo {
// (discriminant_int_val_set is BTreeSet, and iter().next_back() is the is the maximum in the set.)
if let Some(last_upper_val) = discriminant_int_val_set.iter().next_back() {
if sorted_alternate_int_values.first().unwrap() <= last_upper_val {
for (i, val) in sorted_alternate_int_values.iter().enumerate() {
for (index, val) in alternate_int_values.iter().enumerate() {
if discriminant_int_val_set.contains(val) {
die!(&raw_alternative_values[i] => format!("'{}' in the alternative values is already attributed to a previous variant", val));
die!(&raw_alternative_values[index] => format!("'{}' in the alternative values is already attributed to a previous variant", val));
}
}
}
Expand Down

0 comments on commit 483e933

Please sign in to comment.