Skip to content

Commit b5dac2d

Browse files
committed
Fix ICE in pattern matching with generic const array length errors
1 parent 2f7620a commit b5dac2d

File tree

3 files changed

+73
-7
lines changed

3 files changed

+73
-7
lines changed

compiler/rustc_mir_build/src/builder/matches/match_pair.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4343
) {
4444
let tcx = self.tcx;
4545
let (min_length, exact_size) = if let Some(place_resolved) = place.try_to_place(self) {
46-
match place_resolved.ty(&self.local_decls, tcx).ty.kind() {
47-
ty::Array(_, length) => (
48-
length
49-
.try_to_target_usize(tcx)
50-
.expect("expected len of array pat to be definite"),
51-
true,
52-
),
46+
let place_ty = place_resolved.ty(&self.local_decls, tcx).ty;
47+
match place_ty.kind() {
48+
ty::Array(_, length) => {
49+
if let Some(length) = length.try_to_target_usize(tcx) {
50+
(length, true)
51+
} else {
52+
// This can happen when the array length is a generic const
53+
// expression that couldn't be evaluated (e.g., due to an error).
54+
// Since there's already a compilation error, we use a fallback
55+
// to avoid an ICE.
56+
tcx.dcx().span_delayed_bug(
57+
tcx.def_span(self.def_id),
58+
"array length in pattern couldn't be evaluated",
59+
);
60+
((prefix.len() + suffix.len()).try_into().unwrap(), false)
61+
}
62+
}
5363
_ => ((prefix.len() + suffix.len()).try_into().unwrap(), false),
5464
}
5565
} else {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ compile-flags: --crate-type=lib
2+
3+
#![feature(generic_const_exprs)]
4+
//~^ WARN the feature `generic_const_exprs` is incomplete
5+
6+
fn is_123<const N: usize>(
7+
x: [u32; {
8+
//~^ ERROR overly complex generic constant
9+
N + 1;
10+
5
11+
}],
12+
) -> bool {
13+
match x {
14+
[1, 2] => true,
15+
_ => false,
16+
}
17+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/generic-const-array-empty-pattern-ice-139815.rs:7:12
3+
|
4+
LL | #![feature(generic_const_exprs)]
5+
| ^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error: overly complex generic constant
11+
--> $DIR/generic-const-array-empty-pattern-ice-139815.rs:12:14
12+
|
13+
LL | x: [u32; {
14+
| ______________^
15+
LL | |
16+
LL | | N;
17+
LL | | 5
18+
LL | | }],
19+
| |_____^ blocks are not supported in generic constants
20+
|
21+
= help: consider moving this anonymous constant into a `const` function
22+
= note: this operation may be supported in the future
23+
24+
error: overly complex generic constant
25+
--> $DIR/generic-const-array-empty-pattern-ice-139815.rs:26:14
26+
|
27+
LL | x: [u32; {
28+
| ______________^
29+
LL | |
30+
LL | | N + 1;
31+
LL | | 5
32+
LL | | }],
33+
| |_____^ blocks are not supported in generic constants
34+
|
35+
= help: consider moving this anonymous constant into a `const` function
36+
= note: this operation may be supported in the future
37+
38+
error: aborting due to 2 previous errors; 1 warning emitted
39+

0 commit comments

Comments
 (0)