about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-06-26 02:19:34 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-06-26 02:20:14 +0000
commit9bb3ea0febcbb8f6d7715256a5644daa985cf4e7 (patch)
treeeeed21468b6bceeed80766490852c8cee2653170 /src/libsyntax/parse
parent8eddf0280014972e051856dfe949054acf53c043 (diff)
parent8cad25199acb346bf8d6b1771f1f50dc9e59374c (diff)
downloadrust-9bb3ea0febcbb8f6d7715256a5644daa985cf4e7.tar.gz
rust-9bb3ea0febcbb8f6d7715256a5644daa985cf4e7.zip
Rollup merge of #34436 - jseyfried:no_block_expr, r=eddyb
To allow these braced macro invocation, this PR removes the optional expression from `ast::Block` and instead uses a `StmtKind::Expr` at the end of the statement list.

Currently, braced macro invocations in blocks can expand into statements (and items) except when they are last in a block, in which case they can only expand into expressions.

For example,
```rust
macro_rules! make_stmt {
    () => { let x = 0; }
}

fn f() {
    make_stmt! {} //< This is OK...
    let x = 0; //< ... unless this line is commented out.
}
```

Fixes #34418.
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/mod.rs1
-rw-r--r--src/libsyntax/parse/parser.rs27
2 files changed, 10 insertions, 18 deletions
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 0c5a672dfbc..bbcc044d43c 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -957,7 +957,6 @@ mod tests {
                                                 attrs: ThinVec::new()})),
                                             id: ast::DUMMY_NODE_ID,
                                             span: sp(17,19)}),
-                                        expr: None,
                                         id: ast::DUMMY_NODE_ID,
                                         rules: ast::BlockCheckMode::Default, // no idea
                                         span: sp(15,21),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 83401011ed4..813d90103b8 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3236,9 +3236,12 @@ impl<'a> Parser<'a> {
                 let body_expr = self.parse_expr()?;
                 P(ast::Block {
                     id: ast::DUMMY_NODE_ID,
-                    stmts: vec![],
                     span: body_expr.span,
-                    expr: Some(body_expr),
+                    stmts: vec![Stmt {
+                        span: body_expr.span,
+                        node: StmtKind::Expr(body_expr),
+                        id: ast::DUMMY_NODE_ID,
+                    }],
                     rules: BlockCheckMode::Default,
                 })
             }
@@ -4098,7 +4101,6 @@ impl<'a> Parser<'a> {
     /// Precondition: already parsed the '{'.
     fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> PResult<'a, P<Block>> {
         let mut stmts = vec![];
-        let mut expr = None;
 
         while !self.eat(&token::CloseDelim(token::Brace)) {
             let Stmt {node, span, ..} = if let Some(s) = self.parse_stmt_() {
@@ -4112,10 +4114,10 @@ impl<'a> Parser<'a> {
 
             match node {
                 StmtKind::Expr(e) => {
-                    self.handle_expression_like_statement(e, span, &mut stmts, &mut expr)?;
+                    self.handle_expression_like_statement(e, span, &mut stmts)?;
                 }
                 StmtKind::Mac(mac) => {
-                    self.handle_macro_in_block(mac.unwrap(), span, &mut stmts, &mut expr)?;
+                    self.handle_macro_in_block(mac.unwrap(), span, &mut stmts)?;
                 }
                 _ => { // all other kinds of statements:
                     let mut hi = span.hi;
@@ -4135,7 +4137,6 @@ impl<'a> Parser<'a> {
 
         Ok(P(ast::Block {
             stmts: stmts,
-            expr: expr,
             id: ast::DUMMY_NODE_ID,
             rules: s,
             span: mk_sp(lo, self.last_span.hi),
@@ -4145,8 +4146,7 @@ impl<'a> Parser<'a> {
     fn handle_macro_in_block(&mut self,
                              (mac, style, attrs): (ast::Mac, MacStmtStyle, ThinVec<Attribute>),
                              span: Span,
-                             stmts: &mut Vec<Stmt>,
-                             last_block_expr: &mut Option<P<Expr>>)
+                             stmts: &mut Vec<Stmt>)
                              -> PResult<'a, ()> {
         if style == MacStmtStyle::NoBraces {
             // statement macro without braces; might be an
@@ -4165,7 +4165,7 @@ impl<'a> Parser<'a> {
                     let lo = e.span.lo;
                     let e = self.parse_dot_or_call_expr_with(e, lo, attrs)?;
                     let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
-                    self.handle_expression_like_statement(e, span, stmts, last_block_expr)?;
+                    self.handle_expression_like_statement(e, span, stmts)?;
                 }
             }
         } else {
@@ -4179,11 +4179,6 @@ impl<'a> Parser<'a> {
                     });
                     self.bump();
                 }
-                token::CloseDelim(token::Brace) => {
-                    // if a block ends in `m!(arg)` without
-                    // a `;`, it must be an expr
-                    *last_block_expr = Some(self.mk_mac_expr(span.lo, span.hi, mac.node, attrs));
-                }
                 _ => {
                     stmts.push(Stmt {
                         id: ast::DUMMY_NODE_ID,
@@ -4199,8 +4194,7 @@ impl<'a> Parser<'a> {
     fn handle_expression_like_statement(&mut self,
                                         e: P<Expr>,
                                         span: Span,
-                                        stmts: &mut Vec<Stmt>,
-                                        last_block_expr: &mut Option<P<Expr>>)
+                                        stmts: &mut Vec<Stmt>)
                                         -> PResult<'a, ()> {
         // expression without semicolon
         if classify::expr_requires_semi_to_be_stmt(&e) {
@@ -4227,7 +4221,6 @@ impl<'a> Parser<'a> {
                     span: span_with_semi,
                 });
             }
-            token::CloseDelim(token::Brace) => *last_block_expr = Some(e),
             _ => {
                 stmts.push(Stmt {
                     id: ast::DUMMY_NODE_ID,