diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-08-02 18:11:29 -0700 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-08-02 21:44:14 -0700 |
| commit | c2bb2f08372ad6e688ea0b7915d003cd4053cfec (patch) | |
| tree | 6a6889c010b1d40256683455dcf1e844cf856b59 /src/rustc | |
| parent | c9c3a49bfccf03e53f70cfaaaa85a622c50e5d2b (diff) | |
| download | rust-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/rustc')
| -rw-r--r-- | src/rustc/middle/typeck/check.rs | 22 |
1 files changed, 12 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 { |
