diff --git a/doc/tutorial.md b/doc/tutorial.md index a5f2001eaf5..b721a3628c9 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1305,7 +1305,7 @@ match crayons[0] { A vector can be destructured using pattern matching: ~~~~ -let numbers: [int, ..3] = [1, 2, 3]; +let numbers: &[int] = &[1, 2, 3]; let score = match numbers { [] => 0, [a] => a * 10, diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 1b420b9c06a..1422e17b059 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -255,6 +255,9 @@ pub fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { } not_useful } + ty::ty_evec(_, ty::vstore_fixed(n)) => { + is_useful_specialized(cx, m, v, vec(n), n, left_ty) + } ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { let max_len = do m.rev_iter().fold(0) |max_len, r| { match r[0].node { @@ -409,6 +412,29 @@ pub fn missing_ctor(cx: &MatchCheckCtxt, else if true_found { Some(val(const_bool(false))) } else { Some(val(const_bool(true))) } } + ty::ty_evec(_, ty::vstore_fixed(n)) => { + let mut missing = true; + let mut wrong = false; + for r in m.iter() { + match r[0].node { + pat_vec(ref before, ref slice, ref after) => { + let count = before.len() + after.len(); + if (count < n && slice.is_none()) || count > n { + wrong = true; + } + if count == n || (count < n && slice.is_some()) { + missing = false; + } + } + _ => {} + } + } + match (wrong, missing) { + (true, _) => Some(vec(n)), // should be compile-time error + (_, true) => Some(vec(n)), + _ => None + } + } ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { // Find the lengths and slices of all vector patterns. diff --git a/src/test/compile-fail/borrowck-move-out-of-vec-tail.rs b/src/test/compile-fail/borrowck-move-out-of-vec-tail.rs index 39a0e585ad2..0f67d8a6d0c 100644 --- a/src/test/compile-fail/borrowck-move-out-of-vec-tail.rs +++ b/src/test/compile-fail/borrowck-move-out-of-vec-tail.rs @@ -6,7 +6,7 @@ struct Foo { } pub fn main() { - let x = [ + let x = ~[ Foo { string: ~"foo" }, Foo { string: ~"bar" }, Foo { string: ~"baz" } diff --git a/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs b/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs index 7f98eba5996..ca20d68e4cd 100644 --- a/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs +++ b/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs @@ -1,5 +1,5 @@ fn a() -> &[int] { - let vec = [1, 2, 3, 4]; + let vec = ~[1, 2, 3, 4]; let tail = match vec { [_, ..tail] => tail, //~ ERROR does not live long enough _ => fail!("a") @@ -8,7 +8,7 @@ fn a() -> &[int] { } fn b() -> &[int] { - let vec = [1, 2, 3, 4]; + let vec = ~[1, 2, 3, 4]; let init = match vec { [..init, _] => init, //~ ERROR does not live long enough _ => fail!("b") @@ -17,7 +17,7 @@ fn b() -> &[int] { } fn c() -> &[int] { - let vec = [1, 2, 3, 4]; + let vec = ~[1, 2, 3, 4]; let slice = match vec { [_, ..slice, _] => slice, //~ ERROR does not live long enough _ => fail!("c") diff --git a/src/test/compile-fail/borrowck-vec-pattern-nesting.rs b/src/test/compile-fail/borrowck-vec-pattern-nesting.rs index 36ae5f88208..02ba1b9d2ff 100644 --- a/src/test/compile-fail/borrowck-vec-pattern-nesting.rs +++ b/src/test/compile-fail/borrowck-vec-pattern-nesting.rs @@ -1,24 +1,24 @@ fn a() { - let mut vec = [~1, ~2, ~3]; + let mut vec = ~[~1, ~2, ~3]; match vec { [~ref _a] => { - vec[0] = ~4; //~ ERROR cannot assign to `vec[]` because it is borrowed + vec[0] = ~4; //~ ERROR cannot assign to `(*vec)[]` because it is borrowed } _ => fail!("foo") } } fn b() { - let mut vec = [~1, ~2, ~3]; + let mut vec = ~[~1, ~2, ~3]; match vec { [.._b] => { - vec[0] = ~4; //~ ERROR cannot assign to `vec[]` because it is borrowed + vec[0] = ~4; //~ ERROR cannot assign to `(*vec)[]` because it is borrowed } } } fn c() { - let mut vec = [~1, ~2, ~3]; + let mut vec = ~[~1, ~2, ~3]; match vec { [_a, .._b] => { //~^ ERROR cannot move out @@ -35,7 +35,7 @@ fn c() { } fn d() { - let mut vec = [~1, ~2, ~3]; + let mut vec = ~[~1, ~2, ~3]; match vec { [.._a, _b] => { //~^ ERROR cannot move out @@ -46,7 +46,7 @@ fn d() { } fn e() { - let mut vec = [~1, ~2, ~3]; + let mut vec = ~[~1, ~2, ~3]; match vec { [_a, _b, _c] => {} _ => {} diff --git a/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs b/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs index e3e12a4a416..87511c34172 100644 --- a/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs +++ b/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs @@ -1,5 +1,5 @@ fn a() -> &int { - let vec = [1, 2, 3, 4]; + let vec = ~[1, 2, 3, 4]; let tail = match vec { [_a, ..tail] => &tail[0], //~ ERROR borrowed value does not live long enough _ => fail!("foo") diff --git a/src/test/compile-fail/match-vec-fixed.rs b/src/test/compile-fail/match-vec-fixed.rs new file mode 100644 index 00000000000..b3e139805a0 --- /dev/null +++ b/src/test/compile-fail/match-vec-fixed.rs @@ -0,0 +1,16 @@ +fn a() { + let v = [1, 2, 3]; + match v { + [_, _, _] => {} + [_, _, _] => {} //~ ERROR unreachable pattern + } + match v { + [_, 1, _] => {} + [_, 1, _] => {} //~ ERROR unreachable pattern + _ => {} + } +} + +fn main() { + a(); +} diff --git a/src/test/compile-fail/match-vec-unreachable.rs b/src/test/compile-fail/match-vec-unreachable.rs index 3930e7d2192..b557242af44 100644 --- a/src/test/compile-fail/match-vec-unreachable.rs +++ b/src/test/compile-fail/match-vec-unreachable.rs @@ -6,13 +6,13 @@ fn main() { _ => () } - match [~"foo", ~"bar", ~"baz"] { + match ~[~"foo", ~"bar", ~"baz"] { [a, _, _, .._] => { println(a); } [~"foo", ~"bar", ~"baz", ~"foo", ~"bar"] => { } //~ ERROR unreachable pattern _ => { } } - match ['a', 'b', 'c'] { + match ~['a', 'b', 'c'] { ['a', 'b', 'c', .._tail] => {} ['a', 'b', 'c'] => {} //~ ERROR unreachable pattern _ => {} diff --git a/src/test/run-pass/vec-matching-fixed.rs b/src/test/run-pass/vec-matching-fixed.rs new file mode 100644 index 00000000000..234311dec33 --- /dev/null +++ b/src/test/run-pass/vec-matching-fixed.rs @@ -0,0 +1,28 @@ +fn a() { + let x = [1, 2, 3]; + match x { + [1, 2, 4] => ::std::util::unreachable(), + [0, 2, 3, .._] => ::std::util::unreachable(), + [0, .._, 3] => ::std::util::unreachable(), + [0, .._] => ::std::util::unreachable(), + [1, 2, 3] => (), + [_, _, _] => ::std::util::unreachable(), + } + match x { + [.._] => (), + } + match x { + [_, _, _, .._] => (), + } + match x { + [a, b, c] => { + assert_eq!(1, a); + assert_eq!(2, b); + assert_eq!(3, c); + } + } +} + +pub fn main() { + a(); +} diff --git a/src/test/run-pass/vec-matching.rs b/src/test/run-pass/vec-matching.rs index 5e906fa2659..fb73c7e097d 100644 --- a/src/test/run-pass/vec-matching.rs +++ b/src/test/run-pass/vec-matching.rs @@ -1,5 +1,5 @@ fn a() { - let x = [1]; + let x = ~[1]; match x { [_, _, _, _, _, .._] => ::std::util::unreachable(), [.._, _, _, _, _] => ::std::util::unreachable(), @@ -13,7 +13,7 @@ fn a() { } fn b() { - let x = [1, 2, 3]; + let x = ~[1, 2, 3]; match x { [a, b, ..c] => { assert_eq!(a, 1); diff --git a/src/test/run-pass/vec-tail-matching.rs b/src/test/run-pass/vec-tail-matching.rs index 27f4fc83351..6a60308f2e7 100644 --- a/src/test/run-pass/vec-tail-matching.rs +++ b/src/test/run-pass/vec-tail-matching.rs @@ -3,7 +3,7 @@ struct Foo { } pub fn main() { - let x = [ + let x = ~[ Foo { string: ~"foo" }, Foo { string: ~"bar" }, Foo { string: ~"baz" }