Add unreachability detection for missized patterns of fixed size vectors

Fixed #13482
This commit is contained in:
Jakub Wieczorek 2014-06-01 14:40:55 +02:00
parent 1e68d57682
commit 9dca26cf92
2 changed files with 45 additions and 11 deletions

View file

@ -632,9 +632,9 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
fcx.infcx().next_region_var(
infer::PatternRegion(pat.span));
let check_err = || {
for elt in before.iter() {
check_pat(pcx, &**elt, ty::mk_err());
let check_err = |found: String| {
for &elt in before.iter() {
check_pat(pcx, &*elt, ty::mk_err());
}
for elt in slice.iter() {
check_pat(pcx, &**elt, ty::mk_err());
@ -653,15 +653,16 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
})
},
Some(expected),
"a vector pattern".to_string(),
found,
None);
fcx.write_error(pat.id);
};
let (elt_type, region_var, mutbl) = match *structure_of(fcx,
let (elt_type, region_var, mutbl, fixed) = match *structure_of(fcx,
pat.span,
expected) {
ty::ty_vec(mt, Some(_)) => (mt.ty, default_region_var, ast::MutImmutable),
ty::ty_vec(mt, Some(fixed)) =>
(mt.ty, default_region_var, ast::MutImmutable, Some(fixed)),
ty::ty_uniq(t) => match ty::get(t).sty {
ty::ty_vec(mt, None) => {
fcx.type_error_message(pat.span,
@ -671,25 +672,40 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
},
expected,
None);
(mt.ty, default_region_var, ast::MutImmutable)
(mt.ty, default_region_var, ast::MutImmutable, None)
}
_ => {
check_err();
check_err("a vector pattern".to_string());
return;
}
},
ty::ty_rptr(r, mt) => match ty::get(mt.ty).sty {
ty::ty_vec(mt, None) => (mt.ty, r, mt.mutbl),
ty::ty_vec(mt, None) => (mt.ty, r, mt.mutbl, None),
_ => {
check_err();
check_err("a vector pattern".to_string());
return;
}
},
_ => {
check_err();
check_err("a vector pattern".to_string());
return;
}
};
let min_len = before.len() + after.len();
fixed.and_then(|count| match slice {
Some(_) if count < min_len =>
Some(format!("a fixed vector pattern of size at least {}", min_len)),
None if count != min_len =>
Some(format!("a fixed vector pattern of size {}", min_len)),
_ => None
}).and_then(|message| {
check_err(message);
Some(())
});
for elt in before.iter() {
check_pat(pcx, &**elt, elt_type);
}

View file

@ -0,0 +1,18 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {
let x = [1,2];
let y = match x {
[] => None,
//~^ ERROR expected `[<generic integer #1>, .. 2]` but found a fixed vector pattern of size 0
[a,_] => Some(a)
};
}