提交 8ab075ee 编写于 作者: T Tim Chevalier

Clean up occurs check code and give non-breaking loop {..}s _|_ type

The latter change is so that code dominated by a loop{ } without a
break gets considered unreachable.

The former change is just cosmetic (occurs_check_fails was a predicate
when it should be a unit-typed function that can fail).
上级 205cefdc
...@@ -125,7 +125,7 @@ ...@@ -125,7 +125,7 @@
export unify; export unify;
export variant_info; export variant_info;
export walk_ty; export walk_ty;
export occurs_check_fails; export occurs_check;
export closure_kind; export closure_kind;
export ck_block; export ck_block;
export ck_box; export ck_box;
...@@ -1088,7 +1088,7 @@ fn vars_in_type(cx: ctxt, ty: t) -> [int] { ...@@ -1088,7 +1088,7 @@ fn vars_in_type(cx: ctxt, ty: t) -> [int] {
fn type_autoderef(cx: ctxt, t: t) -> t { fn type_autoderef(cx: ctxt, t: t) -> t {
let t1 = t; let t1 = t;
while true { loop {
alt get(t1).struct { alt get(t1).struct {
ty_box(mt) | ty_uniq(mt) { t1 = mt.ty; } ty_box(mt) | ty_uniq(mt) { t1 = mt.ty; }
ty_res(_, inner, tps) { ty_res(_, inner, tps) {
...@@ -1427,28 +1427,22 @@ fn method_lteq(a: method, b: method) -> bool { ...@@ -1427,28 +1427,22 @@ fn method_lteq(a: method, b: method) -> bool {
ret std::sort::merge_sort(bind method_lteq(_, _), meths); ret std::sort::merge_sort(bind method_lteq(_, _), meths);
} }
fn occurs_check_fails(tcx: ctxt, sp: option<span>, vid: int, rt: t) -> fn occurs_check(tcx: ctxt, sp: span, vid: int, rt: t) {
bool {
// Fast path // Fast path
if !type_has_vars(rt) { ret false; } if !type_has_vars(rt) { ret; }
// Occurs check! // Occurs check!
if vec::contains(vars_in_type(tcx, rt), vid) { if vec::contains(vars_in_type(tcx, rt), vid) {
alt sp {
some(s) {
// Maybe this should be span_err -- however, there's an // Maybe this should be span_err -- however, there's an
// assertion later on that the type doesn't contain // assertion later on that the type doesn't contain
// variables, so in this case we have to be sure to die. // variables, so in this case we have to be sure to die.
tcx.sess.span_fatal tcx.sess.span_fatal
(s, "type inference failed because I \ (sp, "type inference failed because I \
could not find a type\n that's both of the form " could not find a type\n that's both of the form "
+ ty_to_str(tcx, mk_var(tcx, vid)) + + ty_to_str(tcx, mk_var(tcx, vid)) +
" and of the form " + ty_to_str(tcx, rt) + " and of the form " + ty_to_str(tcx, rt) +
" - such a type would have to be infinitely large."); " - such a type would have to be infinitely large.");
} }
_ { ret true; }
}
} else { ret false; }
} }
// Maintains a little union-set tree for inferred modes. `canon()` returns // Maintains a little union-set tree for inferred modes. `canon()` returns
......
...@@ -1005,15 +1005,13 @@ fn unify(fcx: @fn_ctxt, expected: ty::t, actual: ty::t) -> ...@@ -1005,15 +1005,13 @@ fn unify(fcx: @fn_ctxt, expected: ty::t, actual: ty::t) ->
// instead of ty::struct. // instead of ty::struct.
fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> ty::t { fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> ty::t {
let t1 = t; let t1 = t;
while true { loop {
alt structure_of(fcx, sp, t1) { alt structure_of(fcx, sp, t1) {
ty::ty_box(inner) | ty::ty_uniq(inner) { ty::ty_box(inner) | ty::ty_uniq(inner) {
alt ty::get(t1).struct { alt ty::get(t1).struct {
ty::ty_var(v1) { ty::ty_var(v1) {
if ty::occurs_check_fails(fcx.ccx.tcx, some(sp), v1, ty::occurs_check(fcx.ccx.tcx, sp, v1,
ty::mk_box(fcx.ccx.tcx, inner)) { ty::mk_box(fcx.ccx.tcx, inner));
break;
}
} }
_ { } _ { }
} }
...@@ -1033,8 +1031,7 @@ fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> ty::t { ...@@ -1033,8 +1031,7 @@ fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> ty::t {
} }
_ { ret t1; } _ { ret t1; }
} }
} };
core::unreachable();
} }
fn resolve_type_vars_if_possible(fcx: @fn_ctxt, typ: ty::t) -> ty::t { fn resolve_type_vars_if_possible(fcx: @fn_ctxt, typ: ty::t) -> ty::t {
...@@ -2326,6 +2323,7 @@ fn check_user_unop(fcx: @fn_ctxt, op_str: str, mname: str, ...@@ -2326,6 +2323,7 @@ fn check_user_unop(fcx: @fn_ctxt, op_str: str, mname: str,
ast::expr_loop(body) { ast::expr_loop(body) {
check_block_no_value(fcx, body); check_block_no_value(fcx, body);
write_ty(tcx, id, ty::mk_nil(tcx)); write_ty(tcx, id, ty::mk_nil(tcx));
bot = !may_break(body);
} }
ast::expr_alt(expr, arms, _) { ast::expr_alt(expr, arms, _) {
bot = check_expr(fcx, expr); bot = check_expr(fcx, expr);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册