Skip to content

Commit 22179f4

Browse files
committed
librustc: Feature gate subslice matching in non-tail positions.
This breaks code that uses the `..xs` form anywhere but at the end of a slice. For example: match foo { [ 1, ..xs, 2 ] [ ..xs, 1, 2 ] } Add the `#![feature(advanced_slice_patterns)]` gate to reenable the syntax. RFC #54. Closes #16951. [breaking-change]
1 parent 6f34760 commit 22179f4

12 files changed

+57
-6
lines changed

src/doc/rust.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3290,13 +3290,15 @@ between `_` and `..` is that the pattern `C(_)` is only type-correct if `C` has
32903290
exactly one argument, while the pattern `C(..)` is type-correct for any enum
32913291
variant `C`, regardless of how many arguments `C` has.
32923292

3293-
Used inside a vector pattern, `..` stands for any number of elements. This
3294-
wildcard can be used at most once for a given vector, which implies that it
3295-
cannot be used to specifically match elements that are at an unknown distance
3296-
from both ends of a vector, like `[.., 42, ..]`. If followed by a variable name,
3297-
it will bind the corresponding slice to the variable. Example:
3293+
Used inside a vector pattern, `..` stands for any number of elements, when the
3294+
`advanced_slice_patterns` feature gate is turned on. This wildcard can be used
3295+
at most once for a given vector, which implies that it cannot be used to
3296+
specifically match elements that are at an unknown distance from both ends of a
3297+
vector, like `[.., 42, ..]`. If followed by a variable name, it will bind the
3298+
corresponding slice to the variable. Example:
32983299

32993300
~~~~
3301+
# #![feature(advanced_slice_patterns)]
33003302
fn is_symmetric(list: &[uint]) -> bool {
33013303
match list {
33023304
[] | [_] => true,

src/librustc/front/feature_gate.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
6969
("rustc_diagnostic_macros", Active),
7070
("unboxed_closures", Active),
7171
("import_shadowing", Active),
72+
("advanced_slice_patterns", Active),
7273

7374
// if you change this list without updating src/doc/rust.md, cmr will be sad
7475

@@ -364,6 +365,20 @@ impl<'a> Visitor<()> for Context<'a> {
364365
}
365366
}
366367

368+
fn visit_pat(&mut self, pattern: &ast::Pat, (): ()) {
369+
match pattern.node {
370+
ast::PatVec(_, Some(_), ref last) if !last.is_empty() => {
371+
self.gate_feature("advanced_slice_patterns",
372+
pattern.span,
373+
"multiple-element slice matches anywhere \
374+
but at the end of a slice (e.g. \
375+
`[0, ..xs, 0]` are experimental")
376+
}
377+
_ => {}
378+
}
379+
visit::walk_pat(self, pattern, ())
380+
}
381+
367382
fn visit_fn(&mut self,
368383
fn_kind: &visit::FnKind,
369384
fn_decl: &ast::FnDecl,

src/test/compile-fail/borrowck-vec-pattern-element-loan.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(advanced_slice_patterns)]
12+
1113
fn a<'a>() -> &'a [int] {
1214
let vec = vec!(1, 2, 3, 4);
1315
let vec: &[int] = vec.as_slice(); //~ ERROR does not live long enough

src/test/compile-fail/borrowck-vec-pattern-nesting.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(advanced_slice_patterns)]
1112

1213
fn a() {
1314
let mut vec = [box 1i, box 2, box 3];
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let x = [ 1i, 2, 3, 4, 5 ];
13+
match x {
14+
[ ..xs, 4, 5 ] => {} //~ ERROR multiple-element slice matches
15+
[ 1, ..xs, 5 ] => {} //~ ERROR multiple-element slice matches
16+
[ 1, 2, ..xs ] => {} // OK without feature gate
17+
}
18+
}
19+

src/test/compile-fail/non-exhaustive-pattern-witness.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![feature(struct_variant)]
11+
#![feature(advanced_slice_patterns, struct_variant)]
1212

1313
struct Foo {
1414
first: bool,

src/test/run-pass/ignore-all-the-things.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(advanced_slice_patterns)]
12+
1113
struct Foo(int, int, int, int);
1214
struct Bar{a: int, b: int, c: int, d: int}
1315

src/test/run-pass/issue-7784.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(advanced_slice_patterns)]
12+
1113
fn foo<T: Add<T, T> + Clone>([x, y, z]: [T, ..3]) -> (T, T, T) {
1214
(x.clone(), x.clone() + y.clone(), x + y + z)
1315
}

src/test/run-pass/match-vec-alternatives.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(advanced_slice_patterns)]
12+
1113
fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) -> &'static str {
1214
match (l1, l2) {
1315
([], []) => "both empty",

src/test/run-pass/vec-matching-fixed.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(advanced_slice_patterns)]
12+
1113
fn a() {
1214
let x = [1i, 2, 3];
1315
match x {

src/test/run-pass/vec-matching-fold.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(advanced_slice_patterns)]
12+
1113
fn foldl<T,U:Clone>(values: &[T],
1214
initial: U,
1315
function: |partial: U, element: &T| -> U)

src/test/run-pass/vec-matching.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(advanced_slice_patterns)]
12+
1113
fn a() {
1214
let x = [1i];
1315
match x {

0 commit comments

Comments
 (0)