about summary refs log tree commit diff
path: root/src/rustc/middle
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-03-10 20:35:41 -0800
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-03-10 20:35:41 -0800
commit8ab075ee456fd426090d5927d6fa53677988aa51 (patch)
tree68342aa9a1332ea0a2e619abbfa9633b2d900fa4 /src/rustc/middle
parent205cefdc6e0e53c6df8075b5c37edd4e0803a598 (diff)
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).
Diffstat (limited to 'src/rustc/middle')
-rw-r--r--src/rustc/middle/ty.rs18
-rw-r--r--src/rustc/middle/typeck.rs12
2 files changed, 11 insertions, 19 deletions
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index ea8de5b8b77..800caaf639c 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<span>, 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 7ecb5b9aa34..0b99b400068 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);