From 9519c00a196490ef1dcb0a97772ccfc41fb8a7ca Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Wed, 9 Mar 2016 23:29:06 +0200 Subject: [PATCH] disable multiple-match slice patterns Like [a, ..b]. These are typed in a very odd way, which causes some issues for MIR translation. Slice patterns with ignore patterns, e.g. [a, .., b], are allowed (but still gated under `advanced_slice_patterns`). --- src/librustc/mir/repr.rs | 14 ----- src/librustc/mir/tcx.rs | 1 - src/librustc/mir/visit.rs | 9 --- src/librustc_mir/build/matches/simplify.rs | 18 +++--- src/librustc_mir/build/matches/util.rs | 54 ++-------------- src/librustc_mir/transform/erase_regions.rs | 1 - src/librustc_trans/trans/mir/rvalue.rs | 21 ------- src/librustc_typeck/check/_match.rs | 5 ++ .../borrowck/borrowck-move-out-of-vec-tail.rs | 8 +-- .../borrowck-vec-pattern-element-loan.rs | 12 ++-- .../borrowck-vec-pattern-loan-from-mut.rs | 4 +- .../borrowck-vec-pattern-move-tail.rs | 3 +- .../borrowck/borrowck-vec-pattern-nesting.rs | 32 +++++----- .../borrowck-vec-pattern-tail-element-loan.rs | 3 +- .../feature-gate-slice-patterns.rs | 2 +- src/test/compile-fail/issue-12369.rs | 4 +- src/test/compile-fail/issue-12567.rs | 12 ++-- .../{run-pass => compile-fail}/issue-15080.rs | 6 +- .../{run-pass => compile-fail}/issue-15104.rs | 3 + .../{run-pass => compile-fail}/issue-7784.rs | 2 +- src/test/compile-fail/match-vec-mismatch.rs | 2 +- .../compile-fail/match-vec-unreachable.rs | 7 ++- .../non-exhaustive-match-slice-patterns.rs | 63 +++++++++++++++++++ src/test/compile-fail/non-exhaustive-match.rs | 22 ------- .../non-exhaustive-pattern-witness.rs | 14 ----- .../vec-matching-fold.rs | 4 +- .../vec-matching-legal-tail-element-borrow.rs | 1 + .../vec-matching.rs | 8 ++- .../vec-tail-matching.rs | 1 + .../zero_sized_subslice_match.rs | 1 + 30 files changed, 153 insertions(+), 184 deletions(-) rename src/test/{run-pass => compile-fail}/issue-15080.rs (80%) rename src/test/{run-pass => compile-fail}/issue-15104.rs (87%) rename src/test/{run-pass => compile-fail}/issue-7784.rs (94%) create mode 100644 src/test/compile-fail/non-exhaustive-match-slice-patterns.rs rename src/test/{run-pass => compile-fail}/vec-matching-fold.rs (90%) rename src/test/{run-pass => compile-fail}/vec-matching-legal-tail-element-borrow.rs (93%) rename src/test/{run-pass => compile-fail}/vec-matching.rs (87%) rename src/test/{run-pass => compile-fail}/vec-tail-matching.rs (95%) rename src/test/{run-pass => compile-fail}/zero_sized_subslice_match.rs (93%) diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index ce7b1ceb35540..4cf6a29116317 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -663,17 +663,6 @@ pub enum Rvalue<'tcx> { /// away after type-checking and before lowering. Aggregate(AggregateKind<'tcx>, Vec>), - /// Generates a slice of the form `&input[from_start..L-from_end]` - /// where `L` is the length of the slice. This is only created by - /// slice pattern matching, so e.g. a pattern of the form `[x, y, - /// .., z]` might create a slice with `from_start=2` and - /// `from_end=1`. - Slice { - input: Lvalue<'tcx>, - from_start: usize, - from_end: usize, - }, - InlineAsm(InlineAsm), } @@ -760,9 +749,6 @@ impl<'tcx> Debug for Rvalue<'tcx> { UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a), Box(ref t) => write!(fmt, "Box({:?})", t), InlineAsm(ref asm) => write!(fmt, "InlineAsm({:?})", asm), - Slice { ref input, from_start, from_end } => - write!(fmt, "{:?}[{:?}..-{:?}]", input, from_start, from_end), - Ref(_, borrow_kind, ref lv) => { let kind_str = match borrow_kind { BorrowKind::Shared => "", diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 26f6db4aa4fc1..0d9d00a3b9c16 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -198,7 +198,6 @@ impl<'tcx> Mir<'tcx> { } } } - Rvalue::Slice { .. } => None, Rvalue::InlineAsm(..) => None } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 5e3c6e028a325..d71bc2e4e47db 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -252,15 +252,6 @@ macro_rules! make_mir_visitor { } } - Rvalue::Slice { ref $($mutability)* input, - from_start, - from_end } => { - self.visit_lvalue(input, LvalueContext::Slice { - from_start: from_start, - from_end: from_end, - }); - } - Rvalue::InlineAsm(_) => { } } diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index 2c8e1c1ccf673..9cbff508215a8 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -61,7 +61,7 @@ impl<'a,'tcx> Builder<'a,'tcx> { /// possible, Err is returned and no changes are made to /// candidate. fn simplify_match_pair<'pat>(&mut self, - mut block: BasicBlock, + block: BasicBlock, match_pair: MatchPair<'pat, 'tcx>, candidate: &mut Candidate<'pat, 'tcx>) -> Result> { @@ -96,12 +96,16 @@ impl<'a,'tcx> Builder<'a,'tcx> { } PatternKind::Array { ref prefix, ref slice, ref suffix } => { - unpack!(block = self.prefix_suffix_slice(&mut candidate.match_pairs, - block, - match_pair.lvalue.clone(), - prefix, - slice.as_ref(), - suffix)); + if let Some(ref slice) = *slice { + match *slice.kind { + PatternKind::Wild => {}, + _ => panic!("bad slice pattern {:?}", slice) + } + } + self.prefix_suffix(&mut candidate.match_pairs, + match_pair.lvalue.clone(), + prefix, + suffix); Ok(block) } diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir/build/matches/util.rs index c295ed168badb..c4b963d977644 100644 --- a/src/librustc_mir/build/matches/util.rs +++ b/src/librustc_mir/build/matches/util.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use build::{BlockAnd, BlockAndExtension, Builder}; +use build::Builder; use build::matches::MatchPair; use hair::*; use rustc::mir::repr::*; @@ -28,54 +28,12 @@ impl<'a,'tcx> Builder<'a,'tcx> { .collect() } - /// When processing an array/slice pattern like `lv @ [x, y, ..s, z]`, - /// this function converts the prefix (`x`, `y`) and suffix (`z`) into - /// distinct match pairs: - /// - /// lv[0 of 3] @ x // see ProjectionElem::ConstantIndex (and its Debug impl) - /// lv[1 of 3] @ y // to explain the `[x of y]` notation - /// lv[-1 of 3] @ z - /// - /// If a slice like `s` is present, then the function also creates - /// a temporary like: - /// - /// tmp0 = lv[2..-1] // using the special Rvalue::Slice - /// - /// and creates a match pair `tmp0 @ s` - pub fn prefix_suffix_slice<'pat>(&mut self, - match_pairs: &mut Vec>, - block: BasicBlock, - lvalue: Lvalue<'tcx>, - prefix: &'pat [Pattern<'tcx>], - opt_slice: Option<&'pat Pattern<'tcx>>, - suffix: &'pat [Pattern<'tcx>]) - -> BlockAnd<()> { - // If there is a `..P` pattern, create a temporary `t0` for - // the slice and then a match pair `t0 @ P`: - if let Some(slice) = opt_slice { - let prefix_len = prefix.len(); - let suffix_len = suffix.len(); - let rvalue = Rvalue::Slice { - input: lvalue.clone(), - from_start: prefix_len, - from_end: suffix_len, - }; - let temp = self.temp(slice.ty.clone()); // no need to schedule drop, temp is always copy - self.cfg.push_assign(block, slice.span, &temp, rvalue); - match_pairs.push(MatchPair::new(temp, slice)); - } - - self.prefix_suffix(match_pairs, lvalue, prefix, suffix); - - block.unit() - } - /// Helper for `prefix_suffix_slice` which just processes the prefix and suffix. - fn prefix_suffix<'pat>(&mut self, - match_pairs: &mut Vec>, - lvalue: Lvalue<'tcx>, - prefix: &'pat [Pattern<'tcx>], - suffix: &'pat [Pattern<'tcx>]) { + pub fn prefix_suffix<'pat>(&mut self, + match_pairs: &mut Vec>, + lvalue: Lvalue<'tcx>, + prefix: &'pat [Pattern<'tcx>], + suffix: &'pat [Pattern<'tcx>]) { let min_length = prefix.len() + suffix.len(); assert!(min_length < u32::MAX as usize); let min_length = min_length as u32; diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index 53d88709add9d..3392cd8dd236a 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -86,7 +86,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> { Rvalue::Len(_) | Rvalue::BinaryOp(_, _, _) | Rvalue::UnaryOp(_, _) | - Rvalue::Slice { input: _, from_start: _, from_end: _ } | Rvalue::InlineAsm(_) => {}, Rvalue::Repeat(_, ref mut value) => value.ty = self.tcx.erase_regions(&value.ty), diff --git a/src/librustc_trans/trans/mir/rvalue.rs b/src/librustc_trans/trans/mir/rvalue.rs index 541df43b49b9a..34e50715518a0 100644 --- a/src/librustc_trans/trans/mir/rvalue.rs +++ b/src/librustc_trans/trans/mir/rvalue.rs @@ -145,25 +145,6 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { bcx } - mir::Rvalue::Slice { ref input, from_start, from_end } => { - let ccx = bcx.ccx(); - let input = self.trans_lvalue(&bcx, input); - let (llbase, lllen) = bcx.with_block(|bcx| { - tvec::get_base_and_len(bcx, - input.llval, - input.ty.to_ty(bcx.tcx())) - }); - let llbase1 = bcx.gepi(llbase, &[from_start]); - let adj = common::C_uint(ccx, from_start + from_end); - let lllen1 = bcx.sub(lllen, adj); - let (lladdrdest, llmetadest) = bcx.with_block(|bcx| { - (expr::get_dataptr(bcx, dest.llval), expr::get_meta(bcx, dest.llval)) - }); - bcx.store(llbase1, lladdrdest); - bcx.store(lllen1, llmetadest); - bcx - } - mir::Rvalue::InlineAsm(ref inline_asm) => { bcx.map_block(|bcx| { asm::trans_inline_asm(bcx, inline_asm) @@ -432,7 +413,6 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { mir::Rvalue::Use(..) | mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) | - mir::Rvalue::Slice { .. } | mir::Rvalue::InlineAsm(..) => { bcx.tcx().sess.bug(&format!("cannot generate operand from rvalue {:?}", rvalue)); } @@ -557,7 +537,6 @@ pub fn rvalue_creates_operand<'tcx>(rvalue: &mir::Rvalue<'tcx>) -> bool { mir::Rvalue::Use(..) | // (**) mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) | - mir::Rvalue::Slice { .. } | mir::Rvalue::InlineAsm(..) => false, } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 548f5ee5e949d..9054d882b6c5e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -335,6 +335,11 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, check_pat(pcx, &elt, inner_ty); } if let Some(ref slice) = *slice { + if slice.node != PatKind::Wild { + tcx.sess.span_err(slice.span, + "multi-element slice patterns are badly broken"); + } + let region = fcx.infcx().next_region_var(infer::PatternRegion(pat.span)); let mutbl = expected_ty.builtin_deref(true, ty::NoPreference) .map_or(hir::MutImmutable, |mt| mt.mutbl); diff --git a/src/test/compile-fail/borrowck/borrowck-move-out-of-vec-tail.rs b/src/test/compile-fail/borrowck/borrowck-move-out-of-vec-tail.rs index d9a2f89a9e21e..257927a58a1c5 100644 --- a/src/test/compile-fail/borrowck/borrowck-move-out-of-vec-tail.rs +++ b/src/test/compile-fail/borrowck/borrowck-move-out-of-vec-tail.rs @@ -25,12 +25,12 @@ pub fn main() { ); let x: &[Foo] = &x; match x { - [_, tail..] => { + [_, tail..] => { //~ ERROR slice patterns are badly broken match tail { - [Foo { string: a }, //~ ERROR cannot move out of borrowed content + [Foo { string: a }, //# ERROR cannot move out of borrowed content Foo { string: b }] => { - //~^^ NOTE attempting to move value to here - //~^^ NOTE and here + //#^^ NOTE attempting to move value to here + //#^^ NOTE and here } _ => { unreachable!(); diff --git a/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs b/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs index 98052ad31a7ef..6673b67dd4483 100644 --- a/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs +++ b/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs @@ -13,9 +13,9 @@ fn a<'a>() -> &'a [isize] { let vec = vec!(1, 2, 3, 4); - let vec: &[isize] = &vec; //~ ERROR does not live long enough + let vec: &[isize] = &vec; //# ERROR does not live long enough let tail = match vec { - [_, tail..] => tail, + [_, tail..] => tail, //~ ERROR slice patterns are badly broken _ => panic!("a") }; tail @@ -23,9 +23,9 @@ fn a<'a>() -> &'a [isize] { fn b<'a>() -> &'a [isize] { let vec = vec!(1, 2, 3, 4); - let vec: &[isize] = &vec; //~ ERROR does not live long enough + let vec: &[isize] = &vec; //# ERROR does not live long enough let init = match vec { - [init.., _] => init, + [init.., _] => init, //~ ERROR slice patterns are badly broken _ => panic!("b") }; init @@ -33,9 +33,9 @@ fn b<'a>() -> &'a [isize] { fn c<'a>() -> &'a [isize] { let vec = vec!(1, 2, 3, 4); - let vec: &[isize] = &vec; //~ ERROR does not live long enough + let vec: &[isize] = &vec; //# ERROR does not live long enough let slice = match vec { - [_, slice.., _] => slice, + [_, slice.., _] => slice, //~ ERROR slice patterns are badly broken _ => panic!("c") }; slice diff --git a/src/test/compile-fail/borrowck/borrowck-vec-pattern-loan-from-mut.rs b/src/test/compile-fail/borrowck/borrowck-vec-pattern-loan-from-mut.rs index db635893c81b9..1d26f491d2ff7 100644 --- a/src/test/compile-fail/borrowck/borrowck-vec-pattern-loan-from-mut.rs +++ b/src/test/compile-fail/borrowck/borrowck-vec-pattern-loan-from-mut.rs @@ -14,8 +14,8 @@ fn a() { let mut v = vec!(1, 2, 3); let vb: &mut [isize] = &mut v; match vb { - [_a, tail..] => { - v.push(tail[0] + tail[1]); //~ ERROR cannot borrow + [_a, tail..] => { //~ ERROR slice patterns are badly broken + v.push(tail[0] + tail[1]); //# ERROR cannot borrow } _ => {} }; diff --git a/src/test/compile-fail/borrowck/borrowck-vec-pattern-move-tail.rs b/src/test/compile-fail/borrowck/borrowck-vec-pattern-move-tail.rs index 97dcaeb0bf1a3..b4988068cfe0f 100644 --- a/src/test/compile-fail/borrowck/borrowck-vec-pattern-move-tail.rs +++ b/src/test/compile-fail/borrowck/borrowck-vec-pattern-move-tail.rs @@ -14,10 +14,11 @@ fn main() { let mut a = [1, 2, 3, 4]; let t = match a { [1, 2, tail..] => tail, + //~^ ERROR slice patterns are badly broken _ => unreachable!() }; println!("t[0]: {}", t[0]); - a[2] = 0; //~ ERROR cannot assign to `a[..]` because it is borrowed + a[2] = 0; //# ERROR cannot assign to `a[..]` because it is borrowed println!("t[0]: {}", t[0]); t[0]; } diff --git a/src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs index a69ce0cb365c7..e4c1ea075a708 100644 --- a/src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs +++ b/src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs @@ -17,7 +17,7 @@ fn a() { let mut vec = [box 1, box 2, box 3]; match vec { [box ref _a, _, _] => { - vec[0] = box 4; //~ ERROR cannot assign + vec[0] = box 4; //# ERROR cannot assign } } } @@ -26,8 +26,8 @@ fn b() { let mut vec = vec!(box 1, box 2, box 3); let vec: &mut [Box] = &mut vec; match vec { - [_b..] => { - vec[0] = box 4; //~ ERROR cannot assign + [_b..] => { //~ ERROR slice patterns are badly broken + vec[0] = box 4; //# ERROR cannot assign } } } @@ -36,8 +36,9 @@ fn c() { let mut vec = vec!(box 1, box 2, box 3); let vec: &mut [Box] = &mut vec; match vec { - [_a, //~ ERROR cannot move out - _b..] => { //~^ NOTE attempting to move value to here + [_a, //# ERROR cannot move out + _b..] => { //#^ NOTE attempting to move value to here + //~^ ERROR slice patterns are badly broken // Note: `_a` is *moved* here, but `b` is borrowing, // hence illegal. @@ -47,32 +48,33 @@ fn c() { } _ => {} } - let a = vec[0]; //~ ERROR cannot move out + let a = vec[0]; //# ERROR cannot move out } fn d() { let mut vec = vec!(box 1, box 2, box 3); let vec: &mut [Box] = &mut vec; match vec { - [_a.., //~ ERROR cannot move out - _b] => {} //~ NOTE attempting to move value to here + [_a.., //# ERROR cannot move out + _b] => {} //# NOTE attempting to move value to here + //~^^ ERROR slice patterns are badly broken _ => {} } - let a = vec[0]; //~ ERROR cannot move out + let a = vec[0]; //# ERROR cannot move out } fn e() { let mut vec = vec!(box 1, box 2, box 3); let vec: &mut [Box] = &mut vec; match vec { - [_a, _b, _c] => {} //~ ERROR cannot move out - //~^ NOTE attempting to move value to here - //~^^ NOTE and here - //~^^^ NOTE and here + [_a, _b, _c] => {} //# ERROR cannot move out + //#^ NOTE attempting to move value to here + //#^^ NOTE and here + //#^^^ NOTE and here _ => {} } - let a = vec[0]; //~ ERROR cannot move out - //~^ NOTE attempting to move value to here + let a = vec[0]; //# ERROR cannot move out + //#^ NOTE attempting to move value to here } fn main() {} diff --git a/src/test/compile-fail/borrowck/borrowck-vec-pattern-tail-element-loan.rs b/src/test/compile-fail/borrowck/borrowck-vec-pattern-tail-element-loan.rs index 82b3490d7d7e1..19afb54c93436 100644 --- a/src/test/compile-fail/borrowck/borrowck-vec-pattern-tail-element-loan.rs +++ b/src/test/compile-fail/borrowck/borrowck-vec-pattern-tail-element-loan.rs @@ -12,9 +12,10 @@ fn a<'a>() -> &'a isize { let vec = vec!(1, 2, 3, 4); - let vec: &[isize] = &vec; //~ ERROR `vec` does not live long enough + let vec: &[isize] = &vec; //# ERROR `vec` does not live long enough let tail = match vec { [_a, tail..] => &tail[0], + //~^ ERROR slice patterns are badly broken _ => panic!("foo") }; tail diff --git a/src/test/compile-fail/feature-gate-slice-patterns.rs b/src/test/compile-fail/feature-gate-slice-patterns.rs index 625cb2d351553..92b7ffd00c40c 100644 --- a/src/test/compile-fail/feature-gate-slice-patterns.rs +++ b/src/test/compile-fail/feature-gate-slice-patterns.rs @@ -13,6 +13,6 @@ fn main() { let x = [1, 2, 3, 4, 5]; match x { - [1, 2, xs..] => {} //~ ERROR slice pattern syntax is experimental + [1, 2, 3, 4, xs] => {} //~ ERROR slice pattern syntax is experimental } } diff --git a/src/test/compile-fail/issue-12369.rs b/src/test/compile-fail/issue-12369.rs index 1333bfac64ee8..4f8877ab7ee6d 100644 --- a/src/test/compile-fail/issue-12369.rs +++ b/src/test/compile-fail/issue-12369.rs @@ -16,6 +16,8 @@ fn main() { [] => 0, [a,b,c] => 3, [a, rest..] => a, - [10,a, rest..] => 10 //~ ERROR: unreachable pattern + //~^ ERROR slice patterns are badly broken + [10,a, rest..] => 10 //# ERROR: unreachable pattern + //~^ ERROR slice patterns are badly broken }; } diff --git a/src/test/compile-fail/issue-12567.rs b/src/test/compile-fail/issue-12567.rs index 1580ec00f94b0..e9547fc4b283a 100644 --- a/src/test/compile-fail/issue-12567.rs +++ b/src/test/compile-fail/issue-12567.rs @@ -14,11 +14,15 @@ fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) { match (l1, l2) { ([], []) => println!("both empty"), ([], [hd, tl..]) | ([hd, tl..], []) => println!("one empty"), - //~^ ERROR: cannot move out of borrowed content - //~^^ ERROR: cannot move out of borrowed content + //~^ ERROR slice patterns are badly broken + //~^^ ERROR slice patterns are badly broken + //#^ ERROR: cannot move out of borrowed content + //#^^ ERROR: cannot move out of borrowed content ([hd1, tl1..], [hd2, tl2..]) => println!("both nonempty"), - //~^ ERROR: cannot move out of borrowed content - //~^^ ERROR: cannot move out of borrowed content + //~^ ERROR slice patterns are badly broken + //~^^ ERROR slice patterns are badly broken + //#^ ERROR: cannot move out of borrowed content + //#^^ ERROR: cannot move out of borrowed content } } diff --git a/src/test/run-pass/issue-15080.rs b/src/test/compile-fail/issue-15080.rs similarity index 80% rename from src/test/run-pass/issue-15080.rs rename to src/test/compile-fail/issue-15080.rs index 7b00ea4a520cd..25226596396d7 100644 --- a/src/test/run-pass/issue-15080.rs +++ b/src/test/compile-fail/issue-15080.rs @@ -11,17 +11,19 @@ #![feature(slice_patterns)] +// move this to run-pass when slice-patterns work + fn main() { let mut x: &[_] = &[1, 2, 3, 4]; let mut result = vec!(); loop { x = match x { - [1, n, 3, rest..] => { + [1, n, 3, rest..] => { //~ ERROR slice patterns are badly broken result.push(n); rest } - [n, rest..] => { + [n, rest..] => { //~ ERROR slice patterns are badly broken result.push(n); rest } diff --git a/src/test/run-pass/issue-15104.rs b/src/test/compile-fail/issue-15104.rs similarity index 87% rename from src/test/run-pass/issue-15104.rs rename to src/test/compile-fail/issue-15104.rs index b55754ee59b35..aa69cc1ff5af7 100644 --- a/src/test/run-pass/issue-15104.rs +++ b/src/test/compile-fail/issue-15104.rs @@ -11,6 +11,8 @@ #![feature(slice_patterns)] +// move this to run-pass when slice-patterns work + fn main() { assert_eq!(count_members(&[1, 2, 3, 4]), 4); } @@ -20,5 +22,6 @@ fn count_members(v: &[usize]) -> usize { [] => 0, [_] => 1, [_x, xs..] => 1 + count_members(xs) + //~^ ERROR slice patterns are badly broken } } diff --git a/src/test/run-pass/issue-7784.rs b/src/test/compile-fail/issue-7784.rs similarity index 94% rename from src/test/run-pass/issue-7784.rs rename to src/test/compile-fail/issue-7784.rs index badc013cd621f..4aeac3a97fed5 100644 --- a/src/test/run-pass/issue-7784.rs +++ b/src/test/compile-fail/issue-7784.rs @@ -35,7 +35,7 @@ fn main() { assert_eq!(d, "baz"); let out = bar("baz", "foo"); - let [a, xs.., d] = out; + let [a, xs.., d] = out; //~ ERROR slice patterns are badly broken assert_eq!(a, "baz"); assert_eq!(xs, ["foo", "foo"]); assert_eq!(d, "baz"); diff --git a/src/test/compile-fail/match-vec-mismatch.rs b/src/test/compile-fail/match-vec-mismatch.rs index ef75213d34b85..46940652ef898 100644 --- a/src/test/compile-fail/match-vec-mismatch.rs +++ b/src/test/compile-fail/match-vec-mismatch.rs @@ -11,7 +11,7 @@ #![feature(slice_patterns)] fn main() { - match "foo".to_string() { + match "foo" { ['f', 'o', ..] => {} //~ ERROR mismatched types _ => { } } diff --git a/src/test/compile-fail/match-vec-unreachable.rs b/src/test/compile-fail/match-vec-unreachable.rs index 48b70b4bda08e..7a3e90ab94a69 100644 --- a/src/test/compile-fail/match-vec-unreachable.rs +++ b/src/test/compile-fail/match-vec-unreachable.rs @@ -15,7 +15,7 @@ fn main() { let x: &[(isize, isize)] = &x; match x { [a, (2, 3), _] => (), - [(1, 2), (2, 3), b] => (), //~ ERROR unreachable pattern + [(1, 2), (2, 3), b] => (), //# ERROR unreachable pattern _ => () } @@ -25,7 +25,7 @@ fn main() { let x: &[String] = &x; match x { [a, _, _, ..] => { println!("{}", a); } - [_, _, _, _, _] => { } //~ ERROR unreachable pattern + [_, _, _, _, _] => { } //# ERROR unreachable pattern _ => { } } @@ -33,7 +33,8 @@ fn main() { let x: &[char] = &x; match x { ['a', 'b', 'c', _tail..] => {} - ['a', 'b', 'c'] => {} //~ ERROR unreachable pattern + //~^ ERROR slice patterns are badly broken + ['a', 'b', 'c'] => {} //# ERROR unreachable pattern _ => {} } } diff --git a/src/test/compile-fail/non-exhaustive-match-slice-patterns.rs b/src/test/compile-fail/non-exhaustive-match-slice-patterns.rs new file mode 100644 index 0000000000000..fc2438295a2f7 --- /dev/null +++ b/src/test/compile-fail/non-exhaustive-match-slice-patterns.rs @@ -0,0 +1,63 @@ +// Copyright 2012-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. + +#![feature(slice_patterns)] +#![feature(advanced_slice_patterns)] + +enum Enum { First, Second(bool) } + +fn vectors_with_nested_enums() { + let x: &'static [Enum] = &[Enum::First, Enum::Second(false)]; + match x { + //#^ ERROR non-exhaustive patterns: `[Second(true), Second(false)]` not covered + [] => (), + [_] => (), + [Enum::First, _] => (), + [Enum::Second(true), Enum::First] => (), + [Enum::Second(true), Enum::Second(true)] => (), + [Enum::Second(false), _] => (), + [_, _, tail.., _] => () + //~^ ERROR slice patterns are badly broken + } +} + +fn main() { + let vec = vec!(Some(42), None, Some(21)); + match &*vec { //# ERROR non-exhaustive patterns: `[]` not covered + [Some(..), None, tail..] => {} + //~^ ERROR slice patterns are badly broken + [Some(..), Some(..), tail..] => {} + //~^ ERROR slice patterns are badly broken + [None] => {} + } + + let vec = vec!(Some(42), None, Some(21)); + let vec: &[Option] = &vec; + match vec { + [Some(..), None, tail..] => {} + //~^ ERROR slice patterns are badly broken + [Some(..), Some(..), tail..] => {} + //~^ ERROR slice patterns are badly broken + [None, None, tail..] => {} + //~^ ERROR slice patterns are badly broken + [None, Some(..), tail..] => {} + //~^ ERROR slice patterns are badly broken + [Some(_)] => {} + [None] => {} + [] => {} + } + let vec = vec!(1); + let vec: &[isize] = &vec; + match vec { + [_, tail..] => (), + //~^ ERROR slice patterns are badly broken + [] => () + } +} diff --git a/src/test/compile-fail/non-exhaustive-match.rs b/src/test/compile-fail/non-exhaustive-match.rs index b9749c2696e32..01d73e6c52c04 100644 --- a/src/test/compile-fail/non-exhaustive-match.rs +++ b/src/test/compile-fail/non-exhaustive-match.rs @@ -39,17 +39,6 @@ fn main() { } let vec = vec!(Some(42), None, Some(21)); let vec: &[Option] = &vec; - match vec { //~ ERROR non-exhaustive patterns: `[]` not covered - [Some(..), None, tail..] => {} - [Some(..), Some(..), tail..] => {} - [None] => {} - } - let vec = vec!(1); - let vec: &[isize] = &vec; - match vec { - [_, tail..] => (), - [] => () - } let vec = vec!(0.5f32); let vec: &[f32] = &vec; match vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _]` not covered @@ -58,15 +47,4 @@ fn main() { [0.1] => (), [] => () } - let vec = vec!(Some(42), None, Some(21)); - let vec: &[Option] = &vec; - match vec { - [Some(..), None, tail..] => {} - [Some(..), Some(..), tail..] => {} - [None, None, tail..] => {} - [None, Some(..), tail..] => {} - [Some(_)] => {} - [None] => {} - [] => {} - } } diff --git a/src/test/compile-fail/non-exhaustive-pattern-witness.rs b/src/test/compile-fail/non-exhaustive-pattern-witness.rs index b986878f78396..73f8c22b8b8b5 100644 --- a/src/test/compile-fail/non-exhaustive-pattern-witness.rs +++ b/src/test/compile-fail/non-exhaustive-pattern-witness.rs @@ -78,20 +78,6 @@ enum Enum { Second(bool) } -fn vectors_with_nested_enums() { - let x: &'static [Enum] = &[Enum::First, Enum::Second(false)]; - match x { - //~^ ERROR non-exhaustive patterns: `[Second(true), Second(false)]` not covered - [] => (), - [_] => (), - [Enum::First, _] => (), - [Enum::Second(true), Enum::First] => (), - [Enum::Second(true), Enum::Second(true)] => (), - [Enum::Second(false), _] => (), - [_, _, tail.., _] => () - } -} - fn missing_nil() { match ((), false) { //~^ ERROR non-exhaustive patterns: `((), false)` not covered diff --git a/src/test/run-pass/vec-matching-fold.rs b/src/test/compile-fail/vec-matching-fold.rs similarity index 90% rename from src/test/run-pass/vec-matching-fold.rs rename to src/test/compile-fail/vec-matching-fold.rs index ee70ea58750d9..624c2353437d8 100644 --- a/src/test/run-pass/vec-matching-fold.rs +++ b/src/test/compile-fail/vec-matching-fold.rs @@ -20,7 +20,7 @@ fn foldl(values: &[T], F: FnMut(U, &T) -> U, { match values { - [ref head, tail..] => + [ref head, tail..] => //~ ERROR slice patterns are badly broken foldl(tail, function(initial, head), function), [] => initial.clone() } @@ -34,7 +34,7 @@ fn foldr(values: &[T], F: FnMut(&T, U) -> U, { match values { - [head.., ref tail] => + [head.., ref tail] => //~ ERROR slice patterns are badly broken foldr(head, function(tail, initial), function), [] => initial.clone() } diff --git a/src/test/run-pass/vec-matching-legal-tail-element-borrow.rs b/src/test/compile-fail/vec-matching-legal-tail-element-borrow.rs similarity index 93% rename from src/test/run-pass/vec-matching-legal-tail-element-borrow.rs rename to src/test/compile-fail/vec-matching-legal-tail-element-borrow.rs index e7553c8e157e3..6d3a1080be7bb 100644 --- a/src/test/run-pass/vec-matching-legal-tail-element-borrow.rs +++ b/src/test/compile-fail/vec-matching-legal-tail-element-borrow.rs @@ -16,6 +16,7 @@ pub fn main() { if !x.is_empty() { let el = match x { [1, ref tail..] => &tail[0], + //~^ ERROR slice patterns are badly broken _ => unreachable!() }; println!("{}", *el); diff --git a/src/test/run-pass/vec-matching.rs b/src/test/compile-fail/vec-matching.rs similarity index 87% rename from src/test/run-pass/vec-matching.rs rename to src/test/compile-fail/vec-matching.rs index eedf27f857700..2485a0176dd43 100644 --- a/src/test/run-pass/vec-matching.rs +++ b/src/test/compile-fail/vec-matching.rs @@ -12,6 +12,8 @@ #![feature(advanced_slice_patterns)] #![feature(slice_patterns)] +// move this to rpass when slice patterns are fixed + fn a() { let x = [1]; match x { @@ -24,7 +26,7 @@ fn a() { fn b() { let x = [1, 2, 3]; match x { - [a, b, c..] => { + [a, b, c..] => { //~ ERROR slice patterns are badly broken assert_eq!(a, 1); assert_eq!(b, 2); let expected: &[_] = &[3]; @@ -32,7 +34,7 @@ fn b() { } } match x { - [a.., b, c] => { + [a.., b, c] => { //~ ERROR slice patterns are badly broken let expected: &[_] = &[1]; assert_eq!(a, expected); assert_eq!(b, 2); @@ -40,7 +42,7 @@ fn b() { } } match x { - [a, b.., c] => { + [a, b.., c] => { //~ ERROR slice patterns are badly broken assert_eq!(a, 1); let expected: &[_] = &[2]; assert_eq!(b, expected); diff --git a/src/test/run-pass/vec-tail-matching.rs b/src/test/compile-fail/vec-tail-matching.rs similarity index 95% rename from src/test/run-pass/vec-tail-matching.rs rename to src/test/compile-fail/vec-tail-matching.rs index 6cc7e3a072cf0..10c56e5a1e459 100644 --- a/src/test/run-pass/vec-tail-matching.rs +++ b/src/test/compile-fail/vec-tail-matching.rs @@ -31,6 +31,7 @@ pub fn main() { match tail { [Foo { .. }, _, Foo { .. }, _tail..] => { + //~^ ERROR slice patterns are badly broken unreachable!(); } [Foo { string: ref a }, Foo { string: ref b }] => { diff --git a/src/test/run-pass/zero_sized_subslice_match.rs b/src/test/compile-fail/zero_sized_subslice_match.rs similarity index 93% rename from src/test/run-pass/zero_sized_subslice_match.rs rename to src/test/compile-fail/zero_sized_subslice_match.rs index 697508ae48889..e83569d74615f 100644 --- a/src/test/run-pass/zero_sized_subslice_match.rs +++ b/src/test/compile-fail/zero_sized_subslice_match.rs @@ -18,5 +18,6 @@ fn main() { // happen anymore match x { [_, y..] => assert_eq!(&x[1] as *const (), &y[0] as *const ()) + //~^ ERROR slice patterns are badly broken } }