mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
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 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
|||||||
gate_all!(generic_const_items, "generic const items are experimental");
|
gate_all!(generic_const_items, "generic const items are experimental");
|
||||||
gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
|
gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
|
||||||
gate_all!(fn_delegation, "functions delegation is 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 !visitor.features.never_patterns {
|
||||||
if let Some(spans) = spans.get(&sym::never_patterns) {
|
if let Some(spans) = spans.get(&sym::never_patterns) {
|
||||||
|
@ -555,6 +555,8 @@ declare_features! (
|
|||||||
(unstable, offset_of_nested, "1.77.0", Some(120140)),
|
(unstable, offset_of_nested, "1.77.0", Some(120140)),
|
||||||
/// Allows using `#[optimize(X)]`.
|
/// Allows using `#[optimize(X)]`.
|
||||||
(unstable, optimize_attribute, "1.34.0", Some(54882)),
|
(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.
|
/// Allows macro attributes on expressions, statements and non-inline modules.
|
||||||
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
|
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
|
||||||
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
|
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
|
||||||
|
@ -1375,6 +1375,12 @@ impl<'a> Parser<'a> {
|
|||||||
return Ok(self.mk_await_expr(self_arg, lo));
|
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 fn_span_lo = self.token.span;
|
||||||
let mut seg = self.parse_path_segment(PathStyle::Expr, None)?;
|
let mut seg = self.parse_path_segment(PathStyle::Expr, None)?;
|
||||||
self.check_trailing_angle_brackets(&seg, &[&token::OpenDelim(Delimiter::Parenthesis)]);
|
self.check_trailing_angle_brackets(&seg, &[&token::OpenDelim(Delimiter::Parenthesis)]);
|
||||||
@ -2889,8 +2895,19 @@ impl<'a> Parser<'a> {
|
|||||||
/// Parses a `match ... { ... }` expression (`match` token already eaten).
|
/// Parses a `match ... { ... }` expression (`match` token already eaten).
|
||||||
fn parse_expr_match(&mut self) -> PResult<'a, P<Expr>> {
|
fn parse_expr_match(&mut self) -> PResult<'a, P<Expr>> {
|
||||||
let match_span = self.prev_token.span;
|
let match_span = self.prev_token.span;
|
||||||
let lo = self.prev_token.span;
|
|
||||||
let scrutinee = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
|
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 let Err(mut e) = self.expect(&token::OpenDelim(Delimiter::Brace)) {
|
||||||
if self.token == token::Semi {
|
if self.token == token::Semi {
|
||||||
e.span_suggestion_short(
|
e.span_suggestion_short(
|
||||||
|
@ -1319,6 +1319,7 @@ symbols! {
|
|||||||
poll,
|
poll,
|
||||||
poll_next,
|
poll_next,
|
||||||
post_dash_lto: "post-lto",
|
post_dash_lto: "post-lto",
|
||||||
|
postfix_match,
|
||||||
powerpc_target_feature,
|
powerpc_target_feature,
|
||||||
powf128,
|
powf128,
|
||||||
powf16,
|
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