-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Incorrect "unreachable pattern" warning on nightly #79048
Comments
Segfault: fn parse_data(data: &[u8]) -> u32 {
match data {
b"" => 1,
}
}
fn main() {
let val = parse_data(b"oops");
println!("{}", val);
} |
cc @Nadrieril |
Fails to compile on both stable and beta:
|
I'm bisecting now. |
searched nightlies: from nightly-2020-10-10 to nightly-2020-11-13 bisected with cargo-bisect-rustc v0.6.0Host triple: x86_64-unknown-linux-gnu cargo bisect-rustc --end=2020-11-13 --test-dir=foo --prompt |
Might be #78072 ? |
I'm far from a |
Purely based of the description, #78072 seems like a likely culprit. CC @Nadrieril, would you be able to take a look? Edit: as mentioned by @alex, this change looks likely to be the cause https://github.com/rust-lang/rust/pull/78072/files#diff-6d8d99538aca600d633270051580c7a9e40b35824ea2863d9dda2c85a733b5d9L390 |
Assigning |
Ok, I can comfirm it looks like it's the |
I'm confused. The comment in
If that's the case then the |
Ok I know, the pattern gets assigned type
This in fact means an important assumption is broken in match checking: that at all points the scrutinee and all patterns have the same type, even when we've dug a bit into the patterns. Here the we have a |
So, I think there's nothing that can be done in fn parse_data(data: &[u8; 0]) -> u8 {
match data {
b"" => 1,
}
} And the following rejected: fn parse_data(data: &[u8]) -> u8 {
match data {
b"" => 1,
}
} Thus we need to know the type of |
Actually I want to blame typechecking here. If there is some magic hidden polymorphism where a pattern can have two different types, it would be cool if typeck could hide it from the rest of the compiler and assign a consistent type to things. But I have zero idea how to go about doing that. |
typeck has magic, I found it when I was doing the PR you linked. Looking for it right now. Will have a link in a second |
rust/compiler/rustc_typeck/src/check/pat.rs Lines 393 to 404 in 30e49a9
has seriously thrown me off before. I tried to figure out a general solution not specific to literals (so we could also allow this for constants), but all of this is extremely subtle. Maybe we can indeed make |
It shouldn't be the responsibility of |
So... typeck can't modify the type of |
Btw it's not just size 0, here's another fun one: fn parse_data(data: &[u8]) -> u8 {
match data {
b"aaa" => 1,
&[_, _, _] => 1,
}
} This is also detected exhaustive, and segfaults on |
yea, this is for all sizes, but only for byte string literals. Let's move this chat to zulip? https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/exhaustiveness.20is.20broken.20.2379048/near/216744730 |
I tried this code:
It produces the following, incorrect, warning:
however, the output is
2
so it's clearly incorrectMeta
rustc --version
:The text was updated successfully, but these errors were encountered: