about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2011-07-01 14:33:15 -0400
committerBrian Anderson <banderson@mozilla.com>2011-07-02 00:06:58 -0700
commitd485e0d15a6d1f263657fbaa61dc31da780fea2d (patch)
tree8474e266a0cf7c757488fb0691adf09187dcbc97 /src/comp
parent67c9ef9b306e6f45842a474e66d122c96139e02c (diff)
downloadrust-d485e0d15a6d1f263657fbaa61dc31da780fea2d.tar.gz
rust-d485e0d15a6d1f263657fbaa61dc31da780fea2d.zip
Allow any string expression to be used with fail.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs2
-rw-r--r--src/comp/front/parser.rs11
-rw-r--r--src/comp/middle/trans.rs44
-rw-r--r--src/comp/middle/tstate/pre_post_conditions.rs12
-rw-r--r--src/comp/middle/tstate/states.rs10
-rw-r--r--src/comp/middle/typeck.rs8
-rw-r--r--src/comp/middle/walk.rs2
-rw-r--r--src/comp/pretty/pprust.rs6
8 files changed, 72 insertions, 23 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index ce3bf568cd8..5acffb85472 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -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]);
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 50a719ea261..12a73e48cbf 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -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);
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 4e930429afe..36ab5ed51d3 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -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());
diff --git a/src/comp/middle/tstate/pre_post_conditions.rs b/src/comp/middle/tstate/pre_post_conditions.rs
index ee056f8ddb6..25d6fb98a92 100644
--- a/src/comp/middle/tstate/pre_post_conditions.rs
+++ b/src/comp/middle/tstate/pre_post_conditions.rs
@@ -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)) {
diff --git a/src/comp/middle/tstate/states.rs b/src/comp/middle/tstate/states.rs
index dc64f64e6df..4e4c3a961d7 100644
--- a/src/comp/middle/tstate/states.rs
+++ b/src/comp/middle/tstate/states.rs
@@ -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);
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index c46c885ab6d..3a06d0ddfa5 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -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)) {
diff --git a/src/comp/middle/walk.rs b/src/comp/middle/walk.rs
index 9ea119f2eb1..66db8fa07fe 100644
--- a/src/comp/middle/walk.rs
+++ b/src/comp/middle/walk.rs
@@ -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); }
diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs
index 4190c69448e..1a53c6758dc 100644
--- a/src/comp/pretty/pprust.rs
+++ b/src/comp/pretty/pprust.rs
@@ -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 (_) { }
             }
         }