about summary refs log tree commit diff
path: root/src/comp/middle
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-07-06 11:38:00 -0700
committerBrian Anderson <banderson@mozilla.com>2011-07-06 11:44:36 -0700
commit5c20a8aa9c377f339bda7f16e8701070d23e6b4e (patch)
tree6b5cb6cb88a378e50ec86dd99020d1e1df13a2c1 /src/comp/middle
parentc31472e84545a90cea929f728cd48a00a10d8274 (diff)
downloadrust-5c20a8aa9c377f339bda7f16e8701070d23e6b4e.tar.gz
rust-5c20a8aa9c377f339bda7f16e8701070d23e6b4e.zip
Make "cannot determine a type for this expression" non-fatal. Closes #621
Diffstat (limited to 'src/comp/middle')
-rw-r--r--src/comp/middle/typeck.rs54
1 files changed, 37 insertions, 17 deletions
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 500817ea307..7c042eee43a 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -1027,28 +1027,45 @@ mod writeback {
     export resolve_type_vars_in_block;
 
     fn resolve_type_vars_in_type(&@fn_ctxt fcx, &span sp, ty::t typ) ->
-       ty::t {
-        if (!ty::type_contains_vars(fcx.ccx.tcx, typ)) { ret typ; }
+        option::t[ty::t] {
+        if (!ty::type_contains_vars(fcx.ccx.tcx, typ)) { ret some(typ); }
         alt (ty::unify::fixup_vars(fcx.ccx.tcx, fcx.var_bindings, typ)) {
-            case (fix_ok(?new_type)) { ret new_type; }
+            case (fix_ok(?new_type)) { ret some(new_type); }
             case (fix_err(?vid)) {
-                fcx.ccx.tcx.sess.span_fatal(sp,
+                fcx.ccx.tcx.sess.span_err(sp,
                                           "cannot determine a type \
                                            for this expression");
+                ret none;
             }
         }
     }
-    fn resolve_type_vars_for_node(&@fn_ctxt fcx, &span sp, ast::node_id id) {
+    fn resolve_type_vars_for_node(&@wb_ctxt wbcx,
+                                  &span sp, ast::node_id id) {
+        auto fcx = wbcx.fcx;
         auto tpot = ty::node_id_to_ty_param_substs_opt_and_ty
             (fcx.ccx.tcx, id);
-        auto new_ty = resolve_type_vars_in_type(fcx, sp, tpot._1);
+        auto new_ty = alt (resolve_type_vars_in_type(fcx, sp, tpot._1)) {
+            case (some(?t)) { t }
+            case (none) {
+                wbcx.success = false;
+                ret
+            }
+        };
         auto new_substs_opt;
         alt (tpot._0) {
             case (none[vec[ty::t]]) { new_substs_opt = none[vec[ty::t]]; }
             case (some[vec[ty::t]](?substs)) {
                 let vec[ty::t] new_substs = [];
                 for (ty::t subst in substs) {
-                    new_substs += [resolve_type_vars_in_type(fcx, sp, subst)];
+                    alt (resolve_type_vars_in_type(fcx, sp, subst)) {
+                        case (some(?t)) {
+                            new_substs += [t];
+                        }
+                        case (none) {
+                            wbcx.success = false;
+                            ret;
+                        }
+                    }
                 }
                 new_substs_opt = some[vec[ty::t]](new_substs);
             }
@@ -1058,19 +1075,20 @@ mod writeback {
 
     type wb_ctxt = rec(@fn_ctxt fcx,
                        // A flag to ignore contained items and lambdas
-                       mutable bool ignore);
+                       mutable bool ignore,
+                       mutable bool success);
 
     fn visit_stmt_pre(@wb_ctxt wbcx, &@ast::stmt s) {
-        resolve_type_vars_for_node(wbcx.fcx, s.span, ty::stmt_node_id(s));
+        resolve_type_vars_for_node(wbcx, s.span, ty::stmt_node_id(s));
     }
     fn visit_expr_pre(@wb_ctxt wbcx, &@ast::expr e) {
-        resolve_type_vars_for_node(wbcx.fcx, e.span, e.id);
+        resolve_type_vars_for_node(wbcx, e.span, e.id);
     }
     fn visit_block_pre(@wb_ctxt wbcx, &ast::block b) {
-        resolve_type_vars_for_node(wbcx.fcx, b.span, b.node.id);
+        resolve_type_vars_for_node(wbcx, b.span, b.node.id);
     }
     fn visit_pat_pre(@wb_ctxt wbcx, &@ast::pat p) {
-        resolve_type_vars_for_node(wbcx.fcx, p.span, p.id);
+        resolve_type_vars_for_node(wbcx, p.span, p.id);
     }
     fn visit_local_pre(@wb_ctxt wbcx, &@ast::local l) {
         auto var_id = lookup_local(wbcx.fcx, l.span, l.node.id);
@@ -1105,11 +1123,12 @@ mod writeback {
                      &ast::fn_ident i, ast::node_id d) {
         wbcx.ignore = false;
     }
-    fn keep_going(@wb_ctxt wbcx) -> bool { ret !wbcx.ignore; }
+    fn keep_going(@wb_ctxt wbcx) -> bool { !wbcx.ignore && wbcx.success }
 
-    fn resolve_type_vars_in_block(&@fn_ctxt fcx, &ast::block block) {
+    fn resolve_type_vars_in_block(&@fn_ctxt fcx, &ast::block block) -> bool {
         auto wbcx = @rec(fcx = fcx,
-                        mutable ignore = false);
+                         mutable ignore = false,
+                         mutable success = true);
         auto visit =
             rec(keep_going=bind keep_going(wbcx),
                 visit_item_pre=bind visit_item_pre(wbcx, _),
@@ -1123,6 +1142,7 @@ mod writeback {
                 visit_local_pre=bind visit_local_pre(wbcx, _)
                 with walk::default_visitor());
         walk::walk_block(visit, block);
+        ret wbcx.success;
     }
 }
 
@@ -2482,9 +2502,9 @@ fn check_fn(&@crate_ctxt ccx, &ast::fn_decl decl, ast::proto proto,
         case (_) { }
     }
 
-    writeback::resolve_type_vars_in_block(fcx, body);
+    auto success = writeback::resolve_type_vars_in_block(fcx, body);
 
-    if (option::is_some(body.node.expr)) {
+    if (success && option::is_some(body.node.expr)) {
         auto tail_expr = option::get(body.node.expr);
         auto tail_expr_ty = expr_ty(ccx.tcx, tail_expr);
         // Have to exclude ty_nil to allow functions to end in