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/ext | |
| 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/ext')
| -rw-r--r-- | src/libsyntax/ext/build.rs | 52 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/ext/quote.rs | 24 |
3 files changed, 38 insertions, 49 deletions
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index f4ae23ed8be..435241f426e 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -88,6 +88,7 @@ pub trait AstBuilder { // statements fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt; + fn stmt_semi(&self, expr: P<ast::Expr>) -> ast::Stmt; fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: P<ast::Expr>) -> ast::Stmt; fn stmt_let_typed(&self, sp: Span, @@ -99,12 +100,8 @@ pub trait AstBuilder { fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt; // blocks - fn block(&self, span: Span, stmts: Vec<ast::Stmt>, - expr: Option<P<ast::Expr>>) -> P<ast::Block>; + fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block>; fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block>; - fn block_all(&self, span: Span, - stmts: Vec<ast::Stmt>, - expr: Option<P<ast::Expr>>) -> P<ast::Block>; // expressions fn expr(&self, span: Span, node: ast::ExprKind) -> P<ast::Expr>; @@ -512,6 +509,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, + node: ast::StmtKind::Expr(expr), + } + } + + fn stmt_semi(&self, expr: P<ast::Expr>) -> ast::Stmt { + ast::Stmt { + id: ast::DUMMY_NODE_ID, + span: expr.span, node: ast::StmtKind::Semi(expr), } } @@ -567,11 +572,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn block(&self, span: Span, stmts: Vec<ast::Stmt>, - expr: Option<P<Expr>>) -> P<ast::Block> { - self.block_all(span, stmts, expr) - } - fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt { ast::Stmt { id: ast::DUMMY_NODE_ID, @@ -581,19 +581,19 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> { - self.block_all(expr.span, Vec::new(), Some(expr)) - } - fn block_all(&self, - span: Span, - stmts: Vec<ast::Stmt>, - expr: Option<P<ast::Expr>>) -> P<ast::Block> { - P(ast::Block { - stmts: stmts, - expr: expr, - id: ast::DUMMY_NODE_ID, - rules: BlockCheckMode::Default, - span: span, - }) + self.block(expr.span, vec![ast::Stmt { + id: ast::DUMMY_NODE_ID, + span: expr.span, + node: ast::StmtKind::Expr(expr), + }]) + } + fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block> { + P(ast::Block { + stmts: stmts, + id: ast::DUMMY_NODE_ID, + rules: BlockCheckMode::Default, + span: span, + }) } fn expr(&self, span: Span, node: ast::ExprKind) -> P<ast::Expr> { @@ -962,14 +962,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ids: Vec<ast::Ident>, stmts: Vec<ast::Stmt>) -> P<ast::Expr> { - 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<ast::Stmt>) -> P<ast::Expr> { - self.lambda0(span, self.block(span, stmts, None)) + self.lambda0(span, self.block(span, stmts)) } fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>, ident: ast::Ident) -> P<ast::Expr> { - 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::Ty>) -> ast::Arg { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 32635f5cdd2..3036a88430a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -611,23 +611,14 @@ pub fn expand_block(blk: P<Block>, fld: &mut MacroExpander) -> P<Block> { // expand the elements of a block. pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> { - 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 3dc7c92f016..68527b0797d 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -513,10 +513,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(sp, vector)); let expanded = expand_wrapper(cx, sp, cx_expr, block, &[&["syntax", "ext", "quote", "rt"]]); base::MacEager::expr(expanded) @@ -766,8 +764,9 @@ fn statements_mk_tt(cx: &ExtCtxt, tt: &TokenTree, matcher: bool) -> Vec<ast::Stm let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp)); let mut tts_stmts = vec![stmt_let_tt]; tts_stmts.extend(statements_mk_tts(cx, &seq.tts[..], matcher)); - let e_tts = cx.expr_block(cx.block(sp, tts_stmts, - Some(cx.expr_ident(sp, id_ext("tt"))))); + tts_stmts.push(cx.stmt_expr(cx.expr_ident(sp, id_ext("tt")))); + let e_tts = cx.expr_block(cx.block(sp, tts_stmts)); + let e_separator = match seq.separator { Some(ref sep) => cx.expr_some(sp, expr_mk_token(cx, sp, sep)), None => cx.expr_none(sp), @@ -882,10 +881,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(sp, vector)); (cx_expr, block) } @@ -899,13 +896,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::<Vec<_>>(); + stmts.push(cx.stmt_expr(expr)); - cx.expr_block(cx.block_all(sp, stmts, Some(expr))) + cx.expr_block(cx.block(sp, stmts)) } fn expand_parse_call(cx: &ExtCtxt, |
