about summary refs log tree commit diff
path: root/src/rustc/middle
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-06-12 16:25:09 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-06-12 17:37:04 -0700
commitaa9d2d88d33266437ca770a7345cce0d23ad1011 (patch)
tree66225e5bd762c78643cb298e90d1f626355cb569 /src/rustc/middle
parente9fc19c3c22174dd4308337805e686bbd4960635 (diff)
downloadrust-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.rs16
-rw-r--r--src/rustc/middle/trans/base.rs16
-rw-r--r--src/rustc/middle/trans/reachable.rs20
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) {