Skip to content

Commit

Permalink
Generate a temporary for assign_ops. Issue rust-lang#2581
Browse files Browse the repository at this point in the history
  • Loading branch information
eholk committed Jun 13, 2012
1 parent c04c8cc commit 3391b31
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/rustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1439,6 +1439,7 @@ fn copy_val_no_check(bcx: block, action: copy_action, dst: ValueRef,
// doesn't need to be dropped. (Issue #839)
fn move_val(cx: block, action: copy_action, dst: ValueRef,
src: lval_result, t: ty::t) -> block {
assert !cx.terminated;
let _icx = cx.insn_ctxt("move_val");
let mut src_val = src.val;
let tcx = cx.tcx();
Expand Down Expand Up @@ -1721,15 +1722,24 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop,
some(origin) {
let callee_id = ast_util::op_expr_callee_id(ex);
let fty = node_id_type(bcx, callee_id);
ret trans_call_inner(

let dty = expr_ty(bcx, dst);
let target = alloc_ty(bcx, dty);

let bcx = trans_call_inner(
bcx, ex.info(), fty,
expr_ty(bcx, ex),
{|bcx|
// FIXME provide the already-computed address, not the expr
// #2528
impl::trans_method_callee(bcx, callee_id, dst, origin)
},
arg_exprs([src]), save_in(lhs_res.val));
arg_exprs([src]), save_in(target));

ret move_val(bcx, DROP_EXISTING, lhs_res.val,
// FIXME: should kind be owned?
{bcx: bcx, val: target, kind: owned},
dty);
}
_ {}
}
Expand Down
74 changes: 74 additions & 0 deletions src/test/run-pass/operator-overloading-leaks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// The cases commented as "Leaks" need to not leak. Issue #2581

impl methods<T: copy> for [T] {
fn -(x: [T]/&) -> [T] {
[x[0], x[0], x[0]]
}

fn foo(x: [T]/&) -> [T] {
[x[0], x[0], x[0]]
}
}

impl methods<T: copy> for ~T {
fn +(rhs: ~T) -> ~T {
rhs
}
}

impl methods for ~int {
fn -(rhs: ~int) -> ~int {
~(*self - *rhs)
}
}

impl methods for @int {
fn +(rhs: @int) -> @int {
@(*self + *rhs)
}
}

fn main() {
// leaks
let mut bar = [1, 2, 3];
bar -= [3, 2, 1];
bar -= [4, 5, 6];

io::println(#fmt("%?", bar));

// okay
let mut bar = [1, 2, 3];
bar = bar.foo([3, 2, 1]);
bar = bar.foo([4, 5, 6]);

io::println(#fmt("%?", bar));

// okay
let mut bar = [1, 2, 3];
bar = bar - [3, 2, 1];
bar = bar - [4, 5, 6];

io::println(#fmt("%?", bar));

// Leaks
let mut bar = ~1;
bar += ~2;
bar += ~3;

io:: println(#fmt("%?", bar));

// Leaks
let mut bar = ~1;
bar -= ~2;
bar -= ~3;

io:: println(#fmt("%?", bar));

// Leaks
let mut bar = @1;
bar += @2;
bar += @3;

io:: println(#fmt("%?", bar));

}

0 comments on commit 3391b31

Please sign in to comment.