diff options
Diffstat (limited to 'src/comp/middle')
| -rw-r--r-- | src/comp/middle/alias.rs | 5 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 14 |
2 files changed, 15 insertions, 4 deletions
diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs index 88d4f3b56a5..b4cd16d1ee9 100644 --- a/src/comp/middle/alias.rs +++ b/src/comp/middle/alias.rs @@ -255,7 +255,7 @@ fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [binding] { local_id: 0u, unsafe_tys: unsafe_set(root.mut), mutable copied: alt arg_t.mode { - ast::by_move. { copied } + ast::by_move. | ast::by_copy. { copied } ast::by_mut_ref. { not_allowed } _ { i + 1u == by_ref ? not_allowed : not_copied } }}]; @@ -337,6 +337,9 @@ fn check_ret_ref(cx: ctx, sc: scope, mut: bool, arg_node_id: node_id, if arg.mode == ast::by_move { bad = some("a move-mode parameter"); } + if arg.mode == ast::by_copy { + bad = some("a copy-mode parameter"); + } if cur_node != arg_node_id { bad = some("the wrong parameter"); } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index d5d2620fa6f..b57953d20a6 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -67,8 +67,7 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) -> // that would obviate the need for this check check non_ty_var(cx, arg_ty); let llty = type_of_inner(cx, sp, arg_ty); - if arg.mode == ast::by_val { atys += [llty]; } - else { atys += [T_ptr(llty)]; } + atys += [arg.mode == ast::by_val ? llty : T_ptr(llty)]; } ret atys; } @@ -3636,6 +3635,15 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef, if arg.mode == ast::by_val && (lv.kind == owned || !imm) { val = Load(bcx, val); } + } else if arg.mode == ast::by_copy { + let {bcx: cx, val: alloc} = alloc_ty(bcx, e_ty); + bcx = cx; + if lv.kind == temporary { revoke_clean(bcx, val); } + if lv.kind == owned || !ty::type_is_immediate(ccx.tcx, e_ty) { + bcx = memmove_ty(bcx, alloc, val, e_ty); + } else { Store(bcx, val, alloc); } + val = alloc; + if lv.kind != temporary { bcx = take_ty(bcx, val, e_ty); } } else if ty::type_is_immediate(ccx.tcx, e_ty) && lv.kind != owned { let r = do_spill(bcx, val, e_ty); val = r.val; @@ -4989,7 +4997,7 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg], let argval = alt fcx.llargs.get(id) { local_mem(v) { v } }; alt arg.mode { ast::by_mut_ref. { } - ast::by_move. { add_clean(bcx, argval, arg.ty); } + ast::by_move. | ast::by_copy. { add_clean(bcx, argval, arg.ty); } ast::by_val. { if !ty::type_is_immediate(bcx_tcx(bcx), arg.ty) { let {bcx: cx, val: alloc} = alloc_ty(bcx, arg.ty); |
