diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index ebc65e90b47..4316996e4f0 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -540,6 +540,22 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_pat(&mut self, pattern: &'a ast::Pat) { match &pattern.kind { + PatKind::Slice(pats) => { + for pat in pats { + let inner_pat = match &pat.kind { + PatKind::Ident(.., Some(pat)) => pat, + _ => pat, + }; + if let PatKind::Range(Some(_), None, Spanned { .. }) = inner_pat.kind { + gate_feature_post!( + &self, + half_open_range_patterns, + pat.span, + "`X..` patterns in slices are experimental" + ); + } + } + } PatKind::Box(..) => { gate_feature_post!( &self, diff --git a/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem0.rs b/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem0.rs new file mode 100644 index 00000000000..2884a27349f --- /dev/null +++ b/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem0.rs @@ -0,0 +1,16 @@ +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + let xs = [13, 1, 5, 2, 3, 1, 21, 8]; + let [a, b, c, rest @ ..] = xs; + // Consider the following example: + assert!(a == 13 && b == 1 && c == 5 && rest.len() == 5); + + // What if we wanted to pull this apart without individually binding a, b, and c? + let [first_three @ ..3, rest @ 2..] = xs; + //~^ pattern requires 2 elements but array has 8 + // This is somewhat unintuitive and makes slice patterns exceedingly verbose. + // We want to stabilize half-open RangeFrom (`X..`) patterns + // but without banning us from using them for a more efficient slice pattern syntax. +} diff --git a/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem0.stderr b/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem0.stderr new file mode 100644 index 00000000000..ec3472a5036 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem0.stderr @@ -0,0 +1,9 @@ +error[E0527]: pattern requires 2 elements but array has 8 + --> $DIR/slice_pattern_syntax_problem0.rs:11:9 + | +LL | let [first_three @ ..3, rest @ 2..] = xs; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 8 elements + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0527`. diff --git a/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs b/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs new file mode 100644 index 00000000000..9e289b591d6 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs @@ -0,0 +1,9 @@ +// Instead of allowing the previous case, maintain the feature gate for slice patterns for now. +fn main() { + let xs = [13, 1, 5, 2, 3, 1, 21, 8]; + let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; + //~^ `X..` patterns in slices are experimental + //~| half-open range patterns are unstable + //~| exclusive range pattern syntax is experimental + //~| exclusive range pattern syntax is experimental +} diff --git a/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr b/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr new file mode 100644 index 00000000000..eadaf877670 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr @@ -0,0 +1,39 @@ +error[E0658]: half-open range patterns are unstable + --> $DIR/slice_pattern_syntax_problem1.rs:4:23 + | +LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; + | ^^^ + | + = note: see issue #67264 for more information + = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable + +error[E0658]: `X..` patterns in slices are experimental + --> $DIR/slice_pattern_syntax_problem1.rs:4:10 + | +LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; + | ^^^^^^^ + | + = note: see issue #67264 for more information + = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable + +error[E0658]: exclusive range pattern syntax is experimental + --> $DIR/slice_pattern_syntax_problem1.rs:4:23 + | +LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; + | ^^^ + | + = note: see issue #37854 for more information + = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable + +error[E0658]: exclusive range pattern syntax is experimental + --> $DIR/slice_pattern_syntax_problem1.rs:4:32 + | +LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; + | ^^^^ + | + = note: see issue #37854 for more information + = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem2.rs b/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem2.rs new file mode 100644 index 00000000000..6e7df309491 --- /dev/null +++ b/src/test/ui/half-open-range-patterns/slice_pattern_syntax_problem2.rs @@ -0,0 +1,10 @@ +// run-pass + +fn main() { + let xs = [13, 1, 5, 2, 3, 1, 21, 8]; + if let [3..=14, ..] = xs { + /* this variant must pass for now, unfortunately. + * This test is included here to help inform a future plan for these. + */ + }; +}