Skip to content

Commit

Permalink
librustc_mir: Fix ICE with slice patterns
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dlrobertson committed Jan 13, 2019
1 parent 0c91f3d commit d6c1919
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/librustc_mir/hair/pattern/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1372,7 +1372,14 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>,
let is_visible = adt.is_enum()
|| field.vis.is_accessible_from(cx.module, cx.tcx);
if is_visible {
field.ty(cx.tcx, substs)
let ty = field.ty(cx.tcx, substs);
match ty.sty {
// If the field type returned is an array of an unknown
// size return an TyErr.
ty::Array(_, len) if len.assert_usize(cx.tcx).is_none() =>
cx.tcx.types.err,
_ => ty,
}
} else {
// Treat all non-visible fields as TyErr. They
// can't appear in any other pattern from
Expand Down
35 changes: 35 additions & 0 deletions src/test/ui/issues/issue-57472.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#![crate_type="lib"]
#![deny(unreachable_patterns)]

mod test_struct {
// Test the exact copy of the minimal example
// posted in the issue.
pub struct Punned {
foo: [u8; 1],
bar: [u8; 1],
}

pub fn test(punned: Punned) {
match punned {
Punned { foo: [_], .. } => println!("foo"),
Punned { bar: [_], .. } => println!("bar"),
//~^ ERROR unreachable pattern [unreachable_patterns]
}
}
}

mod test_union {
// Test the same thing using a union.
pub union Punned {
foo: [u8; 1],
bar: [u8; 1],
}

pub fn test(punned: Punned) {
match punned {
Punned { foo: [_] } => println!("foo"),
Punned { bar: [_] } => println!("bar"),
//~^ ERROR unreachable pattern [unreachable_patterns]
}
}
}
20 changes: 20 additions & 0 deletions src/test/ui/issues/issue-57472.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: unreachable pattern
--> $DIR/issue-57472.rs:15:13
|
LL | Punned { bar: [_], .. } => println!("bar"),
| ^^^^^^^^^^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/issue-57472.rs:2:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^

error: unreachable pattern
--> $DIR/issue-57472.rs:31:13
|
LL | Punned { bar: [_] } => println!("bar"),
| ^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

0 comments on commit d6c1919

Please sign in to comment.