diff options
| author | John Gallagher <jgallagher@bignerdranch.com> | 2014-10-02 22:45:46 -0400 |
|---|---|---|
| committer | John Gallagher <jgallagher@bignerdranch.com> | 2014-10-10 20:30:31 -0400 |
| commit | 0c2c8116a307e88f8327e0ea846d2c9c135193b7 (patch) | |
| tree | b9f17f6dc86f3e98b77b0eaf18a7d5ecb05bd7a4 /src/libsyntax/ext | |
| parent | 78a7676898d9f80ab540c6df5d4c9ce35bb50463 (diff) | |
| download | rust-0c2c8116a307e88f8327e0ea846d2c9c135193b7.tar.gz rust-0c2c8116a307e88f8327e0ea846d2c9c135193b7.zip | |
Teach libsyntax about `while let`
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index efe4b76354f..575dcf32dd6 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -67,6 +67,42 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { fld.cx.expr(span, ast::ExprWhile(cond, body, opt_ident)) } + // Desugar ExprWhileLet + // From: `[opt_ident]: while let <pat> = <expr> <body>` + ast::ExprWhileLet(pat, expr, body, opt_ident) => { + // to: + // + // [opt_ident]: loop { + // match <expr> { + // <pat> => <body>, + // _ => break + // } + // } + + // `<pat> => <body>` + let pat_arm = { + let body_expr = fld.cx.expr_block(body); + fld.cx.arm(pat.span, vec![pat], body_expr) + }; + + // `_ => break` + let break_arm = { + let pat_under = fld.cx.pat_wild(span); + let break_expr = fld.cx.expr_break(span); + fld.cx.arm(span, vec![pat_under], break_expr) + }; + + // `match <expr> { ... }` + let arms = vec![pat_arm, break_arm]; + let match_expr = fld.cx.expr(span, + ast::ExprMatch(expr, arms, ast::MatchWhileLetDesugar)); + + // `[opt_ident]: loop { ... }` + let loop_block = fld.cx.block_expr(match_expr); + let (loop_block, opt_ident) = expand_loop_block(loop_block, opt_ident, fld); + fld.cx.expr(span, ast::ExprLoop(loop_block, opt_ident)) + } + // Desugar ExprIfLet // From: `if let <pat> = <expr> <body> [<elseopt>]` ast::ExprIfLet(pat, expr, body, mut elseopt) => { |
