Skip to content

Commit 3626250

Browse files
committed
Allow moving out of mutable unsafe pointers
This makes it possible to de-initialize values anywhere in memory, which is needed, for example, for a fast imlementation of vec::pop.
1 parent dc55c06 commit 3626250

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

src/comp/middle/mut.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import syntax::visit;
55
import syntax::ast_util;
66
import driver::session::session;
77

8-
enum deref_t { unbox, field, index, }
8+
enum deref_t { unbox(bool), field, index, }
99

1010
type deref = @{mut: bool, kind: deref_t, outer_t: ty::t};
1111

@@ -20,15 +20,15 @@ fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) ->
2020
while true {
2121
alt ty::struct(tcx, t) {
2222
ty::ty_box(mt) {
23-
ds += [@{mut: mt.mut == mut, kind: unbox, outer_t: t}];
23+
ds += [@{mut: mt.mut == mut, kind: unbox(false), outer_t: t}];
2424
t = mt.ty;
2525
}
2626
ty::ty_uniq(mt) {
27-
ds += [@{mut: mt.mut == mut, kind: unbox, outer_t: t}];
27+
ds += [@{mut: mt.mut == mut, kind: unbox(false), outer_t: t}];
2828
t = mt.ty;
2929
}
3030
ty::ty_res(_, inner, tps) {
31-
ds += [@{mut: false, kind: unbox, outer_t: t}];
31+
ds += [@{mut: false, kind: unbox(false), outer_t: t}];
3232
t = ty::substitute_type_params(tcx, tps, inner);
3333
}
3434
ty::ty_enum(did, tps) {
@@ -37,7 +37,7 @@ fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) ->
3737
vec::len(variants[0].args) != 1u {
3838
break;
3939
}
40-
ds += [@{mut: false, kind: unbox, outer_t: t}];
40+
ds += [@{mut: false, kind: unbox(false), outer_t: t}];
4141
t = ty::substitute_type_params(tcx, tps, variants[0].args[0]);
4242
}
4343
_ { break; }
@@ -85,15 +85,16 @@ fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) ->
8585
expr_unary(op, base) {
8686
if op == deref {
8787
let base_t = ty::expr_ty(tcx, base);
88-
let is_mut = false;
88+
let is_mut = false, ptr = false;
8989
alt ty::struct(tcx, base_t) {
9090
ty::ty_box(mt) { is_mut = mt.mut == mut; }
9191
ty::ty_uniq(mt) { is_mut = mt.mut == mut; }
9292
ty::ty_res(_, _, _) { }
9393
ty::ty_enum(_, _) { }
94-
ty::ty_ptr(mt) { is_mut = mt.mut == mut; }
94+
ty::ty_ptr(mt) { is_mut = mt.mut == mut; ptr = true; }
9595
}
96-
ds += [@{mut: is_mut, kind: unbox, outer_t: base_t}];
96+
ds += [@{mut: is_mut, kind: unbox(ptr && is_mut),
97+
outer_t: base_t}];
9798
ex = base;
9899
} else { break; }
99100
}
@@ -187,7 +188,7 @@ fn check_lval(cx: @ctx, dest: @expr, msg: msg) {
187188
} else if !root.ds[0].mut {
188189
let name =
189190
alt root.ds[0].kind {
190-
mut::unbox { "immutable box" }
191+
mut::unbox(_) { "immutable box" }
191192
mut::field { "immutable field" }
192193
mut::index { "immutable vec content" }
193194
};
@@ -212,7 +213,8 @@ fn check_move_rhs(cx: @ctx, src: @expr) {
212213
let root = expr_root(cx.tcx, src, false);
213214

214215
// Not a path and no-derefs means this is a temporary.
215-
if vec::len(*root.ds) != 0u {
216+
if vec::len(*root.ds) != 0u &&
217+
root.ds[vec::len(*root.ds) - 1u].kind != unbox(true) {
216218
cx.tcx.sess.span_err(src.span, "moving out of a data structure");
217219
}
218220
}

src/libcore/vec.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,14 @@ fn pop<T: copy>(&v: [const T]) -> T {
307307
let e = v[ln];
308308
v = slice(v, 0u, ln);
309309
ret e;
310+
// FIXME use this implementation after the next snapshot (27.01.2012)
311+
/* let new_ln = len(v) - 1u;
312+
assert (new_ln > 0u);
313+
let valptr = ptr::mut_addr_of(v[new_ln]);
314+
let val <- *valptr;
315+
unsafe::set_len(v, new_ln);
316+
val
317+
*/
310318
}
311319

312320
/*

0 commit comments

Comments
 (0)