Bare functions can coerce to shared closures

This commit is contained in:
Brian Anderson 2011-10-14 15:16:05 -07:00
parent 3bb020aaf8
commit 354bfc8292
2 changed files with 22 additions and 6 deletions

View File

@ -891,7 +891,7 @@ fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> ty::t {
fail; fail;
} }
fn do_fn_block_coerce(fcx: @fn_ctxt, sp: span, actual: ty::t, expected: ty::t) fn do_fn_ty_coerce(fcx: @fn_ctxt, sp: span, actual: ty::t, expected: ty::t)
-> ty::t { -> ty::t {
// fns can be silently coerced to blocks when being used as // fns can be silently coerced to blocks when being used as
@ -910,6 +910,15 @@ fn do_fn_block_coerce(fcx: @fn_ctxt, sp: span, actual: ty::t, expected: ty::t)
_ { actual } _ { actual }
} }
} }
some(ty::ty_fn(ast::proto_bare., args, ret_ty, cf, constrs)) {
alt structure_of_maybe(fcx, sp, expected) {
some(ty::ty_fn(ast::proto_fn., _, _, _, _)) {
ty::mk_fn(fcx.ccx.tcx, ast::proto_fn, args, ret_ty, cf,
constrs)
}
_ { actual }
}
}
_ { actual } _ { actual }
} }
} }
@ -932,7 +941,7 @@ fn simple(fcx: @fn_ctxt, sp: span, expected: ty::t, actual: ty::t) ->
ty::t { ty::t {
full(fcx, sp, expected, actual, [], false).ty full(fcx, sp, expected, actual, [], false).ty
} }
fn block_coerce(fcx: @fn_ctxt, sp: span, expected: ty::t, actual: ty::t) fn fn_coerce(fcx: @fn_ctxt, sp: span, expected: ty::t, actual: ty::t)
-> ty::t { -> ty::t {
full(fcx, sp, expected, actual, [], true).ty full(fcx, sp, expected, actual, [], true).ty
} }
@ -945,10 +954,10 @@ fn with_substs(fcx: @fn_ctxt, sp: span, expected: ty::t, actual: ty::t,
// Requires that the two types unify, and prints an error message if they // Requires that the two types unify, and prints an error message if they
// don't. Returns the unified type and the type parameter substitutions. // don't. Returns the unified type and the type parameter substitutions.
fn full(fcx: @fn_ctxt, sp: span, expected: ty::t, actual: ty::t, fn full(fcx: @fn_ctxt, sp: span, expected: ty::t, actual: ty::t,
ty_param_substs_0: [ty::t], do_block_coerce: bool) -> ty_param_substs_0: [ty::t], do_fn_coerce: bool) ->
ty_param_substs_and_ty { ty_param_substs_and_ty {
if do_block_coerce { if do_fn_coerce {
actual = do_fn_block_coerce(fcx, sp, actual, expected); actual = do_fn_ty_coerce(fcx, sp, actual, expected);
} }
let ty_param_substs: [mutable ty::t] = [mutable]; let ty_param_substs: [mutable ty::t] = [mutable];
@ -1676,7 +1685,7 @@ fn check_call_or_bind(fcx: @fn_ctxt, sp: span, f: @ast::expr,
if is_block == check_blocks { if is_block == check_blocks {
bot |= bot |=
check_expr_with_unifier(fcx, a, check_expr_with_unifier(fcx, a,
demand::block_coerce, demand::fn_coerce,
arg_tys[i].ty); arg_tys[i].ty);
} }
} }

View File

@ -0,0 +1,7 @@
fn# bare() {}
fn likes_shared(f: fn@()) { f() }
fn main() {
likes_shared(bare);
}