Forbid blocks from deinitializing upvars
Move expressions where the RHS is an upvar are now forbidden within block expressions.
This commit is contained in:
parent
efed843b1a
commit
8ab02f7b21
2 changed files with 30 additions and 7 deletions
|
@ -17,6 +17,7 @@ import tritv::ttrue;
|
|||
import bitvectors::*;
|
||||
import syntax::ast::*;
|
||||
import syntax::ast_util::*;
|
||||
import syntax::codemap::span;
|
||||
import middle::ty::expr_ty;
|
||||
import middle::ty::type_is_nil;
|
||||
import middle::ty::type_is_bot;
|
||||
|
@ -31,10 +32,28 @@ import util::common::log_stmt;
|
|||
import util::common::log_stmt_err;
|
||||
import util::common::log_expr_err;
|
||||
|
||||
fn forbid_upvar(fcx: &fn_ctxt, rhs_id: &node_id, sp: &span,
|
||||
t: oper_type) {
|
||||
alt t {
|
||||
oper_move. {
|
||||
alt local_node_id_to_def(fcx, rhs_id) {
|
||||
some(def_upvar(_,_,_)) {
|
||||
fcx.ccx.tcx.sess.span_err(sp, "Tried to deinitialize a variable \
|
||||
declared in a different scope");
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
_ { /* do nothing */ }
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_move_or_copy(fcx: &fn_ctxt, post: &poststate, rhs_path: &path,
|
||||
rhs_id: &node_id, instlhs: &inst, init_op: &init_op) {
|
||||
let rhs_d = local_node_id_to_def_id(fcx, rhs_id);
|
||||
alt rhs_d {
|
||||
forbid_upvar(fcx, rhs_id, rhs_path.span, op_to_oper_ty(init_op));
|
||||
|
||||
let rhs_d_id = local_node_id_to_def_id(fcx, rhs_id);
|
||||
alt rhs_d_id {
|
||||
some(rhsid) {
|
||||
// RHS is a local var
|
||||
let instrhs =
|
||||
|
@ -110,6 +129,7 @@ fn find_pre_post_state_two(fcx: &fn_ctxt, pres: &prestate, lhs: &@expr,
|
|||
changed =
|
||||
find_pre_post_state_expr(fcx, expr_poststate(fcx.ccx, lhs), rhs) ||
|
||||
changed;
|
||||
forbid_upvar(fcx, rhs.id, rhs.span, ty);
|
||||
|
||||
let post = tritv_clone(expr_poststate(fcx.ccx, rhs));
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
// error-pattern:assigning to upvar
|
||||
// error-pattern:Tried to deinitialize a variable declared in a different
|
||||
fn force(f: &block() -> int) -> int { ret f(); }
|
||||
fn main() {
|
||||
let x = 5;
|
||||
let f = lambda () -> int { let y = 6; x <- y; ret 7 };
|
||||
assert (force(f) == 7);
|
||||
log x;
|
||||
let x = @{x:17, y:2};
|
||||
let y = @{x:5, y:5};
|
||||
|
||||
let f = {|&i| log_err i; x <- y; ret 7; };
|
||||
assert (f(5) == 7);
|
||||
log_err x;
|
||||
log_err y;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue