Skip to content

Commit

Permalink
Auto merge of #44108 - mattico:match-pipe, r=petrochenkov
Browse files Browse the repository at this point in the history
Implement RFC 1925

cc #44101
  • Loading branch information
bors committed Sep 2, 2017
2 parents 744dd6c + 22ca03b commit 6f66730
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# `match_beginning_vert`

The tracking issue for this feature is [#44101].

With this feature enabled, you are allowed to add a '|' to the beginning of a
match arm:

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

enum Foo { A, B, C }

fn main() {
let x = Foo::A;
match x {
| Foo::A
| Foo::B => println!("AB"),
| Foo::C => println!("C"),
}
}
```

[#44101]: https://github.com/rust-lang/rust/issues/44101
1 change: 1 addition & 0 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,7 @@ pub struct Arm {
pub pats: Vec<P<Pat>>,
pub guard: Option<P<Expr>>,
pub body: P<Expr>,
pub beginning_vert: Option<Span>, // For RFC 1925 feature gate
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
Expand Down
3 changes: 2 additions & 1 deletion src/libsyntax/ext/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
attrs: vec![],
pats,
guard: None,
body: expr
body: expr,
beginning_vert: None,
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,9 @@ declare_features! (

// allow `#[must_use]` on functions (RFC 1940)
(active, fn_must_use, "1.21.0", Some(43302)),

// allow '|' at beginning of match arms (RFC 1925)
(active, match_beginning_vert, "1.21.0", Some(44101)),
);

declare_features! (
Expand Down Expand Up @@ -1435,6 +1438,15 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
visit::walk_expr(self, e);
}

fn visit_arm(&mut self, arm: &'a ast::Arm) {
if let Some(span) = arm.beginning_vert {
gate_feature_post!(&self, match_beginning_vert,
span,
"Use of a '|' at the beginning of a match arm is experimental")
}
visit::walk_arm(self, arm)
}

fn visit_pat(&mut self, pattern: &'a ast::Pat) {
match pattern.node {
PatKind::Slice(_, Some(_), ref last) if !last.is_empty() => {
Expand Down
4 changes: 3 additions & 1 deletion src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,12 +344,14 @@ pub fn fold_thin_attrs<T: Folder>(attrs: ThinVec<Attribute>, fld: &mut T) -> Thi
fold_attrs(attrs.into(), fld).into()
}

pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm, fld: &mut T) -> Arm {
pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body, beginning_vert}: Arm,
fld: &mut T) -> Arm {
Arm {
attrs: fold_attrs(attrs, fld),
pats: pats.move_map(|x| fld.fold_pat(x)),
guard: guard.map(|x| fld.fold_expr(x)),
body: fld.fold_expr(body),
beginning_vert,
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3155,6 +3155,12 @@ impl<'a> Parser<'a> {
maybe_whole!(self, NtArm, |x| x);

let attrs = self.parse_outer_attributes()?;
// Allow a '|' before the pats (RFC 1925)
let beginning_vert = if self.eat(&token::BinOp(token::Or)) {
Some(self.prev_span)
} else {
None
};
let pats = self.parse_pats()?;
let guard = if self.eat_keyword(keywords::If) {
Some(self.parse_expr()?)
Expand All @@ -3178,6 +3184,7 @@ impl<'a> Parser<'a> {
pats,
guard,
body: expr,
beginning_vert,
})
}

Expand Down
36 changes: 36 additions & 0 deletions src/test/compile-fail/feature-gate-match_beginning_vert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[allow(dead_code)]
enum Foo {
A,
B,
C,
D,
E,
}
use Foo::*;

fn main() {
let x = Foo::A;
match x {
| A => println!("A"),
//~^ ERROR: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
| B | C => println!("BC!"),
//~^ ERROR: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
| _ => {},
//~^ ERROR: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
};
match x {
A | B | C => println!("ABC!"),
_ => {},
};
}

0 comments on commit 6f66730

Please sign in to comment.