diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-06-12 16:25:09 -0700 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-06-12 17:37:04 -0700 |
| commit | aa9d2d88d33266437ca770a7345cce0d23ad1011 (patch) | |
| tree | 66225e5bd762c78643cb298e90d1f626355cb569 /src/rustc/middle | |
| parent | e9fc19c3c22174dd4308337805e686bbd4960635 (diff) | |
| download | rust-aa9d2d88d33266437ca770a7345cce0d23ad1011.tar.gz rust-aa9d2d88d33266437ca770a7345cce0d23ad1011.zip | |
Handle class destructors correctly in metadata
This allows destructors to be inlined, which is necessary since classes can have both ty params and destructors.
Diffstat (limited to 'src/rustc/middle')
| -rw-r--r-- | src/rustc/middle/astencode.rs | 16 | ||||
| -rw-r--r-- | src/rustc/middle/trans/base.rs | 16 | ||||
| -rw-r--r-- | src/rustc/middle/trans/reachable.rs | 20 |
3 files changed, 49 insertions, 3 deletions
diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index d604505455c..0d6b158a9ae 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -427,6 +427,12 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item { with ctor.node} 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}, 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) + } } } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index fe4046c3663..2423f04d11f 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -749,6 +749,12 @@ fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { ty::ty_opaque_closure_ptr(ck) { 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 } }; 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 none { // Not seen yet - alt check csearch::maybe_get_item_ast( + alt csearch::maybe_get_item_ast( ccx.tcx, fn_id, 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); 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)) { ccx.external.insert(fn_id, some(mth.id)); 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) } + csearch::found(ast::ii_dtor(dtor, nm, tps, parent_id)) { + ccx.external.insert(fn_id, some(dtor.node.id)); + local_def(dtor.node.id) + } } } } diff --git a/src/rustc/middle/trans/reachable.rs b/src/rustc/middle/trans/reachable.rs index 25c60aa2793..2b708467874 100644 --- a/src/rustc/middle/trans/reachable.rs +++ b/src/rustc/middle/trans/reachable.rs @@ -9,7 +9,9 @@ import syntax::ast::*; import syntax::{visit, ast_util, ast_map}; import syntax::ast_util::def_id_of_def; import syntax::attr; +import syntax::print::pprust::expr_to_str; import std::map::hashmap; +import driver::session::*; 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) { 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_method(_, impl_id, _) { traverse_def_id(cx, impl_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, ()); option::iter(m_dtor) {|dtor| 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| 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>) { alt e.node { 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(_, _, _) { alt cx.method_map.find(e.id) { |
