-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Confusing error message on negative enum-discriminants #97319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Gave it some more thought, and I'm guessing |
So I got curious and decided to check out what causes this. Looking around a bit trying to find which part of type-checking had to do with enums led me to this function. At the end we there is a part where we go through all the discriminants and ensure none of them are duplicates, and if there are duplicates we emit the E0081 error pointing to the duplicates and all that. The code
However, the type of the
The type of the discriminant is understood to be i8, but the value is expressed as a u8. If I can find a nice solution to this i'll submit a PR. |
Honestly, I think this error could probably be reworded as well; since Of course, that doesn't have to be part of the first PR, but I figure it's worth mentioning here. |
Yeah that would improve the error quality in this case. I haven't checked if we can infer from context whether the discriminant has been explicitly assigned or not, but I assume we can, and in that case whenever we detect a duplicate we could add a small note saying that that the implicit discriminant is just a += 1 from the previous discriminant as you say. Doesn't hurt to do that for both positive and negative discriminant duplicates. Anyway I've got something in the works, I'll explore adding this note aswell as soon as I can get back to my computer with some spare time. @rustbot claim |
You should be able to assume that it's been previously assigned, since if every discriminant were inferred, there wouldn't be conflicts, unless the number of variants overflows the And I think a good example to test here would be: enum Sneaky {
Three = 3,
Two = 2,
One,
} Since the discriminant for |
Oh, I meant inferring if whether the duplicate discriminant was explicitly set or not. In the above example, that would be detecting if So here's what I currently have. An enum like this:
Errors as such:
Not sure about the note. We could split it out with its own span and point to which variant the duplicate increment ( Also I reworded some of the original error message, hopefully it's clearer this way? If not i can revert that. Edit: Sorry @clarfonthey i didn't read your comment properly 😃 . Yeah i guess we could iterate backwards until we hit the first defined discriminant, and point to that in the note. |
Yeah, in that case I'd say something like: discriminant is computed as (specified) + N variants later = (duplicate) |
Ok, I think I'll leave the notification for another PR 😞 . The reason is that in the duplicate-detection loop, we are only storing the As an example, for this enum:
In the loop, once we get to |
Yeah, I think it's totally reasonable to just fix the extremely obvious bug of reinterpreting the integer before tackling the larger issue of the message being weird to begin with. I mostly just wanted to add my thoughts here for a potential solution so anyone else looking to help with this has some ideas to work with. |
(Should I create a separate issue for my other suggestions, or would it make sense to reopen this issue until those errors are also fixed?) |
It would make sense to me to make a new issue specifically for the stuff we missed from this PR? There are probably good reasons to just go through the entire |
Alright, filed! Future discussion can go there. |
Given the following code:
Playground
The current output is:
Ideally the output should look like:
I don't have any understanding of the internal machinery of the diagnostics, but it seems that the value is being cast to the unsigned variant of the integer before displayed (in this case
i8
->u8
). Of course, the discriminant does its job just fine, and explicitly castingDisEnum
to ani8
also works as expected, only the diagnostics are a bit unfortunate.Changing
#[repr(i8)]
to#[repr(isize)]
in the example causes it to underflow close tousize::MAX
which may seem a little intimidating to a newer user who accidentally stumbles on this 😄The output is the same on both Stable and Nightly
The text was updated successfully, but these errors were encountered: