From 8ab075ee456fd426090d5927d6fa53677988aa51 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Sat, 10 Mar 2012 20:35:41 -0800 Subject: [PATCH] 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). --- src/rustc/middle/ty.rs | 18 ++++++------------ src/rustc/middle/typeck.rs | 12 +++++------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index ea8de5b8b77a..800caaf639c0 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -125,7 +125,7 @@ export set_default_mode; export unify; export variant_info; export walk_ty; -export occurs_check_fails; +export occurs_check; export closure_kind; export ck_block; export ck_box; @@ -1088,7 +1088,7 @@ fn vars_in_type(cx: ctxt, ty: t) -> [int] { fn type_autoderef(cx: ctxt, t: t) -> t { let t1 = t; - while true { + loop { alt get(t1).struct { ty_box(mt) | ty_uniq(mt) { t1 = mt.ty; } ty_res(_, inner, tps) { @@ -1427,28 +1427,22 @@ fn sort_methods(meths: [method]) -> [method] { ret std::sort::merge_sort(bind method_lteq(_, _), meths); } -fn occurs_check_fails(tcx: ctxt, sp: option, vid: int, rt: t) -> - bool { +fn occurs_check(tcx: ctxt, sp: span, vid: int, rt: t) { // Fast path - if !type_has_vars(rt) { ret false; } + if !type_has_vars(rt) { ret; } // Occurs check! if vec::contains(vars_in_type(tcx, rt), vid) { - alt sp { - some(s) { // Maybe this should be span_err -- however, there's an // assertion later on that the type doesn't contain // variables, so in this case we have to be sure to die. 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 " + ty_to_str(tcx, mk_var(tcx, vid)) + " and of the form " + ty_to_str(tcx, rt) + " - 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 diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index 7ecb5b9aa34b..0b99b400068d 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -1005,15 +1005,13 @@ mod unify { // instead of ty::struct. fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> ty::t { let t1 = t; - while true { + loop { alt structure_of(fcx, sp, t1) { ty::ty_box(inner) | ty::ty_uniq(inner) { alt ty::get(t1).struct { ty::ty_var(v1) { - if ty::occurs_check_fails(fcx.ccx.tcx, some(sp), v1, - ty::mk_box(fcx.ccx.tcx, inner)) { - break; - } + ty::occurs_check(fcx.ccx.tcx, sp, v1, + ty::mk_box(fcx.ccx.tcx, inner)); } _ { } } @@ -1033,8 +1031,7 @@ fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> ty::t { } _ { ret t1; } } - } - core::unreachable(); + }; } 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, ast::expr_loop(body) { check_block_no_value(fcx, body); write_ty(tcx, id, ty::mk_nil(tcx)); + bot = !may_break(body); } ast::expr_alt(expr, arms, _) { bot = check_expr(fcx, expr);