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
This commit is contained in:
parent
730e8e9310
commit
ccc7651b48
src
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
8
src/test/run-pass/issue-2383.rs
Normal file
8
src/test/run-pass/issue-2383.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use std;
|
||||
import std::deque;
|
||||
import std::deque::t;
|
||||
|
||||
fn main() {
|
||||
let Q = deque::create();
|
||||
Q.add_back(10);
|
||||
}
|
Loading…
Reference in New Issue
Block a user