From ccc7651b482167f61678c8630545a9f0e6b6ea91 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 29 May 2012 14:39:22 -0700 Subject: In reachability, don't ignore nested items Reachability was considering nested items to be unreachable, which was causing the bug in #2383. Once I fixed that, I also had to make impl::make_impl_vtable instantiate methods where necessary, before calling monomorphic_fn. Closes #2383 --- src/rustc/middle/trans/base.rs | 6 +++++- src/rustc/middle/trans/impl.rs | 7 ++++++- src/rustc/middle/trans/reachable.rs | 11 ++++++++--- 3 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src/rustc') diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index bdde26a0f82..f069ce1c2cc 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -40,6 +40,7 @@ import link::{mangle_internal_name_by_type_only, import metadata::{csearch, cstore, encoder}; import metadata::common::link_meta; import util::ppaux::{ty_to_str, ty_to_short_str}; +import syntax::diagnostic::expect; import common::*; import build::*; @@ -2052,7 +2053,10 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t], let tpt = ty::lookup_item_type(ccx.tcx, fn_id); let mut item_ty = tpt.ty; - let map_node = ccx.tcx.items.get(fn_id.node); + let map_node = session::expect(ccx.sess, ccx.tcx.items.find(fn_id.node), + {|| #fmt("While monomorphizing %?, couldn't find it in the item map \ + (may have attempted to monomorphize an item defined in a different \ + crate?)", fn_id)}); // Get the path so that we can create a symbol let (pt, name, span) = alt map_node { ast_map::node_item(i, pt) { diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs index 25aee106a8b..914e282e485 100644 --- a/src/rustc/middle/trans/impl.rs +++ b/src/rustc/middle/trans/impl.rs @@ -258,8 +258,13 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: [ty::t], if (*im.tps).len() > 0u || ty::type_has_self(fty) { C_null(T_ptr(T_nil())) } else { - let m_id = method_with_name(ccx, impl_id, im.ident); + let mut m_id = method_with_name(ccx, impl_id, im.ident); if has_tps { + // If the method is in another crate, need to make an inlined + // copy first + if m_id.crate != ast::local_crate { + m_id = maybe_instantiate_inline(ccx, m_id); + } monomorphic_fn(ccx, m_id, substs, some(vtables), none).val } else if m_id.crate == ast::local_crate { get_item_val(ccx, m_id.node) diff --git a/src/rustc/middle/trans/reachable.rs b/src/rustc/middle/trans/reachable.rs index 814bff13e99..2bbccf3df27 100644 --- a/src/rustc/middle/trans/reachable.rs +++ b/src/rustc/middle/trans/reachable.rs @@ -98,6 +98,7 @@ fn traverse_public_item(cx: ctx, item: @item) { for vec::each(ms) {|m| if tps.len() > 0u || m.tps.len() > 0u || attr::find_inline_attr(m.attrs) != attr::ia_none { + cx.rmap.insert(m.id, ()); traverse_inline_body(cx, m.body); } } @@ -141,9 +142,13 @@ fn traverse_inline_body(cx: ctx, body: blk) { } visit::visit_expr(e, cx, v); } - // Ignore nested items - fn traverse_item(_i: @item, _cx: ctx, _v: visit::vt) {} - visit::visit_block(body, cx, visit::mk_vt(@{ + // Don't ignore nested items: for example if a generic fn contains a + // generic impl (as in deque::create), we need to monomorphize the + // impl as well + fn traverse_item(i: @item, cx: ctx, _v: visit::vt) { + traverse_public_item(cx, i); + } + visit::visit_block(body, cx, visit::mk_vt(@{ visit_expr: traverse_expr, visit_item: traverse_item with *visit::default_visitor() -- cgit 1.4.1-3-g733a5