about summary refs log tree commit diff
path: root/src/libsyntax/print/pprust.rs
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/print/pprust.rs
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/print/pprust.rs')
-rw-r--r--src/libsyntax/print/pprust.rs42
1 files changed, 21 insertions, 21 deletions
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index d399f538004..b56cec72a95 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1619,12 +1619,16 @@ impl<'a> State<'a> {
                     try!(self.word_space("="));
                     try!(self.print_expr(&init));
                 }
+                try!(word(&mut self.s, ";"));
                 self.end()?;
             }
             ast::StmtKind::Item(ref item) => self.print_item(&item)?,
             ast::StmtKind::Expr(ref expr) => {
                 try!(self.space_if_not_bol());
                 try!(self.print_expr_outer_attr_style(&expr, false));
+                if parse::classify::expr_requires_semi_to_be_stmt(expr) {
+                    try!(word(&mut self.s, ";"));
+                }
             }
             ast::StmtKind::Semi(ref expr) => {
                 try!(self.space_if_not_bol());
@@ -1646,9 +1650,6 @@ impl<'a> State<'a> {
                 }
             }
         }
-        if parse::classify::stmt_ends_with_semi(&st.node) {
-            try!(word(&mut self.s, ";"));
-        }
         self.maybe_print_trailing_comment(st.span, None)
     }
 
@@ -1692,17 +1693,17 @@ impl<'a> State<'a> {
 
         try!(self.print_inner_attributes(attrs));
 
-        for st in &blk.stmts {
-            try!(self.print_stmt(st));
-        }
-        match blk.expr {
-            Some(ref expr) => {
-                try!(self.space_if_not_bol());
-                try!(self.print_expr_outer_attr_style(&expr, false));
-                try!(self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi)));
+        for (i, st) in blk.stmts.iter().enumerate() {
+            match st.node {
+                ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => {
+                    try!(self.space_if_not_bol());
+                    try!(self.print_expr_outer_attr_style(&expr, false));
+                    try!(self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi)));
+                }
+                _ => try!(self.print_stmt(st)),
             }
-            _ => ()
         }
+
         try!(self.bclose_maybe_open(blk.span, indented, close_box));
         self.ann.post(self, NodeBlock(blk))
     }
@@ -2111,22 +2112,21 @@ impl<'a> State<'a> {
                     _ => false
                 };
 
-                if !default_return || !body.stmts.is_empty() || body.expr.is_none() {
-                    try!(self.print_block_unclosed(&body));
-                } else {
-                    // we extract the block, so as not to create another set of boxes
-                    let i_expr = body.expr.as_ref().unwrap();
-                    match i_expr.node {
-                        ast::ExprKind::Block(ref blk) => {
+                match body.stmts.last().map(|stmt| &stmt.node) {
+                    Some(&ast::StmtKind::Expr(ref i_expr)) if default_return &&
+                                                              body.stmts.len() == 1 => {
+                        // we extract the block, so as not to create another set of boxes
+                        if let ast::ExprKind::Block(ref blk) = i_expr.node {
                             try!(self.print_block_unclosed_with_attrs(&blk, &i_expr.attrs));
-                        }
-                        _ => {
+                        } else {
                             // this is a bare expression
                             try!(self.print_expr(&i_expr));
                             try!(self.end()); // need to close a box
                         }
                     }
+                    _ => try!(self.print_block_unclosed(&body)),
                 }
+
                 // a box will be closed by print_expr, but we didn't want an overall
                 // wrapper so we closed the corresponding opening. so create an
                 // empty box to satisfy the close.