Skip to content

Commit

Permalink
Handle sequential let semantics properly in typestate
Browse files Browse the repository at this point in the history
Closes #824
  • Loading branch information
catamorphism committed Aug 19, 2011
1 parent 3ddb26e commit d81d864
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 16 deletions.
53 changes: 37 additions & 16 deletions src/comp/middle/tstate/pre_post_conditions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,7 @@ import std::option;
import std::option::none;
import std::option::some;

import tstate::ann::pre_and_post;
import tstate::ann::get_post;
import tstate::ann::postcond;
import tstate::ann::true_precond;
import tstate::ann::false_postcond;
import tstate::ann::empty_poststate;
import tstate::ann::require;
import tstate::ann::require_and_preserve;
import tstate::ann::union;
import tstate::ann::intersect;
import tstate::ann::pp_clone;
import tstate::ann::empty_prestate;
import tstate::ann::set_precondition;
import tstate::ann::set_postcondition;
import tstate::ann::*;
import aux::*;
import bitvectors::bit_num;
import bitvectors::promises;
Expand All @@ -28,7 +15,7 @@ import bitvectors::declare_var;
import bitvectors::gen_poststate;
import bitvectors::relax_precond_block;
import bitvectors::gen;
import tritv::tritv_clone;
import tritv::*;
import syntax::ast::*;
import syntax::visit;
import std::map::new_int_hash;
Expand Down Expand Up @@ -591,6 +578,8 @@ fn find_pre_post_stmt(fcx: &fn_ctxt, s: &stmt) {
stmt_decl(adecl, id) {
alt adecl.node {
decl_local(alocals) {
let e_pp;
let prev_pp = empty_pre_post(num_constraints(fcx.enclosing));
for alocal: @local in alocals {
alt alocal.node.init {
some(an_init) {
Expand All @@ -611,7 +600,16 @@ fn find_pre_post_stmt(fcx: &fn_ctxt, s: &stmt) {
}

for each pat: @pat in pat_bindings(alocal.node.pat) {
let ident = alt pat.node { pat_bind(n) { n } };
/* FIXME: This won't be necessary when typestate
works well enough for pat_bindings to return a
refinement-typed thing. */
let ident = alt pat.node {
pat_bind(n) { n }
_ {
fcx.ccx.tcx.sess.span_bug(pat.span,
"Impossible LHS");
}
};
alt p {
some(p) {
copy_in_postcond(fcx, id,
Expand All @@ -629,6 +627,29 @@ fn find_pre_post_stmt(fcx: &fn_ctxt, s: &stmt) {
if an_init.op == init_move && is_path(an_init.expr) {
forget_in_postcond(fcx, id, an_init.expr.id);
}

/* Clear out anything that the previous initializer
guaranteed */
e_pp = expr_pp(fcx.ccx, an_init.expr);
tritv_copy(prev_pp.precondition,
seq_preconds(fcx, [prev_pp, e_pp]));
/* Include the LHSs too, since those aren't in the
postconds of the RHSs themselves */
for each pat: @pat in pat_bindings(alocal.node.pat) {
alt pat.node {
pat_bind(n) {
set_in_postcond(bit_num(fcx, ninit(pat.id, n)),
prev_pp);
}
_ {
fcx.ccx.tcx.sess.span_bug(pat.span,
"Impossible LHS");
}
};
}
copy_pre_post_(fcx.ccx, id,
prev_pp.precondition,
prev_pp.postcondition);
}
none. {
for each p: @pat in pat_bindings(alocal.node.pat) {
Expand Down
4 changes: 4 additions & 0 deletions src/test/run-pass/multi-let.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
let x = 10, y = x;
assert (y == 10);
}

0 comments on commit d81d864

Please sign in to comment.