Skip to content

Commit f866152

Browse files
committed
Implement RFC 1925
1 parent ed532c0 commit f866152

File tree

7 files changed

+81
-2
lines changed

7 files changed

+81
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# `match_beginning_vert`
2+
3+
The tracking issue for this feature is [#44101].
4+
5+
With this feature enabled, you are allowed to add a '|' to the beginning of a
6+
match arm:
7+
8+
```rust
9+
#![feature(match_beginning_vert)]
10+
11+
enum Foo { A, B }
12+
13+
fn main() {
14+
let x = Foo::A;
15+
match x {
16+
| A | B => {},
17+
}
18+
}
19+
```
20+
21+
[#44101]: https://github.com/rust-lang/rust/issues/44101

src/libsyntax/ast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,7 @@ pub struct Arm {
810810
pub pats: Vec<P<Pat>>,
811811
pub guard: Option<P<Expr>>,
812812
pub body: P<Expr>,
813+
pub beginning_vert: Option<Span>, // For RFC 1925 feature gate
813814
}
814815

815816
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]

src/libsyntax/ext/build.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
878878
attrs: vec![],
879879
pats,
880880
guard: None,
881-
body: expr
881+
body: expr,
882+
beginning_vert: None,
882883
}
883884
}
884885

src/libsyntax/feature_gate.rs

+11
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,9 @@ declare_features! (
379379

380380
// allow `#[must_use]` on functions (RFC 1940)
381381
(active, fn_must_use, "1.21.0", Some(43302)),
382+
383+
// allow '|' at beginning of match arms (RFC 1925)
384+
(active, match_beginning_vert, "1.21.0", Some(44101)),
382385
);
383386

384387
declare_features! (
@@ -1435,6 +1438,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
14351438
visit::walk_expr(self, e);
14361439
}
14371440

1441+
fn visit_arm(&mut self, arm: &'a ast::Arm) {
1442+
if let Some(span) = arm.beginning_vert {
1443+
gate_feature_post!(&self, match_beginning_vert,
1444+
span,
1445+
"Use of a '|' at the beginning of a match arm is experimental")
1446+
}
1447+
}
1448+
14381449
fn visit_pat(&mut self, pattern: &'a ast::Pat) {
14391450
match pattern.node {
14401451
PatKind::Slice(_, Some(_), ref last) if !last.is_empty() => {

src/libsyntax/fold.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -344,12 +344,14 @@ pub fn fold_thin_attrs<T: Folder>(attrs: ThinVec<Attribute>, fld: &mut T) -> Thi
344344
fold_attrs(attrs.into(), fld).into()
345345
}
346346

347-
pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm, fld: &mut T) -> Arm {
347+
pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body, beginning_vert}: Arm,
348+
fld: &mut T) -> Arm {
348349
Arm {
349350
attrs: fold_attrs(attrs, fld),
350351
pats: pats.move_map(|x| fld.fold_pat(x)),
351352
guard: guard.map(|x| fld.fold_expr(x)),
352353
body: fld.fold_expr(body),
354+
beginning_vert,
353355
}
354356
}
355357

src/libsyntax/parse/parser.rs

+7
Original file line numberDiff line numberDiff line change
@@ -3155,6 +3155,12 @@ impl<'a> Parser<'a> {
31553155
maybe_whole!(self, NtArm, |x| x);
31563156

31573157
let attrs = self.parse_outer_attributes()?;
3158+
// Allow a '|' before the pats (RFC 1925)
3159+
let beginning_vert = if self.eat(&token::BinOp(token::Or)) {
3160+
Some(self.prev_span)
3161+
} else {
3162+
None
3163+
};
31583164
let pats = self.parse_pats()?;
31593165
let guard = if self.eat_keyword(keywords::If) {
31603166
Some(self.parse_expr()?)
@@ -3178,6 +3184,7 @@ impl<'a> Parser<'a> {
31783184
pats,
31793185
guard,
31803186
body: expr,
3187+
beginning_vert,
31813188
})
31823189
}
31833190

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#[allow(dead_code)]
12+
enum Foo {
13+
A,
14+
B,
15+
C,
16+
D,
17+
E,
18+
}
19+
use Foo::*;
20+
21+
fn main() {
22+
let x = Foo::A;
23+
match x {
24+
| A => println!("A"),
25+
//~^ ERROR: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
26+
| B | C => println!("BC!"),
27+
//~^ ERROR: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
28+
| _ => {},
29+
//~^ ERROR: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
30+
};
31+
match x {
32+
A | B | C => println!("ABC!"),
33+
_ => {},
34+
};
35+
}
36+

0 commit comments

Comments
 (0)