Skip to content

Commit 74f8eb5

Browse files
committed
rustc: Move duplicate_heap_parts to copy glue; add a test case
1 parent db478ed commit 74f8eb5

File tree

3 files changed

+27
-13
lines changed

3 files changed

+27
-13
lines changed

src/comp/middle/trans.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,6 +1933,9 @@ fn make_copy_glue(&@block_ctxt cx, ValueRef v, &ty::t t) {
19331933
bcx = incr_refcnt_of_boxed(cx, cx.build.Load(v)).bcx;
19341934
} else if (ty::type_is_structural(cx.fcx.lcx.ccx.tcx, t)) {
19351935
bcx = iter_structural_ty(cx, v, t, bind copy_ty(_, _, _)).bcx;
1936+
if (ty::type_owns_heap_mem(cx.fcx.lcx.ccx.tcx, t)) {
1937+
bcx = duplicate_heap_parts(bcx, v, t).bcx;
1938+
}
19361939
} else { bcx = cx; }
19371940
bcx.build.RetVoid();
19381941
}
@@ -3054,7 +3057,8 @@ fn compare(&@block_ctxt cx, ValueRef lhs, ValueRef rhs, &ty::t t,
30543057
}
30553058

30563059
fn copy_ty(&@block_ctxt cx, ValueRef v, ty::t t) -> result {
3057-
if (ty::type_has_pointers(cx.fcx.lcx.ccx.tcx, t)) {
3060+
if (ty::type_has_pointers(cx.fcx.lcx.ccx.tcx, t) ||
3061+
ty::type_owns_heap_mem(cx.fcx.lcx.ccx.tcx, t)) {
30583062
ret call_tydesc_glue(cx, v, t, abi::tydesc_field_copy_glue);
30593063
}
30603064
ret rslt(cx, C_nil());
@@ -3168,20 +3172,24 @@ fn copy_val(&@block_ctxt cx, copy_action action, ValueRef dst, ValueRef src,
31683172
ty::type_is_bot(ccx.tcx, t)) {
31693173
ret rslt(cx, C_nil());
31703174
} else if (ty::type_is_boxed(ccx.tcx, t)) {
3171-
auto r = copy_ty(cx, src, t);
3175+
auto bcx;
31723176
if (action == DROP_EXISTING) {
3173-
r = drop_ty(r.bcx, r.bcx.build.Load(dst), t);
3177+
bcx = drop_ty(cx, cx.build.Load(dst), t).bcx;
3178+
} else {
3179+
bcx = cx;
31743180
}
3175-
ret rslt(r.bcx, r.bcx.build.Store(src, dst));
3181+
bcx = copy_ty(bcx, src, t).bcx;
3182+
ret rslt(bcx, bcx.build.Store(src, dst));
31763183
} else if (ty::type_is_structural(ccx.tcx, t) ||
31773184
ty::type_has_dynamic_size(ccx.tcx, t)) {
3178-
auto r = copy_ty(cx, src, t);
3179-
if (action == DROP_EXISTING) { r = drop_ty(r.bcx, dst, t); }
3180-
r = memmove_ty(r.bcx, dst, src, t);
3181-
if (ty::type_owns_heap_mem(ccx.tcx, t)) {
3182-
r = duplicate_heap_parts(cx, dst, t);
3185+
auto bcx;
3186+
if (action == DROP_EXISTING) {
3187+
bcx = drop_ty(cx, dst, t).bcx;
3188+
} else {
3189+
bcx = cx;
31833190
}
3184-
ret r;
3191+
bcx = memmove_ty(bcx, dst, src, t).bcx;
3192+
ret copy_ty(bcx, dst, t);
31853193
}
31863194
ccx.sess.bug("unexpected type in trans::copy_val: " +
31873195
ty_to_str(ccx.tcx, t));

src/rt/rust_upcall.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,18 +452,17 @@ copy_elements(rust_task *task, type_desc *elem_t,
452452
void *pdst, void *psrc, size_t n)
453453
{
454454
char *dst = (char *)pdst, *src = (char *)psrc;
455+
memmove(dst, src, n);
455456

456-
// FIXME: Copy glue doesn't work this way.
457457
// increment the refcount of each element of the vector
458458
if (elem_t->copy_glue) {
459459
glue_fn *copy_glue = elem_t->copy_glue;
460460
size_t elem_size = elem_t->size;
461461
const type_desc **tydescs = elem_t->first_param;
462-
for (char *p = src; p < src+n; p += elem_size) {
462+
for (char *p = dst; p < dst+n; p += elem_size) {
463463
copy_glue(NULL, task, NULL, tydescs, p);
464464
}
465465
}
466-
memmove(dst, src, n);
467466
}
468467

469468
extern "C" CDECL void

src/test/run-pass/generic-ivec.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// xfail-stage0
2+
3+
fn f[T](@T v) {}
4+
fn main() {
5+
f(@~[ 1, 2, 3, 4, 5 ]);
6+
}
7+

0 commit comments

Comments
 (0)