Add postfix-match experimental feature
Co-authored-by: Josh Stone <jistone@redhat.com>
This commit is contained in:
parent
62415e2a95
commit
68a58f255a
@ -565,6 +565,7 @@ macro_rules! gate_all {
|
||||
gate_all!(generic_const_items, "generic const items are experimental");
|
||||
gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
|
||||
gate_all!(fn_delegation, "functions delegation is not yet fully implemented");
|
||||
gate_all!(postfix_match, "postfix match is experimental");
|
||||
|
||||
if !visitor.features.never_patterns {
|
||||
if let Some(spans) = spans.get(&sym::never_patterns) {
|
||||
|
@ -555,6 +555,8 @@ pub fn internal(&self, feature: Symbol) -> bool {
|
||||
(unstable, offset_of_nested, "1.77.0", Some(120140)),
|
||||
/// Allows using `#[optimize(X)]`.
|
||||
(unstable, optimize_attribute, "1.34.0", Some(54882)),
|
||||
/// Allows postfix match `expr.match { ... }`
|
||||
(unstable, postfix_match, "CURRENT_RUSTC_VERSION", Some(121618)),
|
||||
/// Allows macro attributes on expressions, statements and non-inline modules.
|
||||
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
|
||||
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
|
||||
|
@ -1375,6 +1375,12 @@ fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Exp
|
||||
return Ok(self.mk_await_expr(self_arg, lo));
|
||||
}
|
||||
|
||||
if self.eat_keyword(kw::Match) {
|
||||
let match_span = self.prev_token.span;
|
||||
self.psess.gated_spans.gate(sym::postfix_match, match_span);
|
||||
return self.parse_match_block(lo, match_span, self_arg);
|
||||
}
|
||||
|
||||
let fn_span_lo = self.token.span;
|
||||
let mut seg = self.parse_path_segment(PathStyle::Expr, None)?;
|
||||
self.check_trailing_angle_brackets(&seg, &[&token::OpenDelim(Delimiter::Parenthesis)]);
|
||||
@ -2889,8 +2895,19 @@ pub(crate) fn eat_label(&mut self) -> Option<Label> {
|
||||
/// Parses a `match ... { ... }` expression (`match` token already eaten).
|
||||
fn parse_expr_match(&mut self) -> PResult<'a, P<Expr>> {
|
||||
let match_span = self.prev_token.span;
|
||||
let lo = self.prev_token.span;
|
||||
let scrutinee = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
|
||||
|
||||
self.parse_match_block(match_span, match_span, scrutinee)
|
||||
}
|
||||
|
||||
/// Parses a `match expr { ... }` or a `expr.match { ... }` expression.
|
||||
/// This is after the match token and scrutinee are eaten
|
||||
fn parse_match_block(
|
||||
&mut self,
|
||||
lo: Span,
|
||||
match_span: Span,
|
||||
scrutinee: P<Expr>,
|
||||
) -> PResult<'a, P<Expr>> {
|
||||
if let Err(mut e) = self.expect(&token::OpenDelim(Delimiter::Brace)) {
|
||||
if self.token == token::Semi {
|
||||
e.span_suggestion_short(
|
||||
|
@ -1319,6 +1319,7 @@
|
||||
poll,
|
||||
poll_next,
|
||||
post_dash_lto: "post-lto",
|
||||
postfix_match,
|
||||
powerpc_target_feature,
|
||||
powf128,
|
||||
powf16,
|
||||
|
22
src/doc/unstable-book/src/language-features/postfix-match.md
Normal file
22
src/doc/unstable-book/src/language-features/postfix-match.md
Normal file
@ -0,0 +1,22 @@
|
||||
# `postfix-match`
|
||||
|
||||
`postfix-match` adds the feature for matching upon values postfix
|
||||
the expressions that generate the values.
|
||||
|
||||
```rust,edition2021
|
||||
#![feature(postfix_match)]
|
||||
|
||||
enum Foo {
|
||||
Bar,
|
||||
Baz
|
||||
}
|
||||
|
||||
fn get_foo() -> Foo {
|
||||
Foo::Bar
|
||||
}
|
||||
|
||||
get_foo().match {
|
||||
Foo::Bar => {},
|
||||
Foo::Baz => panic!(),
|
||||
}
|
||||
```
|
17
tests/ui/feature-gates/feature-gate-postfix_match.rs
Normal file
17
tests/ui/feature-gates/feature-gate-postfix_match.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Testing that postfix match doesn't work without enabling the feature
|
||||
|
||||
fn main() {
|
||||
let val = Some(42);
|
||||
|
||||
val.match { //~ ERROR postfix match is experimental
|
||||
Some(42) => "the answer to life, the universe, and everything",
|
||||
_ => "might be the answer to something"
|
||||
};
|
||||
|
||||
// Test that the gate works behind a cfg
|
||||
#[cfg(FALSE)]
|
||||
val.match { //~ ERROR postfix match is experimental
|
||||
Some(42) => "the answer to life, the universe, and everything",
|
||||
_ => "might be the answer to something"
|
||||
};
|
||||
}
|
23
tests/ui/feature-gates/feature-gate-postfix_match.stderr
Normal file
23
tests/ui/feature-gates/feature-gate-postfix_match.stderr
Normal file
@ -0,0 +1,23 @@
|
||||
error[E0658]: postfix match is experimental
|
||||
--> $DIR/feature-gate-postfix_match.rs:6:9
|
||||
|
|
||||
LL | val.match {
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #121618 <https://github.com/rust-lang/rust/issues/121618> for more information
|
||||
= help: add `#![feature(postfix_match)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: postfix match is experimental
|
||||
--> $DIR/feature-gate-postfix_match.rs:13:9
|
||||
|
|
||||
LL | val.match {
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #121618 <https://github.com/rust-lang/rust/issues/121618> for more information
|
||||
= help: add `#![feature(postfix_match)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
16
tests/ui/match/postfix-match/pf-match-chain.rs
Normal file
16
tests/ui/match/postfix-match/pf-match-chain.rs
Normal file
@ -0,0 +1,16 @@
|
||||
//@ run-pass
|
||||
|
||||
#![feature(postfix_match)]
|
||||
|
||||
fn main() {
|
||||
1.match {
|
||||
2 => Some(0),
|
||||
_ => None,
|
||||
}.match {
|
||||
None => Ok(true),
|
||||
Some(_) => Err("nope")
|
||||
}.match {
|
||||
Ok(_) => (),
|
||||
Err(_) => panic!()
|
||||
}
|
||||
}
|
7
tests/ui/match/postfix-match/pf-match-exhaustiveness.rs
Normal file
7
tests/ui/match/postfix-match/pf-match-exhaustiveness.rs
Normal file
@ -0,0 +1,7 @@
|
||||
#![feature(postfix_match)]
|
||||
|
||||
fn main() {
|
||||
Some(1).match { //~ non-exhaustive patterns
|
||||
None => {},
|
||||
}
|
||||
}
|
21
tests/ui/match/postfix-match/pf-match-exhaustiveness.stderr
Normal file
21
tests/ui/match/postfix-match/pf-match-exhaustiveness.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
|
||||
--> $DIR/pf-match-exhaustiveness.rs:4:5
|
||||
|
|
||||
LL | Some(1).match {
|
||||
| ^^^^^^^ pattern `Some(_)` not covered
|
||||
|
|
||||
note: `Option<i32>` defined here
|
||||
--> $SRC_DIR/core/src/option.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/option.rs:LL:COL
|
||||
|
|
||||
= note: not covered
|
||||
= note: the matched value is of type `Option<i32>`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ None => {},
|
||||
LL ~ Some(_) => todo!(),
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0004`.
|
15
tests/ui/match/postfix-match/pf-match-types.rs
Normal file
15
tests/ui/match/postfix-match/pf-match-types.rs
Normal file
@ -0,0 +1,15 @@
|
||||
#![feature(postfix_match)]
|
||||
|
||||
fn main() {
|
||||
Some(10).match {
|
||||
//~^ NOTE `match` arms have incompatible types
|
||||
Some(5) => false,
|
||||
//~^ NOTE this is found to be of type `bool`
|
||||
Some(2) => true,
|
||||
//~^ NOTE this is found to be of type `bool`
|
||||
None => (),
|
||||
//~^ ERROR `match` arms have incompatible types
|
||||
//~| NOTE expected `bool`, found `()`
|
||||
_ => true
|
||||
}
|
||||
}
|
21
tests/ui/match/postfix-match/pf-match-types.stderr
Normal file
21
tests/ui/match/postfix-match/pf-match-types.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error[E0308]: `match` arms have incompatible types
|
||||
--> $DIR/pf-match-types.rs:10:20
|
||||
|
|
||||
LL | / Some(10).match {
|
||||
LL | |
|
||||
LL | | Some(5) => false,
|
||||
| | ----- this is found to be of type `bool`
|
||||
LL | |
|
||||
LL | | Some(2) => true,
|
||||
| | ---- this is found to be of type `bool`
|
||||
LL | |
|
||||
LL | | None => (),
|
||||
| | ^^ expected `bool`, found `()`
|
||||
... |
|
||||
LL | | _ => true
|
||||
LL | | }
|
||||
| |_____- `match` arms have incompatible types
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
62
tests/ui/match/postfix-match/postfix-match.rs
Normal file
62
tests/ui/match/postfix-match/postfix-match.rs
Normal file
@ -0,0 +1,62 @@
|
||||
//@ run-pass
|
||||
|
||||
#![feature(postfix_match)]
|
||||
|
||||
struct Bar {
|
||||
foo: u8,
|
||||
baz: u8,
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let thing = Some("thing");
|
||||
|
||||
thing.match {
|
||||
Some("nothing") => {},
|
||||
Some(text) if text.eq_ignore_ascii_case("tapir") => {},
|
||||
Some("true") | Some("false") => {},
|
||||
Some("thing") => {},
|
||||
Some(_) => {},
|
||||
None => {}
|
||||
};
|
||||
|
||||
let num = 2u8;
|
||||
|
||||
num.match {
|
||||
0 => {},
|
||||
1..=5 => {},
|
||||
_ => {},
|
||||
};
|
||||
|
||||
let slic = &[1, 2, 3, 4][..];
|
||||
|
||||
slic.match {
|
||||
[1] => {},
|
||||
[2, _tail @ ..] => {},
|
||||
[1, _] => {},
|
||||
_ => {},
|
||||
};
|
||||
|
||||
slic[0].match {
|
||||
1 => 0,
|
||||
i => i,
|
||||
};
|
||||
|
||||
let out = (1, 2).match {
|
||||
(1, 3) => 0,
|
||||
(_, 1) => 0,
|
||||
(1, i) => i,
|
||||
_ => 3,
|
||||
};
|
||||
assert!(out == 2);
|
||||
|
||||
let strct = Bar {
|
||||
foo: 3,
|
||||
baz: 4
|
||||
};
|
||||
|
||||
strct.match {
|
||||
Bar { foo: 1, .. } => {},
|
||||
Bar { baz: 2, .. } => {},
|
||||
_ => (),
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user