Skip to content

Commit

Permalink
Auto merge of #48516 - petrochenkov:stabsl, r=nikomatsakis
Browse files Browse the repository at this point in the history
Stabilize slice patterns without `..`

And merge `feature(advanced_slice_patterns)` into `feature(slice_patterns)`.

The detailed description can be found in #48836.

Slice patterns were unstable for long time since before 1.0 due to many bugs in the implementation, now this stabilization is possible primarily due to work of @arielb1 who [wrote the new MIR-based implementation of slice patterns](#32202) and @mikhail-m1 who [fixed one remaining class of codegen issues](#47926).

Reference PR rust-lang/reference#259
cc #23121
fixes #48836
  • Loading branch information
bors committed Mar 20, 2018
2 parents 6bfa7d0 + 7c90189 commit b991723
Show file tree
Hide file tree
Showing 75 changed files with 124 additions and 226 deletions.

This file was deleted.

28 changes: 16 additions & 12 deletions src/doc/unstable-book/src/language-features/slice-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,29 @@ The tracking issue for this feature is: [#23121]

[#23121]: https://github.com/rust-lang/rust/issues/23121

See also
[`advanced_slice_patterns`](language-features/advanced-slice-patterns.html).

------------------------


If you want to match against a slice or array, you can use `&` with the
`slice_patterns` feature:
The `slice_patterns` feature gate lets you use `..` to indicate any number of
elements inside a pattern matching a slice. This wildcard can only be used once
for a given array. If there's an pattern before the `..`, the subslice will be
matched against that pattern. For example:

```rust
#![feature(slice_patterns)]

fn is_symmetric(list: &[u32]) -> bool {
match list {
&[] | &[_] => true,
&[x, ref inside.., y] if x == y => is_symmetric(inside),
&[..] => false,
}
}

fn main() {
let v = vec!["match_this", "1"];
let sym = &[0, 1, 4, 2, 4, 1, 0];
assert!(is_symmetric(sym));

match &v[..] {
&["match_this", second] => println!("The second element is {}", second),
_ => {},
}
let not_sym = &[0, 1, 7, 2, 4, 1, 0];
assert!(!is_symmetric(not_sym));
}
```

1 change: 0 additions & 1 deletion src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@
#![feature(ptr_internals)]
#![feature(rustc_attrs)]
#![feature(slice_get_slice)]
#![feature(slice_patterns)]
#![feature(slice_rsplit)]
#![feature(specialization)]
#![feature(staged_api)]
Expand Down
1 change: 0 additions & 1 deletion src/libcore/benches/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#![deny(warnings)]

#![feature(flt2dec)]
#![feature(slice_patterns)]
#![feature(test)]

extern crate core;
Expand Down
1 change: 1 addition & 0 deletions src/libcore/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#![feature(raw)]
#![feature(refcell_replace_swap)]
#![feature(slice_patterns)]
#![feature(slice_rotate)]
#![feature(sort_internals)]
#![feature(specialization)]
#![feature(step_trait)]
Expand Down
1 change: 0 additions & 1 deletion src/librustc/benches/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

#![deny(warnings)]

#![feature(slice_patterns)]
#![feature(test)]

extern crate test;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_apfloat/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
#![forbid(unsafe_code)]

#![feature(i128_type)]
#![feature(slice_patterns)]
#![cfg_attr(stage0, feature(slice_patterns))]
#![feature(try_from)]

// See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
Expand Down
1 change: 0 additions & 1 deletion src/librustc_const_eval/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#![deny(warnings)]

#![feature(rustc_diagnostic_macros)]
#![feature(slice_patterns)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(macro_lifetime_matcher)]
Expand Down
1 change: 0 additions & 1 deletion src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#![feature(macro_vis_matcher)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(slice_patterns)]
#![cfg_attr(stage0, feature(never_type))]

#[macro_use]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#![feature(libc)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(slice_patterns)]
#![cfg_attr(stage0, feature(slice_patterns))]
#![feature(conservative_impl_trait)]
#![feature(optin_builtin_traits)]
#![feature(inclusive_range_fields)]
Expand Down
1 change: 0 additions & 1 deletion src/librustc_trans_utils/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#![feature(i128_type)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(slice_patterns)]
#![feature(conservative_impl_trait)]

extern crate ar;
Expand Down
6 changes: 0 additions & 6 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3559,8 +3559,6 @@ elements in the array being matched.
Example of erroneous code:
```compile_fail,E0527
#![feature(slice_patterns)]
let r = &[1, 2, 3, 4];
match r {
&[a, b] => { // error: pattern requires 2 elements but array
Expand Down Expand Up @@ -3625,8 +3623,6 @@ An array or slice pattern was matched against some other type.
Example of erroneous code:
```compile_fail,E0529
#![feature(slice_patterns)]
let r: f32 = 1.0;
match r {
[a, b] => { // error: expected an array or slice, found `f32`
Expand All @@ -3639,8 +3635,6 @@ Ensure that the pattern and the expression being matched on are of consistent
types:
```
#![feature(slice_patterns)]
let r = [1.0, 2.0];
match r {
[a, b] => { // ok!
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ This API is completely unstable and subject to change.

#![allow(non_camel_case_types)]

#![feature(advanced_slice_patterns)]
#![cfg_attr(stage0, feature(advanced_slice_patterns))]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(conservative_impl_trait)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#![feature(box_syntax)]
#![feature(fs_read_write)]
#![feature(set_stdio)]
#![feature(slice_patterns)]
#![cfg_attr(stage0, feature(slice_patterns))]
#![feature(test)]
#![feature(unicode)]
#![feature(vec_remove_item)]
Expand Down
16 changes: 5 additions & 11 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ declare_features! (
// rustc internal
(active, rustc_diagnostic_macros, "1.0.0", None, None),
(active, rustc_const_unstable, "1.0.0", None, None),
(active, advanced_slice_patterns, "1.0.0", Some(23121), None),
(active, box_syntax, "1.0.0", Some(27779), None),
(active, placement_in_syntax, "1.0.0", Some(27779), None),
(active, unboxed_closures, "1.0.0", Some(29625), None),
Expand Down Expand Up @@ -474,6 +473,8 @@ declare_features! (
(removed, allocator, "1.0.0", None, None),
// Allows the `#[simd]` attribute -- removed in favor of `#[repr(simd)]`
(removed, simd, "1.0.0", Some(27731), None),
// Merged into `slice_patterns`
(removed, advanced_slice_patterns, "1.0.0", Some(23121), None),
);

declare_features! (
Expand Down Expand Up @@ -1655,17 +1656,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {

fn visit_pat(&mut self, pattern: &'a ast::Pat) {
match pattern.node {
PatKind::Slice(_, Some(_), ref last) if !last.is_empty() => {
gate_feature_post!(&self, advanced_slice_patterns,
pattern.span,
"multiple-element slice matches anywhere \
but at the end of a slice (e.g. \
`[0, ..xs, 0]`) are experimental")
}
PatKind::Slice(..) => {
PatKind::Slice(_, Some(ref subslice), _) => {
gate_feature_post!(&self, slice_patterns,
pattern.span,
"slice pattern syntax is experimental");
subslice.span,
"syntax for subslices in slice patterns is not yet stabilized");
}
PatKind::Box(..) => {
gate_feature_post!(&self, box_patterns,
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3618,7 +3618,7 @@ impl<'a> Parser<'a> {
slice = Some(P(Pat {
id: ast::DUMMY_NODE_ID,
node: PatKind::Wild,
span: self.span,
span: self.prev_span,
}));
before_slice = false;
}
Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
//[mir]compile-flags: -Z borrowck=mir

#![feature(slice_patterns)]
#![feature(advanced_slice_patterns)]

pub struct Foo {
x: u32
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

// Test that immutable pattern bindings cannot be reassigned.

#![feature(slice_patterns)]

enum E {
Foo(isize)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir

#![feature(box_syntax, slice_patterns, advanced_slice_patterns)]
#![feature(box_syntax)]
#![feature(slice_patterns)]

fn move_out_from_begin_and_end() {
let a = [box 1, box 2];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(advanced_slice_patterns)]
#![feature(slice_patterns)]

fn a<'a>() -> &'a [isize] {
Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/issue-12369.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// except according to those terms.

#![feature(slice_patterns)]
#![allow(unused_variables)]
#![deny(unreachable_patterns)]

fn main() {
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-13482-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

// compile-flags:-Z verbose

#![feature(slice_patterns)]

fn main() {
let x = [1,2];
let y = match x {
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-13482.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(slice_patterns)]

fn main() {
let x = [1,2];
let y = match x {
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-15381.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(slice_patterns)]

fn main() {
let values: Vec<u8> = vec![1,2,3,4,5,6,7,8];

Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/issue-41255.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

// Matching against float literals should result in a linter error

#![feature(slice_patterns)]
#![feature(exclusive_range_pattern)]
#![allow(unused)]
#![forbid(illegal_floating_point_literal_pattern)]
Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/issue-6804.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

// Matching against NaN should result in a warning

#![feature(slice_patterns)]
#![allow(unused)]
#![deny(illegal_floating_point_literal_pattern)]

Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/match-byte-array-patterns-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(advanced_slice_patterns, slice_patterns)]

fn main() {
let buf = &[0, 1, 2, 3];

Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/match-byte-array-patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(advanced_slice_patterns, slice_patterns)]
#![feature(slice_patterns)]
#![deny(unreachable_patterns)]

fn main() {
Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/match-ref-ice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(slice_patterns)]
#![deny(unreachable_patterns)]

// The arity of `ref x` is always 1. If the pattern is compared to some non-structural type whose
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/match-slice-patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(advanced_slice_patterns, slice_patterns)]
#![feature(slice_patterns)]

fn check(list: &[Option<()>]) {
match list {
Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/match-vec-fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(slice_patterns)]
#![deny(unreachable_patterns)]

fn a() {
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/match-vec-mismatch-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(slice_patterns)]

fn main() {
match () {
[()] => { }
Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/match-vec-unreachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

#![feature(slice_patterns)]
#![deny(unreachable_patterns)]
#![allow(unused_variables)]

fn main() {
let x: Vec<(isize, isize)> = Vec::new();
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/move-out-of-slice-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(slice_patterns, box_patterns)]
#![feature(box_patterns)]

struct A;

Expand Down
Loading

0 comments on commit b991723

Please sign in to comment.