Make a tag for iterness / fnness, teach many places about it.
This commit is contained in:
parent
3aba50ff33
commit
34c60b6edb
6 changed files with 305 additions and 230 deletions
|
@ -78,6 +78,11 @@ tag effect {
|
|||
eff_unsafe;
|
||||
}
|
||||
|
||||
tag proto {
|
||||
proto_iter;
|
||||
proto_fn;
|
||||
}
|
||||
|
||||
tag binop {
|
||||
add;
|
||||
sub;
|
||||
|
@ -187,7 +192,8 @@ tag lit_ {
|
|||
type ty_field = rec(ident ident, @ty ty);
|
||||
type ty_arg = rec(mode mode, @ty ty);
|
||||
// TODO: effect
|
||||
type ty_method = rec(ident ident, vec[ty_arg] inputs, @ty output);
|
||||
type ty_method = rec(proto proto, ident ident,
|
||||
vec[ty_arg] inputs, @ty output);
|
||||
type ty = spanned[ty_];
|
||||
tag ty_ {
|
||||
ty_nil;
|
||||
|
@ -201,7 +207,7 @@ tag ty_ {
|
|||
ty_vec(@ty);
|
||||
ty_tup(vec[@ty]);
|
||||
ty_rec(vec[ty_field]);
|
||||
ty_fn(vec[ty_arg], @ty); // TODO: effect
|
||||
ty_fn(proto, vec[ty_arg], @ty); // TODO: effect
|
||||
ty_obj(vec[ty_method]);
|
||||
ty_path(path, option.t[def]);
|
||||
ty_mutable(@ty);
|
||||
|
@ -210,10 +216,10 @@ tag ty_ {
|
|||
|
||||
type arg = rec(mode mode, @ty ty, ident ident, def_id id);
|
||||
type fn_decl = rec(effect effect,
|
||||
proto proto,
|
||||
vec[arg] inputs,
|
||||
@ty output);
|
||||
type _fn = rec(fn_decl decl,
|
||||
bool is_iter,
|
||||
block body);
|
||||
|
||||
|
||||
|
|
|
@ -133,7 +133,8 @@ impure fn parse_str_lit(parser p) -> ast.ident {
|
|||
}
|
||||
|
||||
|
||||
impure fn parse_ty_fn(parser p, ast.span lo) -> ast.ty_ {
|
||||
impure fn parse_ty_fn(ast.proto proto, parser p,
|
||||
ast.span lo) -> ast.ty_ {
|
||||
impure fn parse_fn_input_ty(parser p) -> rec(ast.mode mode, @ast.ty ty) {
|
||||
auto mode;
|
||||
if (p.peek() == token.BINOP(token.AND)) {
|
||||
|
@ -167,7 +168,16 @@ impure fn parse_ty_fn(parser p, ast.span lo) -> ast.ty_ {
|
|||
output = @spanned(lo, inputs.span, ast.ty_nil);
|
||||
}
|
||||
|
||||
ret ast.ty_fn(inputs.node, output);
|
||||
ret ast.ty_fn(proto, inputs.node, output);
|
||||
}
|
||||
|
||||
impure fn parse_proto(parser p) -> ast.proto {
|
||||
alt (p.peek()) {
|
||||
case (token.ITER) { p.bump(); ret ast.proto_iter; }
|
||||
case (token.FN) { p.bump(); ret ast.proto_fn; }
|
||||
case (?t) { unexpected(p, t); }
|
||||
}
|
||||
fail;
|
||||
}
|
||||
|
||||
impure fn parse_ty_obj(parser p, &mutable ast.span hi) -> ast.ty_ {
|
||||
|
@ -177,14 +187,14 @@ impure fn parse_ty_obj(parser p, &mutable ast.span hi) -> ast.ty_ {
|
|||
|
||||
// FIXME: do something with this, currently it's dropped on the floor.
|
||||
let ast.effect eff = parse_effect(p);
|
||||
|
||||
expect(p, token.FN);
|
||||
let ast.proto proto = parse_proto(p);
|
||||
auto ident = parse_ident(p);
|
||||
auto f = parse_ty_fn(p, flo);
|
||||
auto f = parse_ty_fn(proto, p, flo);
|
||||
expect(p, token.SEMI);
|
||||
alt (f) {
|
||||
case (ast.ty_fn(?inputs, ?output)) {
|
||||
ret rec(ident=ident, inputs=inputs, output=output);
|
||||
case (ast.ty_fn(?proto, ?inputs, ?output)) {
|
||||
ret rec(proto=proto, ident=ident,
|
||||
inputs=inputs, output=output);
|
||||
}
|
||||
}
|
||||
fail;
|
||||
|
@ -286,9 +296,20 @@ impure fn parse_ty(parser p) -> @ast.ty {
|
|||
case (token.FN) {
|
||||
auto flo = p.get_span();
|
||||
p.bump();
|
||||
t = parse_ty_fn(p, flo);
|
||||
t = parse_ty_fn(ast.proto_fn, p, flo);
|
||||
alt (t) {
|
||||
case (ast.ty_fn(_, ?out)) {
|
||||
case (ast.ty_fn(_, _, ?out)) {
|
||||
hi = out.span;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case (token.ITER) {
|
||||
auto flo = p.get_span();
|
||||
p.bump();
|
||||
t = parse_ty_fn(ast.proto_iter, p, flo);
|
||||
alt (t) {
|
||||
case (ast.ty_fn(_, _, ?out)) {
|
||||
hi = out.span;
|
||||
}
|
||||
}
|
||||
|
@ -1537,7 +1558,8 @@ impure fn parse_ty_params(parser p) -> vec[ast.ty_param] {
|
|||
ret ty_params;
|
||||
}
|
||||
|
||||
impure fn parse_fn_decl(parser p, ast.effect eff) -> ast.fn_decl {
|
||||
impure fn parse_fn_decl(parser p, ast.proto proto,
|
||||
ast.effect eff) -> ast.fn_decl {
|
||||
auto pf = parse_arg;
|
||||
let util.common.spanned[vec[ast.arg]] inputs =
|
||||
// FIXME: passing parse_arg as an lval doesn't work at the
|
||||
|
@ -1555,35 +1577,30 @@ impure fn parse_fn_decl(parser p, ast.effect eff) -> ast.fn_decl {
|
|||
} else {
|
||||
output = @spanned(inputs.span, inputs.span, ast.ty_nil);
|
||||
}
|
||||
ret rec(effect=eff, inputs=inputs.node, output=output);
|
||||
ret rec(effect=eff, proto=proto,
|
||||
inputs=inputs.node, output=output);
|
||||
}
|
||||
|
||||
impure fn parse_fn(parser p, ast.effect eff, bool is_iter) -> ast._fn {
|
||||
auto decl = parse_fn_decl(p, eff);
|
||||
impure fn parse_fn(parser p, ast.effect eff, ast.proto proto) -> ast._fn {
|
||||
auto decl = parse_fn_decl(p, proto, eff);
|
||||
auto body = parse_block(p);
|
||||
ret rec(decl = decl,
|
||||
is_iter = is_iter,
|
||||
body = body);
|
||||
}
|
||||
|
||||
impure fn parse_fn_header(parser p, bool is_iter) -> tup(span, ast.ident,
|
||||
vec[ast.ty_param]) {
|
||||
impure fn parse_fn_header(parser p)
|
||||
-> tup(span, ast.proto, ast.ident, vec[ast.ty_param]) {
|
||||
auto lo = p.get_span();
|
||||
if (is_iter) {
|
||||
expect(p, token.ITER);
|
||||
} else {
|
||||
expect(p, token.FN);
|
||||
}
|
||||
auto proto = parse_proto(p);
|
||||
auto id = parse_ident(p);
|
||||
auto ty_params = parse_ty_params(p);
|
||||
ret tup(lo, id, ty_params);
|
||||
ret tup(lo, proto, id, ty_params);
|
||||
}
|
||||
|
||||
impure fn parse_item_fn_or_iter(parser p, ast.effect eff,
|
||||
bool is_iter) -> @ast.item {
|
||||
auto t = parse_fn_header(p, is_iter);
|
||||
auto f = parse_fn(p, eff, is_iter);
|
||||
auto item = ast.item_fn(t._1, f, t._2,
|
||||
impure fn parse_item_fn_or_iter(parser p, ast.effect eff) -> @ast.item {
|
||||
auto t = parse_fn_header(p);
|
||||
auto f = parse_fn(p, eff, t._1);
|
||||
auto item = ast.item_fn(t._2, f, t._3,
|
||||
p.next_def_id(), ast.ann_none);
|
||||
ret @spanned(t._0, f.body.span, item);
|
||||
}
|
||||
|
@ -1598,14 +1615,9 @@ impure fn parse_obj_field(parser p) -> ast.obj_field {
|
|||
impure fn parse_method(parser p) -> @ast.method {
|
||||
auto lo = p.get_span();
|
||||
auto eff = parse_effect(p);
|
||||
auto is_iter = false;
|
||||
alt (p.peek()) {
|
||||
case (token.FN) { p.bump(); }
|
||||
case (token.ITER) { p.bump(); is_iter = true; }
|
||||
case (?t) { unexpected(p, t); }
|
||||
}
|
||||
auto proto = parse_proto(p);
|
||||
auto ident = parse_ident(p);
|
||||
auto f = parse_fn(p, eff, is_iter);
|
||||
auto f = parse_fn(p, eff, proto);
|
||||
auto meth = rec(ident=ident, meth=f,
|
||||
id=p.next_def_id(), ann=ast.ann_none);
|
||||
ret @spanned(lo, f.body.span, meth);
|
||||
|
@ -1689,11 +1701,11 @@ impure fn parse_item_native_type(parser p) -> @ast.native_item {
|
|||
}
|
||||
|
||||
impure fn parse_item_native_fn(parser p, ast.effect eff) -> @ast.native_item {
|
||||
auto t = parse_fn_header(p, false);
|
||||
auto decl = parse_fn_decl(p, eff);
|
||||
auto t = parse_fn_header(p);
|
||||
auto decl = parse_fn_decl(p, t._1, eff);
|
||||
auto hi = p.get_span();
|
||||
expect(p, token.SEMI);
|
||||
auto item = ast.native_item_fn(t._1, decl, t._2, p.next_def_id(),
|
||||
auto item = ast.native_item_fn(t._2, decl, t._3, p.next_def_id(),
|
||||
ast.ann_none);
|
||||
ret @spanned(t._0, hi, item);
|
||||
}
|
||||
|
@ -1883,11 +1895,11 @@ impure fn parse_item(parser p) -> @ast.item {
|
|||
|
||||
case (token.FN) {
|
||||
check (lyr == ast.layer_value);
|
||||
ret parse_item_fn_or_iter(p, eff, false);
|
||||
ret parse_item_fn_or_iter(p, eff);
|
||||
}
|
||||
case (token.ITER) {
|
||||
check (lyr == ast.layer_value);
|
||||
ret parse_item_fn_or_iter(p, eff, true);
|
||||
ret parse_item_fn_or_iter(p, eff);
|
||||
}
|
||||
case (token.MOD) {
|
||||
check (eff == ast.eff_pure);
|
||||
|
|
|
@ -59,6 +59,7 @@ type ast_fold[ENV] =
|
|||
vec[ast.ty_method] meths) -> @ty) fold_ty_obj,
|
||||
|
||||
(fn(&ENV e, &span sp,
|
||||
ast.proto proto,
|
||||
vec[rec(ast.mode mode, @ty ty)] inputs,
|
||||
@ty output) -> @ty) fold_ty_fn,
|
||||
|
||||
|
@ -252,11 +253,10 @@ type ast_fold[ENV] =
|
|||
&ast.block_) -> block) fold_block,
|
||||
|
||||
(fn(&ENV e, &fn_decl decl,
|
||||
bool is_iter,
|
||||
&block body) -> ast._fn) fold_fn,
|
||||
|
||||
(fn(&ENV e, ast.effect effect,
|
||||
vec[arg] inputs,
|
||||
ast.proto proto, vec[arg] inputs,
|
||||
@ty output) -> ast.fn_decl) fold_fn_decl,
|
||||
|
||||
(fn(&ENV e, &ast._mod m) -> ast._mod) fold_mod,
|
||||
|
@ -349,11 +349,13 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
|
|||
case (ast.ty_obj(?meths)) {
|
||||
let vec[ast.ty_method] meths_ = vec();
|
||||
for (ast.ty_method m in meths) {
|
||||
auto tfn = fold_ty_fn(env_, fld, t.span, m.inputs, m.output);
|
||||
auto tfn = fold_ty_fn(env_, fld, t.span, m.proto,
|
||||
m.inputs, m.output);
|
||||
alt (tfn.node) {
|
||||
case (ast.ty_fn(?ins, ?out)) {
|
||||
case (ast.ty_fn(?p, ?ins, ?out)) {
|
||||
append[ast.ty_method]
|
||||
(meths_, rec(inputs=ins, output=out with m));
|
||||
(meths_, rec(proto=p, inputs=ins, output=out
|
||||
with m));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -370,13 +372,14 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
|
|||
ret fld.fold_ty_mutable(env_, t.span, ty_);
|
||||
}
|
||||
|
||||
case (ast.ty_fn(?inputs, ?output)) {
|
||||
ret fold_ty_fn(env_, fld, t.span, inputs, output);
|
||||
case (ast.ty_fn(?proto, ?inputs, ?output)) {
|
||||
ret fold_ty_fn(env_, fld, t.span, proto, inputs, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty_fn[ENV](&ENV env, ast_fold[ENV] fld, &span sp,
|
||||
ast.proto proto,
|
||||
vec[rec(ast.mode mode, @ty ty)] inputs,
|
||||
@ty output) -> @ty {
|
||||
auto output_ = fold_ty(env, fld, output);
|
||||
|
@ -386,7 +389,7 @@ fn fold_ty_fn[ENV](&ENV env, ast_fold[ENV] fld, &span sp,
|
|||
auto input_ = rec(ty=ty_ with input);
|
||||
inputs_ += vec(input_);
|
||||
}
|
||||
ret fld.fold_ty_fn(env, sp, inputs_, output_);
|
||||
ret fld.fold_ty_fn(env, sp, proto, inputs_, output_);
|
||||
}
|
||||
|
||||
fn fold_decl[ENV](&ENV env, ast_fold[ENV] fld, @decl d) -> @decl {
|
||||
|
@ -754,7 +757,7 @@ fn fold_fn_decl[ENV](&ENV env, ast_fold[ENV] fld,
|
|||
inputs += fold_arg(env, fld, a);
|
||||
}
|
||||
auto output = fold_ty[ENV](env, fld, decl.output);
|
||||
ret fld.fold_fn_decl(env, decl.effect, inputs, output);
|
||||
ret fld.fold_fn_decl(env, decl.effect, decl.proto, inputs, output);
|
||||
}
|
||||
|
||||
fn fold_fn[ENV](&ENV env, ast_fold[ENV] fld, &ast._fn f) -> ast._fn {
|
||||
|
@ -762,7 +765,7 @@ fn fold_fn[ENV](&ENV env, ast_fold[ENV] fld, &ast._fn f) -> ast._fn {
|
|||
|
||||
auto body = fold_block[ENV](env, fld, f.body);
|
||||
|
||||
ret fld.fold_fn(env, decl, f.is_iter, body);
|
||||
ret fld.fold_fn(env, decl, body);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1019,9 +1022,10 @@ fn identity_fold_ty_obj[ENV](&ENV env, &span sp,
|
|||
}
|
||||
|
||||
fn identity_fold_ty_fn[ENV](&ENV env, &span sp,
|
||||
ast.proto proto,
|
||||
vec[rec(ast.mode mode, @ty ty)] inputs,
|
||||
@ty output) -> @ty {
|
||||
ret @respan(sp, ast.ty_fn(inputs, output));
|
||||
ret @respan(sp, ast.ty_fn(proto, inputs, output));
|
||||
}
|
||||
|
||||
fn identity_fold_ty_path[ENV](&ENV env, &span sp, ast.path p,
|
||||
|
@ -1301,16 +1305,16 @@ fn identity_fold_block[ENV](&ENV e, &span sp, &ast.block_ blk) -> block {
|
|||
|
||||
fn identity_fold_fn_decl[ENV](&ENV e,
|
||||
ast.effect effect,
|
||||
ast.proto proto,
|
||||
vec[arg] inputs,
|
||||
@ty output) -> ast.fn_decl {
|
||||
ret rec(effect=effect, inputs=inputs, output=output);
|
||||
ret rec(effect=effect, proto=proto, inputs=inputs, output=output);
|
||||
}
|
||||
|
||||
fn identity_fold_fn[ENV](&ENV e,
|
||||
&fn_decl decl,
|
||||
bool is_iter,
|
||||
&block body) -> ast._fn {
|
||||
ret rec(decl=decl, is_iter=is_iter, body=body);
|
||||
ret rec(decl=decl, body=body);
|
||||
}
|
||||
|
||||
fn identity_fold_mod[ENV](&ENV e, &ast._mod m) -> ast._mod {
|
||||
|
@ -1404,7 +1408,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
|
|||
fold_ty_tup = bind identity_fold_ty_tup[ENV](_,_,_),
|
||||
fold_ty_rec = bind identity_fold_ty_rec[ENV](_,_,_),
|
||||
fold_ty_obj = bind identity_fold_ty_obj[ENV](_,_,_),
|
||||
fold_ty_fn = bind identity_fold_ty_fn[ENV](_,_,_,_),
|
||||
fold_ty_fn = bind identity_fold_ty_fn[ENV](_,_,_,_,_),
|
||||
fold_ty_path = bind identity_fold_ty_path[ENV](_,_,_,_),
|
||||
fold_ty_mutable = bind identity_fold_ty_mutable[ENV](_,_,_),
|
||||
|
||||
|
@ -1470,8 +1474,8 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
|
|||
bind identity_fold_view_item_import[ENV](_,_,_,_,_,_),
|
||||
|
||||
fold_block = bind identity_fold_block[ENV](_,_,_),
|
||||
fold_fn = bind identity_fold_fn[ENV](_,_,_,_),
|
||||
fold_fn_decl = bind identity_fold_fn_decl[ENV](_,_,_,_),
|
||||
fold_fn = bind identity_fold_fn[ENV](_,_,_),
|
||||
fold_fn_decl = bind identity_fold_fn_decl[ENV](_,_,_,_,_),
|
||||
fold_mod = bind identity_fold_mod[ENV](_,_),
|
||||
fold_native_mod = bind identity_fold_native_mod[ENV](_,_),
|
||||
fold_crate = bind identity_fold_crate[ENV](_,_,_),
|
||||
|
|
|
@ -449,8 +449,7 @@ fn type_of_explicit_args(@crate_ctxt cx,
|
|||
// - trans_args
|
||||
|
||||
fn type_of_fn_full(@crate_ctxt cx,
|
||||
// FIXME: change bool flag to tag
|
||||
bool is_iter,
|
||||
ast.proto proto,
|
||||
option.t[TypeRef] obj_self,
|
||||
vec[ty.arg] inputs,
|
||||
@ty.t output) -> TypeRef {
|
||||
|
@ -480,7 +479,9 @@ fn type_of_fn_full(@crate_ctxt cx,
|
|||
// Args >3: ty params, if not acquired via capture...
|
||||
if (obj_self == none[TypeRef]) {
|
||||
auto ty_param_count =
|
||||
ty.count_ty_params(plain_ty(ty.ty_fn(inputs, output)));
|
||||
ty.count_ty_params(plain_ty(ty.ty_fn(proto,
|
||||
inputs,
|
||||
output)));
|
||||
auto i = 0u;
|
||||
while (i < ty_param_count) {
|
||||
atys += T_ptr(T_tydesc(cx.tn));
|
||||
|
@ -488,12 +489,12 @@ fn type_of_fn_full(@crate_ctxt cx,
|
|||
}
|
||||
}
|
||||
|
||||
if (is_iter) {
|
||||
if (proto == ast.proto_iter) {
|
||||
// If it's an iter, the 'output' type of the iter is actually the
|
||||
// *input* type of the function we're given as our iter-block
|
||||
// argument.
|
||||
atys += T_fn_pair(cx.tn,
|
||||
type_of_fn_full(cx, false, none[TypeRef],
|
||||
type_of_fn_full(cx, ast.proto_fn, none[TypeRef],
|
||||
vec(rec(mode=ast.val, ty=output)),
|
||||
plain_ty(ty.ty_nil)));
|
||||
}
|
||||
|
@ -505,10 +506,9 @@ fn type_of_fn_full(@crate_ctxt cx,
|
|||
}
|
||||
|
||||
fn type_of_fn(@crate_ctxt cx,
|
||||
// FIXME: change bool flag to tag
|
||||
bool is_iter,
|
||||
ast.proto proto,
|
||||
vec[ty.arg] inputs, @ty.t output) -> TypeRef {
|
||||
ret type_of_fn_full(cx, is_iter, none[TypeRef], inputs, output);
|
||||
ret type_of_fn_full(cx, proto, none[TypeRef], inputs, output);
|
||||
}
|
||||
|
||||
fn type_of_native_fn(@crate_ctxt cx, vec[ty.arg] inputs,
|
||||
|
@ -563,9 +563,8 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
|
|||
}
|
||||
ret T_struct(tys);
|
||||
}
|
||||
case (ty.ty_fn(?args, ?out)) {
|
||||
// FIXME: put iter in ty_fn.
|
||||
ret T_fn_pair(cx.tn, type_of_fn(cx, false, args, out));
|
||||
case (ty.ty_fn(?proto, ?args, ?out)) {
|
||||
ret T_fn_pair(cx.tn, type_of_fn(cx, proto, args, out));
|
||||
}
|
||||
case (ty.ty_native_fn(?args, ?out)) {
|
||||
ret T_fn_pair(cx.tn, type_of_native_fn(cx, args, out));
|
||||
|
@ -577,9 +576,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
|
|||
let vec[TypeRef] mtys = vec();
|
||||
for (ty.method m in meths) {
|
||||
let TypeRef mty =
|
||||
type_of_fn_full(cx,
|
||||
// FIXME: support method iters
|
||||
false,
|
||||
type_of_fn_full(cx, m.proto,
|
||||
some[TypeRef](self_ty),
|
||||
m.inputs, m.output);
|
||||
mtys += T_ptr(mty);
|
||||
|
@ -1339,7 +1336,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
|
|||
T_int(), C_int(0));
|
||||
}
|
||||
|
||||
case (ty.ty_fn(_,_)) {
|
||||
case (ty.ty_fn(_,_,_)) {
|
||||
fn hit_zero(@block_ctxt cx, ValueRef v) -> result {
|
||||
|
||||
// Call through the closure's own fields-drop glue first.
|
||||
|
@ -1440,7 +1437,7 @@ fn decr_refcnt_and_if_zero(@block_ctxt cx,
|
|||
fn type_of_variant(@crate_ctxt cx, &ast.variant v) -> TypeRef {
|
||||
let vec[TypeRef] lltys = vec();
|
||||
alt (ty.ann_to_type(v.ann).struct) {
|
||||
case (ty.ty_fn(?args, _)) {
|
||||
case (ty.ty_fn(_, ?args, _)) {
|
||||
for (ty.arg arg in args) {
|
||||
lltys += vec(type_of(cx, arg.ty));
|
||||
}
|
||||
|
@ -1547,7 +1544,7 @@ fn iter_structural_ty(@block_ctxt cx,
|
|||
|
||||
auto fn_ty = ty.ann_to_type(variants.(i).ann);
|
||||
alt (fn_ty.struct) {
|
||||
case (ty.ty_fn(?args, _)) {
|
||||
case (ty.ty_fn(_, ?args, _)) {
|
||||
auto llvarp = variant_cx.build.
|
||||
TruncOrBitCast(llunion_ptr,
|
||||
T_ptr(llvarty));
|
||||
|
@ -1584,7 +1581,7 @@ fn iter_structural_ty(@block_ctxt cx,
|
|||
|
||||
ret res(next_cx, C_nil());
|
||||
}
|
||||
case (ty.ty_fn(_,_)) {
|
||||
case (ty.ty_fn(_,_,_)) {
|
||||
auto box_cell =
|
||||
cx.build.GEP(v,
|
||||
vec(C_int(0),
|
||||
|
@ -2264,17 +2261,18 @@ fn trans_for_each(@block_ctxt cx,
|
|||
// pointer along with the foreach-body-fn pointer into a 'normal' fn pair
|
||||
// and pass it in as a first class fn-arg to the iterator.
|
||||
|
||||
auto foreach_llty = type_of_fn_full(cx.fcx.ccx, false, none[TypeRef],
|
||||
vec(rec(mode=ast.val, ty=decl_ty)),
|
||||
plain_ty(ty.ty_nil));
|
||||
auto iter_body_llty = type_of_fn_full(cx.fcx.ccx, ast.proto_fn,
|
||||
none[TypeRef],
|
||||
vec(rec(mode=ast.val, ty=decl_ty)),
|
||||
plain_ty(ty.ty_nil));
|
||||
|
||||
let ValueRef llforeach = decl_fastcall_fn(cx.fcx.ccx.llmod,
|
||||
s, foreach_llty);
|
||||
let ValueRef lliterbody = decl_fastcall_fn(cx.fcx.ccx.llmod,
|
||||
s, iter_body_llty);
|
||||
|
||||
// FIXME: handle ty params properly.
|
||||
let vec[ast.ty_param] ty_params = vec();
|
||||
|
||||
auto fcx = new_fn_ctxt(cx.fcx.ccx, s, llforeach);
|
||||
auto fcx = new_fn_ctxt(cx.fcx.ccx, s, lliterbody);
|
||||
auto bcx = new_top_block_ctxt(fcx);
|
||||
|
||||
// FIXME: populate lllocals from llenv here.
|
||||
|
@ -2282,13 +2280,16 @@ fn trans_for_each(@block_ctxt cx,
|
|||
res.bcx.build.RetVoid();
|
||||
|
||||
|
||||
// Step 3: Call iter passing [llforeach, llenv], plus other args.
|
||||
// Step 3: Call iter passing [lliterbody, llenv], plus other args.
|
||||
|
||||
alt (seq.node) {
|
||||
case (ast.expr_call(?f, ?args, ?ann)) {
|
||||
// FIXME_ finish here by transferring to trans_call,
|
||||
// suitably refactored.
|
||||
cx.fcx.ccx.sess.unimpl("for each loop in trans");
|
||||
|
||||
// log "lliterbody: " + val_str(cx.fcx.ccx.tn, lliterbody);
|
||||
ret trans_call(cx, f,
|
||||
some[ValueRef](lliterbody),
|
||||
args,
|
||||
ann);
|
||||
}
|
||||
}
|
||||
fail;
|
||||
|
@ -2933,6 +2934,7 @@ fn trans_args(@block_ctxt cx,
|
|||
ValueRef llenv,
|
||||
option.t[ValueRef] llobj,
|
||||
option.t[generic_info] gen,
|
||||
option.t[ValueRef] lliterbody,
|
||||
&vec[@ast.expr] es,
|
||||
@ty.t fn_ty)
|
||||
-> tup(@block_ctxt, vec[ValueRef], ValueRef) {
|
||||
|
@ -2993,6 +2995,14 @@ fn trans_args(@block_ctxt cx,
|
|||
// Args >3: ty_params ...
|
||||
llargs += lltydescs;
|
||||
|
||||
// ... then possibly an lliterbody argument.
|
||||
alt (lliterbody) {
|
||||
case (none[ValueRef]) {}
|
||||
case (some[ValueRef](?lli)) {
|
||||
llargs += lli;
|
||||
}
|
||||
}
|
||||
|
||||
// ... then explicit args.
|
||||
auto i = 0u;
|
||||
for (@ast.expr e in es) {
|
||||
|
@ -3048,7 +3058,9 @@ fn trans_args(@block_ctxt cx,
|
|||
}
|
||||
|
||||
fn trans_call(@block_ctxt cx, @ast.expr f,
|
||||
vec[@ast.expr] args, &ast.ann ann) -> result {
|
||||
option.t[ValueRef] lliterbody,
|
||||
vec[@ast.expr] args,
|
||||
&ast.ann ann) -> result {
|
||||
auto f_res = trans_lval(cx, f);
|
||||
auto faddr = f_res.res.val;
|
||||
auto llenv = C_null(T_opaque_closure_ptr(cx.fcx.ccx.tn));
|
||||
|
@ -3077,12 +3089,21 @@ fn trans_call(@block_ctxt cx, @ast.expr f,
|
|||
auto args_res = trans_args(f_res.res.bcx,
|
||||
llenv, f_res.llobj,
|
||||
f_res.generic,
|
||||
lliterbody,
|
||||
args, fn_ty);
|
||||
|
||||
auto bcx = args_res._0;
|
||||
auto llargs = args_res._1;
|
||||
auto llretslot = args_res._2;
|
||||
|
||||
/*
|
||||
log "calling: " + val_str(cx.fcx.ccx.tn, faddr);
|
||||
|
||||
for (ValueRef arg in llargs) {
|
||||
log "arg: " + val_str(cx.fcx.ccx.tn, arg);
|
||||
}
|
||||
*/
|
||||
|
||||
bcx.build.FastCall(faddr, llargs);
|
||||
auto retval = C_nil();
|
||||
|
||||
|
@ -3308,7 +3329,7 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
|
|||
}
|
||||
|
||||
case (ast.expr_call(?f, ?args, ?ann)) {
|
||||
ret trans_call(cx, f, args, ann);
|
||||
ret trans_call(cx, f, none[ValueRef], args, ann);
|
||||
}
|
||||
|
||||
case (ast.expr_cast(?e, _, ?ann)) {
|
||||
|
@ -3707,8 +3728,7 @@ fn new_fn_ctxt(@crate_ctxt cx,
|
|||
// - trans_args
|
||||
|
||||
fn create_llargs_for_fn_args(&@fn_ctxt cx,
|
||||
// FIXME: change bool flag to tag
|
||||
bool is_iter,
|
||||
ast.proto proto,
|
||||
option.t[TypeRef] ty_self,
|
||||
@ty.t ret_ty,
|
||||
&vec[ast.arg] args,
|
||||
|
@ -3733,7 +3753,7 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx,
|
|||
}
|
||||
}
|
||||
|
||||
if (is_iter) {
|
||||
if (proto == ast.proto_iter) {
|
||||
auto llarg = llvm.LLVMGetParam(cx.llfn, arg_n);
|
||||
check (llarg as int != 0);
|
||||
cx.lliterbody = some[ValueRef](llarg);
|
||||
|
@ -3794,7 +3814,7 @@ fn is_terminated(@block_ctxt cx) -> bool {
|
|||
|
||||
fn arg_tys_of_fn(ast.ann ann) -> vec[ty.arg] {
|
||||
alt (ty.ann_to_type(ann).struct) {
|
||||
case (ty.ty_fn(?arg_tys, _)) {
|
||||
case (ty.ty_fn(_, ?arg_tys, _)) {
|
||||
ret arg_tys;
|
||||
}
|
||||
}
|
||||
|
@ -3803,7 +3823,7 @@ fn arg_tys_of_fn(ast.ann ann) -> vec[ty.arg] {
|
|||
|
||||
fn ret_ty_of_fn_ty(@ty.t t) -> @ty.t {
|
||||
alt (t.struct) {
|
||||
case (ty.ty_fn(_, ?ret_ty)) {
|
||||
case (ty.ty_fn(_, _, ?ret_ty)) {
|
||||
ret ret_ty;
|
||||
}
|
||||
}
|
||||
|
@ -3875,7 +3895,7 @@ fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
|
|||
cx.item_names.insert(cx.path, llfndecl);
|
||||
|
||||
auto fcx = new_fn_ctxt(cx, cx.path, llfndecl);
|
||||
create_llargs_for_fn_args(fcx, f.is_iter,
|
||||
create_llargs_for_fn_args(fcx, f.decl.proto,
|
||||
ty_self, ret_ty_of_fn(ann),
|
||||
f.decl.inputs, ty_params);
|
||||
auto bcx = new_top_block_ctxt(fcx);
|
||||
|
@ -3915,10 +3935,8 @@ fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
|
|||
|
||||
auto llfnty = T_nil();
|
||||
alt (node_ann_type(cx, m.node.ann).struct) {
|
||||
case (ty.ty_fn(?inputs, ?output)) {
|
||||
llfnty = type_of_fn_full(cx,
|
||||
// FIXME: support method iters.
|
||||
false,
|
||||
case (ty.ty_fn(?proto, ?inputs, ?output)) {
|
||||
llfnty = type_of_fn_full(cx, proto,
|
||||
some[TypeRef](self_ty),
|
||||
inputs, output);
|
||||
}
|
||||
|
@ -3962,7 +3980,7 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
|
|||
}
|
||||
|
||||
auto fcx = new_fn_ctxt(cx, cx.path, llctor_decl);
|
||||
create_llargs_for_fn_args(fcx, false,
|
||||
create_llargs_for_fn_args(fcx, ast.proto_fn,
|
||||
none[TypeRef], ret_ty_of_fn(ann),
|
||||
fn_args, ty_params);
|
||||
|
||||
|
@ -4091,7 +4109,7 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
|
|||
let ValueRef llfndecl = cx.item_ids.get(variant.id);
|
||||
|
||||
auto fcx = new_fn_ctxt(cx, cx.path, llfndecl);
|
||||
create_llargs_for_fn_args(fcx, false,
|
||||
create_llargs_for_fn_args(fcx, ast.proto_fn,
|
||||
none[TypeRef], ret_ty_of_fn(variant.ann),
|
||||
fn_args, ty_params);
|
||||
|
||||
|
|
|
@ -19,7 +19,10 @@ import util.common.span;
|
|||
|
||||
type arg = rec(ast.mode mode, @t ty);
|
||||
type field = rec(ast.ident ident, @t ty);
|
||||
type method = rec(ast.ident ident, vec[arg] inputs, @t output);
|
||||
type method = rec(ast.proto proto,
|
||||
ast.ident ident,
|
||||
vec[arg] inputs,
|
||||
@t output);
|
||||
|
||||
// NB: If you change this, you'll probably want to change the corresponding
|
||||
// AST structure in front/ast.rs as well.
|
||||
|
@ -37,7 +40,7 @@ tag sty {
|
|||
ty_vec(@t);
|
||||
ty_tup(vec[@t]);
|
||||
ty_rec(vec[field]);
|
||||
ty_fn(vec[arg], @t); // TODO: effect
|
||||
ty_fn(ast.proto, vec[arg], @t); // TODO: effect
|
||||
ty_native_fn(vec[arg], @t); // TODO: effect
|
||||
ty_obj(vec[method]);
|
||||
ty_var(int); // ephemeral type var
|
||||
|
@ -122,9 +125,13 @@ fn ast_ty_to_str(&@ast.ty ty) -> str {
|
|||
s += ")";
|
||||
}
|
||||
|
||||
case (ast.ty_fn(?inputs, ?output)) {
|
||||
case (ast.ty_fn(?proto, ?inputs, ?output)) {
|
||||
auto f = ast_fn_input_to_str;
|
||||
s = "fn(";
|
||||
if (proto == ast.proto_fn) {
|
||||
s = "fn(";
|
||||
} else {
|
||||
s = "iter(";
|
||||
}
|
||||
auto is = _vec.map[rec(ast.mode mode, @ast.ty ty),str](f, inputs);
|
||||
s += _str.connect(is, ", ");
|
||||
s += ")";
|
||||
|
@ -175,10 +182,14 @@ fn ty_to_str(&@t typ) -> str {
|
|||
ret s + ty_to_str(input.ty);
|
||||
}
|
||||
|
||||
fn fn_to_str(option.t[ast.ident] ident,
|
||||
fn fn_to_str(ast.proto proto,
|
||||
option.t[ast.ident] ident,
|
||||
vec[arg] inputs, @t output) -> str {
|
||||
auto f = fn_input_to_str;
|
||||
auto s = "fn";
|
||||
if (proto == ast.proto_iter) {
|
||||
s = "iter";
|
||||
}
|
||||
alt (ident) {
|
||||
case (some[ast.ident](?i)) {
|
||||
s += " ";
|
||||
|
@ -198,7 +209,8 @@ fn ty_to_str(&@t typ) -> str {
|
|||
}
|
||||
|
||||
fn method_to_str(&method m) -> str {
|
||||
ret fn_to_str(some[ast.ident](m.ident), m.inputs, m.output) + ";";
|
||||
ret fn_to_str(m.proto, some[ast.ident](m.ident),
|
||||
m.inputs, m.output) + ";";
|
||||
}
|
||||
|
||||
fn field_to_str(&field f) -> str {
|
||||
|
@ -245,12 +257,12 @@ fn ty_to_str(&@t typ) -> str {
|
|||
}
|
||||
}
|
||||
|
||||
case (ty_fn(?inputs, ?output)) {
|
||||
s = fn_to_str(none[ast.ident], inputs, output);
|
||||
case (ty_fn(?proto, ?inputs, ?output)) {
|
||||
s = fn_to_str(proto, none[ast.ident], inputs, output);
|
||||
}
|
||||
|
||||
case (ty_native_fn(?inputs, ?output)) {
|
||||
s = fn_to_str(none[ast.ident], inputs, output);
|
||||
s = fn_to_str(ast.proto_fn, none[ast.ident], inputs, output);
|
||||
}
|
||||
|
||||
case (ty_obj(?meths)) {
|
||||
|
@ -326,13 +338,13 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
|
|||
}
|
||||
ret rewrap(ty, ty_rec(new_fields));
|
||||
}
|
||||
case (ty_fn(?args, ?ret_ty)) {
|
||||
case (ty_fn(?proto, ?args, ?ret_ty)) {
|
||||
let vec[arg] new_args = vec();
|
||||
for (arg a in args) {
|
||||
auto new_ty = fold_ty(fld, a.ty);
|
||||
new_args += vec(rec(mode=a.mode, ty=new_ty));
|
||||
}
|
||||
ret rewrap(ty, ty_fn(new_args, fold_ty(fld, ret_ty)));
|
||||
ret rewrap(ty, ty_fn(proto, new_args, fold_ty(fld, ret_ty)));
|
||||
}
|
||||
case (ty_obj(?methods)) {
|
||||
let vec[method] new_methods = vec();
|
||||
|
@ -341,7 +353,8 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
|
|||
for (arg a in m.inputs) {
|
||||
new_args += vec(rec(mode=a.mode, ty=fold_ty(fld, a.ty)));
|
||||
}
|
||||
new_methods += vec(rec(ident=m.ident, inputs=new_args,
|
||||
new_methods += vec(rec(proto=m.proto, ident=m.ident,
|
||||
inputs=new_args,
|
||||
output=fold_ty(fld, m.output)));
|
||||
}
|
||||
ret rewrap(ty, ty_obj(new_methods));
|
||||
|
@ -378,7 +391,7 @@ fn type_is_structural(@t ty) -> bool {
|
|||
case (ty_tup(_)) { ret true; }
|
||||
case (ty_rec(_)) { ret true; }
|
||||
case (ty_tag(_,_)) { ret true; }
|
||||
case (ty_fn(_,_)) { ret true; }
|
||||
case (ty_fn(_,_,_)) { ret true; }
|
||||
case (ty_obj(_)) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
|
@ -573,23 +586,29 @@ fn count_ty_params(@t ty) -> uint {
|
|||
// Type accessors for substructures of types
|
||||
|
||||
fn ty_fn_args(@t fty) -> vec[arg] {
|
||||
alt (fty.struct) {
|
||||
case (ty.ty_fn(?a, _)) { ret a; }
|
||||
}
|
||||
alt (fty.struct) {
|
||||
case (ty.ty_fn(_, ?a, _)) { ret a; }
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_fn_proto(@t fty) -> ast.proto {
|
||||
alt (fty.struct) {
|
||||
case (ty.ty_fn(?p, _, _)) { ret p; }
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_fn_ret(@t fty) -> @t {
|
||||
alt (fty.struct) {
|
||||
case (ty.ty_fn(_, ?r)) { ret r; }
|
||||
}
|
||||
alt (fty.struct) {
|
||||
case (ty.ty_fn(_, _, ?r)) { ret r; }
|
||||
}
|
||||
}
|
||||
|
||||
fn is_fn_ty(@t fty) -> bool {
|
||||
alt (fty.struct) {
|
||||
case (ty.ty_fn(_, _)) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
ret false;
|
||||
alt (fty.struct) {
|
||||
case (ty.ty_fn(_, _, _)) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
ret false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -808,80 +827,87 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
|
|||
}
|
||||
|
||||
fn unify_fn(@hashmap[int,@ty.t] bindings,
|
||||
ast.proto e_proto,
|
||||
ast.proto a_proto,
|
||||
@ty.t expected,
|
||||
@ty.t actual,
|
||||
&unify_handler handler,
|
||||
vec[arg] expected_inputs, @t expected_output,
|
||||
vec[arg] actual_inputs, @t actual_output)
|
||||
-> unify_result {
|
||||
auto expected_len = _vec.len[arg](expected_inputs);
|
||||
auto actual_len = _vec.len[arg](actual_inputs);
|
||||
if (expected_len != actual_len) {
|
||||
ret ures_err(terr_arg_count, expected, actual);
|
||||
}
|
||||
-> unify_result {
|
||||
|
||||
// TODO: as above, we should have an iter2 iterator.
|
||||
let vec[arg] result_ins = vec();
|
||||
auto i = 0u;
|
||||
while (i < expected_len) {
|
||||
auto expected_input = expected_inputs.(i);
|
||||
auto actual_input = actual_inputs.(i);
|
||||
|
||||
// This should be safe, I think?
|
||||
auto result_mode;
|
||||
if (mode_is_alias(expected_input.mode) ||
|
||||
mode_is_alias(actual_input.mode)) {
|
||||
result_mode = ast.alias;
|
||||
} else {
|
||||
result_mode = ast.val;
|
||||
if (e_proto != a_proto) {
|
||||
ret ures_err(terr_mismatch, expected, actual);
|
||||
}
|
||||
|
||||
auto expected_len = _vec.len[arg](expected_inputs);
|
||||
auto actual_len = _vec.len[arg](actual_inputs);
|
||||
if (expected_len != actual_len) {
|
||||
ret ures_err(terr_arg_count, expected, actual);
|
||||
}
|
||||
|
||||
// TODO: as above, we should have an iter2 iterator.
|
||||
let vec[arg] result_ins = vec();
|
||||
auto i = 0u;
|
||||
while (i < expected_len) {
|
||||
auto expected_input = expected_inputs.(i);
|
||||
auto actual_input = actual_inputs.(i);
|
||||
|
||||
// This should be safe, I think?
|
||||
auto result_mode;
|
||||
if (mode_is_alias(expected_input.mode) ||
|
||||
mode_is_alias(actual_input.mode)) {
|
||||
result_mode = ast.alias;
|
||||
} else {
|
||||
result_mode = ast.val;
|
||||
}
|
||||
|
||||
auto result = unify_step(bindings,
|
||||
actual_input.ty,
|
||||
expected_input.ty,
|
||||
handler);
|
||||
|
||||
alt (result) {
|
||||
case (ures_ok(?rty)) {
|
||||
result_ins += vec(rec(mode=result_mode,
|
||||
ty=rty));
|
||||
}
|
||||
|
||||
case (_) {
|
||||
ret result;
|
||||
}
|
||||
}
|
||||
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
// Check the output.
|
||||
auto result_out;
|
||||
auto result = unify_step(bindings,
|
||||
actual_input.ty,
|
||||
expected_input.ty,
|
||||
expected_output,
|
||||
actual_output,
|
||||
handler);
|
||||
|
||||
alt (result) {
|
||||
case (ures_ok(?rty)) {
|
||||
result_ins += vec(rec(mode=result_mode,
|
||||
ty=rty));
|
||||
}
|
||||
case (ures_ok(?rty)) {
|
||||
result_out = rty;
|
||||
}
|
||||
|
||||
case (_) {
|
||||
ret result;
|
||||
}
|
||||
case (_) {
|
||||
ret result;
|
||||
}
|
||||
}
|
||||
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
// Check the output.
|
||||
auto result_out;
|
||||
auto result = unify_step(bindings,
|
||||
expected_output,
|
||||
actual_output,
|
||||
handler);
|
||||
alt (result) {
|
||||
case (ures_ok(?rty)) {
|
||||
result_out = rty;
|
||||
}
|
||||
|
||||
case (_) {
|
||||
ret result;
|
||||
}
|
||||
}
|
||||
|
||||
auto t = plain_ty(ty.ty_fn(result_ins, result_out));
|
||||
ret ures_ok(t);
|
||||
auto t = plain_ty(ty.ty_fn(e_proto, result_ins, result_out));
|
||||
ret ures_ok(t);
|
||||
|
||||
}
|
||||
|
||||
fn unify_obj(@hashmap[int,@ty.t] bindings,
|
||||
@ty.t expected,
|
||||
@ty.t actual,
|
||||
&unify_handler handler,
|
||||
vec[method] expected_meths,
|
||||
vec[method] actual_meths) -> unify_result {
|
||||
@ty.t expected,
|
||||
@ty.t actual,
|
||||
&unify_handler handler,
|
||||
vec[method] expected_meths,
|
||||
vec[method] actual_meths) -> unify_result {
|
||||
let vec[method] result_meths = vec();
|
||||
let uint i = 0u;
|
||||
let uint expected_len = _vec.len[method](expected_meths);
|
||||
|
@ -893,28 +919,28 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
|
|||
|
||||
// FIXME: work around buggy typestate logic for 'alt', sigh.
|
||||
fn is_ok(&unify_result r) -> bool {
|
||||
alt (r) {
|
||||
case (ures_ok(?tfn)) {
|
||||
ret true;
|
||||
alt (r) {
|
||||
case (ures_ok(?tfn)) {
|
||||
ret true;
|
||||
}
|
||||
case (_) {}
|
||||
}
|
||||
case (_) {}
|
||||
}
|
||||
ret false;
|
||||
ret false;
|
||||
}
|
||||
|
||||
fn append_if_ok(&method e_meth,
|
||||
&unify_result r, &mutable vec[method] result_meths) {
|
||||
alt (r) {
|
||||
case (ures_ok(?tfn)) {
|
||||
alt (tfn.struct) {
|
||||
case (ty_fn(?ins, ?out)) {
|
||||
result_meths += vec(rec(inputs = ins,
|
||||
output = out
|
||||
with e_meth));
|
||||
alt (r) {
|
||||
case (ures_ok(?tfn)) {
|
||||
alt (tfn.struct) {
|
||||
case (ty_fn(?proto, ?ins, ?out)) {
|
||||
result_meths += vec(rec(inputs = ins,
|
||||
output = out
|
||||
with e_meth));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (i < expected_len) {
|
||||
|
@ -924,7 +950,9 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
|
|||
ret ures_err(terr_obj_meths(e_meth.ident, a_meth.ident),
|
||||
expected, actual);
|
||||
}
|
||||
auto r = unify_fn(bindings, expected, actual, handler,
|
||||
auto r = unify_fn(bindings,
|
||||
e_meth.proto, a_meth.proto,
|
||||
expected, actual, handler,
|
||||
e_meth.inputs, e_meth.output,
|
||||
a_meth.inputs, a_meth.output);
|
||||
if (!is_ok(r)) {
|
||||
|
@ -1215,12 +1243,13 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
|
|||
}
|
||||
}
|
||||
|
||||
case (ty.ty_fn(?expected_inputs, ?expected_output)) {
|
||||
case (ty.ty_fn(?ep, ?expected_inputs, ?expected_output)) {
|
||||
alt (actual.struct) {
|
||||
case (ty.ty_fn(?actual_inputs, ?actual_output)) {
|
||||
ret unify_fn(bindings, expected, actual, handler,
|
||||
expected_inputs, expected_output,
|
||||
actual_inputs, actual_output);
|
||||
case (ty.ty_fn(?ap, ?actual_inputs, ?actual_output)) {
|
||||
ret unify_fn(bindings, ep, ap,
|
||||
expected, actual, handler,
|
||||
expected_inputs, expected_output,
|
||||
actual_inputs, actual_output);
|
||||
}
|
||||
|
||||
case (_) {
|
||||
|
@ -1230,15 +1259,15 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
|
|||
}
|
||||
|
||||
case (ty.ty_obj(?expected_meths)) {
|
||||
alt (actual.struct) {
|
||||
case (ty.ty_obj(?actual_meths)) {
|
||||
ret unify_obj(bindings, expected, actual, handler,
|
||||
expected_meths, actual_meths);
|
||||
alt (actual.struct) {
|
||||
case (ty.ty_obj(?actual_meths)) {
|
||||
ret unify_obj(bindings, expected, actual, handler,
|
||||
expected_meths, actual_meths);
|
||||
}
|
||||
case (_) {
|
||||
ret ures_err(terr_mismatch, expected, actual);
|
||||
}
|
||||
}
|
||||
case (_) {
|
||||
ret ures_err(terr_mismatch, expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case (ty.ty_var(?expected_id)) {
|
||||
|
|
|
@ -155,10 +155,10 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
|
|||
sty = ty.ty_rec(flds);
|
||||
}
|
||||
|
||||
case (ast.ty_fn(?inputs, ?output)) {
|
||||
case (ast.ty_fn(?proto, ?inputs, ?output)) {
|
||||
auto f = bind ast_arg_to_arg(getter, _);
|
||||
auto i = _vec.map[ast.ty_arg, arg](f, inputs);
|
||||
sty = ty.ty_fn(i, ast_ty_to_ty(getter, output));
|
||||
sty = ty.ty_fn(proto, i, ast_ty_to_ty(getter, output));
|
||||
}
|
||||
|
||||
case (ast.ty_path(?path, ?def)) {
|
||||
|
@ -194,7 +194,8 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
|
|||
auto ins = _vec.map[ast.ty_arg, arg](f, m.inputs);
|
||||
auto out = ast_ty_to_ty(getter, m.output);
|
||||
append[ty.method](tmeths,
|
||||
rec(ident=m.ident,
|
||||
rec(proto=m.proto,
|
||||
ident=m.ident,
|
||||
inputs=ins,
|
||||
output=out));
|
||||
}
|
||||
|
@ -295,7 +296,7 @@ fn ty_of_fn_decl(@ty_item_table id_to_ty_item,
|
|||
ast.def_id def_id) -> @ty.t {
|
||||
auto input_tys = _vec.map[ast.arg,arg](ty_of_arg, decl.inputs);
|
||||
auto output_ty = convert(decl.output);
|
||||
auto t_fn = plain_ty(ty.ty_fn(input_tys, output_ty));
|
||||
auto t_fn = plain_ty(ty.ty_fn(decl.proto, input_tys, output_ty));
|
||||
item_to_ty.insert(def_id, t_fn);
|
||||
ret t_fn;
|
||||
}
|
||||
|
@ -354,7 +355,8 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
auto f = bind ty_of_arg(id_to_ty_item, item_to_ty, _);
|
||||
auto inputs = _vec.map[ast.arg,arg](f, m.node.meth.decl.inputs);
|
||||
auto output = convert(m.node.meth.decl.output);
|
||||
ret rec(ident=m.node.ident, inputs=inputs, output=output);
|
||||
ret rec(proto=m.node.meth.decl.proto, ident=m.node.ident,
|
||||
inputs=inputs, output=output);
|
||||
}
|
||||
|
||||
fn ty_of_obj(@ty_item_table id_to_ty_item,
|
||||
|
@ -385,7 +387,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
auto t_field = ast_ty_to_ty(g, f.ty);
|
||||
append[arg](t_inputs, rec(mode=ast.alias, ty=t_field));
|
||||
}
|
||||
auto t_fn = plain_ty(ty.ty_fn(t_inputs, t_obj));
|
||||
auto t_fn = plain_ty(ty.ty_fn(ast.proto_fn, t_inputs, t_obj));
|
||||
ret t_fn;
|
||||
}
|
||||
|
||||
|
@ -501,7 +503,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
args += vec(rec(mode=ast.alias, ty=arg_ty));
|
||||
}
|
||||
auto tag_t = plain_ty(ty.ty_tag(tag_id, ty_param_tys));
|
||||
result_ty = plain_ty(ty.ty_fn(args, tag_t));
|
||||
result_ty = plain_ty(ty.ty_fn(ast.proto_fn, args, tag_t));
|
||||
}
|
||||
|
||||
item_to_ty.insert(variant.id, result_ty);
|
||||
|
@ -615,7 +617,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
|
||||
fn get_ctor_obj_methods(@ty.t t) -> vec[method] {
|
||||
alt (t.struct) {
|
||||
case (ty.ty_fn(_,?tobj)) {
|
||||
case (ty.ty_fn(_,_,?tobj)) {
|
||||
alt (tobj.struct) {
|
||||
case (ty.ty_obj(?tm)) {
|
||||
ret tm;
|
||||
|
@ -650,7 +652,8 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
let method meth_ty = meth_tys.(ix);
|
||||
let ast.method_ m_;
|
||||
let @ast.method m;
|
||||
auto meth_tfn = plain_ty(ty.ty_fn(meth_ty.inputs,
|
||||
auto meth_tfn = plain_ty(ty.ty_fn(meth_ty.proto,
|
||||
meth_ty.inputs,
|
||||
meth_ty.output));
|
||||
m_ = rec(ann=ast.ann_type(meth_tfn) with meth.node);
|
||||
m = @rec(node=m_ with *meth);
|
||||
|
@ -877,7 +880,7 @@ fn demand_pat(&@fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
|
|||
check (subpats_len == 0u);
|
||||
p_1 = ast.pat_tag(id, subpats, vdef_opt, ast.ann_type(t));
|
||||
}
|
||||
case (ty.ty_fn(?args, ?tag_ty)) {
|
||||
case (ty.ty_fn(_, ?args, ?tag_ty)) {
|
||||
let vec[@ast.pat] new_subpats = vec();
|
||||
auto i = 0u;
|
||||
for (arg a in args) {
|
||||
|
@ -1189,7 +1192,7 @@ fn check_pat(&@fn_ctxt fcx, @ast.pat pat) -> @ast.pat {
|
|||
auto last_id = p.node.idents.(len - 1u);
|
||||
alt (t.struct) {
|
||||
// N-ary variants have function types.
|
||||
case (ty.ty_fn(?args, ?tag_ty)) {
|
||||
case (ty.ty_fn(_, ?args, ?tag_ty)) {
|
||||
auto arg_len = _vec.len[arg](args);
|
||||
auto subpats_len = _vec.len[@ast.pat](subpats);
|
||||
if (arg_len != subpats_len) {
|
||||
|
@ -1628,6 +1631,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
|||
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();
|
||||
|
@ -1654,7 +1658,8 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
|||
i += 1u;
|
||||
}
|
||||
|
||||
let @ty.t t_1 = plain_ty(ty.ty_fn(residual_args, rt_0));
|
||||
let @ty.t t_1 = plain_ty(ty.ty_fn(proto,
|
||||
residual_args, rt_0));
|
||||
ret @fold.respan[ast.expr_](expr.span,
|
||||
ast.expr_bind(f_0, args_1,
|
||||
ast.ann_type(t_1)));
|
||||
|
@ -1677,7 +1682,8 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
|||
append[arg](arg_tys_0, rec(mode=ast.val, ty=expr_ty(a_0)));
|
||||
}
|
||||
auto rt_0 = next_ty_var(fcx.ccx);
|
||||
auto t_0 = plain_ty(ty.ty_fn(arg_tys_0, rt_0));
|
||||
auto t_0 = plain_ty(ty.ty_fn(ty.ty_fn_proto(expr_ty(f_0)),
|
||||
arg_tys_0, rt_0));
|
||||
|
||||
// Unify and write back to the function.
|
||||
auto f_1 = demand_expr(fcx, t_0, f_0);
|
||||
|
@ -1877,7 +1883,8 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
|||
"bad index on obj");
|
||||
}
|
||||
auto meth = methods.(ix);
|
||||
auto t = plain_ty(ty.ty_fn(meth.inputs, meth.output));
|
||||
auto t = plain_ty(ty.ty_fn(meth.proto,
|
||||
meth.inputs, meth.output));
|
||||
auto ann = ast.ann_type(t);
|
||||
ret @fold.respan[ast.expr_](expr.span,
|
||||
ast.expr_field(base_1,
|
||||
|
@ -2047,8 +2054,7 @@ fn check_const(&@crate_ctxt ccx, &span sp, ast.ident ident, @ast.ty t,
|
|||
ret @fold.respan[ast.item_](sp, item);
|
||||
}
|
||||
|
||||
fn check_fn(&@crate_ctxt ccx, &ast.fn_decl decl,
|
||||
bool is_iter, &ast.block body) -> ast._fn {
|
||||
fn check_fn(&@crate_ctxt ccx, &ast.fn_decl decl, &ast.block body) -> ast._fn {
|
||||
auto local_ty_table = @common.new_def_hash[@ty.t]();
|
||||
|
||||
// FIXME: duplicate work: the item annotation already has the arg types
|
||||
|
@ -2075,8 +2081,8 @@ fn check_fn(&@crate_ctxt ccx, &ast.fn_decl decl,
|
|||
auto block_t = check_block(fcx, body);
|
||||
auto block_wb = writeback(fcx, block_t);
|
||||
|
||||
auto fn_t = rec(decl=decl, is_iter=is_iter,
|
||||
body=block_wb);
|
||||
auto fn_t = rec(decl=decl,
|
||||
body=block_wb);
|
||||
ret fn_t;
|
||||
}
|
||||
|
||||
|
@ -2095,7 +2101,7 @@ fn check_item_fn(&@crate_ctxt ccx, &span sp, ast.ident ident, &ast._fn f,
|
|||
}
|
||||
|
||||
auto output_ty = ast_ty_to_ty_crate(ccx, f.decl.output);
|
||||
auto fn_sty = ty.ty_fn(inputs, output_ty);
|
||||
auto fn_sty = ty.ty_fn(f.decl.proto, inputs, output_ty);
|
||||
auto fn_ann = ast.ann_type(plain_ty(fn_sty));
|
||||
|
||||
auto item = ast.item_fn(ident, f, ty_params, id, fn_ann);
|
||||
|
@ -2127,7 +2133,7 @@ fn check_crate(session.session sess, @ast.crate crate) -> @ast.crate {
|
|||
auto fld = fold.new_identity_fold[@crate_ctxt]();
|
||||
|
||||
fld = @rec(update_env_for_item = bind update_obj_fields(_, _),
|
||||
fold_fn = bind check_fn(_,_,_,_),
|
||||
fold_fn = bind check_fn(_,_,_),
|
||||
fold_item_fn = bind check_item_fn(_,_,_,_,_,_,_)
|
||||
with *fld);
|
||||
ret fold.fold_crate[@crate_ctxt](ccx, fld, result._0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue