diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-12-07 15:28:57 +0100 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-12-07 15:28:57 +0100 |
| commit | 03a6e542126b755a9cd2f4f56144107ba0f4d1cd (patch) | |
| tree | 3e939cd30c0c905760fc1827f8519bbc8acd976e | |
| parent | d28e0c0c0ae329705a063a025b853b292ff033a7 (diff) | |
| download | rust-03a6e542126b755a9cd2f4f56144107ba0f4d1cd.tar.gz rust-03a6e542126b755a9cd2f4f56144107ba0f4d1cd.zip | |
Disallow binding by-mut-ref and by-move arguments
Fix bug in bound by-copy arguments. Closes #1261
| -rw-r--r-- | src/comp/middle/mut.rs | 25 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 6 | ||||
| -rw-r--r-- | src/libstd/task.rs | 2 | ||||
| -rw-r--r-- | src/test/bench/task-perf-word-count.rs | 18 | ||||
| -rw-r--r-- | src/test/stdtest/treemap.rs | 4 |
5 files changed, 43 insertions, 12 deletions
diff --git a/src/comp/middle/mut.rs b/src/comp/middle/mut.rs index 12598f3729b..63dadd347e1 100644 --- a/src/comp/middle/mut.rs +++ b/src/comp/middle/mut.rs @@ -150,6 +150,7 @@ fn visit_decl(cx: @ctx, d: @decl, &&e: (), v: visit::vt<()>) { fn visit_expr(cx: @ctx, ex: @expr, &&e: (), v: visit::vt<()>) { alt ex.node { expr_call(f, args, _) { check_call(cx, f, args); } + expr_bind(f, args) { check_bind(cx, f, args); } expr_swap(lhs, rhs) { check_lval(cx, lhs, msg_assign); check_lval(cx, rhs, msg_assign); @@ -230,6 +231,30 @@ fn check_call(cx: @ctx, f: @expr, args: [@expr]) { } } +fn check_bind(cx: @ctx, f: @expr, args: [option::t<@expr>]) { + let arg_ts = ty::ty_fn_args(cx.tcx, ty::expr_ty(cx.tcx, f)); + let i = 0u; + for arg in args { + alt arg { + some(expr) { + alt (alt arg_ts[i].mode { + by_mut_ref. { some("by mutable reference") } + by_move. { some("by move") } + _ { none } + }) { + some(name) { + cx.tcx.sess.span_err( + expr.span, "can not bind an argument passed " + name); + } + none. {} + } + } + _ {} + } + i += 1u; + } +} + fn is_immutable_def(def: def) -> option::t<str> { alt def { def_fn(_, _) | def_mod(_) | def_native_mod(_) | def_const(_) | diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 693c8ae79e8..107c53cfac3 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3462,6 +3462,12 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t, bcx = bound_arg.bcx; let val = bound_arg.val; if out_arg.mode == ast::by_val { val = Load(bcx, val); } + if out_arg.mode == ast::by_copy { + let {bcx: cx, val: alloc} = alloc_ty(bcx, out_arg.ty); + bcx = memmove_ty(cx, alloc, val, out_arg.ty); + bcx = take_ty(bcx, alloc, out_arg.ty); + val = alloc; + } // If the type is parameterized, then we need to cast the // type we actually have to the parameterized out type. if ty::type_contains_params(cx.ccx.tcx, out_arg.ty) { diff --git a/src/libstd/task.rs b/src/libstd/task.rs index a8765407f3a..3e396d3ac63 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -288,7 +288,7 @@ fn spawn_inner<send T>(-data: T, f: fn(T), notify: option<comm::chan<task_notification>>) -> task unsafe { - fn wrapper<send T>(-data: *u8, f: fn(T)) unsafe { + fn wrapper<send T>(data: *u8, f: fn(T)) unsafe { let data: ~T = unsafe::reinterpret_cast(data); f(*data); } diff --git a/src/test/bench/task-perf-word-count.rs b/src/test/bench/task-perf-word-count.rs index 2d4e14af058..d0309713633 100644 --- a/src/test/bench/task-perf-word-count.rs +++ b/src/test/bench/task-perf-word-count.rs @@ -112,12 +112,12 @@ mod map_reduce { send(out, chan(p)); - let ref_count = 0; - let is_done = false; + let state = @{mutable ref_count: 0, mutable is_done: false}; - fn get(p: port<reduce_proto>, &ref_count: int, &is_done: bool) -> - option<int> { - while !is_done || ref_count > 0 { + fn get(p: port<reduce_proto>, state: @{mutable ref_count: int, + mutable is_done: bool}) + -> option<int> { + while !state.is_done || state.ref_count > 0 { alt recv(p) { emit_val(v) { // log_err #fmt("received %d", v); @@ -125,16 +125,16 @@ mod map_reduce { } done. { // log_err "all done"; - is_done = true; + state.is_done = true; } - ref. { ref_count += 1; } - release. { ref_count -= 1; } + ref. { state.ref_count += 1; } + release. { state.ref_count -= 1; } } } ret none; } - reduce(key, bind get(p, ref_count, is_done)); + reduce(key, bind get(p, state)); } fn map_reduce(-inputs: [str]) { diff --git a/src/test/stdtest/treemap.rs b/src/test/stdtest/treemap.rs index 1701be37901..2fba1ebb196 100644 --- a/src/test/stdtest/treemap.rs +++ b/src/test/stdtest/treemap.rs @@ -39,8 +39,8 @@ fn traverse_in_order() { insert(m, 2, ()); insert(m, 1, ()); - let n = 0; - fn t(&n: int, &&k: int, &&_v: ()) { assert (n == k); n += 1; } + let n = @mutable 0; + fn t(n: @mutable int, &&k: int, &&_v: ()) { assert (*n == k); *n += 1; } traverse(m, bind t(n, _, _)); } |
