diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-06-26 02:19:34 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-06-26 02:20:14 +0000 |
| commit | 9bb3ea0febcbb8f6d7715256a5644daa985cf4e7 (patch) | |
| tree | eeed21468b6bceeed80766490852c8cee2653170 /src/libsyntax/parse | |
| parent | 8eddf0280014972e051856dfe949054acf53c043 (diff) | |
| parent | 8cad25199acb346bf8d6b1771f1f50dc9e59374c (diff) | |
| download | rust-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.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 27 |
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, |
