diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 8e1e5e82c31..56f8ca66c2f 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -2209,6 +2209,12 @@ mod unify { if (eq_ty(expected, actual)) { ret ures_ok(expected); } alt (struct(cx.tcx, actual)) { + + // a _|_ type can be used anywhere + case (ty::ty_bot) { + ret ures_ok(expected); + } + // If the RHS is a variable type, then just do the appropriate // binding. case (ty::ty_var(?actual_id)) { diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index df030d72ce8..47585b4bb73 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1341,17 +1341,13 @@ mod pushdown { ann_to_type(scx.fcx.ccx.tcx.node_types, ann), adk); auto then_t = ty::block_ty(scx.fcx.ccx.tcx, then_0); - if (!ty::type_is_bot(scx.fcx.ccx.tcx, then_t)) { - pushdown_block(scx, expected, then_0); - } + pushdown_block(scx, expected, then_0); alt (else_0) { case (none[@ast::expr]) { /* no-op */ } case (some[@ast::expr](?e_0)) { auto else_t = ty::expr_ty(scx.fcx.ccx.tcx, e_0); - if (!ty::type_is_bot(scx.fcx.ccx.tcx, else_t)) { - pushdown_expr(scx, expected, e_0); - } + pushdown_expr(scx, expected, e_0); } } write::ty_only_fixup(scx, ann.id, t); @@ -1472,10 +1468,7 @@ mod pushdown { for (ast::arm arm_0 in arms_0) { pushdown_block(scx, expected, arm_0.block); auto bty = block_ty(scx.fcx.ccx.tcx, arm_0.block); - // Failing alt arms don't need to have a matching type - if (!ty::type_is_bot(scx.fcx.ccx.tcx, bty)) { - t = demand::simple(scx, e.span, t, bty); - } + t = demand::simple(scx, e.span, t, bty); } write::ty_only_fixup(scx, ann.id, t); } @@ -2245,8 +2238,6 @@ fn check_expr(&@stmt_ctxt scx, &@ast::expr expr) { pushdown::pushdown_expr(scx, pattern_ty, expr); - // FIXME: If all the the arms were ty_bot then the result should - // also be ty_bot. At the moment this doesn't seem to matter write::ty_only_fixup(scx, a.id, result_ty); } diff --git a/src/test/run-fail/alt-bot-fail.rs b/src/test/run-fail/alt-bot-fail.rs new file mode 100644 index 00000000000..b580f5a2b0e --- /dev/null +++ b/src/test/run-fail/alt-bot-fail.rs @@ -0,0 +1,21 @@ +// xfail-stage0 +// xfail-stage1 +// xfail-stage2 +// xfail-stage3 +use std; +import std::option::*; + +fn foo(str s) { +} + +fn main() { + auto i = alt (some[int](3)) { + case (none[int]) { + fail + } + case (some[int](_)) { + fail + } + }; + foo(i); +} \ No newline at end of file diff --git a/src/test/run-pass/alt-bot.rs b/src/test/run-pass/alt-bot.rs new file mode 100644 index 00000000000..6be748da3c7 --- /dev/null +++ b/src/test/run-pass/alt-bot.rs @@ -0,0 +1,15 @@ +// xfail-stage0 +use std; +import std::option::*; + +fn main() { + let int i = alt (some[int](3)) { + case (none[int]) { + fail + } + case (some[int](_)) { + 5 + } + }; + log i; +} \ No newline at end of file diff --git a/src/test/run-pass/if-bot.rs b/src/test/run-pass/if-bot.rs new file mode 100644 index 00000000000..6545eedfc85 --- /dev/null +++ b/src/test/run-pass/if-bot.rs @@ -0,0 +1,9 @@ +fn main() { + let int i = if (false) { + fail + } + else { + 5 + }; + log i; +} \ No newline at end of file