From 2fe299d1a53355c9bb78b9067bd2d18bd4eb94e7 Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Thu, 2 Aug 2012 15:52:25 -0700 Subject: [PATCH] Extend ast_map to know about method declarations in traits. --- src/libsyntax/ast.rs | 2 +- src/libsyntax/ast_map.rs | 28 ++++++++++++++++++++-------- src/libsyntax/ast_util.rs | 13 +++++++++++++ src/libsyntax/parse/parser.rs | 2 +- src/rustc/middle/trans/base.rs | 8 +++++++- src/rustc/middle/trans/impl.rs | 2 ++ src/rustc/middle/ty.rs | 4 ++++ 7 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 0dede78ffd0..5f62c2901f0 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -511,7 +511,7 @@ enum lit_ { #[auto_serialize] type ty_method = {ident: ident, attrs: ~[attribute], decl: fn_decl, tps: ~[ty_param], self_ty: self_ty, - span: span}; + id: node_id, span: span}; #[auto_serialize] // A trait method is either required (meaning it doesn't have an diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 90330db78a7..acd20951328 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -35,6 +35,8 @@ fn path_to_str(p: path) -> ~str { enum ast_node { node_item(@item, @path), node_foreign_item(@foreign_item, foreign_abi, @path), + node_trait_method(@trait_method, def_id /* trait did */, + @path /* path to the trait */), node_method(@method, def_id /* impl did */, @path /* path to the impl */), node_variant(variant, @item, @path), node_expr(@expr), @@ -218,19 +220,24 @@ fn map_item(i: @item, cx: ctx, v: vt) { let (_, ms) = ast_util::split_class_items(items); // Map trait refs to their parent classes. This is // so we can find the self_ty - do vec::iter(traits) |p| { cx.map.insert(p.ref_id, - node_item(i, item_path)); - // This is so we can look up the right things when - // encoding/decoding - cx.map.insert(p.impl_id, - node_item(i, item_path)); - - }; + for traits.each |p| { + cx.map.insert(p.ref_id, node_item(i, item_path)); + // This is so we can look up the right things when + // encoding/decoding + cx.map.insert(p.impl_id, node_item(i, item_path)); + } let d_id = ast_util::local_def(i.id); let p = extend(cx, i.ident); // only need to handle methods do vec::iter(ms) |m| { map_method(d_id, p, m, cx); } } + item_trait(tps, methods) { + for methods.each |tm| { + let id = ast_util::trait_method_to_ty_method(tm).id; + let d_id = ast_util::local_def(i.id); + cx.map.insert(id, node_trait_method(@tm, d_id, item_path)); + } + } _ { } } alt i.node { @@ -283,6 +290,11 @@ fn node_id_to_str(map: map, id: node_id) -> ~str { fmt!{"method %s in %s (id=%?)", *m.ident, path_to_str(*path), id} } + some(node_trait_method(tm, impl_did, path)) { + let m = ast_util::trait_method_to_ty_method(*tm); + fmt!{"method %s in %s (id=%?)", + *m.ident, path_to_str(*path), id} + } some(node_variant(variant, def_id, path)) { fmt!{"variant %s in %s (id=%?)", *variant.node.name, path_to_str(*path), id} diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 21d2de2d31b..119f4465d9e 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -316,6 +316,19 @@ fn split_class_items(cs: ~[@class_member]) -> (~[ivar], ~[@method]) { (vs, ms) } +// extract a ty_method from a trait_method. if the trait_method is +// a default, pull out the useful fields to make a ty_method +fn trait_method_to_ty_method(method: trait_method) -> ty_method { + alt method { + required(m) { m } + provided(m) { + {ident: m.ident, attrs: m.attrs, + decl: m.decl, tps: m.tps, self_ty: m.self_ty, + id: m.id, span: m.span} + } + } +} + pure fn class_member_visibility(ci: @class_member) -> visibility { alt ci.node { instance_var(_, _, _, _, vis) { vis } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7d5a088a04f..537e72f707f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -291,7 +291,7 @@ fn parse_trait_methods() -> ~[trait_method] { required({ident: ident, attrs: attrs, decl: {purity: pur with d}, tps: tps, self_ty: self_ty, - span: mk_sp(lo, hi)}) + id: p.get_id(), span: mk_sp(lo, hi)}) } token::LBRACE { debug!{"parse_trait_methods(): parsing provided method"}; diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index eaee22ee677..6d1645ae766 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -2111,6 +2111,9 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, } ast_map::node_ctor(nm, _, ct, _, pt) { (pt, nm, ct.span) } ast_map::node_dtor(_, dtor, _, pt) {(pt, @~"drop", dtor.span)} + ast_map::node_trait_method(*) { + ccx.tcx.sess.bug(~"Can't monomorphize a trait method") + } ast_map::node_expr(*) { ccx.tcx.sess.bug(~"Can't monomorphize an expr") } @@ -2207,6 +2210,9 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, ast_map::node_expr(*) { ccx.tcx.sess.bug(~"Can't monomorphize an expr") } + ast_map::node_trait_method(*) { + ccx.tcx.sess.bug(~"Can't monomorphize a trait method") + } ast_map::node_export(*) { ccx.tcx.sess.bug(~"Can't monomorphize an export") } @@ -2418,7 +2424,7 @@ fn take_local(table: hashmap, return {val: slf, kind: lv_owned}; } _ { - cx.sess().unimpl(fmt!{"unsupported def type in trans_local_def: %?", + cx.sess().unimpl(fmt!{"unsupported def type in trans_local_var: %?", def}); } } diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs index 6f254f867f6..363b9ece7ad 100644 --- a/src/rustc/middle/trans/impl.rs +++ b/src/rustc/middle/trans/impl.rs @@ -185,6 +185,8 @@ fn resolve_vtables_in_fn_ctxt(fcx: fn_ctxt, vts: typeck::vtable_res) @vec::map(*vts, |d| resolve_vtable_in_fn_ctxt(fcx, d)) } +// Apply the typaram substitutions in the fn_ctxt to a vtable. This should +// eliminate any vtable_params. fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin) -> typeck::vtable_origin { alt vt { diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 004a2da5d92..afb18c605c4 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -2759,6 +2759,10 @@ fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path { ast_map::node_method(method, _, path) { vec::append_one(*path, ast_map::path_name(method.ident)) } + ast_map::node_trait_method(trait_method, _, path) { + let method = ast_util::trait_method_to_ty_method(*trait_method); + vec::append_one(*path, ast_map::path_name(method.ident)) + } ast_map::node_variant(variant, _, path) { vec::append_one(vec::init(*path), -- GitLab