From b7da35a5aa7603c3010e1aa9e5ff6de5660058fb Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Thu, 23 Jun 2016 09:51:18 +0000 Subject: Remove field `expr` of `ast::Block` --- src/libsyntax/ast.rs | 5 +---- src/libsyntax/ext/build.rs | 45 +++++++++++++++++++------------------------ src/libsyntax/ext/expand.rs | 11 +---------- src/libsyntax/ext/quote.rs | 24 +++++++++++------------ src/libsyntax/fold.rs | 3 +-- src/libsyntax/parse/parser.rs | 30 ++++++++--------------------- src/libsyntax/print/pprust.rs | 29 +++++++++------------------- src/libsyntax/test.rs | 2 +- src/libsyntax/visit.rs | 1 - 9 files changed, 52 insertions(+), 98 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 8537fcc221c..e138119149c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -528,9 +528,6 @@ impl PartialEq for MetaItemKind { pub struct Block { /// Statements in a block pub stmts: Vec, - /// An expression at the end of the block - /// without a semicolon, if any - pub expr: Option>, pub id: NodeId, /// Distinguishes between `unsafe { ... }` and `{ ... }` pub rules: BlockCheckMode, @@ -803,7 +800,7 @@ pub enum StmtKind { /// Could be an item or a local (let) binding: Decl(P, NodeId), - /// Expr without trailing semi-colon (must have unit type): + /// Expr without trailing semi-colon Expr(P, NodeId), /// Expr with trailing semi-colon (may have any type): diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 3a1cdae9bfb..1a01fa2e9e0 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -98,12 +98,9 @@ pub trait AstBuilder { fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt; // blocks - fn block(&self, span: Span, stmts: Vec, - expr: Option>) -> P; + fn block(&self, span: Span, stmts: Vec) -> P; fn block_expr(&self, expr: P) -> P; - fn block_all(&self, span: Span, - stmts: Vec, - expr: Option>) -> P; + fn block_all(&self, span: Span, stmts: Vec) -> P; // expressions fn expr(&self, span: Span, node: ast::ExprKind) -> P; @@ -508,7 +505,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn stmt_expr(&self, expr: P) -> ast::Stmt { - respan(expr.span, ast::StmtKind::Semi(expr, ast::DUMMY_NODE_ID)) + respan(expr.span, ast::StmtKind::Expr(expr, ast::DUMMY_NODE_ID)) } fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, @@ -556,9 +553,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { P(respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID))) } - fn block(&self, span: Span, stmts: Vec, - expr: Option>) -> P { - self.block_all(span, stmts, expr) + fn block(&self, span: Span, stmts: Vec) -> P { + self.block_all(span, stmts) } fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt { @@ -567,19 +563,18 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn block_expr(&self, expr: P) -> P { - self.block_all(expr.span, Vec::new(), Some(expr)) - } - fn block_all(&self, - span: Span, - stmts: Vec, - expr: Option>) -> P { - P(ast::Block { - stmts: stmts, - expr: expr, - id: ast::DUMMY_NODE_ID, - rules: BlockCheckMode::Default, - span: span, - }) + self.block_all(expr.span, vec![Spanned { + span: expr.span, + node: ast::StmtKind::Expr(expr, ast::DUMMY_NODE_ID), + }]) + } + fn block_all(&self, span: Span, stmts: Vec) -> P { + P(ast::Block { + stmts: stmts, + id: ast::DUMMY_NODE_ID, + rules: BlockCheckMode::Default, + span: span, + }) } fn expr(&self, span: Span, node: ast::ExprKind) -> P { @@ -948,14 +943,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ids: Vec, stmts: Vec) -> P { - self.lambda(span, ids, self.block(span, stmts, None)) + self.lambda(span, ids, self.block(span, stmts)) } fn lambda_stmts_0(&self, span: Span, stmts: Vec) -> P { - self.lambda0(span, self.block(span, stmts, None)) + self.lambda0(span, self.block(span, stmts)) } fn lambda_stmts_1(&self, span: Span, stmts: Vec, ident: ast::Ident) -> P { - self.lambda1(span, self.block(span, stmts, None), ident) + self.lambda1(span, self.block(span, stmts), ident) } fn arg(&self, span: Span, ident: ast::Ident, ty: P) -> ast::Arg { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 73acbb2aa0a..263c10cee5b 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -636,23 +636,14 @@ pub fn expand_block(blk: P, fld: &mut MacroExpander) -> P { // expand the elements of a block. pub fn expand_block_elts(b: P, fld: &mut MacroExpander) -> P { - b.map(|Block {id, stmts, expr, rules, span}| { + b.map(|Block {id, stmts, rules, span}| { let new_stmts = stmts.into_iter().flat_map(|x| { // perform pending renames and expand macros in the statement fld.fold_stmt(x).into_iter() }).collect(); - let new_expr = expr.map(|x| { - let expr = { - let pending_renames = &mut fld.cx.syntax_env.info().pending_renames; - let mut rename_fld = IdentRenamer{renames:pending_renames}; - rename_fld.fold_expr(x) - }; - fld.fold_expr(expr) - }); Block { id: fld.new_id(id), stmts: new_stmts, - expr: new_expr, rules: rules, span: span } diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 871b0d4b1c0..b1290451cbf 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -512,10 +512,8 @@ pub fn expand_quote_matcher(cx: &mut ExtCtxt, let (cx_expr, tts) = parse_arguments_to_quote(cx, tts); let mut vector = mk_stmts_let(cx, sp); vector.extend(statements_mk_tts(cx, &tts[..], true)); - let block = cx.expr_block( - cx.block_all(sp, - vector, - Some(cx.expr_ident(sp, id_ext("tt"))))); + vector.push(cx.stmt_expr(cx.expr_ident(sp, id_ext("tt")))); + let block = cx.expr_block(cx.block_all(sp, vector)); let expanded = expand_wrapper(cx, sp, cx_expr, block, &[&["syntax", "ext", "quote", "rt"]]); base::MacEager::expr(expanded) @@ -765,8 +763,9 @@ fn statements_mk_tt(cx: &ExtCtxt, tt: &TokenTree, matcher: bool) -> Vec cx.expr_some(sp, expr_mk_token(cx, sp, sep)), None => cx.expr_none(sp), @@ -884,10 +883,8 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[TokenTree]) let mut vector = mk_stmts_let(cx, sp); vector.extend(statements_mk_tts(cx, &tts[..], false)); - let block = cx.expr_block( - cx.block_all(sp, - vector, - Some(cx.expr_ident(sp, id_ext("tt"))))); + vector.push(cx.stmt_expr(cx.expr_ident(sp, id_ext("tt")))); + let block = cx.expr_block(cx.block_all(sp, vector)); (cx_expr, block) } @@ -901,13 +898,14 @@ fn expand_wrapper(cx: &ExtCtxt, let cx_expr_borrow = cx.expr_addr_of(sp, cx.expr_deref(sp, cx_expr)); let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr_borrow); - let stmts = imports.iter().map(|path| { + let mut stmts = imports.iter().map(|path| { // make item: `use ...;` let path = path.iter().map(|s| s.to_string()).collect(); cx.stmt_item(sp, cx.item_use_glob(sp, ast::Visibility::Inherited, ids_ext(path))) - }).chain(Some(stmt_let_ext_cx)).collect(); + }).chain(Some(stmt_let_ext_cx)).collect::>(); + stmts.push(cx.stmt_expr(expr)); - cx.expr_block(cx.block_all(sp, stmts, Some(expr))) + cx.expr_block(cx.block_all(sp, stmts)) } fn expand_parse_call(cx: &ExtCtxt, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index edf418e3332..8647937027b 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -845,10 +845,9 @@ fn noop_fold_bounds(bounds: TyParamBounds, folder: &mut T) } pub fn noop_fold_block(b: P, folder: &mut T) -> P { - b.map(|Block {id, stmts, expr, rules, span}| Block { + b.map(|Block {id, stmts, rules, span}| Block { id: folder.new_id(id), stmts: stmts.move_flat_map(|s| folder.fold_stmt(s).into_iter()), - expr: expr.and_then(|x| folder.fold_opt_expr(x)), rules: rules, span: folder.new_span(span), }) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 341b076e7cf..dea6589fe7c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3217,9 +3217,11 @@ 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![Spanned { + span: body_expr.span, + node: StmtKind::Expr(body_expr, ast::DUMMY_NODE_ID), + }], rules: BlockCheckMode::Default, }) } @@ -4082,7 +4084,6 @@ impl<'a> Parser<'a> { /// Precondition: already parsed the '{'. fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> PResult<'a, P> { let mut stmts = vec![]; - let mut expr = None; while !self.eat(&token::CloseDelim(token::Brace)) { let Spanned {node, span} = if let Some(s) = self.parse_stmt_() { @@ -4095,11 +4096,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, MacStmtStyle::NoBraces, attrs) => { - // statement macro without braces; might be an - // expr depending on whether a semicolon follows + // statement macro without braces match self.token { token::Semi => { stmts.push(Spanned { @@ -4115,11 +4115,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, - &mut stmts, - &mut expr)?; + self.handle_expression_like_statement(e, span, &mut stmts)?; } } } @@ -4133,13 +4129,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 - expr = Some(self.mk_mac_expr(span.lo, span.hi, - m.and_then(|x| x.node), - attrs)); - } _ => { stmts.push(Spanned { node: StmtKind::Mac(m, style, attrs), @@ -4165,7 +4154,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), @@ -4175,8 +4163,7 @@ impl<'a> Parser<'a> { fn handle_expression_like_statement(&mut self, e: P, span: Span, - stmts: &mut Vec, - last_block_expr: &mut Option>) + stmts: &mut Vec) -> PResult<'a, ()> { // expression without semicolon if classify::expr_requires_semi_to_be_stmt(&e) { @@ -4202,7 +4189,6 @@ impl<'a> Parser<'a> { span: span_with_semi, }); } - token::CloseDelim(token::Brace) => *last_block_expr = Some(e), _ => { stmts.push(Spanned { node: StmtKind::Expr(e, ast::DUMMY_NODE_ID), diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a2ee5bf6090..d38d5d9b6b6 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1619,9 +1619,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) } @@ -1668,14 +1665,6 @@ impl<'a> State<'a> { 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))); - } - _ => () - } try!(self.bclose_maybe_open(blk.span, indented, close_box)); self.ann.post(self, NodeBlock(blk)) } @@ -2084,24 +2073,23 @@ 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.as_attr_slice())); - } - _ => { + } 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. @@ -2295,6 +2283,7 @@ impl<'a> State<'a> { try!(self.word_space("=")); try!(self.print_expr(&init)); } + try!(word(&mut self.s, ";")); self.end() } ast::DeclKind::Item(ref item) => self.print_item(&item) diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index ca6ed76d549..72beea0421b 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -474,7 +474,7 @@ fn mk_main(cx: &mut TestCtxt) -> P { let main_attr = ecx.attribute(sp, main_meta); // pub fn main() { ... } let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![])); - let main_body = ecx.block_all(sp, vec![call_test_main], None); + let main_body = ecx.block_all(sp, vec![call_test_main]); let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], main_ret_ty), ast::Unsafety::Normal, ast::Constness::NotConst, diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 07a6317706b..cf91f5ece72 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -608,7 +608,6 @@ pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) { walk_list!(visitor, visit_stmt, &block.stmts); - walk_list!(visitor, visit_expr, &block.expr); } pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { -- cgit 1.4.1-3-g733a5 From 060a84d1f7fee5585aa6ebc50c74b0b35f2c0283 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Thu, 23 Jun 2016 23:26:32 +0000 Subject: Refactor away duplicate method `ecx.block_all()` --- src/libsyntax/ext/build.rs | 9 ++------- src/libsyntax/ext/quote.rs | 6 +++--- src/libsyntax/test.rs | 2 +- src/libsyntax_ext/deriving/generic/mod.rs | 2 +- 4 files changed, 7 insertions(+), 12 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 1a01fa2e9e0..480a0894201 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -100,7 +100,6 @@ pub trait AstBuilder { // blocks fn block(&self, span: Span, stmts: Vec) -> P; fn block_expr(&self, expr: P) -> P; - fn block_all(&self, span: Span, stmts: Vec) -> P; // expressions fn expr(&self, span: Span, node: ast::ExprKind) -> P; @@ -553,22 +552,18 @@ impl<'a> AstBuilder for ExtCtxt<'a> { P(respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID))) } - fn block(&self, span: Span, stmts: Vec) -> P { - self.block_all(span, stmts) - } - fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt { let decl = respan(sp, ast::DeclKind::Item(item)); respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID)) } fn block_expr(&self, expr: P) -> P { - self.block_all(expr.span, vec![Spanned { + self.block(expr.span, vec![Spanned { span: expr.span, node: ast::StmtKind::Expr(expr, ast::DUMMY_NODE_ID), }]) } - fn block_all(&self, span: Span, stmts: Vec) -> P { + fn block(&self, span: Span, stmts: Vec) -> P { P(ast::Block { stmts: stmts, id: ast::DUMMY_NODE_ID, diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index b1290451cbf..74a88842d22 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -513,7 +513,7 @@ pub fn expand_quote_matcher(cx: &mut ExtCtxt, let mut vector = mk_stmts_let(cx, sp); vector.extend(statements_mk_tts(cx, &tts[..], true)); vector.push(cx.stmt_expr(cx.expr_ident(sp, id_ext("tt")))); - let block = cx.expr_block(cx.block_all(sp, vector)); + let block = cx.expr_block(cx.block(sp, vector)); let expanded = expand_wrapper(cx, sp, cx_expr, block, &[&["syntax", "ext", "quote", "rt"]]); base::MacEager::expr(expanded) @@ -884,7 +884,7 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[TokenTree]) let mut vector = mk_stmts_let(cx, sp); vector.extend(statements_mk_tts(cx, &tts[..], false)); vector.push(cx.stmt_expr(cx.expr_ident(sp, id_ext("tt")))); - let block = cx.expr_block(cx.block_all(sp, vector)); + let block = cx.expr_block(cx.block(sp, vector)); (cx_expr, block) } @@ -905,7 +905,7 @@ fn expand_wrapper(cx: &ExtCtxt, }).chain(Some(stmt_let_ext_cx)).collect::>(); stmts.push(cx.stmt_expr(expr)); - cx.expr_block(cx.block_all(sp, stmts)) + cx.expr_block(cx.block(sp, stmts)) } fn expand_parse_call(cx: &ExtCtxt, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 72beea0421b..39d3599e106 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -474,7 +474,7 @@ fn mk_main(cx: &mut TestCtxt) -> P { let main_attr = ecx.attribute(sp, main_meta); // pub fn main() { ... } let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![])); - let main_body = ecx.block_all(sp, vec![call_test_main]); + let main_body = ecx.block(sp, vec![call_test_main]); let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], main_ret_ty), ast::Unsafety::Normal, ast::Constness::NotConst, diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index dd27c1ec202..635d9ee5516 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -1333,7 +1333,7 @@ impl<'a> MethodDef<'a> { let all_match = cx.expr_match(sp, match_arg, match_arms); let arm_expr = cx.expr_if(sp, discriminant_test, all_match, Some(arm_expr)); index_let_stmts.push(cx.stmt_expr(arm_expr)); - cx.expr_block(cx.block_all(sp, index_let_stmts)) + cx.expr_block(cx.block(sp, index_let_stmts)) } else if variants.is_empty() { // As an additional wrinkle, For a zero-variant enum A, // currently the compiler -- cgit 1.4.1-3-g733a5 From 8cad25199acb346bf8d6b1771f1f50dc9e59374c Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Fri, 24 Jun 2016 11:39:18 +0000 Subject: Add `ecx.stmt_semi()` and fix issues with the pretty-printer --- src/libsyntax/ext/build.rs | 5 +++++ src/libsyntax/parse/mod.rs | 1 - src/libsyntax/print/pprust.rs | 15 +++++++++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 480a0894201..4bfbd37edd9 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -87,6 +87,7 @@ pub trait AstBuilder { // statements fn stmt_expr(&self, expr: P) -> ast::Stmt; + fn stmt_semi(&self, expr: P) -> ast::Stmt; fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: P) -> ast::Stmt; fn stmt_let_typed(&self, sp: Span, @@ -507,6 +508,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> { respan(expr.span, ast::StmtKind::Expr(expr, ast::DUMMY_NODE_ID)) } + fn stmt_semi(&self, expr: P) -> ast::Stmt { + respan(expr.span, ast::StmtKind::Semi(expr, ast::DUMMY_NODE_ID)) + } + fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: P) -> ast::Stmt { let pat = if mutbl { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 2e4d46bc983..f79d6e8421a 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -953,7 +953,6 @@ mod tests { attrs: None,}), 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/print/pprust.rs b/src/libsyntax/print/pprust.rs index d38d5d9b6b6..00edd5585c2 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1599,6 +1599,9 @@ impl<'a> State<'a> { 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()); @@ -1662,9 +1665,17 @@ impl<'a> State<'a> { try!(self.print_inner_attributes(attrs)); - for st in &blk.stmts { - try!(self.print_stmt(st)); + 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)) } -- cgit 1.4.1-3-g733a5