Allow any string expression to be used with fail.
This commit is contained in:
parent
67c9ef9b30
commit
d485e0d15a
9 changed files with 80 additions and 26 deletions
|
@ -275,7 +275,7 @@ tag expr_ {
|
|||
expr_index(@expr, @expr);
|
||||
expr_path(path);
|
||||
expr_ext(path, vec[@expr], option::t[str], @expr);
|
||||
expr_fail(option::t[str]);
|
||||
expr_fail(option::t[@expr]);
|
||||
expr_break;
|
||||
expr_cont;
|
||||
expr_ret(option::t[@expr]);
|
||||
|
|
|
@ -841,12 +841,15 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
|||
lo = ex_ext.span.lo;
|
||||
ex = ex_ext.node;
|
||||
} else if (eat_word(p, "fail")) {
|
||||
auto msg;
|
||||
alt (p.peek()) {
|
||||
case (token::LIT_STR(?s)) { msg = some(p.get_str(s)); p.bump(); }
|
||||
case (_) { msg = none; }
|
||||
case (token::SEMI) { ex = ast::expr_fail(none) }
|
||||
case (token::RBRACE) { ex = ast::expr_fail(none) }
|
||||
case (_) {
|
||||
auto e = parse_expr(p);
|
||||
hi = e.span.hi;
|
||||
ex = ast::expr_fail(some(e));
|
||||
}
|
||||
}
|
||||
ex = ast::expr_fail(msg);
|
||||
} else if (eat_word(p, "log")) {
|
||||
auto e = parse_expr(p);
|
||||
ex = ast::expr_log(1, e);
|
||||
|
|
|
@ -6157,13 +6157,8 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output) ->
|
|||
case (ast::expr_ext(_, _, _, ?expanded)) {
|
||||
ret trans_expr(cx, expanded);
|
||||
}
|
||||
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_fail(?expr)) {
|
||||
ret trans_fail_expr(cx, some(e.span), expr);
|
||||
}
|
||||
case (ast::expr_log(?lvl, ?a)) { ret trans_log(lvl, cx, a); }
|
||||
case (ast::expr_assert(?a)) {
|
||||
|
@ -6366,9 +6361,40 @@ fn trans_check_expr(&@block_ctxt cx, &@ast::expr e, &str s) -> result {
|
|||
ret rslt(next_cx, C_nil());
|
||||
}
|
||||
|
||||
fn trans_fail_expr(&@block_ctxt cx, &option::t[common::span] sp_opt,
|
||||
&option::t[@ast::expr] fail_expr)
|
||||
-> result {
|
||||
alt (fail_expr) {
|
||||
case (some(?expr)) {
|
||||
auto tcx = cx.fcx.lcx.ccx.tcx;
|
||||
auto expr_res = trans_expr(cx, expr);
|
||||
auto e_ty = ty::expr_ty(tcx, expr);
|
||||
|
||||
if (ty::type_is_str(tcx, e_ty)) {
|
||||
auto elt = cx.build.GEP(expr_res.val,
|
||||
[C_int(0), C_int(abi::vec_elt_data)]);
|
||||
ret trans_fail_value(cx, sp_opt, elt);
|
||||
} else {
|
||||
cx.fcx.lcx.ccx.sess.span_fatal(expr.span,
|
||||
"fail called with unsupported \
|
||||
type " + ty_to_str(tcx, e_ty));
|
||||
}
|
||||
}
|
||||
case (_) {
|
||||
ret trans_fail(cx, sp_opt, "explicit failure");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn trans_fail(&@block_ctxt cx, &option::t[common::span] sp_opt, &str fail_str)
|
||||
-> result {
|
||||
auto V_fail_str = C_cstr(cx.fcx.lcx.ccx, fail_str);
|
||||
ret trans_fail_value(cx, sp_opt, V_fail_str);
|
||||
}
|
||||
|
||||
fn trans_fail_value(&@block_ctxt cx, &option::t[common::span] sp_opt,
|
||||
&ValueRef V_fail_str)
|
||||
-> result {
|
||||
auto V_filename;
|
||||
auto V_line;
|
||||
alt (sp_opt) {
|
||||
|
@ -6382,9 +6408,9 @@ fn trans_fail(&@block_ctxt cx, &option::t[common::span] sp_opt, &str fail_str)
|
|||
V_line = 0;
|
||||
}
|
||||
}
|
||||
V_fail_str = cx.build.PointerCast(V_fail_str, T_ptr(T_i8()));
|
||||
auto V_str = cx.build.PointerCast(V_fail_str, T_ptr(T_i8()));
|
||||
V_filename = cx.build.PointerCast(V_filename, T_ptr(T_i8()));
|
||||
auto args = [cx.fcx.lltaskptr, V_fail_str, V_filename, C_int(V_line)];
|
||||
auto args = [cx.fcx.lltaskptr, V_str, V_filename, C_int(V_line)];
|
||||
cx.build.Call(cx.fcx.lcx.ccx.upcalls._fail, args);
|
||||
cx.build.Unreachable();
|
||||
ret rslt(cx, C_nil());
|
||||
|
|
|
@ -529,11 +529,19 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
|
|||
find_pre_post_expr(fcx, operator);
|
||||
copy_pre_post(fcx.ccx, e.id, operator);
|
||||
}
|
||||
case (expr_fail(_)) {
|
||||
case (expr_fail(?maybe_val)) {
|
||||
auto prestate;
|
||||
alt (maybe_val) {
|
||||
case (none) { prestate = empty_prestate(num_local_vars); }
|
||||
case (some(?fail_val)) {
|
||||
find_pre_post_expr(fcx, fail_val);
|
||||
prestate = expr_precond(fcx.ccx, fail_val);
|
||||
}
|
||||
}
|
||||
set_pre_and_post(fcx.ccx, e.id,
|
||||
/* if execution continues after fail,
|
||||
then everything is true! */
|
||||
empty_prestate(num_local_vars),
|
||||
prestate,
|
||||
false_postcond(num_local_vars));
|
||||
}
|
||||
case (expr_assert(?p)) {
|
||||
|
|
|
@ -543,12 +543,18 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
|
|||
case (expr_cast(?operand, _)) {
|
||||
ret find_pre_post_state_sub(fcx, pres, operand, e.id, none);
|
||||
}
|
||||
case (expr_fail(_)) {
|
||||
case (expr_fail(?maybe_fail_val)) {
|
||||
ret set_prestate_ann(fcx.ccx, e.id, pres) |
|
||||
/* if execution continues after fail, then everything is true!
|
||||
woo! */
|
||||
set_poststate_ann(fcx.ccx, e.id,
|
||||
false_postcond(num_constrs));
|
||||
false_postcond(num_constrs)) |
|
||||
alt(maybe_fail_val) {
|
||||
case (none) { false }
|
||||
case (some(?fail_val)) {
|
||||
find_pre_post_state_expr(fcx, pres, fail_val)
|
||||
}
|
||||
}
|
||||
}
|
||||
case (expr_assert(?p)) {
|
||||
ret find_pre_post_state_sub(fcx, pres, p, e.id, none);
|
||||
|
|
|
@ -1622,7 +1622,13 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
|
|||
auto t = expr_ty(fcx.ccx.tcx, expanded);
|
||||
write::ty_only_fixup(fcx, id, t);
|
||||
}
|
||||
case (ast::expr_fail(_)) { write::bot_ty(fcx.ccx.tcx, id); }
|
||||
case (ast::expr_fail(?expr_opt)) {
|
||||
alt (expr_opt) {
|
||||
case (none) { /* do nothing */ }
|
||||
case (some(?e)) { check_expr(fcx, e); }
|
||||
}
|
||||
write::bot_ty(fcx.ccx.tcx, id);
|
||||
}
|
||||
case (ast::expr_break) { write::bot_ty(fcx.ccx.tcx, id); }
|
||||
case (ast::expr_cont) { write::bot_ty(fcx.ccx.tcx, id); }
|
||||
case (ast::expr_ret(?expr_opt)) {
|
||||
|
|
|
@ -369,7 +369,7 @@ fn walk_expr(&ast_visitor v, @ast::expr e) {
|
|||
|
||||
walk_expr(v, expansion);
|
||||
}
|
||||
case (ast::expr_fail(_)) { }
|
||||
case (ast::expr_fail(?eo)) { walk_expr_opt(v, eo); }
|
||||
case (ast::expr_break) { }
|
||||
case (ast::expr_cont) { }
|
||||
case (ast::expr_ret(?eo)) { walk_expr_opt(v, eo); }
|
||||
|
|
|
@ -838,10 +838,10 @@ fn print_expr(&ps s, &@ast::expr expr) {
|
|||
pclose(s);
|
||||
}
|
||||
case (ast::expr_path(?path)) { print_path(s, path); }
|
||||
case (ast::expr_fail(?str)) {
|
||||
case (ast::expr_fail(?maybe_fail_val)) {
|
||||
word(s.s, "fail");
|
||||
alt (str) {
|
||||
case (some(?msg)) { word(s.s, #fmt(" \"%s\"", msg)); }
|
||||
alt (maybe_fail_val) {
|
||||
case (some(?expr)) { word(s.s, " "); print_expr(s, expr); }
|
||||
case (_) { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
|
||||
|
||||
|
||||
// error-pattern:woooo
|
||||
fn main() { fail"woooo"; }
|
||||
// error-pattern:wooooo
|
||||
fn main() {
|
||||
auto a = 1;
|
||||
if (1 == 1) {
|
||||
a = 2;
|
||||
}
|
||||
fail "woooo" + "o";
|
||||
}
|
Loading…
Reference in a new issue