Skip to content

Commit 35af111

Browse files
authored
Rollup merge of #57538 - dlrobertson:fix_57472, r=zackmdavis
librustc_mir: Fix ICE with slice patterns If a match arm does not include all fields in a structure and a later pattern includes a field that is an array, we will attempt to use the array type from the prior arm. When calculating the field type, treat a array of an unknown size as a `TyErr`. Fixes: #57472
2 parents d7c1e0d + d6c1919 commit 35af111

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

src/librustc_mir/hair/pattern/_match.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1372,7 +1372,14 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>,
13721372
let is_visible = adt.is_enum()
13731373
|| field.vis.is_accessible_from(cx.module, cx.tcx);
13741374
if is_visible {
1375-
field.ty(cx.tcx, substs)
1375+
let ty = field.ty(cx.tcx, substs);
1376+
match ty.sty {
1377+
// If the field type returned is an array of an unknown
1378+
// size return an TyErr.
1379+
ty::Array(_, len) if len.assert_usize(cx.tcx).is_none() =>
1380+
cx.tcx.types.err,
1381+
_ => ty,
1382+
}
13761383
} else {
13771384
// Treat all non-visible fields as TyErr. They
13781385
// can't appear in any other pattern from

src/test/ui/issues/issue-57472.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#![crate_type="lib"]
2+
#![deny(unreachable_patterns)]
3+
4+
mod test_struct {
5+
// Test the exact copy of the minimal example
6+
// posted in the issue.
7+
pub struct Punned {
8+
foo: [u8; 1],
9+
bar: [u8; 1],
10+
}
11+
12+
pub fn test(punned: Punned) {
13+
match punned {
14+
Punned { foo: [_], .. } => println!("foo"),
15+
Punned { bar: [_], .. } => println!("bar"),
16+
//~^ ERROR unreachable pattern [unreachable_patterns]
17+
}
18+
}
19+
}
20+
21+
mod test_union {
22+
// Test the same thing using a union.
23+
pub union Punned {
24+
foo: [u8; 1],
25+
bar: [u8; 1],
26+
}
27+
28+
pub fn test(punned: Punned) {
29+
match punned {
30+
Punned { foo: [_] } => println!("foo"),
31+
Punned { bar: [_] } => println!("bar"),
32+
//~^ ERROR unreachable pattern [unreachable_patterns]
33+
}
34+
}
35+
}

src/test/ui/issues/issue-57472.stderr

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: unreachable pattern
2+
--> $DIR/issue-57472.rs:15:13
3+
|
4+
LL | Punned { bar: [_], .. } => println!("bar"),
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: lint level defined here
8+
--> $DIR/issue-57472.rs:2:9
9+
|
10+
LL | #![deny(unreachable_patterns)]
11+
| ^^^^^^^^^^^^^^^^^^^^
12+
13+
error: unreachable pattern
14+
--> $DIR/issue-57472.rs:31:13
15+
|
16+
LL | Punned { bar: [_] } => println!("bar"),
17+
| ^^^^^^^^^^^^^^^^^^^
18+
19+
error: aborting due to 2 previous errors
20+

0 commit comments

Comments
 (0)