about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-08-02 18:11:29 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-08-02 21:44:14 -0700
commitc2bb2f08372ad6e688ea0b7915d003cd4053cfec (patch)
tree6a6889c010b1d40256683455dcf1e844cf856b59 /src
parentc9c3a49bfccf03e53f70cfaaaa85a622c50e5d2b (diff)
downloadrust-c2bb2f08372ad6e688ea0b7915d003cd4053cfec.tar.gz
rust-c2bb2f08372ad6e688ea0b7915d003cd4053cfec.zip
When checking loop bodies and do-expr bodies, don't require the expected type to exist
If the expected type is none (due to a type error), we shouldn't fail with an ICE, but
rather, just print out another type error. Changed the do-expr type error message to
make sense in this context (see the test case for how it works).

Closes #3044.
Diffstat (limited to 'src')
-rw-r--r--src/rustc/middle/typeck/check.rs22
-rw-r--r--src/test/compile-fail/issue-3044.rs9
2 files changed, 21 insertions, 10 deletions
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index 61a6c8dff51..c6856d10dc5 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -1316,7 +1316,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
                   _ { none }
                 }
               }
-              ast::not | ast::neg { some(expected.get()) }
+              ast::not | ast::neg { expected }
               ast::deref { none }
             }
         };
@@ -1475,10 +1475,11 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         capture::check_capture_clause(tcx, expr.id, cap_clause);
       }
       ast::expr_fn_block(decl, body, cap_clause) {
+          let proto = unpack_expected(fcx, expected, |sty|
+              alt sty { ty::ty_fn({proto, _}) { some(proto) } _ { none } }
+          ).get_default(ast::proto_box);
         // Take the prototype from the expected type, but default to block:
-        let proto = unpack_expected(fcx, expected, |sty|
-            alt sty { ty::ty_fn({proto, _}) { some(proto) } _ { none } }
-        ).get_default(ast::proto_box);
+          let proto = proto_1.get_default(ast::proto_box);
         check_expr_fn(fcx, expr, proto, decl, body, false, expected);
         capture::check_capture_clause(tcx, expr.id, cap_clause);
       }
@@ -1489,9 +1490,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         // parameter. The catch here is that we need to validate two things:
         // 1. a closure that returns a bool is expected
         // 2. the cloure that was given returns unit
-        let expected_sty = unpack_expected(fcx, expected, |x| some(x)).get();
+        let expected_sty = unpack_expected(fcx, expected, |x| some(x));
         let (inner_ty, proto) = alt expected_sty {
-          ty::ty_fn(fty) {
+          some(ty::ty_fn(fty)) {
             alt infer::mk_subty(fcx.infcx, fty.output, ty::mk_bool(tcx)) {
               result::ok(_) {}
               result::err(err) {
@@ -1526,14 +1527,15 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         }
       }
       ast::expr_do_body(b) {
-        let expected_sty = unpack_expected(fcx, expected, |x| some(x)).get();
+        let expected_sty = unpack_expected(fcx, expected, |x| some(x));
         let (inner_ty, proto) = alt expected_sty {
-          ty::ty_fn(fty) {
+          some(ty::ty_fn(fty)) {
             (ty::mk_fn(tcx, fty), fty.proto)
           }
           _ {
-            tcx.sess.span_fatal(expr.span, ~"a `do` function's last argument \
-                                            should be of function type");
+            tcx.sess.span_fatal(expr.span, ~"Non-function passed to a `do` \
+              function as its last argument, or wrong number of arguments \
+              passed to a `do` function");
           }
         };
         alt check b.node {
diff --git a/src/test/compile-fail/issue-3044.rs b/src/test/compile-fail/issue-3044.rs
new file mode 100644
index 00000000000..5898e7242c7
--- /dev/null
+++ b/src/test/compile-fail/issue-3044.rs
@@ -0,0 +1,9 @@
+// error-pattern: Non-function passed to a `do` function as its last argument, or wrong number of arguments passed to a `do` function
+fn main() {
+    let needlesArr: ~[char] = ~['a', 'f'];
+    do vec::foldr(needlesArr) |x, y| {
+    }
+// for some reason if I use the new error syntax for the two error messages this generates,
+// the test runner gets confused -- tjc
+}
+