diff options
| author | Graydon Hoare <graydon@mozilla.com> | 2011-05-16 19:04:45 -0700 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2011-05-16 19:04:45 -0700 |
| commit | a2e2e781035a7e99cd4b8320caeeb8566590d21e (patch) | |
| tree | 0987ea09d9297789023c0b982a569f5107ba92ee /src/comp/front | |
| parent | fbbc1a77d242fafa1393127defa7ffec0bcb9e54 (diff) | |
| parent | 41b7af9652038712acf223bf9a309a3cc9be6281 (diff) | |
| download | rust-a2e2e781035a7e99cd4b8320caeeb8566590d21e.tar.gz rust-a2e2e781035a7e99cd4b8320caeeb8566590d21e.zip | |
Merge remote branch 'origin/master' into HEAD
Conflicts: src/comp/middle/trans.rs
Diffstat (limited to 'src/comp/front')
| -rw-r--r-- | src/comp/front/ast.rs | 18 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 42 |
2 files changed, 48 insertions, 12 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index d795d6c2363..5dfc2d8ddfa 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -1,4 +1,3 @@ - import std::map::hashmap; import std::option; import std::_str; @@ -7,7 +6,7 @@ import util::common::span; import util::common::spanned; import util::common::ty_mach; import util::common::filename; -import util::typestate_ann::ts_ann; +import middle::tstate::ann::ts_ann; type ident = str; @@ -323,6 +322,12 @@ type ty_method = rec(proto proto, ident ident, type ty = spanned[ty_]; tag ty_ { ty_nil; + ty_bot; /* return type of ! functions and type of + ret/fail/break/cont. there is no syntax + for this type. */ + /* bot represents the value of functions that don't return a value + locally to their context. in contrast, things like log that do + return, but don't return a meaningful value, have result type nil. */ ty_bool; ty_int; ty_uint; @@ -354,12 +359,19 @@ type constr = spanned[constr_]; type arg = rec(mode mode, @ty ty, ident ident, def_id id); type fn_decl = rec(vec[arg] inputs, @ty output, - purity purity); + purity purity, + controlflow cf); tag purity { pure_fn; // declared with "pred" impure_fn; // declared with "fn" } +tag controlflow { + noreturn; // functions with return type _|_ that always + // raise an error or exit (i.e. never return to the caller) + return; // everything else +} + type _fn = rec(fn_decl decl, proto proto, block body); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 3fa25857d3f..104c2c6f71a 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -23,6 +23,11 @@ tag file_type { SOURCE_FILE; } +tag ty_or_bang { + a_ty(@ast::ty); + a_bang; +} + state type parser = state obj { fn peek() -> token::token; @@ -448,6 +453,13 @@ fn parse_ty_constrs(@ast::ty t, parser p) -> @ast::ty { ret t; } +fn parse_ty_or_bang(parser p) -> ty_or_bang { + alt (p.peek()) { + case (token::NOT) { p.bump(); ret a_bang; } + case (_) { ret a_ty(parse_ty(p)); } + } +} + fn parse_ty(parser p) -> @ast::ty { auto lo = p.get_lo_pos(); auto hi = lo; @@ -1713,7 +1725,7 @@ fn parse_fn_decl(parser p, ast::purity purity) -> ast::fn_decl { some(token::COMMA), pf, p); - let @ast::ty output; + let ty_or_bang res; // FIXME: dropping constrs on the floor at the moment. // pick them up when they're used by typestate pass. @@ -1721,12 +1733,23 @@ fn parse_fn_decl(parser p, ast::purity purity) -> ast::fn_decl { if (p.peek() == token::RARROW) { p.bump(); - output = parse_ty(p); + res = parse_ty_or_bang(p); } else { - output = @spanned(inputs.span.lo, inputs.span.hi, ast::ty_nil); + res = a_ty(@spanned(inputs.span.lo, inputs.span.hi, ast::ty_nil)); + } + + alt (res) { + case (a_ty(?t)) { + ret rec(inputs=inputs.node, output=t, + purity=purity, cf=ast::return); + } + case (a_bang) { + ret rec(inputs=inputs.node, + output=@spanned(p.get_lo_pos(), + p.get_hi_pos(), ast::ty_bot), + purity=purity, cf=ast::noreturn); + } } - // FIXME - ret rec(inputs=inputs.node, output=output, purity=purity); } fn parse_fn(parser p, ast::proto proto, ast::purity purity) -> ast::_fn { @@ -1778,11 +1801,12 @@ fn parse_dtor(parser p) -> @ast::method { let vec[ast::arg] inputs = []; let @ast::ty output = @spanned(lo, lo, ast::ty_nil); let ast::fn_decl d = rec(inputs=inputs, - output=output, - purity=ast::impure_fn); + output=output, + purity=ast::impure_fn, + cf=ast::return); let ast::_fn f = rec(decl = d, - proto = ast::proto_fn, - body = b); + proto = ast::proto_fn, + body = b); let ast::method_ m = rec(ident="drop", meth=f, id=p.next_def_id(), |
