Skip to content

Commit 2cc01e2

Browse files
committed
Add ability to deref unique boxes. Make unique boxes immediates.
Issue #409
1 parent 956bc69 commit 2cc01e2

File tree

5 files changed

+31
-20
lines changed

5 files changed

+31
-20
lines changed

src/comp/middle/trans.rs

+10-12
Original file line numberDiff line numberDiff line change
@@ -2053,7 +2053,7 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
20532053
ret cx;
20542054
} else if ty::type_is_nil(tcx, t) || ty::type_is_bot(tcx, t) {
20552055
ret cx;
2056-
} else if ty::type_is_boxed(tcx, t) {
2056+
} else if ty::type_is_boxed(tcx, t) || ty::type_is_unique_box(tcx, t) {
20572057
if src.is_mem { src_val = Load(cx, src_val); }
20582058
if action == DROP_EXISTING { cx = drop_ty(cx, dst, t); }
20592059
Store(cx, src_val, dst);
@@ -3138,7 +3138,6 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
31383138
InBoundsGEP(sub.bcx, sub.val,
31393139
[C_int(0), C_int(abi::box_rc_field_body)])
31403140
}
3141-
ty::ty_uniq(_) { fail "uniq lval translation unimplemented" }
31423141
ty::ty_res(_, _, _) {
31433142
InBoundsGEP(sub.bcx, sub.val, [C_int(0), C_int(1)])
31443143
}
@@ -3151,7 +3150,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
31513150
} else { T_typaram_ptr(ccx.tn) };
31523151
PointerCast(sub.bcx, sub.val, ellty)
31533152
}
3154-
ty::ty_ptr(_) { sub.val }
3153+
ty::ty_ptr(_) | ty::ty_uniq(_) { sub.val }
31553154
};
31563155
ret lval_mem(sub.bcx, val);
31573156
}
@@ -4306,7 +4305,7 @@ fn with_out_method(work: fn(out_method) -> result, cx: @block_ctxt,
43064305
// immediate-ness of the type.
43074306
fn type_is_immediate(ccx: @crate_ctxt, t: ty::t) -> bool {
43084307
ret ty::type_is_scalar(ccx.tcx, t) || ty::type_is_boxed(ccx.tcx, t) ||
4309-
ty::type_is_native(ccx.tcx, t);
4308+
ty::type_is_unique_box(ccx.tcx, t) || ty::type_is_native(ccx.tcx, t);
43104309
}
43114310

43124311
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,
45024501
node_id: ast::node_id) -> result {
45034502
let bcx = cx;
45044503

4504+
let lv = trans_lval(bcx, contents);
4505+
bcx = lv.bcx;
4506+
45054507
let contents_ty = ty::expr_ty(bcx_tcx(bcx), contents);
45064508
let r = size_of(bcx, contents_ty);
45074509
bcx = r.bcx;
@@ -4513,15 +4515,11 @@ fn trans_uniq(cx: @block_ctxt, contents: @ast::expr,
45134515
bcx = r.bcx;
45144516
let llptr = r.val;
45154517

4516-
let uniq_ty = node_id_type(bcx_ccx(cx), node_id);
4517-
r = alloc_ty(bcx, uniq_ty);
4518-
let llptrptr = r.val;
4519-
bcx = r.bcx;
4520-
Store(bcx, llptr, llptrptr);
4518+
bcx = move_val_if_temp(bcx, INIT, llptr, lv, contents_ty);
45214519

4522-
r = trans_expr_out(bcx, contents, save_in(llptr));
4523-
add_clean_temp(r.bcx, llptrptr, uniq_ty);
4524-
ret rslt(r.bcx, llptrptr);
4520+
let uniq_ty = node_id_type(bcx_ccx(cx), node_id);
4521+
add_clean_temp(r.bcx, llptr, uniq_ty);
4522+
ret rslt(r.bcx, llptr);
45254523
}
45264524

45274525
fn trans_break_cont(sp: span, cx: @block_ctxt, to_end: bool) -> result {

src/comp/middle/trans_common.rs

-6
Original file line numberDiff line numberDiff line change
@@ -294,12 +294,6 @@ fn add_clean_temp(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
294294
// this will be more involved. For now, we simply zero out the local, and the
295295
// drop glue checks whether it is zero.
296296
fn revoke_clean(cx: @block_ctxt, val: ValueRef, t: ty::t) -> @block_ctxt {
297-
if ty::type_is_unique(bcx_tcx(cx), t) {
298-
// Just zero out the allocation. This ensures that the GC won't try to
299-
// traverse dangling pointers.
300-
ret trans::zero_alloca(cx, val, t).bcx;
301-
}
302-
303297
let sc_cx = find_scope_cx(cx);
304298
let found = -1;
305299
let i = 0;

src/comp/middle/ty.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ export type_is_bool;
150150
export type_is_bot;
151151
export type_is_box;
152152
export type_is_boxed;
153+
export type_is_unique_box;
153154
export type_is_vec;
154155
export type_is_fp;
155156
export type_allows_implicit_copy;
@@ -855,11 +856,24 @@ fn get_element_type(cx: ctxt, ty: t, i: uint) -> t {
855856
}
856857

857858
fn type_is_box(cx: ctxt, ty: t) -> bool {
858-
alt struct(cx, ty) { ty_box(_) { ret true; } _ { ret false; } }
859+
alt struct(cx, ty) {
860+
ty_box(_) { ret true; }
861+
_ { ret false; }
862+
}
859863
}
860864

861865
fn type_is_boxed(cx: ctxt, ty: t) -> bool {
862-
alt struct(cx, ty) { ty_box(_) { ret true; } _ { ret false; } }
866+
alt struct(cx, ty) {
867+
ty_box(_) { ret true; }
868+
_ { ret false; }
869+
}
870+
}
871+
872+
fn type_is_unique_box(cx: ctxt, ty: t) -> bool {
873+
alt struct(cx, ty) {
874+
ty_uniq(_) { ret true; }
875+
_ { ret false; }
876+
}
863877
}
864878

865879
fn type_is_vec(cx: ctxt, ty: t) -> bool {

src/comp/middle/typeck.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
17251725
ast::deref. {
17261726
alt structure_of(fcx, expr.span, oper_t) {
17271727
ty::ty_box(inner) { oper_t = inner.ty; }
1728+
ty::ty_uniq(inner) { oper_t = inner; }
17281729
ty::ty_res(_, inner, _) { oper_t = inner; }
17291730
ty::ty_tag(id, tps) {
17301731
let variants = ty::tag_variants(tcx, id);

src/test/run-pass/unique-deref.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
let i = ~100;
3+
assert *i == 100;
4+
}

0 commit comments

Comments
 (0)