mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 06:51:58 +00:00
Auto merge of #83918 - workingjubilee:stable-rangefrom-pat, r=joshtriplett
Stabilize "RangeFrom" patterns in 1.55 Implements a partial stabilization of #67264 and #37854. Reference PR: https://github.com/rust-lang/reference/pull/900 # Stabilization Report This stabilizes the `X..` pattern, shown as such, offering an exhaustive match for unsigned integers: ```rust match x as u32 { 0 => println!("zero!"), 1.. => println!("positive number!"), } ``` Currently if a Rust author wants to write such a match on an integer, they must use `1..={integer}::MAX` . By allowing a "RangeFrom" style pattern, this simplifies the match to not require the MAX path and thus not require specifically repeating the type inside the match, allowing for easier refactoring. This is particularly useful for instances like the above case, where different behavior on "0" vs. "1 or any positive number" is desired, and the actual MAX is unimportant. Notably, this excepts slice patterns which include half-open ranges from stabilization, as the wisdom of those is still subject to some debate. ## Practical Applications Instances of this specific usage have appeared in the compiler:16143d1067/compiler/rustc_middle/src/ty/inhabitedness/mod.rs (L219)
673d0db5e3/compiler/rustc_ty_utils/src/ty.rs (L524)
And I have noticed there are also a handful of "in the wild" users who have deployed it to similar effect, especially in the case of rejecting any value of a certain number or greater. It simply makes it much more ergonomic to write an irrefutable match, as done in Katholieke Universiteit Leuven's [SCALE and MAMBA project](05e5db00d5/WebAssembly/scale_std/src/fixed_point.rs (L685-L695)
). ## Tests There were already many tests in [src/test/ui/half-open-range/patterns](90a2e5e3fe/src/test/ui/half-open-range-patterns
), as well as [generic pattern tests that test the `exclusive_range_pattern` feature](673d0db5e3/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs
), many dating back to the feature's introduction and remaining standing to this day. However, this stabilization comes with some additional tests to explore the... sometimes interesting behavior of interactions with other patterns. e.g. There is, at least, a mild diagnostic improvement in some edge cases, because before now, the pattern `0..=(5+1)` encounters the `half_open_range_patterns` feature gate and can thus emit the request to enable the feature flag, while also emitting the "inclusive range with no end" diagnostic. There is no intent to allow an `X..=` pattern that I am aware of, so removing the flag request is a strict improvement. The arrival of the `J | K` "or" pattern also enables some odd formations. Some of the behavior tested for here is derived from experiments in this [Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=58777b3c715c85165ac4a70d93efeefc) example, linked at https://github.com/rust-lang/rust/issues/67264#issuecomment-812770692, which may be useful to reference to observe the current behavior more closely. In addition tests constituting an explanation of the "slicing range patterns" syntax issue are included in this PR. ## Desiderata The exclusive range patterns and half-open range patterns are fairly strongly requested by many authors, as they make some patterns much more natural to write, but there is disagreement regarding the "closed" exclusive range pattern or the "RangeTo" pattern, especially where it creates "off by one" gaps in the presence of a "catch-all" wildcard case. Also, there are obviously no range analyses in place that will force diagnostics for e.g. highly overlapping matches. I believe these should be warned on, ideally, and I think it would be reasonable to consider such a blocker to stabilizing this feature, but there is no technical issue with the feature as-is from the purely syntactic perspective as such overlapping or missed matches can already be generated today with such a catch-all case. And part of the "point" of the feature, at least from my view, is to make it easier to omit wildcard matches: a pattern with such an "open" match produces an irrefutable match and does not need the wild card case, making it easier to benefit from exhaustiveness checking. ## History - Implemented: - Partially via exclusive ranges: https://github.com/rust-lang/rust/pull/35712 - Fully with half-open ranges: https://github.com/rust-lang/rust/pull/67258 - Unresolved Questions: - The precedence concerns of https://github.com/rust-lang/rust/pull/48501 were considered as likely requiring adjustment but probably wanting a uniform consistent change across all pattern styles, given https://github.com/rust-lang/rust/issues/67264#issuecomment-720711656, but it is still unknown what changes might be desired - How we want to handle slice patterns in ranges seems to be an open question still, as witnessed in the discussion of this PR! I checked but I couldn't actually find an RFC for this, and given "approved provisionally by lang team without an RFC", I believe this might require an RFC before it can land? Unsure of procedure here, on account of this being stabilizing a subset of a feature of syntax. r? `@scottmcm`
This commit is contained in:
commit
0d76b73745
@ -677,7 +677,9 @@ pub enum BindingMode {
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum RangeEnd {
|
||||
/// `..=` or `...`
|
||||
Included(RangeSyntax),
|
||||
/// `..`
|
||||
Excluded,
|
||||
}
|
||||
|
||||
@ -689,6 +691,7 @@ pub enum RangeSyntax {
|
||||
DotDotEq,
|
||||
}
|
||||
|
||||
/// All the different flavors of pattern that Rust recognizes.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum PatKind {
|
||||
/// Represents a wildcard pattern (`_`).
|
||||
@ -729,7 +732,7 @@ pub enum PatKind {
|
||||
/// A literal.
|
||||
Lit(P<Expr>),
|
||||
|
||||
/// A range pattern (e.g., `1...2`, `1..=2` or `1..2`).
|
||||
/// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
|
||||
Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
|
||||
|
||||
/// A slice pattern `[a, b, c]`.
|
||||
|
@ -565,6 +565,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,
|
||||
@ -573,7 +589,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
"box pattern syntax is experimental"
|
||||
);
|
||||
}
|
||||
PatKind::Range(_, _, Spanned { node: RangeEnd::Excluded, .. }) => {
|
||||
PatKind::Range(_, Some(_), Spanned { node: RangeEnd::Excluded, .. }) => {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
exclusive_range_pattern,
|
||||
|
@ -715,7 +715,6 @@ impl<'a> Parser<'a> {
|
||||
} else if self.eat(&token::DotDotEq) {
|
||||
RangeEnd::Included(RangeSyntax::DotDotEq)
|
||||
} else if self.eat(&token::DotDot) {
|
||||
self.sess.gated_spans.gate(sym::exclusive_range_pattern, self.prev_token.span);
|
||||
RangeEnd::Excluded
|
||||
} else {
|
||||
return None;
|
||||
@ -735,7 +734,6 @@ impl<'a> Parser<'a> {
|
||||
Some(self.parse_pat_range_end()?)
|
||||
} else {
|
||||
// Parsing e.g. `X..`.
|
||||
self.sess.gated_spans.gate(sym::half_open_range_patterns, begin.span.to(re.span));
|
||||
if let RangeEnd::Included(_) = re.node {
|
||||
// FIXME(Centril): Consider semantic errors instead in `ast_validation`.
|
||||
// Possibly also do this for `X..=` in *expression* contexts.
|
||||
|
@ -0,0 +1,26 @@
|
||||
# `exclusive_range_pattern`
|
||||
|
||||
The tracking issue for this feature is: [#37854].
|
||||
|
||||
|
||||
[#67264]: https://github.com/rust-lang/rust/issues/67264
|
||||
[#37854]: https://github.com/rust-lang/rust/issues/37854
|
||||
-----
|
||||
|
||||
The `exclusive_range_pattern` feature allows non-inclusive range
|
||||
patterns (`0..10`) to be used in appropriate pattern matching
|
||||
contexts. It also can be combined with `#![feature(half_open_range_patterns]`
|
||||
to be able to use RangeTo patterns (`..10`).
|
||||
|
||||
It also enabled RangeFrom patterns but that has since been
|
||||
stabilized.
|
||||
|
||||
```rust
|
||||
#![feature(exclusive_range_pattern)]
|
||||
let x = 5;
|
||||
match x {
|
||||
0..10 => println!("single digit"),
|
||||
10 => println!("ten isn't part of the above range"),
|
||||
_ => println!("nor is everything else.")
|
||||
}
|
||||
```
|
@ -0,0 +1,27 @@
|
||||
# `half_open_range_patterns`
|
||||
|
||||
The tracking issue for this feature is: [#67264]
|
||||
It is part of the `#![exclusive_range_pattern]` feature,
|
||||
tracked at [#37854].
|
||||
|
||||
[#67264]: https://github.com/rust-lang/rust/issues/67264
|
||||
[#37854]: https://github.com/rust-lang/rust/issues/37854
|
||||
-----
|
||||
|
||||
The `half_open_range_patterns` feature allows RangeTo patterns
|
||||
(`..10`) to be used in appropriate pattern matching contexts.
|
||||
This requires also enabling the `exclusive_range_pattern` feature.
|
||||
|
||||
It also enabled RangeFrom patterns but that has since been
|
||||
stabilized.
|
||||
|
||||
```rust
|
||||
#![feature(half_open_range_patterns)]
|
||||
#![feature(exclusive_range_pattern)]
|
||||
let x = 5;
|
||||
match x {
|
||||
..0 => println!("negative!"), // "RangeTo" pattern. Unstable.
|
||||
0 => println!("zero!"),
|
||||
1.. => println!("positive!"), // "RangeFrom" pattern. Stable.
|
||||
}
|
||||
```
|
@ -11,12 +11,8 @@ fn foo() {
|
||||
//~| ERROR range-to patterns with `...` are not allowed
|
||||
if let ..5 = 0 {}
|
||||
//~^ ERROR half-open range patterns are unstable
|
||||
if let 5.. = 0 {}
|
||||
//~^ ERROR half-open range patterns are unstable
|
||||
if let 5..= = 0 {}
|
||||
//~^ ERROR half-open range patterns are unstable
|
||||
//~| ERROR inclusive range with no end
|
||||
//~^ ERROR inclusive range with no end
|
||||
if let 5... = 0 {}
|
||||
//~^ ERROR half-open range patterns are unstable
|
||||
//~| ERROR inclusive range with no end
|
||||
//~^ ERROR inclusive range with no end
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ LL | if let ...5 = 0 {}
|
||||
| ^^^ help: use `..=` instead
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:16:13
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:14:13
|
||||
|
|
||||
LL | if let 5..= = 0 {}
|
||||
| ^^^ help: use `..` instead
|
||||
@ -13,7 +13,7 @@ LL | if let 5..= = 0 {}
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:19:13
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:16:13
|
||||
|
|
||||
LL | if let 5... = 0 {}
|
||||
| ^^^ help: use `..` instead
|
||||
@ -47,34 +47,7 @@ LL | if let ..5 = 0 {}
|
||||
= note: see issue #67264 <https://github.com/rust-lang/rust/issues/67264> for more information
|
||||
= help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: half-open range patterns are unstable
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:14:12
|
||||
|
|
||||
LL | if let 5.. = 0 {}
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #67264 <https://github.com/rust-lang/rust/issues/67264> for more information
|
||||
= help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: half-open range patterns are unstable
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:16:12
|
||||
|
|
||||
LL | if let 5..= = 0 {}
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #67264 <https://github.com/rust-lang/rust/issues/67264> for more information
|
||||
= help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: half-open range patterns are unstable
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:19:12
|
||||
|
|
||||
LL | if let 5... = 0 {}
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #67264 <https://github.com/rust-lang/rust/issues/67264> for more information
|
||||
= help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0586, E0658.
|
||||
For more information about an error, try `rustc --explain E0586`.
|
||||
|
@ -0,0 +1,32 @@
|
||||
// run-pass
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(exclusive_range_pattern)]
|
||||
#![feature(half_open_range_patterns)]
|
||||
#![feature(inline_const)]
|
||||
|
||||
fn main() {
|
||||
let mut if_lettable = vec![];
|
||||
let mut first_or = vec![];
|
||||
let mut or_two = vec![];
|
||||
let mut range_from = vec![];
|
||||
let mut bottom = vec![];
|
||||
|
||||
for x in -9 + 1..=(9 - 2) {
|
||||
if let -1..=0 | 2..3 | 4 = x {
|
||||
if_lettable.push(x)
|
||||
}
|
||||
match x {
|
||||
1 | -3..0 => first_or.push(x),
|
||||
y @ (0..5 | 6) => or_two.push(y),
|
||||
y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
|
||||
y @ -5.. => range_from.push(y),
|
||||
y @ ..-7 => assert_eq!(y, -8),
|
||||
y => bottom.push(y),
|
||||
}
|
||||
}
|
||||
assert_eq!(if_lettable, [-1, 0, 2, 4]);
|
||||
assert_eq!(first_or, [-3, -2, -1, 1]);
|
||||
assert_eq!(or_two, [0, 2, 3, 4, 6]);
|
||||
assert_eq!(range_from, [-5, -4, 7]);
|
||||
assert_eq!(bottom, [-7, -6]);
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
fn main() {
|
||||
let mut if_lettable = Vec::<i32>::new();
|
||||
let mut first_or = Vec::<i32>::new();
|
||||
let mut or_two = Vec::<i32>::new();
|
||||
let mut range_from = Vec::<i32>::new();
|
||||
let mut bottom = Vec::<i32>::new();
|
||||
let mut errors_only = Vec::<i32>::new();
|
||||
|
||||
for x in -9 + 1..=(9 - 2) {
|
||||
if let n @ 2..3|4 = x {
|
||||
//~^ error: variable `n` is not bound in all patterns
|
||||
//~| exclusive range pattern syntax is experimental
|
||||
errors_only.push(x);
|
||||
} else if let 2..3 | 4 = x {
|
||||
//~^ exclusive range pattern syntax is experimental
|
||||
if_lettable.push(x);
|
||||
}
|
||||
match x as i32 {
|
||||
0..5+1 => errors_only.push(x),
|
||||
//~^ error: expected one of `=>`, `if`, or `|`, found `+`
|
||||
1 | -3..0 => first_or.push(x),
|
||||
y @ (0..5 | 6) => or_two.push(y),
|
||||
y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
|
||||
y @ -5.. => range_from.push(y),
|
||||
y @ ..-7 => assert_eq!(y, -8),
|
||||
y => bottom.push(y),
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
error: expected one of `=>`, `if`, or `|`, found `+`
|
||||
--> $DIR/range_pat_interactions1.rs:19:17
|
||||
|
|
||||
LL | 0..5+1 => errors_only.push(x),
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error[E0408]: variable `n` is not bound in all patterns
|
||||
--> $DIR/range_pat_interactions1.rs:10:25
|
||||
|
|
||||
LL | if let n @ 2..3|4 = x {
|
||||
| - ^ pattern doesn't bind `n`
|
||||
| |
|
||||
| variable not in all patterns
|
||||
|
||||
error[E0658]: exclusive range pattern syntax is experimental
|
||||
--> $DIR/range_pat_interactions1.rs:10:20
|
||||
|
|
||||
LL | if let n @ 2..3|4 = x {
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/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/range_pat_interactions1.rs:14:23
|
||||
|
|
||||
LL | } else if let 2..3 | 4 = x {
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
|
||||
= help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0408, E0658.
|
||||
For more information about an error, try `rustc --explain E0408`.
|
@ -0,0 +1,21 @@
|
||||
fn main() {
|
||||
let mut first_or = Vec::<i32>::new();
|
||||
let mut or_two = Vec::<i32>::new();
|
||||
let mut range_from = Vec::<i32>::new();
|
||||
let mut bottom = Vec::<i32>::new();
|
||||
let mut errors_only = Vec::<i32>::new();
|
||||
|
||||
for x in -9 + 1..=(9 - 2) {
|
||||
match x as i32 {
|
||||
0..=(5+1) => errors_only.push(x),
|
||||
//~^ error: inclusive range with no end
|
||||
//~| error: expected one of `=>`, `if`, or `|`, found `(`
|
||||
1 | -3..0 => first_or.push(x),
|
||||
y @ (0..5 | 6) => or_two.push(y),
|
||||
y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
|
||||
y @ -5.. => range_from.push(y),
|
||||
y @ ..-7 => assert_eq!(y, -8),
|
||||
y => bottom.push(y),
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/range_pat_interactions2.rs:10:14
|
||||
|
|
||||
LL | 0..=(5+1) => errors_only.push(x),
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found `(`
|
||||
--> $DIR/range_pat_interactions2.rs:10:17
|
||||
|
|
||||
LL | 0..=(5+1) => errors_only.push(x),
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0586`.
|
@ -0,0 +1,24 @@
|
||||
fn main() {
|
||||
let mut first_or = Vec::<i32>::new();
|
||||
let mut or_two = Vec::<i32>::new();
|
||||
let mut range_from = Vec::<i32>::new();
|
||||
let mut bottom = Vec::<i32>::new();
|
||||
|
||||
for x in -9 + 1..=(9 - 2) {
|
||||
match x as i32 {
|
||||
8.. => bottom.push(x),
|
||||
1 | -3..0 => first_or.push(x),
|
||||
//~^ exclusive range pattern syntax is experimental
|
||||
y @ (0..5 | 6) => or_two.push(y),
|
||||
//~^ exclusive range pattern syntax is experimental
|
||||
y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
|
||||
//~^ inline-const is experimental
|
||||
//~| exclusive range pattern syntax is experimental
|
||||
y @ -5.. => range_from.push(y),
|
||||
y @ ..-7 => assert_eq!(y, -8),
|
||||
//~^ half-open range patterns are unstable
|
||||
//~| exclusive range pattern syntax is experimental
|
||||
y => bottom.push(y),
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
error[E0658]: half-open range patterns are unstable
|
||||
--> $DIR/range_pat_interactions3.rs:18:17
|
||||
|
|
||||
LL | y @ ..-7 => assert_eq!(y, -8),
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #67264 <https://github.com/rust-lang/rust/issues/67264> for more information
|
||||
= help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: inline-const is experimental
|
||||
--> $DIR/range_pat_interactions3.rs:14:20
|
||||
|
|
||||
LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
|
||||
= help: add `#![feature(inline_const)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: exclusive range pattern syntax is experimental
|
||||
--> $DIR/range_pat_interactions3.rs:10:17
|
||||
|
|
||||
LL | 1 | -3..0 => first_or.push(x),
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/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/range_pat_interactions3.rs:12:18
|
||||
|
|
||||
LL | y @ (0..5 | 6) => or_two.push(y),
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/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/range_pat_interactions3.rs:14:17
|
||||
|
|
||||
LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/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/range_pat_interactions3.rs:18:17
|
||||
|
|
||||
LL | y @ ..-7 => assert_eq!(y, -8),
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
|
||||
= help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -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.
|
||||
}
|
@ -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`.
|
@ -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
|
||||
}
|
@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
|
@ -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.
|
||||
*/
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user