Skip to content

Commit 03a6e54

Browse files
committed
Disallow binding by-mut-ref and by-move arguments
Fix bug in bound by-copy arguments. Closes #1261
1 parent d28e0c0 commit 03a6e54

File tree

5 files changed

+43
-12
lines changed

5 files changed

+43
-12
lines changed

src/comp/middle/mut.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ fn visit_decl(cx: @ctx, d: @decl, &&e: (), v: visit::vt<()>) {
150150
fn visit_expr(cx: @ctx, ex: @expr, &&e: (), v: visit::vt<()>) {
151151
alt ex.node {
152152
expr_call(f, args, _) { check_call(cx, f, args); }
153+
expr_bind(f, args) { check_bind(cx, f, args); }
153154
expr_swap(lhs, rhs) {
154155
check_lval(cx, lhs, msg_assign);
155156
check_lval(cx, rhs, msg_assign);
@@ -230,6 +231,30 @@ fn check_call(cx: @ctx, f: @expr, args: [@expr]) {
230231
}
231232
}
232233

234+
fn check_bind(cx: @ctx, f: @expr, args: [option::t<@expr>]) {
235+
let arg_ts = ty::ty_fn_args(cx.tcx, ty::expr_ty(cx.tcx, f));
236+
let i = 0u;
237+
for arg in args {
238+
alt arg {
239+
some(expr) {
240+
alt (alt arg_ts[i].mode {
241+
by_mut_ref. { some("by mutable reference") }
242+
by_move. { some("by move") }
243+
_ { none }
244+
}) {
245+
some(name) {
246+
cx.tcx.sess.span_err(
247+
expr.span, "can not bind an argument passed " + name);
248+
}
249+
none. {}
250+
}
251+
}
252+
_ {}
253+
}
254+
i += 1u;
255+
}
256+
}
257+
233258
fn is_immutable_def(def: def) -> option::t<str> {
234259
alt def {
235260
def_fn(_, _) | def_mod(_) | def_native_mod(_) | def_const(_) |

src/comp/middle/trans.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3462,6 +3462,12 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
34623462
bcx = bound_arg.bcx;
34633463
let val = bound_arg.val;
34643464
if out_arg.mode == ast::by_val { val = Load(bcx, val); }
3465+
if out_arg.mode == ast::by_copy {
3466+
let {bcx: cx, val: alloc} = alloc_ty(bcx, out_arg.ty);
3467+
bcx = memmove_ty(cx, alloc, val, out_arg.ty);
3468+
bcx = take_ty(bcx, alloc, out_arg.ty);
3469+
val = alloc;
3470+
}
34653471
// If the type is parameterized, then we need to cast the
34663472
// type we actually have to the parameterized out type.
34673473
if ty::type_contains_params(cx.ccx.tcx, out_arg.ty) {

src/libstd/task.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ fn spawn_inner<send T>(-data: T, f: fn(T),
288288
notify: option<comm::chan<task_notification>>)
289289
-> task unsafe {
290290

291-
fn wrapper<send T>(-data: *u8, f: fn(T)) unsafe {
291+
fn wrapper<send T>(data: *u8, f: fn(T)) unsafe {
292292
let data: ~T = unsafe::reinterpret_cast(data);
293293
f(*data);
294294
}

src/test/bench/task-perf-word-count.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,29 +112,29 @@ mod map_reduce {
112112

113113
send(out, chan(p));
114114

115-
let ref_count = 0;
116-
let is_done = false;
115+
let state = @{mutable ref_count: 0, mutable is_done: false};
117116

118-
fn get(p: port<reduce_proto>, &ref_count: int, &is_done: bool) ->
119-
option<int> {
120-
while !is_done || ref_count > 0 {
117+
fn get(p: port<reduce_proto>, state: @{mutable ref_count: int,
118+
mutable is_done: bool})
119+
-> option<int> {
120+
while !state.is_done || state.ref_count > 0 {
121121
alt recv(p) {
122122
emit_val(v) {
123123
// log_err #fmt("received %d", v);
124124
ret some(v);
125125
}
126126
done. {
127127
// log_err "all done";
128-
is_done = true;
128+
state.is_done = true;
129129
}
130-
ref. { ref_count += 1; }
131-
release. { ref_count -= 1; }
130+
ref. { state.ref_count += 1; }
131+
release. { state.ref_count -= 1; }
132132
}
133133
}
134134
ret none;
135135
}
136136

137-
reduce(key, bind get(p, ref_count, is_done));
137+
reduce(key, bind get(p, state));
138138
}
139139

140140
fn map_reduce(-inputs: [str]) {

src/test/stdtest/treemap.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ fn traverse_in_order() {
3939
insert(m, 2, ());
4040
insert(m, 1, ());
4141

42-
let n = 0;
43-
fn t(&n: int, &&k: int, &&_v: ()) { assert (n == k); n += 1; }
42+
let n = @mutable 0;
43+
fn t(n: @mutable int, &&k: int, &&_v: ()) { assert (*n == k); *n += 1; }
4444
traverse(m, bind t(n, _, _));
4545
}
4646

0 commit comments

Comments
 (0)