Add error for pattern-matching on arrays without a fixed size

This commit is contained in:
varkor 2019-05-31 22:27:26 +01:00
parent 21551359a5
commit 5a2410a07c
4 changed files with 85 additions and 18 deletions

View File

@ -400,27 +400,36 @@ pub fn check_pat_walk(
let expected_ty = self.structurally_resolved_type(pat.span, expected);
let (inner_ty, slice_ty) = match expected_ty.sty {
ty::Array(inner_ty, size) => {
let size = size.unwrap_usize(tcx);
let min_len = before.len() as u64 + after.len() as u64;
if slice.is_none() {
if min_len != size {
struct_span_err!(
tcx.sess, pat.span, E0527,
"pattern requires {} elements but array has {}",
min_len, size)
.span_label(pat.span, format!("expected {} elements", size))
if let Some(size) = size.assert_usize(tcx) {
let min_len = before.len() as u64 + after.len() as u64;
if slice.is_none() {
if min_len != size {
struct_span_err!(
tcx.sess, pat.span, E0527,
"pattern requires {} elements but array has {}",
min_len, size)
.span_label(pat.span, format!("expected {} elements", size))
.emit();
}
(inner_ty, tcx.types.err)
} else if let Some(rest) = size.checked_sub(min_len) {
(inner_ty, tcx.mk_array(inner_ty, rest))
} else {
struct_span_err!(tcx.sess, pat.span, E0528,
"pattern requires at least {} elements but array has {}",
min_len, size)
.span_label(pat.span,
format!("pattern cannot match array of {} elements", size))
.emit();
(inner_ty, tcx.types.err)
}
(inner_ty, tcx.types.err)
} else if let Some(rest) = size.checked_sub(min_len) {
(inner_ty, tcx.mk_array(inner_ty, rest))
} else {
struct_span_err!(tcx.sess, pat.span, E0528,
"pattern requires at least {} elements but array has {}",
min_len, size)
.span_label(pat.span,
format!("pattern cannot match array of {} elements", size))
.emit();
struct_span_err!(
tcx.sess,
pat.span,
E0730,
"cannot pattern-match on an array without a fixed length",
).emit();
(inner_ty, tcx.types.err)
}
}

View File

@ -4648,6 +4648,38 @@ fn make_recursive_type() -> impl Sized {
```
"##,
E0730: r##"
An array without a fixed length was pattern-matched.
Example of erroneous code:
```compile_fail,E0730
#![feature(const_generics)]
fn is_123<const N: usize>(x: [u32; N]) -> bool {
match x {
[1, 2, 3] => true, // error: cannot pattern-match on an
// array without a fixed length
_ => false
}
}
```
Ensure that the pattern is consistent with the size of the matched
array. Additional elements can be matched with `..`:
```
#![feature(slice_patterns)]
let r = &[1, 2, 3, 4];
match r {
&[a, b, ..] => { // ok!
println!("a={}, b={}", a, b);
}
}
```
"##,
}
register_diagnostics! {

View File

@ -0,0 +1,11 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
fn is_123<const N: usize>(x: [u32; N]) -> bool {
match x {
[1, 2, 3] => true, //~ ERROR cannot pattern-match on an array without a fixed length
_ => false
}
}
fn main() {}

View File

@ -0,0 +1,15 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/E0730.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
error[E0730]: cannot pattern-match on an array without a fixed length
--> $DIR/E0730.rs:6:9
|
LL | [1, 2, 3] => true,
| ^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0730`.