Support all expression forms in typestate

Added support for self_method, cont, chan, port, recv, send, be,
do_while, spawn, and ext; handled break and cont correctly.
(However, there are no non-xfailed test cases for ext or spawn in
stage0 currently.)

Although the standard library compiles and all test cases pass with
typestate enabled, I left typestate checking disabled as rustc
terminates abnormally when building the standard library if so,
even though it does generate code correctly.
This commit is contained in:
Tim Chevalier 2011-04-21 17:39:04 -07:00 committed by Graydon Hoare
parent 7c4f8cb459
commit 0190ebfe07
4 changed files with 274 additions and 12 deletions

View file

@ -1,3 +1,5 @@
import std.map;
import std.map.hashmap;
import std._uint;
import std._int;
import std._vec;
@ -5,6 +7,9 @@ import std.option.none;
import front.ast;
import util.typestate_ann.ts_ann;
import middle.fold;
import middle.fold.respan;
import std.io.stdout;
import std.io.str_writer;
import std.io.string_writer;
@ -16,6 +21,7 @@ import pretty.pp.mkstate;
type filename = str;
type span = rec(uint lo, uint hi);
type spanned[T] = rec(T node, span span);
type flag = hashmap[str, ()];
tag ty_mach {
ty_i8;
@ -222,6 +228,32 @@ fn decl_lhs(@ast.decl d) -> ast.def_id {
}
}
fn has_nonlocal_exits(&ast.block b) -> bool {
/* overkill, but just passing around a mutable bool doesn't seem
to work in rustboot */
auto has_exits = new_str_hash[()]();
fn set_break(&flag f, &span sp, ast.ann a) -> @ast.expr {
f.insert("foo", ());
ret @respan(sp, ast.expr_break(a));
}
fn set_cont(&flag f, &span sp, ast.ann a) -> @ast.expr {
f.insert("foo", ());
ret @respan(sp, ast.expr_cont(a));
}
fn check_b(&flag f) -> bool {
ret (f.size() == 0u);
}
auto fld0 = fold.new_identity_fold[flag]();
fld0 = @rec(fold_expr_break = bind set_break(_,_,_),
fold_expr_cont = bind set_cont(_,_,_),
keep_going = bind check_b(_) with *fld0);
fold.fold_block[flag](has_exits, fld0, b);
ret (has_exits.size() > 0u);
}
//
// Local Variables:
// mode: rust