diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index cf9e8252538..9237e35d9a0 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5052,6 +5052,10 @@ fn trans_expr_out(cx: &@block_ctxt, e: &@ast::expr, output: out_method) -> sub.bcx.build.Br(next_cx.llbb); ret rslt(next_cx, sub.val); } + ast::expr_copy(a) { + // FIXME: this has more-subtle semantics than just "fall through". + ret trans_expr_out(cx, a, output); + } ast::expr_move(dst, src) { let lhs_res = trans_lval(cx, dst); assert (lhs_res.is_mem); diff --git a/src/comp/middle/trans_alt.rs b/src/comp/middle/trans_alt.rs index 366a9adf53b..015e515c834 100644 --- a/src/comp/middle/trans_alt.rs +++ b/src/comp/middle/trans_alt.rs @@ -517,12 +517,13 @@ fn trans_alt(cx: &@block_ctxt, expr: &@ast::expr, arms: &[ast::arm], // Not alt-related, but similar to the pattern-munging code above fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef, - table: hashmap[ast::node_id, ValueRef], copy: bool) + table: hashmap[ast::node_id, ValueRef], + make_copy: bool) -> @block_ctxt { let ccx = bcx.fcx.lcx.ccx; alt pat.node { ast::pat_bind(_) { - if copy { + if make_copy { let ty = ty::node_id_to_monotype(ccx.tcx, pat.id); let llty = trans::type_of(ccx, pat.span, ty); let alloc = trans::alloca(bcx, llty); @@ -541,7 +542,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef, let args = extract_variant_args(bcx, pat.id, vdefs, val); let i = 0; for argval: ValueRef in args.vals { - bcx = bind_irrefutable_pat(bcx, sub.(i), argval, table, copy); + bcx = bind_irrefutable_pat(bcx, sub.(i), argval, table, + make_copy); i += 1; } } @@ -553,7 +555,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef, let ix: uint = ty::field_idx(ccx.sess, pat.span, f.ident, rec_fields); let r = trans::GEP_tup_like(bcx, rec_ty, val, ~[0, ix as int]); - bcx = bind_irrefutable_pat(r.bcx, f.pat, r.val, table, copy); + bcx = bind_irrefutable_pat(r.bcx, f.pat, r.val, table, make_copy); } } ast::pat_tup(elems) { @@ -561,7 +563,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef, let i = 0u; for elem in elems { let r = trans::GEP_tup_like(bcx, tup_ty, val, ~[0, i as int]); - bcx = bind_irrefutable_pat(r.bcx, elem, r.val, table, copy); + bcx = bind_irrefutable_pat(r.bcx, elem, r.val, table, make_copy); i += 1u; } } diff --git a/src/comp/middle/tstate/pre_post_conditions.rs b/src/comp/middle/tstate/pre_post_conditions.rs index 8af21dfe055..e08c6afa338 100644 --- a/src/comp/middle/tstate/pre_post_conditions.rs +++ b/src/comp/middle/tstate/pre_post_conditions.rs @@ -406,6 +406,10 @@ fn find_pre_post_expr(fcx: &fn_ctxt, e: @expr) { expr_tup(elts) { find_pre_post_exprs(fcx, elts, e.id); } + expr_copy(a) { + find_pre_post_expr(fcx, a); + copy_pre_post(fcx.ccx, e.id, a); + } expr_move(lhs, rhs) { handle_update(fcx, e, lhs, rhs, oper_move); } expr_swap(lhs, rhs) { handle_update(fcx, e, lhs, rhs, oper_swap); } expr_assign(lhs, rhs) { handle_update(fcx, e, lhs, rhs, oper_assign); } diff --git a/src/comp/middle/tstate/states.rs b/src/comp/middle/tstate/states.rs index ff36b791003..8776c0107ba 100644 --- a/src/comp/middle/tstate/states.rs +++ b/src/comp/middle/tstate/states.rs @@ -393,6 +393,9 @@ fn find_pre_post_state_expr(fcx: &fn_ctxt, pres: &prestate, e: @expr) -> ivec::len(elts)), elts, return); } + expr_copy(a) { + ret find_pre_post_state_sub(fcx, pres, a, e.id, none); + } expr_move(lhs, rhs) { ret find_pre_post_state_two(fcx, pres, lhs, rhs, e.id, oper_move); } diff --git a/src/comp/middle/tstate/tritv.rs b/src/comp/middle/tstate/tritv.rs index 998e20e19a3..1a280297bbe 100644 --- a/src/comp/middle/tstate/tritv.rs +++ b/src/comp/middle/tstate/tritv.rs @@ -204,8 +204,8 @@ fn tritv_copy(target: &t, source: &t) -> bool { let changed = !bitv::equal(target.uncertain, source.uncertain) || !bitv::equal(target.val, source.val); - bitv::copy(target.uncertain, source.uncertain); - bitv::copy(target.val, source.val); + bitv::assign(target.uncertain, source.uncertain); + bitv::assign(target.val, source.val); ret changed; } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 839e01a62f5..e500aad42f9 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1942,6 +1942,13 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, bot = check_expr_with(fcx, e, ty::mk_bool(tcx)); write::nil_ty(tcx, id); } + ast::expr_copy(a) { + bot = check_expr_with_unifier(fcx, a, unify, expected); + let tpot = ty::node_id_to_ty_param_substs_opt_and_ty(fcx.ccx.tcx, + a.id); + write::ty_fixup(fcx, id, tpot); + + } ast::expr_move(lhs, rhs) { require_impure(tcx.sess, fcx.purity, expr.span); bot = check_assignment(fcx, expr.span, lhs, rhs, id); diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index b997b084e87..82ca1772c73 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -317,6 +317,7 @@ tag expr_ { * FIXME: many of these @exprs should be constrained with * is_lval once we have constrained types working. */ + expr_copy(@expr); expr_move(@expr, @expr); expr_assign(@expr, @expr); expr_swap(@expr, @expr); diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs index 7e5bbf41493..806d72499aa 100644 --- a/src/comp/syntax/fold.rs +++ b/src/comp/syntax/fold.rs @@ -397,6 +397,9 @@ fn noop_fold_expr(e: &expr_, fld: ast_fold) -> expr_ { expr_move(el, er) { expr_move(fld.fold_expr(el), fld.fold_expr(er)) } + expr_copy(e) { + expr_copy(fld.fold_expr(e)) + } expr_assign(el, er) { expr_assign(fld.fold_expr(el), fld.fold_expr(er)) } diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index 19f058d7ee2..86d61ba1f94 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -180,6 +180,7 @@ fn bad_expr_word_table() -> hashmap[str, ()] { words.insert("log_err", ()); words.insert("tag", ()); words.insert("obj", ()); + words.insert("copy", ()); ret words; } @@ -999,6 +1000,10 @@ fn parse_bottom_expr(p: &parser) -> @ast::expr { hi = e.span.hi; expect(p, token::RPAREN); ex = ast::expr_chan(e); + } else if (eat_word(p, "copy")) { + let e = parse_expr(p); + ex = ast::expr_copy(e); + hi = e.span.hi; } else if (eat_word(p, "self")) { log "parsing a self-call..."; expect(p, token::DOT); diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs index 59781bdbfba..3835435777f 100644 --- a/src/comp/syntax/print/pprust.rs +++ b/src/comp/syntax/print/pprust.rs @@ -881,6 +881,10 @@ fn print_expr(s: &ps, expr: &@ast::expr) { ibox(s, 0u); print_block(s, blk); } + ast::expr_copy(e) { + word_space(s, "copy"); + print_expr(s, e); + } ast::expr_move(lhs, rhs) { print_expr(s, lhs); space(s.s); diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs index e0a5bebd256..2f366621c28 100644 --- a/src/comp/syntax/visit.rs +++ b/src/comp/syntax/visit.rs @@ -299,6 +299,7 @@ fn visit_expr[E](ex: &@expr, e: &E, v: &vt[E]) { expr_fn(f) { v.visit_fn(f, ~[], ex.span, none, ex.id, e, v); } expr_block(b) { v.visit_block(b, e, v); } expr_assign(a, b) { v.visit_expr(b, e, v); v.visit_expr(a, e, v); } + expr_copy(a) { v.visit_expr(a, e, v); } expr_move(a, b) { v.visit_expr(b, e, v); v.visit_expr(a, e, v); } expr_swap(a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); } expr_assign_op(_, a, b) { diff --git a/src/lib/bitv.rs b/src/lib/bitv.rs index 759c9b24d48..b241cce6b3d 100644 --- a/src/lib/bitv.rs +++ b/src/lib/bitv.rs @@ -3,7 +3,7 @@ export t; export create; export union; export intersect; -export copy; +export assign; export clone; export get; export equal; @@ -63,7 +63,10 @@ fn intersect(v0: &t, v1: &t) -> bool { fn right(w0: uint, w1: uint) -> uint { ret w1; } -fn copy(v0: &t, v1: t) -> bool { let sub = right; ret process(sub, v0, v1); } +fn assign(v0: &t, v1: t) -> bool { + let sub = right; + ret process(sub, v0, v1); +} fn clone(v: t) -> t { let storage = ivec::init_elt_mut[uint](0u, v.nbits / uint_bits() + 1u); diff --git a/src/test/run-pass/expr-copy.rs b/src/test/run-pass/expr-copy.rs new file mode 100644 index 00000000000..6fbaf4f7679 --- /dev/null +++ b/src/test/run-pass/expr-copy.rs @@ -0,0 +1,5 @@ +fn main() { + let x = 10; + let y = copy x; + log y; +} \ No newline at end of file