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.
This commit is contained in:
Dan Robertson 2019-01-13 14:23:32 +00:00
parent 0c91f3d97f
commit d6c19191b0
No known key found for this signature in database
GPG Key ID: 45C4A652C47E42A5
3 changed files with 63 additions and 1 deletions

View File

@ -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

View File

@ -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]
}
}
}

View File

@ -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