From 1cda74deee3bdd1e373502cf3298ac552da2b863 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 15 Sep 2011 11:42:56 +0200 Subject: [PATCH] Add representation for by-ref let bindings Issue #918 --- src/comp/middle/alias.rs | 3 ++- src/comp/middle/mut.rs | 2 +- src/comp/middle/resolve.rs | 6 +++--- src/comp/middle/trans.rs | 4 ++-- src/comp/middle/tstate/auxiliary.rs | 6 ++++-- src/comp/middle/tstate/pre_post_conditions.rs | 2 +- src/comp/middle/typeck.rs | 2 +- src/comp/syntax/ast.rs | 4 +++- src/comp/syntax/fold.rs | 5 ++++- src/comp/syntax/parse/parser.rs | 10 ++++++---- src/comp/syntax/print/pprust.rs | 4 +++- src/comp/syntax/visit.rs | 2 +- 12 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs index c8536ef2ddb..f3850d977ee 100644 --- a/src/comp/middle/alias.rs +++ b/src/comp/middle/alias.rs @@ -144,7 +144,8 @@ fn visit_decl(cx: @ctx, d: @ast::decl, sc: scope, v: vt) { visit::visit_decl(d, sc, v); alt d.node { ast::decl_local(locs) { - for loc: @ast::local in locs { + // FIXME check that init is lvalue + for (style, loc) in locs { alt loc.node.init { some(init) { if init.op == ast::init_move { diff --git a/src/comp/middle/mut.rs b/src/comp/middle/mut.rs index 253b402fb04..11c56456ebf 100644 --- a/src/comp/middle/mut.rs +++ b/src/comp/middle/mut.rs @@ -142,7 +142,7 @@ fn visit_decl(cx: @ctx, d: @decl, e: (), v: visit::vt<()>) { visit::visit_decl(d, e, v); alt d.node { decl_local(locs) { - for loc: @local in locs { + for (_, loc) in locs { alt loc.node.init { some(init) { if init.op == init_move { check_move_rhs(cx, init.expr); } diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 4a1aa3ec8c6..587ad4541ce 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -371,7 +371,7 @@ fn visit_decl_with_scope(d: @decl, sc: scopes, v: vt) { }; alt d.node { decl_local(locs) { - for loc in locs { v.visit_local(loc, sc, v);; *loc_pos += 1u; } + for (_, loc) in locs { v.visit_local(loc, sc, v);; *loc_pos += 1u; } } decl_item(it) { v.visit_item(it, sc, v); } } @@ -797,7 +797,7 @@ fn lookup_in_block(name: ident, b: ast::blk_, pos: uint, loc_pos: uint, let j = vec::len(locs); while j > 0u { j -= 1u; - let loc = locs[j]; + let (_, loc) = locs[j]; if ns == ns_value && (i < pos || j < loc_pos) { alt lookup_in_pat(name, loc.node.pat) { some(did) { ret some(ast::def_local(did)); } @@ -1315,7 +1315,7 @@ fn check_block(e: @env, b: ast::blk, x: (), v: vt<()>) { alt d.node { ast::decl_local(locs) { let local_values = checker(*e, "value"); - for loc in locs { + for (_, loc) in locs { for each p in ast_util::pat_bindings(loc.node.pat) { let ident = alt p.node { pat_bind(n) { n } }; add_name(local_values, p.span, ident); diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index b6a1b9df198..3f517a4a7cd 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -4538,7 +4538,7 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> result { ast::stmt_decl(d, _) { alt d.node { ast::decl_local(locals) { - for local: @ast::local in locals { + for (_, local) in locals { bcx = init_local(bcx, local).bcx; } } @@ -4654,7 +4654,7 @@ iter block_locals(b: ast::blk) -> @ast::local { ast::stmt_decl(d, _) { alt d.node { ast::decl_local(locals) { - for local: @ast::local in locals { put local; } + for (_, local) in locals { put local; } } _ {/* fall through */ } } diff --git a/src/comp/middle/tstate/auxiliary.rs b/src/comp/middle/tstate/auxiliary.rs index 45c25980baf..39312e17ca1 100644 --- a/src/comp/middle/tstate/auxiliary.rs +++ b/src/comp/middle/tstate/auxiliary.rs @@ -1063,8 +1063,10 @@ fn local_to_bindings(loc: @local) -> binding { {lhs: lhs, rhs: loc.node.init} } -fn locals_to_bindings(locals: [@local]) -> [binding] { - vec::map(local_to_bindings, locals) +fn locals_to_bindings(locals: [(let_style, @local)]) -> [binding] { + let rslt = []; + for (_, loc) in locals { rslt += [local_to_bindings(loc)]; } + ret rslt; } fn callee_modes(fcx: fn_ctxt, callee: node_id) -> [ty::mode] { diff --git a/src/comp/middle/tstate/pre_post_conditions.rs b/src/comp/middle/tstate/pre_post_conditions.rs index a37092e97af..8cb28cfaca4 100644 --- a/src/comp/middle/tstate/pre_post_conditions.rs +++ b/src/comp/middle/tstate/pre_post_conditions.rs @@ -572,7 +572,7 @@ fn find_pre_post_stmt(fcx: fn_ctxt, s: stmt) { decl_local(alocals) { let e_pp; let prev_pp = empty_pre_post(num_constraints(fcx.enclosing)); - for alocal: @local in alocals { + for (_, alocal) in alocals { alt alocal.node.init { some(an_init) { /* LHS always becomes initialized, diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index d72a94b1e96..0e2ace6291b 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -2418,7 +2418,7 @@ fn check_stmt(fcx: @fn_ctxt, stmt: @ast::stmt) -> bool { node_id = id; alt decl.node { ast::decl_local(ls) { - for l: @ast::local in ls { bot |= check_decl_local(fcx, l); } + for (_, l) in ls { bot |= check_decl_local(fcx, l); } } ast::decl_item(_) {/* ignore for now */ } } diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index f064519cca3..5e6269a9a8f 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -149,7 +149,9 @@ type local = spanned; type decl = spanned; -tag decl_ { decl_local([@local]); decl_item(@item); } +tag let_style { let_copy; let_ref; } + +tag decl_ { decl_local([(let_style, @local)]); decl_item(@item); } type arm = {pats: [@pat], guard: option::t<@expr>, body: blk}; diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs index ad0edde86e6..d3702dacfc6 100644 --- a/src/comp/syntax/fold.rs +++ b/src/comp/syntax/fold.rs @@ -296,7 +296,10 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ { fn noop_fold_decl(d: decl_, fld: ast_fold) -> decl_ { ret alt d { - decl_local(ls) { decl_local(vec::map(fld.fold_local, ls)) } + decl_local(ls) { + decl_local(vec::map({|l| let (st, lc) = l; + (st, fld.fold_local(lc))}, ls)) + } decl_item(it) { decl_item(fld.fold_item(it)) } } } diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index 1ea3ddbec67..4a449c25a97 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -1505,11 +1505,13 @@ fn parse_local(p: parser, allow_init: bool) -> @ast::local { } fn parse_let(p: parser) -> @ast::decl { + fn parse_let_style(p: parser) -> ast::let_style { + eat(p, token::BINOP(token::AND)) ? ast::let_ref : ast::let_copy + } let lo = p.get_lo_pos(); - let locals = [parse_local(p, true)]; - while p.peek() == token::COMMA { - p.bump(); - locals += [parse_local(p, true)]; + let locals = [(parse_let_style(p), parse_local(p, true))]; + while eat(p, token::COMMA) { + locals += [(parse_let_style(p), parse_local(p, true))]; } ret @spanned(lo, p.get_last_hi_pos(), ast::decl_local(locals)); } diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs index c550531e386..b6964b429f5 100644 --- a/src/comp/syntax/print/pprust.rs +++ b/src/comp/syntax/print/pprust.rs @@ -1024,8 +1024,10 @@ fn print_decl(s: ps, decl: @ast::decl) { space_if_not_bol(s); ibox(s, indent_unit); word_nbsp(s, "let"); - fn print_local(s: ps, loc: @ast::local) { + fn print_local(s: ps, loc_st: (ast::let_style, @ast::local)) { + let (st, loc) = loc_st; ibox(s, indent_unit); + if st == ast::let_ref { word(s.s, "&"); } print_local_decl(s, loc); end(s); alt loc.node.init { diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs index a50785ced24..386f5564781 100644 --- a/src/comp/syntax/visit.rs +++ b/src/comp/syntax/visit.rs @@ -212,7 +212,7 @@ fn visit_stmt(s: @stmt, e: E, v: vt) { fn visit_decl(d: @decl, e: E, v: vt) { alt d.node { decl_local(locs) { - for loc: @ast::local in locs { v.visit_local(loc, e, v); } + for (_, loc) in locs { v.visit_local(loc, e, v); } } decl_item(it) { v.visit_item(it, e, v); } }