Forbid assignment to by-reference bindings

Issue #918
This commit is contained in:
Marijn Haverbeke 2011-09-15 14:08:54 +02:00
parent d7a1d6a1cb
commit 25787bd2b8
12 changed files with 25 additions and 21 deletions

View File

@ -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 ty_can_unsafely_include(cx: ctx, 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
}

View File

@ -245,6 +245,7 @@ fn is_immutable_def(def: def) -> option::t<str> {
if !mut { some("upvar") } else { is_immutable_def(*inner) }
}
def_binding(_) { some("binding") }
def_local(_, let_ref.) { some("by-reference binding") }
_ { none }
}
}

View File

@ -608,7 +608,7 @@ fn scope_closes(sc: scope) -> option::t<bool> {
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 }

View File

@ -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 }
}
}

View File

@ -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 @@ tag if_ty { if_check; plain_if; }
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<def> {
fn local_node_id_to_def_id(fcx: fn_ctxt, i: node_id) -> option::t<def_id> {
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)
}

View File

@ -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...) */ }

View File

@ -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);

View File

@ -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);
}

View File

@ -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; }

View File

@ -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};

View File

@ -32,7 +32,7 @@ tag def {
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 */

View File

@ -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; }