diff options
| author | Patrick Walton <[email protected]> | 2011-02-22 15:28:47 -0800 |
|---|---|---|
| committer | Patrick Walton <[email protected]> | 2011-02-22 15:50:07 -0800 |
| commit | 01c2761769ab93682afec9101b4896a7253b5251 (patch) | |
| tree | f92674e05c49f42089e4fcc065b1f8ca6d0e1ddd | |
| parent | Finish the type of native functions. We now get (diff) | |
| download | rust-01c2761769ab93682afec9101b4896a7253b5251.tar.xz rust-01c2761769ab93682afec9101b4896a7253b5251.zip | |
Rework typechecking of bind expressions
| -rw-r--r-- | src/comp/middle/typeck.rs | 65 |
1 files changed, 29 insertions, 36 deletions
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index b259fb4e..1b39cdf5 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1702,47 +1702,40 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr { } case (ast.expr_bind(?f, ?args, _)) { - auto f_0 = check_expr(fcx, f); - auto t_0 = expr_ty(f_0); - - if (!ty.is_fn_ty(t_0)) { - fcx.ccx.sess.span_err(f_0.span, - "mismatched types: bind callee has " + - "non-function type: " + - ty_to_str(t_0)); - } - - let ast.proto proto = ty.ty_fn_proto(t_0); - let vec[arg] arg_tys_0 = ty.ty_fn_args(t_0); - let @ty.t rt_0 = ty.ty_fn_ret(t_0); - let vec[option.t[@ast.expr]] args_1 = vec(); - - let uint i = 0u; - - let vec[arg] residual_args = vec(); - for (option.t[@ast.expr] a in args) { - alt (a) { - case (none[@ast.expr]) { - append[arg](residual_args, - arg_tys_0.(i)); - append[option.t[@ast.expr]](args_1, - none[@ast.expr]); - } - case (some[@ast.expr](?sa)) { - auto arg_1 = check_expr(fcx, sa); - auto arg_t = expr_ty(arg_1); - demand_expr(fcx, arg_tys_0.(i).ty, arg_1); - append[option.t[@ast.expr]](args_1, - some[@ast.expr](arg_1)); + // Call the generic checker. + auto result = check_call_or_bind(fcx, f, args); + + // Pull the argument and return types out. + auto proto_1 = ast.proto_fn; // FIXME: typestate botch + let vec[ty.arg] arg_tys_1 = vec(); + auto rt_1 = plain_ty(ty.ty_nil); // FIXME: typestate botch + alt (expr_ty(result._0).struct) { + case (ty.ty_fn(?proto, ?arg_tys, ?rt)) { + proto_1 = proto; + rt_1 = rt; + + // For each blank argument, add the type of that argument + // to the resulting function type. + auto i = 0u; + while (i < _vec.len[option.t[@ast.expr]](args)) { + alt (args.(i)) { + case (some[@ast.expr](_)) { /* no-op */ } + case (none[@ast.expr]) { + arg_tys_1 += vec(arg_tys.(i)); + } + } + i += 1u; } } - i += 1u; + case (_) { + log "LHS of bind expr didn't have a function type?!"; + fail; + } } - let @ty.t t_1 = plain_ty(ty.ty_fn(proto, residual_args, rt_0)); - + auto t_1 = plain_ty(ty.ty_fn(proto_1, arg_tys_1, rt_1)); ret @fold.respan[ast.expr_](expr.span, - ast.expr_bind(f_0, args_1, + ast.expr_bind(result._0, result._1, ast.ann_type(t_1))); } |