Skip to content

Commit cefff23

Browse files
committed
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.
1 parent 4e03112 commit cefff23

File tree

4 files changed

+18
-40
lines changed

4 files changed

+18
-40
lines changed

src/comp/middle/trans.rs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3587,8 +3587,8 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
35873587
};
35883588

35893589
// Actually construct the closure
3590-
let closure = build_environment
3591-
(bcx, lltydescs, env_vals + vec::map(env_expr, bound), true);
3590+
let closure = build_environment(bcx, lltydescs, env_vals +
3591+
vec::map({|x| env_expr(x)}, bound), true);
35923592
bcx = closure.bcx;
35933593

35943594
// Make thunk
@@ -5163,12 +5163,9 @@ fn trans_res_ctor(cx: @local_ctxt, sp: span, dtor: ast::_fn,
51635163
let lltop = bcx.llbb;
51645164
let arg_t = arg_tys_of_fn(ccx, ctor_id)[0].ty;
51655165
let tup_t = ty::mk_tup(ccx.tcx, [ty::mk_int(ccx.tcx), arg_t]);
5166-
let arg;
5167-
alt fcx.llargs.find(dtor.decl.inputs[0].id) {
5168-
some(local_mem(x)) { arg = load_if_immediate(bcx, x, arg_t); }
5169-
some(local_imm(x)) { arg = x; }
5170-
_ { ccx.sess.span_fatal(sp, "unbound dtor decl in trans_res_ctor"); }
5171-
}
5166+
let arg = alt fcx.llargs.find(dtor.decl.inputs[0].id) {
5167+
some(local_mem(x)) { x }
5168+
};
51725169
let llretptr = fcx.llretptr;
51735170
if ty::type_has_dynamic_size(ccx.tcx, ret_t) {
51745171
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,
51775174

51785175
// FIXME: silly checks
51795176
check type_is_tup_like(bcx, tup_t);
5180-
let dst = GEP_tup_like(bcx, tup_t, llretptr, [0, 1]);
5181-
bcx = dst.bcx;
5182-
bcx = copy_val(bcx, INIT, dst.val, arg, arg_t);
5177+
let {bcx, val: dst} = GEP_tup_like(bcx, tup_t, llretptr, [0, 1]);
5178+
bcx = memmove_ty(bcx, dst, arg, arg_t);
51835179
check type_is_tup_like(bcx, tup_t);
51845180
let flag = GEP_tup_like(bcx, tup_t, llretptr, [0, 0]);
51855181
bcx = flag.bcx;
@@ -5206,7 +5202,7 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
52065202
let i = 0u;
52075203
for varg: ast::variant_arg in variant.node.args {
52085204
fn_args +=
5209-
[{mode: ast::by_ref,
5205+
[{mode: ast::by_copy,
52105206
ty: varg.ty,
52115207
ident: "arg" + uint::to_str(i, 10u),
52125208
id: varg.id}];
@@ -5261,11 +5257,9 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
52615257
if ty::type_contains_params(bcx_tcx(bcx), arg_ty) {
52625258
lldestptr = PointerCast(bcx, lldestptr, val_ty(llarg));
52635259
}
5264-
llarg = load_if_immediate(bcx, llarg, arg_ty);
5265-
bcx = copy_val(bcx, INIT, lldestptr, llarg, arg_ty);
5260+
bcx = memmove_ty(bcx, lldestptr, llarg, arg_ty);
52665261
i += 1u;
52675262
}
5268-
bcx = trans_block_cleanups(bcx, find_scope_cx(bcx));
52695263
build_return(bcx);
52705264
finish_fn(fcx, lltop);
52715265
}

src/comp/middle/trans_objects.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
4141
// we're creating.
4242
let fn_args: [ast::arg] = [];
4343
for f: ast::obj_field in ob.fields {
44-
fn_args += [{mode: ast::by_ref, ty: f.ty, ident: f.ident,
44+
fn_args += [{mode: ast::by_copy, ty: f.ty, ident: f.ident,
4545
id: f.id}];
4646
}
4747
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,
174174
let body_fields =
175175
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]);
176176
bcx = body_fields.bcx;
177+
// TODO: can we just get fields_ty out of body_ty instead?
178+
let fields_ty = ty::mk_tup(ccx.tcx, obj_fields);
177179
i = 0;
178180
for f: ast::obj_field in ob.fields {
179181
alt bcx.fcx.llargs.find(f.id) {
180-
some(arg1) {
181-
let arg = alt arg1 {
182-
local_mem(v) { load_if_immediate(bcx, v, arg_tys[i].ty) }
183-
local_imm(v) { v }
184-
};
185-
// TODO: can we just get fields_ty out of body_ty instead?
186-
let fields_ty: ty::t = ty::mk_tup(ccx.tcx, obj_fields);
182+
some(local_mem(arg)) {
187183
// Silly check
188184
check type_is_tup_like(bcx, fields_ty);
189185
let field =
190186
GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]);
191-
bcx = field.bcx;
192-
bcx = copy_val(bcx, INIT, field.val, arg, arg_tys[i].ty);
187+
bcx = memmove_ty(field.bcx, field.val, arg, arg_tys[i].ty);
193188
i += 1;
194189
}
195-
none. {
196-
bcx_ccx(bcx).sess.span_fatal(f.ty.span,
197-
"internal error in trans_obj");
198-
}
199190
}
200191
}
201192

src/comp/middle/ty.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ export mk_type;
8484
export mk_uint;
8585
export mk_uniq;
8686
export mk_var;
87-
export mk_iter_body_fn;
8887
export mode;
8988
export mt;
9089
export node_type_table;
@@ -587,11 +586,6 @@ fn mk_type(_cx: ctxt) -> t { ret idx_type; }
587586

588587
fn mk_native(cx: ctxt, did: def_id) -> t { ret gen_ty(cx, ty_native(did)); }
589588

590-
fn mk_iter_body_fn(cx: ctxt, output: t) -> t {
591-
ret mk_fn(cx, ast::proto_block, [{mode: ast::by_ref, ty: output}],
592-
ty::mk_nil(cx), ast::return_val, []);
593-
}
594-
595589
// Returns the one-level-deep type structure of the given type.
596590
pure fn struct(cx: ctxt, typ: t) -> sty { interner::get(*cx.ts, typ).struct }
597591

src/comp/middle/typeck.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ mod collect {
597597
for f: ast::obj_field in ob.fields {
598598
let g = bind getter(cx, _);
599599
let t_field = ast_ty_to_ty(cx.tcx, g, f.ty);
600-
t_inputs += [{mode: ast::by_ref, ty: t_field}];
600+
t_inputs += [{mode: ast::by_copy, ty: t_field}];
601601
}
602602

603603
let t_fn =
@@ -646,8 +646,7 @@ mod collect {
646646
let t_arg = ty_of_arg(cx, f.decl.inputs[0]);
647647
let t_res =
648648
{kinds: ty_param_kinds(tps),
649-
ty:
650-
ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty,
649+
ty: ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty,
651650
mk_ty_params(cx, tps))};
652651
cx.tcx.tcache.insert(local_def(it.id), t_res);
653652
ret t_res;
@@ -708,7 +707,7 @@ mod collect {
708707
let args: [arg] = [];
709708
for va: ast::variant_arg in variant.node.args {
710709
let arg_ty = ast_ty_to_ty(cx.tcx, f, va.ty);
711-
args += [{mode: ast::by_ref, ty: arg_ty}];
710+
args += [{mode: ast::by_copy, ty: arg_ty}];
712711
}
713712
let tag_t = ty::mk_tag(cx.tcx, tag_id, ty_param_tys);
714713
// FIXME: this will be different for constrained types
@@ -785,7 +784,7 @@ mod collect {
785784
mk_ty_params(cx, tps));
786785
let t_ctor =
787786
ty::mk_fn(cx.tcx, ast::proto_shared(ast::sugar_normal),
788-
[t_arg], t_res,
787+
[{mode: ast::by_copy with t_arg}], t_res,
789788
ast::return_val, []);
790789
let t_dtor =
791790
ty::mk_fn(cx.tcx, ast::proto_shared(ast::sugar_normal),

0 commit comments

Comments
 (0)