mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 19:58:32 +00:00
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.
This commit is contained in:
parent
c9c3a49bfc
commit
c2bb2f0837
@ -1316,7 +1316,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||||||
_ { none }
|
_ { none }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::not | ast::neg { some(expected.get()) }
|
ast::not | ast::neg { expected }
|
||||||
ast::deref { none }
|
ast::deref { none }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1475,10 +1475,11 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||||||
capture::check_capture_clause(tcx, expr.id, cap_clause);
|
capture::check_capture_clause(tcx, expr.id, cap_clause);
|
||||||
}
|
}
|
||||||
ast::expr_fn_block(decl, body, 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:
|
// Take the prototype from the expected type, but default to block:
|
||||||
let proto = unpack_expected(fcx, expected, |sty|
|
let proto = proto_1.get_default(ast::proto_box);
|
||||||
alt sty { ty::ty_fn({proto, _}) { some(proto) } _ { none } }
|
|
||||||
).get_default(ast::proto_box);
|
|
||||||
check_expr_fn(fcx, expr, proto, decl, body, false, expected);
|
check_expr_fn(fcx, expr, proto, decl, body, false, expected);
|
||||||
capture::check_capture_clause(tcx, expr.id, cap_clause);
|
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:
|
// parameter. The catch here is that we need to validate two things:
|
||||||
// 1. a closure that returns a bool is expected
|
// 1. a closure that returns a bool is expected
|
||||||
// 2. the cloure that was given returns unit
|
// 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 {
|
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)) {
|
alt infer::mk_subty(fcx.infcx, fty.output, ty::mk_bool(tcx)) {
|
||||||
result::ok(_) {}
|
result::ok(_) {}
|
||||||
result::err(err) {
|
result::err(err) {
|
||||||
@ -1526,14 +1527,15 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::expr_do_body(b) {
|
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 {
|
let (inner_ty, proto) = alt expected_sty {
|
||||||
ty::ty_fn(fty) {
|
some(ty::ty_fn(fty)) {
|
||||||
(ty::mk_fn(tcx, fty), fty.proto)
|
(ty::mk_fn(tcx, fty), fty.proto)
|
||||||
}
|
}
|
||||||
_ {
|
_ {
|
||||||
tcx.sess.span_fatal(expr.span, ~"a `do` function's last argument \
|
tcx.sess.span_fatal(expr.span, ~"Non-function passed to a `do` \
|
||||||
should be of function type");
|
function as its last argument, or wrong number of arguments \
|
||||||
|
passed to a `do` function");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
alt check b.node {
|
alt check b.node {
|
||||||
|
9
src/test/compile-fail/issue-3044.rs
Normal file
9
src/test/compile-fail/issue-3044.rs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user