Implement a new protocol for for loops that's much more easily composable

This commit is contained in:
Alex Crichton 2013-05-02 18:33:08 -04:00
parent ad8e236f32
commit 0cde8ba684
2 changed files with 30 additions and 5 deletions

View File

@ -550,7 +550,14 @@ pub fn trans_call_inner(in_cx: block,
// drop the value if it is not being saved.
unsafe {
if llvm::LLVMIsUndef(llretslot) != lib::llvm::True {
if ty::type_is_immediate(ret_ty) {
if ty::type_is_nil(ret_ty) {
// When implementing the for-loop sugar syntax, the
// type of the for-loop is nil, but the function
// it's invoking returns a bool. This is a special
// case to ignore instead of invoking the Store
// below into a scratch pointer of a mismatched
// type.
} else if ty::type_is_immediate(ret_ty) {
let llscratchptr = alloc_ty(bcx, ret_ty);
Store(bcx, llresult, llscratchptr);
bcx = glue::drop_ty(bcx, llscratchptr, ret_ty);

View File

@ -1294,6 +1294,26 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
// The callee checks for bot / err, we don't need to
}
fn write_call(fcx: @mut FnCtxt,
call_expr: @ast::expr,
output: ty::t,
sugar: ast::CallSugar) {
let ret_ty = match sugar {
ast::ForSugar => {
match ty::get(output).sty {
ty::ty_bool => {}
_ => fcx.type_error_message(call_expr.span, |actual| {
fmt!("expected `for` closure to return `bool`, \
but found `%s`", actual) },
output, None)
}
ty::mk_nil()
}
_ => output
};
fcx.write_ty(call_expr.id, ret_ty);
}
// A generic function for doing all of the checking for call expressions
fn check_call(fcx: @mut FnCtxt,
call_expr: @ast::expr,
@ -1344,8 +1364,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
check_argument_types(fcx, call_expr.span, fn_sig.inputs, f,
args, sugar, DontDerefArgs);
// Pull the return type out of the type of the function.
fcx.write_ty(call_expr.id, fn_sig.output);
write_call(fcx, call_expr, fn_sig.output, sugar);
}
// Checks a method call.
@ -1401,8 +1420,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
fn_ty, expr, args, sugar,
DontDerefArgs);
// Pull the return type out of the type of the function.
fcx.write_ty(expr.id, ret_ty);
write_call(fcx, expr, ret_ty, sugar);
}
// A generic function for checking the then and else in an if