Add unreachability detection for missized patterns of fixed size vectors
Fixed #13482
This commit is contained in:
parent
1e68d57682
commit
9dca26cf92
2 changed files with 45 additions and 11 deletions
|
@ -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);
|
||||
}
|
||||
|
|
18
src/test/compile-fail/issue-13482.rs
Normal file
18
src/test/compile-fail/issue-13482.rs
Normal 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)
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue