diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 3f3bf9f665a..2bcc19b6c69 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3024,13 +3024,20 @@ fn memmove_ty(&@block_ctxt cx, ValueRef dst, ValueRef src, &ty::t t) -> // Duplicates the heap-owned memory owned by a value of the given type. fn duplicate_heap_parts(&@block_ctxt cx, ValueRef vptr, ty::t typ) -> result { alt (ty::struct(cx.fcx.lcx.ccx.tcx, typ)) { - case (ty::ty_ivec(?tm)) { - ret ivec::duplicate_heap_part(cx, vptr, tm.ty); - } - case (ty::ty_str) { - ret ivec::duplicate_heap_part(cx, vptr, - ty::mk_mach(cx.fcx.lcx.ccx.tcx, common::ty_u8)); + case (ty::ty_ivec(?tm)) { + ret ivec::duplicate_heap_part(cx, vptr, tm.ty); + } + case (ty::ty_istr) { + ret ivec::duplicate_heap_part(cx, vptr, + ty::mk_mach(cx.fcx.lcx.ccx.tcx, common::ty_u8)); + } + case (_) { // TODO: guard + if (ty::type_is_structural(cx.fcx.lcx.ccx.tcx, typ)) { + ret iter_structural_ty(cx, vptr, typ, duplicate_heap_parts); } + + ret res(cx, C_nil()); + } } } diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index fe2cba1180c..e392c8aa0f3 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1151,36 +1151,62 @@ fn type_is_signed(&ctxt cx, &t ty) -> bool { } fn type_owns_heap_mem(&ctxt cx, &t ty) -> bool { + auto result = false; alt (struct(cx, ty)) { - case (ty_ivec(_)) { ret true; } - case (ty_istr) { ret true; } + case (ty_ivec(_)) { result = true; } + case (ty_istr) { result = true; } - case (ty_nil) { ret false; } - case (ty_bot) { ret false; } - case (ty_bool) { ret false; } - case (ty_int) { ret false; } - case (ty_float) { ret false; } - case (ty_uint) { ret false; } - case (ty_machine(_)) { ret false; } - case (ty_char) { ret false; } - case (ty_str) { ret false; } - case (ty_tag(_,_)) { ret false; } - case (ty_box(_)) { ret false; } - case (ty_vec(_)) { ret false; } - case (ty_ptr(_)) { ret false; } - case (ty_port(_)) { ret false; } - case (ty_chan(_)) { ret false; } - case (ty_task) { ret false; } - case (ty_tup(_)) { ret false; } - case (ty_rec(_)) { ret false; } - case (ty_fn(_,_,_,_,_)) { ret false; } - case (ty_native_fn(_,_,_)) { ret false; } - case (ty_obj(_)) { ret false; } + // scalar types + case (ty_nil) { result = false; } + case (ty_bot) { result = false; } + case (ty_bool) { result = false; } + case (ty_int) { result = false; } + case (ty_float) { result = false; } + case (ty_uint) { result = false; } + case (ty_machine(_)) { result = false; } + case (ty_char) { result = false; } + case (ty_type) { result = false; } + case (ty_native) { result = false; } + + // boxed types + case (ty_str) { result = false; } + case (ty_box(_)) { result = false; } + case (ty_vec(_)) { result = false; } + case (ty_fn(_,_,_,_,_)) { result = false; } + case (ty_native_fn(_,_,_)) { result = false; } + case (ty_obj(_)) { result = false; } + + // structural types + case (ty_tag(?did, ?tps)) { + auto variants = tag_variants(cx, did); + for (variant_info variant in variants) { + auto tup_ty = mk_imm_tup(cx, variant.args); + // Perform any type parameter substitutions. + tup_ty = substitute_type_params(cx, tps, tup_ty); + if (type_owns_heap_mem(cx, tup_ty)) { result = true; } + } + } + case (ty_tup(?elts)) { + for (mt m in elts) { + if (type_owns_heap_mem(cx, m.ty)) { result = true; } + } + } + case (ty_rec(?flds)) { + for (field f in flds) { + if (type_owns_heap_mem(cx, f.mt.ty)) { result = true; } + } + } + + case (ty_ptr(_)) { result = false; } + case (ty_port(_)) { result = false; } + case (ty_chan(_)) { result = false; } + case (ty_task) { result = false; } + case (ty_tup(_)) { result = false; } + case (ty_rec(_)) { result = false; } case (ty_var(_)) { fail "ty_var in type_owns_heap_mem"; } - case (ty_param(_)) { ret false; } - case (ty_type) { ret false; } - case (ty_native) { ret false; } + case (ty_param(_)) { result = false; } } + ret result; } fn type_param(&ctxt cx, &t ty) -> option::t[uint] {