Skip to content

disable multiple-match slice patterns #32161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions src/librustc/mir/repr.rs
Original file line number Diff line number Diff line change
@@ -663,17 +663,6 @@ pub enum Rvalue<'tcx> {
/// away after type-checking and before lowering.
Aggregate(AggregateKind<'tcx>, Vec<Operand<'tcx>>),

/// 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 => "",
1 change: 0 additions & 1 deletion src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
@@ -198,7 +198,6 @@ impl<'tcx> Mir<'tcx> {
}
}
}
Rvalue::Slice { .. } => None,
Rvalue::InlineAsm(..) => None
}
}
9 changes: 0 additions & 9 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
@@ -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(_) => {
}
}
18 changes: 11 additions & 7 deletions src/librustc_mir/build/matches/simplify.rs
Original file line number Diff line number Diff line change
@@ -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<BasicBlock, MatchPair<'pat, 'tcx>> {
@@ -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)
}

54 changes: 6 additions & 48 deletions src/librustc_mir/build/matches/util.rs
Original file line number Diff line number Diff line change
@@ -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<MatchPair<'pat, 'tcx>>,
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<MatchPair<'pat, 'tcx>>,
lvalue: Lvalue<'tcx>,
prefix: &'pat [Pattern<'tcx>],
suffix: &'pat [Pattern<'tcx>]) {
pub fn prefix_suffix<'pat>(&mut self,
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
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;
1 change: 0 additions & 1 deletion src/librustc_mir/transform/erase_regions.rs
Original file line number Diff line number Diff line change
@@ -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),
21 changes: 0 additions & 21 deletions src/librustc_trans/trans/mir/rvalue.rs
Original file line number Diff line number Diff line change
@@ -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,
}
5 changes: 5 additions & 0 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
@@ -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);
Original file line number Diff line number Diff line change
@@ -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!();
Original file line number Diff line number Diff line change
@@ -13,29 +13,29 @@

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
}

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
}

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
Original file line number Diff line number Diff line change
@@ -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
}
_ => {}
};
Original file line number Diff line number Diff line change
@@ -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];
}
32 changes: 17 additions & 15 deletions src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs
Original file line number Diff line number Diff line change
@@ -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<isize>] = &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<isize>] = &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<isize>] = &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<isize>] = &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() {}
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion src/test/compile-fail/feature-gate-slice-patterns.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
4 changes: 3 additions & 1 deletion src/test/compile-fail/issue-12369.rs
Original file line number Diff line number Diff line change
@@ -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
};
}
12 changes: 8 additions & 4 deletions src/test/compile-fail/issue-12567.rs
Original file line number Diff line number Diff line change
@@ -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
}
}

Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
@@ -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");
2 changes: 1 addition & 1 deletion src/test/compile-fail/match-vec-mismatch.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
#![feature(slice_patterns)]

fn main() {
match "foo".to_string() {
match "foo" {
['f', 'o', ..] => {} //~ ERROR mismatched types
_ => { }
}
7 changes: 4 additions & 3 deletions src/test/compile-fail/match-vec-unreachable.rs
Original file line number Diff line number Diff line change
@@ -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,15 +25,16 @@ fn main() {
let x: &[String] = &x;
match x {
[a, _, _, ..] => { println!("{}", a); }
[_, _, _, _, _] => { } //~ ERROR unreachable pattern
[_, _, _, _, _] => { } //# ERROR unreachable pattern
_ => { }
}

let x: Vec<char> = vec!('a', 'b', 'c');
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
_ => {}
}
}
63 changes: 63 additions & 0 deletions src/test/compile-fail/non-exhaustive-match-slice-patterns.rs
Original file line number Diff line number Diff line change
@@ -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 <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.

#![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<isize>] = &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
[] => ()
}
}
22 changes: 0 additions & 22 deletions src/test/compile-fail/non-exhaustive-match.rs
Original file line number Diff line number Diff line change
@@ -39,17 +39,6 @@ fn main() {
}
let vec = vec!(Some(42), None, Some(21));
let vec: &[Option<isize>] = &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<isize>] = &vec;
match vec {
[Some(..), None, tail..] => {}
[Some(..), Some(..), tail..] => {}
[None, None, tail..] => {}
[None, Some(..), tail..] => {}
[Some(_)] => {}
[None] => {}
[] => {}
}
}
14 changes: 0 additions & 14 deletions src/test/compile-fail/non-exhaustive-pattern-witness.rs
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ fn foldl<T, U, F>(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<T, U, F>(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()
}
Original file line number Diff line number Diff line change
@@ -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);
Original file line number Diff line number Diff line change
@@ -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,23 +26,23 @@ 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];
assert_eq!(c, expected);
}
}
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);
assert_eq!(c, 3);
}
}
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);
Original file line number Diff line number Diff line change
@@ -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 }] => {
Original file line number Diff line number Diff line change
@@ -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
}
}