-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
rustc fails to detect duplicate switch cases due to integer overflow #13727
Comments
Triage: still reproduces. |
Still happens. Interestingly, rustc then crashed (Windows, 32b, nightly 1576142 2015-03-01). |
Visiting for triage: this is still an issue |
…rflow' ICE Reference: rust-lang/rust#13727
…rflow' ICE Reference: rust-lang/rust#13727
Seems this is not due to overflow. I've triggered the bug with this code: |
Reduced: #[allow(dead_code)]
#[repr(u32)]
enum SomeEnum {
A = 0x0,
B = 0x0,
}
#[allow(dead_code)]
fn a(b: SomeEnum) {
match b {
SomeEnum::A => (),
SomeEnum::B => (),
}
}
fn main() {}
|
I can't reproduce this on nightly; the 256/512 testcase gives an "unreachable pattern" error, and the enum testcase gives "discriminant value |
I'll create regression tests for this. |
…hievink fix: add fallback case in generated `PartialEq` impl Partially fixes rust-lang#13727. When generating `PartialEq` implementations for enums, the original code can already generate the following fallback case: ```rs _ => std::mem::discriminant(self) == std::mem::discriminant(other), ``` However, it has been suppressed in the following example for no good reason: ```rs enum Either<T, U> { Left(T), Right(U), } impl<T, U> PartialEq for Either<T, U> { fn eq(&self, other: &Self) -> bool { match (self, other) { (Self::Left(l0), Self::Left(r0)) => l0 == r0, (Self::Right(l0), Self::Right(r0)) => l0 == r0, // _ => std::mem::discriminant(self) == std::mem::discriminant(other), // ^ this completes the match arms! } } } ``` This PR has removed that suppression logic. ~~Of course, the PR could have suppressed the fallback case generation for single-variant enums instead, but I believe that this case is quite rare and should be caught by `#[warn(unreachable_patterns)]` anyway.~~ After this fix, when the enum has >1 variants, the following fallback arm will be generated : * `_ => false,` if we've already gone through every case where the variants of `self` and `other` match; * The original one (as stated above) in other cases. --- Note: The code example is still wrong after the fix due to incorrect trait bounds.
…Veykril fix: add generic `TypeBoundList` in generated derivable impl Potentially fixes rust-lang#13727. Continuing with the work in rust-lang#13732, this fix tries to add correct type bounds in the generated `impl` block: ```diff enum Either<T, U> { Left(T), Right(U), } - impl<T, U> PartialEq for Either<T, U> { + impl<T: PartialEq, U: PartialEq> PartialEq for Either<T, U> { fn eq(&self, other: &Self) -> bool { match (self, other) { (Self::Left(l0), Self::Left(r0)) => l0 == r0, (Self::Right(l0), Self::Right(r0)) => l0 == r0, _ => false, } } } ```
A small app to demonstrate the problem:
Compilation fails in llvm:
Rustc should detect the double label due to overflow.
The text was updated successfully, but these errors were encountered: