]> git.lizzy.rs Git - rust.git/blob - src/librustc_metadata/encoder.rs
Rollup merge of #31031 - brson:issue-30123, r=nikomatsakis
[rust.git] / src / librustc_metadata / encoder.rs
1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // Metadata encoding
12
13 #![allow(unused_must_use)] // everything is just a MemWriter, can't fail
14 #![allow(non_camel_case_types)]
15
16 use common::*;
17 use cstore;
18 use decoder;
19 use tyencode;
20 use index::{self, IndexData};
21
22 use middle::cstore::{LOCAL_CRATE, CrateStore, InlinedItemRef, LinkMeta, tls};
23 use middle::def;
24 use middle::def_id::{CRATE_DEF_INDEX, DefId};
25 use middle::dependency_format::Linkage;
26 use middle::stability;
27 use middle::subst;
28 use middle::ty::{self, Ty};
29
30 use rustc::back::svh::Svh;
31 use rustc::front::map::{LinkedPath, PathElem, PathElems};
32 use rustc::front::map as ast_map;
33 use rustc::mir::repr::Mir;
34 use rustc::session::config;
35 use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};
36
37 use serialize::Encodable;
38 use std::cell::RefCell;
39 use std::io::prelude::*;
40 use std::io::{Cursor, SeekFrom};
41 use std::rc::Rc;
42 use std::u32;
43 use syntax::abi;
44 use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum};
45 use syntax::attr;
46 use syntax::attr::AttrMetaMethods;
47 use syntax::errors::Handler;
48 use syntax::parse::token::special_idents;
49 use syntax;
50 use rbml::writer::Encoder;
51
52 use rustc_front::hir;
53 use rustc_front::intravisit::Visitor;
54 use rustc_front::intravisit;
55
56 pub type EncodeInlinedItem<'a> =
57     Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
58
59 pub struct EncodeParams<'a, 'tcx: 'a> {
60     pub diag: &'a Handler,
61     pub tcx: &'a ty::ctxt<'tcx>,
62     pub reexports: &'a def::ExportMap,
63     pub item_symbols: &'a RefCell<NodeMap<String>>,
64     pub link_meta: &'a LinkMeta,
65     pub cstore: &'a cstore::CStore,
66     pub encode_inlined_item: EncodeInlinedItem<'a>,
67     pub reachable: &'a NodeSet,
68     pub mir_map: &'a NodeMap<Mir<'tcx>>,
69 }
70
71 pub struct EncodeContext<'a, 'tcx: 'a> {
72     pub diag: &'a Handler,
73     pub tcx: &'a ty::ctxt<'tcx>,
74     pub reexports: &'a def::ExportMap,
75     pub item_symbols: &'a RefCell<NodeMap<String>>,
76     pub link_meta: &'a LinkMeta,
77     pub cstore: &'a cstore::CStore,
78     pub encode_inlined_item: RefCell<EncodeInlinedItem<'a>>,
79     pub type_abbrevs: tyencode::abbrev_map<'tcx>,
80     pub reachable: &'a NodeSet,
81     pub mir_map: &'a NodeMap<Mir<'tcx>>,
82 }
83
84 impl<'a, 'tcx> EncodeContext<'a,'tcx> {
85     fn local_id(&self, def_id: DefId) -> NodeId {
86         self.tcx.map.as_local_node_id(def_id).unwrap()
87     }
88 }
89
90 /// "interned" entries referenced by id
91 #[derive(PartialEq, Eq, Hash)]
92 pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) }
93
94 struct CrateIndex<'tcx> {
95     items: IndexData,
96     xrefs: FnvHashMap<XRef<'tcx>, u32>, // sequentially-assigned
97 }
98
99 impl<'tcx> CrateIndex<'tcx> {
100     fn record(&mut self, id: DefId, rbml_w: &mut Encoder) {
101         let position = rbml_w.mark_stable_position();
102         self.items.record(id, position);
103     }
104
105     fn add_xref(&mut self, xref: XRef<'tcx>) -> u32 {
106         let old_len = self.xrefs.len() as u32;
107         *self.xrefs.entry(xref).or_insert(old_len)
108     }
109 }
110
111 fn encode_name(rbml_w: &mut Encoder, name: Name) {
112     rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str());
113 }
114
115 fn encode_def_id(rbml_w: &mut Encoder, id: DefId) {
116     rbml_w.wr_tagged_u64(tag_def_id, def_to_u64(id));
117 }
118
119 /// For every DefId that we create a metadata item for, we include a
120 /// serialized copy of its DefKey, which allows us to recreate a path.
121 fn encode_def_id_and_key(ecx: &EncodeContext,
122                          rbml_w: &mut Encoder,
123                          def_id: DefId)
124 {
125     encode_def_id(rbml_w, def_id);
126     encode_def_key(ecx, rbml_w, def_id);
127 }
128
129 fn encode_def_key(ecx: &EncodeContext,
130                   rbml_w: &mut Encoder,
131                   def_id: DefId)
132 {
133     rbml_w.start_tag(tag_def_key);
134     let def_key = ecx.tcx.map.def_key(def_id);
135     def_key.encode(rbml_w);
136     rbml_w.end_tag();
137 }
138
139 fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder,
140                               ecx: &EncodeContext<'a, 'tcx>,
141                               trait_ref: ty::TraitRef<'tcx>,
142                               tag: usize) {
143     rbml_w.start_tag(tag);
144     tyencode::enc_trait_ref(rbml_w.writer, &ecx.ty_str_ctxt(), trait_ref);
145     rbml_w.mark_stable_position();
146     rbml_w.end_tag();
147 }
148
149 // Item info table encoding
150 fn encode_family(rbml_w: &mut Encoder, c: char) {
151     rbml_w.wr_tagged_u8(tag_items_data_item_family, c as u8);
152 }
153
154 pub fn def_to_u64(did: DefId) -> u64 {
155     assert!(did.index.as_u32() < u32::MAX);
156     (did.krate as u64) << 32 | (did.index.as_usize() as u64)
157 }
158
159 pub fn def_to_string(did: DefId) -> String {
160     format!("{}:{}", did.krate, did.index.as_usize())
161 }
162
163 fn encode_item_variances(rbml_w: &mut Encoder,
164                          ecx: &EncodeContext,
165                          id: NodeId) {
166     let v = ecx.tcx.item_variances(ecx.tcx.map.local_def_id(id));
167     rbml_w.start_tag(tag_item_variances);
168     v.encode(rbml_w);
169     rbml_w.end_tag();
170 }
171
172 fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder,
173                                              ecx: &EncodeContext<'a, 'tcx>,
174                                              index: &mut CrateIndex<'tcx>,
175                                              id: NodeId) {
176     encode_bounds_and_type(rbml_w,
177                            ecx,
178                            index,
179                            &ecx.tcx.lookup_item_type(ecx.tcx.map.local_def_id(id)),
180                            &ecx.tcx.lookup_predicates(ecx.tcx.map.local_def_id(id)));
181 }
182
183 fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder,
184                                     ecx: &EncodeContext<'a, 'tcx>,
185                                     index: &mut CrateIndex<'tcx>,
186                                     scheme: &ty::TypeScheme<'tcx>,
187                                     predicates: &ty::GenericPredicates<'tcx>) {
188     encode_generics(rbml_w, ecx, index,
189                     &scheme.generics, &predicates, tag_item_generics);
190     encode_type(ecx, rbml_w, scheme.ty);
191 }
192
193 fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) {
194     let id = def_to_u64(vid);
195     rbml_w.wr_tagged_u64(tag_items_data_item_variant, id);
196     rbml_w.wr_tagged_u64(tag_mod_child, id);
197 }
198
199 fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
200                             rbml_w: &mut Encoder,
201                             closure_type: &ty::ClosureTy<'tcx>) {
202     tyencode::enc_closure_ty(rbml_w.writer, &ecx.ty_str_ctxt(), closure_type);
203     rbml_w.mark_stable_position();
204 }
205
206 fn encode_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
207                          rbml_w: &mut Encoder,
208                          typ: Ty<'tcx>) {
209     rbml_w.start_tag(tag_items_data_item_type);
210     tyencode::enc_ty(rbml_w.writer, &ecx.ty_str_ctxt(), typ);
211     rbml_w.mark_stable_position();
212     rbml_w.end_tag();
213 }
214
215 fn encode_region(ecx: &EncodeContext,
216                  rbml_w: &mut Encoder,
217                  r: ty::Region) {
218     rbml_w.start_tag(tag_items_data_region);
219     tyencode::enc_region(rbml_w.writer, &ecx.ty_str_ctxt(), r);
220     rbml_w.mark_stable_position();
221     rbml_w.end_tag();
222 }
223
224 fn encode_symbol(ecx: &EncodeContext,
225                  rbml_w: &mut Encoder,
226                  id: NodeId) {
227     match ecx.item_symbols.borrow().get(&id) {
228         Some(x) => {
229             debug!("encode_symbol(id={}, str={})", id, *x);
230             rbml_w.wr_tagged_str(tag_items_data_item_symbol, x);
231         }
232         None => {
233             ecx.diag.bug(&format!("encode_symbol: id not found {}", id));
234         }
235     }
236 }
237
238 fn encode_disr_val(_: &EncodeContext,
239                    rbml_w: &mut Encoder,
240                    disr_val: ty::Disr) {
241     rbml_w.wr_tagged_str(tag_disr_val, &disr_val.to_string());
242 }
243
244 fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) {
245     rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(id));
246 }
247
248 fn encode_struct_fields(rbml_w: &mut Encoder,
249                         variant: ty::VariantDef) {
250     for f in &variant.fields {
251         if f.name == special_idents::unnamed_field.name {
252             rbml_w.start_tag(tag_item_unnamed_field);
253         } else {
254             rbml_w.start_tag(tag_item_field);
255             encode_name(rbml_w, f.name);
256         }
257         encode_struct_field_family(rbml_w, f.vis);
258         encode_def_id(rbml_w, f.did);
259         rbml_w.end_tag();
260     }
261 }
262
263 fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
264                                       rbml_w: &mut Encoder,
265                                       id: NodeId,
266                                       vis: hir::Visibility,
267                                       index: &mut CrateIndex<'tcx>) {
268     debug!("encode_enum_variant_info(id={})", id);
269
270     let mut disr_val = 0;
271     let def = ecx.tcx.lookup_adt_def(ecx.tcx.map.local_def_id(id));
272     for variant in &def.variants {
273         let vid = variant.did;
274         let variant_node_id = ecx.local_id(vid);
275
276         if let ty::VariantKind::Struct = variant.kind() {
277             // tuple-like enum variant fields aren't really items so
278             // don't try to encode them.
279             for field in &variant.fields {
280                 encode_field(ecx, rbml_w, field, index);
281             }
282         }
283
284         index.record(vid, rbml_w);
285         rbml_w.start_tag(tag_items_data_item);
286         encode_def_id_and_key(ecx, rbml_w, vid);
287         encode_family(rbml_w, match variant.kind() {
288             ty::VariantKind::Struct => 'V',
289             ty::VariantKind::Tuple => 'v',
290             ty::VariantKind::Unit => 'w',
291         });
292         encode_name(rbml_w, variant.name);
293         encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(id));
294         encode_visibility(rbml_w, vis);
295
296         let attrs = ecx.tcx.get_attrs(vid);
297         encode_attributes(rbml_w, &attrs);
298         encode_repr_attrs(rbml_w, ecx, &attrs);
299
300         let stab = stability::lookup_stability(ecx.tcx, vid);
301         let depr = stability::lookup_deprecation(ecx.tcx, vid);
302         encode_stability(rbml_w, stab);
303         encode_deprecation(rbml_w, depr);
304
305         encode_struct_fields(rbml_w, variant);
306
307         let specified_disr_val = variant.disr_val;
308         if specified_disr_val != disr_val {
309             encode_disr_val(ecx, rbml_w, specified_disr_val);
310             disr_val = specified_disr_val;
311         }
312         encode_bounds_and_type_for_item(rbml_w, ecx, index, variant_node_id);
313
314         ecx.tcx.map.with_path(variant_node_id, |path| encode_path(rbml_w, path));
315         rbml_w.end_tag();
316         disr_val = disr_val.wrapping_add(1);
317     }
318 }
319
320 fn encode_path<PI: Iterator<Item=PathElem>>(rbml_w: &mut Encoder, path: PI) {
321     let path = path.collect::<Vec<_>>();
322     rbml_w.start_tag(tag_path);
323     rbml_w.wr_tagged_u32(tag_path_len, path.len() as u32);
324     for pe in &path {
325         let tag = match *pe {
326             ast_map::PathMod(_) => tag_path_elem_mod,
327             ast_map::PathName(_) => tag_path_elem_name
328         };
329         rbml_w.wr_tagged_str(tag, &pe.name().as_str());
330     }
331     rbml_w.end_tag();
332 }
333
334 /// Iterates through "auxiliary node IDs", which are node IDs that describe
335 /// top-level items that are sub-items of the given item. Specifically:
336 ///
337 /// * For newtype structs, iterates through the node ID of the constructor.
338 fn each_auxiliary_node_id<F>(item: &hir::Item, callback: F) -> bool where
339     F: FnOnce(NodeId) -> bool,
340 {
341     let mut continue_ = true;
342     match item.node {
343         hir::ItemStruct(ref struct_def, _) => {
344             // If this is a newtype struct, return the constructor.
345             if struct_def.is_tuple() {
346                 continue_ = callback(struct_def.id());
347             }
348         }
349         _ => {}
350     }
351
352     continue_
353 }
354
355 fn encode_reexports(ecx: &EncodeContext,
356                     rbml_w: &mut Encoder,
357                     id: NodeId) {
358     debug!("(encoding info for module) encoding reexports for {}", id);
359     match ecx.reexports.get(&id) {
360         Some(exports) => {
361             debug!("(encoding info for module) found reexports for {}", id);
362             for exp in exports {
363                 debug!("(encoding info for module) reexport '{}' ({:?}) for \
364                         {}",
365                        exp.name,
366                        exp.def_id,
367                        id);
368                 rbml_w.start_tag(tag_items_data_item_reexport);
369                 rbml_w.wr_tagged_u64(tag_items_data_item_reexport_def_id,
370                                      def_to_u64(exp.def_id));
371                 rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
372                                      &exp.name.as_str());
373                 rbml_w.end_tag();
374             }
375         },
376         None => debug!("(encoding info for module) found no reexports for {}", id),
377     }
378 }
379
380 fn encode_info_for_mod(ecx: &EncodeContext,
381                        rbml_w: &mut Encoder,
382                        md: &hir::Mod,
383                        attrs: &[ast::Attribute],
384                        id: NodeId,
385                        path: PathElems,
386                        name: Name,
387                        vis: hir::Visibility) {
388     rbml_w.start_tag(tag_items_data_item);
389     encode_def_id_and_key(ecx, rbml_w, ecx.tcx.map.local_def_id(id));
390     encode_family(rbml_w, 'm');
391     encode_name(rbml_w, name);
392     debug!("(encoding info for module) encoding info for module ID {}", id);
393
394     // Encode info about all the module children.
395     for item_id in &md.item_ids {
396         rbml_w.wr_tagged_u64(tag_mod_child,
397                              def_to_u64(ecx.tcx.map.local_def_id(item_id.id)));
398
399         let item = ecx.tcx.map.expect_item(item_id.id);
400         each_auxiliary_node_id(item, |auxiliary_node_id| {
401             rbml_w.wr_tagged_u64(tag_mod_child,
402                                  def_to_u64(ecx.tcx.map.local_def_id(auxiliary_node_id)));
403             true
404         });
405     }
406
407     encode_path(rbml_w, path.clone());
408     encode_visibility(rbml_w, vis);
409
410     let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(id));
411     let depr = stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(id));
412     encode_stability(rbml_w, stab);
413     encode_deprecation(rbml_w, depr);
414
415     // Encode the reexports of this module, if this module is public.
416     if vis == hir::Public {
417         debug!("(encoding info for module) encoding reexports for {}", id);
418         encode_reexports(ecx, rbml_w, id);
419     }
420     encode_attributes(rbml_w, attrs);
421
422     rbml_w.end_tag();
423 }
424
425 fn encode_struct_field_family(rbml_w: &mut Encoder,
426                               visibility: hir::Visibility) {
427     encode_family(rbml_w, match visibility {
428         hir::Public => 'g',
429         hir::Inherited => 'N'
430     });
431 }
432
433 fn encode_visibility(rbml_w: &mut Encoder, visibility: hir::Visibility) {
434     let ch = match visibility {
435         hir::Public => 'y',
436         hir::Inherited => 'i',
437     };
438     rbml_w.wr_tagged_u8(tag_items_data_item_visibility, ch as u8);
439 }
440
441 fn encode_constness(rbml_w: &mut Encoder, constness: hir::Constness) {
442     rbml_w.start_tag(tag_items_data_item_constness);
443     let ch = match constness {
444         hir::Constness::Const => 'c',
445         hir::Constness::NotConst => 'n',
446     };
447     rbml_w.wr_str(&ch.to_string());
448     rbml_w.end_tag();
449 }
450
451 fn encode_explicit_self(rbml_w: &mut Encoder,
452                         explicit_self: &ty::ExplicitSelfCategory) {
453     let tag = tag_item_trait_method_explicit_self;
454
455     // Encode the base self type.
456     match *explicit_self {
457         ty::ExplicitSelfCategory::Static => {
458             rbml_w.wr_tagged_bytes(tag, &['s' as u8]);
459         }
460         ty::ExplicitSelfCategory::ByValue => {
461             rbml_w.wr_tagged_bytes(tag, &['v' as u8]);
462         }
463         ty::ExplicitSelfCategory::ByBox => {
464             rbml_w.wr_tagged_bytes(tag, &['~' as u8]);
465         }
466         ty::ExplicitSelfCategory::ByReference(_, m) => {
467             // FIXME(#4846) encode custom lifetime
468             let ch = encode_mutability(m);
469             rbml_w.wr_tagged_bytes(tag, &['&' as u8, ch]);
470         }
471     }
472
473     fn encode_mutability(m: hir::Mutability) -> u8 {
474         match m {
475             hir::MutImmutable => 'i' as u8,
476             hir::MutMutable => 'm' as u8,
477         }
478     }
479 }
480
481 fn encode_item_sort(rbml_w: &mut Encoder, sort: char) {
482     rbml_w.wr_tagged_u8(tag_item_trait_item_sort, sort as u8);
483 }
484
485 fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
486                           rbml_w: &mut Encoder,
487                           field: ty::FieldDef<'tcx>,
488                           index: &mut CrateIndex<'tcx>) {
489     let nm = field.name;
490     let id = ecx.local_id(field.did);
491
492     index.record(field.did, rbml_w);
493     rbml_w.start_tag(tag_items_data_item);
494     debug!("encode_field: encoding {} {}", nm, id);
495     encode_struct_field_family(rbml_w, field.vis);
496     encode_name(rbml_w, nm);
497     encode_bounds_and_type_for_item(rbml_w, ecx, index, id);
498     encode_def_id_and_key(ecx, rbml_w, field.did);
499
500     let stab = stability::lookup_stability(ecx.tcx, field.did);
501     let depr = stability::lookup_deprecation(ecx.tcx, field.did);
502     encode_stability(rbml_w, stab);
503     encode_deprecation(rbml_w, depr);
504
505     rbml_w.end_tag();
506 }
507
508 fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
509                                          rbml_w: &mut Encoder,
510                                          name: Name,
511                                          struct_def: &hir::VariantData,
512                                          index: &mut CrateIndex<'tcx>,
513                                          struct_id: NodeId) {
514     let ctor_id = struct_def.id();
515     let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id);
516
517     index.record(ctor_def_id, rbml_w);
518     rbml_w.start_tag(tag_items_data_item);
519     encode_def_id_and_key(ecx, rbml_w, ctor_def_id);
520     encode_family(rbml_w, match *struct_def {
521         hir::VariantData::Struct(..) => 'S',
522         hir::VariantData::Tuple(..) => 's',
523         hir::VariantData::Unit(..) => 'u',
524     });
525     encode_bounds_and_type_for_item(rbml_w, ecx, index, ctor_id);
526     encode_name(rbml_w, name);
527     ecx.tcx.map.with_path(ctor_id, |path| encode_path(rbml_w, path));
528     encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(struct_id));
529
530     if ecx.item_symbols.borrow().contains_key(&ctor_id) {
531         encode_symbol(ecx, rbml_w, ctor_id);
532     }
533
534     let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(ctor_id));
535     let depr= stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(ctor_id));
536     encode_stability(rbml_w, stab);
537     encode_deprecation(rbml_w, depr);
538
539     // indicate that this is a tuple struct ctor, because downstream users will normally want
540     // the tuple struct definition, but without this there is no way for them to tell that
541     // they actually have a ctor rather than a normal function
542     rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]);
543
544     rbml_w.end_tag();
545 }
546
547 fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
548                              ecx: &EncodeContext<'a, 'tcx>,
549                              index: &mut CrateIndex<'tcx>,
550                              generics: &ty::Generics<'tcx>,
551                              predicates: &ty::GenericPredicates<'tcx>,
552                              tag: usize)
553 {
554     rbml_w.start_tag(tag);
555
556     for param in &generics.types {
557         rbml_w.start_tag(tag_type_param_def);
558         tyencode::enc_type_param_def(rbml_w.writer, &ecx.ty_str_ctxt(), param);
559         rbml_w.mark_stable_position();
560         rbml_w.end_tag();
561     }
562
563     // Region parameters
564     for param in &generics.regions {
565         rbml_w.start_tag(tag_region_param_def);
566
567         rbml_w.start_tag(tag_region_param_def_ident);
568         encode_name(rbml_w, param.name);
569         rbml_w.end_tag();
570
571         rbml_w.wr_tagged_u64(tag_region_param_def_def_id,
572                              def_to_u64(param.def_id));
573
574         rbml_w.wr_tagged_u64(tag_region_param_def_space,
575                              param.space.to_uint() as u64);
576
577         rbml_w.wr_tagged_u64(tag_region_param_def_index,
578                              param.index as u64);
579
580         for &bound_region in &param.bounds {
581             encode_region(ecx, rbml_w, bound_region);
582         }
583
584         rbml_w.end_tag();
585     }
586
587     encode_predicates_in_current_doc(rbml_w, ecx, index, predicates);
588
589     rbml_w.end_tag();
590 }
591
592 fn encode_predicates_in_current_doc<'a,'tcx>(rbml_w: &mut Encoder,
593                                              _ecx: &EncodeContext<'a,'tcx>,
594                                              index: &mut CrateIndex<'tcx>,
595                                              predicates: &ty::GenericPredicates<'tcx>)
596 {
597     for (space, _, predicate) in predicates.predicates.iter_enumerated() {
598         let tag = match space {
599             subst::TypeSpace => tag_type_predicate,
600             subst::SelfSpace => tag_self_predicate,
601             subst::FnSpace => tag_fn_predicate
602         };
603
604         rbml_w.wr_tagged_u32(tag,
605             index.add_xref(XRef::Predicate(predicate.clone())));
606     }
607 }
608
609 fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder,
610                               ecx: &EncodeContext<'a,'tcx>,
611                               index: &mut CrateIndex<'tcx>,
612                               predicates: &ty::GenericPredicates<'tcx>,
613                               tag: usize)
614 {
615     rbml_w.start_tag(tag);
616     encode_predicates_in_current_doc(rbml_w, ecx, index, predicates);
617     rbml_w.end_tag();
618 }
619
620 fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
621                                      rbml_w: &mut Encoder,
622                                      index: &mut CrateIndex<'tcx>,
623                                      method_ty: &ty::Method<'tcx>) {
624     encode_def_id_and_key(ecx, rbml_w, method_ty.def_id);
625     encode_name(rbml_w, method_ty.name);
626     encode_generics(rbml_w, ecx, index,
627                     &method_ty.generics, &method_ty.predicates,
628                     tag_method_ty_generics);
629     encode_visibility(rbml_w, method_ty.vis);
630     encode_explicit_self(rbml_w, &method_ty.explicit_self);
631     match method_ty.explicit_self {
632         ty::ExplicitSelfCategory::Static => {
633             encode_family(rbml_w, STATIC_METHOD_FAMILY);
634         }
635         _ => encode_family(rbml_w, METHOD_FAMILY)
636     }
637 }
638
639 fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
640                                               rbml_w: &mut Encoder,
641                                               index: &mut CrateIndex<'tcx>,
642                                               associated_const: &ty::AssociatedConst,
643                                               impl_path: PathElems,
644                                               parent_id: NodeId,
645                                               impl_item_opt: Option<&hir::ImplItem>) {
646     debug!("encode_info_for_associated_const({:?},{:?})",
647            associated_const.def_id,
648            associated_const.name);
649
650     index.record(associated_const.def_id, rbml_w);
651     rbml_w.start_tag(tag_items_data_item);
652
653     encode_def_id_and_key(ecx, rbml_w, associated_const.def_id);
654     encode_name(rbml_w, associated_const.name);
655     encode_visibility(rbml_w, associated_const.vis);
656     encode_family(rbml_w, 'C');
657
658     encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
659     encode_item_sort(rbml_w, 'C');
660
661     encode_bounds_and_type_for_item(rbml_w, ecx, index,
662                                     ecx.local_id(associated_const.def_id));
663
664     let stab = stability::lookup_stability(ecx.tcx, associated_const.def_id);
665     let depr = stability::lookup_deprecation(ecx.tcx, associated_const.def_id);
666     encode_stability(rbml_w, stab);
667     encode_deprecation(rbml_w, depr);
668
669     let elem = ast_map::PathName(associated_const.name);
670     encode_path(rbml_w, impl_path.chain(Some(elem)));
671
672     if let Some(ii) = impl_item_opt {
673         encode_attributes(rbml_w, &ii.attrs);
674         encode_inlined_item(ecx,
675                             rbml_w,
676                             InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id),
677                                                      ii));
678     }
679
680     rbml_w.end_tag();
681 }
682
683 fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
684                                     rbml_w: &mut Encoder,
685                                     index: &mut CrateIndex<'tcx>,
686                                     m: &ty::Method<'tcx>,
687                                     impl_path: PathElems,
688                                     is_default_impl: bool,
689                                     parent_id: NodeId,
690                                     impl_item_opt: Option<&hir::ImplItem>) {
691
692     debug!("encode_info_for_method: {:?} {:?}", m.def_id,
693            m.name);
694     index.record(m.def_id, rbml_w);
695     rbml_w.start_tag(tag_items_data_item);
696
697     encode_method_ty_fields(ecx, rbml_w, index, m);
698     encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
699     encode_item_sort(rbml_w, 'r');
700
701     let stab = stability::lookup_stability(ecx.tcx, m.def_id);
702     let depr = stability::lookup_deprecation(ecx.tcx, m.def_id);
703     encode_stability(rbml_w, stab);
704     encode_deprecation(rbml_w, depr);
705
706     let m_node_id = ecx.local_id(m.def_id);
707     encode_bounds_and_type_for_item(rbml_w, ecx, index, m_node_id);
708
709     let elem = ast_map::PathName(m.name);
710     encode_path(rbml_w, impl_path.chain(Some(elem)));
711     if let Some(impl_item) = impl_item_opt {
712         if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
713             encode_attributes(rbml_w, &impl_item.attrs);
714             let scheme = ecx.tcx.lookup_item_type(m.def_id);
715             let any_types = !scheme.generics.types.is_empty();
716             let needs_inline = any_types || is_default_impl ||
717                                attr::requests_inline(&impl_item.attrs);
718             if needs_inline || sig.constness == hir::Constness::Const {
719                 encode_inlined_item(ecx,
720                                     rbml_w,
721                                     InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id),
722                                                              impl_item));
723             }
724             encode_constness(rbml_w, sig.constness);
725             if !any_types {
726                 let m_id = ecx.local_id(m.def_id);
727                 encode_symbol(ecx, rbml_w, m_id);
728             }
729             encode_method_argument_names(rbml_w, &sig.decl);
730         }
731     }
732
733     rbml_w.end_tag();
734 }
735
736 fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
737                                              rbml_w: &mut Encoder,
738                                              index: &mut CrateIndex<'tcx>,
739                                              associated_type: &ty::AssociatedType<'tcx>,
740                                              impl_path: PathElems,
741                                              parent_id: NodeId,
742                                              impl_item_opt: Option<&hir::ImplItem>) {
743     debug!("encode_info_for_associated_type({:?},{:?})",
744            associated_type.def_id,
745            associated_type.name);
746
747     index.record(associated_type.def_id, rbml_w);
748     rbml_w.start_tag(tag_items_data_item);
749
750     encode_def_id_and_key(ecx, rbml_w, associated_type.def_id);
751     encode_name(rbml_w, associated_type.name);
752     encode_visibility(rbml_w, associated_type.vis);
753     encode_family(rbml_w, 'y');
754     encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
755     encode_item_sort(rbml_w, 't');
756
757     let stab = stability::lookup_stability(ecx.tcx, associated_type.def_id);
758     let depr = stability::lookup_deprecation(ecx.tcx, associated_type.def_id);
759     encode_stability(rbml_w, stab);
760     encode_deprecation(rbml_w, depr);
761
762     let elem = ast_map::PathName(associated_type.name);
763     encode_path(rbml_w, impl_path.chain(Some(elem)));
764
765     if let Some(ii) = impl_item_opt {
766         encode_attributes(rbml_w, &ii.attrs);
767     } else {
768         encode_predicates(rbml_w, ecx, index,
769                           &ecx.tcx.lookup_predicates(associated_type.def_id),
770                           tag_item_generics);
771     }
772
773     if let Some(ty) = associated_type.ty {
774         encode_type(ecx, rbml_w, ty);
775     }
776
777     rbml_w.end_tag();
778 }
779
780 fn encode_method_argument_names(rbml_w: &mut Encoder,
781                                 decl: &hir::FnDecl) {
782     rbml_w.start_tag(tag_method_argument_names);
783     for arg in &decl.inputs {
784         let tag = tag_method_argument_name;
785         if let hir::PatIdent(_, ref path1, _) = arg.pat.node {
786             let name = path1.node.name.as_str();
787             rbml_w.wr_tagged_bytes(tag, name.as_bytes());
788         } else {
789             rbml_w.wr_tagged_bytes(tag, &[]);
790         }
791     }
792     rbml_w.end_tag();
793 }
794
795 fn encode_repr_attrs(rbml_w: &mut Encoder,
796                      ecx: &EncodeContext,
797                      attrs: &[ast::Attribute]) {
798     let mut repr_attrs = Vec::new();
799     for attr in attrs {
800         repr_attrs.extend(attr::find_repr_attrs(ecx.tcx.sess.diagnostic(),
801                                                 attr));
802     }
803     rbml_w.start_tag(tag_items_data_item_repr);
804     repr_attrs.encode(rbml_w);
805     rbml_w.end_tag();
806 }
807
808 fn encode_inlined_item(ecx: &EncodeContext,
809                        rbml_w: &mut Encoder,
810                        ii: InlinedItemRef) {
811     let mut eii = ecx.encode_inlined_item.borrow_mut();
812     let eii: &mut EncodeInlinedItem = &mut *eii;
813     eii(ecx, rbml_w, ii);
814
815     let node_id = match ii {
816         InlinedItemRef::Item(item) => item.id,
817         InlinedItemRef::TraitItem(_, trait_item) => trait_item.id,
818         InlinedItemRef::ImplItem(_, impl_item) => impl_item.id,
819         InlinedItemRef::Foreign(foreign_item) => foreign_item.id
820     };
821
822     encode_mir(ecx, rbml_w, node_id);
823 }
824
825 fn encode_mir(ecx: &EncodeContext, rbml_w: &mut Encoder, node_id: NodeId) {
826     if let Some(mir) = ecx.mir_map.get(&node_id) {
827         rbml_w.start_tag(tag_mir as usize);
828         rbml_w.emit_opaque(|opaque_encoder| {
829             tls::enter_encoding_context(ecx, opaque_encoder, |_, opaque_encoder| {
830                 Encodable::encode(mir, opaque_encoder)
831             })
832         }).unwrap();
833         rbml_w.end_tag();
834     }
835 }
836
837 const FN_FAMILY: char = 'f';
838 const STATIC_METHOD_FAMILY: char = 'F';
839 const METHOD_FAMILY: char = 'h';
840
841 // Encodes the inherent implementations of a structure, enumeration, or trait.
842 fn encode_inherent_implementations(ecx: &EncodeContext,
843                                    rbml_w: &mut Encoder,
844                                    def_id: DefId) {
845     match ecx.tcx.inherent_impls.borrow().get(&def_id) {
846         None => {}
847         Some(implementations) => {
848             for &impl_def_id in implementations.iter() {
849                 rbml_w.start_tag(tag_items_data_item_inherent_impl);
850                 encode_def_id(rbml_w, impl_def_id);
851                 rbml_w.end_tag();
852             }
853         }
854     }
855 }
856
857 fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<&attr::Stability>) {
858     stab_opt.map(|stab| {
859         rbml_w.start_tag(tag_items_data_item_stability);
860         stab.encode(rbml_w).unwrap();
861         rbml_w.end_tag();
862     });
863 }
864
865 fn encode_deprecation(rbml_w: &mut Encoder, depr_opt: Option<attr::Deprecation>) {
866     depr_opt.map(|depr| {
867         rbml_w.start_tag(tag_items_data_item_deprecation);
868         depr.encode(rbml_w).unwrap();
869         rbml_w.end_tag();
870     });
871 }
872
873 fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
874                           rbml_w: &mut Encoder,
875                           xrefs: FnvHashMap<XRef<'tcx>, u32>)
876 {
877     let mut xref_positions = vec![0; xrefs.len()];
878     rbml_w.start_tag(tag_xref_data);
879     for (xref, id) in xrefs.into_iter() {
880         xref_positions[id as usize] = rbml_w.mark_stable_position() as u32;
881         match xref {
882             XRef::Predicate(p) => {
883                 tyencode::enc_predicate(rbml_w.writer, &ecx.ty_str_ctxt(), &p)
884             }
885         }
886     }
887     rbml_w.mark_stable_position();
888     rbml_w.end_tag();
889
890     rbml_w.start_tag(tag_xref_index);
891     index::write_dense_index(xref_positions, rbml_w.writer);
892     rbml_w.end_tag();
893 }
894
895 fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
896                                   rbml_w: &mut Encoder,
897                                   item: &hir::Item,
898                                   index: &mut CrateIndex<'tcx>,
899                                   path: PathElems,
900                                   vis: hir::Visibility) {
901     let tcx = ecx.tcx;
902
903     debug!("encoding info for item at {}",
904            tcx.sess.codemap().span_to_string(item.span));
905
906     let def_id = ecx.tcx.map.local_def_id(item.id);
907     let stab = stability::lookup_stability(tcx, ecx.tcx.map.local_def_id(item.id));
908     let depr = stability::lookup_deprecation(tcx, ecx.tcx.map.local_def_id(item.id));
909
910     match item.node {
911       hir::ItemStatic(_, m, _) => {
912         index.record(def_id, rbml_w);
913         rbml_w.start_tag(tag_items_data_item);
914         encode_def_id_and_key(ecx, rbml_w, def_id);
915         if m == hir::MutMutable {
916             encode_family(rbml_w, 'b');
917         } else {
918             encode_family(rbml_w, 'c');
919         }
920         encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
921         encode_symbol(ecx, rbml_w, item.id);
922         encode_name(rbml_w, item.name);
923         encode_path(rbml_w, path);
924         encode_visibility(rbml_w, vis);
925         encode_stability(rbml_w, stab);
926         encode_deprecation(rbml_w, depr);
927         encode_attributes(rbml_w, &item.attrs);
928         rbml_w.end_tag();
929       }
930       hir::ItemConst(_, _) => {
931         index.record(def_id, rbml_w);
932         rbml_w.start_tag(tag_items_data_item);
933         encode_def_id_and_key(ecx, rbml_w, def_id);
934         encode_family(rbml_w, 'C');
935         encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
936         encode_name(rbml_w, item.name);
937         encode_path(rbml_w, path);
938         encode_attributes(rbml_w, &item.attrs);
939         encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
940         encode_visibility(rbml_w, vis);
941         encode_stability(rbml_w, stab);
942         encode_deprecation(rbml_w, depr);
943         rbml_w.end_tag();
944       }
945       hir::ItemFn(ref decl, _, constness, _, ref generics, _) => {
946         index.record(def_id, rbml_w);
947         rbml_w.start_tag(tag_items_data_item);
948         encode_def_id_and_key(ecx, rbml_w, def_id);
949         encode_family(rbml_w, FN_FAMILY);
950         let tps_len = generics.ty_params.len();
951         encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
952         encode_name(rbml_w, item.name);
953         encode_path(rbml_w, path);
954         encode_attributes(rbml_w, &item.attrs);
955         let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs);
956         if needs_inline || constness == hir::Constness::Const {
957             encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
958         }
959         if tps_len == 0 {
960             encode_symbol(ecx, rbml_w, item.id);
961         }
962         encode_constness(rbml_w, constness);
963         encode_visibility(rbml_w, vis);
964         encode_stability(rbml_w, stab);
965         encode_deprecation(rbml_w, depr);
966         encode_method_argument_names(rbml_w, &**decl);
967         rbml_w.end_tag();
968       }
969       hir::ItemMod(ref m) => {
970         index.record(def_id, rbml_w);
971         encode_info_for_mod(ecx,
972                             rbml_w,
973                             m,
974                             &item.attrs,
975                             item.id,
976                             path,
977                             item.name,
978                             item.vis);
979       }
980       hir::ItemForeignMod(ref fm) => {
981         index.record(def_id, rbml_w);
982         rbml_w.start_tag(tag_items_data_item);
983         encode_def_id_and_key(ecx, rbml_w, def_id);
984         encode_family(rbml_w, 'n');
985         encode_name(rbml_w, item.name);
986         encode_path(rbml_w, path);
987
988         // Encode all the items in this module.
989         for foreign_item in &fm.items {
990             rbml_w.wr_tagged_u64(tag_mod_child,
991                                  def_to_u64(ecx.tcx.map.local_def_id(foreign_item.id)));
992         }
993         encode_visibility(rbml_w, vis);
994         encode_stability(rbml_w, stab);
995         encode_deprecation(rbml_w, depr);
996         rbml_w.end_tag();
997       }
998       hir::ItemTy(..) => {
999         index.record(def_id, rbml_w);
1000         rbml_w.start_tag(tag_items_data_item);
1001         encode_def_id_and_key(ecx, rbml_w, def_id);
1002         encode_family(rbml_w, 'y');
1003         encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
1004         encode_name(rbml_w, item.name);
1005         encode_path(rbml_w, path);
1006         encode_visibility(rbml_w, vis);
1007         encode_stability(rbml_w, stab);
1008         encode_deprecation(rbml_w, depr);
1009         rbml_w.end_tag();
1010       }
1011       hir::ItemEnum(ref enum_definition, _) => {
1012         index.record(def_id, rbml_w);
1013
1014         rbml_w.start_tag(tag_items_data_item);
1015         encode_def_id_and_key(ecx, rbml_w, def_id);
1016         encode_family(rbml_w, 't');
1017         encode_item_variances(rbml_w, ecx, item.id);
1018         encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
1019         encode_name(rbml_w, item.name);
1020         encode_attributes(rbml_w, &item.attrs);
1021         encode_repr_attrs(rbml_w, ecx, &item.attrs);
1022         for v in &enum_definition.variants {
1023             encode_variant_id(rbml_w, ecx.tcx.map.local_def_id(v.node.data.id()));
1024         }
1025         encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
1026         encode_path(rbml_w, path);
1027
1028         // Encode inherent implementations for this enumeration.
1029         encode_inherent_implementations(ecx, rbml_w, def_id);
1030
1031         encode_visibility(rbml_w, vis);
1032         encode_stability(rbml_w, stab);
1033         encode_deprecation(rbml_w, depr);
1034         rbml_w.end_tag();
1035
1036         encode_enum_variant_info(ecx,
1037                                  rbml_w,
1038                                  item.id,
1039                                  vis,
1040                                  index);
1041       }
1042       hir::ItemStruct(ref struct_def, _) => {
1043         let def = ecx.tcx.lookup_adt_def(def_id);
1044         let variant = def.struct_variant();
1045
1046         /* Index the class*/
1047         index.record(def_id, rbml_w);
1048
1049         /* Now, make an item for the class itself */
1050         rbml_w.start_tag(tag_items_data_item);
1051         encode_def_id_and_key(ecx, rbml_w, def_id);
1052         encode_family(rbml_w, match *struct_def {
1053             hir::VariantData::Struct(..) => 'S',
1054             hir::VariantData::Tuple(..) => 's',
1055             hir::VariantData::Unit(..) => 'u',
1056         });
1057         encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
1058
1059         encode_item_variances(rbml_w, ecx, item.id);
1060         encode_name(rbml_w, item.name);
1061         encode_attributes(rbml_w, &item.attrs);
1062         encode_path(rbml_w, path.clone());
1063         encode_stability(rbml_w, stab);
1064         encode_deprecation(rbml_w, depr);
1065         encode_visibility(rbml_w, vis);
1066         encode_repr_attrs(rbml_w, ecx, &item.attrs);
1067
1068         /* Encode def_ids for each field and method
1069          for methods, write all the stuff get_trait_method
1070         needs to know*/
1071         encode_struct_fields(rbml_w, variant);
1072
1073         encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
1074
1075         // Encode inherent implementations for this structure.
1076         encode_inherent_implementations(ecx, rbml_w, def_id);
1077
1078         if !struct_def.is_struct() {
1079             let ctor_did = ecx.tcx.map.local_def_id(struct_def.id());
1080             rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor,
1081                                  def_to_u64(ctor_did));
1082         }
1083
1084         rbml_w.end_tag();
1085
1086         for field in &variant.fields {
1087             encode_field(ecx, rbml_w, field, index);
1088         }
1089
1090         // If this is a tuple-like struct, encode the type of the constructor.
1091         if !struct_def.is_struct() {
1092             encode_info_for_struct_ctor(ecx, rbml_w, item.name, struct_def, index, item.id);
1093         }
1094       }
1095       hir::ItemDefaultImpl(unsafety, _) => {
1096           index.record(def_id, rbml_w);
1097           rbml_w.start_tag(tag_items_data_item);
1098           encode_def_id_and_key(ecx, rbml_w, def_id);
1099           encode_family(rbml_w, 'd');
1100           encode_name(rbml_w, item.name);
1101           encode_unsafety(rbml_w, unsafety);
1102
1103           let trait_ref = tcx.impl_trait_ref(ecx.tcx.map.local_def_id(item.id)).unwrap();
1104           encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
1105           rbml_w.end_tag();
1106       }
1107       hir::ItemImpl(unsafety, polarity, _, _, _, ref ast_items) => {
1108         // We need to encode information about the default methods we
1109         // have inherited, so we drive this based on the impl structure.
1110         let impl_items = tcx.impl_items.borrow();
1111         let items = impl_items.get(&def_id).unwrap();
1112
1113         index.record(def_id, rbml_w);
1114         rbml_w.start_tag(tag_items_data_item);
1115         encode_def_id_and_key(ecx, rbml_w, def_id);
1116         encode_family(rbml_w, 'i');
1117         encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
1118         encode_name(rbml_w, item.name);
1119         encode_attributes(rbml_w, &item.attrs);
1120         encode_unsafety(rbml_w, unsafety);
1121         encode_polarity(rbml_w, polarity);
1122
1123         match tcx.custom_coerce_unsized_kinds.borrow().get(&ecx.tcx.map.local_def_id(item.id)) {
1124             Some(&kind) => {
1125                 rbml_w.start_tag(tag_impl_coerce_unsized_kind);
1126                 kind.encode(rbml_w);
1127                 rbml_w.end_tag();
1128             }
1129             None => {}
1130         }
1131
1132         for &item_def_id in items {
1133             rbml_w.start_tag(tag_item_impl_item);
1134             match item_def_id {
1135                 ty::ConstTraitItemId(item_def_id) => {
1136                     encode_def_id(rbml_w, item_def_id);
1137                     encode_item_sort(rbml_w, 'C');
1138                 }
1139                 ty::MethodTraitItemId(item_def_id) => {
1140                     encode_def_id(rbml_w, item_def_id);
1141                     encode_item_sort(rbml_w, 'r');
1142                 }
1143                 ty::TypeTraitItemId(item_def_id) => {
1144                     encode_def_id(rbml_w, item_def_id);
1145                     encode_item_sort(rbml_w, 't');
1146                 }
1147             }
1148             rbml_w.end_tag();
1149         }
1150         if let Some(trait_ref) = tcx.impl_trait_ref(ecx.tcx.map.local_def_id(item.id)) {
1151             encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
1152         }
1153         encode_path(rbml_w, path.clone());
1154         encode_stability(rbml_w, stab);
1155         encode_deprecation(rbml_w, depr);
1156         rbml_w.end_tag();
1157
1158         // Iterate down the trait items, emitting them. We rely on the
1159         // assumption that all of the actually implemented trait items
1160         // appear first in the impl structure, in the same order they do
1161         // in the ast. This is a little sketchy.
1162         let num_implemented_methods = ast_items.len();
1163         for (i, &trait_item_def_id) in items.iter().enumerate() {
1164             let ast_item = if i < num_implemented_methods {
1165                 Some(&ast_items[i])
1166             } else {
1167                 None
1168             };
1169
1170             match tcx.impl_or_trait_item(trait_item_def_id.def_id()) {
1171                 ty::ConstTraitItem(ref associated_const) => {
1172                     encode_info_for_associated_const(ecx,
1173                                                      rbml_w,
1174                                                      index,
1175                                                      &*associated_const,
1176                                                      path.clone(),
1177                                                      item.id,
1178                                                      ast_item)
1179                 }
1180                 ty::MethodTraitItem(ref method_type) => {
1181                     encode_info_for_method(ecx,
1182                                            rbml_w,
1183                                            index,
1184                                            &**method_type,
1185                                            path.clone(),
1186                                            false,
1187                                            item.id,
1188                                            ast_item)
1189                 }
1190                 ty::TypeTraitItem(ref associated_type) => {
1191                     encode_info_for_associated_type(ecx,
1192                                                     rbml_w,
1193                                                     index,
1194                                                     &**associated_type,
1195                                                     path.clone(),
1196                                                     item.id,
1197                                                     ast_item)
1198                 }
1199             }
1200         }
1201       }
1202       hir::ItemTrait(_, _, _, ref ms) => {
1203         index.record(def_id, rbml_w);
1204         rbml_w.start_tag(tag_items_data_item);
1205         encode_def_id_and_key(ecx, rbml_w, def_id);
1206         encode_family(rbml_w, 'I');
1207         encode_item_variances(rbml_w, ecx, item.id);
1208         let trait_def = tcx.lookup_trait_def(def_id);
1209         let trait_predicates = tcx.lookup_predicates(def_id);
1210         encode_unsafety(rbml_w, trait_def.unsafety);
1211         encode_paren_sugar(rbml_w, trait_def.paren_sugar);
1212         encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id));
1213         encode_associated_type_names(rbml_w, &trait_def.associated_type_names);
1214         encode_generics(rbml_w, ecx, index,
1215                         &trait_def.generics, &trait_predicates,
1216                         tag_item_generics);
1217         encode_predicates(rbml_w, ecx, index,
1218                           &tcx.lookup_super_predicates(def_id),
1219                           tag_item_super_predicates);
1220         encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
1221         encode_name(rbml_w, item.name);
1222         encode_attributes(rbml_w, &item.attrs);
1223         encode_visibility(rbml_w, vis);
1224         encode_stability(rbml_w, stab);
1225         encode_deprecation(rbml_w, depr);
1226         for &method_def_id in tcx.trait_item_def_ids(def_id).iter() {
1227             rbml_w.start_tag(tag_item_trait_item);
1228             match method_def_id {
1229                 ty::ConstTraitItemId(const_def_id) => {
1230                     encode_def_id(rbml_w, const_def_id);
1231                     encode_item_sort(rbml_w, 'C');
1232                 }
1233                 ty::MethodTraitItemId(method_def_id) => {
1234                     encode_def_id(rbml_w, method_def_id);
1235                     encode_item_sort(rbml_w, 'r');
1236                 }
1237                 ty::TypeTraitItemId(type_def_id) => {
1238                     encode_def_id(rbml_w, type_def_id);
1239                     encode_item_sort(rbml_w, 't');
1240                 }
1241             }
1242             rbml_w.end_tag();
1243
1244             rbml_w.wr_tagged_u64(tag_mod_child,
1245                                  def_to_u64(method_def_id.def_id()));
1246         }
1247         encode_path(rbml_w, path.clone());
1248
1249         // Encode inherent implementations for this trait.
1250         encode_inherent_implementations(ecx, rbml_w, def_id);
1251
1252         rbml_w.end_tag();
1253
1254         // Now output the trait item info for each trait item.
1255         let r = tcx.trait_item_def_ids(def_id);
1256         for (i, &item_def_id) in r.iter().enumerate() {
1257             assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE);
1258
1259             index.record(item_def_id.def_id(), rbml_w);
1260             rbml_w.start_tag(tag_items_data_item);
1261
1262             encode_parent_item(rbml_w, def_id);
1263
1264             let stab = stability::lookup_stability(tcx, item_def_id.def_id());
1265             let depr = stability::lookup_deprecation(tcx, item_def_id.def_id());
1266             encode_stability(rbml_w, stab);
1267             encode_deprecation(rbml_w, depr);
1268
1269             let trait_item_type =
1270                 tcx.impl_or_trait_item(item_def_id.def_id());
1271             let is_nonstatic_method;
1272             match trait_item_type {
1273                 ty::ConstTraitItem(associated_const) => {
1274                     encode_name(rbml_w, associated_const.name);
1275                     encode_def_id_and_key(ecx, rbml_w, associated_const.def_id);
1276                     encode_visibility(rbml_w, associated_const.vis);
1277
1278                     let elem = ast_map::PathName(associated_const.name);
1279                     encode_path(rbml_w,
1280                                 path.clone().chain(Some(elem)));
1281
1282                     encode_family(rbml_w, 'C');
1283
1284                     encode_bounds_and_type_for_item(rbml_w, ecx, index,
1285                                                     ecx.local_id(associated_const.def_id));
1286
1287                     is_nonstatic_method = false;
1288                 }
1289                 ty::MethodTraitItem(method_ty) => {
1290                     let method_def_id = item_def_id.def_id();
1291
1292                     encode_method_ty_fields(ecx, rbml_w, index, &*method_ty);
1293
1294                     let elem = ast_map::PathName(method_ty.name);
1295                     encode_path(rbml_w,
1296                                 path.clone().chain(Some(elem)));
1297
1298                     match method_ty.explicit_self {
1299                         ty::ExplicitSelfCategory::Static => {
1300                             encode_family(rbml_w,
1301                                           STATIC_METHOD_FAMILY);
1302                         }
1303                         _ => {
1304                             encode_family(rbml_w,
1305                                           METHOD_FAMILY);
1306                         }
1307                     }
1308                     encode_bounds_and_type_for_item(rbml_w, ecx, index,
1309                                                     ecx.local_id(method_def_id));
1310
1311                     is_nonstatic_method = method_ty.explicit_self !=
1312                         ty::ExplicitSelfCategory::Static;
1313                 }
1314                 ty::TypeTraitItem(associated_type) => {
1315                     encode_name(rbml_w, associated_type.name);
1316                     encode_def_id_and_key(ecx, rbml_w, associated_type.def_id);
1317
1318                     let elem = ast_map::PathName(associated_type.name);
1319                     encode_path(rbml_w,
1320                                 path.clone().chain(Some(elem)));
1321
1322                     encode_item_sort(rbml_w, 't');
1323                     encode_family(rbml_w, 'y');
1324
1325                     if let Some(ty) = associated_type.ty {
1326                         encode_type(ecx, rbml_w, ty);
1327                     }
1328
1329                     is_nonstatic_method = false;
1330                 }
1331             }
1332
1333             let trait_item = &ms[i];
1334             encode_attributes(rbml_w, &trait_item.attrs);
1335             match trait_item.node {
1336                 hir::ConstTraitItem(_, ref default) => {
1337                     if default.is_some() {
1338                         encode_item_sort(rbml_w, 'C');
1339                     } else {
1340                         encode_item_sort(rbml_w, 'c');
1341                     }
1342
1343                     encode_inlined_item(ecx, rbml_w,
1344                                         InlinedItemRef::TraitItem(def_id, trait_item));
1345                 }
1346                 hir::MethodTraitItem(ref sig, ref body) => {
1347                     // If this is a static method, we've already
1348                     // encoded this.
1349                     if is_nonstatic_method {
1350                         // FIXME: I feel like there is something funny
1351                         // going on.
1352                         encode_bounds_and_type_for_item(rbml_w, ecx, index,
1353                                                         ecx.local_id(item_def_id.def_id()));
1354                     }
1355
1356                     if body.is_some() {
1357                         encode_item_sort(rbml_w, 'p');
1358                         encode_inlined_item(ecx, rbml_w,
1359                                             InlinedItemRef::TraitItem(def_id, trait_item));
1360                     } else {
1361                         encode_item_sort(rbml_w, 'r');
1362                     }
1363                     encode_method_argument_names(rbml_w, &sig.decl);
1364                 }
1365
1366                 hir::TypeTraitItem(..) => {}
1367             }
1368
1369             rbml_w.end_tag();
1370         }
1371       }
1372       hir::ItemExternCrate(_) | hir::ItemUse(_) => {
1373         // these are encoded separately
1374       }
1375     }
1376 }
1377
1378 fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
1379                                           rbml_w: &mut Encoder,
1380                                           nitem: &hir::ForeignItem,
1381                                           index: &mut CrateIndex<'tcx>,
1382                                           path: PathElems,
1383                                           abi: abi::Abi) {
1384     let def_id = ecx.tcx.map.local_def_id(nitem.id);
1385
1386     index.record(def_id, rbml_w);
1387     rbml_w.start_tag(tag_items_data_item);
1388     encode_def_id_and_key(ecx, rbml_w, def_id);
1389     encode_visibility(rbml_w, nitem.vis);
1390     match nitem.node {
1391       hir::ForeignItemFn(ref fndecl, _) => {
1392         encode_family(rbml_w, FN_FAMILY);
1393         encode_bounds_and_type_for_item(rbml_w, ecx, index, nitem.id);
1394         encode_name(rbml_w, nitem.name);
1395         if abi == abi::RustIntrinsic || abi == abi::PlatformIntrinsic {
1396             encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(nitem));
1397         }
1398         encode_attributes(rbml_w, &*nitem.attrs);
1399         let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
1400         let depr = stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
1401         encode_stability(rbml_w, stab);
1402         encode_deprecation(rbml_w, depr);
1403         encode_symbol(ecx, rbml_w, nitem.id);
1404         encode_method_argument_names(rbml_w, &*fndecl);
1405       }
1406       hir::ForeignItemStatic(_, mutbl) => {
1407         if mutbl {
1408             encode_family(rbml_w, 'b');
1409         } else {
1410             encode_family(rbml_w, 'c');
1411         }
1412         encode_bounds_and_type_for_item(rbml_w, ecx, index, nitem.id);
1413         encode_attributes(rbml_w, &*nitem.attrs);
1414         let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
1415         let depr = stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
1416         encode_stability(rbml_w, stab);
1417         encode_deprecation(rbml_w, depr);
1418         encode_symbol(ecx, rbml_w, nitem.id);
1419         encode_name(rbml_w, nitem.name);
1420       }
1421     }
1422     encode_path(rbml_w, path);
1423     rbml_w.end_tag();
1424 }
1425
1426 fn my_visit_expr(expr: &hir::Expr,
1427                  rbml_w: &mut Encoder,
1428                  ecx: &EncodeContext,
1429                  index: &mut CrateIndex) {
1430     match expr.node {
1431         hir::ExprClosure(..) => {
1432             let def_id = ecx.tcx.map.local_def_id(expr.id);
1433
1434             index.record(def_id, rbml_w);
1435
1436             rbml_w.start_tag(tag_items_data_item);
1437             encode_def_id_and_key(ecx, rbml_w, def_id);
1438
1439             rbml_w.start_tag(tag_items_closure_ty);
1440             write_closure_type(ecx, rbml_w, &ecx.tcx.tables.borrow().closure_tys[&def_id]);
1441             rbml_w.end_tag();
1442
1443             rbml_w.start_tag(tag_items_closure_kind);
1444             ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap();
1445             rbml_w.end_tag();
1446
1447             ecx.tcx.map.with_path(expr.id, |path| encode_path(rbml_w, path));
1448
1449             assert!(ecx.mir_map.contains_key(&expr.id));
1450             encode_mir(ecx, rbml_w, expr.id);
1451
1452             rbml_w.end_tag();
1453         }
1454         _ => { }
1455     }
1456 }
1457
1458 fn my_visit_item<'a, 'tcx>(i: &hir::Item,
1459                            rbml_w: &mut Encoder,
1460                            ecx: &EncodeContext<'a, 'tcx>,
1461                            index: &mut CrateIndex<'tcx>) {
1462     ecx.tcx.map.with_path(i.id, |path| {
1463         encode_info_for_item(ecx, rbml_w, i, index, path, i.vis);
1464     });
1465 }
1466
1467 fn my_visit_foreign_item<'a, 'tcx>(ni: &hir::ForeignItem,
1468                                    rbml_w: &mut Encoder,
1469                                    ecx: &EncodeContext<'a, 'tcx>,
1470                                    index: &mut CrateIndex<'tcx>) {
1471     debug!("writing foreign item {}::{}",
1472             ecx.tcx.map.path_to_string(ni.id),
1473             ni.name);
1474
1475     let abi = ecx.tcx.map.get_foreign_abi(ni.id);
1476     ecx.tcx.map.with_path(ni.id, |path| {
1477         encode_info_for_foreign_item(ecx, rbml_w,
1478                                      ni, index,
1479                                      path, abi);
1480     });
1481 }
1482
1483 struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
1484     rbml_w_for_visit_item: &'a mut Encoder<'b>,
1485     ecx: &'a EncodeContext<'c,'tcx>,
1486     index: &'a mut CrateIndex<'tcx>,
1487 }
1488
1489 impl<'a, 'b, 'c, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'c, 'tcx> {
1490     fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
1491         intravisit::walk_expr(self, ex);
1492         my_visit_expr(ex, self.rbml_w_for_visit_item, self.ecx, self.index);
1493     }
1494     fn visit_item(&mut self, i: &'tcx hir::Item) {
1495         intravisit::walk_item(self, i);
1496         my_visit_item(i, self.rbml_w_for_visit_item, self.ecx, self.index);
1497     }
1498     fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) {
1499         intravisit::walk_foreign_item(self, ni);
1500         my_visit_foreign_item(ni, self.rbml_w_for_visit_item, self.ecx, self.index);
1501     }
1502 }
1503
1504 fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
1505                                    rbml_w: &mut Encoder)
1506                                    -> CrateIndex<'tcx> {
1507     let krate = ecx.tcx.map.krate();
1508
1509     let mut index = CrateIndex {
1510         items: IndexData::new(ecx.tcx.map.num_local_def_ids()),
1511         xrefs: FnvHashMap()
1512     };
1513     rbml_w.start_tag(tag_items_data);
1514
1515     index.record(DefId::local(CRATE_DEF_INDEX), rbml_w);
1516     encode_info_for_mod(ecx,
1517                         rbml_w,
1518                         &krate.module,
1519                         &[],
1520                         CRATE_NODE_ID,
1521                         [].iter().cloned().chain(LinkedPath::empty()),
1522                         syntax::parse::token::intern(&ecx.link_meta.crate_name),
1523                         hir::Public);
1524
1525     krate.visit_all_items(&mut EncodeVisitor {
1526         index: &mut index,
1527         ecx: ecx,
1528         rbml_w_for_visit_item: &mut *rbml_w,
1529     });
1530
1531     rbml_w.end_tag();
1532     index
1533 }
1534
1535 fn encode_item_index(rbml_w: &mut Encoder, index: IndexData) {
1536     rbml_w.start_tag(tag_index);
1537     index.write_index(rbml_w.writer);
1538     rbml_w.end_tag();
1539 }
1540
1541 fn encode_meta_item(rbml_w: &mut Encoder, mi: &ast::MetaItem) {
1542     match mi.node {
1543       ast::MetaWord(ref name) => {
1544         rbml_w.start_tag(tag_meta_item_word);
1545         rbml_w.wr_tagged_str(tag_meta_item_name, name);
1546         rbml_w.end_tag();
1547       }
1548       ast::MetaNameValue(ref name, ref value) => {
1549         match value.node {
1550           ast::LitStr(ref value, _) => {
1551             rbml_w.start_tag(tag_meta_item_name_value);
1552             rbml_w.wr_tagged_str(tag_meta_item_name, name);
1553             rbml_w.wr_tagged_str(tag_meta_item_value, value);
1554             rbml_w.end_tag();
1555           }
1556           _ => {/* FIXME (#623): encode other variants */ }
1557         }
1558       }
1559       ast::MetaList(ref name, ref items) => {
1560         rbml_w.start_tag(tag_meta_item_list);
1561         rbml_w.wr_tagged_str(tag_meta_item_name, name);
1562         for inner_item in items {
1563             encode_meta_item(rbml_w, &**inner_item);
1564         }
1565         rbml_w.end_tag();
1566       }
1567     }
1568 }
1569
1570 fn encode_attributes(rbml_w: &mut Encoder, attrs: &[ast::Attribute]) {
1571     rbml_w.start_tag(tag_attributes);
1572     for attr in attrs {
1573         rbml_w.start_tag(tag_attribute);
1574         rbml_w.wr_tagged_u8(tag_attribute_is_sugared_doc, attr.node.is_sugared_doc as u8);
1575         encode_meta_item(rbml_w, &*attr.node.value);
1576         rbml_w.end_tag();
1577     }
1578     rbml_w.end_tag();
1579 }
1580
1581 fn encode_unsafety(rbml_w: &mut Encoder, unsafety: hir::Unsafety) {
1582     let byte: u8 = match unsafety {
1583         hir::Unsafety::Normal => 0,
1584         hir::Unsafety::Unsafe => 1,
1585     };
1586     rbml_w.wr_tagged_u8(tag_unsafety, byte);
1587 }
1588
1589 fn encode_paren_sugar(rbml_w: &mut Encoder, paren_sugar: bool) {
1590     let byte: u8 = if paren_sugar {1} else {0};
1591     rbml_w.wr_tagged_u8(tag_paren_sugar, byte);
1592 }
1593
1594 fn encode_defaulted(rbml_w: &mut Encoder, is_defaulted: bool) {
1595     let byte: u8 = if is_defaulted {1} else {0};
1596     rbml_w.wr_tagged_u8(tag_defaulted_trait, byte);
1597 }
1598
1599 fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[Name]) {
1600     rbml_w.start_tag(tag_associated_type_names);
1601     for &name in names {
1602         rbml_w.wr_tagged_str(tag_associated_type_name, &name.as_str());
1603     }
1604     rbml_w.end_tag();
1605 }
1606
1607 fn encode_polarity(rbml_w: &mut Encoder, polarity: hir::ImplPolarity) {
1608     let byte: u8 = match polarity {
1609         hir::ImplPolarity::Positive => 0,
1610         hir::ImplPolarity::Negative => 1,
1611     };
1612     rbml_w.wr_tagged_u8(tag_polarity, byte);
1613 }
1614
1615 fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
1616     fn get_ordered_deps(cstore: &cstore::CStore)
1617                         -> Vec<(CrateNum, Rc<cstore::crate_metadata>)> {
1618         // Pull the cnums and name,vers,hash out of cstore
1619         let mut deps = Vec::new();
1620         cstore.iter_crate_data(|cnum, val| {
1621             deps.push((cnum, val.clone()));
1622         });
1623
1624         // Sort by cnum
1625         deps.sort_by(|kv1, kv2| kv1.0.cmp(&kv2.0));
1626
1627         // Sanity-check the crate numbers
1628         let mut expected_cnum = 1;
1629         for &(n, _) in &deps {
1630             assert_eq!(n, expected_cnum);
1631             expected_cnum += 1;
1632         }
1633
1634         deps
1635     }
1636
1637     // We're just going to write a list of crate 'name-hash-version's, with
1638     // the assumption that they are numbered 1 to n.
1639     // FIXME (#2166): This is not nearly enough to support correct versioning
1640     // but is enough to get transitive crate dependencies working.
1641     rbml_w.start_tag(tag_crate_deps);
1642     for (_cnum, dep) in get_ordered_deps(cstore) {
1643         encode_crate_dep(rbml_w, &dep);
1644     }
1645     rbml_w.end_tag();
1646 }
1647
1648 fn encode_lang_items(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1649     rbml_w.start_tag(tag_lang_items);
1650
1651     for (i, &opt_def_id) in ecx.tcx.lang_items.items() {
1652         if let Some(def_id) = opt_def_id {
1653             if def_id.is_local() {
1654                 rbml_w.start_tag(tag_lang_items_item);
1655                 rbml_w.wr_tagged_u32(tag_lang_items_item_id, i as u32);
1656                 rbml_w.wr_tagged_u32(tag_lang_items_item_index, def_id.index.as_u32());
1657                 rbml_w.end_tag();
1658             }
1659         }
1660     }
1661
1662     for i in &ecx.tcx.lang_items.missing {
1663         rbml_w.wr_tagged_u32(tag_lang_items_missing, *i as u32);
1664     }
1665
1666     rbml_w.end_tag();   // tag_lang_items
1667 }
1668
1669 fn encode_native_libraries(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1670     rbml_w.start_tag(tag_native_libraries);
1671
1672     for &(ref lib, kind) in ecx.tcx.sess.cstore.used_libraries().iter() {
1673         match kind {
1674             cstore::NativeStatic => {} // these libraries are not propagated
1675             cstore::NativeFramework | cstore::NativeUnknown => {
1676                 rbml_w.start_tag(tag_native_libraries_lib);
1677                 rbml_w.wr_tagged_u32(tag_native_libraries_kind, kind as u32);
1678                 rbml_w.wr_tagged_str(tag_native_libraries_name, lib);
1679                 rbml_w.end_tag();
1680             }
1681         }
1682     }
1683
1684     rbml_w.end_tag();
1685 }
1686
1687 fn encode_plugin_registrar_fn(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1688     match ecx.tcx.sess.plugin_registrar_fn.get() {
1689         Some(id) => {
1690             let def_id = ecx.tcx.map.local_def_id(id);
1691             rbml_w.wr_tagged_u32(tag_plugin_registrar_fn, def_id.index.as_u32());
1692         }
1693         None => {}
1694     }
1695 }
1696
1697 fn encode_codemap(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1698     rbml_w.start_tag(tag_codemap);
1699     let codemap = ecx.tcx.sess.codemap();
1700
1701     for filemap in &codemap.files.borrow()[..] {
1702
1703         if filemap.lines.borrow().is_empty() || filemap.is_imported() {
1704             // No need to export empty filemaps, as they can't contain spans
1705             // that need translation.
1706             // Also no need to re-export imported filemaps, as any downstream
1707             // crate will import them from their original source.
1708             continue;
1709         }
1710
1711         rbml_w.start_tag(tag_codemap_filemap);
1712         rbml_w.emit_opaque(|opaque_encoder| {
1713             filemap.encode(opaque_encoder)
1714         }).unwrap();
1715         rbml_w.end_tag();
1716     }
1717
1718     rbml_w.end_tag();
1719 }
1720
1721 /// Serialize the text of the exported macros
1722 fn encode_macro_defs(rbml_w: &mut Encoder,
1723                      krate: &hir::Crate) {
1724     rbml_w.start_tag(tag_macro_defs);
1725     for def in &krate.exported_macros {
1726         rbml_w.start_tag(tag_macro_def);
1727
1728         encode_name(rbml_w, def.name);
1729         encode_attributes(rbml_w, &def.attrs);
1730
1731         rbml_w.wr_tagged_str(tag_macro_def_body,
1732                              &::syntax::print::pprust::tts_to_string(&def.body));
1733
1734         rbml_w.end_tag();
1735     }
1736     rbml_w.end_tag();
1737 }
1738
1739 fn encode_struct_field_attrs(ecx: &EncodeContext,
1740                              rbml_w: &mut Encoder,
1741                              krate: &hir::Crate) {
1742     struct StructFieldVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
1743         ecx: &'a EncodeContext<'b, 'tcx>,
1744         rbml_w: &'a mut Encoder<'c>,
1745     }
1746
1747     impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for StructFieldVisitor<'a, 'b, 'c, 'tcx> {
1748         fn visit_struct_field(&mut self, field: &hir::StructField) {
1749             self.rbml_w.start_tag(tag_struct_field);
1750             let def_id = self.ecx.tcx.map.local_def_id(field.node.id);
1751             encode_def_id(self.rbml_w, def_id);
1752             encode_attributes(self.rbml_w, &field.node.attrs);
1753             self.rbml_w.end_tag();
1754         }
1755     }
1756
1757     rbml_w.start_tag(tag_struct_fields);
1758     krate.visit_all_items(&mut StructFieldVisitor { ecx: ecx, rbml_w: rbml_w });
1759     rbml_w.end_tag();
1760 }
1761
1762
1763
1764 struct ImplVisitor<'a, 'tcx:'a> {
1765     tcx: &'a ty::ctxt<'tcx>,
1766     impls: FnvHashMap<DefId, Vec<DefId>>
1767 }
1768
1769 impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> {
1770     fn visit_item(&mut self, item: &hir::Item) {
1771         if let hir::ItemImpl(..) = item.node {
1772             let impl_id = self.tcx.map.local_def_id(item.id);
1773             if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) {
1774                 self.impls.entry(trait_ref.def_id)
1775                     .or_insert(vec![])
1776                     .push(impl_id);
1777             }
1778         }
1779     }
1780 }
1781
1782 /// Encodes an index, mapping each trait to its (local) implementations.
1783 fn encode_impls<'a>(ecx: &'a EncodeContext,
1784                     krate: &hir::Crate,
1785                     rbml_w: &'a mut Encoder) {
1786     let mut visitor = ImplVisitor {
1787         tcx: ecx.tcx,
1788         impls: FnvHashMap()
1789     };
1790     krate.visit_all_items(&mut visitor);
1791
1792     rbml_w.start_tag(tag_impls);
1793     for (trait_, trait_impls) in visitor.impls {
1794         rbml_w.start_tag(tag_impls_trait);
1795         encode_def_id(rbml_w, trait_);
1796         for impl_ in trait_impls {
1797             rbml_w.wr_tagged_u64(tag_impls_trait_impl, def_to_u64(impl_));
1798         }
1799         rbml_w.end_tag();
1800     }
1801     rbml_w.end_tag();
1802 }
1803
1804 fn encode_misc_info(ecx: &EncodeContext,
1805                     krate: &hir::Crate,
1806                     rbml_w: &mut Encoder) {
1807     rbml_w.start_tag(tag_misc_info);
1808     rbml_w.start_tag(tag_misc_info_crate_items);
1809     for item_id in &krate.module.item_ids {
1810         rbml_w.wr_tagged_u64(tag_mod_child,
1811                              def_to_u64(ecx.tcx.map.local_def_id(item_id.id)));
1812
1813         let item = ecx.tcx.map.expect_item(item_id.id);
1814         each_auxiliary_node_id(item, |auxiliary_node_id| {
1815             rbml_w.wr_tagged_u64(tag_mod_child,
1816                                  def_to_u64(ecx.tcx.map.local_def_id(auxiliary_node_id)));
1817             true
1818         });
1819     }
1820
1821     // Encode reexports for the root module.
1822     encode_reexports(ecx, rbml_w, 0);
1823
1824     rbml_w.end_tag();
1825     rbml_w.end_tag();
1826 }
1827
1828 // Encodes all reachable symbols in this crate into the metadata.
1829 //
1830 // This pass is seeded off the reachability list calculated in the
1831 // middle::reachable module but filters out items that either don't have a
1832 // symbol associated with them (they weren't translated) or if they're an FFI
1833 // definition (as that's not defined in this crate).
1834 fn encode_reachable(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1835     rbml_w.start_tag(tag_reachable_ids);
1836     for &id in ecx.reachable {
1837         let def_id = ecx.tcx.map.local_def_id(id);
1838         rbml_w.wr_tagged_u32(tag_reachable_id, def_id.index.as_u32());
1839     }
1840     rbml_w.end_tag();
1841 }
1842
1843 fn encode_crate_dep(rbml_w: &mut Encoder,
1844                     dep: &cstore::crate_metadata) {
1845     rbml_w.start_tag(tag_crate_dep);
1846     rbml_w.wr_tagged_str(tag_crate_dep_crate_name, &dep.name());
1847     let hash = decoder::get_crate_hash(dep.data());
1848     rbml_w.wr_tagged_str(tag_crate_dep_hash, hash.as_str());
1849     rbml_w.wr_tagged_u8(tag_crate_dep_explicitly_linked,
1850                         dep.explicitly_linked.get() as u8);
1851     rbml_w.end_tag();
1852 }
1853
1854 fn encode_hash(rbml_w: &mut Encoder, hash: &Svh) {
1855     rbml_w.wr_tagged_str(tag_crate_hash, hash.as_str());
1856 }
1857
1858 fn encode_rustc_version(rbml_w: &mut Encoder) {
1859     rbml_w.wr_tagged_str(tag_rustc_version, &rustc_version());
1860 }
1861
1862 fn encode_crate_name(rbml_w: &mut Encoder, crate_name: &str) {
1863     rbml_w.wr_tagged_str(tag_crate_crate_name, crate_name);
1864 }
1865
1866 fn encode_crate_triple(rbml_w: &mut Encoder, triple: &str) {
1867     rbml_w.wr_tagged_str(tag_crate_triple, triple);
1868 }
1869
1870 fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) {
1871     let tag = tag_dylib_dependency_formats;
1872     match ecx.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) {
1873         Some(arr) => {
1874             let s = arr.iter().enumerate().filter_map(|(i, slot)| {
1875                 let kind = match *slot {
1876                     Linkage::NotLinked |
1877                     Linkage::IncludedFromDylib => return None,
1878                     Linkage::Dynamic => "d",
1879                     Linkage::Static => "s",
1880                 };
1881                 Some(format!("{}:{}", i + 1, kind))
1882             }).collect::<Vec<String>>();
1883             rbml_w.wr_tagged_str(tag, &s.join(","));
1884         }
1885         None => {
1886             rbml_w.wr_tagged_str(tag, "");
1887         }
1888     }
1889 }
1890
1891 // NB: Increment this as you change the metadata encoding version.
1892 #[allow(non_upper_case_globals)]
1893 pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 2 ];
1894
1895 pub fn encode_metadata(parms: EncodeParams, krate: &hir::Crate) -> Vec<u8> {
1896     let EncodeParams {
1897         item_symbols,
1898         diag,
1899         tcx,
1900         reexports,
1901         cstore,
1902         encode_inlined_item,
1903         link_meta,
1904         reachable,
1905         mir_map,
1906         ..
1907     } = parms;
1908     let ecx = EncodeContext {
1909         diag: diag,
1910         tcx: tcx,
1911         reexports: reexports,
1912         item_symbols: item_symbols,
1913         link_meta: link_meta,
1914         cstore: cstore,
1915         encode_inlined_item: RefCell::new(encode_inlined_item),
1916         type_abbrevs: RefCell::new(FnvHashMap()),
1917         reachable: reachable,
1918         mir_map: mir_map,
1919     };
1920
1921     let mut wr = Cursor::new(Vec::new());
1922
1923     {
1924         let mut rbml_w = Encoder::new(&mut wr);
1925         encode_metadata_inner(&mut rbml_w, &ecx, krate)
1926     }
1927
1928     // RBML compacts the encoded bytes whenever appropriate,
1929     // so there are some garbages left after the end of the data.
1930     let metalen = wr.seek(SeekFrom::Current(0)).unwrap() as usize;
1931     let mut v = wr.into_inner();
1932     v.truncate(metalen);
1933     assert_eq!(v.len(), metalen);
1934
1935     // And here we run into yet another obscure archive bug: in which metadata
1936     // loaded from archives may have trailing garbage bytes. Awhile back one of
1937     // our tests was failing sporadically on the OSX 64-bit builders (both nopt
1938     // and opt) by having rbml generate an out-of-bounds panic when looking at
1939     // metadata.
1940     //
1941     // Upon investigation it turned out that the metadata file inside of an rlib
1942     // (and ar archive) was being corrupted. Some compilations would generate a
1943     // metadata file which would end in a few extra bytes, while other
1944     // compilations would not have these extra bytes appended to the end. These
1945     // extra bytes were interpreted by rbml as an extra tag, so they ended up
1946     // being interpreted causing the out-of-bounds.
1947     //
1948     // The root cause of why these extra bytes were appearing was never
1949     // discovered, and in the meantime the solution we're employing is to insert
1950     // the length of the metadata to the start of the metadata. Later on this
1951     // will allow us to slice the metadata to the precise length that we just
1952     // generated regardless of trailing bytes that end up in it.
1953     let len = v.len() as u32;
1954     v.insert(0, (len >>  0) as u8);
1955     v.insert(0, (len >>  8) as u8);
1956     v.insert(0, (len >> 16) as u8);
1957     v.insert(0, (len >> 24) as u8);
1958     return v;
1959 }
1960
1961 fn encode_metadata_inner(rbml_w: &mut Encoder,
1962                          ecx: &EncodeContext,
1963                          krate: &hir::Crate) {
1964     struct Stats {
1965         attr_bytes: u64,
1966         dep_bytes: u64,
1967         lang_item_bytes: u64,
1968         native_lib_bytes: u64,
1969         plugin_registrar_fn_bytes: u64,
1970         codemap_bytes: u64,
1971         macro_defs_bytes: u64,
1972         impl_bytes: u64,
1973         misc_bytes: u64,
1974         item_bytes: u64,
1975         index_bytes: u64,
1976         xref_bytes: u64,
1977         zero_bytes: u64,
1978         total_bytes: u64,
1979     }
1980     let mut stats = Stats {
1981         attr_bytes: 0,
1982         dep_bytes: 0,
1983         lang_item_bytes: 0,
1984         native_lib_bytes: 0,
1985         plugin_registrar_fn_bytes: 0,
1986         codemap_bytes: 0,
1987         macro_defs_bytes: 0,
1988         impl_bytes: 0,
1989         misc_bytes: 0,
1990         item_bytes: 0,
1991         index_bytes: 0,
1992         xref_bytes: 0,
1993         zero_bytes: 0,
1994         total_bytes: 0,
1995     };
1996
1997     encode_rustc_version(rbml_w);
1998     encode_crate_name(rbml_w, &ecx.link_meta.crate_name);
1999     encode_crate_triple(rbml_w, &ecx.tcx.sess.opts.target_triple);
2000     encode_hash(rbml_w, &ecx.link_meta.crate_hash);
2001     encode_dylib_dependency_formats(rbml_w, &ecx);
2002
2003     let mut i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2004     encode_attributes(rbml_w, &krate.attrs);
2005     stats.attr_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2006
2007     i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2008     encode_crate_deps(rbml_w, ecx.cstore);
2009     stats.dep_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2010
2011     // Encode the language items.
2012     i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2013     encode_lang_items(&ecx, rbml_w);
2014     stats.lang_item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2015
2016     // Encode the native libraries used
2017     i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2018     encode_native_libraries(&ecx, rbml_w);
2019     stats.native_lib_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2020
2021     // Encode the plugin registrar function
2022     i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2023     encode_plugin_registrar_fn(&ecx, rbml_w);
2024     stats.plugin_registrar_fn_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2025
2026     // Encode codemap
2027     i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2028     encode_codemap(&ecx, rbml_w);
2029     stats.codemap_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2030
2031     // Encode macro definitions
2032     i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2033     encode_macro_defs(rbml_w, krate);
2034     stats.macro_defs_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2035
2036     // Encode the def IDs of impls, for coherence checking.
2037     i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2038     encode_impls(&ecx, krate, rbml_w);
2039     stats.impl_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2040
2041     // Encode miscellaneous info.
2042     i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2043     encode_misc_info(&ecx, krate, rbml_w);
2044     encode_reachable(&ecx, rbml_w);
2045     stats.misc_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2046
2047     // Encode and index the items.
2048     rbml_w.start_tag(tag_items);
2049     i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2050     let index = encode_info_for_items(&ecx, rbml_w);
2051     stats.item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2052     rbml_w.end_tag();
2053
2054     i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2055     encode_item_index(rbml_w, index.items);
2056     stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2057
2058     i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2059     encode_xrefs(&ecx, rbml_w, index.xrefs);
2060     stats.xref_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2061
2062     encode_struct_field_attrs(&ecx, rbml_w, krate);
2063
2064     stats.total_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2065
2066     if ecx.tcx.sess.meta_stats() {
2067         for e in rbml_w.writer.get_ref() {
2068             if *e == 0 {
2069                 stats.zero_bytes += 1;
2070             }
2071         }
2072
2073         println!("metadata stats:");
2074         println!("       attribute bytes: {}", stats.attr_bytes);
2075         println!("             dep bytes: {}", stats.dep_bytes);
2076         println!("       lang item bytes: {}", stats.lang_item_bytes);
2077         println!("          native bytes: {}", stats.native_lib_bytes);
2078         println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
2079         println!("         codemap bytes: {}", stats.codemap_bytes);
2080         println!("       macro def bytes: {}", stats.macro_defs_bytes);
2081         println!("            impl bytes: {}", stats.impl_bytes);
2082         println!("            misc bytes: {}", stats.misc_bytes);
2083         println!("            item bytes: {}", stats.item_bytes);
2084         println!("           index bytes: {}", stats.index_bytes);
2085         println!("            xref bytes: {}", stats.xref_bytes);
2086         println!("            zero bytes: {}", stats.zero_bytes);
2087         println!("           total bytes: {}", stats.total_bytes);
2088     }
2089 }
2090
2091 // Get the encoded string for a type
2092 pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> Vec<u8> {
2093     let mut wr = Cursor::new(Vec::new());
2094     tyencode::enc_ty(&mut wr, &tyencode::ctxt {
2095         diag: tcx.sess.diagnostic(),
2096         ds: def_to_string,
2097         tcx: tcx,
2098         abbrevs: &RefCell::new(FnvHashMap())
2099     }, t);
2100     wr.into_inner()
2101 }