diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 7b22e700682..1220d6abf6d 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -201,10 +201,11 @@ tag ty_ { } type arg = rec(mode mode, @ty ty, ident ident, def_id id); -type _fn = rec(effect effect, +type fn_decl = rec(effect effect, + vec[arg] inputs, + @ty output); +type _fn = rec(fn_decl decl, bool is_iter, - vec[arg] inputs, - @ty output, block body); @@ -254,6 +255,7 @@ tag item_ { type native_item = spanned[native_item_]; tag native_item_ { native_item_ty(ident, def_id); + native_item_fn(ident, fn_decl, vec[ty_param], def_id); } fn index_view_item(mod_index index, @view_item it) { @@ -304,6 +306,9 @@ fn index_native_item(native_mod_index index, @native_item it) { case (ast.native_item_ty(?id, _)) { index.insert(id, it); } + case (ast.native_item_fn(?id, _, _, _)) { + index.insert(id, it); + } } } diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 1d54a6e15ff..e04b82214b8 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -1441,7 +1441,7 @@ impure fn parse_ty_params(parser p) -> vec[ast.ty_param] { ret ty_params; } -impure fn parse_fn(parser p, ast.effect eff, bool is_iter) -> ast._fn { +impure fn parse_fn_decl(parser p, 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 @@ -1459,18 +1459,19 @@ impure fn parse_fn(parser p, ast.effect eff, bool is_iter) -> ast._fn { } else { output = @spanned(inputs.span, inputs.span, ast.ty_nil); } + ret rec(effect=eff, 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); auto body = parse_block(p); - - ret rec(effect = eff, + ret rec(decl = decl, is_iter = is_iter, - inputs = inputs.node, - output = output, body = body); } -impure fn parse_item_fn_or_iter(parser p, ast.effect eff, - bool is_iter) -> @ast.item { +impure fn parse_fn_header(parser p, bool is_iter) -> tup(span, ast.ident, + vec[ast.ty_param]) { auto lo = p.get_span(); if (is_iter) { expect(p, token.ITER); @@ -1479,10 +1480,16 @@ impure fn parse_item_fn_or_iter(parser p, ast.effect eff, } auto id = parse_ident(p); auto ty_params = parse_ty_params(p); + ret tup(lo, 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(id, f, ty_params, + auto item = ast.item_fn(t._1, f, t._2, p.next_def_id(), ast.ann_none); - ret @spanned(lo, f.body.span, item); + ret @spanned(t._0, f.body.span, item); } @@ -1585,11 +1592,24 @@ impure fn parse_item_native_type(parser p) -> @ast.native_item { ret @spanned(t._0, hi, 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 hi = p.get_span(); + expect(p, token.SEMI); + auto item = ast.native_item_fn(t._1, decl, t._2, p.next_def_id()); + ret @spanned(t._0, hi, item); +} + impure fn parse_native_item(parser p) -> @ast.native_item { + let ast.effect eff = parse_effect(p); alt (p.peek()) { case (token.TYPE) { ret parse_item_native_type(p); } + case (token.FN) { + ret parse_item_native_fn(p, eff); + } } } diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index b9027836afb..688d21d20a3 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -10,6 +10,7 @@ import util.common.ty_mach; import util.common.append; import front.ast; +import front.ast.fn_decl; import front.ast.ident; import front.ast.path; import front.ast.mutability; @@ -194,6 +195,11 @@ type ast_fold[ENV] = vec[ast.ty_param] ty_params, def_id id, ann a) -> @item) fold_item_fn, + (fn(&ENV e, &span sp, ident ident, + &ast.fn_decl decl, + vec[ast.ty_param] ty_params, + def_id id) -> @native_item) fold_native_item_fn, + (fn(&ENV e, &span sp, ident ident, &ast._mod m, def_id id) -> @item) fold_item_mod, @@ -229,10 +235,13 @@ type ast_fold[ENV] = (fn(&ENV e, &span sp, &ast.block_) -> block) fold_block, - (fn(&ENV e, ast.effect effect, + (fn(&ENV e, &fn_decl decl, bool is_iter, + &block body) -> ast._fn) fold_fn, + + (fn(&ENV e, ast.effect effect, vec[arg] inputs, - @ty output, &block body) -> ast._fn) fold_fn, + @ty output) -> ast.fn_decl) fold_fn_decl, (fn(&ENV e, &ast._mod m) -> ast._mod) fold_mod, @@ -688,17 +697,22 @@ fn fold_arg[ENV](&ENV env, ast_fold[ENV] fld, &arg a) -> arg { ret rec(ty=ty with a); } - -fn fold_fn[ENV](&ENV env, ast_fold[ENV] fld, &ast._fn f) -> ast._fn { - +fn fold_fn_decl[ENV](&ENV env, ast_fold[ENV] fld, + &ast.fn_decl decl) -> ast.fn_decl { let vec[ast.arg] inputs = vec(); - for (ast.arg a in f.inputs) { + for (ast.arg a in decl.inputs) { inputs += fold_arg(env, fld, a); } - auto output = fold_ty[ENV](env, fld, f.output); + auto output = fold_ty[ENV](env, fld, decl.output); + ret fld.fold_fn_decl(env, decl.effect, inputs, output); +} + +fn fold_fn[ENV](&ENV env, ast_fold[ENV] fld, &ast._fn f) -> ast._fn { + auto decl = fold_fn_decl(env, fld, f.decl); + auto body = fold_block[ENV](env, fld, f.body); - ret fld.fold_fn(env, f.effect, f.is_iter, inputs, output, body); + ret fld.fold_fn(env, decl, f.is_iter, body); } @@ -857,6 +871,10 @@ fn fold_native_item[ENV](&ENV env, ast_fold[ENV] fld, case (ast.native_item_ty(?ident, ?id)) { ret fld.fold_native_item_ty(env_, i.span, ident, id); } + case (ast.native_item_fn(?ident, ?fn_decl, ?ty_params, ?id)) { + ret fld.fold_native_item_fn(env_, i.span, ident, fn_decl, + ty_params, id); + } } } @@ -1144,6 +1162,13 @@ fn identity_fold_item_fn[ENV](&ENV e, &span sp, ident i, ret @respan(sp, ast.item_fn(i, f, ty_params, id, a)); } +fn identity_fold_native_item_fn[ENV](&ENV e, &span sp, ident i, + &ast.fn_decl decl, + vec[ast.ty_param] ty_params, + def_id id) -> @native_item { + ret @respan(sp, ast.native_item_fn(i, decl, ty_params, id)); +} + fn identity_fold_item_mod[ENV](&ENV e, &span sp, ident i, &ast._mod m, def_id id) -> @item { ret @respan(sp, ast.item_mod(i, m, id)); @@ -1199,14 +1224,18 @@ fn identity_fold_block[ENV](&ENV e, &span sp, &ast.block_ blk) -> block { ret respan(sp, blk); } +fn identity_fold_fn_decl[ENV](&ENV e, + ast.effect effect, + vec[arg] inputs, + @ty output) -> ast.fn_decl { + ret rec(effect=effect, inputs=inputs, output=output); +} + fn identity_fold_fn[ENV](&ENV e, - ast.effect effect, + &fn_decl decl, bool is_iter, - vec[arg] inputs, - @ast.ty output, &block body) -> ast._fn { - ret rec(effect=effect, is_iter=is_iter, inputs=inputs, - output=output, body=body); + ret rec(decl=decl, is_iter=is_iter, body=body); } fn identity_fold_mod[ENV](&ENV e, &ast._mod m) -> ast._mod { @@ -1343,6 +1372,8 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] { fold_item_const= bind identity_fold_item_const[ENV](_,_,_,_,_,_,_), fold_item_fn = bind identity_fold_item_fn[ENV](_,_,_,_,_,_,_), + fold_native_item_fn = + bind identity_fold_native_item_fn[ENV](_,_,_,_,_,_), fold_item_mod = bind identity_fold_item_mod[ENV](_,_,_,_,_), fold_item_native_mod = bind identity_fold_item_native_mod[ENV](_,_,_,_,_), @@ -1358,7 +1389,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 = 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](_,_,_), diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 1af3b20596c..2cfbcc83eac 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -283,7 +283,7 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] { case (scope_item(?it)) { alt (it.node) { case (ast.item_fn(_, ?f, ?ty_params, _, _)) { - for (ast.arg a in f.inputs) { + for (ast.arg a in f.decl.inputs) { if (_str.eq(a.ident, i)) { auto t = ast.def_arg(a.id); ret some(def_wrap_other(t)); diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 4610cef631c..22f4109fd10 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3553,10 +3553,10 @@ fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid, auto fcx = new_fn_ctxt(cx, cx.path, llfndecl); create_llargs_for_fn_args(fcx, ty_self, ret_ty_of_fn(ann), - f.inputs, ty_params); + f.decl.inputs, ty_params); auto bcx = new_top_block_ctxt(fcx); - copy_args_to_allocas(bcx, ty_self, f.inputs, + copy_args_to_allocas(bcx, ty_self, f.decl.inputs, arg_tys_of_fn(ann)); alt (fcx.llself) { diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 43d35b37041..5412f13135e 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -285,8 +285,8 @@ fn collect_item_types(session.session sess, @ast.crate crate) auto get = bind getter(id_to_ty_item, item_to_ty, _); auto convert = bind ast_ty_to_ty(get, _); auto f = bind ty_of_arg(id_to_ty_item, item_to_ty, _); - auto inputs = _vec.map[ast.arg,arg](f, m.node.meth.inputs); - auto output = convert(m.node.meth.output); + 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); } @@ -339,8 +339,9 @@ fn collect_item_types(session.session sess, @ast.crate crate) // TODO: handle ty-params auto f = bind ty_of_arg(id_to_ty_item, item_to_ty, _); - auto input_tys = _vec.map[ast.arg,arg](f, fn_info.inputs); - auto output_ty = convert(fn_info.output); + auto input_tys = _vec.map[ast.arg,arg](f, + fn_info.decl.inputs); + auto output_ty = convert(fn_info.decl.output); auto t_fn = plain_ty(ty.ty_fn(input_tys, output_ty)); item_to_ty.insert(def_id, t_fn); @@ -1773,9 +1774,8 @@ 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.effect effect, - bool is_iter, vec[ast.arg] inputs, - @ast.ty output, &ast.block body) -> ast._fn { +fn check_fn(&@crate_ctxt ccx, &ast.fn_decl decl, + bool is_iter, &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 @@ -1789,12 +1789,12 @@ fn check_fn(&@crate_ctxt ccx, ast.effect effect, } // Store the type of each argument in the table. - for (ast.arg arg in inputs) { + for (ast.arg arg in decl.inputs) { auto input_ty = ast_ty_to_ty_crate(ccx, arg.ty); local_ty_table.insert(arg.id, input_ty); } - let @fn_ctxt fcx = @rec(ret_ty = ast_ty_to_ty_crate(ccx, output), + let @fn_ctxt fcx = @rec(ret_ty = ast_ty_to_ty_crate(ccx, decl.output), locals = local_ty_table, ccx = ccx); @@ -1802,8 +1802,8 @@ fn check_fn(&@crate_ctxt ccx, ast.effect effect, auto block_t = check_block(fcx, body); auto block_wb = writeback(fcx, block_t); - auto fn_t = rec(effect=effect, is_iter=is_iter, - inputs=inputs, output=output, body=block_wb); + auto fn_t = rec(decl=decl, is_iter=is_iter, + body=block_wb); ret fn_t; } @@ -1816,12 +1816,12 @@ fn check_item_fn(&@crate_ctxt ccx, &span sp, ast.ident ident, &ast._fn f, // again here, we can extract them. let vec[arg] inputs = vec(); - for (ast.arg arg in f.inputs) { + for (ast.arg arg in f.decl.inputs) { auto input_ty = ast_ty_to_ty_crate(ccx, arg.ty); inputs += vec(rec(mode=arg.mode, ty=input_ty)); } - auto output_ty = ast_ty_to_ty_crate(ccx, f.output); + auto output_ty = ast_ty_to_ty_crate(ccx, f.decl.output); auto fn_sty = ty.ty_fn(inputs, output_ty); auto fn_ann = ast.ann_type(plain_ty(fn_sty)); @@ -1854,7 +1854,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); diff --git a/src/test/run-pass/native2.rs b/src/test/run-pass/native2.rs index b848ec8c9a3..a6df93f5d87 100644 --- a/src/test/run-pass/native2.rs +++ b/src/test/run-pass/native2.rs @@ -1,5 +1,6 @@ native "rust" mod rustrt { type vbuf; + fn vec_buf[T](vec[T] v, uint offset) -> vbuf; } fn main(vec[str] args) {