]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/metadata/encoder.rs
auto merge of #15999 : Kimundi/rust/fix_folder, r=nikomatsakis
[rust.git] / src / librustc / metadata / encoder.rs
index 87333499ec3a2f2a10b1a2ce32abd8b770a5b4cd..dbda4f58d960f91fc721e205ccdc5431acf6dc87 100644 (file)
@@ -26,6 +26,7 @@
 use middle::typeck;
 use middle::stability;
 use middle;
+use util::io::SeekableMemWriter;
 use util::nodemap::{NodeMap, NodeSet};
 
 use serialize::Encodable;
@@ -33,7 +34,6 @@
 use std::gc::Gc;
 use std::hash::Hash;
 use std::hash;
-use std::io::MemWriter;
 use std::mem;
 use std::collections::HashMap;
 use syntax::abi;
@@ -43,6 +43,7 @@
 use syntax::ast_map;
 use syntax::ast_util::*;
 use syntax::ast_util;
+use syntax::ast_util::PostExpansionMethod;
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
 use syntax::diagnostic::SpanHandler;
@@ -60,7 +61,7 @@ pub enum InlinedItemRef<'a> {
     IIForeignRef(&'a ast::ForeignItem)
 }
 
-pub type Encoder<'a> = writer::Encoder<'a, MemWriter>;
+pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
 
 pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
                                   ebml_w: &mut Encoder,
@@ -208,6 +209,18 @@ fn encode_variant_id(ebml_w: &mut Encoder, vid: DefId) {
     ebml_w.end_tag();
 }
 
+pub fn write_closure_type(ecx: &EncodeContext,
+                          ebml_w: &mut Encoder,
+                          closure_type: &ty::ClosureTy) {
+    let ty_str_ctxt = &tyencode::ctxt {
+        diag: ecx.diag,
+        ds: def_to_string,
+        tcx: ecx.tcx,
+        abbrevs: &ecx.type_abbrevs
+    };
+    tyencode::enc_closure_ty(ebml_w.writer, ty_str_ctxt, closure_type);
+}
+
 pub fn write_type(ecx: &EncodeContext,
                   ebml_w: &mut Encoder,
                   typ: ty::t) {
@@ -301,8 +314,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
                             ebml_w: &mut Encoder,
                             id: NodeId,
                             variants: &[P<Variant>],
-                            index: &mut Vec<entry<i64>>,
-                            generics: &ast::Generics) {
+                            index: &mut Vec<entry<i64>>) {
     debug!("encode_enum_variant_info(id={:?})", id);
 
     let mut disr_val = 0;
@@ -330,10 +342,6 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
         encode_stability(ebml_w, stab);
 
         match variant.node.kind {
-            ast::TupleVariantKind(ref args)
-                    if args.len() > 0 && generics.ty_params.len() == 0 => {
-                encode_symbol(ecx, ebml_w, variant.node.id);
-            }
             ast::TupleVariantKind(_) => {},
             ast::StructVariantKind(_) => {
                 let fields = ty::lookup_struct_fields(ecx.tcx, def_id);
@@ -401,7 +409,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
             for base_impl_did in implementations.borrow().iter() {
                 for &method_did in impl_methods.get(base_impl_did).iter() {
                     let m = ty::method(ecx.tcx, method_did);
-                    if m.explicit_self == ast::SelfStatic {
+                    if m.explicit_self == ty::StaticExplicitSelfCategory {
                         encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
                     }
                 }
@@ -420,7 +428,7 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
     match ecx.tcx.trait_methods_cache.borrow().find(&exp.def_id) {
         Some(methods) => {
             for m in methods.iter() {
-                if m.explicit_self == ast::SelfStatic {
+                if m.explicit_self == ty::StaticExplicitSelfCategory {
                     encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
                 }
             }
@@ -622,15 +630,22 @@ fn encode_visibility(ebml_w: &mut Encoder, visibility: Visibility) {
     ebml_w.end_tag();
 }
 
-fn encode_explicit_self(ebml_w: &mut Encoder, explicit_self: ast::ExplicitSelf_) {
+fn encode_explicit_self(ebml_w: &mut Encoder,
+                        explicit_self: &ty::ExplicitSelfCategory) {
     ebml_w.start_tag(tag_item_trait_method_explicit_self);
 
     // Encode the base self type.
-    match explicit_self {
-        SelfStatic   => { ebml_w.writer.write(&[ 's' as u8 ]); }
-        SelfValue(_) => { ebml_w.writer.write(&[ 'v' as u8 ]); }
-        SelfUniq(_)  => { ebml_w.writer.write(&[ '~' as u8 ]); }
-        SelfRegion(_, m, _) => {
+    match *explicit_self {
+        ty::StaticExplicitSelfCategory => {
+            ebml_w.writer.write(&[ 's' as u8 ]);
+        }
+        ty::ByValueExplicitSelfCategory => {
+            ebml_w.writer.write(&[ 'v' as u8 ]);
+        }
+        ty::ByBoxExplicitSelfCategory => {
+            ebml_w.writer.write(&[ '~' as u8 ]);
+        }
+        ty::ByReferenceExplicitSelfCategory(_, m) => {
             // FIXME(#4846) encode custom lifetime
             ebml_w.writer.write(&['&' as u8]);
             encode_mutability(ebml_w, m);
@@ -747,10 +762,10 @@ fn encode_method_ty_fields(ecx: &EncodeContext,
                               tag_item_method_tps);
     encode_method_fty(ecx, ebml_w, &method_ty.fty);
     encode_visibility(ebml_w, method_ty.vis);
-    encode_explicit_self(ebml_w, method_ty.explicit_self);
+    encode_explicit_self(ebml_w, &method_ty.explicit_self);
     let fn_style = method_ty.fty.fn_style;
     match method_ty.explicit_self {
-        ast::SelfStatic => {
+        ty::StaticExplicitSelfCategory => {
             encode_family(ebml_w, fn_style_static_method_family(fn_style));
         }
         _ => encode_family(ebml_w, style_fn_family(fn_style))
@@ -798,7 +813,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
         } else {
             encode_symbol(ecx, ebml_w, m.def_id.node);
         }
-        encode_method_argument_names(ebml_w, method_fn_decl(&*ast_method));
+        encode_method_argument_names(ebml_w, &*ast_method.pe_fn_decl());
     }
 
     ebml_w.end_tag();
@@ -999,7 +1014,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         encode_stability(ebml_w, stab);
         ebml_w.end_tag();
       }
-      ItemEnum(ref enum_definition, ref generics) => {
+      ItemEnum(ref enum_definition, _) => {
         add_to_index(item, ebml_w, index);
 
         ebml_w.start_tag(tag_items_data_item);
@@ -1026,8 +1041,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
                                  ebml_w,
                                  item.id,
                                  (*enum_definition).variants.as_slice(),
-                                 index,
-                                 generics);
+                                 index);
       }
       ItemStruct(struct_def, _) => {
         let fields = ty::lookup_struct_fields(tcx, def_id);
@@ -1205,7 +1219,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
             encode_path(ebml_w, path.clone().chain(Some(elem).move_iter()));
 
             match method_ty.explicit_self {
-                SelfStatic => {
+                ty::StaticExplicitSelfCategory => {
                     encode_family(ebml_w,
                                   fn_style_static_method_family(
                                       method_ty.fty.fn_style));
@@ -1232,7 +1246,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
                     encode_attributes(ebml_w, m.attrs.as_slice());
                     // If this is a static method, we've already encoded
                     // this.
-                    if method_ty.explicit_self != SelfStatic {
+                    if method_ty.explicit_self != ty::StaticExplicitSelfCategory {
                         // FIXME: I feel like there is something funny going on.
                         let pty = ty::lookup_item_type(tcx, method_def_id);
                         encode_bounds_and_type(ebml_w, ecx, &pty);
@@ -1240,7 +1254,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
                     encode_method_sort(ebml_w, 'p');
                     encode_inlined_item(ecx, ebml_w,
                                         IIMethodRef(def_id, true, &*m));
-                    encode_method_argument_names(ebml_w, method_fn_decl(m));
+                    encode_method_argument_names(ebml_w, &*m.pe_fn_decl());
                 }
             }
 
@@ -1393,7 +1407,7 @@ fn encode_info_for_items(ecx: &EncodeContext,
 // Path and definition ID indexing
 
 fn encode_index<T: Hash>(ebml_w: &mut Encoder, index: Vec<entry<T>>,
-                         write_fn: |&mut MemWriter, &T|) {
+                         write_fn: |&mut SeekableMemWriter, &T|) {
     let mut buckets: Vec<Vec<entry<T>>> = Vec::from_fn(256, |_| Vec::new());
     for elt in index.move_iter() {
         let h = hash::hash(&elt.val) as uint;
@@ -1410,7 +1424,7 @@ fn encode_index<T: Hash>(ebml_w: &mut Encoder, index: Vec<entry<T>>,
             ebml_w.start_tag(tag_index_buckets_bucket_elt);
             assert!(elt.pos < 0xffff_ffff);
             {
-                let wr: &mut MemWriter = ebml_w.writer;
+                let wr: &mut SeekableMemWriter = ebml_w.writer;
                 wr.write_be_u32(elt.pos as u32);
             }
             write_fn(ebml_w.writer, &elt.val);
@@ -1422,15 +1436,15 @@ fn encode_index<T: Hash>(ebml_w: &mut Encoder, index: Vec<entry<T>>,
     ebml_w.start_tag(tag_index_table);
     for pos in bucket_locs.iter() {
         assert!(*pos < 0xffff_ffff);
-        let wr: &mut MemWriter = ebml_w.writer;
+        let wr: &mut SeekableMemWriter = ebml_w.writer;
         wr.write_be_u32(*pos as u32);
     }
     ebml_w.end_tag();
     ebml_w.end_tag();
 }
 
-fn write_i64(writer: &mut MemWriter, &n: &i64) {
-    let wr: &mut MemWriter = writer;
+fn write_i64(writer: &mut SeekableMemWriter, &n: &i64) {
+    let wr: &mut SeekableMemWriter = writer;
     assert!(n < 0x7fff_ffff);
     wr.write_be_u32(n as u32);
 }
@@ -1476,6 +1490,7 @@ fn encode_attributes(ebml_w: &mut Encoder, attrs: &[Attribute]) {
     ebml_w.start_tag(tag_attributes);
     for attr in attrs.iter() {
         ebml_w.start_tag(tag_attribute);
+        ebml_w.wr_tagged_u8(tag_attribute_is_sugared_doc, attr.node.is_sugared_doc as u8);
         encode_meta_item(ebml_w, attr.node.value);
         ebml_w.end_tag();
     }
@@ -1530,14 +1545,14 @@ fn encode_lang_items(ecx: &EncodeContext, ebml_w: &mut Encoder) {
 
                 ebml_w.start_tag(tag_lang_items_item_id);
                 {
-                    let wr: &mut MemWriter = ebml_w.writer;
+                    let wr: &mut SeekableMemWriter = ebml_w.writer;
                     wr.write_be_u32(i as u32);
                 }
                 ebml_w.end_tag();   // tag_lang_items_item_id
 
                 ebml_w.start_tag(tag_lang_items_item_node_id);
                 {
-                    let wr: &mut MemWriter = ebml_w.writer;
+                    let wr: &mut SeekableMemWriter = ebml_w.writer;
                     wr.write_be_u32(id.node as u32);
                 }
                 ebml_w.end_tag();   // tag_lang_items_item_node_id
@@ -1604,12 +1619,55 @@ fn encode_macro_defs(ecx: &EncodeContext,
                      krate: &Crate,
                      ebml_w: &mut Encoder) {
     ebml_w.start_tag(tag_exported_macros);
-    for span in krate.exported_macros.iter() {
-        encode_macro_def(ecx, ebml_w, span);
+    for item in krate.exported_macros.iter() {
+        encode_macro_def(ecx, ebml_w, &item.span);
     }
     ebml_w.end_tag();
 }
 
+fn encode_unboxed_closures<'a>(
+                           ecx: &'a EncodeContext,
+                           ebml_w: &'a mut Encoder) {
+    ebml_w.start_tag(tag_unboxed_closures);
+    for (unboxed_closure_id, unboxed_closure_type) in
+            ecx.tcx.unboxed_closure_types.borrow().iter() {
+        if unboxed_closure_id.krate != LOCAL_CRATE {
+            continue
+        }
+
+        ebml_w.start_tag(tag_unboxed_closure);
+        encode_def_id(ebml_w, *unboxed_closure_id);
+        ebml_w.start_tag(tag_unboxed_closure_type);
+        write_closure_type(ecx, ebml_w, unboxed_closure_type);
+        ebml_w.end_tag();
+        ebml_w.end_tag();
+    }
+    ebml_w.end_tag();
+}
+
+fn encode_struct_field_attrs(ebml_w: &mut Encoder, krate: &Crate) {
+    struct StructFieldVisitor<'a, 'b> {
+        ebml_w: &'a mut Encoder<'b>,
+    }
+
+    impl<'a, 'b> Visitor<()> for StructFieldVisitor<'a, 'b> {
+        fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
+            self.ebml_w.start_tag(tag_struct_field);
+            self.ebml_w.wr_tagged_u32(tag_struct_field_id, field.node.id);
+            encode_attributes(self.ebml_w, field.node.attrs.as_slice());
+            self.ebml_w.end_tag();
+        }
+    }
+
+    ebml_w.start_tag(tag_struct_fields);
+    visit::walk_crate(&mut StructFieldVisitor {
+        ebml_w: ebml_w
+    }, krate, ());
+    ebml_w.end_tag();
+}
+
+
+
 struct ImplVisitor<'a,'b,'c> {
     ecx: &'a EncodeContext<'b>,
     ebml_w: &'a mut Encoder<'c>,
@@ -1766,12 +1824,12 @@ fn encode_dylib_dependency_formats(ebml_w: &mut Encoder, ecx: &EncodeContext) {
       0, 0, 0, 1 ];
 
 pub fn encode_metadata(parms: EncodeParams, krate: &Crate) -> Vec<u8> {
-    let mut wr = MemWriter::new();
+    let mut wr = SeekableMemWriter::new();
     encode_metadata_inner(&mut wr, parms, krate);
     wr.unwrap().move_iter().collect()
 }
 
-fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate) {
+fn encode_metadata_inner(wr: &mut SeekableMemWriter, parms: EncodeParams, krate: &Crate) {
     struct Stats {
         attr_bytes: u64,
         dep_bytes: u64,
@@ -1779,6 +1837,7 @@ struct Stats {
         native_lib_bytes: u64,
         plugin_registrar_fn_bytes: u64,
         macro_defs_bytes: u64,
+        unboxed_closure_bytes: u64,
         impl_bytes: u64,
         misc_bytes: u64,
         item_bytes: u64,
@@ -1793,6 +1852,7 @@ struct Stats {
         native_lib_bytes: 0,
         plugin_registrar_fn_bytes: 0,
         macro_defs_bytes: 0,
+        unboxed_closure_bytes: 0,
         impl_bytes: 0,
         misc_bytes: 0,
         item_bytes: 0,
@@ -1865,6 +1925,11 @@ struct Stats {
     encode_macro_defs(&ecx, krate, &mut ebml_w);
     stats.macro_defs_bytes = ebml_w.writer.tell().unwrap() - i;
 
+    // Encode the types of all unboxed closures in this crate.
+    i = ebml_w.writer.tell().unwrap();
+    encode_unboxed_closures(&ecx, &mut ebml_w);
+    stats.unboxed_closure_bytes = ebml_w.writer.tell().unwrap() - i;
+
     // Encode the def IDs of impls, for coherence checking.
     i = ebml_w.writer.tell().unwrap();
     encode_impls(&ecx, krate, &mut ebml_w);
@@ -1887,6 +1952,8 @@ struct Stats {
     stats.index_bytes = ebml_w.writer.tell().unwrap() - i;
     ebml_w.end_tag();
 
+    encode_struct_field_attrs(&mut ebml_w, krate);
+
     stats.total_bytes = ebml_w.writer.tell().unwrap();
 
     if tcx.sess.meta_stats() {
@@ -1903,6 +1970,7 @@ struct Stats {
         println!("          native bytes: {}", stats.native_lib_bytes);
         println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
         println!("       macro def bytes: {}", stats.macro_defs_bytes);
+        println!(" unboxed closure bytes: {}", stats.unboxed_closure_bytes);
         println!("            impl bytes: {}", stats.impl_bytes);
         println!("            misc bytes: {}", stats.misc_bytes);
         println!("            item bytes: {}", stats.item_bytes);
@@ -1914,7 +1982,7 @@ struct Stats {
 
 // Get the encoded string for a type
 pub fn encoded_ty(tcx: &ty::ctxt, t: ty::t) -> String {
-    let mut wr = MemWriter::new();
+    let mut wr = SeekableMemWriter::new();
     tyencode::enc_ty(&mut wr, &tyencode::ctxt {
         diag: tcx.sess.diagnostic(),
         ds: def_to_string,