Skip to content

Improve diagnostics for duplicate enum discriminants #97533

Closed
@clarfonthey

Description

@clarfonthey

This is split out from the discussion in #97319.

First, the existing error for duplicate enum discriminants could be improved. The best summary of what we have now can be seen in the test added for #97319, which fixes part of it:

enum Enum {
    P = 3,
    X = 3,
    Y = 5
}

#[repr(u8)]
enum EnumOverflowRepr {
    P = 257,
    X = 513,
}

#[repr(i8)]
enum NegDisEnum {
    First = -1,
    Second = -2,
    Last,
}

Which outputs:

error[E0081]: discriminant value `3` assigned more than once
  --> $DIR/E0081.rs:1:1
   |
LL | / enum Enum {
LL | |
LL | |     P = 3,
   | |         - first assignment of `3`
LL | |
LL | |     X = 3,
   | |         - second assignment of `3`
LL | |
LL | |     Y = 5
LL | | }
   | |_^

error[E0081]: discriminant value `1` assigned more than once
  --> $DIR/E0081.rs:11:1
   |
LL | / enum EnumOverflowRepr {
LL | |
LL | |     P = 257,
   | |         --- first assignment of `1` (overflowed from `257`)
LL | |
LL | |     X = 513,
   | |         --- second assignment of `1` (overflowed from `513`)
LL | |
LL | | }
   | |_^

error[E0081]: discriminant value `-1` assigned more than once
  --> $DIR/E0081.rs:20:1
   |
LL | / enum NegDisEnum {
LL | |
LL | |     First = -1,
   | |             -- first assignment of `-1`
LL | |
LL | |     Second = -2,
   | |     ----------- assigned discriminant for `Last` was incremented from this discriminant
LL | |
LL | |     Last,
   | |     ---- second assignment of `-1`
LL | |
LL | | }
   | |_^

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0081`.

I suggested that the last version of the error should suggest explicitly stating that the discriminant for Last is computed as (Second = -2) + (1 variant later) = -1 = First, or somehow better wording that. Essentially, make it clear to the user that things are incremented positively, regardless of the order of existing discriminants.

Secondly, @Bryysen suggested that the code that does this (check_enum) could definitely use some additional refactoring as well in this comment.

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsD-papercutDiagnostics: An error or lint that needs small tweaks.D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.D-verboseDiagnostics: Too much output caused by a single piece of incorrect code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions