diff options
| author | Brian Anderson <banderson@mozilla.com> | 2011-09-21 14:00:11 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2011-09-21 14:40:55 -0700 |
| commit | 2cc01e2ca2d84af609ecef3a415ee7839715900f (patch) | |
| tree | a26ef99b3dbaff3a9d44321c21d599e731184306 /src | |
| parent | 956bc69330cef83977c6f0031fc53efc44542560 (diff) | |
| download | rust-2cc01e2ca2d84af609ecef3a415ee7839715900f.tar.gz rust-2cc01e2ca2d84af609ecef3a415ee7839715900f.zip | |
Add ability to deref unique boxes. Make unique boxes immediates.
Issue #409
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/trans.rs | 22 | ||||
| -rw-r--r-- | src/comp/middle/trans_common.rs | 6 | ||||
| -rw-r--r-- | src/comp/middle/ty.rs | 18 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 1 | ||||
| -rw-r--r-- | src/test/run-pass/unique-deref.rs | 4 |
5 files changed, 31 insertions, 20 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 0f48df3bdbd..21e34102ab9 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -2053,7 +2053,7 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef, ret cx; } else if ty::type_is_nil(tcx, t) || ty::type_is_bot(tcx, t) { ret cx; - } else if ty::type_is_boxed(tcx, t) { + } else if ty::type_is_boxed(tcx, t) || ty::type_is_unique_box(tcx, t) { if src.is_mem { src_val = Load(cx, src_val); } if action == DROP_EXISTING { cx = drop_ty(cx, dst, t); } Store(cx, src_val, dst); @@ -3138,7 +3138,6 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result { InBoundsGEP(sub.bcx, sub.val, [C_int(0), C_int(abi::box_rc_field_body)]) } - ty::ty_uniq(_) { fail "uniq lval translation unimplemented" } ty::ty_res(_, _, _) { InBoundsGEP(sub.bcx, sub.val, [C_int(0), C_int(1)]) } @@ -3151,7 +3150,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result { } else { T_typaram_ptr(ccx.tn) }; PointerCast(sub.bcx, sub.val, ellty) } - ty::ty_ptr(_) { sub.val } + ty::ty_ptr(_) | ty::ty_uniq(_) { sub.val } }; ret lval_mem(sub.bcx, val); } @@ -4306,7 +4305,7 @@ fn with_out_method(work: fn(out_method) -> result, cx: @block_ctxt, // immediate-ness of the type. fn type_is_immediate(ccx: @crate_ctxt, t: ty::t) -> bool { ret ty::type_is_scalar(ccx.tcx, t) || ty::type_is_boxed(ccx.tcx, t) || - ty::type_is_native(ccx.tcx, t); + ty::type_is_unique_box(ccx.tcx, t) || ty::type_is_native(ccx.tcx, t); } fn do_spill(cx: @block_ctxt, v: ValueRef, t: ty::t) -> result { @@ -4502,6 +4501,9 @@ fn trans_uniq(cx: @block_ctxt, contents: @ast::expr, node_id: ast::node_id) -> result { let bcx = cx; + let lv = trans_lval(bcx, contents); + bcx = lv.bcx; + let contents_ty = ty::expr_ty(bcx_tcx(bcx), contents); let r = size_of(bcx, contents_ty); bcx = r.bcx; @@ -4513,15 +4515,11 @@ fn trans_uniq(cx: @block_ctxt, contents: @ast::expr, bcx = r.bcx; let llptr = r.val; - let uniq_ty = node_id_type(bcx_ccx(cx), node_id); - r = alloc_ty(bcx, uniq_ty); - let llptrptr = r.val; - bcx = r.bcx; - Store(bcx, llptr, llptrptr); + bcx = move_val_if_temp(bcx, INIT, llptr, lv, contents_ty); - r = trans_expr_out(bcx, contents, save_in(llptr)); - add_clean_temp(r.bcx, llptrptr, uniq_ty); - ret rslt(r.bcx, llptrptr); + let uniq_ty = node_id_type(bcx_ccx(cx), node_id); + add_clean_temp(r.bcx, llptr, uniq_ty); + ret rslt(r.bcx, llptr); } fn trans_break_cont(sp: span, cx: @block_ctxt, to_end: bool) -> result { diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 5304f6d97de..74f60004f72 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -294,12 +294,6 @@ fn add_clean_temp(cx: @block_ctxt, val: ValueRef, ty: ty::t) { // this will be more involved. For now, we simply zero out the local, and the // drop glue checks whether it is zero. fn revoke_clean(cx: @block_ctxt, val: ValueRef, t: ty::t) -> @block_ctxt { - if ty::type_is_unique(bcx_tcx(cx), t) { - // Just zero out the allocation. This ensures that the GC won't try to - // traverse dangling pointers. - ret trans::zero_alloca(cx, val, t).bcx; - } - let sc_cx = find_scope_cx(cx); let found = -1; let i = 0; diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 8393aa3ad4c..56f9ab3d7f9 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -150,6 +150,7 @@ export type_is_bool; export type_is_bot; export type_is_box; export type_is_boxed; +export type_is_unique_box; export type_is_vec; export type_is_fp; export type_allows_implicit_copy; @@ -855,11 +856,24 @@ fn get_element_type(cx: ctxt, ty: t, i: uint) -> t { } fn type_is_box(cx: ctxt, ty: t) -> bool { - alt struct(cx, ty) { ty_box(_) { ret true; } _ { ret false; } } + alt struct(cx, ty) { + ty_box(_) { ret true; } + _ { ret false; } + } } fn type_is_boxed(cx: ctxt, ty: t) -> bool { - alt struct(cx, ty) { ty_box(_) { ret true; } _ { ret false; } } + alt struct(cx, ty) { + ty_box(_) { ret true; } + _ { ret false; } + } +} + +fn type_is_unique_box(cx: ctxt, ty: t) -> bool { + alt struct(cx, ty) { + ty_uniq(_) { ret true; } + _ { ret false; } + } } fn type_is_vec(cx: ctxt, ty: t) -> bool { diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index c6d24802ecd..758883a1aa0 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1725,6 +1725,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, ast::deref. { alt structure_of(fcx, expr.span, oper_t) { ty::ty_box(inner) { oper_t = inner.ty; } + ty::ty_uniq(inner) { oper_t = inner; } ty::ty_res(_, inner, _) { oper_t = inner; } ty::ty_tag(id, tps) { let variants = ty::tag_variants(tcx, id); diff --git a/src/test/run-pass/unique-deref.rs b/src/test/run-pass/unique-deref.rs new file mode 100644 index 00000000000..876bbc02d26 --- /dev/null +++ b/src/test/run-pass/unique-deref.rs @@ -0,0 +1,4 @@ +fn main() { + let i = ~100; + assert *i == 100; +} \ No newline at end of file |
