1
Fork 0

Change expansion of for loop to use a match statement

so that the "innermost enclosing statement" used for rvalue
temporaries matches up with user expectations
This commit is contained in:
Niko Matsakis 2014-01-17 08:30:06 -05:00
parent 8f16356e5f
commit b1da8c618f
2 changed files with 82 additions and 18 deletions

View file

@ -137,15 +137,16 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
// to:
//
// {
// let _i = &mut <src_expr>;
// ['<ident>:] loop {
// match i.next() {
// match &mut <src_expr> {
// i => {
// ['<ident>:] loop {
// match i.next() {
// None => break,
// Some(<src_pat>) => <src_loop_block>
// }
// }
// }
// }
// }
let local_ident = token::gensym_ident("i");
let next_ident = fld.cx.ident_of("next");
@ -154,10 +155,6 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
let local_path = fld.cx.path_ident(span, local_ident);
let some_path = fld.cx.path_ident(span, fld.cx.ident_of("Some"));
// `let i = &mut <src_expr>`
let iter_decl_stmt = fld.cx.stmt_let(span, false, local_ident,
fld.cx.expr_mut_addr_of(span, src_expr));
// `None => break ['<ident>];`
let none_arm = {
// FIXME #6993: this map goes away:
@ -185,16 +182,13 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
ast::ExprLoop(fld.cx.block_expr(match_expr),
opt_ident));
// `{ let ... ; loop { ... } }`
let block = fld.cx.block(span,
~[iter_decl_stmt],
Some(loop_expr));
// `i => loop { ... }`
@ast::Expr {
id: ast::DUMMY_NODE_ID,
node: ast::ExprBlock(block),
span: span,
}
// `match &mut <src_expr> { i => loop { ... } }`
let discrim = fld.cx.expr_mut_addr_of(span, src_expr);
let i_pattern = fld.cx.pat_ident(span, local_ident);
let arm = fld.cx.arm(span, ~[i_pattern], loop_expr);
fld.cx.expr_match(span, discrim, ~[arm])
}
_ => noop_fold_expr(e, fld)