Skip to content

Commit 1452c9c

Browse files
committed
Allow attributes on match arms
RFC: 0008-match-arm-attributes
1 parent 3d05e7f commit 1452c9c

File tree

8 files changed

+66
-3
lines changed

8 files changed

+66
-3
lines changed

src/librustc/front/config.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -36,6 +36,9 @@ impl<'a> fold::Folder for Context<'a> {
3636
fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ {
3737
fold_item_underscore(self, item)
3838
}
39+
fn fold_expr(&mut self, expr: @ast::Expr) -> @ast::Expr {
40+
fold_expr(self, expr)
41+
}
3942
}
4043

4144
pub fn strip_items(krate: ast::Crate,
@@ -189,6 +192,24 @@ fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
189192
})
190193
}
191194

195+
fn fold_expr(cx: &mut Context, expr: @ast::Expr) -> @ast::Expr {
196+
let expr = match expr.node {
197+
ast::ExprMatch(ref m, ref arms) => {
198+
let arms = arms.iter()
199+
.filter(|a| (cx.in_cfg)(a.attrs.as_slice()))
200+
.map(|a| a.clone())
201+
.collect();
202+
@ast::Expr {
203+
id: expr.id,
204+
span: expr.span.clone(),
205+
node: ast::ExprMatch(m.clone(), arms),
206+
}
207+
}
208+
_ => expr.clone()
209+
};
210+
fold::noop_fold_expr(expr, cx)
211+
}
212+
192213
fn item_in_cfg(cx: &mut Context, item: &ast::Item) -> bool {
193214
return (cx.in_cfg)(item.attrs.as_slice());
194215
}

src/libsyntax/ast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ pub enum Decl_ {
440440

441441
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
442442
pub struct Arm {
443+
pub attrs: Vec<Attribute>,
443444
pub pats: Vec<@Pat>,
444445
pub guard: Option<@Expr>,
445446
pub body: @Expr,

src/libsyntax/ext/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
726726

727727
fn arm(&self, _span: Span, pats: Vec<@ast::Pat> , expr: @ast::Expr) -> ast::Arm {
728728
ast::Arm {
729+
attrs: vec!(),
729730
pats: pats,
730731
guard: None,
731732
body: expr

src/libsyntax/ext/deriving/primitive.rs

+2
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure
110110

111111
// arm for `_ if $guard => $body`
112112
let arm = ast::Arm {
113+
attrs: vec!(),
113114
pats: vec!(cx.pat_wild(span)),
114115
guard: Some(guard),
115116
body: body,
@@ -129,6 +130,7 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure
129130

130131
// arm for `_ => None`
131132
let arm = ast::Arm {
133+
attrs: vec!(),
132134
pats: vec!(cx.pat_wild(trait_span)),
133135
guard: None,
134136
body: cx.expr_none(trait_span),

src/libsyntax/fold.rs

+1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ pub trait Folder {
119119

120120
fn fold_arm(&mut self, a: &Arm) -> Arm {
121121
Arm {
122+
attrs: a.attrs.iter().map(|x| fold_attribute_(*x, self)).collect(),
122123
pats: a.pats.iter().map(|x| self.fold_pat(*x)).collect(),
123124
guard: a.guard.map(|x| self.fold_expr(x)),
124125
body: self.fold_expr(a.body),

src/libsyntax/parse/parser.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -2539,6 +2539,7 @@ impl<'a> Parser<'a> {
25392539
self.commit_expr_expecting(discriminant, token::LBRACE);
25402540
let mut arms: Vec<Arm> = Vec::new();
25412541
while self.token != token::RBRACE {
2542+
let attrs = self.parse_outer_attributes();
25422543
let pats = self.parse_pats();
25432544
let mut guard = None;
25442545
if self.eat_keyword(keywords::If) {
@@ -2557,7 +2558,12 @@ impl<'a> Parser<'a> {
25572558
self.eat(&token::COMMA);
25582559
}
25592560

2560-
arms.push(ast::Arm { pats: pats, guard: guard, body: expr });
2561+
arms.push(ast::Arm {
2562+
attrs: attrs,
2563+
pats: pats,
2564+
guard: guard,
2565+
body: expr
2566+
});
25612567
}
25622568
let hi = self.span.hi;
25632569
self.bump();

src/libsyntax/print/pprust.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1286,9 +1286,14 @@ impl<'a> State<'a> {
12861286
try!(self.bopen());
12871287
let len = arms.len();
12881288
for (i, arm) in arms.iter().enumerate() {
1289-
try!(space(&mut self.s));
1289+
// I have no idea why this check is necessary, but here it
1290+
// is :(
1291+
if arm.attrs.is_empty() {
1292+
try!(space(&mut self.s));
1293+
}
12901294
try!(self.cbox(indent_unit));
12911295
try!(self.ibox(0u));
1296+
try!(self.print_outer_attributes(arm.attrs.as_slice()));
12921297
let mut first = true;
12931298
for p in arm.pats.iter() {
12941299
if first {

src/test/run-pass/cfg-match-arm.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2014 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+
enum Foo {
12+
Bar,
13+
Baz,
14+
}
15+
16+
fn foo(f: Foo) {
17+
match f {
18+
Bar => {},
19+
#[cfg(not(asdfa))]
20+
Baz => {},
21+
#[cfg(afsd)]
22+
Basdfwe => {}
23+
}
24+
}
25+
26+
pub fn main() {}

0 commit comments

Comments
 (0)