Skip to content

Commit 8ab02f7

Browse files
committed
Forbid blocks from deinitializing upvars
Move expressions where the RHS is an upvar are now forbidden within block expressions.
1 parent efed843 commit 8ab02f7

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

src/comp/middle/tstate/states.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import tritv::ttrue;
1717
import bitvectors::*;
1818
import syntax::ast::*;
1919
import syntax::ast_util::*;
20+
import syntax::codemap::span;
2021
import middle::ty::expr_ty;
2122
import middle::ty::type_is_nil;
2223
import middle::ty::type_is_bot;
@@ -31,10 +32,28 @@ import util::common::log_stmt;
3132
import util::common::log_stmt_err;
3233
import util::common::log_expr_err;
3334

35+
fn forbid_upvar(fcx: &fn_ctxt, rhs_id: &node_id, sp: &span,
36+
t: oper_type) {
37+
alt t {
38+
oper_move. {
39+
alt local_node_id_to_def(fcx, rhs_id) {
40+
some(def_upvar(_,_,_)) {
41+
fcx.ccx.tcx.sess.span_err(sp, "Tried to deinitialize a variable \
42+
declared in a different scope");
43+
}
44+
_ {}
45+
}
46+
}
47+
_ { /* do nothing */ }
48+
}
49+
}
50+
3451
fn handle_move_or_copy(fcx: &fn_ctxt, post: &poststate, rhs_path: &path,
3552
rhs_id: &node_id, instlhs: &inst, init_op: &init_op) {
36-
let rhs_d = local_node_id_to_def_id(fcx, rhs_id);
37-
alt rhs_d {
53+
forbid_upvar(fcx, rhs_id, rhs_path.span, op_to_oper_ty(init_op));
54+
55+
let rhs_d_id = local_node_id_to_def_id(fcx, rhs_id);
56+
alt rhs_d_id {
3857
some(rhsid) {
3958
// RHS is a local var
4059
let instrhs =
@@ -110,6 +129,7 @@ fn find_pre_post_state_two(fcx: &fn_ctxt, pres: &prestate, lhs: &@expr,
110129
changed =
111130
find_pre_post_state_expr(fcx, expr_poststate(fcx.ccx, lhs), rhs) ||
112131
changed;
132+
forbid_upvar(fcx, rhs.id, rhs.span, ty);
113133

114134
let post = tritv_clone(expr_poststate(fcx.ccx, rhs));
115135

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
// error-pattern:assigning to upvar
1+
// error-pattern:Tried to deinitialize a variable declared in a different
22
fn force(f: &block() -> int) -> int { ret f(); }
33
fn main() {
4-
let x = 5;
5-
let f = lambda () -> int { let y = 6; x <- y; ret 7 };
6-
assert (force(f) == 7);
7-
log x;
4+
let x = @{x:17, y:2};
5+
let y = @{x:5, y:5};
6+
7+
let f = {|&i| log_err i; x <- y; ret 7; };
8+
assert (f(5) == 7);
9+
log_err x;
10+
log_err y;
811
}

0 commit comments

Comments
 (0)