From 1a68a98824cab9122bb39920d09415ff34a3944e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 3 Nov 2011 10:57:54 +0100 Subject: [PATCH] Disallow writing to function arguments again Remove implicit copying hack. Closes #1118 --- src/comp/driver/rustc.rs | 2 +- src/comp/metadata/creader.rs | 1 + src/comp/middle/alias.rs | 2 +- src/comp/middle/mut.rs | 6 ++- src/comp/middle/resolve.rs | 3 ++ src/comp/middle/trans.rs | 83 +++++++++++++----------------- src/comp/middle/trans_alt.rs | 16 +++--- src/comp/middle/trans_objects.rs | 3 +- src/comp/middle/trans_vec.rs | 13 +++-- src/comp/middle/typeck.rs | 5 +- src/comp/syntax/parse/lexer.rs | 21 ++------ src/comp/syntax/parse/parser.rs | 1 + src/lib/aio.rs | 2 +- src/lib/float.rs | 9 ++-- src/lib/int.rs | 3 +- src/lib/io.rs | 24 ++++----- src/lib/str.rs | 2 +- src/lib/term.rs | 1 + src/lib/test.rs | 2 +- src/lib/u64.rs | 1 + src/lib/u8.rs | 3 +- src/lib/uint.rs | 3 +- src/test/run-pass/issue-507.rs | 2 +- src/test/run-pass/move-4-unique.rs | 1 + src/test/run-pass/move-4.rs | 1 + src/test/run-pass/obj-docs.rs | 2 +- src/test/run-pass/obj-self-2.rs | 4 +- src/test/run-pass/obj-self-3.rs | 4 +- 28 files changed, 107 insertions(+), 113 deletions(-) diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index 22d6bcd8366..74d13c9a4ca 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -504,7 +504,7 @@ fn early_error(msg: str) -> ! { } fn main(args: [str]) { - let binary = vec::shift(args); + let args = args, binary = vec::shift(args); let match = alt getopts::getopts(args, opts()) { getopts::success(m) { m } diff --git a/src/comp/metadata/creader.rs b/src/comp/metadata/creader.rs index 2328c2efa93..5946b337b48 100644 --- a/src/comp/metadata/creader.rs +++ b/src/comp/metadata/creader.rs @@ -118,6 +118,7 @@ fn find_library_crate(sess: session::session, ident: ast::ident, -> option::t<{ident: str, data: @[u8]}> { attr::require_unique_names(sess, metas); + let metas = metas; // Metadata "name" will be used to find the crate. Use `ident' // as "name" if the attribute is not explicitly specified diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs index e98b5590f64..940ce38fa40 100644 --- a/src/comp/middle/alias.rs +++ b/src/comp/middle/alias.rs @@ -132,7 +132,7 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt) { } fn visit_block(cx: @ctx, b: ast::blk, sc: scope, v: vt) { - let bs = sc.bs; + let bs = sc.bs, sc = sc; for stmt in b.node.stmts { alt stmt.node { ast::stmt_decl(@{node: ast::decl_item(it), _}, _) { diff --git a/src/comp/middle/mut.rs b/src/comp/middle/mut.rs index 4c286e6cab4..7f5b523aba5 100644 --- a/src/comp/middle/mut.rs +++ b/src/comp/middle/mut.rs @@ -15,7 +15,7 @@ type deref = @{mut: bool, kind: deref_t, outer_t: ty::t}; fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) -> {ex: @expr, ds: @[deref]} { fn maybe_auto_unbox(tcx: ty::ctxt, t: ty::t) -> {t: ty::t, ds: [deref]} { - let ds = []; + let ds = [], t = t; while true { alt ty::struct(tcx, t) { ty::ty_box(mt) { @@ -44,7 +44,7 @@ fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) -> } ret {t: t, ds: ds}; } - let ds: [deref] = []; + let ds: [deref] = [], ex = ex; while true { alt copy ex.node { expr_field(base, ident) { @@ -237,6 +237,8 @@ fn is_immutable_def(def: def) -> option::t { def_use(_) { some("static item") } + def_arg(_, by_ref.) | def_arg(_, by_val.) | + def_arg(_, mode_infer.) { some("argument") } def_obj_field(_, imm.) { some("immutable object field") } def_upvar(_, inner, mut) { if !mut { some("upvar") } else { is_immutable_def(*inner) } diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 64169dd47ac..7745f8b94c2 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -502,6 +502,7 @@ fn ns_name(ns: namespace) -> str { fn unresolved_err(e: env, sc: scopes, sp: span, name: ident, kind: str) { fn find_fn_or_mod_scope(sc: scopes) -> option::t { + let sc = sc; while true { alt sc { cons(cur, rest) { @@ -671,6 +672,7 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace) let closing = []; // Used to determine whether obj fields are in scope let left_fn_level2 = false; + let sc = sc; while true { alt copy sc { nil. { ret none::; } @@ -1191,6 +1193,7 @@ fn check_mod_name(e: env, name: ident, entries: list) { let saw_mod = false; let saw_type = false; let saw_value = false; + let entries = entries; fn dup(e: env, sp: span, word: str, name: ident) { e.sess.span_fatal(sp, "duplicate definition of " + word + name); } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 06922935d0d..e5e5b721a04 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -929,7 +929,7 @@ fn trans_stack_local_derived_tydesc(cx: @block_ctxt, llsz: ValueRef, let llmyroottydesc = alloca(cx, bcx_ccx(cx).tydesc_type); // By convention, desc 0 is the root descriptor. - llroottydesc = Load(cx, llroottydesc); + let llroottydesc = Load(cx, llroottydesc); Store(cx, llroottydesc, llmyroottydesc); // Store a pointer to the rest of the descriptors. @@ -1352,7 +1352,7 @@ fn make_free_glue(bcx: @block_ctxt, v: ValueRef, t: ty::t) { // everything to a pointer to the type that the glue acts on). let bcx = alt ty::struct(bcx_tcx(bcx), t) { ty::ty_box(body_mt) { - v = PointerCast(bcx, v, type_of_1(bcx, t)); + let v = PointerCast(bcx, v, type_of_1(bcx, t)); let body = GEPi(bcx, v, [0, abi::box_rc_field_body]); let bcx = drop_ty(bcx, body, body_mt.ty); if !bcx_ccx(bcx).sess.get_opts().do_gc { @@ -1361,7 +1361,7 @@ fn make_free_glue(bcx: @block_ctxt, v: ValueRef, t: ty::t) { } ty::ty_uniq(content_mt) { check trans_uniq::type_is_unique_box(bcx, t); - v = PointerCast(bcx, v, type_of_1(bcx, t)); + let v = PointerCast(bcx, v, type_of_1(bcx, t)); trans_uniq::make_free_glue(bcx, v, t) } ty::ty_vec(_) | ty::ty_str. { @@ -1388,7 +1388,7 @@ fn make_free_glue(bcx: @block_ctxt, v: ValueRef, t: ty::t) { // Call through the closure's own fields-drop glue first. // Then free the body. let ccx = bcx_ccx(bcx); - v = PointerCast(bcx, v, T_opaque_closure_ptr(ccx)); + let v = PointerCast(bcx, v, T_opaque_closure_ptr(ccx)); let body = GEPi(bcx, v, [0, abi::box_rc_field_body]); let bindings = GEPi(bcx, body, [0, abi::closure_elt_bindings]); @@ -1448,7 +1448,7 @@ fn trans_res_drop(cx: @block_ctxt, rs: ValueRef, did: ast::def_id, // Silly check check type_is_tup_like(cx, tup_ty); let drop_flag = GEP_tup_like(cx, tup_ty, rs, [0, 0]); - cx = drop_flag.bcx; + let cx = drop_flag.bcx; let null_test = IsNull(cx, Load(cx, drop_flag.val)); CondBr(cx, null_test, next_cx.llbb, drop_cx.llbb); cx = drop_cx; @@ -1487,7 +1487,7 @@ fn decr_refcnt_maybe_free(cx: @block_ctxt, box_ptr: ValueRef, t: ty::t) let free_cx = new_sub_block_ctxt(cx, "free"); let next_cx = new_sub_block_ctxt(cx, "next"); let llbox_ty = T_opaque_obj_ptr(ccx); - box_ptr = PointerCast(cx, box_ptr, llbox_ty); + let box_ptr = PointerCast(cx, box_ptr, llbox_ty); let null_test = IsNull(cx, box_ptr); CondBr(cx, null_test, next_cx.llbb, rc_adj_cx.llbb); let rc_ptr = @@ -1640,6 +1640,7 @@ fn iter_structural_ty(cx: @block_ctxt, av: ValueRef, t: ty::t, if std::vec::len::(variant.args) == 0u { ret cx; } let fn_ty = variant.ctor_ty; let ccx = bcx_ccx(cx); + let cx = cx; alt ty::struct(ccx.tcx, fn_ty) { ty::ty_fn(_, args, _, _, _) { let j = 0u; @@ -1661,6 +1662,7 @@ fn iter_structural_ty(cx: @block_ctxt, av: ValueRef, t: ty::t, /* Typestate constraint that shows the unimpl case doesn't happen? */ + let cx = cx; alt ty::struct(bcx_tcx(cx), t) { ty::ty_rec(fields) { let i: int = 0; @@ -2054,7 +2056,7 @@ fn copy_val(cx: @block_ctxt, action: copy_action, dst: ValueRef, fn copy_val_no_check(bcx: @block_ctxt, action: copy_action, dst: ValueRef, src: ValueRef, t: ty::t) -> @block_ctxt { - let ccx = bcx_ccx(bcx); + let ccx = bcx_ccx(bcx), bcx = bcx; if ty::type_is_scalar(ccx.tcx, t) || ty::type_is_native(ccx.tcx, t) { Store(bcx, src, dst); ret bcx; @@ -2084,7 +2086,7 @@ fn copy_val_no_check(bcx: @block_ctxt, action: copy_action, dst: ValueRef, fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef, src: lval_result, t: ty::t) -> @block_ctxt { let src_val = src.val; - let tcx = bcx_tcx(cx); + let tcx = bcx_tcx(cx), cx = cx; if ty::type_is_scalar(tcx, t) || ty::type_is_native(tcx, t) { if src.kind == owned { src_val = Load(cx, src_val); } Store(cx, src_val, dst); @@ -2230,7 +2232,7 @@ fn trans_unary(bcx: @block_ctxt, op: ast::unop, e: @ast::expr, fn trans_expr_fn(bcx: @block_ctxt, f: ast::_fn, sp: span, id: ast::node_id, dest: dest) -> @block_ctxt { if dest == ignore { ret bcx; } - let ccx = bcx_ccx(bcx); + let ccx = bcx_ccx(bcx), bcx = bcx; let fty = node_id_type(ccx, id); check returns_non_ty_var(ccx, fty); let llfnty = type_of_fn_from_ty(ccx, sp, fty, 0u); @@ -2238,9 +2240,8 @@ fn trans_expr_fn(bcx: @block_ctxt, f: ast::_fn, sp: span, let s = mangle_internal_name_by_path(ccx, sub_cx.path); let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty); - let copying = - f.proto == ast::proto_shared(ast::sugar_normal) - || f.proto == ast::proto_shared(ast::sugar_sexy); + let copying = f.proto == ast::proto_shared(ast::sugar_normal) + || f.proto == ast::proto_shared(ast::sugar_sexy); let env; alt f.proto { ast::proto_block. | ast::proto_shared(_) { @@ -2300,7 +2301,7 @@ fn trans_eager_binop(cx: @block_ctxt, op: ast::binop, lhs: ValueRef, if op == ast::add && ty::type_is_sequence(bcx_tcx(cx), intype) { ret tvec::trans_add(cx, intype, lhs, rhs, dest); } - let val = alt op { + let cx = cx, val = alt op { ast::add. { if is_float { FAdd(cx, lhs, rhs) } else { Add(cx, lhs, rhs) } @@ -2573,9 +2574,9 @@ fn trans_for(cx: @block_ctxt, local: @ast::local, seq: @ast::expr, new_loop_scope_block_ctxt(bcx, option::some(next_cx), outer_next_cx, "for loop scope"); Br(bcx, scope_cx.llbb); - curr = PointerCast(bcx, curr, T_ptr(type_of_or_i8(bcx, t))); - bcx = trans_alt::bind_irrefutable_pat(scope_cx, local.node.pat, curr, - false); + let curr = PointerCast(bcx, curr, T_ptr(type_of_or_i8(bcx, t))); + let bcx = trans_alt::bind_irrefutable_pat(scope_cx, local.node.pat, + curr, false); bcx = trans_block_dps(bcx, body, ignore); Br(bcx, next_cx.llbb); ret next_cx; @@ -2649,7 +2650,7 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef], // Finally, synthesize a type for that whole vector. let closure_ty: ty::t = ty::mk_tup(tcx, closure_tys); - let temp_cleanups = []; + let temp_cleanups = [], bcx = bcx; // Allocate a box that can hold something closure-sized. let (closure, box) = if copying { let r = trans_malloc_boxed(bcx, closure_ty); @@ -2903,7 +2904,7 @@ fn lval_static_fn(bcx: @block_ctxt, tpt: ty::ty_param_kinds_and_ty, trans_external_path(bcx, fn_id, tpt) }; let tys = ty::node_id_to_type_params(bcx_tcx(bcx), id); - let gen = none; + let gen = none, bcx = bcx; if std::vec::len::(tys) != 0u { let tydescs = [], tis = []; for t in tys { @@ -3736,7 +3737,7 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef, // This will be needed if this is a generic call, because the callee has // to cast her view of the arguments to the caller's view. let arg_tys = type_of_explicit_args(ccx, cx.sp, args); - let i = 0u; + let i = 0u, outer_cx = outer_cx; for e: @ast::expr in es { let is_referenced = alt ret_style { ast::return_ref(_, arg_n) { i + 1u == arg_n } @@ -3838,7 +3839,7 @@ fn trans_c_stack_native_call(bcx: @block_ctxt, f: @ast::expr, args: [@ast::expr], dest: dest) -> @block_ctxt { let ccx = bcx_ccx(bcx); let f_res = trans_callee(bcx, f); - let llfn = f_res.val; bcx = f_res.bcx; + let llfn = f_res.val, bcx = f_res.bcx; // Translate the callee. let { params: _, ty: fn_ty } = ty::expr_ty_params_and_ty(bcx_tcx(bcx), f); @@ -4033,6 +4034,7 @@ fn trans_landing_pad(bcx: @block_ctxt, fn trans_tup(bcx: @block_ctxt, elts: [@ast::expr], id: ast::node_id, dest: dest) -> @block_ctxt { let t = node_id_type(bcx.fcx.lcx.ccx, id); + let bcx = bcx; let addr = alt dest { ignore. { for ex in elts { bcx = trans_expr(bcx, ex, ignore); } @@ -4057,6 +4059,7 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field], base: option::t<@ast::expr>, id: ast::node_id, dest: dest) -> @block_ctxt { let t = node_id_type(bcx_ccx(bcx), id); + let bcx = bcx; let addr = alt dest { ignore. { for fld in fields { @@ -4116,6 +4119,7 @@ fn trans_expr_save_in(bcx: @block_ctxt, e: @ast::expr, dest: ValueRef) // trans_expr_save_in. For intermediates where you don't care about lval-ness, // use trans_temp_expr. fn trans_temp_lval(bcx: @block_ctxt, e: @ast::expr) -> lval_result { + let bcx = bcx; if expr_is_lval(bcx_tcx(bcx), e) { ret trans_lval(bcx, e); } else { @@ -4429,6 +4433,7 @@ fn trans_check_expr(cx: @block_ctxt, e: @ast::expr, s: str) -> @block_ctxt { fn trans_fail_expr(bcx: @block_ctxt, sp_opt: option::t, fail_expr: option::t<@ast::expr>) -> @block_ctxt { + let bcx = bcx; alt fail_expr { some(expr) { let tcx = bcx_tcx(bcx); @@ -4483,7 +4488,7 @@ fn trans_fail_value(bcx: @block_ctxt, sp_opt: option::t, fn trans_break_cont(sp: span, bcx: @block_ctxt, to_end: bool) -> @block_ctxt { // Locate closest loop block, outputting cleanup as we go. - let cleanup_cx = bcx; + let cleanup_cx = bcx, bcx = bcx; while true { bcx = trans_block_cleanups(bcx, cleanup_cx); alt copy cleanup_cx.kind { @@ -4524,7 +4529,7 @@ fn trans_cont(sp: span, cx: @block_ctxt) -> @block_ctxt { } fn trans_ret(bcx: @block_ctxt, e: option::t<@ast::expr>) -> @block_ctxt { - let cleanup_cx = bcx; + let cleanup_cx = bcx, bcx = bcx; alt e { some(x) { if ast_util::ret_by_ref(bcx.fcx.ret_style) { @@ -4582,6 +4587,7 @@ fn init_local(bcx: @block_ctxt, local: @ast::local) -> @block_ctxt { } }; + let bcx = bcx; alt local.node.init { some(init) { if init.op == ast::init_assign || @@ -4730,7 +4736,7 @@ fn trans_block_cleanups(bcx: @block_ctxt, cleanup_cx: @block_ctxt) -> if cleanup_cx.kind == NON_SCOPE_BLOCK { assert (std::vec::len::(cleanup_cx.cleanups) == 0u); } - let i = std::vec::len::(cleanup_cx.cleanups); + let i = std::vec::len::(cleanup_cx.cleanups), bcx = bcx; while i > 0u { i -= 1u; let c = cleanup_cx.cleanups[i]; @@ -4863,6 +4869,7 @@ fn trans_block(bcx: @block_ctxt, b: ast::blk) -> @block_ctxt { fn trans_block_dps(bcx: @block_ctxt, b: ast::blk, dest: dest) -> @block_ctxt { + let bcx = bcx; block_locals(b) {|local| bcx = alloc_local(bcx, local); }; for s: @ast::stmt in b.node.stmts { bcx = trans_stmt(bcx, *s); @@ -4998,41 +5005,25 @@ fn create_llargs_for_fn_args(cx: @fn_ctxt, ty_self: option::t, } fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg], - arg_tys: [ty::arg], ignore_mut: bool) - -> @block_ctxt { - let arg_n: uint = 0u; + arg_tys: [ty::arg]) -> @block_ctxt { + let arg_n: uint = 0u, bcx = bcx; for arg in arg_tys { let id = args[arg_n].id; - let mutated = !ignore_mut && fcx.lcx.ccx.mut_map.contains_key(id); let argval = alt fcx.llargs.get(id) { local_mem(v) { v } }; alt arg.mode { ast::by_mut_ref. { } ast::by_move. { add_clean(bcx, argval, arg.ty); } ast::by_val. { - if mutated || !ty::type_is_immediate(bcx_tcx(bcx), arg.ty) { + if !ty::type_is_immediate(bcx_tcx(bcx), arg.ty) { let {bcx: cx, val: alloc} = alloc_ty(bcx, arg.ty); bcx = cx; Store(bcx, argval, alloc); - if mutated { - bcx = take_ty(bcx, alloc, arg.ty); - add_clean(bcx, alloc, arg.ty); - } fcx.llargs.insert(id, local_mem(alloc)); } else { fcx.llargs.insert(id, local_imm(argval)); } } - ast::by_ref. { - // Overwrite the llargs entry for locally mutated params - // with a local alloca. - if mutated { - let {bcx: cx, val: alloc} = alloc_ty(bcx, arg.ty); - bcx = copy_val(cx, INIT, alloc, - load_if_immediate(cx, argval, arg.ty), arg.ty); - fcx.llargs.insert(id, local_mem(alloc)); - add_clean(bcx, alloc, arg.ty); - } - } + ast::by_ref. {} } arg_n += 1u; } @@ -5129,7 +5120,7 @@ fn trans_closure(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef, let block_ty = node_id_type(cx.ccx, f.body.node.id); let arg_tys = arg_tys_of_fn(fcx.lcx.ccx, id); - bcx = copy_args_to_allocas(fcx, bcx, f.decl.inputs, arg_tys, false); + bcx = copy_args_to_allocas(fcx, bcx, f.decl.inputs, arg_tys); maybe_load_env(fcx); @@ -5254,7 +5245,7 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id, let arg_tys = arg_tys_of_fn(ccx, variant.node.id); let bcx = new_top_block_ctxt(fcx); let lltop = bcx.llbb; - bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys, true); + bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys); // Cast the tag to a type we can GEP into. let llblobptr = @@ -5991,7 +5982,7 @@ fn decl_crate_map(sess: session::session, mapname: str, let n_subcrates = 1; let cstore = sess.get_cstore(); while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; } - if !sess.get_opts().library { mapname = "toplevel"; } + let mapname = sess.get_opts().library ? mapname : "toplevel"; let sym_name = "_rust_crate_map_" + mapname; let arrtype = T_array(int_type, n_subcrates as uint); let maptype = T_struct([int_type, arrtype]); diff --git a/src/comp/middle/trans_alt.rs b/src/comp/middle/trans_alt.rs index ce9768d88a4..9990e9dbfef 100644 --- a/src/comp/middle/trans_alt.rs +++ b/src/comp/middle/trans_alt.rs @@ -44,7 +44,7 @@ tag opt_result { range_result(result, result); } fn trans_opt(bcx: @block_ctxt, o: opt) -> opt_result { - let ccx = bcx_ccx(bcx); + let ccx = bcx_ccx(bcx), bcx = bcx; alt o { lit(l) { alt l.node { @@ -249,7 +249,7 @@ fn get_options(ccx: @crate_ctxt, m: match, col: uint) -> [opt] { fn extract_variant_args(bcx: @block_ctxt, pat_id: ast::node_id, vdefs: {tg: def_id, var: def_id}, val: ValueRef) -> {vals: [ValueRef], bcx: @block_ctxt} { - let ccx = bcx.fcx.lcx.ccx; + let ccx = bcx.fcx.lcx.ccx, bcx = bcx; let ty_param_substs = ty::node_id_to_type_params(ccx.tcx, pat_id); let blobptr = val; let variants = ty::tag_variants(ccx.tcx, vdefs.tg); @@ -348,6 +348,7 @@ fn pick_col(m: match) -> uint { fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail, &exits: [exit_node]) { + let bcx = bcx; if vec::len(m) == 0u { Br(bcx, f()); ret; } if vec::len(m[0].pats) == 0u { let data = m[0].data; @@ -543,7 +544,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail, let le = trans::trans_compare(ge.bcx, ast::le, test_val, t, rend.val, t); let in_range = rslt(le.bcx, And(le.bcx, ge.val, le.val)); - /*let*/ bcx = in_range.bcx; //XXX uncomment for assertion + bcx = in_range.bcx; let cleanup_cx = trans::trans_block_cleanups(bcx, compare_cx); bcx = new_sub_block_ctxt(bcx, "compare_next"); @@ -580,7 +581,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail, fn make_phi_bindings(bcx: @block_ctxt, map: [exit_node], ids: ast_util::pat_id_map) -> bool { let our_block = bcx.llbb as uint; - let success = true; + let success = true, bcx = bcx; ids.items {|name, node_id| let llbbs = []; let vals = []; @@ -679,7 +680,7 @@ fn trans_alt(cx: @block_ctxt, expr: @ast::expr, arms: [ast::arm], // Not alt-related, but similar to the pattern-munging code above fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef, make_copy: bool) -> @block_ctxt { - let ccx = bcx.fcx.lcx.ccx; + let ccx = bcx.fcx.lcx.ccx, bcx = bcx; alt pat.node { ast::pat_bind(_) { if make_copy || ccx.copy_map.contains_key(pat.id) { @@ -690,9 +691,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef, check non_ty_var(ccx, ty); let llty = trans::type_of(ccx, pat.span, ty); let alloc = trans::alloca(bcx, llty); - bcx = - trans::copy_val(bcx, trans::INIT, alloc, - trans::load_if_immediate(bcx, val, ty), ty); + bcx = trans::copy_val(bcx, trans::INIT, alloc, + trans::load_if_immediate(bcx, val, ty), ty); bcx.fcx.lllocals.insert(pat.id, local_mem(alloc)); trans_common::add_clean(bcx, alloc, ty); } else { bcx.fcx.lllocals.insert(pat.id, local_mem(val)); } diff --git a/src/comp/middle/trans_objects.rs b/src/comp/middle/trans_objects.rs index 526f60dd88a..73fed9205ac 100644 --- a/src/comp/middle/trans_objects.rs +++ b/src/comp/middle/trans_objects.rs @@ -54,7 +54,7 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id, // Both regular arguments and type parameters are handled here. create_llargs_for_fn_args(fcx, none::, fn_args, ty_params); let arg_tys: [ty::arg] = arg_tys_of_fn(ccx, ctor_id); - bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys, true); + bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys); // Pick up the type of this object by looking at our own output type, that // is, the output type of the object constructor we're building. @@ -216,6 +216,7 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id, // itself. fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj, id: ast::node_id, dest: trans::dest) -> @block_ctxt { + let bcx = bcx; if dest == trans::ignore { alt anon_obj.inner_obj { some(e) { ret trans::trans_expr(bcx, e, trans::ignore); } diff --git a/src/comp/middle/trans_vec.rs b/src/comp/middle/trans_vec.rs index 5df7164328c..b63aee9ae1d 100644 --- a/src/comp/middle/trans_vec.rs +++ b/src/comp/middle/trans_vec.rs @@ -99,7 +99,7 @@ fn make_free_glue(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t) -> fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id, dest: dest) -> @block_ctxt { - let ccx = bcx_ccx(bcx); + let ccx = bcx_ccx(bcx), bcx = bcx; if dest == trans::ignore { for arg in args { bcx = trans::trans_expr(bcx, arg, trans::ignore); @@ -150,10 +150,9 @@ fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef, let ccx = bcx_ccx(cx); let unit_ty = ty::sequence_element_type(bcx_tcx(cx), vec_ty); let dynamic = ty::type_has_dynamic_size(bcx_tcx(cx), unit_ty); - if dynamic { - lhsptr = PointerCast(cx, lhsptr, T_ptr(T_ptr(ccx.opaque_vec_type))); - rhs = PointerCast(cx, rhs, T_ptr(ccx.opaque_vec_type)); - } + let (lhsptr, rhs) = !dynamic ? (lhsptr, rhs) : + (PointerCast(cx, lhsptr, T_ptr(T_ptr(ccx.opaque_vec_type))), + PointerCast(cx, rhs, T_ptr(ccx.opaque_vec_type))); let strings = alt ty::struct(bcx_tcx(cx), vec_ty) { ty::ty_str. { true } ty::ty_vec(_) { false } @@ -271,7 +270,7 @@ fn iter_vec_raw(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t, let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty); let llunitty = type_of_or_i8(bcx, unit_ty); let {bcx: bcx, val: unit_sz} = size_of(bcx, unit_ty); - vptr = PointerCast(bcx, vptr, T_ptr(T_vec(ccx, llunitty))); + let vptr = PointerCast(bcx, vptr, T_ptr(T_vec(ccx, llunitty))); let data_ptr = get_dataptr(bcx, vptr, llunitty); // Calculate the last pointer address we want to handle. @@ -302,7 +301,7 @@ fn iter_vec_raw(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t, fn iter_vec(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t, f: iter_vec_block) -> @block_ctxt { let ccx = bcx_ccx(bcx); - vptr = PointerCast(bcx, vptr, T_ptr(ccx.opaque_vec_type)); + let vptr = PointerCast(bcx, vptr, T_ptr(ccx.opaque_vec_type)); ret iter_vec_raw(bcx, vptr, vec_ty, get_fill(bcx, vptr), f); } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 2c8034abc0e..be79474536d 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1693,9 +1693,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, element_ty: ty::t, body: ast::blk, node_id: ast::node_id) -> bool { let locid = lookup_local(fcx, local.span, local.node.id); - element_ty = - demand::simple(fcx, local.span, element_ty, - ty::mk_var(fcx.ccx.tcx, locid)); + let element_ty = demand::simple(fcx, local.span, element_ty, + ty::mk_var(fcx.ccx.tcx, locid)); let bot = check_decl_local(fcx, local); check_block(fcx, body); // Unify type of decl with element type of the seq diff --git a/src/comp/syntax/parse/lexer.rs b/src/comp/syntax/parse/lexer.rs index 10581643701..685b93941b9 100644 --- a/src/comp/syntax/parse/lexer.rs +++ b/src/comp/syntax/parse/lexer.rs @@ -158,17 +158,6 @@ fn consume_block_comment(rdr: reader) { be consume_whitespace_and_comments(rdr); } -fn string_to_int(s: str) -> int { - let negative = false; - if str::char_at(s, 0u) == '-' { - negative = true; - s = str::substr(s, 1u, str::byte_len(s) - 1u); - } - let accum_int: int = 0; - for c: u8 in s { accum_int *= 10; accum_int += dec_digit_val(c as char); } - ret if negative { -accum_int } else { accum_int }; -} - fn scan_exponent(rdr: reader) -> option::t { let c = rdr.curr(); let rslt = ""; @@ -210,7 +199,7 @@ fn scan_dec_digits(rdr: reader) -> str { } fn scan_number(c: char, rdr: reader) -> token::token { - let accum_int = 0; + let accum_int = 0, c = c; let num_str: str = ""; let n = rdr.next(); if c == '0' && n == 'x' { @@ -233,7 +222,7 @@ fn scan_number(c: char, rdr: reader) -> token::token { } } else { num_str = scan_dec_digits_with_prefix(rdr); - accum_int = string_to_int(num_str); + accum_int = std::int::from_str(num_str); } c = rdr.curr(); n = rdr.next(); @@ -321,8 +310,8 @@ fn scan_number(c: char, rdr: reader) -> token::token { } fn scan_numeric_escape(rdr: reader, n_hex_digits: uint) -> char { - let accum_int = 0; - while n_hex_digits != 0u { + let accum_int = 0, i = n_hex_digits; + while i != 0u { let n = rdr.curr(); rdr.bump(); if !is_hex_digit(n) { @@ -331,7 +320,7 @@ fn scan_numeric_escape(rdr: reader, n_hex_digits: uint) -> char { } accum_int *= 16; accum_int += hex_digit_val(n); - n_hex_digits -= 1u; + i -= 1u; } ret accum_int as char; } diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index b22afb9efdb..66a3b3440e8 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -1038,6 +1038,7 @@ fn parse_dot_or_call_expr(p: parser) -> @ast::expr { fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr { let lo = e.span.lo; let hi = e.span.hi; + let e = e; while true { alt p.peek() { token::LPAREN. { diff --git a/src/lib/aio.rs b/src/lib/aio.rs index 162090af0d7..d369f26f256 100644 --- a/src/lib/aio.rs +++ b/src/lib/aio.rs @@ -157,7 +157,7 @@ fn iotask(c: chan) { log "io task init"; // Spawn our request task - let reqtask = task::spawn_joinable(c, request_task); + let reqtask = task::spawn_joinable(copy c, request_task); log "uv run task init"; // Enter IO loop. This never returns until aio_stop is called. diff --git a/src/lib/float.rs b/src/lib/float.rs index e37b9f386b1..0b8a701e7aa 100644 --- a/src/lib/float.rs +++ b/src/lib/float.rs @@ -17,18 +17,19 @@ num - The float value digits: The number of significant digits */ fn to_str(num: float, digits: uint) -> str { - let accum = if num < 0.0 { num = -num; "-" } else { "" }; + let (num, accum) = num < 0.0 ? (-num, "-") : (num, ""); let trunc = num as uint; let frac = num - (trunc as float); accum += uint::str(trunc); if frac == 0.0 || digits == 0u { ret accum; } accum += "."; - while digits > 0u && frac > 0.0 { + let i = digits; + while i > 0u && frac > 0.0 { frac *= 10.0; let digit = frac as uint; accum += uint::str(digit); frac -= digit as float; - digits -= 1u; + i -= 1u; } ret accum; } @@ -60,7 +61,7 @@ Returns: Otherwise, the floating-point number represented [num]. */ fn from_str(num: str) -> float { - num = str::trim(num); + let num = str::trim(num); let pos = 0u; //Current byte position in the string. //Used to walk the string in O(n). diff --git a/src/lib/int.rs b/src/lib/int.rs index 62fb0a7cb63..65edaf75dc3 100644 --- a/src/lib/int.rs +++ b/src/lib/int.rs @@ -80,7 +80,8 @@ Function: range Iterate over the range [`lo`..`hi`) */ fn range(lo: int, hi: int, it: block(int)) { - while lo < hi { it(lo); lo += 1; } + let i = lo; + while i < hi { it(i); i += 1; } } /* diff --git a/src/lib/io.rs b/src/lib/io.rs index dad3001262f..c2e9b0cec69 100644 --- a/src/lib/io.rs +++ b/src/lib/io.rs @@ -132,31 +132,31 @@ obj new_reader(rdr: buf_reader) { fn read_le_uint(size: uint) -> uint { let val = 0u; let pos = 0u; - while size > 0u { + let i = size; + while i > 0u { val += (rdr.read_byte() as uint) << pos; pos += 8u; - size -= 1u; + i -= 1u; } ret val; } fn read_le_int(size: uint) -> int { - let val = 0u; - let pos = 0u; - while size > 0u { + let val = 0u, pos = 0u, i = size; + while i > 0u { val += (rdr.read_byte() as uint) << pos; pos += 8u; - size -= 1u; + i -= 1u; } ret val as int; } // FIXME deal with eof? fn read_be_uint(sz: uint) -> uint { - let val = 0u; + let val = 0u, i = sz; - while sz > 0u { - sz -= 1u; - val += (rdr.read_byte() as uint) << sz * 8u; + while i > 0u { + i -= 1u; + val += (rdr.read_byte() as uint) << i * 8u; } ret val; } @@ -324,8 +324,8 @@ type writer = }; fn uint_to_le_bytes(n: uint, size: uint) -> [u8] { - let bytes: [u8] = []; - while size > 0u { bytes += [n & 255u as u8]; n >>= 8u; size -= 1u; } + let bytes: [u8] = [], i = size, n = n; + while i > 0u { bytes += [n & 255u as u8]; n >>= 8u; i -= 1u; } ret bytes; } diff --git a/src/lib/str.rs b/src/lib/str.rs index 48eac133bd1..ecc635d073f 100644 --- a/src/lib/str.rs +++ b/src/lib/str.rs @@ -277,7 +277,7 @@ fn char_range_at(s: str, i: uint) -> {ch: char, next: uint} { if w == 1u { ret {ch: b0 as char, next: i + 1u}; } let val = 0u; let end = i + w; - i += 1u; + let i = i + 1u; while i < end { let byte = s[i]; assert (byte & 192u8 == tag_cont_u8); diff --git a/src/lib/term.rs b/src/lib/term.rs index c0dc9ee588d..94c9fbca4e4 100644 --- a/src/lib/term.rs +++ b/src/lib/term.rs @@ -76,6 +76,7 @@ fn color_supported() -> bool { fn set_color(writer: io::buf_writer, first_char: u8, color: u8) { assert (color < 16u8); esc(writer); + let color = color; if color >= 8u8 { writer.write(['1' as u8, ';' as u8]); color -= 8u8; } writer.write([first_char, ('0' as u8) + color, 'm' as u8]); } diff --git a/src/lib/test.rs b/src/lib/test.rs index af1e15880af..649aa338d30 100644 --- a/src/lib/test.rs +++ b/src/lib/test.rs @@ -334,7 +334,7 @@ fn default_test_to_task(&&f: default_test_fn) -> joinable { configure_test_task(); f(); } - ret task::spawn_joinable(f, run_task); + ret task::spawn_joinable(copy f, run_task); } // Call from within a test task to make sure it's set up correctly diff --git a/src/lib/u64.rs b/src/lib/u64.rs index b0b78af3995..3109e5dc50f 100644 --- a/src/lib/u64.rs +++ b/src/lib/u64.rs @@ -52,6 +52,7 @@ fn to_str(n: u64, radix: uint) -> str { let s = ""; + let n = n; while n > 0u64 { s = digit(n % r64) + s; n /= r64; } ret s; } diff --git a/src/lib/u8.rs b/src/lib/u8.rs index 6faab75873c..c2f7aba7ce7 100644 --- a/src/lib/u8.rs +++ b/src/lib/u8.rs @@ -55,7 +55,8 @@ Function: range Iterate over the range [`lo`..`hi`) */ fn range(lo: u8, hi: u8, it: block(u8)) { - while lo < hi { it(lo); lo += 1u8; } + let i = lo; + while i < hi { it(i); i += 1u8; } } // Local Variables: diff --git a/src/lib/uint.rs b/src/lib/uint.rs index 5de9bd974e4..a9ea4d03c90 100644 --- a/src/lib/uint.rs +++ b/src/lib/uint.rs @@ -61,7 +61,8 @@ Function: range Iterate over the range [`lo`..`hi`) */ fn range(lo: uint, hi: uint, it: block(uint)) { - while lo < hi { it(lo); lo += 1u; } + let i = lo; + while i < hi { it(i); i += 1u; } } /* diff --git a/src/test/run-pass/issue-507.rs b/src/test/run-pass/issue-507.rs index 7f405141a7b..8a3339a065c 100644 --- a/src/test/run-pass/issue-507.rs +++ b/src/test/run-pass/issue-507.rs @@ -18,7 +18,7 @@ import std::comm::recv; fn grandchild(c: chan) { send(c, 42); } fn child(c: chan) { - let _grandchild = task::spawn_joinable(c, grandchild); + let _grandchild = task::spawn_joinable(copy c, grandchild); join(_grandchild); } diff --git a/src/test/run-pass/move-4-unique.rs b/src/test/run-pass/move-4-unique.rs index 2e91a799e76..27fedd2222f 100644 --- a/src/test/run-pass/move-4-unique.rs +++ b/src/test/run-pass/move-4-unique.rs @@ -2,6 +2,7 @@ use std; import std::uint; fn test(foo: ~{a: int, b: int, c: int}) -> ~{a: int, b: int, c: int} { + let foo = foo; let bar <- foo; let baz <- bar; let quux <- baz; diff --git a/src/test/run-pass/move-4.rs b/src/test/run-pass/move-4.rs index 5a104555375..76a4fa00924 100644 --- a/src/test/run-pass/move-4.rs +++ b/src/test/run-pass/move-4.rs @@ -3,6 +3,7 @@ use std; import std::uint; fn test(foo: @{a: int, b: int, c: int}) -> @{a: int, b: int, c: int} { + let foo = foo; let bar <- foo; let baz <- bar; let quux <- baz; diff --git a/src/test/run-pass/obj-docs.rs b/src/test/run-pass/obj-docs.rs index 8b5dd2121f0..f08897a2fa3 100644 --- a/src/test/run-pass/obj-docs.rs +++ b/src/test/run-pass/obj-docs.rs @@ -41,7 +41,7 @@ fn main() { } obj sender(c: chan) { - fn take(z: int) { send(c, z); } + fn take(z: int) { send(c, copy z); } } fn give_ints(t: taker) { t.take(1); t.take(2); t.take(3); } diff --git a/src/test/run-pass/obj-self-2.rs b/src/test/run-pass/obj-self-2.rs index ca33b382792..d0c450aaeba 100644 --- a/src/test/run-pass/obj-self-2.rs +++ b/src/test/run-pass/obj-self-2.rs @@ -2,8 +2,8 @@ fn main() { obj foo() { - fn m1(i: int) { i += 1; log "hi!"; } - fn m2(i: int) { i += 1; self.m1(i); } + fn m1(i: int) { let i = i + 1; log "hi!"; } + fn m2(i: int) { let i = i + 1; self.m1(i); } } let a = foo(); let i: int = 0; diff --git a/src/test/run-pass/obj-self-3.rs b/src/test/run-pass/obj-self-3.rs index 29720216bd1..16aa3a60971 100644 --- a/src/test/run-pass/obj-self-3.rs +++ b/src/test/run-pass/obj-self-3.rs @@ -2,9 +2,9 @@ fn main() { obj foo() { - fn m1(i: int) -> int { i += 1; ret i; } + fn m1(i: int) -> int { let i = i + 1; ret i; } fn m2(i: int) -> int { ret self.m1(i); } - fn m3(i: int) -> int { i += 1; ret self.m1(i); } + fn m3(i: int) -> int { let i = i + 1; ret self.m1(i); } } let a = foo(); let i: int = 0;