Skip to content

Commit 8ab075e

Browse files
committed
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).
1 parent 205cefd commit 8ab075e

File tree

2 files changed

+11
-19
lines changed

2 files changed

+11
-19
lines changed

src/rustc/middle/ty.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export set_default_mode;
125125
export unify;
126126
export variant_info;
127127
export walk_ty;
128-
export occurs_check_fails;
128+
export occurs_check;
129129
export closure_kind;
130130
export ck_block;
131131
export ck_box;
@@ -1088,7 +1088,7 @@ fn vars_in_type(cx: ctxt, ty: t) -> [int] {
10881088

10891089
fn type_autoderef(cx: ctxt, t: t) -> t {
10901090
let t1 = t;
1091-
while true {
1091+
loop {
10921092
alt get(t1).struct {
10931093
ty_box(mt) | ty_uniq(mt) { t1 = mt.ty; }
10941094
ty_res(_, inner, tps) {
@@ -1427,28 +1427,22 @@ fn sort_methods(meths: [method]) -> [method] {
14271427
ret std::sort::merge_sort(bind method_lteq(_, _), meths);
14281428
}
14291429

1430-
fn occurs_check_fails(tcx: ctxt, sp: option<span>, vid: int, rt: t) ->
1431-
bool {
1430+
fn occurs_check(tcx: ctxt, sp: span, vid: int, rt: t) {
14321431
// Fast path
1433-
if !type_has_vars(rt) { ret false; }
1432+
if !type_has_vars(rt) { ret; }
14341433

14351434
// Occurs check!
14361435
if vec::contains(vars_in_type(tcx, rt), vid) {
1437-
alt sp {
1438-
some(s) {
14391436
// Maybe this should be span_err -- however, there's an
14401437
// assertion later on that the type doesn't contain
14411438
// variables, so in this case we have to be sure to die.
14421439
tcx.sess.span_fatal
1443-
(s, "type inference failed because I \
1440+
(sp, "type inference failed because I \
14441441
could not find a type\n that's both of the form "
14451442
+ ty_to_str(tcx, mk_var(tcx, vid)) +
14461443
" and of the form " + ty_to_str(tcx, rt) +
14471444
" - such a type would have to be infinitely large.");
1448-
}
1449-
_ { ret true; }
1450-
}
1451-
} else { ret false; }
1445+
}
14521446
}
14531447

14541448
// Maintains a little union-set tree for inferred modes. `canon()` returns

src/rustc/middle/typeck.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,15 +1005,13 @@ mod unify {
10051005
// instead of ty::struct.
10061006
fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> ty::t {
10071007
let t1 = t;
1008-
while true {
1008+
loop {
10091009
alt structure_of(fcx, sp, t1) {
10101010
ty::ty_box(inner) | ty::ty_uniq(inner) {
10111011
alt ty::get(t1).struct {
10121012
ty::ty_var(v1) {
1013-
if ty::occurs_check_fails(fcx.ccx.tcx, some(sp), v1,
1014-
ty::mk_box(fcx.ccx.tcx, inner)) {
1015-
break;
1016-
}
1013+
ty::occurs_check(fcx.ccx.tcx, sp, v1,
1014+
ty::mk_box(fcx.ccx.tcx, inner));
10171015
}
10181016
_ { }
10191017
}
@@ -1033,8 +1031,7 @@ fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> ty::t {
10331031
}
10341032
_ { ret t1; }
10351033
}
1036-
}
1037-
core::unreachable();
1034+
};
10381035
}
10391036

10401037
fn resolve_type_vars_if_possible(fcx: @fn_ctxt, typ: ty::t) -> ty::t {
@@ -2326,6 +2323,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
23262323
ast::expr_loop(body) {
23272324
check_block_no_value(fcx, body);
23282325
write_ty(tcx, id, ty::mk_nil(tcx));
2326+
bot = !may_break(body);
23292327
}
23302328
ast::expr_alt(expr, arms, _) {
23312329
bot = check_expr(fcx, expr);

0 commit comments

Comments
 (0)