1
Fork 0

librustc: Remove unique vector patterns from the language.

Preparatory work for removing unique vectors from the language, which is
itself preparatory work for dynamically sized types.
This commit is contained in:
Patrick Walton 2014-02-13 09:46:46 -08:00
parent ea0058281c
commit 33923f47e3
25 changed files with 229 additions and 198 deletions

View file

@ -315,13 +315,16 @@ pub fn opt_shard(maybestr: Option<~str>) -> Option<(uint,uint)> {
match maybestr { match maybestr {
None => None, None => None,
Some(s) => { Some(s) => {
match s.split('.').to_owned_vec() { let vector = s.split('.').to_owned_vec();
[a, b] => match (from_str::<uint>(a), from_str::<uint>(b)) { if vector.len() == 2 {
(Some(a), Some(b)) => Some((a,b)), match (from_str::<uint>(vector[0]),
_ => None from_str::<uint>(vector[1])) {
}, (Some(a), Some(b)) => Some((a, b)),
_ => None _ => None
} }
} else {
None
}
} }
} }
} }

View file

@ -130,15 +130,14 @@ fn helper(input: libc::c_int, messages: Port<Req>) {
} }
'outer: loop { 'outer: loop {
let timeout = match active { let timeout = if active.len() == 0 {
// Empty array? no timeout (wait forever for the next request) // Empty array? no timeout (wait forever for the next request)
[] => ptr::null(), ptr::null()
} else {
[~Inner { target, .. }, ..] => {
let now = now(); let now = now();
// If this request has already expired, then signal it and go // If this request has already expired, then signal it and go
// through another iteration // through another iteration
if target <= now { if active[0].target <= now {
signal(&mut active, &mut dead); signal(&mut active, &mut dead);
continue; continue;
} }
@ -146,11 +145,10 @@ fn helper(input: libc::c_int, messages: Port<Req>) {
// The actual timeout listed in the requests array is an // The actual timeout listed in the requests array is an
// absolute date, so here we translate the absolute time to a // absolute date, so here we translate the absolute time to a
// relative time. // relative time.
let tm = target - now; let tm = active[0].target - now;
timeout.tv_sec = (tm / 1000) as libc::time_t; timeout.tv_sec = (tm / 1000) as libc::time_t;
timeout.tv_usec = ((tm % 1000) * 1000) as libc::suseconds_t; timeout.tv_usec = ((tm % 1000) * 1000) as libc::suseconds_t;
&timeout as *libc::timeval &timeout as *libc::timeval
}
}; };
imp::fd_set(&mut set, input); imp::fd_set(&mut set, input);

View file

@ -495,24 +495,23 @@ impl ToPrimitive for BigUint {
#[cfg(target_word_size = "32")] #[cfg(target_word_size = "32")]
#[inline] #[inline]
fn to_u64(&self) -> Option<u64> { fn to_u64(&self) -> Option<u64> {
match self.data { match self.data.len() {
[] => { 0 => Some(0),
Some(0) 1 => Some(self.data[0] as u64),
2 => {
Some(BigDigit::to_uint(self.data[1], self.data[0]) as u64)
} }
[n0] => { 3 => {
Some(n0 as u64) let n_lo = BigDigit::to_uint(self.data[1], self.data[0]) as
} u64;
[n0, n1] => { let n_hi = self.data[2] as u64;
Some(BigDigit::to_uint(n1, n0) as u64)
}
[n0, n1, n2] => {
let n_lo = BigDigit::to_uint(n1, n0) as u64;
let n_hi = n2 as u64;
Some((n_hi << 32) + n_lo) Some((n_hi << 32) + n_lo)
} }
[n0, n1, n2, n3] => { 4 => {
let n_lo = BigDigit::to_uint(n1, n0) as u64; let n_lo = BigDigit::to_uint(self.data[1], self.data[0])
let n_hi = BigDigit::to_uint(n3, n2) as u64; as u64;
let n_hi = BigDigit::to_uint(self.data[3], self.data[2])
as u64;
Some((n_hi << 32) + n_lo) Some((n_hi << 32) + n_lo)
} }
_ => None _ => None
@ -522,16 +521,10 @@ impl ToPrimitive for BigUint {
#[cfg(target_word_size = "64")] #[cfg(target_word_size = "64")]
#[inline] #[inline]
fn to_u64(&self) -> Option<u64> { fn to_u64(&self) -> Option<u64> {
match self.data { match self.data.len() {
[] => { 0 => Some(0),
Some(0) 1 => Some(self.data[0] as u64),
} 2 => Some(BigDigit::to_uint(self.data[1], self.data[0]) as u64),
[n0] => {
Some(n0 as u64)
}
[n0, n1] => {
Some(BigDigit::to_uint(n1, n0) as u64)
}
_ => None _ => None
} }
} }

View file

@ -1213,15 +1213,13 @@ fn check_unused_mut_pat(cx: &Context, p: &ast::Pat) {
ast::PatIdent(ast::BindByValue(ast::MutMutable), ast::PatIdent(ast::BindByValue(ast::MutMutable),
ref path, _) if pat_util::pat_is_binding(cx.tcx.def_map, p)=> { ref path, _) if pat_util::pat_is_binding(cx.tcx.def_map, p)=> {
// `let mut _a = 1;` doesn't need a warning. // `let mut _a = 1;` doesn't need a warning.
let initial_underscore = match path.segments { let initial_underscore = if path.segments.len() == 1 {
[ast::PathSegment { identifier: id, .. }] => { token::get_ident(path.segments[0].identifier).get()
token::get_ident(id).get().starts_with("_") .starts_with("_")
} } else {
_ => {
cx.tcx.sess.span_bug(p.span, cx.tcx.sess.span_bug(p.span,
"mutable binding that doesn't \ "mutable binding that doesn't consist \
consist of exactly one segment"); of exactly one segment")
}
}; };
let used_mut_nodes = cx.tcx.used_mut_nodes.borrow(); let used_mut_nodes = cx.tcx.used_mut_nodes.borrow();

View file

@ -603,7 +603,17 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
ty::ty_vec(mt, vstore) => { ty::ty_vec(mt, vstore) => {
let region_var = match vstore { let region_var = match vstore {
ty::vstore_slice(r) => r, ty::vstore_slice(r) => r,
ty::vstore_uniq | ty::vstore_fixed(_) => { ty::vstore_uniq => {
fcx.type_error_message(pat.span,
|_| {
~"unique vector patterns are no \
longer supported"
},
expected,
None);
default_region_var
}
ty::vstore_fixed(_) => {
default_region_var default_region_var
} }
}; };

View file

@ -3894,8 +3894,11 @@ pub fn ast_expr_vstore_to_vstore(fcx: @FnCtxt,
ast::ExprVstoreUniq => ty::vstore_uniq, ast::ExprVstoreUniq => ty::vstore_uniq,
ast::ExprVstoreSlice | ast::ExprVstoreMutSlice => { ast::ExprVstoreSlice | ast::ExprVstoreMutSlice => {
match e.node { match e.node {
ast::ExprLit(..) | ast::ExprLit(..) => {
ast::ExprVec([], _) => { // string literals and *empty slices* live in static memory
ty::vstore_slice(ty::ReStatic)
}
ast::ExprVec(ref elements, _) if elements.len() == 0 => {
// string literals and *empty slices* live in static memory // string literals and *empty slices* live in static memory
ty::vstore_slice(ty::ReStatic) ty::vstore_slice(ty::ReStatic)
} }

View file

@ -311,10 +311,9 @@ pub fn unindent(s: &str) -> ~str {
} }
}); });
match lines { if lines.len() >= 1 {
[head, .. tail] => { let mut unindented = ~[ lines[0].trim() ];
let mut unindented = ~[ head.trim() ]; unindented.push_all(lines.tail().map(|&line| {
unindented.push_all(tail.map(|&line| {
if line.is_whitespace() { if line.is_whitespace() {
line line
} else { } else {
@ -323,8 +322,8 @@ pub fn unindent(s: &str) -> ~str {
} }
})); }));
unindented.connect("\n") unindented.connect("\n")
} } else {
[] => s.to_owned() s.to_owned()
} }
} }

View file

@ -97,13 +97,11 @@ fn cs_clone(
name)) name))
} }
match *all_fields { if all_fields.len() >= 1 && all_fields[0].name.is_none() {
[FieldInfo { name: None, .. }, ..] => {
// enum-like // enum-like
let subcalls = all_fields.map(subcall); let subcalls = all_fields.map(subcall);
cx.expr_call_ident(trait_span, ctor_ident, subcalls) cx.expr_call_ident(trait_span, ctor_ident, subcalls)
}, } else {
_ => {
// struct-like // struct-like
let fields = all_fields.map(|field| { let fields = all_fields.map(|field| {
let ident = match field.name { let ident = match field.name {
@ -122,5 +120,4 @@ fn cs_clone(
cx.expr_struct_ident(trait_span, ctor_ident, fields) cx.expr_struct_ident(trait_span, ctor_ident, fields)
} }
} }
}
} }

View file

@ -663,10 +663,11 @@ impl<'a> MethodDef<'a> {
} }
// transpose raw_fields // transpose raw_fields
let fields = match raw_fields { let fields = if raw_fields.len() > 0 {
[ref self_arg, .. rest] => { raw_fields[0].iter()
self_arg.iter().enumerate().map(|(i, &(span, opt_id, field))| { .enumerate()
let other_fields = rest.map(|l| { .map(|(i, &(span, opt_id, field))| {
let other_fields = raw_fields.tail().map(|l| {
match &l[i] { match &l[i] {
&(_, _, ex) => ex &(_, _, ex) => ex
} }
@ -678,10 +679,10 @@ impl<'a> MethodDef<'a> {
other: other_fields other: other_fields
} }
}).collect() }).collect()
} } else {
[] => { cx.span_bug(trait_.span, cx.span_bug(trait_.span,
"no self arguments to non-static method \ "no self arguments to non-static method in generic \
in generic `deriving`") } `deriving`")
}; };
// body of the inner most destructuring match // body of the inner most destructuring match

View file

@ -54,7 +54,10 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt,
MetaNameValue(_, ref l) => { MetaNameValue(_, ref l) => {
cx.span_err(l.span, "unexpected value in `deriving`"); cx.span_err(l.span, "unexpected value in `deriving`");
} }
MetaWord(_) | MetaList(_, []) => { MetaWord(_) => {
cx.span_warn(mitem.span, "empty trait list in `deriving`");
}
MetaList(_, ref titems) if titems.len() == 0 => {
cx.span_warn(mitem.span, "empty trait list in `deriving`"); cx.span_warn(mitem.span, "empty trait list in `deriving`");
} }
MetaList(_, ref titems) => { MetaList(_, ref titems) => {

View file

@ -74,7 +74,8 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
// Getting harder... making the format string: // Getting harder... making the format string:
match *substr.fields { match *substr.fields {
// unit struct/nullary variant: no work necessary! // unit struct/nullary variant: no work necessary!
Struct([]) | EnumMatching(_, _, []) => {} Struct(ref fields) if fields.len() == 0 => {}
EnumMatching(_, _, ref fields) if fields.len() == 0 => {}
Struct(ref fields) | EnumMatching(_, _, ref fields) => { Struct(ref fields) | EnumMatching(_, _, ref fields) => {
if fields[0].name.is_none() { if fields[0].name.is_none() {

View file

@ -40,7 +40,7 @@ pub fn expand_option_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> base::MacResult { -> base::MacResult {
let exprs = match get_exprs_from_tts(cx, sp, tts) { let exprs = match get_exprs_from_tts(cx, sp, tts) {
Some([]) => { Some(ref exprs) if exprs.len() == 0 => {
cx.span_err(sp, "env! takes 1 or 2 arguments"); cx.span_err(sp, "env! takes 1 or 2 arguments");
return MacResult::dummy_expr(sp); return MacResult::dummy_expr(sp);
} }

View file

@ -647,14 +647,10 @@ impl Visitor<()> for NewNameFinderContext {
&ast::Path { &ast::Path {
global: false, global: false,
span: _, span: _,
segments: [ segments: ref segments
ast::PathSegment { } if segments.len() == 1 => {
identifier: id, self.ident_accumulator.push(segments[0].identifier)
lifetimes: _,
types: _
} }
]
} => self.ident_accumulator.push(id),
// I believe these must be enums... // I believe these must be enums...
_ => () _ => ()
} }
@ -1187,7 +1183,12 @@ foo_module!()
let bindings = name_finder.ident_accumulator; let bindings = name_finder.ident_accumulator;
let cxbinds: ~[&ast::Ident] = let cxbinds: ~[&ast::Ident] =
bindings.iter().filter(|b| "xx" == token::get_ident(**b).get()).collect(); bindings.iter().filter(|b| {
let ident = token::get_ident(**b);
let string = ident.get();
"xx" == string
}).collect();
let cxbinds: &[&ast::Ident] = cxbinds;
let cxbind = match cxbinds { let cxbind = match cxbinds {
[b] => b, [b] => b,
_ => fail!("expected just one binding for ext_cx") _ => fail!("expected just one binding for ext_cx")

View file

@ -363,40 +363,48 @@ mod test {
// check the token-tree-ization of macros // check the token-tree-ization of macros
#[test] fn string_to_tts_macro () { #[test] fn string_to_tts_macro () {
let tts = string_to_tts(~"macro_rules! zip (($a)=>($a))"); let tts = string_to_tts(~"macro_rules! zip (($a)=>($a))");
let tts: &[ast::TokenTree] = tts;
match tts { match tts {
[ast::TTTok(_,_), [ast::TTTok(_,_),
ast::TTTok(_,token::NOT), ast::TTTok(_,token::NOT),
ast::TTTok(_,_), ast::TTTok(_,_),
ast::TTDelim(delim_elts)] => ast::TTDelim(delim_elts)] => {
match *delim_elts { let delim_elts: &[ast::TokenTree] = *delim_elts;
match delim_elts {
[ast::TTTok(_,token::LPAREN), [ast::TTTok(_,token::LPAREN),
ast::TTDelim(first_set), ast::TTDelim(first_set),
ast::TTTok(_,token::FAT_ARROW), ast::TTTok(_,token::FAT_ARROW),
ast::TTDelim(second_set), ast::TTDelim(second_set),
ast::TTTok(_,token::RPAREN)] => ast::TTTok(_,token::RPAREN)] => {
match *first_set { let first_set: &[ast::TokenTree] = *first_set;
match first_set {
[ast::TTTok(_,token::LPAREN), [ast::TTTok(_,token::LPAREN),
ast::TTTok(_,token::DOLLAR), ast::TTTok(_,token::DOLLAR),
ast::TTTok(_,_), ast::TTTok(_,_),
ast::TTTok(_,token::RPAREN)] => ast::TTTok(_,token::RPAREN)] => {
match *second_set { let second_set: &[ast::TokenTree] =
*second_set;
match second_set {
[ast::TTTok(_,token::LPAREN), [ast::TTTok(_,token::LPAREN),
ast::TTTok(_,token::DOLLAR), ast::TTTok(_,token::DOLLAR),
ast::TTTok(_,_), ast::TTTok(_,_),
ast::TTTok(_,token::RPAREN)] => ast::TTTok(_,token::RPAREN)] => {
assert_eq!("correct","correct"), assert_eq!("correct","correct")
}
_ => assert_eq!("wrong 4","correct") _ => assert_eq!("wrong 4","correct")
}
}, },
_ => { _ => {
error!("failing value 3: {:?}",first_set); error!("failing value 3: {:?}",first_set);
assert_eq!("wrong 3","correct") assert_eq!("wrong 3","correct")
} }
}
}, },
_ => { _ => {
error!("failing value 2: {:?}",delim_elts); error!("failing value 2: {:?}",delim_elts);
assert_eq!("wrong","correct"); assert_eq!("wrong","correct");
} }
}
}, },
_ => { _ => {
error!("failing value: {:?}",tts); error!("failing value: {:?}",tts);

View file

@ -81,7 +81,13 @@ impl<T> SmallVector<T> {
pub fn expect_one(self, err: &'static str) -> T { pub fn expect_one(self, err: &'static str) -> T {
match self { match self {
One(v) => v, One(v) => v,
Many([v]) => v, Many(v) => {
if v.len() == 1 {
v.move_iter().next().unwrap()
} else {
fail!(err)
}
}
_ => fail!(err) _ => fail!(err)
} }
} }

View file

@ -21,6 +21,7 @@ pub fn main() {
Foo { string: ~"bar" }, Foo { string: ~"bar" },
Foo { string: ~"baz" } Foo { string: ~"baz" }
]; ];
let x: &[Foo] = x;
match x { match x {
[_, ..tail] => { [_, ..tail] => {
match tail { match tail {

View file

@ -10,8 +10,9 @@
fn a() -> &[int] { fn a() -> &[int] {
let vec = ~[1, 2, 3, 4]; let vec = ~[1, 2, 3, 4];
let vec: &[int] = vec; //~ ERROR does not live long enough
let tail = match vec { let tail = match vec {
[_, ..tail] => tail, //~ ERROR does not live long enough [_, ..tail] => tail,
_ => fail!("a") _ => fail!("a")
}; };
tail tail
@ -19,8 +20,9 @@ fn a() -> &[int] {
fn b() -> &[int] { fn b() -> &[int] {
let vec = ~[1, 2, 3, 4]; let vec = ~[1, 2, 3, 4];
let vec: &[int] = vec; //~ ERROR does not live long enough
let init = match vec { let init = match vec {
[..init, _] => init, //~ ERROR does not live long enough [..init, _] => init,
_ => fail!("b") _ => fail!("b")
}; };
init init
@ -28,8 +30,9 @@ fn b() -> &[int] {
fn c() -> &[int] { fn c() -> &[int] {
let vec = ~[1, 2, 3, 4]; let vec = ~[1, 2, 3, 4];
let vec: &[int] = vec; //~ ERROR does not live long enough
let slice = match vec { let slice = match vec {
[_, ..slice, _] => slice, //~ ERROR does not live long enough [_, ..slice, _] => slice,
_ => fail!("c") _ => fail!("c")
}; };
slice slice

View file

@ -10,7 +10,8 @@
fn a() { fn a() {
let mut v = ~[1, 2, 3]; let mut v = ~[1, 2, 3];
match v { let vb: &mut [int] = v;
match vb {
[_a, ..tail] => { [_a, ..tail] => {
v.push(tail[0] + tail[1]); //~ ERROR cannot borrow v.push(tail[0] + tail[1]); //~ ERROR cannot borrow
} }

View file

@ -9,17 +9,17 @@
// except according to those terms. // except according to those terms.
fn a() { fn a() {
let mut vec = ~[~1, ~2, ~3]; let mut vec = [~1, ~2, ~3];
match vec { match vec {
[~ref _a] => { [~ref _a, _, _] => {
vec[0] = ~4; //~ ERROR cannot assign vec[0] = ~4; //~ ERROR cannot assign
} }
_ => fail!("foo")
} }
} }
fn b() { fn b() {
let mut vec = ~[~1, ~2, ~3]; let mut vec = ~[~1, ~2, ~3];
let vec: &mut [~int] = vec;
match vec { match vec {
[.._b] => { [.._b] => {
vec[0] = ~4; //~ ERROR cannot assign vec[0] = ~4; //~ ERROR cannot assign
@ -29,6 +29,7 @@ fn b() {
fn c() { fn c() {
let mut vec = ~[~1, ~2, ~3]; let mut vec = ~[~1, ~2, ~3];
let vec: &mut [~int] = vec;
match vec { match vec {
[_a, .._b] => { [_a, .._b] => {
//~^ ERROR cannot move out //~^ ERROR cannot move out
@ -41,27 +42,31 @@ fn c() {
} }
_ => {} _ => {}
} }
let a = vec[0]; //~ ERROR use of partially moved value: `vec` let a = vec[0]; //~ ERROR cannot move out
} }
fn d() { fn d() {
let mut vec = ~[~1, ~2, ~3]; let mut vec = ~[~1, ~2, ~3];
let vec: &mut [~int] = vec;
match vec { match vec {
[.._a, _b] => { [.._a, _b] => {
//~^ ERROR cannot move out //~^ ERROR cannot move out
} }
_ => {} _ => {}
} }
let a = vec[0]; //~ ERROR use of partially moved value: `vec` let a = vec[0]; //~ ERROR cannot move out
} }
fn e() { fn e() {
let mut vec = ~[~1, ~2, ~3]; let mut vec = ~[~1, ~2, ~3];
let vec: &mut [~int] = vec;
match vec { match vec {
[_a, _b, _c] => {} [_a, _b, _c] => {} //~ ERROR cannot move out
//~^ ERROR cannot move out
//~^^ ERROR cannot move out
_ => {} _ => {}
} }
let a = vec[0]; //~ ERROR use of partially moved value: `vec` let a = vec[0]; //~ ERROR cannot move out
} }
fn main() {} fn main() {}

View file

@ -10,8 +10,9 @@
fn a() -> &int { fn a() -> &int {
let vec = ~[1, 2, 3, 4]; let vec = ~[1, 2, 3, 4];
let vec: &[int] = vec; //~ ERROR `vec[..]` does not live long enough
let tail = match vec { let tail = match vec {
[_a, ..tail] => &tail[0], //~ ERROR `vec[..]` does not live long enough [_a, ..tail] => &tail[0],
_ => fail!("foo") _ => fail!("foo")
}; };
tail tail

View file

@ -10,19 +10,24 @@
fn main() { fn main() {
let x: ~[(int, int)] = ~[]; let x: ~[(int, int)] = ~[];
let x: &[(int, int)] = x;
match x { match x {
[a, (2, 3), _] => (), [a, (2, 3), _] => (),
[(1, 2), (2, 3), b] => (), //~ ERROR unreachable pattern [(1, 2), (2, 3), b] => (), //~ ERROR unreachable pattern
_ => () _ => ()
} }
match ~[~"foo", ~"bar", ~"baz"] { let x: ~[~str] = ~[~"foo", ~"bar", ~"baz"];
let x: &[~str] = x;
match x {
[a, _, _, ..] => { println!("{}", a); } [a, _, _, ..] => { println!("{}", a); }
[~"foo", ~"bar", ~"baz", ~"foo", ~"bar"] => { } //~ ERROR unreachable pattern [~"foo", ~"bar", ~"baz", ~"foo", ~"bar"] => { } //~ ERROR unreachable pattern
_ => { } _ => { }
} }
match ~['a', 'b', 'c'] { let x: ~[char] = ~['a', 'b', 'c'];
let x: &[char] = x;
match x {
['a', 'b', 'c', .._tail] => {} ['a', 'b', 'c', .._tail] => {}
['a', 'b', 'c'] => {} //~ ERROR unreachable pattern ['a', 'b', 'c'] => {} //~ ERROR unreachable pattern
_ => {} _ => {}

View file

@ -35,23 +35,31 @@ fn main() {
(_, a) => {} (_, a) => {}
(b, b) => {} (b, b) => {}
} }
match ~[Some(42), None, Some(21)] { let vec = ~[Some(42), None, Some(21)];
let vec: &[Option<int>] = vec;
match vec {
//~^ ERROR non-exhaustive patterns: vectors of length 0 not covered //~^ ERROR non-exhaustive patterns: vectors of length 0 not covered
[Some(..), None, ..tail] => {} [Some(..), None, ..tail] => {}
[Some(..), Some(..), ..tail] => {} [Some(..), Some(..), ..tail] => {}
[None] => {} [None] => {}
} }
match ~[1] { let vec = ~[1];
let vec: &[int] = vec;
match vec {
[_, ..tail] => (), [_, ..tail] => (),
[] => () [] => ()
} }
match ~[0.5] { //~ ERROR non-exhaustive patterns: vectors of length 4 not covered let vec = ~[0.5];
let vec: &[f32] = vec;
match vec { //~ ERROR non-exhaustive patterns: vectors of length 4 not covered
[0.1, 0.2, 0.3] => (), [0.1, 0.2, 0.3] => (),
[0.1, 0.2] => (), [0.1, 0.2] => (),
[0.1] => (), [0.1] => (),
[] => () [] => ()
} }
match ~[Some(42), None, Some(21)] { let vec = ~[Some(42), None, Some(21)];
let vec: &[Option<int>] = vec;
match vec {
[Some(..), None, ..tail] => {} [Some(..), None, ..tail] => {}
[Some(..), Some(..), ..tail] => {} [Some(..), Some(..), ..tail] => {}
[None, None, ..tail] => {} [None, None, ..tail] => {}

View file

@ -9,24 +9,22 @@
// except according to those terms. // except according to those terms.
pub fn main() { pub fn main() {
let x = ~[1, 2, 3]; let x = [1, 2, 3];
match x { match x {
[2, ..] => fail!(), [2, _, _] => fail!(),
[1, ..tail] => { [1, a, b] => {
assert_eq!(tail, [2, 3]); assert_eq!([a, b], [2, 3]);
} }
[_] => fail!(), [_, _, _] => fail!(),
[] => fail!()
} }
let y = (~[(1, true), (2, false)], 0.5); let y = ([(1, true), (2, false)], 0.5);
match y { match y {
([_, _, _], 0.5) => fail!(), ([(1, a), (b, false)], _) => {
([(1, a), (b, false), ..tail], _) => {
assert_eq!(a, true); assert_eq!(a, true);
assert_eq!(b, 2); assert_eq!(b, 2);
assert!(tail.is_empty());
} }
([.._tail], _) => fail!() ([_, _], 0.5) => fail!(),
([_, _], _) => fail!(),
} }
} }

View file

@ -9,28 +9,22 @@
// except according to those terms. // except according to those terms.
fn a() { fn a() {
let x = ~[1]; let x = [1];
match x { match x {
[_, _, _, _, _, ..] => fail!(),
[.., _, _, _, _] => fail!(),
[_, .., _, _] => fail!(),
[_, _] => fail!(),
[a] => { [a] => {
assert_eq!(a, 1); assert_eq!(a, 1);
} }
[] => fail!()
} }
} }
fn b() { fn b() {
let x = ~[1, 2, 3]; let x = [1, 2, 3];
match x { match x {
[a, b, ..c] => { [a, b, ..c] => {
assert_eq!(a, 1); assert_eq!(a, 1);
assert_eq!(b, 2); assert_eq!(b, 2);
assert_eq!(c, &[3]); assert_eq!(c, &[3]);
} }
_ => fail!()
} }
match x { match x {
[..a, b, c] => { [..a, b, c] => {
@ -38,7 +32,6 @@ fn b() {
assert_eq!(b, 2); assert_eq!(b, 2);
assert_eq!(c, 3); assert_eq!(c, 3);
} }
_ => fail!()
} }
match x { match x {
[a, ..b, c] => { [a, ..b, c] => {
@ -46,7 +39,6 @@ fn b() {
assert_eq!(b, &[2]); assert_eq!(b, &[2]);
assert_eq!(c, 3); assert_eq!(c, 3);
} }
_ => fail!()
} }
match x { match x {
[a, b, c] => { [a, b, c] => {
@ -54,7 +46,6 @@ fn b() {
assert_eq!(b, 2); assert_eq!(b, 2);
assert_eq!(c, 3); assert_eq!(c, 3);
} }
_ => fail!()
} }
} }

View file

@ -14,7 +14,7 @@ struct Foo {
} }
pub fn main() { pub fn main() {
let x = ~[ let x = [
Foo { string: ~"foo" }, Foo { string: ~"foo" },
Foo { string: ~"bar" }, Foo { string: ~"bar" },
Foo { string: ~"baz" } Foo { string: ~"baz" }
@ -39,8 +39,5 @@ pub fn main() {
} }
} }
} }
_ => {
unreachable!();
}
} }
} }