diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index 92913c3e28d..7f3e49de551 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -10,8 +10,8 @@ export log_str; export lock_and_signal, condition, methods; enum type_desc = { - size: libc::size_t, - align: libc::size_t + size: uint, + align: uint // Remaining fields not listed }; diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index fed358d9388..65fcd0a59ca 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -31,11 +31,11 @@ impl arena for arena { head = chunk(uint::next_power_of_two(new_min_chunk_size + 1u)); self.chunks = @cons(head, self.chunks); - ret self.alloc(n_bytes, align); + ret self.alloc_inner(n_bytes, align); } #[inline(always)] - fn alloc(n_bytes: uint, align: uint) -> *() { + fn alloc_inner(n_bytes: uint, align: uint) -> *() { let alignm1 = align - 1u; let mut head = list::head(self.chunks); @@ -52,5 +52,13 @@ impl arena for arena { ret unsafe::reinterpret_cast(p); } } + + #[inline(always)] + fn alloc(tydesc: *()) -> *() { + unsafe { + let tydesc = tydesc as *sys::type_desc; + self.alloc_inner((*tydesc).size, (*tydesc).align) + } + } } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 05b17d1fbe7..823795d9155 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -3693,9 +3693,9 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block { ret trans_assign_op(bcx, e, op, dst, src); } ast::expr_new(pool, alloc_id, val) { - // First, call pool->alloc(sz, align) to get back a void*. Then, - // cast this memory to the required type and evaluate value into - // it. + // First, call pool->alloc(tydesc) to get back a void*. + // Then, cast this memory to the required type and evaluate value + // into it. let ccx = bcx.ccx(); // Allocate space for the ptr that will be returned from @@ -3706,24 +3706,21 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block { #debug["ptr_ty = %s", ppaux::ty_to_str(tcx, ptr_ty)]; #debug["ptr_ptr_val = %s", val_str(ccx.tn, ptr_ptr_val)]; - let void_ty = ty::mk_ptr(tcx, {ty: ty::mk_nil(tcx), - mutbl: ast::m_imm}); - let voidval = { - let llvoid_ty = type_of(ccx, void_ty); - PointerCast(bcx, ptr_ptr_val, T_ptr(llvoid_ty)) - }; - + let void_ty = ty::mk_nil_ptr(tcx); + let llvoid_ty = type_of(ccx, void_ty); + let voidval = PointerCast(bcx, ptr_ptr_val, T_ptr(llvoid_ty)); #debug["voidval = %s", val_str(ccx.tn, voidval)]; - let llval_ty = type_of(ccx, expr_ty(bcx, val)); - let args = - ~[llsize_of(ccx, llval_ty), llalign_of(ccx, llval_ty)]; + let static_ti = get_tydesc(ccx, expr_ty(bcx, val)); + lazily_emit_all_tydesc_glue(ccx, static_ti); + let lltydesc = PointerCast(bcx, static_ti.tydesc, llvoid_ty); + let origin = bcx.ccx().maps.method_map.get(alloc_id); let bcx = trans_call_inner( bcx, e.info(), node_id_type(bcx, alloc_id), void_ty, |bcx| impl::trans_method_callee(bcx, alloc_id, pool, origin), - arg_vals(args), + arg_vals(~[lltydesc]), save_in(voidval)); #debug["dest = %s", dest_str(ccx, dest)]; diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index bd9230613d3..504023687dd 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -1631,17 +1631,15 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, some(entry) { fcx.ccx.method_map.insert(alloc_id, entry); - // Check that the alloc() method has the expected type, which - // should be fn(sz: uint, align: uint) -> *(). + // Check that the alloc() method has the expected + // type, which should be fn(tydesc: *()) -> *(). let expected_ty = { - let ty_uint = ty::mk_uint(tcx); let ty_nilp = ty::mk_ptr(tcx, {ty: ty::mk_nil(tcx), mutbl: ast::m_imm}); - let m = ast::expl(ty::default_arg_mode_for_ty(ty_uint)); + let m = ast::expl(ty::default_arg_mode_for_ty(ty_nilp)); ty::mk_fn(tcx, {purity: ast::impure_fn, proto: ast::proto_any, - inputs: ~[{mode: m, ty: ty_uint}, - {mode: m, ty: ty_uint}], + inputs: ~[{mode: m, ty: ty_nilp}], output: ty_nilp, ret_style: ast::return_val, constraints: ~[]}) diff --git a/src/test/compile-fail/placement-new-bad-method-type.rs b/src/test/compile-fail/placement-new-bad-method-type.rs index 10db67161d1..2126a6bddc6 100644 --- a/src/test/compile-fail/placement-new-bad-method-type.rs +++ b/src/test/compile-fail/placement-new-bad-method-type.rs @@ -11,5 +11,5 @@ impl methods for malloc_pool { fn main() { let p = &malloc_pool(()); let x = new(*p) 4u; - //~^ ERROR mismatched types: expected `fn(uint, uint) -> *()` + //~^ ERROR mismatched types: expected `fn(*()) -> *()` } diff --git a/src/test/run-pass/placement-new-leaky.rs b/src/test/run-pass/placement-new-leaky.rs index d33e9311a29..85363c432e0 100644 --- a/src/test/run-pass/placement-new-leaky.rs +++ b/src/test/run-pass/placement-new-leaky.rs @@ -3,11 +3,17 @@ import libc, unsafe; enum malloc_pool = (); impl methods for malloc_pool { - fn alloc(sz: uint, align: uint) -> *() { + fn alloc_inner(sz: uint, align: uint) -> *() { unsafe { unsafe::reinterpret_cast(libc::malloc(sz as libc::size_t)) } } + fn alloc(tydesc: *()) -> *() { + unsafe { + let tydesc = tydesc as *sys::type_desc; + self.alloc_inner((*tydesc).size, (*tydesc).align) + } + } } fn main() { diff --git a/src/test/run-pass/regions-mock-trans-impls.rs b/src/test/run-pass/regions-mock-trans-impls.rs index 077ca3d51ed..cdd8033a1d1 100644 --- a/src/test/run-pass/regions-mock-trans-impls.rs +++ b/src/test/run-pass/regions-mock-trans-impls.rs @@ -16,9 +16,15 @@ type ccx = { }; impl arena for arena { - fn alloc(sz: uint, _align: uint) -> *() unsafe { + fn alloc_inner(sz: uint, _align: uint) -> *() unsafe { ret unsafe::reinterpret_cast(libc::malloc(sz as libc::size_t)); } + fn alloc(tydesc: *()) -> *() { + unsafe { + let tydesc = tydesc as *sys::type_desc; + self.alloc_inner((*tydesc).size, (*tydesc).align) + } + } } fn h(bcx : &bcx) -> &bcx {