diff --git a/src/doc/unstable-book/src/language-features/match-beginning-vert.md b/src/doc/unstable-book/src/language-features/match-beginning-vert.md
new file mode 100644
index 00000000000..6ef1ab38e8d
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/match-beginning-vert.md
@@ -0,0 +1,21 @@
+# `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 }
+
+fn main() {
+ let x = Foo::A;
+ match x {
+ | A | B => {},
+ }
+}
+```
+
+[#44101]: https://github.com/rust-lang/rust/issues/44101
\ No newline at end of file
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 925178f8639..720f6cd32bd 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -810,6 +810,7 @@ pub struct Arm {
pub pats: Vec
>,
pub guard: Option
>,
pub body: P,
+ pub beginning_vert: Option, // For RFC 1925 feature gate
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 66df734b328..48d789372a0 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -878,7 +878,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
attrs: vec![],
pats,
guard: None,
- body: expr
+ body: expr,
+ beginning_vert: None,
}
}
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 8251b03632a..adef4942b67 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -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! (
@@ -1435,6 +1438,14 @@ 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")
+ }
+ }
+
fn visit_pat(&mut self, pattern: &'a ast::Pat) {
match pattern.node {
PatKind::Slice(_, Some(_), ref last) if !last.is_empty() => {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index d9f453a93ad..03c47b71d02 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -344,12 +344,14 @@ pub fn fold_thin_attrs(attrs: ThinVec, fld: &mut T) -> Thi
fold_attrs(attrs.into(), fld).into()
}
-pub fn noop_fold_arm(Arm {attrs, pats, guard, body}: Arm, fld: &mut T) -> Arm {
+pub fn noop_fold_arm(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,
}
}
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index d08373334f1..1f033b25fe4 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -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()?)
@@ -3178,6 +3184,7 @@ impl<'a> Parser<'a> {
pats,
guard,
body: expr,
+ beginning_vert,
})
}
diff --git a/src/test/compile-fail/feature-gate-match_beginning_vert.rs b/src/test/compile-fail/feature-gate-match_beginning_vert.rs
new file mode 100644
index 00000000000..9085563c99d
--- /dev/null
+++ b/src/test/compile-fail/feature-gate-match_beginning_vert.rs
@@ -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 or the MIT license
+// , 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!"),
+ _ => {},
+ };
+}
+