]> git.lizzy.rs Git - rust.git/commitdiff
Add ability to deref unique boxes. Make unique boxes immediates.
authorBrian Anderson <banderson@mozilla.com>
Wed, 21 Sep 2011 21:00:11 +0000 (14:00 -0700)
committerBrian Anderson <banderson@mozilla.com>
Wed, 21 Sep 2011 21:40:55 +0000 (14:40 -0700)
Issue #409

src/comp/middle/trans.rs
src/comp/middle/trans_common.rs
src/comp/middle/ty.rs
src/comp/middle/typeck.rs
src/test/run-pass/unique-deref.rs [new file with mode: 0644]

index 0f48df3bdbd7f02e9e2a66ca07d1f915d5a90fe2..21e34102ab96aaab41327707285c7b1ee8e5e766 100644 (file)
@@ -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 {
index 5304f6d97de2175478e4834b8e6682c22dd54f25..74f60004f72e078dd8ee4351ab58c4daae7d34d6 100644 (file)
@@ -294,12 +294,6 @@ fn spill_and_drop(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;
index 8393aa3ad4c1f6bf763b34319573108769ca447d..56f9ab3d7f9a9385f8075d2624dca927b7d2360b 100644 (file)
 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 {
index c6d24802ecd90c6ec0362596a256193a16d6b316..758883a1aa0aa330a8a192b183a4538d2722408f 100644 (file)
@@ -1725,6 +1725,7 @@ fn check_binop_type_compat(fcx: @fn_ctxt, span: span, ty: ty::t,
           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 (file)
index 0000000..876bbc0
--- /dev/null
@@ -0,0 +1,4 @@
+fn main() {
+    let i = ~100;
+    assert *i == 100;
+}
\ No newline at end of file