mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Handle nested items correctly in typestate_check
Summary says it all. Actually, only nested objects and functions are handled, but that's better than before. The fold that I was using before to traverse a crate wasn't working correctly, because annotations have to reflect the number of local variables of the nearest enclosing function (in turn, because annotations are represented as bit vectors). The fold was traversing the AST in the wrong order, first filling in the annotations correctly, but then re-traversing them with the bit vector length for any outer nested functions, and so on. Remedying this required writing a lot of tedious boilerplate code because I scrapped the idea of using a fold altogether. I also made typestate_check handle unary, field, alt, and fail. Also, some miscellaneous changes: * added annotations to blocks in typeck * fix pprust so it can handle spawn * added more logging functions in util.common * fixed _vec.or * added maybe and from_maybe in option * removed fold_block field from ast_fold, since it was never used
This commit is contained in:
parent
3d9cf15d0b
commit
b7dd75c904
@ -291,8 +291,6 @@ type ast_fold[ENV] =
|
||||
(fn(&ENV e, ann a) -> ann) fold_ann,
|
||||
|
||||
// Additional nodes.
|
||||
(fn(&ENV e, &span sp,
|
||||
&ast.block_) -> block) fold_block,
|
||||
|
||||
(fn(&ENV e, &fn_decl decl,
|
||||
ast.proto proto,
|
||||
@ -1716,7 +1714,6 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
|
||||
|
||||
fold_ann = bind identity_fold_ann[ENV](_,_),
|
||||
|
||||
fold_block = bind identity_fold_block[ENV](_,_,_),
|
||||
fold_fn = bind identity_fold_fn[ENV](_,_,_,_),
|
||||
fold_fn_decl = bind identity_fold_fn_decl[ENV](_,_,_),
|
||||
fold_mod = bind identity_fold_mod[ENV](_,_),
|
||||
|
@ -1469,7 +1469,8 @@ mod Pushdown {
|
||||
}
|
||||
case (none[@ast.expr]) {
|
||||
Demand.simple(fcx, bloc.span, expected, plain_ty(ty.ty_nil));
|
||||
ret bloc;
|
||||
ret fold.respan[ast.block_](bloc.span,
|
||||
rec(a = boring_ann() with bloc.node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -475,6 +475,13 @@ fn print_expr(ps s, &@ast.expr expr) {
|
||||
commasep[option.t[@ast.expr]](s, args, f);
|
||||
pclose(s);
|
||||
}
|
||||
case (ast.expr_spawn(_,_,?e,?es,_)) {
|
||||
wrd1(s, "spawn");
|
||||
print_expr(s, e);
|
||||
popen(s);
|
||||
commasep_exprs(s, es);
|
||||
pclose(s);
|
||||
}
|
||||
case (ast.expr_binary(?op,?lhs,?rhs,_)) {
|
||||
auto prec = operator_prec(op);
|
||||
print_maybe_parens(s, lhs, prec);
|
||||
@ -1018,3 +1025,13 @@ fn print_comment(ps s, lexer.cmnt_ cmnt) {
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
// c-basic-offset: 4
|
||||
// buffer-file-coding-system: utf-8-unix
|
||||
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
||||
// End:
|
||||
//
|
||||
|
@ -137,6 +137,35 @@ fn log_block(&ast.block b) -> () {
|
||||
log(s.get_str());
|
||||
}
|
||||
|
||||
fn log_ann(&ast.ann a) -> () {
|
||||
alt (a) {
|
||||
case (ast.ann_none) {
|
||||
log("ann_none");
|
||||
}
|
||||
case (ast.ann_type(_,_,_)) {
|
||||
log("ann_type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn log_stmt(ast.stmt st) -> () {
|
||||
let str_writer s = string_writer();
|
||||
auto out_ = mkstate(s.get_writer(), 80u);
|
||||
auto out = @rec(s=out_,
|
||||
comments=none[vec[front.lexer.cmnt]],
|
||||
mutable cur_cmnt=0u);
|
||||
alt (st.node) {
|
||||
case (ast.stmt_decl(?decl,_)) {
|
||||
print_decl(out, decl);
|
||||
}
|
||||
case (ast.stmt_expr(?ex,_)) {
|
||||
print_expr(out, ex);
|
||||
}
|
||||
case (_) { /* do nothing */ }
|
||||
}
|
||||
log(s.get_str());
|
||||
}
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
|
@ -147,6 +147,11 @@ fn ann_prestate(&ts_ann a) -> prestate {
|
||||
ret a.states.prestate;
|
||||
}
|
||||
|
||||
fn pp_clone(&pre_and_post p) -> pre_and_post {
|
||||
ret rec(precondition=bitv.clone(p.precondition),
|
||||
postcondition=bitv.clone(p.postcondition));
|
||||
}
|
||||
|
||||
// returns true if a implies b
|
||||
// that is, returns true except if for some bits c and d,
|
||||
// c = 1 and d = 0
|
||||
@ -155,3 +160,14 @@ fn implies(bitv.t a, bitv.t b) -> bool {
|
||||
bitv.difference(tmp, a);
|
||||
ret bitv.is_false(tmp);
|
||||
}
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
// c-basic-offset: 4
|
||||
// buffer-file-coding-system: utf-8-unix
|
||||
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
||||
// End:
|
||||
//
|
||||
|
@ -266,7 +266,7 @@ fn unzip[T, U](&vec[tup(T, U)] v) -> tup(vec[T], vec[U]) {
|
||||
|
||||
fn or(&vec[bool] v) -> bool {
|
||||
auto f = orb;
|
||||
be _vec.foldl[bool, bool](f, false, v);
|
||||
ret _vec.foldl[bool, bool](f, false, v);
|
||||
}
|
||||
|
||||
fn clone[T](&vec[T] v) -> vec[T] {
|
||||
|
@ -39,12 +39,16 @@ fn is_none[T](&t[T] opt) -> bool {
|
||||
}
|
||||
|
||||
fn from_maybe[T](&T def, &t[T] opt) -> T {
|
||||
alt(opt) {
|
||||
case (none[T]) { ret def; }
|
||||
case (some[T](?t)) { ret t; }
|
||||
}
|
||||
auto f = bind util.id[T](_);
|
||||
ret maybe[T, T](def, f, opt);
|
||||
}
|
||||
|
||||
fn maybe[T, U](&U def, fn(&T) -> U f, &t[T] opt) -> U {
|
||||
alt (opt) {
|
||||
case (none[T]) { ret def; }
|
||||
case (some[T](?t)) { ret f(t); }
|
||||
}
|
||||
}
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
// fill-column: 78;
|
||||
|
12
src/test/compile-fail/use-uninit-dtor.rs
Normal file
12
src/test/compile-fail/use-uninit-dtor.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// xfail-stage0
|
||||
// error-pattern:Unsatisfied precondition
|
||||
|
||||
fn main() {
|
||||
state obj foo(int x) {
|
||||
drop {
|
||||
let int baz;
|
||||
log(baz);
|
||||
}
|
||||
}
|
||||
fail;
|
||||
}
|
Loading…
Reference in New Issue
Block a user