about summary refs log tree commit diff
path: root/src/rustc/metadata
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2012-03-08 23:13:57 +0100
committerMarijn Haverbeke <marijnh@gmail.com>2012-03-15 09:32:53 +0100
commit2c8c50d6cb1d7cce0f597dd60daf2a5109b9c0de (patch)
tree8a6d57985ac4b24feb0b7c89b19ca3e4c3bf2666 /src/rustc/metadata
parent4650e8bcf404d4c27dbbd5446a56fb066ada30f9 (diff)
downloadrust-2c8c50d6cb1d7cce0f597dd60daf2a5109b9c0de.tar.gz
rust-2c8c50d6cb1d7cce0f597dd60daf2a5109b9c0de.zip
Make sure enum and resource constructors are inlined properly
Diffstat (limited to 'src/rustc/metadata')
-rw-r--r--src/rustc/metadata/astencode.rs1
-rw-r--r--src/rustc/metadata/common.rs4
-rw-r--r--src/rustc/metadata/csearch.rs10
-rw-r--r--src/rustc/metadata/decoder.rs31
-rw-r--r--src/rustc/metadata/encoder.rs17
5 files changed, 43 insertions, 20 deletions
diff --git a/src/rustc/metadata/astencode.rs b/src/rustc/metadata/astencode.rs
index 3d54ffe3944..ee0afc22fb4 100644
--- a/src/rustc/metadata/astencode.rs
+++ b/src/rustc/metadata/astencode.rs
@@ -137,6 +137,7 @@ fn visit_ids(item: ast::inlined_item, vfn: fn@(ast::node_id)) {
             vfn(i.id);
             alt i.node {
               ast::item_res(_, _, _, d_id, c_id) { vfn(d_id); vfn(c_id); }
+              ast::item_enum(vs, _) { for v in vs { vfn(v.node.id); } }
               _ {}
             }
         },
diff --git a/src/rustc/metadata/common.rs b/src/rustc/metadata/common.rs
index 3d3a3fff48f..db3dc4078ed 100644
--- a/src/rustc/metadata/common.rs
+++ b/src/rustc/metadata/common.rs
@@ -28,7 +28,7 @@ const tag_items_data_item_symbol: uint = 0x0du;
 
 const tag_items_data_item_variant: uint = 0x0eu;
 
-const tag_items_data_item_enum_id: uint = 0x0fu;
+const tag_items_data_parent_item: uint = 0x0fu;
 
 const tag_index: uint = 0x11u;
 
@@ -62,6 +62,8 @@ const tag_crate_dep: uint = 0x26u;
 
 const tag_crate_hash: uint = 0x28u;
 
+const tag_parent_item: uint = 0x29u;
+
 const tag_mod_impl: uint = 0x30u;
 
 const tag_item_method: uint = 0x31u;
diff --git a/src/rustc/metadata/csearch.rs b/src/rustc/metadata/csearch.rs
index 6a336da1e52..6be4124d5e6 100644
--- a/src/rustc/metadata/csearch.rs
+++ b/src/rustc/metadata/csearch.rs
@@ -19,7 +19,7 @@ export get_type;
 export get_impl_iface;
 export get_impl_method;
 export get_item_path;
-export maybe_get_item_ast;
+export maybe_get_item_ast, found_ast, found, found_parent, not_found;
 
 fn get_symbol(cstore: cstore::cstore, def: ast::def_id) -> str {
     let cdata = cstore::get_crate_data(cstore, def.crate).data;
@@ -80,11 +80,17 @@ fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path {
     [ast_map::path_mod(cdata.name)] + path
 }
 
+enum found_ast {
+    found(ast::inlined_item),
+    found_parent(ast::def_id, ast::inlined_item),
+    not_found,
+}
+
 // Finds the AST for this item in the crate metadata, if any.  If the item was
 // not marked for inlining, then the AST will not be present and hence none
 // will be returned.
 fn maybe_get_item_ast(tcx: ty::ctxt, maps: maps, def: ast::def_id)
-    -> option<ast::inlined_item> {
+    -> found_ast {
     let cstore = tcx.sess.cstore;
     let cdata = cstore::get_crate_data(cstore, def.crate);
     decoder::maybe_get_item_ast(cdata, tcx, maps, def.node)
diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs
index f78c0ade6f1..ac6e32f292d 100644
--- a/src/rustc/metadata/decoder.rs
+++ b/src/rustc/metadata/decoder.rs
@@ -96,9 +96,12 @@ fn item_symbol(item: ebml::doc) -> str {
     ret str::from_bytes(ebml::doc_data(sym));
 }
 
-fn variant_enum_id(d: ebml::doc) -> ast::def_id {
-    let tagdoc = ebml::get_doc(d, tag_items_data_item_enum_id);
-    ret parse_def_id(ebml::doc_data(tagdoc));
+fn item_parent_item(d: ebml::doc) -> option<ast::def_id> {
+    let found = none;
+    ebml::tagged_docs(d, tag_items_data_parent_item) {|did|
+        found = some(parse_def_id(ebml::doc_data(did)));
+    }
+    found
 }
 
 fn variant_disr_val(d: ebml::doc) -> option<int> {
@@ -230,7 +233,7 @@ fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) ->
       'm' { ast::def_mod(did) }
       'n' { ast::def_native_mod(did) }
       'v' {
-        let tid = variant_enum_id(item);
+        let tid = option::get(item_parent_item(item));
         tid = {crate: cnum, node: tid.node};
         ast::def_variant(tid, did)
       }
@@ -278,10 +281,26 @@ fn get_item_path(cdata: cmd, id: ast::node_id) -> ast_map::path {
 }
 
 fn maybe_get_item_ast(cdata: cmd, tcx: ty::ctxt, maps: maps,
-                      id: ast::node_id) -> option<ast::inlined_item> {
+                      id: ast::node_id) -> csearch::found_ast {
     let item_doc = lookup_item(id, cdata.data);
     let path = vec::init(item_path(item_doc));
-    astencode::decode_inlined_item(cdata, tcx, maps, path, item_doc)
+    alt astencode::decode_inlined_item(cdata, tcx, maps, path, item_doc) {
+      some(ii) { csearch::found(ii) }
+      none {
+        alt item_parent_item(item_doc) {
+          some(did) {
+            let did = translate_def_id(cdata, did);
+            let parent_item = lookup_item(did.node, cdata.data);
+            alt astencode::decode_inlined_item(cdata, tcx, maps, path,
+                                               parent_item) {
+              some(ii) { csearch::found_parent(did, ii) }
+              none { csearch::not_found }
+            }
+          }
+          none { csearch::not_found }
+        }
+      }
+    }
 }
 
 fn get_enum_variants(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 6a8a77b1191..ae9ab788ac0 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -241,8 +241,8 @@ fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: ebml::writer, disr_val: int) {
     ebml_w.end_tag();
 }
 
-fn encode_enum_id(ebml_w: ebml::writer, id: def_id) {
-    ebml_w.start_tag(tag_items_data_item_enum_id);
+fn encode_parent_item(ebml_w: ebml::writer, id: def_id) {
+    ebml_w.start_tag(tag_items_data_parent_item);
     ebml_w.writer.write(str::bytes(def_to_str(id)));
     ebml_w.end_tag();
 }
@@ -260,7 +260,7 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
         encode_def_id(ebml_w, local_def(variant.node.id));
         encode_family(ebml_w, 'v');
         encode_name(ebml_w, variant.node.name);
-        encode_enum_id(ebml_w, local_def(id));
+        encode_parent_item(ebml_w, local_def(id));
         encode_type(ecx, ebml_w,
                     node_id_to_type(ecx.ccx.tcx, variant.node.id));
         if vec::len(variant.node.args) > 0u && ty_params.len() == 0u {
@@ -397,6 +397,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
         for v: variant in variants {
             encode_variant_id(ebml_w, local_def(v.node.id));
         }
+        astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
         encode_path(ebml_w, path, ast_map::path_name(item.ident));
         ebml_w.end_tag();
         encode_enum_variant_info(ecx, ebml_w, item.id, variants,
@@ -414,11 +415,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
         encode_type_param_bounds(ebml_w, ecx, tps);
         encode_type(ecx, ebml_w, ty::ty_fn_ret(fn_ty));
         encode_name(ebml_w, item.ident);
-        if tps.len() == 0u {
-            encode_symbol(ecx, ebml_w, item.id);
-        } else {
-            astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
-        }
+        astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
         encode_path(ebml_w, path, ast_map::path_name(item.ident));
         ebml_w.end_tag();
 
@@ -428,9 +425,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
         encode_family(ebml_w, 'f');
         encode_type_param_bounds(ebml_w, ecx, tps);
         encode_type(ecx, ebml_w, fn_ty);
-        if tps.len() == 0u {
-            encode_symbol(ecx, ebml_w, ctor_id);
-        }
+        encode_parent_item(ebml_w, local_def(item.id));
         encode_path(ebml_w, path, ast_map::path_name(item.ident));
         ebml_w.end_tag();
       }