From 25787bd2b887edcd7749268b6d0d1376312714d1 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 15 Sep 2011 14:08:54 +0200 Subject: [PATCH] Forbid assignment to by-reference bindings Issue #918 --- src/comp/middle/alias.rs | 4 ++-- src/comp/middle/mut.rs | 1 + src/comp/middle/resolve.rs | 10 ++++++---- src/comp/middle/trans.rs | 4 ++-- src/comp/middle/tstate/auxiliary.rs | 9 +++++---- src/comp/middle/tstate/bitvectors.rs | 2 +- src/comp/middle/tstate/pre_post_conditions.rs | 6 +++--- src/comp/middle/tstate/states.rs | 2 +- src/comp/middle/ty.rs | 2 +- src/comp/middle/typeck.rs | 2 +- src/comp/syntax/ast.rs | 2 +- src/comp/syntax/ast_util.rs | 2 +- 12 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs index d5cecec7e6f..8ad3a4ca934 100644 --- a/src/comp/middle/alias.rs +++ b/src/comp/middle/alias.rs @@ -324,7 +324,7 @@ fn check_ret_ref(cx: ctx, sc: scope, mut: bool, expr: @ast::expr) { let mut_field = mut_field(root.ds); alt path_def(cx, root.ex) { none. { bad = some("temporary"); } - some(ast::def_local(did)) | some(ast::def_binding(did)) | + some(ast::def_local(did, _)) | some(ast::def_binding(did)) | some(ast::def_arg(did, _)) { let cur_node = did.node; while true { @@ -590,7 +590,7 @@ fn helper(tcx: ty::ctxt, needle: ty::t, haystack: ty::t, mut: bool) -> fn def_is_local(d: ast::def, objfields_count: bool) -> bool { ret alt d { - ast::def_local(_) | ast::def_arg(_, _) | ast::def_binding(_) | + ast::def_local(_, _) | ast::def_arg(_, _) | ast::def_binding(_) | ast::def_upvar(_, _, _) { true } diff --git a/src/comp/middle/mut.rs b/src/comp/middle/mut.rs index 11c56456ebf..641d72af16d 100644 --- a/src/comp/middle/mut.rs +++ b/src/comp/middle/mut.rs @@ -245,6 +245,7 @@ fn is_immutable_def(def: def) -> option::t { if !mut { some("upvar") } else { is_immutable_def(*inner) } } def_binding(_) { some("binding") } + def_local(_, let_ref.) { some("by-reference binding") } _ { none } } } diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 587ad4541ce..b8f10a8f3e7 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -608,7 +608,7 @@ fn scope_closes(sc: scope) -> option::t { fn def_is_local(d: def) -> bool { ret alt d { - ast::def_arg(_, _) | ast::def_local(_) | ast::def_binding(_) | + ast::def_arg(_, _) | ast::def_local(_, _) | ast::def_binding(_) | ast::def_upvar(_, _, _) { true } @@ -797,10 +797,12 @@ fn lookup_in_block(name: ident, b: ast::blk_, pos: uint, loc_pos: uint, let j = vec::len(locs); while j > 0u { j -= 1u; - let (_, loc) = locs[j]; + let (style, loc) = locs[j]; if ns == ns_value && (i < pos || j < loc_pos) { alt lookup_in_pat(name, loc.node.pat) { - some(did) { ret some(ast::def_local(did)); } + some(did) { + ret some(ast::def_local(did, style)); + } _ { } } } @@ -1154,7 +1156,7 @@ fn ns_for_def(d: def) -> namespace { ast::def_native_mod(_) { ns_module } ast::def_const(_) { ns_value } ast::def_arg(_, _) { ns_value } - ast::def_local(_) { ns_value } + ast::def_local(_, _) { ns_value } ast::def_upvar(_, _, _) { ns_value } ast::def_variant(_, _) { ns_value } ast::def_ty(_) { ns_type } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index a456608776e..c341a2a8ee7 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -2871,7 +2871,7 @@ fn trans_local_var(cx: @block_ctxt, def: ast::def) -> lval_result { assert (cx.fcx.llargs.contains_key(did.node)); ret lval_mem(cx, cx.fcx.llargs.get(did.node)); } - ast::def_local(did) { + ast::def_local(did, _) { assert (cx.fcx.lllocals.contains_key(did.node)); ret lval_mem(cx, cx.fcx.lllocals.get(did.node)); } @@ -4399,7 +4399,7 @@ fn trans_ret(cx: @block_ctxt, e: option::t<@ast::expr>) -> result { let is_local = alt x.node { ast::expr_path(p) { alt bcx_tcx(bcx).def_map.get(x.id) { - ast::def_local(_) { true } + ast::def_local(_, _) { true } _ { false } } } diff --git a/src/comp/middle/tstate/auxiliary.rs b/src/comp/middle/tstate/auxiliary.rs index 39312e17ca1..99d3252a2dc 100644 --- a/src/comp/middle/tstate/auxiliary.rs +++ b/src/comp/middle/tstate/auxiliary.rs @@ -575,8 +575,8 @@ fn expr_to_constr_arg(tcx: ty::ctxt, e: @expr) -> @constr_arg_use { alt e.node { expr_path(p) { alt tcx.def_map.find(e.id) { - some(def_local(id)) | some(def_arg(id, _)) | some(def_binding(id)) | - some(def_upvar(id, _, _)) { + some(def_local(id, _)) | some(def_arg(id, _)) | + some(def_binding(id)) | some(def_upvar(id, _, _)) { ret @respan(p.span, carg_ident({ident: p.node.idents[0], node: id.node})); } @@ -790,7 +790,8 @@ fn path_to_ident(cx: ty::ctxt, p: path) -> ident { fn local_node_id_to_def_id_strict(fcx: fn_ctxt, sp: span, i: node_id) -> def_id { alt local_node_id_to_def(fcx, i) { - some(def_local(id)) | some(def_arg(id, _)) | some(def_upvar(id, _, _)) { + some(def_local(id, _)) | some(def_arg(id, _)) | + some(def_upvar(id, _, _)) { ret id; } some(_) { @@ -813,7 +814,7 @@ fn local_node_id_to_def(fcx: fn_ctxt, i: node_id) -> option::t { fn local_node_id_to_def_id(fcx: fn_ctxt, i: node_id) -> option::t { alt local_node_id_to_def(fcx, i) { - some(def_local(id)) | some(def_arg(id, _)) | some(def_binding(id)) | + some(def_local(id, _)) | some(def_arg(id, _)) | some(def_binding(id)) | some(def_upvar(id, _, _)) { some(id) } diff --git a/src/comp/middle/tstate/bitvectors.rs b/src/comp/middle/tstate/bitvectors.rs index 0d9e558b1f7..bfc698f7311 100644 --- a/src/comp/middle/tstate/bitvectors.rs +++ b/src/comp/middle/tstate/bitvectors.rs @@ -184,7 +184,7 @@ fn clear_in_poststate_expr(fcx: fn_ctxt, e: @expr, t: poststate) { alt vec::last(p.node.idents) { some(i) { alt local_node_id_to_def(fcx, e.id) { - some(def_local(d_id)) { + some(def_local(d_id, _)) { clear_in_poststate_(bit_num(fcx, ninit(d_id.node, i)), t); } some(_) {/* ignore args (for now...) */ } diff --git a/src/comp/middle/tstate/pre_post_conditions.rs b/src/comp/middle/tstate/pre_post_conditions.rs index 8cb28cfaca4..d7697d47668 100644 --- a/src/comp/middle/tstate/pre_post_conditions.rs +++ b/src/comp/middle/tstate/pre_post_conditions.rs @@ -197,7 +197,7 @@ fn gen_if_local(fcx: fn_ctxt, lhs: @expr, rhs: @expr, larger_id: node_id, alt node_id_to_def(fcx.ccx, new_var) { some(d) { alt d { - def_local(d_id) { + def_local(d_id, _) { find_pre_post_expr(fcx, rhs); let p = expr_pp(fcx.ccx, rhs); set_pre_and_post(fcx.ccx, larger_id, p.precondition, @@ -235,7 +235,7 @@ fn handle_update(fcx: fn_ctxt, parent: @expr, lhs: @expr, rhs: @expr, // pure and assign_op require the lhs to be init'd let df = node_id_to_def_strict(fcx.ccx.tcx, lhs.id); alt df { - def_local(d_id) { + def_local(d_id, _) { let i = bit_num(fcx, ninit(d_id.node, path_to_ident(fcx.ccx.tcx, p))); @@ -281,7 +281,7 @@ fn handle_var(fcx: fn_ctxt, rslt: pre_and_post, id: node_id, name: ident) { fn handle_var_def(fcx: fn_ctxt, rslt: pre_and_post, def: def, name: ident) { alt def { - def_local(d_id) | def_arg(d_id, _) { + def_local(d_id, _) | def_arg(d_id, _) { use_var(fcx, d_id.node); let i = bit_num(fcx, ninit(d_id.node, name)); require_and_preserve(i, rslt); diff --git a/src/comp/middle/tstate/states.rs b/src/comp/middle/tstate/states.rs index 620592fd378..fd227d3042f 100644 --- a/src/comp/middle/tstate/states.rs +++ b/src/comp/middle/tstate/states.rs @@ -232,7 +232,7 @@ fn gen_if_local(fcx: fn_ctxt, p: poststate, e: @expr) -> bool { alt e.node { expr_path(pth) { alt fcx.ccx.tcx.def_map.find(e.id) { - some(def_local(loc)) { + some(def_local(loc, _)) { ret set_in_poststate_ident(fcx, loc.node, path_to_ident(fcx.ccx.tcx, pth), p); } diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 84400b8c03a..eeea7d4358f 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -2559,7 +2559,7 @@ fn def_has_ty_params(def: ast::def) -> bool { ast::def_mod(_) { ret false; } ast::def_const(_) { ret false; } ast::def_arg(_, _) { ret false; } - ast::def_local(_) { ret false; } + ast::def_local(_, _) { ret false; } ast::def_upvar(_, _, _) { ret false; } ast::def_variant(_, _) { ret true; } ast::def_ty(_) { ret false; } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 0e2ace6291b..226d012bf78 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -92,7 +92,7 @@ fn ty_param_kinds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) -> let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, id.node)); ret {kinds: no_kinds, ty: typ}; } - ast::def_local(id) { + ast::def_local(id, _) { assert (fcx.locals.contains_key(id.node)); let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, id.node)); ret {kinds: no_kinds, ty: typ}; diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index 5e6269a9a8f..7f64b8de699 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -32,7 +32,7 @@ def_native_mod(def_id); def_const(def_id); def_arg(def_id, mode); - def_local(def_id); + def_local(def_id, let_style); def_variant(def_id, /* tag */def_id); /* variant */ diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs index b6c4eb9a929..17c8ac2cef1 100644 --- a/src/comp/syntax/ast_util.rs +++ b/src/comp/syntax/ast_util.rs @@ -30,7 +30,7 @@ fn def_id_of_def(d: def) -> def_id { def_native_mod(id) { ret id; } def_const(id) { ret id; } def_arg(id, _) { ret id; } - def_local(id) { ret id; } + def_local(id, _) { ret id; } def_variant(_, id) { ret id; } def_ty(id) { ret id; } def_ty_arg(_, _) { fail; } -- GitLab