Make tag, resource and object constructors take their arguments by copy
Doing something like some([1, 2, 3]) will now no longer create a temporary copy of the vector. It will also be easier for the kind checker to see that putting a resource into a data-structure constructor is safe.
This commit is contained in:
parent
4e03112141
commit
cefff237bf
@ -3587,8 +3587,8 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
|
||||
};
|
||||
|
||||
// Actually construct the closure
|
||||
let closure = build_environment
|
||||
(bcx, lltydescs, env_vals + vec::map(env_expr, bound), true);
|
||||
let closure = build_environment(bcx, lltydescs, env_vals +
|
||||
vec::map({|x| env_expr(x)}, bound), true);
|
||||
bcx = closure.bcx;
|
||||
|
||||
// Make thunk
|
||||
@ -5163,12 +5163,9 @@ fn trans_res_ctor(cx: @local_ctxt, sp: span, dtor: ast::_fn,
|
||||
let lltop = bcx.llbb;
|
||||
let arg_t = arg_tys_of_fn(ccx, ctor_id)[0].ty;
|
||||
let tup_t = ty::mk_tup(ccx.tcx, [ty::mk_int(ccx.tcx), arg_t]);
|
||||
let arg;
|
||||
alt fcx.llargs.find(dtor.decl.inputs[0].id) {
|
||||
some(local_mem(x)) { arg = load_if_immediate(bcx, x, arg_t); }
|
||||
some(local_imm(x)) { arg = x; }
|
||||
_ { ccx.sess.span_fatal(sp, "unbound dtor decl in trans_res_ctor"); }
|
||||
}
|
||||
let arg = alt fcx.llargs.find(dtor.decl.inputs[0].id) {
|
||||
some(local_mem(x)) { x }
|
||||
};
|
||||
let llretptr = fcx.llretptr;
|
||||
if ty::type_has_dynamic_size(ccx.tcx, ret_t) {
|
||||
let llret_t = T_ptr(T_struct([ccx.int_type, llvm::LLVMTypeOf(arg)]));
|
||||
@ -5177,9 +5174,8 @@ fn trans_res_ctor(cx: @local_ctxt, sp: span, dtor: ast::_fn,
|
||||
|
||||
// FIXME: silly checks
|
||||
check type_is_tup_like(bcx, tup_t);
|
||||
let dst = GEP_tup_like(bcx, tup_t, llretptr, [0, 1]);
|
||||
bcx = dst.bcx;
|
||||
bcx = copy_val(bcx, INIT, dst.val, arg, arg_t);
|
||||
let {bcx, val: dst} = GEP_tup_like(bcx, tup_t, llretptr, [0, 1]);
|
||||
bcx = memmove_ty(bcx, dst, arg, arg_t);
|
||||
check type_is_tup_like(bcx, tup_t);
|
||||
let flag = GEP_tup_like(bcx, tup_t, llretptr, [0, 0]);
|
||||
bcx = flag.bcx;
|
||||
@ -5206,7 +5202,7 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
|
||||
let i = 0u;
|
||||
for varg: ast::variant_arg in variant.node.args {
|
||||
fn_args +=
|
||||
[{mode: ast::by_ref,
|
||||
[{mode: ast::by_copy,
|
||||
ty: varg.ty,
|
||||
ident: "arg" + uint::to_str(i, 10u),
|
||||
id: varg.id}];
|
||||
@ -5261,11 +5257,9 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
|
||||
if ty::type_contains_params(bcx_tcx(bcx), arg_ty) {
|
||||
lldestptr = PointerCast(bcx, lldestptr, val_ty(llarg));
|
||||
}
|
||||
llarg = load_if_immediate(bcx, llarg, arg_ty);
|
||||
bcx = copy_val(bcx, INIT, lldestptr, llarg, arg_ty);
|
||||
bcx = memmove_ty(bcx, lldestptr, llarg, arg_ty);
|
||||
i += 1u;
|
||||
}
|
||||
bcx = trans_block_cleanups(bcx, find_scope_cx(bcx));
|
||||
build_return(bcx);
|
||||
finish_fn(fcx, lltop);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
|
||||
// we're creating.
|
||||
let fn_args: [ast::arg] = [];
|
||||
for f: ast::obj_field in ob.fields {
|
||||
fn_args += [{mode: ast::by_ref, ty: f.ty, ident: f.ident,
|
||||
fn_args += [{mode: ast::by_copy, ty: f.ty, ident: f.ident,
|
||||
id: f.id}];
|
||||
}
|
||||
let fcx = new_fn_ctxt(cx, sp, llctor_decl);
|
||||
@ -174,28 +174,19 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
|
||||
let body_fields =
|
||||
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]);
|
||||
bcx = body_fields.bcx;
|
||||
// TODO: can we just get fields_ty out of body_ty instead?
|
||||
let fields_ty = ty::mk_tup(ccx.tcx, obj_fields);
|
||||
i = 0;
|
||||
for f: ast::obj_field in ob.fields {
|
||||
alt bcx.fcx.llargs.find(f.id) {
|
||||
some(arg1) {
|
||||
let arg = alt arg1 {
|
||||
local_mem(v) { load_if_immediate(bcx, v, arg_tys[i].ty) }
|
||||
local_imm(v) { v }
|
||||
};
|
||||
// TODO: can we just get fields_ty out of body_ty instead?
|
||||
let fields_ty: ty::t = ty::mk_tup(ccx.tcx, obj_fields);
|
||||
some(local_mem(arg)) {
|
||||
// Silly check
|
||||
check type_is_tup_like(bcx, fields_ty);
|
||||
let field =
|
||||
GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]);
|
||||
bcx = field.bcx;
|
||||
bcx = copy_val(bcx, INIT, field.val, arg, arg_tys[i].ty);
|
||||
bcx = memmove_ty(field.bcx, field.val, arg, arg_tys[i].ty);
|
||||
i += 1;
|
||||
}
|
||||
none. {
|
||||
bcx_ccx(bcx).sess.span_fatal(f.ty.span,
|
||||
"internal error in trans_obj");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,6 @@
|
||||
export mk_uint;
|
||||
export mk_uniq;
|
||||
export mk_var;
|
||||
export mk_iter_body_fn;
|
||||
export mode;
|
||||
export mt;
|
||||
export node_type_table;
|
||||
@ -587,11 +586,6 @@ fn mk_param(cx: ctxt, n: uint, k: ast::kind) -> t {
|
||||
|
||||
fn mk_native(cx: ctxt, did: def_id) -> t { ret gen_ty(cx, ty_native(did)); }
|
||||
|
||||
fn mk_iter_body_fn(cx: ctxt, output: t) -> t {
|
||||
ret mk_fn(cx, ast::proto_block, [{mode: ast::by_ref, ty: output}],
|
||||
ty::mk_nil(cx), ast::return_val, []);
|
||||
}
|
||||
|
||||
// Returns the one-level-deep type structure of the given type.
|
||||
pure fn struct(cx: ctxt, typ: t) -> sty { interner::get(*cx.ts, typ).struct }
|
||||
|
||||
|
@ -597,7 +597,7 @@ fn ty_of_obj_ctor(cx: @ctxt, id: ast::ident, ob: ast::_obj,
|
||||
for f: ast::obj_field in ob.fields {
|
||||
let g = bind getter(cx, _);
|
||||
let t_field = ast_ty_to_ty(cx.tcx, g, f.ty);
|
||||
t_inputs += [{mode: ast::by_ref, ty: t_field}];
|
||||
t_inputs += [{mode: ast::by_copy, ty: t_field}];
|
||||
}
|
||||
|
||||
let t_fn =
|
||||
@ -646,8 +646,7 @@ fn ty_of_item(cx: @ctxt, it: @ast::item) -> ty::ty_param_kinds_and_ty {
|
||||
let t_arg = ty_of_arg(cx, f.decl.inputs[0]);
|
||||
let t_res =
|
||||
{kinds: ty_param_kinds(tps),
|
||||
ty:
|
||||
ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty,
|
||||
ty: ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty,
|
||||
mk_ty_params(cx, tps))};
|
||||
cx.tcx.tcache.insert(local_def(it.id), t_res);
|
||||
ret t_res;
|
||||
@ -708,7 +707,7 @@ fn get_tag_variant_types(cx: @ctxt, tag_id: ast::def_id,
|
||||
let args: [arg] = [];
|
||||
for va: ast::variant_arg in variant.node.args {
|
||||
let arg_ty = ast_ty_to_ty(cx.tcx, f, va.ty);
|
||||
args += [{mode: ast::by_ref, ty: arg_ty}];
|
||||
args += [{mode: ast::by_copy, ty: arg_ty}];
|
||||
}
|
||||
let tag_t = ty::mk_tag(cx.tcx, tag_id, ty_param_tys);
|
||||
// FIXME: this will be different for constrained types
|
||||
@ -785,7 +784,7 @@ fn convert(cx: @ctxt, abi: @mutable option::t<ast::native_abi>,
|
||||
mk_ty_params(cx, tps));
|
||||
let t_ctor =
|
||||
ty::mk_fn(cx.tcx, ast::proto_shared(ast::sugar_normal),
|
||||
[t_arg], t_res,
|
||||
[{mode: ast::by_copy with t_arg}], t_res,
|
||||
ast::return_val, []);
|
||||
let t_dtor =
|
||||
ty::mk_fn(cx.tcx, ast::proto_shared(ast::sugar_normal),
|
||||
|
Loading…
Reference in New Issue
Block a user