Handle class destructors correctly in metadata
This allows destructors to be inlined, which is necessary since classes can have both ty params and destructors.
This commit is contained in:
parent
e9fc19c3c2
commit
aa9d2d88d3
8 changed files with 91 additions and 26 deletions
|
@ -730,7 +730,8 @@ enum inlined_item {
|
||||||
ii_item(@item),
|
ii_item(@item),
|
||||||
ii_method(def_id /* impl id */, @method),
|
ii_method(def_id /* impl id */, @method),
|
||||||
ii_native(@native_item),
|
ii_native(@native_item),
|
||||||
ii_ctor(class_ctor, ident, [ty_param], def_id /* parent id */)
|
ii_ctor(class_ctor, ident, [ty_param], def_id /* parent id */),
|
||||||
|
ii_dtor(class_dtor, ident, [ty_param], def_id /* parent id */)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -106,7 +106,7 @@ fn map_decoded_item(diag: span_handler,
|
||||||
// don't decode and instantiate the impl, but just the method, we have to
|
// don't decode and instantiate the impl, but just the method, we have to
|
||||||
// add it to the table now:
|
// add it to the table now:
|
||||||
alt ii {
|
alt ii {
|
||||||
ii_item(_) | ii_ctor(_,_,_,_) { /* fallthrough */ }
|
ii_item(*) | ii_ctor(*) | ii_dtor(*) { /* fallthrough */ }
|
||||||
ii_native(i) {
|
ii_native(i) {
|
||||||
cx.map.insert(i.id, node_native_item(i, native_abi_rust_intrinsic,
|
cx.map.insert(i.id, node_native_item(i, native_abi_rust_intrinsic,
|
||||||
@path));
|
@path));
|
||||||
|
|
|
@ -320,6 +320,7 @@ impl inlined_item_methods for inlined_item {
|
||||||
ii_native(i) { /* FIXME: bad */ copy i.ident }
|
ii_native(i) { /* FIXME: bad */ copy i.ident }
|
||||||
ii_method(_, m) { /* FIXME: bad */ copy m.ident }
|
ii_method(_, m) { /* FIXME: bad */ copy m.ident }
|
||||||
ii_ctor(_, nm, _, _) { /* FIXME: bad */ copy nm }
|
ii_ctor(_, nm, _, _) { /* FIXME: bad */ copy nm }
|
||||||
|
ii_dtor(_, nm, _, _) { /* FIXME: bad */ copy nm }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,6 +330,7 @@ impl inlined_item_methods for inlined_item {
|
||||||
ii_native(i) { i.id }
|
ii_native(i) { i.id }
|
||||||
ii_method(_, m) { m.id }
|
ii_method(_, m) { m.id }
|
||||||
ii_ctor(ctor, _, _, _) { ctor.node.id }
|
ii_ctor(ctor, _, _, _) { ctor.node.id }
|
||||||
|
ii_dtor(dtor, _, _, _) { dtor.node.id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,6 +342,9 @@ impl inlined_item_methods for inlined_item {
|
||||||
ii_ctor(ctor, nm, tps, parent_id) {
|
ii_ctor(ctor, nm, tps, parent_id) {
|
||||||
visit::visit_class_ctor_helper(ctor, nm, tps, parent_id, e, v);
|
visit::visit_class_ctor_helper(ctor, nm, tps, parent_id, e, v);
|
||||||
}
|
}
|
||||||
|
ii_dtor(dtor, nm, tps, parent_id) {
|
||||||
|
visit::visit_class_dtor_helper(dtor, tps, parent_id, e, v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,15 +335,18 @@ fn get_class_method(cdata: cmd, id: ast::node_id, name: str) -> ast::def_id {
|
||||||
|
|
||||||
fn class_dtor(cdata: cmd, id: ast::node_id) -> option<ast::def_id> {
|
fn class_dtor(cdata: cmd, id: ast::node_id) -> option<ast::def_id> {
|
||||||
let items = ebml::get_doc(ebml::doc(cdata.data), tag_items);
|
let items = ebml::get_doc(ebml::doc(cdata.data), tag_items);
|
||||||
|
let mut found = none;
|
||||||
let cls_items = alt maybe_find_item(id, items) {
|
let cls_items = alt maybe_find_item(id, items) {
|
||||||
some(it) { it }
|
some(it) { it }
|
||||||
none { ret none; }};
|
none { fail (#fmt("class_dtor: class id not found \
|
||||||
let mut rslt = none;
|
when looking up dtor for %d", id)); }
|
||||||
ebml::tagged_docs(cls_items, tag_item_dtor) {|f|
|
};
|
||||||
let did = parse_def_id(ebml::doc_data(f));
|
ebml::tagged_docs(cls_items, tag_item_dtor) {|doc|
|
||||||
rslt = some(translate_def_id(cdata, did));
|
let doc1 = ebml::get_doc(doc, tag_def_id);
|
||||||
}
|
let did = parse_def_id(ebml::doc_data(doc1));
|
||||||
rslt
|
found = some(translate_def_id(cdata, did));
|
||||||
|
};
|
||||||
|
found
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_symbol(data: @[u8], id: ast::node_id) -> str {
|
fn get_symbol(data: @[u8], id: ast::node_id) -> str {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ebml::writer;
|
||||||
import syntax::ast::*;
|
import syntax::ast::*;
|
||||||
import syntax::print::pprust;
|
import syntax::print::pprust;
|
||||||
import syntax::{ast_util, visit};
|
import syntax::{ast_util, visit};
|
||||||
import syntax::ast_util::local_def;
|
import syntax::ast_util::*;
|
||||||
import common::*;
|
import common::*;
|
||||||
import middle::ty;
|
import middle::ty;
|
||||||
import middle::ty::node_id_to_type;
|
import middle::ty::node_id_to_type;
|
||||||
|
@ -206,12 +206,6 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
|
||||||
add_to_index(ebml_w, path, index, it.ident);
|
add_to_index(ebml_w, path, index, it.ident);
|
||||||
encode_named_def_id(ebml_w, it.ident,
|
encode_named_def_id(ebml_w, it.ident,
|
||||||
local_def(ctor.node.id));
|
local_def(ctor.node.id));
|
||||||
/* Encode id for dtor */
|
|
||||||
option::iter(m_dtor) {|dtor|
|
|
||||||
ebml_w.wr_tag(tag_item_dtor) {||
|
|
||||||
encode_def_id(ebml_w, local_def(dtor.node.id));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
encode_class_item_paths(ebml_w, items, path + [it.ident],
|
encode_class_item_paths(ebml_w, items, path + [it.ident],
|
||||||
index);
|
index);
|
||||||
}
|
}
|
||||||
|
@ -485,8 +479,8 @@ fn encode_info_for_fn(ecx: @encode_ctxt, ebml_w: ebml::writer,
|
||||||
encode_family(ebml_w, purity_fn_family(decl.purity));
|
encode_family(ebml_w, purity_fn_family(decl.purity));
|
||||||
encode_type_param_bounds(ebml_w, ecx, tps);
|
encode_type_param_bounds(ebml_w, ecx, tps);
|
||||||
let its_ty = node_id_to_type(ecx.tcx, id);
|
let its_ty = node_id_to_type(ecx.tcx, id);
|
||||||
#debug("fn name = %s ty = %s", ident,
|
#debug("fn name = %s ty = %s its node id = %d", ident,
|
||||||
util::ppaux::ty_to_str(ecx.tcx, its_ty));
|
util::ppaux::ty_to_str(ecx.tcx, its_ty), id);
|
||||||
encode_type(ecx, ebml_w, its_ty);
|
encode_type(ecx, ebml_w, its_ty);
|
||||||
encode_path(ebml_w, path, ast_map::path_name(ident));
|
encode_path(ebml_w, path, ast_map::path_name(ident));
|
||||||
alt item {
|
alt item {
|
||||||
|
@ -623,13 +617,23 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||||
encode_enum_variant_info(ecx, ebml_w, item.id, variants,
|
encode_enum_variant_info(ecx, ebml_w, item.id, variants,
|
||||||
path, index, tps);
|
path, index, tps);
|
||||||
}
|
}
|
||||||
item_class(tps, ifaces, items, ctor, _dtor, rp) {
|
item_class(tps, ifaces, items, ctor, m_dtor, rp) {
|
||||||
/* First, encode the fields and methods
|
/* First, encode the fields and methods
|
||||||
These come first because we need to write them to make
|
These come first because we need to write them to make
|
||||||
the index, and the index needs to be in the item for the
|
the index, and the index needs to be in the item for the
|
||||||
class itself */
|
class itself */
|
||||||
let idx = encode_info_for_class(ecx, ebml_w, item.id, path, tps,
|
let idx = encode_info_for_class(ecx, ebml_w, item.id, path, tps,
|
||||||
items, index);
|
items, index);
|
||||||
|
/* Encode the dtor */
|
||||||
|
option::iter(m_dtor) {|dtor|
|
||||||
|
*index += [{val: dtor.node.id, pos: ebml_w.writer.tell()}];
|
||||||
|
encode_info_for_fn(ecx, ebml_w, dtor.node.id, item.ident
|
||||||
|
+ "_dtor", path, if tps.len() > 0u {
|
||||||
|
some(ii_dtor(dtor, item.ident, tps,
|
||||||
|
local_def(item.id))) }
|
||||||
|
else { none }, tps, ast_util::dtor_dec());
|
||||||
|
}
|
||||||
|
|
||||||
/* Index the class*/
|
/* Index the class*/
|
||||||
add_to_index();
|
add_to_index();
|
||||||
/* Now, make an item for the class itself */
|
/* Now, make an item for the class itself */
|
||||||
|
@ -644,6 +648,14 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||||
for ifaces.each {|t|
|
for ifaces.each {|t|
|
||||||
encode_iface_ref(ebml_w, ecx, t);
|
encode_iface_ref(ebml_w, ecx, t);
|
||||||
}
|
}
|
||||||
|
/* Encode the dtor */
|
||||||
|
/* Encode id for dtor */
|
||||||
|
option::iter(m_dtor) {|dtor|
|
||||||
|
ebml_w.wr_tag(tag_item_dtor) {||
|
||||||
|
encode_def_id(ebml_w, local_def(dtor.node.id));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* Encode def_ids for each field and method
|
/* Encode def_ids for each field and method
|
||||||
for methods, write all the stuff get_iface_method
|
for methods, write all the stuff get_iface_method
|
||||||
needs to know*/
|
needs to know*/
|
||||||
|
@ -803,9 +815,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
|
||||||
encode_info_for_item(ecx, ebml_w, i, index, *pt);
|
encode_info_for_item(ecx, ebml_w, i, index, *pt);
|
||||||
/* encode ctor, then encode items */
|
/* encode ctor, then encode items */
|
||||||
alt i.node {
|
alt i.node {
|
||||||
item_class(tps, _, _, ctor, _, _) {
|
item_class(tps, _, _, ctor, m_dtor, _) {
|
||||||
/* this is assuming that ctors aren't inlined...
|
|
||||||
probably shouldn't assume that */
|
|
||||||
#debug("encoding info for ctor %s %d", i.ident,
|
#debug("encoding info for ctor %s %d", i.ident,
|
||||||
ctor.node.id);
|
ctor.node.id);
|
||||||
*index += [{val: ctor.node.id, pos: ebml_w.writer.tell()}];
|
*index += [{val: ctor.node.id, pos: ebml_w.writer.tell()}];
|
||||||
|
@ -813,7 +823,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
|
||||||
*pt, if tps.len() > 0u {
|
*pt, if tps.len() > 0u {
|
||||||
some(ii_ctor(ctor, i.ident, tps,
|
some(ii_ctor(ctor, i.ident, tps,
|
||||||
local_def(i.id))) }
|
local_def(i.id))) }
|
||||||
else { none }, tps, ctor.node.dec)
|
else { none }, tps, ctor.node.dec);
|
||||||
}
|
}
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -427,6 +427,12 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
|
||||||
with ctor.node}
|
with ctor.node}
|
||||||
with ctor}, nm, tps, parent_id)
|
with ctor}, nm, tps, parent_id)
|
||||||
}
|
}
|
||||||
|
ast::ii_dtor(dtor, nm, tps, parent_id) {
|
||||||
|
let dtor_body = fld.fold_block(dtor.node.body);
|
||||||
|
ast::ii_dtor({node: {body: dtor_body
|
||||||
|
with dtor.node}
|
||||||
|
with dtor}, nm, tps, parent_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,6 +470,16 @@ fn renumber_ast(xcx: extended_decode_ctxt, ii: ast::inlined_item)
|
||||||
with ctor.node}
|
with ctor.node}
|
||||||
with ctor}, nm, new_params, new_parent)
|
with ctor}, nm, new_params, new_parent)
|
||||||
}
|
}
|
||||||
|
ast::ii_dtor(dtor, nm, tps, parent_id) {
|
||||||
|
let dtor_body = fld.fold_block(dtor.node.body);
|
||||||
|
let new_params = fold::fold_ty_params(tps, fld);
|
||||||
|
let dtor_id = fld.new_id(dtor.node.id);
|
||||||
|
let new_parent = xcx.tr_def_id(parent_id);
|
||||||
|
let new_self = fld.new_id(dtor.node.self_id);
|
||||||
|
ast::ii_dtor({node: {id: dtor_id, self_id: new_self, body: dtor_body}
|
||||||
|
with dtor},
|
||||||
|
nm, new_params, new_parent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -749,6 +749,12 @@ fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
|
||||||
ty::ty_opaque_closure_ptr(ck) {
|
ty::ty_opaque_closure_ptr(ck) {
|
||||||
closure::make_opaque_cbox_free_glue(bcx, ck, v)
|
closure::make_opaque_cbox_free_glue(bcx, ck, v)
|
||||||
}
|
}
|
||||||
|
ty::ty_class(did,substs) {
|
||||||
|
// Call the dtor if there is one
|
||||||
|
option::map_default(ty::ty_dtor(bcx.tcx(), did), bcx) {|dt_id|
|
||||||
|
trans_class_drop(bcx, v, dt_id, did, substs)
|
||||||
|
}
|
||||||
|
}
|
||||||
_ { bcx }
|
_ { bcx }
|
||||||
};
|
};
|
||||||
build_return(bcx);
|
build_return(bcx);
|
||||||
|
@ -2287,7 +2293,7 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
|
||||||
}
|
}
|
||||||
some(none) { fn_id } // Not inlinable
|
some(none) { fn_id } // Not inlinable
|
||||||
none { // Not seen yet
|
none { // Not seen yet
|
||||||
alt check csearch::maybe_get_item_ast(
|
alt csearch::maybe_get_item_ast(
|
||||||
ccx.tcx, fn_id,
|
ccx.tcx, fn_id,
|
||||||
bind astencode::decode_inlined_item(_, _, ccx.maps, _, _)) {
|
bind astencode::decode_inlined_item(_, _, ccx.maps, _, _)) {
|
||||||
|
|
||||||
|
@ -2327,6 +2333,10 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
|
||||||
trans_item(ccx, *item);
|
trans_item(ccx, *item);
|
||||||
local_def(my_id)
|
local_def(my_id)
|
||||||
}
|
}
|
||||||
|
csearch::found_parent(_, _) {
|
||||||
|
ccx.sess.bug("maybe_get_item_ast returned a found_parent \
|
||||||
|
with a non-item parent");
|
||||||
|
}
|
||||||
csearch::found(ast::ii_method(impl_did, mth)) {
|
csearch::found(ast::ii_method(impl_did, mth)) {
|
||||||
ccx.external.insert(fn_id, some(mth.id));
|
ccx.external.insert(fn_id, some(mth.id));
|
||||||
let {bounds: impl_bnds, rp: _, ty: impl_ty} =
|
let {bounds: impl_bnds, rp: _, ty: impl_ty} =
|
||||||
|
@ -2340,6 +2350,10 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
|
||||||
}
|
}
|
||||||
local_def(mth.id)
|
local_def(mth.id)
|
||||||
}
|
}
|
||||||
|
csearch::found(ast::ii_dtor(dtor, nm, tps, parent_id)) {
|
||||||
|
ccx.external.insert(fn_id, some(dtor.node.id));
|
||||||
|
local_def(dtor.node.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,9 @@ import syntax::ast::*;
|
||||||
import syntax::{visit, ast_util, ast_map};
|
import syntax::{visit, ast_util, ast_map};
|
||||||
import syntax::ast_util::def_id_of_def;
|
import syntax::ast_util::def_id_of_def;
|
||||||
import syntax::attr;
|
import syntax::attr;
|
||||||
|
import syntax::print::pprust::expr_to_str;
|
||||||
import std::map::hashmap;
|
import std::map::hashmap;
|
||||||
|
import driver::session::*;
|
||||||
|
|
||||||
export map, find_reachable;
|
export map, find_reachable;
|
||||||
|
|
||||||
|
@ -58,7 +60,11 @@ fn traverse_export(cx: ctx, exp_id: node_id) {
|
||||||
|
|
||||||
fn traverse_def_id(cx: ctx, did: def_id) {
|
fn traverse_def_id(cx: ctx, did: def_id) {
|
||||||
if did.crate != local_crate { ret; }
|
if did.crate != local_crate { ret; }
|
||||||
alt cx.tcx.items.get(did.node) {
|
let n = alt cx.tcx.items.find(did.node) {
|
||||||
|
none { ret; } // This can happen for self, for example
|
||||||
|
some(n) { n }
|
||||||
|
};
|
||||||
|
alt n {
|
||||||
ast_map::node_item(item, _) { traverse_public_item(cx, item); }
|
ast_map::node_item(item, _) { traverse_public_item(cx, item); }
|
||||||
ast_map::node_method(_, impl_id, _) { traverse_def_id(cx, impl_id); }
|
ast_map::node_method(_, impl_id, _) { traverse_def_id(cx, impl_id); }
|
||||||
ast_map::node_native_item(item, _, _) { cx.rmap.insert(item.id, ()); }
|
ast_map::node_native_item(item, _, _) { cx.rmap.insert(item.id, ()); }
|
||||||
|
@ -111,6 +117,10 @@ fn traverse_public_item(cx: ctx, item: @item) {
|
||||||
cx.rmap.insert(ctor.node.id, ());
|
cx.rmap.insert(ctor.node.id, ());
|
||||||
option::iter(m_dtor) {|dtor|
|
option::iter(m_dtor) {|dtor|
|
||||||
cx.rmap.insert(dtor.node.id, ());
|
cx.rmap.insert(dtor.node.id, ());
|
||||||
|
// dtors don't have attrs
|
||||||
|
if tps.len() > 0u {
|
||||||
|
traverse_inline_body(cx, dtor.node.body);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for vec::each(items) {|item|
|
for vec::each(items) {|item|
|
||||||
alt item.node {
|
alt item.node {
|
||||||
|
@ -134,7 +144,13 @@ fn traverse_inline_body(cx: ctx, body: blk) {
|
||||||
fn traverse_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
|
fn traverse_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
|
||||||
alt e.node {
|
alt e.node {
|
||||||
expr_path(_) {
|
expr_path(_) {
|
||||||
traverse_def_id(cx, def_id_of_def(cx.tcx.def_map.get(e.id)));
|
alt cx.tcx.def_map.find(e.id) {
|
||||||
|
some(d) {
|
||||||
|
traverse_def_id(cx, def_id_of_def(d));
|
||||||
|
}
|
||||||
|
none { cx.tcx.sess.span_bug(e.span, #fmt("Unbound node \
|
||||||
|
id %? while traversing %s", e.id, expr_to_str(e))); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
expr_field(_, _, _) {
|
expr_field(_, _, _) {
|
||||||
alt cx.method_map.find(e.id) {
|
alt cx.method_map.find(e.id) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue