diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 44cab2120a0..8797d05a51f 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -6388,9 +6388,9 @@ fn trans_fail_expr(&@block_ctxt cx, &option::t[common::span] sp_opt, [C_int(0), C_int(abi::vec_elt_data)]); ret trans_fail_value(bcx, sp_opt, elt); } else { - bcx.fcx.lcx.ccx.sess.span_fatal(expr.span, - "fail called with unsupported \ - type " + ty_to_str(tcx, e_ty)); + cx.fcx.lcx.ccx.sess.span_bug(expr.span, + "fail called with unsupported \ + type " + ty_to_str(tcx, e_ty)); } } case (_) { diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 41c3ff993ee..6fbe6493061 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -229,6 +229,11 @@ fn type_is_scalar(&@fn_ctxt fcx, &span sp, ty::t typ) -> bool { ret ty::type_is_scalar(fcx.ccx.tcx, typ_s); } +fn type_is_str(&@fn_ctxt fcx, &span sp, ty::t typ) -> bool { + auto typ_s = structurally_resolved_type(fcx, sp, typ); + ret ty::type_is_str(fcx.ccx.tcx, typ_s); +} + // Parses the programmer's textual representation of a type into our internal // notion of a type. `getter` is a function that returns the type @@ -1658,7 +1663,17 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) { case (ast::expr_fail(?expr_opt)) { alt (expr_opt) { case (none) { /* do nothing */ } - case (some(?e)) { check_expr(fcx, e); } + case (some(?e)) { + check_expr(fcx, e); + auto tcx = fcx.ccx.tcx; + auto ety = expr_ty(tcx, e); + if (!type_is_str(fcx, e.span, ety)) { + tcx.sess.span_fatal(e.span, + #fmt("mismatched types: expected \ + str, found %s", + ty_to_str(tcx, ety))); + } + } } write::bot_ty(fcx.ccx.tcx, id); } diff --git a/src/test/compile-fail/fail-expr.rs b/src/test/compile-fail/fail-expr.rs new file mode 100644 index 00000000000..dbc5afa016d --- /dev/null +++ b/src/test/compile-fail/fail-expr.rs @@ -0,0 +1,5 @@ +// error-pattern:mismatched types + +fn main() { + fail 5; +} \ No newline at end of file