diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs index e264b887c38..55d4fb400e1 100644 --- a/src/comp/middle/alias.rs +++ b/src/comp/middle/alias.rs @@ -573,6 +573,7 @@ fn expr_root(&ctx cx, @ast::expr ex, bool autoderef) -> case (ty::ty_box(?mt)) { mut = mt.mut != ast::imm; } case (ty::ty_res(_, _, _)) {} case (ty::ty_tag(_, _)) {} + case (ty::ty_ptr(?mt)) { mut = mt.mut != ast::imm; } } vec::push(ds, rec(mut=mut, kind=unbox, outer_t=base_t)); ex = base; diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 0acf799b145..9f4abee52d4 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5263,11 +5263,11 @@ fn trans_lval_gen(&@block_ctxt cx, &@ast::expr e) -> lval_result { auto t = ty::expr_ty(ccx.tcx, base); auto val = alt (ty::struct(ccx.tcx, t)) { case (ty::ty_box(_)) { - sub.bcx.build.GEP + sub.bcx.build.InBoundsGEP (sub.val, ~[C_int(0), C_int(abi::box_rc_field_body)]) } case (ty::ty_res(_, _, _)) { - sub.bcx.build.GEP(sub.val, ~[C_int(0), C_int(1)]) + sub.bcx.build.InBoundsGEP(sub.val, ~[C_int(0), C_int(1)]) } case (ty::ty_tag(_, _)) { auto ety = ty::expr_ty(ccx.tcx, e); @@ -5279,6 +5279,7 @@ fn trans_lval_gen(&@block_ctxt cx, &@ast::expr e) -> lval_result { }; sub.bcx.build.PointerCast(sub.val, ellty) } + case (ty::ty_ptr(_)) { sub.val } }; ret lval_mem(sub.bcx, val); } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index cdd106385a5..e0cf926141e 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1712,6 +1712,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) { oper_t = ty::substitute_type_params (fcx.ccx.tcx, tps, variants.(0).args.(0)); } + case (ty::ty_ptr(?inner)) { oper_t = inner.ty; } case (_) { fcx.ccx.tcx.sess.span_fatal (expr.span, "dereferencing non-" + diff --git a/src/lib/ptr.rs b/src/lib/ptr.rs index 8fcf331e0eb..b230a61e966 100644 --- a/src/lib/ptr.rs +++ b/src/lib/ptr.rs @@ -1,10 +1,10 @@ // Unsafe pointer utility functions. native "rust-intrinsic" mod rusti { - fn addr_of[T](&T val) -> *T; + fn addr_of[T](&mutable T val) -> *mutable T; fn ptr_offset[T](*T ptr, uint count) -> *T; } -fn addr_of[T](&T val) -> *T { ret rusti::addr_of(val); } +fn addr_of[T](&mutable T val) -> *mutable T { ret rusti::addr_of(val); } fn offset[T](*T ptr, uint count) -> *T { ret rusti::ptr_offset(ptr, count); } diff --git a/src/test/run-pass/lib-ptr.rs b/src/test/run-pass/lib-ptr.rs new file mode 100644 index 00000000000..79a535fd966 --- /dev/null +++ b/src/test/run-pass/lib-ptr.rs @@ -0,0 +1,23 @@ +// xfail-stage0 + +use std; +import std::ptr; +import std::unsafe; + +type pair = rec(mutable int fst, mutable int snd); + +fn main() { + auto p = rec(mutable fst=10, mutable snd=20); + let *mutable pair pptr = ptr::addr_of(p); + let *mutable int iptr = unsafe::reinterpret_cast(pptr); + assert (*iptr == 10); + *iptr = 30; + assert (*iptr == 30); + assert (p.fst == 30); + + *pptr = rec(mutable fst=50, mutable snd=60); + assert (*iptr == 50); + assert (p.fst == 50); + assert (p.snd == 60); +} +