Remove mod indices from the AST

They are now created by the resolve pass, which is the only pass that
needs them, and kept internal to that pass.
This commit is contained in:
Marijn Haverbeke 2011-05-11 16:30:48 +02:00
parent 5bea22d75c
commit 14f1fe0e29
6 changed files with 165 additions and 202 deletions

View File

@ -360,21 +360,8 @@ fn unop_to_str(unop op) -> str {
vec[@method] methods,
Option.t[@method] dtor);
tag mod_index_entry {
mie_view_item(@view_item);
mie_item(@item);
mie_tag_variant(@item /* tag item */, uint /* variant index */);
}
tag native_mod_index_entry {
nmie_view_item(@view_item);
nmie_item(@native_item);
}
type mod_index = hashmap[ident,mod_index_entry];
type _mod = rec(vec[@view_item] view_items,
vec[@item] items,
mod_index index);
vec[@item] items);
tag native_abi {
native_abi_rust;
@ -386,9 +373,7 @@ fn unop_to_str(unop op) -> str {
type native_mod = rec(str native_name,
native_abi abi,
vec[@view_item] view_items,
vec[@native_item] items,
native_mod_index index);
type native_mod_index = hashmap[ident,native_mod_index_entry];
vec[@native_item] items);
type variant_arg = rec(@ty ty, def_id id);
type variant_ = rec(str name, vec[variant_arg] args, def_id id, ann ann);
@ -433,78 +418,6 @@ fn item_ident(@item it) -> ident {
fn_decl, vec[ty_param], def_id, ann);
}
fn index_view_item(mod_index index, @view_item it) {
alt (it.node) {
case(ast.view_item_use(?id, _, _, _)) {
index.insert(id, ast.mie_view_item(it));
}
case(ast.view_item_import(?def_ident,_,_)) {
index.insert(def_ident, ast.mie_view_item(it));
}
case(ast.view_item_export(_)) {
// NB: don't index these, they might collide with
// the import or use that they're exporting. Have
// to do linear search for exports.
}
}
}
fn index_item(mod_index index, @item it) {
alt (it.node) {
case (ast.item_const(?id, _, _, _, _)) {
index.insert(id, ast.mie_item(it));
}
case (ast.item_fn(?id, _, _, _, _)) {
index.insert(id, ast.mie_item(it));
}
case (ast.item_mod(?id, _, _)) {
index.insert(id, ast.mie_item(it));
}
case (ast.item_native_mod(?id, _, _)) {
index.insert(id, ast.mie_item(it));
}
case (ast.item_ty(?id, _, _, _, _)) {
index.insert(id, ast.mie_item(it));
}
case (ast.item_tag(?id, ?variants, _, _, _)) {
index.insert(id, ast.mie_item(it));
let uint variant_idx = 0u;
for (ast.variant v in variants) {
index.insert(v.node.name,
ast.mie_tag_variant(it, variant_idx));
variant_idx += 1u;
}
}
case (ast.item_obj(?id, _, _, _, _)) {
index.insert(id, ast.mie_item(it));
}
}
}
fn index_native_item(native_mod_index index, @native_item it) {
alt (it.node) {
case (ast.native_item_ty(?id, _)) {
index.insert(id, ast.nmie_item(it));
}
case (ast.native_item_fn(?id, _, _, _, _, _)) {
index.insert(id, ast.nmie_item(it));
}
}
}
fn index_native_view_item(native_mod_index index, @view_item it) {
alt (it.node) {
case(ast.view_item_import(?def_ident,_,_)) {
index.insert(def_ident, ast.nmie_view_item(it));
}
case(ast.view_item_export(_)) {
// NB: don't index these, they might collide with
// the import or use that they're exporting. Have
// to do linear search for exports.
}
}
}
fn is_exported(ident i, _mod m) -> bool {
auto count = 0;
for (@ast.view_item vi in m.view_items) {

View File

@ -236,13 +236,11 @@ fn eval_crate_directives(ctx cx,
vec[@ast.crate_directive] cdirs,
str prefix,
&mutable vec[@ast.view_item] view_items,
&mutable vec[@ast.item] items,
hashmap[ast.ident,
ast.mod_index_entry] index) {
&mutable vec[@ast.item] items) {
for (@ast.crate_directive sub_cdir in cdirs) {
eval_crate_directive(cx, e, sub_cdir, prefix,
view_items, items, index);
view_items, items);
}
}
@ -252,12 +250,11 @@ fn eval_crate_directives_to_mod(ctx cx, env e,
str prefix) -> ast._mod {
let vec[@ast.view_item] view_items = vec();
let vec[@ast.item] items = vec();
auto index = new_str_hash[ast.mod_index_entry]();
eval_crate_directives(cx, e, cdirs, prefix,
view_items, items, index);
view_items, items);
ret rec(view_items=view_items, items=items, index=index);
ret rec(view_items=view_items, items=items);
}
@ -266,15 +263,13 @@ fn eval_crate_directive_block(ctx cx,
&ast.block blk,
str prefix,
&mutable vec[@ast.view_item] view_items,
&mutable vec[@ast.item] items,
hashmap[ast.ident,
ast.mod_index_entry] index) {
&mutable vec[@ast.item] items) {
for (@ast.stmt s in blk.node.stmts) {
alt (s.node) {
case (ast.stmt_crate_directive(?cdir)) {
eval_crate_directive(cx, e, cdir, prefix,
view_items, items, index);
view_items, items);
}
case (_) {
cx.sess.span_err(s.span,
@ -289,9 +284,7 @@ fn eval_crate_directive_expr(ctx cx,
@ast.expr x,
str prefix,
&mutable vec[@ast.view_item] view_items,
&mutable vec[@ast.item] items,
hashmap[ast.ident,
ast.mod_index_entry] index) {
&mutable vec[@ast.item] items) {
alt (x.node) {
case (ast.expr_if(?cond, ?thn, ?elopt, _)) {
@ -302,15 +295,13 @@ fn eval_crate_directive_expr(ctx cx,
if (val_as_bool(cv)) {
ret eval_crate_directive_block(cx, e, thn, prefix,
view_items, items,
index);
view_items, items);
}
alt (elopt) {
case (some[@ast.expr](?els)) {
ret eval_crate_directive_expr(cx, e, els, prefix,
view_items, items,
index);
view_items, items);
}
case (_) {
// Absent-else is ok.
@ -326,14 +317,13 @@ fn eval_crate_directive_expr(ctx cx,
auto pv = eval_lit(cx, arm.pat.span, lit);
if (val_eq(cx.sess, arm.pat.span, vv, pv)) {
ret eval_crate_directive_block
(cx, e, arm.block, prefix,
view_items, items, index);
(cx, e, arm.block, prefix, view_items, items);
}
}
case (ast.pat_wild(_)) {
ret eval_crate_directive_block
(cx, e, arm.block, prefix,
view_items, items, index);
view_items, items);
}
case (_) {
cx.sess.span_err(arm.pat.span,
@ -346,8 +336,7 @@ fn eval_crate_directive_expr(ctx cx,
case (ast.expr_block(?block, _)) {
ret eval_crate_directive_block(cx, e, block, prefix,
view_items, items,
index);
view_items, items);
}
case (_) {
@ -361,21 +350,19 @@ fn eval_crate_directive(ctx cx,
@ast.crate_directive cdir,
str prefix,
&mutable vec[@ast.view_item] view_items,
&mutable vec[@ast.item] items,
hashmap[ast.ident,
ast.mod_index_entry] index) {
&mutable vec[@ast.item] items) {
alt (cdir.node) {
case (ast.cdir_let(?id, ?x, ?cdirs)) {
auto v = eval_expr(cx, e, x);
auto e0 = vec(tup(id, v)) + e;
eval_crate_directives(cx, e0, cdirs, prefix,
view_items, items, index);
view_items, items);
}
case (ast.cdir_expr(?x)) {
eval_crate_directive_expr(cx, e, x, prefix,
view_items, items, index);
view_items, items);
}
case (ast.cdir_src_mod(?id, ?file_opt)) {
@ -404,7 +391,6 @@ fn eval_crate_directive(ctx cx,
cx.chpos = p0.get_chpos();
auto im = ast.item_mod(id, m0, next_id);
auto i = @spanned(cdir.span.lo, cdir.span.hi, im);
ast.index_item(index, i);
Vec.push[@ast.item](items, i);
}
@ -422,13 +408,11 @@ fn eval_crate_directive(ctx cx,
auto m0 = eval_crate_directives_to_mod(cx, e, cdirs, full_path);
auto im = ast.item_mod(id, m0, cx.p.next_def_id());
auto i = @spanned(cdir.span.lo, cdir.span.hi, im);
ast.index_item(index, i);
Vec.push[@ast.item](items, i);
}
case (ast.cdir_view_item(?vi)) {
Vec.push[@ast.view_item](view_items, vi);
ast.index_view_item(index, vi);
}
case (ast.cdir_meta(?mi)) {

View File

@ -1889,17 +1889,12 @@ fn parse_item_obj(parser p, ast.layer lyr) -> @ast.item {
}
fn parse_mod_items(parser p, token.token term) -> ast._mod {
auto index = new_str_hash[ast.mod_index_entry]();
auto view_items = parse_view(p, index);
auto view_items = parse_view(p);
let vec[@ast.item] items = vec();
while (p.peek() != term) {
auto item = parse_item(p);
items += vec(item);
// Index the item.
ast.index_item(index, item);
items += vec(parse_item(p));
}
ret rec(view_items=view_items, items=items, index=index);
ret rec(view_items=view_items, items=items);
}
fn parse_item_const(parser p) -> @ast.item {
@ -1972,22 +1967,16 @@ fn parse_native_item(parser p) -> @ast.native_item {
fn parse_native_mod_items(parser p,
str native_name,
ast.native_abi abi) -> ast.native_mod {
auto index = new_str_hash[ast.native_mod_index_entry]();
let vec[@ast.native_item] items = vec();
auto view_items = parse_native_view(p, index);
auto view_items = parse_native_view(p);
while (p.peek() != token.RBRACE) {
auto item = parse_native_item(p);
items += vec(item);
// Index the item.
ast.index_native_item(index, item);
items += vec(parse_native_item(p));
}
ret rec(native_name=native_name, abi=abi,
view_items=view_items,
items=items,
index=index);
items=items);
}
fn default_native_name(session.session sess, str id) -> str {
@ -2353,25 +2342,18 @@ fn is_view_item(token.token t) -> bool {
ret false;
}
fn parse_view(parser p, ast.mod_index index) -> vec[@ast.view_item] {
fn parse_view(parser p) -> vec[@ast.view_item] {
let vec[@ast.view_item] items = vec();
while (is_view_item(p.peek())) {
auto item = parse_view_item(p);
items += vec(item);
ast.index_view_item(index, item);
items += vec(parse_view_item(p));
}
ret items;
}
fn parse_native_view(parser p, ast.native_mod_index index)
-> vec[@ast.view_item] {
fn parse_native_view(parser p) -> vec[@ast.view_item] {
let vec[@ast.view_item] items = vec();
while (is_view_item(p.peek())) {
auto item = parse_view_item(p);
items += vec(item);
ast.index_native_view_item(index, item);
items += vec(parse_view_item(p));
}
ret items;
}

View File

@ -1057,21 +1057,18 @@ fn fold_mod[ENV](&ENV e, &ast_fold[ENV] fld, &ast._mod m) -> ast._mod {
let vec[@view_item] view_items = vec();
let vec[@item] items = vec();
auto index = new_str_hash[ast.mod_index_entry]();
for (@view_item vi in m.view_items) {
auto new_vi = fold_view_item[ENV](e, fld, vi);
Vec.push[@view_item](view_items, new_vi);
ast.index_view_item(index, new_vi);
}
for (@item i in m.items) {
auto new_item = fold_item[ENV](e, fld, i);
Vec.push[@item](items, new_item);
ast.index_item(index, new_item);
}
ret fld.fold_mod(e, rec(view_items=view_items, items=items, index=index));
ret fld.fold_mod(e, rec(view_items=view_items, items=items));
}
fn fold_native_item[ENV](&ENV env, &ast_fold[ENV] fld,
@ -1098,7 +1095,6 @@ fn fold_native_mod[ENV](&ENV e, &ast_fold[ENV] fld,
&ast.native_mod m) -> ast.native_mod {
let vec[@view_item] view_items = vec();
let vec[@native_item] items = vec();
auto index = new_str_hash[ast.native_mod_index_entry]();
for (@view_item vi in m.view_items) {
auto new_vi = fold_view_item[ENV](e, fld, vi);
@ -1108,14 +1104,12 @@ fn fold_native_mod[ENV](&ENV e, &ast_fold[ENV] fld,
for (@native_item i in m.items) {
auto new_item = fold_native_item[ENV](e, fld, i);
Vec.push[@native_item](items, new_item);
ast.index_native_item(index, new_item);
}
ret fld.fold_native_mod(e, rec(native_name=m.native_name,
abi=m.abi,
view_items=view_items,
items=items,
index=index));
items=items));
}
fn fold_crate[ENV](&ENV env, &ast_fold[ENV] fld,

View File

@ -7,6 +7,7 @@
import driver.session.session;
import util.common.new_def_hash;
import util.common.new_int_hash;
import util.common.new_str_hash;
import util.common.span;
import util.typestate_ann.ts_ann;
import std.Map.hashmap;
@ -26,6 +27,11 @@
// locates all names (in expressions, types, and alt patterns) and resolves
// them, storing the resulting def in the AST nodes.
// This module internally uses -1 as a def_id for the top_level module in a
// crate. The parser doesn't assign a def_id to this module.
// (FIXME See https://github.com/graydon/rust/issues/358 for the reason this
// isn't a const.)
tag scope {
scope_crate(@ast.crate);
scope_item(@ast.item);
@ -35,10 +41,6 @@
scope_arm(ast.arm);
}
tag wrap_mod {
wmod(ast._mod);
wnmod(ast.native_mod);
}
tag import_state {
todo(@ast.view_item, list[scope]);
resolving(span);
@ -57,8 +59,24 @@ fn eq(&tup(def_id,str) v1, &tup(def_id,str) v2) -> bool {
ret std.Map.mk_hashmap[tup(def_id,str),def](hash, eq);
}
tag mod_index_entry {
mie_view_item(@ast.view_item);
mie_item(@ast.item);
mie_tag_variant(@ast.item /* tag item */, uint /* variant index */);
}
type mod_index = hashmap[ident,mod_index_entry];
type indexed_mod = rec(ast._mod m, mod_index index);
tag native_mod_index_entry {
nmie_view_item(@ast.view_item);
nmie_item(@ast.native_item);
}
type nmod_index = hashmap[ident,native_mod_index_entry];
type indexed_nmod = rec(ast.native_mod m, nmod_index index);
type env = rec(hashmap[ast.def_num,import_state] imports,
hashmap[ast.def_num,@wrap_mod] mod_map,
hashmap[ast.def_num,@indexed_mod] mod_map,
hashmap[ast.def_num,@indexed_nmod] nmod_map,
hashmap[def_id,vec[ident]] ext_map,
ext_hash ext_cache,
session sess);
@ -74,7 +92,8 @@ fn eq(&tup(def_id,str) v1, &tup(def_id,str) v2) -> bool {
fn resolve_crate(session sess, @ast.crate crate) -> @ast.crate {
auto e = @rec(imports = new_int_hash[import_state](),
mod_map = new_int_hash[@wrap_mod](),
mod_map = new_int_hash[@indexed_mod](),
nmod_map = new_int_hash[@indexed_nmod](),
ext_map = new_def_hash[vec[ident]](),
ext_cache = new_ext_hash(),
sess = sess);
@ -94,6 +113,9 @@ fn map_crate(&@env e, &ast.crate c) {
visit_item_pre = bind push_env_for_item_map_mod(e, cell, _),
visit_item_post = bind pop_env_for_item(cell, _)
with walk.default_visitor());
// Register the top-level mod
e.mod_map.insert(-1, @rec(m=c.node.module,
index=index_mod(c.node.module)));
walk.walk_crate(v, c);
// Helpers for this pass.
@ -108,10 +130,12 @@ fn push_env_for_item_map_mod(@env e, @mutable list[scope] sc,
*sc = cons[scope](scope_item(i), @*sc);
alt (i.node) {
case (ast.item_mod(_, ?md, ?defid)) {
e.mod_map.insert(defid._1, @wmod(md));
auto index = index_mod(md);
e.mod_map.insert(defid._1, @rec(m=md, index=index));
}
case (ast.item_native_mod(_, ?nmd, ?defid)) {
e.mod_map.insert(defid._1, @wnmod(nmd));
auto index = index_nmod(nmd);
e.nmod_map.insert(defid._1, @rec(m=nmd, index=index));
}
case (_) {}
}
@ -375,7 +399,8 @@ fn in_scope(&env e, ident id, &scope s, namespace ns)
-> Option.t[def] {
alt (s) {
case (scope_crate(?c)) {
ret lookup_in_regular_mod(e, c.node.module, id, ns, inside);
auto defid = tup(ast.local_crate, -1);
ret lookup_in_regular_mod(e, defid, id, ns, inside);
}
case (scope_item(?it)) {
alt (it.node) {
@ -390,11 +415,11 @@ fn in_scope(&env e, ident id, &scope s, namespace ns)
ret lookup_in_ty_params(id, ty_params);
}
}
case (ast.item_mod(_, ?m, _)) {
ret lookup_in_regular_mod(e, m, id, ns, inside);
case (ast.item_mod(_, _, ?defid)) {
ret lookup_in_regular_mod(e, defid, id, ns, inside);
}
case (ast.item_native_mod(_, ?m, _)) {
ret lookup_in_native_mod(e, m, id, ns);
case (ast.item_native_mod(_, ?m, ?defid)) {
ret lookup_in_native_mod(e, defid, id, ns);
}
case (ast.item_ty(_, _, ?ty_params, _, _)) {
if (ns == ns_type) {
@ -606,8 +631,6 @@ fn lookup_in_mod(&env e, def m, ident id, namespace ns, dir dr)
ret cached;
}
auto path = vec(id);
// def_num=-1 is a kludge to overload def_mod for external crates,
// since those don't get a def num
if (defid._1 != -1) {
path = e.ext_map.get(defid) + path;
}
@ -619,18 +642,10 @@ fn lookup_in_mod(&env e, def m, ident id, namespace ns, dir dr)
}
alt (m) {
case (ast.def_mod(?defid)) {
alt (*e.mod_map.get(defid._1)) {
case (wmod(?m)) {
ret lookup_in_regular_mod(e, m, id, ns, dr);
}
}
ret lookup_in_regular_mod(e, defid, id, ns, dr);
}
case (ast.def_native_mod(?defid)) {
alt (*e.mod_map.get(defid._1)) {
case (wnmod(?m)) {
ret lookup_in_native_mod(e, m, id, ns);
}
}
ret lookup_in_native_mod(e, defid, id, ns);
}
}
}
@ -646,21 +661,22 @@ fn found_view_item(&env e, @ast.view_item vi, namespace ns) -> Option.t[def] {
}
}
fn lookup_in_regular_mod(&env e, &ast._mod md, ident id, namespace ns, dir dr)
fn lookup_in_regular_mod(&env e, def_id defid, ident id, namespace ns, dir dr)
-> Option.t[def] {
auto found = md.index.find(id);
if (found == none[ast.mod_index_entry] ||
(dr == outside && !ast.is_exported(id, md))) {
auto info = e.mod_map.get(defid._1);
auto found = info.index.find(id);
if (found == none[mod_index_entry] ||
(dr == outside && !ast.is_exported(id, info.m))) {
ret none[def];
}
alt (Option.get(found)) {
case (ast.mie_view_item(?view_item)) {
case (mie_view_item(?view_item)) {
ret found_view_item(e, view_item, ns);
}
case (ast.mie_item(?item)) {
case (mie_item(?item)) {
ret found_def_item(item, ns);
}
case (ast.mie_tag_variant(?item, ?variant_idx)) {
case (mie_tag_variant(?item, ?variant_idx)) {
alt (item.node) {
case (ast.item_tag(_, ?variants, _, ?tid, _)) {
if (ns == ns_value) {
@ -675,17 +691,18 @@ fn lookup_in_regular_mod(&env e, &ast._mod md, ident id, namespace ns, dir dr)
}
}
fn lookup_in_native_mod(&env e, &ast.native_mod md, ident id, namespace ns)
fn lookup_in_native_mod(&env e, def_id defid, ident id, namespace ns)
-> Option.t[def] {
auto found = md.index.find(id);
if (found == none[ast.native_mod_index_entry]) {
auto info = e.nmod_map.get(defid._1);
auto found = info.index.find(id);
if (found == none[native_mod_index_entry]) {
ret none[def];
}
alt (Option.get(found)) {
case (ast.nmie_view_item(?view_item)) {
case (nmie_view_item(?view_item)) {
ret found_view_item(e, view_item, ns);
}
case (ast.nmie_item(?item)) {
case (nmie_item(?item)) {
alt (item.node) {
case (ast.native_item_ty(_, ?id)) {
if (ns == ns_type) {
@ -704,6 +721,86 @@ fn lookup_in_native_mod(&env e, &ast.native_mod md, ident id, namespace ns)
ret none[def];
}
// Module indexing
fn index_mod(&ast._mod md) -> mod_index {
auto index = new_str_hash[mod_index_entry]();
for (@ast.view_item it in md.view_items) {
alt (it.node) {
case(ast.view_item_use(?id, _, _, _)) {
index.insert(id, mie_view_item(it));
}
case(ast.view_item_import(?def_ident,_,_)) {
index.insert(def_ident, mie_view_item(it));
}
case(ast.view_item_export(_)) {}
}
}
for (@ast.item it in md.items) {
alt (it.node) {
case (ast.item_const(?id, _, _, _, _)) {
index.insert(id, mie_item(it));
}
case (ast.item_fn(?id, _, _, _, _)) {
index.insert(id, mie_item(it));
}
case (ast.item_mod(?id, _, _)) {
index.insert(id, mie_item(it));
}
case (ast.item_native_mod(?id, _, _)) {
index.insert(id, mie_item(it));
}
case (ast.item_ty(?id, _, _, _, _)) {
index.insert(id, mie_item(it));
}
case (ast.item_tag(?id, ?variants, _, _, _)) {
index.insert(id, mie_item(it));
let uint variant_idx = 0u;
for (ast.variant v in variants) {
index.insert(v.node.name,
mie_tag_variant(it, variant_idx));
variant_idx += 1u;
}
}
case (ast.item_obj(?id, _, _, _, _)) {
index.insert(id, mie_item(it));
}
}
}
ret index;
}
fn index_nmod(&ast.native_mod md) -> nmod_index {
auto index = new_str_hash[native_mod_index_entry]();
for (@ast.view_item it in md.view_items) {
alt (it.node) {
case(ast.view_item_import(?def_ident,_,_)) {
index.insert(def_ident, nmie_view_item(it));
}
case(ast.view_item_export(_)) {}
}
}
for (@ast.native_item it in md.items) {
alt (it.node) {
case (ast.native_item_ty(?id, _)) {
index.insert(id, nmie_item(it));
}
case (ast.native_item_fn(?id, _, _, _, _, _)) {
index.insert(id, nmie_item(it));
}
}
}
ret index;
}
// External lookups
// FIXME creader should handle multiple namespaces
fn check_def_by_ns(def d, namespace ns) -> bool {
ret alt (d) {

View File

@ -6,7 +6,6 @@
import front.ast.item;
import front.ast.block;
import front.ast.block_;
import front.ast.mod_index_entry;
import front.ast.obj_field;
import front.ast.decl;
import front.ast.arm;
@ -83,8 +82,6 @@
import front.ast._obj;
import front.ast._mod;
import front.ast.crate;
import front.ast.mod_index_entry;
import front.ast.mie_item;
import front.ast.item_fn;
import front.ast.item_obj;
import front.ast.def_local;
@ -2357,14 +2354,12 @@ fn annotate_fn(&fn_info_map fm, &ast._fn f) -> ast._fn {
}
fn annotate_mod(&fn_info_map fm, &ast._mod m) -> ast._mod {
let vec[@item] new_items = vec();
auto new_index = new_str_hash[mod_index_entry]();
for (@item i in m.items) {
auto new_i = annotate_item(fm, i);
Vec.push[@item](new_items, new_i);
ast.index_item(new_index, new_i);
}
ret rec(items=new_items, index=new_index with m);
ret rec(items=new_items with m);
}
fn annotate_method(&fn_info_map fm, &@method m) -> @method {
auto f_info = get_fn_info(fm, m.node.id);
@ -2471,15 +2466,13 @@ fn annotate_item(&fn_info_map fm, &@ast.item item) -> @ast.item {
fn annotate_module(&fn_info_map fm, &ast._mod module) -> ast._mod {
let vec[@item] new_items = vec();
auto new_index = new_str_hash[ast.mod_index_entry]();
for (@item i in module.items) {
auto new_item = annotate_item(fm, i);
Vec.push[@item](new_items, new_item);
ast.index_item(new_index, new_item);
}
ret rec(items = new_items, index = new_index with module);
ret rec(items = new_items with module);
}
fn annotate_crate(&fn_info_map fm, &@ast.crate crate) -> @ast.crate {