diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 1943d3de3ad7..c5fa8a5db031 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -1499,18 +1499,19 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L check_transparent(tcx, sp, def); } -/// Part of enum check, errors if two or more discriminants are equal +/// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal fn detect_discriminant_duplicate<'tcx>( tcx: TyCtxt<'tcx>, mut discrs: Vec<(VariantIdx, Discr<'tcx>)>, vs: &'tcx [hir::Variant<'tcx>], self_span: Span, ) { - // Helper closure to reduce duplicate code. This gets called everytime we detect a duplicate + // Helper closure to reduce duplicate code. This gets called everytime we detect a duplicate. + // Here `idx` refers to the order of which the discriminant appears, and its index in `vs` let report = |dis: Discr<'tcx>, idx: usize, err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>| { - let var = &vs[idx]; + let var = &vs[idx]; // HIR for the duplicate discriminant let (span, display_discr) = match var.disr_expr { Some(ref expr) => { // In the case the discriminant is both a duplicate and overflowed, let the user know @@ -1533,8 +1534,8 @@ fn detect_discriminant_duplicate<'tcx>( vs[..idx].iter().rev().enumerate().find(|v| v.1.disr_expr.is_some()) { let ve_ident = var.ident; - let sp = if n > 1 { "variants" } else { "variant" }; let n = n + 1; + let sp = if n > 1 { "variants" } else { "variant" }; err.span_label( *span, @@ -1549,7 +1550,7 @@ fn detect_discriminant_duplicate<'tcx>( err.span_label(span, format!("{display_discr} assigned here")); }; - // Here we are loop through the discriminants, comparing each discriminant to another. + // Here we loop through the discriminants, comparing each discriminant to another. // When a duplicate is detected, we instatiate an error and point to both // initial and duplicate value. The duplicate discriminant is then discarded by swapping // it with the last element and decrementing the `vec.len` (which is why we have to evaluate diff --git a/src/test/ui/error-codes/E0081.rs b/src/test/ui/error-codes/E0081.rs index 5e970a89307b..f53fda864d65 100644 --- a/src/test/ui/error-codes/E0081.rs +++ b/src/test/ui/error-codes/E0081.rs @@ -27,9 +27,9 @@ enum NegDisEnum { //~^ NOTE `-1` assigned here } -#[repr(i32)] enum MultipleDuplicates { //~^ ERROR discriminant value `0` assigned more than once + //~^^ ERROR discriminant value `-2` assigned more than once V0, //~^ NOTE `0` assigned here V1 = 0, @@ -39,10 +39,15 @@ enum MultipleDuplicates { V4 = 0, //~^ NOTE `0` assigned here V5 = -2, - //~^ NOTE discriminant for `V7` incremented from this startpoint (`V5` + 2 variant later => `V7` = 0) + //~^ NOTE discriminant for `V7` incremented from this startpoint (`V5` + 2 variants later => `V7` = 0) + //~^^ NOTE `-2` assigned here V6, V7, //~^ NOTE `0` assigned here + V8 = -3, + //~^ NOTE discriminant for `V9` incremented from this startpoint (`V8` + 1 variant later => `V9` = -2) + V9, + //~^ NOTE `-2` assigned here } fn main() { diff --git a/src/test/ui/error-codes/E0081.stderr b/src/test/ui/error-codes/E0081.stderr index d27861aca5fc..64562fefc866 100644 --- a/src/test/ui/error-codes/E0081.stderr +++ b/src/test/ui/error-codes/E0081.stderr @@ -38,11 +38,11 @@ LL | Last, | ---- `-1` assigned here error[E0081]: discriminant value `0` assigned more than once - --> $DIR/E0081.rs:31:1 + --> $DIR/E0081.rs:30:1 | LL | enum MultipleDuplicates { | ^^^^^^^^^^^^^^^^^^^^^^^ -LL | +... LL | V0, | -- `0` assigned here LL | @@ -53,11 +53,26 @@ LL | V4 = 0, | - `0` assigned here LL | LL | V5 = -2, - | ------- discriminant for `V7` incremented from this startpoint (`V5` + 2 variant later => `V7` = 0) + | ------- discriminant for `V7` incremented from this startpoint (`V5` + 2 variants later => `V7` = 0) ... LL | V7, | -- `0` assigned here -error: aborting due to 4 previous errors +error[E0081]: discriminant value `-2` assigned more than once + --> $DIR/E0081.rs:30:1 + | +LL | enum MultipleDuplicates { + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | V5 = -2, + | -- `-2` assigned here +... +LL | V8 = -3, + | ------- discriminant for `V9` incremented from this startpoint (`V8` + 1 variant later => `V9` = -2) +LL | +LL | V9, + | -- `-2` assigned here + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0081`. diff --git a/src/test/ui/tag-variant-disr-dup.rs b/src/test/ui/tag-variant-disr-dup.rs deleted file mode 100644 index e497f993da28..000000000000 --- a/src/test/ui/tag-variant-disr-dup.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Black and White have the same discriminator value ... - -enum Color { - //~^ ERROR discriminant value `0` assigned more than once - Red = 0xff0000, - Green = 0x00ff00, - Blue = 0x0000ff, - Black = 0x000000, - White = 0x000000, -} - -fn main() { } diff --git a/src/test/ui/tag-variant-disr-dup.stderr b/src/test/ui/tag-variant-disr-dup.stderr deleted file mode 100644 index 4932cde0b18f..000000000000 --- a/src/test/ui/tag-variant-disr-dup.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0081]: discriminant value `0` assigned more than once - --> $DIR/tag-variant-disr-dup.rs:3:1 - | -LL | enum Color { - | ^^^^^^^^^^ -... -LL | Black = 0x000000, - | -------- `0` assigned here -LL | White = 0x000000, - | -------- `0` assigned here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0081`.