From 30a4eab380a5452da5f66045962449e58be4c718 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 22 Sep 2011 16:04:27 -0700 Subject: [PATCH] Autoderef indexes and fields of unique boxes Issue #409 --- src/comp/middle/trans.rs | 7 ++++++- src/comp/middle/trans_uniq.rs | 9 ++++++++- src/comp/middle/typeck.rs | 2 +- src/test/run-pass/unique-autoderef-field.rs | 6 ++++++ src/test/run-pass/unique-autoderef-index.rs | 4 ++++ 5 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass/unique-autoderef-field.rs create mode 100644 src/test/run-pass/unique-autoderef-index.rs diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 15ad627c207..3d2dd1bbe56 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -2305,7 +2305,12 @@ fn autoderef(cx: @block_ctxt, v: ValueRef, t: ty::t) -> result_t { v1 = PointerCast(cx, body, T_ptr(llty)); } else { v1 = body; } } - ty::ty_uniq(t) { fail "autoderef uniq unimplemented"; } + ty::ty_uniq(_) { + check trans_uniq::type_is_unique_box(cx, t1); + let derefed = trans_uniq::autoderef(cx, v1, t1); + t1 = derefed.t; + v1 = derefed.v; + } ty::ty_res(did, inner, tps) { t1 = ty::substitute_type_params(ccx.tcx, tps, inner); v1 = GEP(cx, v1, [C_int(0), C_int(1)]); diff --git a/src/comp/middle/trans_uniq.rs b/src/comp/middle/trans_uniq.rs index a26e3224723..2003f6a55aa 100644 --- a/src/comp/middle/trans_uniq.rs +++ b/src/comp/middle/trans_uniq.rs @@ -15,7 +15,7 @@ import trans::{ new_sub_block_ctxt }; -export trans_uniq, make_free_glue, type_is_unique_box, copy_val; +export trans_uniq, make_free_glue, type_is_unique_box, copy_val, autoderef; pure fn type_is_unique_box(bcx: @block_ctxt, ty: ty::t) -> bool { unchecked { @@ -100,4 +100,11 @@ fn copy_val(cx: @block_ctxt, dst: ValueRef, src: ValueRef, let bcx = trans::copy_val(bcx, INIT, dst, src, content_ty); Store(bcx, src, llptr); ret bcx; +} + +fn autoderef(bcx: @block_ctxt, v: ValueRef, t: ty::t) + : type_is_unique_box(bcx, t) -> {v: ValueRef, t: ty::t} { + + let content_ty = content_ty(bcx, t); + ret {v: v, t: content_ty}; } \ No newline at end of file diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 88035da6c62..7d7936b6cf1 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -845,7 +845,7 @@ fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> ty::t { let t1 = t; while true { alt structure_of(fcx, sp, t1) { - ty::ty_box(inner) { + ty::ty_box(inner) | ty::ty_uniq(inner) { alt ty::struct(fcx.ccx.tcx, t1) { ty::ty_var(v1) { if ty::occurs_check_fails(fcx.ccx.tcx, some(sp), v1, diff --git a/src/test/run-pass/unique-autoderef-field.rs b/src/test/run-pass/unique-autoderef-field.rs new file mode 100644 index 00000000000..2bfbdf45d64 --- /dev/null +++ b/src/test/run-pass/unique-autoderef-field.rs @@ -0,0 +1,6 @@ +fn main() { + let i = ~{ + j: 100 + }; + assert i.j == 100; +} \ No newline at end of file diff --git a/src/test/run-pass/unique-autoderef-index.rs b/src/test/run-pass/unique-autoderef-index.rs new file mode 100644 index 00000000000..6b978fc1506 --- /dev/null +++ b/src/test/run-pass/unique-autoderef-index.rs @@ -0,0 +1,4 @@ +fn main() { + let i = ~[100]; + assert i[0] == 100; +} \ No newline at end of file