Skip to content

Commit 0cde8ba

Browse files
committed
Implement a new protocol for for loops that's much more easily composable
1 parent ad8e236 commit 0cde8ba

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

src/librustc/middle/trans/callee.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,14 @@ pub fn trans_call_inner(in_cx: block,
550550
// drop the value if it is not being saved.
551551
unsafe {
552552
if llvm::LLVMIsUndef(llretslot) != lib::llvm::True {
553-
if ty::type_is_immediate(ret_ty) {
553+
if ty::type_is_nil(ret_ty) {
554+
// When implementing the for-loop sugar syntax, the
555+
// type of the for-loop is nil, but the function
556+
// it's invoking returns a bool. This is a special
557+
// case to ignore instead of invoking the Store
558+
// below into a scratch pointer of a mismatched
559+
// type.
560+
} else if ty::type_is_immediate(ret_ty) {
554561
let llscratchptr = alloc_ty(bcx, ret_ty);
555562
Store(bcx, llresult, llscratchptr);
556563
bcx = glue::drop_ty(bcx, llscratchptr, ret_ty);

src/librustc/middle/typeck/check/mod.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,26 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
12941294
// The callee checks for bot / err, we don't need to
12951295
}
12961296

1297+
fn write_call(fcx: @mut FnCtxt,
1298+
call_expr: @ast::expr,
1299+
output: ty::t,
1300+
sugar: ast::CallSugar) {
1301+
let ret_ty = match sugar {
1302+
ast::ForSugar => {
1303+
match ty::get(output).sty {
1304+
ty::ty_bool => {}
1305+
_ => fcx.type_error_message(call_expr.span, |actual| {
1306+
fmt!("expected `for` closure to return `bool`, \
1307+
but found `%s`", actual) },
1308+
output, None)
1309+
}
1310+
ty::mk_nil()
1311+
}
1312+
_ => output
1313+
};
1314+
fcx.write_ty(call_expr.id, ret_ty);
1315+
}
1316+
12971317
// A generic function for doing all of the checking for call expressions
12981318
fn check_call(fcx: @mut FnCtxt,
12991319
call_expr: @ast::expr,
@@ -1344,8 +1364,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
13441364
check_argument_types(fcx, call_expr.span, fn_sig.inputs, f,
13451365
args, sugar, DontDerefArgs);
13461366

1347-
// Pull the return type out of the type of the function.
1348-
fcx.write_ty(call_expr.id, fn_sig.output);
1367+
write_call(fcx, call_expr, fn_sig.output, sugar);
13491368
}
13501369

13511370
// Checks a method call.
@@ -1401,8 +1420,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
14011420
fn_ty, expr, args, sugar,
14021421
DontDerefArgs);
14031422

1404-
// Pull the return type out of the type of the function.
1405-
fcx.write_ty(expr.id, ret_ty);
1423+
write_call(fcx, expr, ret_ty, sugar);
14061424
}
14071425

14081426
// A generic function for checking the then and else in an if

0 commit comments

Comments
 (0)