Insert plumbing for move that behaves just like assign.

This commit is contained in:
Michael Sullivan 2011-05-27 17:38:52 -07:00 committed by Graydon Hoare
parent 43342e9a66
commit 5e7bba3d23
9 changed files with 81 additions and 0 deletions

View File

@ -257,6 +257,7 @@ tag expr_ {
expr_do_while(block, @expr, ann);
expr_alt(@expr, vec[arm], ann);
expr_block(block, ann);
expr_move(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_assign(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_assign_op(binop, @expr /* TODO: @expr|is_lval */, @expr, ann);
expr_send(@expr /* TODO: @expr|is_lval */, @expr, ann);

View File

@ -1251,6 +1251,12 @@ fn parse_assign_expr(&parser p) -> @ast::expr {
ret @spanned(lo, rhs.span.hi,
ast::expr_assign_op(aop, lhs, rhs, p.get_ann()));
}
case (token::LARROW) {
p.bump();
auto rhs = parse_expr(p);
ret @spanned(lo, rhs.span.hi,
ast::expr_move(lhs, rhs, p.get_ann()));
}
case (token::SEND) {
p.bump();
auto rhs = parse_expr(p);

View File

@ -5500,6 +5500,18 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output)
ret res(next_cx, sub.val);
}
case (ast::expr_move(?dst, ?src, ?ann)) {
auto lhs_res = trans_lval(cx, dst);
assert (lhs_res.is_mem);
*(lhs_res.res.bcx) = rec(sp=src.span with *(lhs_res.res.bcx));
auto rhs_res = trans_expr(lhs_res.res.bcx, src);
auto t = node_ann_type(cx.fcx.lcx.ccx, ann);
// FIXME: calculate copy init-ness in typestate.
// FIXME: do all of the special move stuff
ret copy_ty(rhs_res.bcx, DROP_EXISTING,
lhs_res.res.val, rhs_res.val, t);
}
case (ast::expr_assign(?dst, ?src, ?ann)) {
auto lhs_res = trans_lval(cx, dst);
assert (lhs_res.is_mem);

View File

@ -109,6 +109,7 @@ import front::ast::expr_rec;
import front::ast::expr_if;
import front::ast::expr_binary;
import front::ast::expr_unary;
import front::ast::expr_move;
import front::ast::expr_assign;
import front::ast::expr_assign_op;
import front::ast::expr_while;
@ -362,6 +363,17 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) -> () {
vec::plus_option[@expr](es, maybe_base);
find_pre_post_exprs(fcx, es, a);
}
case (expr_move(?lhs, ?rhs, ?a)) {
// FIXME: this needs to deinitialize the rhs
alt (lhs.node) {
case (expr_path(?p, ?a_lhs)) {
gen_if_local(fcx, lhs, rhs, a, a_lhs);
}
case (_) {
find_pre_post_exprs(fcx, [lhs, rhs], a);
}
}
}
case (expr_assign(?lhs, ?rhs, ?a)) {
alt (lhs.node) {
case (expr_path(?p, ?a_lhs)) {

View File

@ -119,6 +119,7 @@ import front::ast::expr_rec;
import front::ast::expr_if;
import front::ast::expr_binary;
import front::ast::expr_unary;
import front::ast::expr_move;
import front::ast::expr_assign;
import front::ast::expr_assign_op;
import front::ast::expr_while;
@ -329,6 +330,32 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
}
ret changed;
}
case (expr_move(?lhs, ?rhs, ?a)) {
// FIXME: this needs to deinitialize the rhs
extend_prestate_ann(fcx.ccx, a, pres);
alt (lhs.node) {
case (expr_path(?p, ?a_lhs)) {
// assignment to local var
changed = pure_exp(fcx.ccx, a_lhs, pres) || changed;
changed = find_pre_post_state_expr(fcx, pres, rhs)
|| changed;
changed = extend_poststate_ann(fcx.ccx, a,
expr_poststate(fcx.ccx, rhs)) || changed;
changed = gen_if_local(fcx, a_lhs, a)|| changed;
}
case (_) {
// assignment to something that must already have been init'd
changed = find_pre_post_state_expr(fcx, pres, lhs)
|| changed;
changed = find_pre_post_state_expr(fcx,
expr_poststate(fcx.ccx, lhs), rhs) || changed;
changed = extend_poststate_ann(fcx.ccx, a,
expr_poststate(fcx.ccx, rhs)) || changed;
}
}
ret changed;
}
case (expr_assign(?lhs, ?rhs, ?a)) {
extend_prestate_ann(fcx.ccx, a, pres);

View File

@ -1767,6 +1767,7 @@ fn expr_ann(&@ast::expr e) -> ast::ann {
case (ast::expr_do_while(_,_,?a)) { ret a; }
case (ast::expr_alt(_,_,?a)) { ret a; }
case (ast::expr_block(_,?a)) { ret a; }
case (ast::expr_move(_,_,?a)) { ret a; }
case (ast::expr_assign(_,_,?a)) { ret a; }
case (ast::expr_assign_op(_,_,_,?a)) { ret a; }
case (ast::expr_send(_,_,?a)) { ret a; }

View File

@ -1388,6 +1388,13 @@ mod pushdown {
write::ty_only_fixup(scx, ann.id, t);
pushdown_block(scx, t, bloc);
}
case (ast::expr_move(?lhs_0, ?rhs_0, ?ann)) {
auto t = demand::autoderef(scx, e.span, expected,
ann_to_type(scx.fcx.ccx.tcx.node_types, ann), adk);
pushdown_expr(scx, expected, lhs_0);
pushdown_expr(scx, expected, rhs_0);
write::ty_only_fixup(scx, ann.id, t);
}
case (ast::expr_assign(?lhs_0, ?rhs_0, ?ann)) {
auto t = demand::autoderef(scx, e.span, expected,
ann_to_type(scx.fcx.ccx.tcx.node_types, ann), adk);
@ -2106,6 +2113,11 @@ fn check_expr(&@stmt_ctxt scx, &@ast::expr expr) {
write::nil_ty(scx.fcx.ccx.tcx, a.id);
}
case (ast::expr_move(?lhs, ?rhs, ?a)) {
require_impure(scx.fcx.ccx.tcx.sess, scx.fcx.purity, expr.span);
check_assignment(scx, lhs, rhs, a);
}
case (ast::expr_assign(?lhs, ?rhs, ?a)) {
require_impure(scx.fcx.ccx.tcx.sess, scx.fcx.purity, expr.span);
check_assignment(scx, lhs, rhs, a);

View File

@ -394,6 +394,10 @@ fn walk_expr(&ast_visitor v, @ast::expr e) {
walk_expr(v, a);
walk_expr(v, b);
}
case (ast::expr_move(?a, ?b, _)) {
walk_expr(v, a);
walk_expr(v, b);
}
case (ast::expr_assign_op(_, ?a, ?b, _)) {
walk_expr(v, a);
walk_expr(v, b);

View File

@ -690,6 +690,12 @@ fn print_expr(&ps s, &@ast::expr expr) {
ibox(s.s, 0u);
print_block(s, block);
}
case (ast::expr_move(?lhs,?rhs,_)) {
print_expr(s, lhs);
space(s.s);
wrd1(s, "<-");
print_expr(s, rhs);
}
case (ast::expr_assign(?lhs,?rhs,_)) {
print_expr(s, lhs);
space(s.s);