diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index f670c2760a7..4f83ee7fa8d 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -272,7 +272,7 @@ tag expr_ { expr_index(@expr, @expr, ann); expr_path(path, ann); expr_ext(path, vec[@expr], option::t[str], @expr, ann); - expr_fail(ann); + expr_fail(ann, option::t[str]); expr_break(ann); expr_cont(ann); expr_ret(option::t[@expr], ann); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index b84a740a917..562bc0cc32e 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -256,7 +256,6 @@ fn parse_value_ident(&parser p) -> ast::ident { ret parse_ident(p); } - /* FIXME: gross hack copied from rustboot to make certain configuration-based * decisions work at build-time. We should probably change it to use a * lexical sytnax-extension or something similar. For now we just imitate @@ -934,7 +933,17 @@ fn parse_bottom_expr(&parser p) -> @ast::expr { ex = expand_syntax_ext(p, ext_span, pth, es.node, none[str]); } else if (eat_word(p, "fail")) { - ex = ast::expr_fail(p.get_ann()); + auto msg; + alt (p.peek()) { + case (token::LIT_STR(?s)) { + msg = some[str](p.get_str(s)); + p.bump(); + } + case (_) { + msg = none[str]; + } + } + ex = ast::expr_fail(p.get_ann(), msg); } else if (eat_word(p, "log")) { auto e = parse_expr(p); auto hi = e.span.hi; @@ -1643,7 +1652,7 @@ fn stmt_ends_with_semi(&ast::stmt stmt) -> bool { case (ast::expr_field(_,_,_)) { ret true; } case (ast::expr_index(_,_,_)) { ret true; } case (ast::expr_path(_,_)) { ret true; } - case (ast::expr_fail(_)) { ret true; } + case (ast::expr_fail(_,_)) { ret true; } case (ast::expr_break(_)) { ret true; } case (ast::expr_cont(_)) { ret true; } case (ast::expr_ret(_,_)) { ret true; } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 01192deb8da..0fac5651f14 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5628,8 +5628,17 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output) ret trans_expr(cx, expanded); } - case (ast::expr_fail(_)) { - ret trans_fail(cx, some(e.span), "explicit failure"); + case (ast::expr_fail(_, ?str)) { + auto failmsg; + alt (str) { + case (some(?msg)) { + failmsg = msg; + } + case (_) { + failmsg = "explicit failure"; + } + } + ret trans_fail(cx, some(e.span), failmsg); } case (ast::expr_log(?lvl, ?a, _)) { diff --git a/src/comp/middle/tstate/pre_post_conditions.rs b/src/comp/middle/tstate/pre_post_conditions.rs index d1df649f7a6..da4e333f0a6 100644 --- a/src/comp/middle/tstate/pre_post_conditions.rs +++ b/src/comp/middle/tstate/pre_post_conditions.rs @@ -459,7 +459,7 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) -> () { find_pre_post_expr(fcx, operator); copy_pre_post(fcx.ccx, a, operator); } - case (expr_fail(?a)) { + case (expr_fail(?a, _)) { set_pre_and_post(fcx.ccx, a, /* if execution continues after fail, then everything is true! */ diff --git a/src/comp/middle/tstate/states.rs b/src/comp/middle/tstate/states.rs index 37cc40b5c9e..369f307aa81 100644 --- a/src/comp/middle/tstate/states.rs +++ b/src/comp/middle/tstate/states.rs @@ -508,7 +508,7 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool { expr_poststate(fcx.ccx, operand)) || changed; ret changed; } - case (expr_fail(?a)) { + case (expr_fail(?a, _)) { changed = extend_prestate_ann(fcx.ccx, a, pres) || changed; /* if execution continues after fail, then everything is true! woo! */ changed = set_poststate_ann(fcx.ccx, a, diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 3d0c612a085..3487af78561 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1657,7 +1657,7 @@ fn expr_ann(&@ast::expr e) -> ast::ann { case (ast::expr_index(_,_,?a)) { ret a; } case (ast::expr_path(_,?a)) { ret a; } case (ast::expr_ext(_,_,_,_,?a)) { ret a; } - case (ast::expr_fail(?a)) { ret a; } + case (ast::expr_fail(?a,_)) { ret a; } case (ast::expr_ret(_,?a)) { ret a; } case (ast::expr_put(_,?a)) { ret a; } case (ast::expr_be(_,?a)) { ret a; } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index db3f3ede0c7..afafde4e916 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1276,7 +1276,7 @@ mod pushdown { write::ty_only_fixup(fcx, ann.id, t); } /* FIXME: should this check the type annotations? */ - case (ast::expr_fail(_)) { /* no-op */ } + case (ast::expr_fail(_,_)) { /* no-op */ } case (ast::expr_log(_,_,_)) { /* no-op */ } case (ast::expr_break(_)) { /* no-op */ } case (ast::expr_cont(_)) { /* no-op */ } @@ -1972,7 +1972,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) { write::ty_only_fixup(fcx, a.id, t); } - case (ast::expr_fail(?a)) { + case (ast::expr_fail(?a, _)) { write::bot_ty(fcx.ccx.tcx, a.id); } diff --git a/src/comp/middle/walk.rs b/src/comp/middle/walk.rs index 1ecafe1f02f..214846a5ecf 100644 --- a/src/comp/middle/walk.rs +++ b/src/comp/middle/walk.rs @@ -431,7 +431,7 @@ fn walk_expr(&ast_visitor v, @ast::expr e) { // Only walk expansion, not args/body. walk_expr(v, expansion); } - case (ast::expr_fail(_)) { } + case (ast::expr_fail(_, _)) { } case (ast::expr_break(_)) { } case (ast::expr_cont(_)) { } case (ast::expr_ret(?eo, _)) { diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs index 2c7e65dcb22..db6d62bdbc8 100644 --- a/src/comp/pretty/pprust.rs +++ b/src/comp/pretty/pprust.rs @@ -825,8 +825,13 @@ fn print_expr(&ps s, &@ast::expr expr) { case (ast::expr_path(?path,_)) { print_path(s, path); } - case (ast::expr_fail(_)) { + case (ast::expr_fail(_, ?str)) { word(s.s, "fail"); + alt (str) { + case (some(?msg)) { + word(s.s, #fmt("\"%s\"", msg)); + } + } } case (ast::expr_break(_)) { word(s.s, "break"); diff --git a/src/test/run-fail/explicit-fail-msg.rs b/src/test/run-fail/explicit-fail-msg.rs new file mode 100644 index 00000000000..e37cf5d58f5 --- /dev/null +++ b/src/test/run-fail/explicit-fail-msg.rs @@ -0,0 +1,5 @@ +// error-pattern:woooo + +fn main() { + fail "woooo"; +}