Rework typechecking of bind expressions
This commit is contained in:
parent
b389611ce7
commit
01c2761769
1 changed files with 27 additions and 34 deletions
|
@ -1702,47 +1702,40 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
||||||
}
|
}
|
||||||
|
|
||||||
case (ast.expr_bind(?f, ?args, _)) {
|
case (ast.expr_bind(?f, ?args, _)) {
|
||||||
auto f_0 = check_expr(fcx, f);
|
// Call the generic checker.
|
||||||
auto t_0 = expr_ty(f_0);
|
auto result = check_call_or_bind(fcx, f, args);
|
||||||
|
|
||||||
if (!ty.is_fn_ty(t_0)) {
|
// Pull the argument and return types out.
|
||||||
fcx.ccx.sess.span_err(f_0.span,
|
auto proto_1 = ast.proto_fn; // FIXME: typestate botch
|
||||||
"mismatched types: bind callee has " +
|
let vec[ty.arg] arg_tys_1 = vec();
|
||||||
"non-function type: " +
|
auto rt_1 = plain_ty(ty.ty_nil); // FIXME: typestate botch
|
||||||
ty_to_str(t_0));
|
alt (expr_ty(result._0).struct) {
|
||||||
}
|
case (ty.ty_fn(?proto, ?arg_tys, ?rt)) {
|
||||||
|
proto_1 = proto;
|
||||||
|
rt_1 = rt;
|
||||||
|
|
||||||
let ast.proto proto = ty.ty_fn_proto(t_0);
|
// For each blank argument, add the type of that argument
|
||||||
let vec[arg] arg_tys_0 = ty.ty_fn_args(t_0);
|
// to the resulting function type.
|
||||||
let @ty.t rt_0 = ty.ty_fn_ret(t_0);
|
auto i = 0u;
|
||||||
let vec[option.t[@ast.expr]] args_1 = vec();
|
while (i < _vec.len[option.t[@ast.expr]](args)) {
|
||||||
|
alt (args.(i)) {
|
||||||
let uint i = 0u;
|
case (some[@ast.expr](_)) { /* no-op */ }
|
||||||
|
case (none[@ast.expr]) {
|
||||||
let vec[arg] residual_args = vec();
|
arg_tys_1 += vec(arg_tys.(i));
|
||||||
for (option.t[@ast.expr] a in args) {
|
}
|
||||||
alt (a) {
|
}
|
||||||
case (none[@ast.expr]) {
|
i += 1u;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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,
|
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)));
|
ast.ann_type(t_1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue