about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-05-29 14:39:22 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-05-29 14:40:35 -0700
commitccc7651b482167f61678c8630545a9f0e6b6ea91 (patch)
tree54c52cfbdada09f448a7357221034956c1ff5967 /src/rustc
parent730e8e93103ee657bcaad55f32f0de52e83b19aa (diff)
downloadrust-ccc7651b482167f61678c8630545a9f0e6b6ea91.tar.gz
rust-ccc7651b482167f61678c8630545a9f0e6b6ea91.zip
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
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/middle/trans/base.rs6
-rw-r--r--src/rustc/middle/trans/impl.rs7
-rw-r--r--src/rustc/middle/trans/reachable.rs11
3 files changed, 19 insertions, 5 deletions
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<ctx>) {}
-    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<ctx>) {
+      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()