-
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
ICE matching on a non-[u8] const array #66501
Comments
The feature gate isn't needed to trigger the ICE |
Oh, well spotted. And it appears that fails on stable too then |
cc @pnkfelix as it's possible this is related to your structural match work I guess? |
Funny enough: this doesn't ICE const CONST: [(); 1] = [()];
match &[()] {
&[()] => {}
&CONST => {}
} but instead shows the correct "unreachable" warning |
Reduced: fn main() {
const CONST: &[(); 0] = &[];
match &[] {
&[] => {}
CONST => {}
}
} |
What the heck?!? |
triage: P-high. Removing nomination. Self-assigning. |
That's a leftover from matching on byte strings, which used to be one of the few constants one could actually match on. |
I think it's one more of theses cases where we don't know how to handle |
I've figured out a way to eliminate the ICE, but I do not think my code has the desired semantics. That is, I would imagine we would want this to be accepted: const CONST: &[(); 1] = &[()];
fn main() {
match &[()] {
::CONST => {}
}
} but my current draft code rejects the above as non-exhaustive. On the other hand, that does match the current behavior of the compiler, for better or for worse. Update: Or maybe I've forgotten the desirata for how match usefulness and consts are supposed to interact...? |
This was not a stable reduction; on the current nightly, the above length-zero ZST array is accepted with no ICE, while the original length-one ZST array still causes an ICE. |
Yet another fun variation on the test: fn main() {
const CONST: &[Option<()>; 1] = &[Some(())];
match &[Some(())] {
&[None] => {}
CONST => {}
&[Some(())] => {}
}
} yields:
|
The reason it exists is that we don't want to unpack a multi megabyte byte string you may have gotten from The reason why I believe we should also do this optimization for other types is that you can easily transmute a multi megabyte byte string to another array type in a constant, and then you have the same problem all over again. (Or you init with a repeat expression). I agree that it would be nicer and less fragilr if we just unpacked everything. |
Btw, #67192 addresses a few of the ICEs around this |
Since #76376 the original and reduced versions no longer ICE, but fn main() {
const CONST: &[Option<()>; 1] = &[Some(())];
match &[Some(())] {
&[None] => {}
CONST => {}
&[Some(())] => {}
}
} still does |
The above no longer ICEs after #70743, could do with a test |
Add some regression tests Closes rust-lang#66501 Closes rust-lang#68951 Closes rust-lang#72565 Closes rust-lang#74244 Closes rust-lang#75299 The first issue is fixed in 1.43.0, other issues are fixed in the recent nightly.
This produces an ICE (playground link):
It points to this assert firing:
rust/src/librustc_mir/hair/pattern/_match.rs
Lines 1739 to 1745 in d801458
This assert assumes that if we match on a
&[T; n]
with a const, thenT
must beu8
. I'm not sure where this assumption comes from (I'd guess byte-array patterns), but it's clearly wrong. Note that this also fails with any other non-u8
type here instead of()
.Note that this does not fail when the arrays are not behind references, or if we use slices instead of arrays.
EDIT: removed unnecessary
slice_patterns
feature gateThe text was updated successfully, but these errors were encountered: