Make _|_ unify with anything
The typechecker had a number of special cases for unifying types with _|_ (as with checking if and alt). But, a value of type _|_ should be usable in any context, as such a value always diverges, and will never be used by its immediate context. Changed unify accordingly, removed special cases.
This commit is contained in:
parent
af6b4821c1
commit
1a96e79fe0
|
@ -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)) {
|
||||
|
|
|
@ -1341,19 +1341,15 @@ 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
write::ty_only_fixup(scx, ann.id, t);
|
||||
}
|
||||
case (ast::expr_for(?decl, ?seq, ?bloc, ?ann)) {
|
||||
|
@ -1472,11 +1468,8 @@ 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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
fn main() {
|
||||
let int i = if (false) {
|
||||
fail
|
||||
}
|
||||
else {
|
||||
5
|
||||
};
|
||||
log i;
|
||||
}
|
Loading…
Reference in New Issue