Skip to content

Commit 3391b31

Browse files
committed
Generate a temporary for assign_ops. Issue rust-lang#2581
1 parent c04c8cc commit 3391b31

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

src/rustc/middle/trans/base.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,6 +1439,7 @@ fn copy_val_no_check(bcx: block, action: copy_action, dst: ValueRef,
14391439
// doesn't need to be dropped. (Issue #839)
14401440
fn move_val(cx: block, action: copy_action, dst: ValueRef,
14411441
src: lval_result, t: ty::t) -> block {
1442+
assert !cx.terminated;
14421443
let _icx = cx.insn_ctxt("move_val");
14431444
let mut src_val = src.val;
14441445
let tcx = cx.tcx();
@@ -1721,15 +1722,24 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop,
17211722
some(origin) {
17221723
let callee_id = ast_util::op_expr_callee_id(ex);
17231724
let fty = node_id_type(bcx, callee_id);
1724-
ret trans_call_inner(
1725+
1726+
let dty = expr_ty(bcx, dst);
1727+
let target = alloc_ty(bcx, dty);
1728+
1729+
let bcx = trans_call_inner(
17251730
bcx, ex.info(), fty,
17261731
expr_ty(bcx, ex),
17271732
{|bcx|
17281733
// FIXME provide the already-computed address, not the expr
17291734
// #2528
17301735
impl::trans_method_callee(bcx, callee_id, dst, origin)
17311736
},
1732-
arg_exprs([src]), save_in(lhs_res.val));
1737+
arg_exprs([src]), save_in(target));
1738+
1739+
ret move_val(bcx, DROP_EXISTING, lhs_res.val,
1740+
// FIXME: should kind be owned?
1741+
{bcx: bcx, val: target, kind: owned},
1742+
dty);
17331743
}
17341744
_ {}
17351745
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// The cases commented as "Leaks" need to not leak. Issue #2581
2+
3+
impl methods<T: copy> for [T] {
4+
fn -(x: [T]/&) -> [T] {
5+
[x[0], x[0], x[0]]
6+
}
7+
8+
fn foo(x: [T]/&) -> [T] {
9+
[x[0], x[0], x[0]]
10+
}
11+
}
12+
13+
impl methods<T: copy> for ~T {
14+
fn +(rhs: ~T) -> ~T {
15+
rhs
16+
}
17+
}
18+
19+
impl methods for ~int {
20+
fn -(rhs: ~int) -> ~int {
21+
~(*self - *rhs)
22+
}
23+
}
24+
25+
impl methods for @int {
26+
fn +(rhs: @int) -> @int {
27+
@(*self + *rhs)
28+
}
29+
}
30+
31+
fn main() {
32+
// leaks
33+
let mut bar = [1, 2, 3];
34+
bar -= [3, 2, 1];
35+
bar -= [4, 5, 6];
36+
37+
io::println(#fmt("%?", bar));
38+
39+
// okay
40+
let mut bar = [1, 2, 3];
41+
bar = bar.foo([3, 2, 1]);
42+
bar = bar.foo([4, 5, 6]);
43+
44+
io::println(#fmt("%?", bar));
45+
46+
// okay
47+
let mut bar = [1, 2, 3];
48+
bar = bar - [3, 2, 1];
49+
bar = bar - [4, 5, 6];
50+
51+
io::println(#fmt("%?", bar));
52+
53+
// Leaks
54+
let mut bar = ~1;
55+
bar += ~2;
56+
bar += ~3;
57+
58+
io:: println(#fmt("%?", bar));
59+
60+
// Leaks
61+
let mut bar = ~1;
62+
bar -= ~2;
63+
bar -= ~3;
64+
65+
io:: println(#fmt("%?", bar));
66+
67+
// Leaks
68+
let mut bar = @1;
69+
bar += @2;
70+
bar += @3;
71+
72+
io:: println(#fmt("%?", bar));
73+
74+
}

0 commit comments

Comments
 (0)