Skip to content

Commit d0b245e

Browse files
committed
---
yaml --- r: 2571 b: refs/heads/master c: 971b5d5 h: refs/heads/master i: 2569: f94f711 2567: a57a869 v: v3
1 parent d9c3720 commit d0b245e

File tree

23 files changed

+3277
-52
lines changed

23 files changed

+3277
-52
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: c75125fcce8618229ca973dc3360ffa8c6cb9648
2+
refs/heads/master: 971b5d5151f79582252fa1281edb09cf86fd63ff

trunk/src/comp/driver/rustc.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import middle::trans;
99
import middle::resolve;
1010
import middle::ty;
1111
import middle::typeck;
12-
import middle::typestate_check;
12+
import middle::tstate::ck;
1313
import back::link;
1414
import lib::llvm;
1515
import util::common;
@@ -105,7 +105,8 @@ fn compile_input(session::session sess,
105105

106106
if (sess.get_opts().run_typestate) {
107107
crate = time(time_passes, "typestate checking",
108-
bind typestate_check::check_crate(crate, def_map));
108+
bind middle::tstate::ck::check_crate(node_type_table,
109+
ty_cx, crate));
109110
}
110111

111112
auto llmod = time[llvm::ModuleRef](time_passes, "translation",

trunk/src/comp/front/ast.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import std::map::hashmap;
32
import std::option;
43
import std::_str;
@@ -7,7 +6,7 @@ import util::common::span;
76
import util::common::spanned;
87
import util::common::ty_mach;
98
import util::common::filename;
10-
import util::typestate_ann::ts_ann;
9+
import middle::tstate::ann::ts_ann;
1110

1211
type ident = str;
1312

@@ -323,6 +322,12 @@ type ty_method = rec(proto proto, ident ident,
323322
type ty = spanned[ty_];
324323
tag ty_ {
325324
ty_nil;
325+
ty_bot; /* return type of ! functions and type of
326+
ret/fail/break/cont. there is no syntax
327+
for this type. */
328+
/* bot represents the value of functions that don't return a value
329+
locally to their context. in contrast, things like log that do
330+
return, but don't return a meaningful value, have result type nil. */
326331
ty_bool;
327332
ty_int;
328333
ty_uint;
@@ -354,12 +359,19 @@ type constr = spanned[constr_];
354359
type arg = rec(mode mode, @ty ty, ident ident, def_id id);
355360
type fn_decl = rec(vec[arg] inputs,
356361
@ty output,
357-
purity purity);
362+
purity purity,
363+
controlflow cf);
358364
tag purity {
359365
pure_fn; // declared with "pred"
360366
impure_fn; // declared with "fn"
361367
}
362368

369+
tag controlflow {
370+
noreturn; // functions with return type _|_ that always
371+
// raise an error or exit (i.e. never return to the caller)
372+
return; // everything else
373+
}
374+
363375
type _fn = rec(fn_decl decl,
364376
proto proto,
365377
block body);

trunk/src/comp/front/parser.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ tag file_type {
2323
SOURCE_FILE;
2424
}
2525

26+
tag ty_or_bang {
27+
a_ty(@ast::ty);
28+
a_bang;
29+
}
30+
2631
state type parser =
2732
state obj {
2833
fn peek() -> token::token;
@@ -448,6 +453,13 @@ fn parse_ty_constrs(@ast::ty t, parser p) -> @ast::ty {
448453
ret t;
449454
}
450455

456+
fn parse_ty_or_bang(parser p) -> ty_or_bang {
457+
alt (p.peek()) {
458+
case (token::NOT) { p.bump(); ret a_bang; }
459+
case (_) { ret a_ty(parse_ty(p)); }
460+
}
461+
}
462+
451463
fn parse_ty(parser p) -> @ast::ty {
452464
auto lo = p.get_lo_pos();
453465
auto hi = lo;
@@ -1713,20 +1725,31 @@ fn parse_fn_decl(parser p, ast::purity purity) -> ast::fn_decl {
17131725
some(token::COMMA),
17141726
pf, p);
17151727

1716-
let @ast::ty output;
1728+
let ty_or_bang res;
17171729

17181730
// FIXME: dropping constrs on the floor at the moment.
17191731
// pick them up when they're used by typestate pass.
17201732
parse_constrs(p);
17211733

17221734
if (p.peek() == token::RARROW) {
17231735
p.bump();
1724-
output = parse_ty(p);
1736+
res = parse_ty_or_bang(p);
17251737
} else {
1726-
output = @spanned(inputs.span.lo, inputs.span.hi, ast::ty_nil);
1738+
res = a_ty(@spanned(inputs.span.lo, inputs.span.hi, ast::ty_nil));
1739+
}
1740+
1741+
alt (res) {
1742+
case (a_ty(?t)) {
1743+
ret rec(inputs=inputs.node, output=t,
1744+
purity=purity, cf=ast::return);
1745+
}
1746+
case (a_bang) {
1747+
ret rec(inputs=inputs.node,
1748+
output=@spanned(p.get_lo_pos(),
1749+
p.get_hi_pos(), ast::ty_bot),
1750+
purity=purity, cf=ast::noreturn);
1751+
}
17271752
}
1728-
// FIXME
1729-
ret rec(inputs=inputs.node, output=output, purity=purity);
17301753
}
17311754

17321755
fn parse_fn(parser p, ast::proto proto, ast::purity purity) -> ast::_fn {
@@ -1778,11 +1801,12 @@ fn parse_dtor(parser p) -> @ast::method {
17781801
let vec[ast::arg] inputs = vec();
17791802
let @ast::ty output = @spanned(lo, lo, ast::ty_nil);
17801803
let ast::fn_decl d = rec(inputs=inputs,
1781-
output=output,
1782-
purity=ast::impure_fn);
1804+
output=output,
1805+
purity=ast::impure_fn,
1806+
cf=ast::return);
17831807
let ast::_fn f = rec(decl = d,
1784-
proto = ast::proto_fn,
1785-
body = b);
1808+
proto = ast::proto_fn,
1809+
body = b);
17861810
let ast::method_ m = rec(ident="drop",
17871811
meth=f,
17881812
id=p.next_def_id(),

trunk/src/comp/middle/fold.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import util::common::new_str_hash;
77
import util::common::spanned;
88
import util::common::span;
99
import util::common::ty_mach;
10-
import util::typestate_ann::ts_ann;
10+
import middle::tstate::ann::ts_ann;
1111

1212
import front::ast;
1313
import front::ast::fn_decl;
1414
import front::ast::ident;
1515
import front::ast::path;
1616
import front::ast::mutability;
17+
import front::ast::controlflow;
1718
import front::ast::ty;
1819
import front::ast::expr;
1920
import front::ast::stmt;
@@ -44,6 +45,7 @@ type ast_fold[ENV] =
4445

4546
// Type folds.
4647
(fn(&ENV e, &span sp) -> @ty) fold_ty_nil,
48+
(fn(&ENV e, &span sp) -> @ty) fold_ty_bot,
4749
(fn(&ENV e, &span sp) -> @ty) fold_ty_bool,
4850
(fn(&ENV e, &span sp) -> @ty) fold_ty_int,
4951
(fn(&ENV e, &span sp) -> @ty) fold_ty_uint,
@@ -314,7 +316,7 @@ type ast_fold[ENV] =
314316
(fn(&ENV e,
315317
&vec[arg] inputs,
316318
&@ty output,
317-
&purity p) -> ast::fn_decl) fold_fn_decl,
319+
&purity p, &controlflow c) -> ast::fn_decl) fold_fn_decl,
318320

319321
(fn(&ENV e, &ast::_mod m) -> ast::_mod) fold_mod,
320322

@@ -375,6 +377,7 @@ fn fold_ty[ENV](&ENV env, &ast_fold[ENV] fld, &@ty t) -> @ty {
375377

376378
alt (t.node) {
377379
case (ast::ty_nil) { ret fld.fold_ty_nil(env_, t.span); }
380+
case (ast::ty_bot) { ret fld.fold_ty_bot(env_, t.span); }
378381
case (ast::ty_bool) { ret fld.fold_ty_bool(env_, t.span); }
379382
case (ast::ty_int) { ret fld.fold_ty_int(env_, t.span); }
380383
case (ast::ty_uint) { ret fld.fold_ty_uint(env_, t.span); }
@@ -926,7 +929,7 @@ fn fold_fn_decl[ENV](&ENV env, &ast_fold[ENV] fld,
926929
inputs += vec(fold_arg(env, fld, a));
927930
}
928931
auto output = fold_ty[ENV](env, fld, decl.output);
929-
ret fld.fold_fn_decl(env, inputs, output, decl.purity);
932+
ret fld.fold_fn_decl(env, inputs, output, decl.purity, decl.cf);
930933
}
931934

932935
fn fold_fn[ENV](&ENV env, &ast_fold[ENV] fld, &ast::_fn f) -> ast::_fn {
@@ -1202,6 +1205,10 @@ fn identity_fold_ty_nil[ENV](&ENV env, &span sp) -> @ty {
12021205
ret @respan(sp, ast::ty_nil);
12031206
}
12041207

1208+
fn identity_fold_ty_bot[ENV](&ENV env, &span sp) -> @ty {
1209+
ret @respan(sp, ast::ty_bot);
1210+
}
1211+
12051212
fn identity_fold_ty_bool[ENV](&ENV env, &span sp) -> @ty {
12061213
ret @respan(sp, ast::ty_bool);
12071214
}
@@ -1622,8 +1629,8 @@ fn identity_fold_block[ENV](&ENV e, &span sp, &ast::block_ blk) -> block {
16221629
fn identity_fold_fn_decl[ENV](&ENV e,
16231630
&vec[arg] inputs,
16241631
&@ty output,
1625-
&purity p) -> ast::fn_decl {
1626-
ret rec(inputs=inputs, output=output, purity=p);
1632+
&purity p, &controlflow c) -> ast::fn_decl {
1633+
ret rec(inputs=inputs, output=output, purity=p, cf=c);
16271634
}
16281635

16291636
fn identity_fold_fn[ENV](&ENV e,
@@ -1722,6 +1729,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
17221729
fold_path = bind identity_fold_path[ENV](_,_,_),
17231730

17241731
fold_ty_nil = bind identity_fold_ty_nil[ENV](_,_),
1732+
fold_ty_bot = bind identity_fold_ty_bot[ENV](_,_),
17251733
fold_ty_bool = bind identity_fold_ty_bool[ENV](_,_),
17261734
fold_ty_int = bind identity_fold_ty_int[ENV](_,_),
17271735
fold_ty_uint = bind identity_fold_ty_uint[ENV](_,_),
@@ -1821,7 +1829,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
18211829
fold_ann = bind identity_fold_ann[ENV](_,_),
18221830

18231831
fold_fn = bind identity_fold_fn[ENV](_,_,_,_),
1824-
fold_fn_decl = bind identity_fold_fn_decl[ENV](_,_,_,_),
1832+
fold_fn_decl = bind identity_fold_fn_decl[ENV](_,_,_,_,_),
18251833
fold_mod = bind identity_fold_mod[ENV](_,_),
18261834
fold_native_mod = bind identity_fold_native_mod[ENV](_,_),
18271835
fold_crate = bind identity_fold_crate[ENV](_,_,_,_),

trunk/src/comp/middle/resolve.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import util::common::new_int_hash;
1010
import util::common::new_uint_hash;
1111
import util::common::new_str_hash;
1212
import util::common::span;
13-
import util::typestate_ann::ts_ann;
13+
import middle::tstate::ann::ts_ann;
1414
import std::map::hashmap;
1515
import std::list::list;
1616
import std::list::nil;

trunk/src/comp/middle/trans.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,7 @@ fn type_of_inner(&@crate_ctxt cx, &ty::t t) -> TypeRef {
757757
alt (ty::struct(cx.tcx, t)) {
758758
case (ty::ty_native) { llty = T_ptr(T_i8()); }
759759
case (ty::ty_nil) { llty = T_nil(); }
760+
case (ty::ty_bot) { llty = T_nil(); } /* ...I guess? */
760761
case (ty::ty_bool) { llty = T_bool(); }
761762
case (ty::ty_int) { llty = T_int(); }
762763
case (ty::ty_float) { llty = T_float(); }
@@ -3186,8 +3187,8 @@ fn copy_ty(&@block_ctxt cx,
31863187
if (ty::type_is_scalar(cx.fcx.lcx.ccx.tcx, t) ||
31873188
ty::type_is_native(cx.fcx.lcx.ccx.tcx, t)) {
31883189
ret res(cx, cx.build.Store(src, dst));
3189-
3190-
} else if (ty::type_is_nil(cx.fcx.lcx.ccx.tcx, t)) {
3190+
} else if (ty::type_is_nil(cx.fcx.lcx.ccx.tcx, t) ||
3191+
ty::type_is_bot(cx.fcx.lcx.ccx.tcx, t)) {
31913192
ret res(cx, C_nil());
31923193

31933194
} else if (ty::type_is_boxed(cx.fcx.lcx.ccx.tcx, t)) {
@@ -3552,6 +3553,8 @@ fn autoderef(&@block_ctxt cx, ValueRef v, &ty::t t) -> result {
35523553
}
35533554
}
35543555
}
3556+
3557+
fail; // fools the return-checker
35553558
}
35563559

35573560
fn autoderefed_ty(&@crate_ctxt ccx, &ty::t t) -> ty::t {
@@ -3567,6 +3570,8 @@ fn autoderefed_ty(&@crate_ctxt ccx, &ty::t t) -> ty::t {
35673570
}
35683571
}
35693572
}
3573+
3574+
fail; // fools the return-checker
35703575
}
35713576

35723577
fn trans_binary(&@block_ctxt cx, ast::binop op,
@@ -3591,12 +3596,17 @@ fn trans_binary(&@block_ctxt cx, ast::binop op,
35913596
auto lhs_false_cx = new_scope_block_ctxt(cx, "lhs false");
35923597
auto lhs_false_res = res(lhs_false_cx, C_bool(false));
35933598

3599+
// The following line ensures that any cleanups for rhs
3600+
// are done within the block for rhs. This is necessary
3601+
// because and/or are lazy. So the rhs may never execute,
3602+
// and the cleanups can't be pushed into later code.
3603+
auto rhs_bcx = trans_block_cleanups(rhs_res.bcx, rhs_cx);
3604+
35943605
lhs_res.bcx.build.CondBr(lhs_res.val,
35953606
rhs_cx.llbb,
35963607
lhs_false_cx.llbb);
3597-
35983608
ret join_results(cx, T_bool(),
3599-
vec(lhs_false_res, rhs_res));
3609+
vec(lhs_false_res, rec(bcx=rhs_bcx with rhs_res)));
36003610
}
36013611

36023612
case (ast::or) {
@@ -3615,12 +3625,15 @@ fn trans_binary(&@block_ctxt cx, ast::binop op,
36153625
auto lhs_true_cx = new_scope_block_ctxt(cx, "lhs true");
36163626
auto lhs_true_res = res(lhs_true_cx, C_bool(true));
36173627

3628+
// see the and case for an explanation
3629+
auto rhs_bcx = trans_block_cleanups(rhs_res.bcx, rhs_cx);
3630+
36183631
lhs_res.bcx.build.CondBr(lhs_res.val,
36193632
lhs_true_cx.llbb,
36203633
rhs_cx.llbb);
36213634

36223635
ret join_results(cx, T_bool(),
3623-
vec(lhs_true_res, rhs_res));
3636+
vec(lhs_true_res, rec(bcx=rhs_bcx with rhs_res)));
36243637
}
36253638

36263639
case (_) {
@@ -4984,6 +4997,8 @@ fn trans_bind(&@block_ctxt cx, &@ast::expr f,
49844997
ret res(bcx, pair_v);
49854998
}
49864999
}
5000+
5001+
fail; // sadly needed b/c the compiler doesn't know yet that unimpl fails
49875002
}
49885003

49895004
fn trans_arg_expr(&@block_ctxt cx,

trunk/src/comp/util/typestate_ann.rs renamed to trunk/src/comp/middle/tstate/ann.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,13 @@ fn set_in_poststate(uint i, &pre_and_post_state s) -> bool {
111111

112112
// Sets all the bits in a's precondition to equal the
113113
// corresponding bit in p's precondition.
114-
fn set_precondition(&ts_ann a, &precond p) -> () {
114+
fn set_precondition(@ts_ann a, &precond p) -> () {
115115
bitv::copy(a.conditions.precondition, p);
116116
}
117117

118118
// Sets all the bits in a's postcondition to equal the
119119
// corresponding bit in p's postcondition.
120-
fn set_postcondition(&ts_ann a, &postcond p) -> () {
120+
fn set_postcondition(@ts_ann a, &postcond p) -> () {
121121
bitv::copy(a.conditions.postcondition, p);
122122
}
123123

@@ -158,6 +158,10 @@ fn ann_prestate(&ts_ann a) -> prestate {
158158
ret a.states.prestate;
159159
}
160160

161+
fn ann_poststate(&ts_ann a) -> poststate {
162+
ret a.states.poststate;
163+
}
164+
161165
fn pp_clone(&pre_and_post p) -> pre_and_post {
162166
ret rec(precondition=clone(p.precondition),
163167
postcondition=clone(p.postcondition));

0 commit comments

Comments
 (0)