From 9dca26cf92b26ea878b142430d2309919a85aee6 Mon Sep 17 00:00:00 2001 From: Jakub Wieczorek Date: Sun, 1 Jun 2014 14:40:55 +0200 Subject: [PATCH] Add unreachability detection for missized patterns of fixed size vectors Fixed #13482 --- src/librustc/middle/typeck/check/_match.rs | 38 +++++++++++++++------- src/test/compile-fail/issue-13482.rs | 18 ++++++++++ 2 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 src/test/compile-fail/issue-13482.rs diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index edb77e04b30..9fa8d916e2a 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -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); } diff --git a/src/test/compile-fail/issue-13482.rs b/src/test/compile-fail/issue-13482.rs new file mode 100644 index 00000000000..2b769b9e499 --- /dev/null +++ b/src/test/compile-fail/issue-13482.rs @@ -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 or the MIT license +// , 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 `[, .. 2]` but found a fixed vector pattern of size 0 + [a,_] => Some(a) + }; +}