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.
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.
13 #![allow(unused_must_use)] // everything is just a MemWriter, can't fail
14 #![allow(non_camel_case_types)]
20 use index::{self, IndexData};
22 use middle::cstore::{LOCAL_CRATE, CrateStore, InlinedItemRef, LinkMeta, tls};
24 use middle::def_id::{CRATE_DEF_INDEX, DefId};
25 use middle::dependency_format::Linkage;
26 use middle::stability;
28 use middle::ty::{self, Ty};
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};
37 use serialize::Encodable;
38 use std::cell::RefCell;
39 use std::io::prelude::*;
40 use std::io::{Cursor, SeekFrom};
44 use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum};
46 use syntax::attr::AttrMetaMethods;
47 use syntax::diagnostic::SpanHandler;
48 use syntax::parse::token::special_idents;
50 use rbml::writer::Encoder;
53 use rustc_front::intravisit::Visitor;
54 use rustc_front::intravisit;
56 pub type EncodeInlinedItem<'a> =
57 Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
59 pub struct EncodeParams<'a, 'tcx: 'a> {
60 pub diag: &'a SpanHandler,
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>>,
71 pub struct EncodeContext<'a, 'tcx: 'a> {
72 pub diag: &'a SpanHandler,
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>>,
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()
90 /// "interned" entries referenced by id
91 #[derive(PartialEq, Eq, Hash)]
92 pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) }
94 struct CrateIndex<'tcx> {
96 xrefs: FnvHashMap<XRef<'tcx>, u32>, // sequentially-assigned
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);
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)
111 fn encode_name(rbml_w: &mut Encoder, name: Name) {
112 rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str());
115 fn encode_def_id(rbml_w: &mut Encoder, id: DefId) {
116 rbml_w.wr_tagged_u64(tag_def_id, def_to_u64(id));
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,
125 encode_def_id(rbml_w, def_id);
126 encode_def_key(ecx, rbml_w, def_id);
129 fn encode_def_key(ecx: &EncodeContext,
130 rbml_w: &mut Encoder,
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);
139 fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder,
140 ecx: &EncodeContext<'a, 'tcx>,
141 trait_ref: ty::TraitRef<'tcx>,
143 let ty_str_ctxt = &tyencode::ctxt {
147 abbrevs: &ecx.type_abbrevs
150 rbml_w.start_tag(tag);
151 tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref);
155 // Item info table encoding
156 fn encode_family(rbml_w: &mut Encoder, c: char) {
157 rbml_w.wr_tagged_u8(tag_items_data_item_family, c as u8);
160 pub fn def_to_u64(did: DefId) -> u64 {
161 assert!(did.index.as_u32() < u32::MAX);
162 (did.krate as u64) << 32 | (did.index.as_usize() as u64)
165 pub fn def_to_string(did: DefId) -> String {
166 format!("{}:{}", did.krate, did.index.as_usize())
169 fn encode_item_variances(rbml_w: &mut Encoder,
172 let v = ecx.tcx.item_variances(ecx.tcx.map.local_def_id(id));
173 rbml_w.start_tag(tag_item_variances);
178 fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder,
179 ecx: &EncodeContext<'a, 'tcx>,
180 index: &mut CrateIndex<'tcx>,
182 encode_bounds_and_type(rbml_w,
185 &ecx.tcx.lookup_item_type(ecx.tcx.map.local_def_id(id)),
186 &ecx.tcx.lookup_predicates(ecx.tcx.map.local_def_id(id)));
189 fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder,
190 ecx: &EncodeContext<'a, 'tcx>,
191 index: &mut CrateIndex<'tcx>,
192 scheme: &ty::TypeScheme<'tcx>,
193 predicates: &ty::GenericPredicates<'tcx>) {
194 encode_generics(rbml_w, ecx, index,
195 &scheme.generics, &predicates, tag_item_generics);
196 encode_type(ecx, rbml_w, scheme.ty);
199 fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) {
200 let id = def_to_u64(vid);
201 rbml_w.wr_tagged_u64(tag_items_data_item_variant, id);
202 rbml_w.wr_tagged_u64(tag_mod_child, id);
205 pub fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
206 rbml_w: &mut Encoder,
207 closure_type: &ty::ClosureTy<'tcx>) {
208 let ty_str_ctxt = &tyencode::ctxt {
212 abbrevs: &ecx.type_abbrevs
214 tyencode::enc_closure_ty(rbml_w, ty_str_ctxt, closure_type);
217 pub fn write_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
218 rbml_w: &mut Encoder,
220 let ty_str_ctxt = &tyencode::ctxt {
224 abbrevs: &ecx.type_abbrevs
226 tyencode::enc_ty(rbml_w, ty_str_ctxt, typ);
229 pub fn write_trait_ref<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
230 rbml_w: &mut Encoder,
231 trait_ref: &ty::TraitRef<'tcx>) {
232 let ty_str_ctxt = &tyencode::ctxt {
236 abbrevs: &ecx.type_abbrevs
238 tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, *trait_ref);
241 pub fn write_region(ecx: &EncodeContext,
242 rbml_w: &mut Encoder,
244 let ty_str_ctxt = &tyencode::ctxt {
248 abbrevs: &ecx.type_abbrevs
250 tyencode::enc_region(rbml_w, ty_str_ctxt, r);
253 fn encode_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
254 rbml_w: &mut Encoder,
256 rbml_w.start_tag(tag_items_data_item_type);
257 write_type(ecx, rbml_w, typ);
261 fn encode_region(ecx: &EncodeContext,
262 rbml_w: &mut Encoder,
264 rbml_w.start_tag(tag_items_data_region);
265 write_region(ecx, rbml_w, r);
269 fn encode_symbol(ecx: &EncodeContext,
270 rbml_w: &mut Encoder,
272 match ecx.item_symbols.borrow().get(&id) {
274 debug!("encode_symbol(id={}, str={})", id, *x);
275 rbml_w.wr_tagged_str(tag_items_data_item_symbol, x);
278 ecx.diag.handler().bug(
279 &format!("encode_symbol: id not found {}", id));
284 fn encode_disr_val(_: &EncodeContext,
285 rbml_w: &mut Encoder,
286 disr_val: ty::Disr) {
287 rbml_w.wr_tagged_str(tag_disr_val, &disr_val.to_string());
290 fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) {
291 rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(id));
294 fn encode_struct_fields(rbml_w: &mut Encoder,
295 variant: ty::VariantDef) {
296 for f in &variant.fields {
297 if f.name == special_idents::unnamed_field.name {
298 rbml_w.start_tag(tag_item_unnamed_field);
300 rbml_w.start_tag(tag_item_field);
301 encode_name(rbml_w, f.name);
303 encode_struct_field_family(rbml_w, f.vis);
304 encode_def_id(rbml_w, f.did);
309 fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
310 rbml_w: &mut Encoder,
312 vis: hir::Visibility,
313 index: &mut CrateIndex<'tcx>) {
314 debug!("encode_enum_variant_info(id={})", id);
316 let mut disr_val = 0;
317 let def = ecx.tcx.lookup_adt_def(ecx.tcx.map.local_def_id(id));
318 for variant in &def.variants {
319 let vid = variant.did;
320 let variant_node_id = ecx.local_id(vid);
322 if let ty::VariantKind::Struct = variant.kind() {
323 // tuple-like enum variant fields aren't really items so
324 // don't try to encode them.
325 for field in &variant.fields {
326 encode_field(ecx, rbml_w, field, index);
330 index.record(vid, rbml_w);
331 rbml_w.start_tag(tag_items_data_item);
332 encode_def_id_and_key(ecx, rbml_w, vid);
333 encode_family(rbml_w, match variant.kind() {
334 ty::VariantKind::Unit | ty::VariantKind::Tuple => 'v',
335 ty::VariantKind::Struct => 'V'
337 encode_name(rbml_w, variant.name);
338 encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(id));
339 encode_visibility(rbml_w, vis);
341 let attrs = ecx.tcx.get_attrs(vid);
342 encode_attributes(rbml_w, &attrs);
343 encode_repr_attrs(rbml_w, ecx, &attrs);
345 let stab = stability::lookup_stability(ecx.tcx, vid);
346 let depr = stability::lookup_deprecation(ecx.tcx, vid);
347 encode_stability(rbml_w, stab);
348 encode_deprecation(rbml_w, depr);
350 encode_struct_fields(rbml_w, variant);
352 let specified_disr_val = variant.disr_val;
353 if specified_disr_val != disr_val {
354 encode_disr_val(ecx, rbml_w, specified_disr_val);
355 disr_val = specified_disr_val;
357 encode_bounds_and_type_for_item(rbml_w, ecx, index, variant_node_id);
359 ecx.tcx.map.with_path(variant_node_id, |path| encode_path(rbml_w, path));
361 disr_val = disr_val.wrapping_add(1);
365 fn encode_path<PI: Iterator<Item=PathElem>>(rbml_w: &mut Encoder, path: PI) {
366 let path = path.collect::<Vec<_>>();
367 rbml_w.start_tag(tag_path);
368 rbml_w.wr_tagged_u32(tag_path_len, path.len() as u32);
370 let tag = match *pe {
371 ast_map::PathMod(_) => tag_path_elem_mod,
372 ast_map::PathName(_) => tag_path_elem_name
374 rbml_w.wr_tagged_str(tag, &pe.name().as_str());
379 /// Iterates through "auxiliary node IDs", which are node IDs that describe
380 /// top-level items that are sub-items of the given item. Specifically:
382 /// * For newtype structs, iterates through the node ID of the constructor.
383 fn each_auxiliary_node_id<F>(item: &hir::Item, callback: F) -> bool where
384 F: FnOnce(NodeId) -> bool,
386 let mut continue_ = true;
388 hir::ItemStruct(ref struct_def, _) => {
389 // If this is a newtype struct, return the constructor.
390 if struct_def.is_tuple() {
391 continue_ = callback(struct_def.id());
400 fn encode_reexports(ecx: &EncodeContext,
401 rbml_w: &mut Encoder,
403 debug!("(encoding info for module) encoding reexports for {}", id);
404 match ecx.reexports.get(&id) {
406 debug!("(encoding info for module) found reexports for {}", id);
408 debug!("(encoding info for module) reexport '{}' ({:?}) for \
413 rbml_w.start_tag(tag_items_data_item_reexport);
414 rbml_w.wr_tagged_u64(tag_items_data_item_reexport_def_id,
415 def_to_u64(exp.def_id));
416 rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
421 None => debug!("(encoding info for module) found no reexports for {}", id),
425 fn encode_info_for_mod(ecx: &EncodeContext,
426 rbml_w: &mut Encoder,
428 attrs: &[ast::Attribute],
432 vis: hir::Visibility) {
433 rbml_w.start_tag(tag_items_data_item);
434 encode_def_id_and_key(ecx, rbml_w, ecx.tcx.map.local_def_id(id));
435 encode_family(rbml_w, 'm');
436 encode_name(rbml_w, name);
437 debug!("(encoding info for module) encoding info for module ID {}", id);
439 // Encode info about all the module children.
440 for item_id in &md.item_ids {
441 rbml_w.wr_tagged_u64(tag_mod_child,
442 def_to_u64(ecx.tcx.map.local_def_id(item_id.id)));
444 let item = ecx.tcx.map.expect_item(item_id.id);
445 each_auxiliary_node_id(item, |auxiliary_node_id| {
446 rbml_w.wr_tagged_u64(tag_mod_child,
447 def_to_u64(ecx.tcx.map.local_def_id(auxiliary_node_id)));
452 encode_path(rbml_w, path.clone());
453 encode_visibility(rbml_w, vis);
455 let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(id));
456 let depr = stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(id));
457 encode_stability(rbml_w, stab);
458 encode_deprecation(rbml_w, depr);
460 // Encode the reexports of this module, if this module is public.
461 if vis == hir::Public {
462 debug!("(encoding info for module) encoding reexports for {}", id);
463 encode_reexports(ecx, rbml_w, id);
465 encode_attributes(rbml_w, attrs);
470 fn encode_struct_field_family(rbml_w: &mut Encoder,
471 visibility: hir::Visibility) {
472 encode_family(rbml_w, match visibility {
474 hir::Inherited => 'N'
478 fn encode_visibility(rbml_w: &mut Encoder, visibility: hir::Visibility) {
479 let ch = match visibility {
481 hir::Inherited => 'i',
483 rbml_w.wr_tagged_u8(tag_items_data_item_visibility, ch as u8);
486 fn encode_constness(rbml_w: &mut Encoder, constness: hir::Constness) {
487 rbml_w.start_tag(tag_items_data_item_constness);
488 let ch = match constness {
489 hir::Constness::Const => 'c',
490 hir::Constness::NotConst => 'n',
492 rbml_w.wr_str(&ch.to_string());
496 fn encode_explicit_self(rbml_w: &mut Encoder,
497 explicit_self: &ty::ExplicitSelfCategory) {
498 let tag = tag_item_trait_method_explicit_self;
500 // Encode the base self type.
501 match *explicit_self {
502 ty::StaticExplicitSelfCategory => {
503 rbml_w.wr_tagged_bytes(tag, &['s' as u8]);
505 ty::ByValueExplicitSelfCategory => {
506 rbml_w.wr_tagged_bytes(tag, &['v' as u8]);
508 ty::ByBoxExplicitSelfCategory => {
509 rbml_w.wr_tagged_bytes(tag, &['~' as u8]);
511 ty::ByReferenceExplicitSelfCategory(_, m) => {
512 // FIXME(#4846) encode custom lifetime
513 let ch = encode_mutability(m);
514 rbml_w.wr_tagged_bytes(tag, &['&' as u8, ch]);
518 fn encode_mutability(m: hir::Mutability) -> u8 {
520 hir::MutImmutable => 'i' as u8,
521 hir::MutMutable => 'm' as u8,
526 fn encode_item_sort(rbml_w: &mut Encoder, sort: char) {
527 rbml_w.wr_tagged_u8(tag_item_trait_item_sort, sort as u8);
530 fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
531 rbml_w: &mut Encoder,
532 field: ty::FieldDef<'tcx>,
533 index: &mut CrateIndex<'tcx>) {
535 let id = ecx.local_id(field.did);
537 index.record(field.did, rbml_w);
538 rbml_w.start_tag(tag_items_data_item);
539 debug!("encode_field: encoding {} {}", nm, id);
540 encode_struct_field_family(rbml_w, field.vis);
541 encode_name(rbml_w, nm);
542 encode_bounds_and_type_for_item(rbml_w, ecx, index, id);
543 encode_def_id_and_key(ecx, rbml_w, field.did);
545 let stab = stability::lookup_stability(ecx.tcx, field.did);
546 let depr = stability::lookup_deprecation(ecx.tcx, field.did);
547 encode_stability(rbml_w, stab);
548 encode_deprecation(rbml_w, depr);
553 fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
554 rbml_w: &mut Encoder,
557 index: &mut CrateIndex<'tcx>,
559 let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id);
561 index.record(ctor_def_id, rbml_w);
562 rbml_w.start_tag(tag_items_data_item);
563 encode_def_id_and_key(ecx, rbml_w, ctor_def_id);
564 encode_family(rbml_w, 'o');
565 encode_bounds_and_type_for_item(rbml_w, ecx, index, ctor_id);
566 encode_name(rbml_w, name);
567 ecx.tcx.map.with_path(ctor_id, |path| encode_path(rbml_w, path));
568 encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(struct_id));
570 if ecx.item_symbols.borrow().contains_key(&ctor_id) {
571 encode_symbol(ecx, rbml_w, ctor_id);
574 let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(ctor_id));
575 let depr= stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(ctor_id));
576 encode_stability(rbml_w, stab);
577 encode_deprecation(rbml_w, depr);
579 // indicate that this is a tuple struct ctor, because downstream users will normally want
580 // the tuple struct definition, but without this there is no way for them to tell that
581 // they actually have a ctor rather than a normal function
582 rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]);
587 fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
588 ecx: &EncodeContext<'a, 'tcx>,
589 index: &mut CrateIndex<'tcx>,
590 generics: &ty::Generics<'tcx>,
591 predicates: &ty::GenericPredicates<'tcx>,
594 rbml_w.start_tag(tag);
597 let ty_str_ctxt = &tyencode::ctxt {
601 abbrevs: &ecx.type_abbrevs
604 for param in &generics.types {
605 rbml_w.start_tag(tag_type_param_def);
606 tyencode::enc_type_param_def(rbml_w, ty_str_ctxt, param);
611 for param in &generics.regions {
612 rbml_w.start_tag(tag_region_param_def);
614 rbml_w.start_tag(tag_region_param_def_ident);
615 encode_name(rbml_w, param.name);
618 rbml_w.wr_tagged_u64(tag_region_param_def_def_id,
619 def_to_u64(param.def_id));
621 rbml_w.wr_tagged_u64(tag_region_param_def_space,
622 param.space.to_uint() as u64);
624 rbml_w.wr_tagged_u64(tag_region_param_def_index,
627 for &bound_region in ¶m.bounds {
628 encode_region(ecx, rbml_w, bound_region);
634 encode_predicates_in_current_doc(rbml_w, ecx, index, predicates);
639 fn encode_predicates_in_current_doc<'a,'tcx>(rbml_w: &mut Encoder,
640 _ecx: &EncodeContext<'a,'tcx>,
641 index: &mut CrateIndex<'tcx>,
642 predicates: &ty::GenericPredicates<'tcx>)
644 for (space, _, predicate) in predicates.predicates.iter_enumerated() {
645 let tag = match space {
646 subst::TypeSpace => tag_type_predicate,
647 subst::SelfSpace => tag_self_predicate,
648 subst::FnSpace => tag_fn_predicate
651 rbml_w.wr_tagged_u32(tag,
652 index.add_xref(XRef::Predicate(predicate.clone())));
656 fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder,
657 ecx: &EncodeContext<'a,'tcx>,
658 index: &mut CrateIndex<'tcx>,
659 predicates: &ty::GenericPredicates<'tcx>,
662 rbml_w.start_tag(tag);
663 encode_predicates_in_current_doc(rbml_w, ecx, index, predicates);
667 fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
668 rbml_w: &mut Encoder,
669 index: &mut CrateIndex<'tcx>,
670 method_ty: &ty::Method<'tcx>) {
671 encode_def_id_and_key(ecx, rbml_w, method_ty.def_id);
672 encode_name(rbml_w, method_ty.name);
673 encode_generics(rbml_w, ecx, index,
674 &method_ty.generics, &method_ty.predicates,
675 tag_method_ty_generics);
676 encode_visibility(rbml_w, method_ty.vis);
677 encode_explicit_self(rbml_w, &method_ty.explicit_self);
678 match method_ty.explicit_self {
679 ty::StaticExplicitSelfCategory => {
680 encode_family(rbml_w, STATIC_METHOD_FAMILY);
682 _ => encode_family(rbml_w, METHOD_FAMILY)
686 fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
687 rbml_w: &mut Encoder,
688 index: &mut CrateIndex<'tcx>,
689 associated_const: &ty::AssociatedConst,
690 impl_path: PathElems,
692 impl_item_opt: Option<&hir::ImplItem>) {
693 debug!("encode_info_for_associated_const({:?},{:?})",
694 associated_const.def_id,
695 associated_const.name);
697 index.record(associated_const.def_id, rbml_w);
698 rbml_w.start_tag(tag_items_data_item);
700 encode_def_id_and_key(ecx, rbml_w, associated_const.def_id);
701 encode_name(rbml_w, associated_const.name);
702 encode_visibility(rbml_w, associated_const.vis);
703 encode_family(rbml_w, 'C');
705 encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
706 encode_item_sort(rbml_w, 'C');
708 encode_bounds_and_type_for_item(rbml_w, ecx, index,
709 ecx.local_id(associated_const.def_id));
711 let stab = stability::lookup_stability(ecx.tcx, associated_const.def_id);
712 let depr = stability::lookup_deprecation(ecx.tcx, associated_const.def_id);
713 encode_stability(rbml_w, stab);
714 encode_deprecation(rbml_w, depr);
716 let elem = ast_map::PathName(associated_const.name);
717 encode_path(rbml_w, impl_path.chain(Some(elem)));
719 if let Some(ii) = impl_item_opt {
720 encode_attributes(rbml_w, &ii.attrs);
721 encode_inlined_item(ecx,
723 InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id),
730 fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
731 rbml_w: &mut Encoder,
732 index: &mut CrateIndex<'tcx>,
733 m: &ty::Method<'tcx>,
734 impl_path: PathElems,
735 is_default_impl: bool,
737 impl_item_opt: Option<&hir::ImplItem>) {
739 debug!("encode_info_for_method: {:?} {:?}", m.def_id,
741 index.record(m.def_id, rbml_w);
742 rbml_w.start_tag(tag_items_data_item);
744 encode_method_ty_fields(ecx, rbml_w, index, m);
745 encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
746 encode_item_sort(rbml_w, 'r');
748 let stab = stability::lookup_stability(ecx.tcx, m.def_id);
749 let depr = stability::lookup_deprecation(ecx.tcx, m.def_id);
750 encode_stability(rbml_w, stab);
751 encode_deprecation(rbml_w, depr);
753 let m_node_id = ecx.local_id(m.def_id);
754 encode_bounds_and_type_for_item(rbml_w, ecx, index, m_node_id);
756 let elem = ast_map::PathName(m.name);
757 encode_path(rbml_w, impl_path.chain(Some(elem)));
758 if let Some(impl_item) = impl_item_opt {
759 if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
760 encode_attributes(rbml_w, &impl_item.attrs);
761 let scheme = ecx.tcx.lookup_item_type(m.def_id);
762 let any_types = !scheme.generics.types.is_empty();
763 let needs_inline = any_types || is_default_impl ||
764 attr::requests_inline(&impl_item.attrs);
765 if needs_inline || sig.constness == hir::Constness::Const {
766 encode_inlined_item(ecx,
768 InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id),
771 encode_constness(rbml_w, sig.constness);
773 let m_id = ecx.local_id(m.def_id);
774 encode_symbol(ecx, rbml_w, m_id);
776 encode_method_argument_names(rbml_w, &sig.decl);
783 fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
784 rbml_w: &mut Encoder,
785 index: &mut CrateIndex<'tcx>,
786 associated_type: &ty::AssociatedType<'tcx>,
787 impl_path: PathElems,
789 impl_item_opt: Option<&hir::ImplItem>) {
790 debug!("encode_info_for_associated_type({:?},{:?})",
791 associated_type.def_id,
792 associated_type.name);
794 index.record(associated_type.def_id, rbml_w);
795 rbml_w.start_tag(tag_items_data_item);
797 encode_def_id_and_key(ecx, rbml_w, associated_type.def_id);
798 encode_name(rbml_w, associated_type.name);
799 encode_visibility(rbml_w, associated_type.vis);
800 encode_family(rbml_w, 'y');
801 encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
802 encode_item_sort(rbml_w, 't');
804 let stab = stability::lookup_stability(ecx.tcx, associated_type.def_id);
805 let depr = stability::lookup_deprecation(ecx.tcx, associated_type.def_id);
806 encode_stability(rbml_w, stab);
807 encode_deprecation(rbml_w, depr);
809 let elem = ast_map::PathName(associated_type.name);
810 encode_path(rbml_w, impl_path.chain(Some(elem)));
812 if let Some(ii) = impl_item_opt {
813 encode_attributes(rbml_w, &ii.attrs);
815 encode_predicates(rbml_w, ecx, index,
816 &ecx.tcx.lookup_predicates(associated_type.def_id),
820 if let Some(ty) = associated_type.ty {
821 encode_type(ecx, rbml_w, ty);
827 fn encode_method_argument_names(rbml_w: &mut Encoder,
828 decl: &hir::FnDecl) {
829 rbml_w.start_tag(tag_method_argument_names);
830 for arg in &decl.inputs {
831 let tag = tag_method_argument_name;
832 if let hir::PatIdent(_, ref path1, _) = arg.pat.node {
833 let name = path1.node.name.as_str();
834 rbml_w.wr_tagged_bytes(tag, name.as_bytes());
836 rbml_w.wr_tagged_bytes(tag, &[]);
842 fn encode_repr_attrs(rbml_w: &mut Encoder,
844 attrs: &[ast::Attribute]) {
845 let mut repr_attrs = Vec::new();
847 repr_attrs.extend(attr::find_repr_attrs(ecx.tcx.sess.diagnostic(),
850 rbml_w.start_tag(tag_items_data_item_repr);
851 repr_attrs.encode(rbml_w);
855 fn encode_inlined_item(ecx: &EncodeContext,
856 rbml_w: &mut Encoder,
857 ii: InlinedItemRef) {
858 let mut eii = ecx.encode_inlined_item.borrow_mut();
859 let eii: &mut EncodeInlinedItem = &mut *eii;
860 eii(ecx, rbml_w, ii);
862 encode_mir(ecx, rbml_w, ii);
865 fn encode_mir(ecx: &EncodeContext, rbml_w: &mut Encoder, ii: InlinedItemRef) {
867 InlinedItemRef::Item(item) => item.id,
868 InlinedItemRef::TraitItem(_, trait_item) => trait_item.id,
869 InlinedItemRef::ImplItem(_, impl_item) => impl_item.id,
870 InlinedItemRef::Foreign(foreign_item) => foreign_item.id
873 if let Some(mir) = ecx.mir_map.get(&id) {
874 rbml_w.start_tag(tag_mir as usize);
875 Encodable::encode(mir, rbml_w).unwrap();
880 const FN_FAMILY: char = 'f';
881 const STATIC_METHOD_FAMILY: char = 'F';
882 const METHOD_FAMILY: char = 'h';
884 // Encodes the inherent implementations of a structure, enumeration, or trait.
885 fn encode_inherent_implementations(ecx: &EncodeContext,
886 rbml_w: &mut Encoder,
888 match ecx.tcx.inherent_impls.borrow().get(&def_id) {
890 Some(implementations) => {
891 for &impl_def_id in implementations.iter() {
892 rbml_w.start_tag(tag_items_data_item_inherent_impl);
893 encode_def_id(rbml_w, impl_def_id);
900 fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<&attr::Stability>) {
901 stab_opt.map(|stab| {
902 rbml_w.start_tag(tag_items_data_item_stability);
903 stab.encode(rbml_w).unwrap();
908 fn encode_deprecation(rbml_w: &mut Encoder, depr_opt: Option<attr::Deprecation>) {
909 depr_opt.map(|depr| {
910 rbml_w.start_tag(tag_items_data_item_deprecation);
911 depr.encode(rbml_w).unwrap();
916 fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
917 rbml_w: &mut Encoder,
918 xrefs: FnvHashMap<XRef<'tcx>, u32>)
920 let ty_str_ctxt = &tyencode::ctxt {
924 abbrevs: &ecx.type_abbrevs
927 let mut xref_positions = vec![0; xrefs.len()];
928 rbml_w.start_tag(tag_xref_data);
929 for (xref, id) in xrefs.into_iter() {
930 xref_positions[id as usize] = rbml_w.mark_stable_position() as u32;
932 XRef::Predicate(p) => {
933 tyencode::enc_predicate(rbml_w, ty_str_ctxt, &p)
939 rbml_w.start_tag(tag_xref_index);
940 index::write_dense_index(xref_positions, rbml_w.writer);
944 fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
945 rbml_w: &mut Encoder,
947 index: &mut CrateIndex<'tcx>,
949 vis: hir::Visibility) {
952 debug!("encoding info for item at {}",
953 tcx.sess.codemap().span_to_string(item.span));
955 let def_id = ecx.tcx.map.local_def_id(item.id);
956 let stab = stability::lookup_stability(tcx, ecx.tcx.map.local_def_id(item.id));
957 let depr = stability::lookup_deprecation(tcx, ecx.tcx.map.local_def_id(item.id));
960 hir::ItemStatic(_, m, _) => {
961 index.record(def_id, rbml_w);
962 rbml_w.start_tag(tag_items_data_item);
963 encode_def_id_and_key(ecx, rbml_w, def_id);
964 if m == hir::MutMutable {
965 encode_family(rbml_w, 'b');
967 encode_family(rbml_w, 'c');
969 encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
970 encode_symbol(ecx, rbml_w, item.id);
971 encode_name(rbml_w, item.name);
972 encode_path(rbml_w, path);
973 encode_visibility(rbml_w, vis);
974 encode_stability(rbml_w, stab);
975 encode_deprecation(rbml_w, depr);
976 encode_attributes(rbml_w, &item.attrs);
979 hir::ItemConst(_, _) => {
980 index.record(def_id, rbml_w);
981 rbml_w.start_tag(tag_items_data_item);
982 encode_def_id_and_key(ecx, rbml_w, def_id);
983 encode_family(rbml_w, 'C');
984 encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
985 encode_name(rbml_w, item.name);
986 encode_path(rbml_w, path);
987 encode_attributes(rbml_w, &item.attrs);
988 encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
989 encode_visibility(rbml_w, vis);
990 encode_stability(rbml_w, stab);
991 encode_deprecation(rbml_w, depr);
994 hir::ItemFn(ref decl, _, constness, _, ref generics, _) => {
995 index.record(def_id, rbml_w);
996 rbml_w.start_tag(tag_items_data_item);
997 encode_def_id_and_key(ecx, rbml_w, def_id);
998 encode_family(rbml_w, FN_FAMILY);
999 let tps_len = generics.ty_params.len();
1000 encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
1001 encode_name(rbml_w, item.name);
1002 encode_path(rbml_w, path);
1003 encode_attributes(rbml_w, &item.attrs);
1004 let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs);
1005 if needs_inline || constness == hir::Constness::Const {
1006 encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
1009 encode_symbol(ecx, rbml_w, item.id);
1011 encode_constness(rbml_w, constness);
1012 encode_visibility(rbml_w, vis);
1013 encode_stability(rbml_w, stab);
1014 encode_deprecation(rbml_w, depr);
1015 encode_method_argument_names(rbml_w, &**decl);
1018 hir::ItemMod(ref m) => {
1019 index.record(def_id, rbml_w);
1020 encode_info_for_mod(ecx,
1029 hir::ItemForeignMod(ref fm) => {
1030 index.record(def_id, rbml_w);
1031 rbml_w.start_tag(tag_items_data_item);
1032 encode_def_id_and_key(ecx, rbml_w, def_id);
1033 encode_family(rbml_w, 'n');
1034 encode_name(rbml_w, item.name);
1035 encode_path(rbml_w, path);
1037 // Encode all the items in this module.
1038 for foreign_item in &fm.items {
1039 rbml_w.wr_tagged_u64(tag_mod_child,
1040 def_to_u64(ecx.tcx.map.local_def_id(foreign_item.id)));
1042 encode_visibility(rbml_w, vis);
1043 encode_stability(rbml_w, stab);
1044 encode_deprecation(rbml_w, depr);
1047 hir::ItemTy(..) => {
1048 index.record(def_id, rbml_w);
1049 rbml_w.start_tag(tag_items_data_item);
1050 encode_def_id_and_key(ecx, rbml_w, def_id);
1051 encode_family(rbml_w, 'y');
1052 encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
1053 encode_name(rbml_w, item.name);
1054 encode_path(rbml_w, path);
1055 encode_visibility(rbml_w, vis);
1056 encode_stability(rbml_w, stab);
1057 encode_deprecation(rbml_w, depr);
1060 hir::ItemEnum(ref enum_definition, _) => {
1061 index.record(def_id, rbml_w);
1063 rbml_w.start_tag(tag_items_data_item);
1064 encode_def_id_and_key(ecx, rbml_w, def_id);
1065 encode_family(rbml_w, 't');
1066 encode_item_variances(rbml_w, ecx, item.id);
1067 encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
1068 encode_name(rbml_w, item.name);
1069 encode_attributes(rbml_w, &item.attrs);
1070 encode_repr_attrs(rbml_w, ecx, &item.attrs);
1071 for v in &enum_definition.variants {
1072 encode_variant_id(rbml_w, ecx.tcx.map.local_def_id(v.node.data.id()));
1074 encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
1075 encode_path(rbml_w, path);
1077 // Encode inherent implementations for this enumeration.
1078 encode_inherent_implementations(ecx, rbml_w, def_id);
1080 encode_visibility(rbml_w, vis);
1081 encode_stability(rbml_w, stab);
1082 encode_deprecation(rbml_w, depr);
1085 encode_enum_variant_info(ecx,
1091 hir::ItemStruct(ref struct_def, _) => {
1092 let def = ecx.tcx.lookup_adt_def(def_id);
1093 let variant = def.struct_variant();
1095 /* Index the class*/
1096 index.record(def_id, rbml_w);
1098 /* Now, make an item for the class itself */
1099 rbml_w.start_tag(tag_items_data_item);
1100 encode_def_id_and_key(ecx, rbml_w, def_id);
1101 encode_family(rbml_w, 'S');
1102 encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
1104 encode_item_variances(rbml_w, ecx, item.id);
1105 encode_name(rbml_w, item.name);
1106 encode_attributes(rbml_w, &item.attrs);
1107 encode_path(rbml_w, path.clone());
1108 encode_stability(rbml_w, stab);
1109 encode_deprecation(rbml_w, depr);
1110 encode_visibility(rbml_w, vis);
1111 encode_repr_attrs(rbml_w, ecx, &item.attrs);
1113 /* Encode def_ids for each field and method
1114 for methods, write all the stuff get_trait_method
1116 encode_struct_fields(rbml_w, variant);
1118 encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
1120 // Encode inherent implementations for this structure.
1121 encode_inherent_implementations(ecx, rbml_w, def_id);
1123 if !struct_def.is_struct() {
1124 let ctor_did = ecx.tcx.map.local_def_id(struct_def.id());
1125 rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor,
1126 def_to_u64(ctor_did));
1131 for field in &variant.fields {
1132 encode_field(ecx, rbml_w, field, index);
1135 // If this is a tuple-like struct, encode the type of the constructor.
1136 if !struct_def.is_struct() {
1137 encode_info_for_struct_ctor(ecx, rbml_w, item.name, struct_def.id(), index, item.id);
1140 hir::ItemDefaultImpl(unsafety, _) => {
1141 index.record(def_id, rbml_w);
1142 rbml_w.start_tag(tag_items_data_item);
1143 encode_def_id_and_key(ecx, rbml_w, def_id);
1144 encode_family(rbml_w, 'd');
1145 encode_name(rbml_w, item.name);
1146 encode_unsafety(rbml_w, unsafety);
1148 let trait_ref = tcx.impl_trait_ref(ecx.tcx.map.local_def_id(item.id)).unwrap();
1149 encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
1152 hir::ItemImpl(unsafety, polarity, _, _, _, ref ast_items) => {
1153 // We need to encode information about the default methods we
1154 // have inherited, so we drive this based on the impl structure.
1155 let impl_items = tcx.impl_items.borrow();
1156 let items = impl_items.get(&def_id).unwrap();
1158 index.record(def_id, rbml_w);
1159 rbml_w.start_tag(tag_items_data_item);
1160 encode_def_id_and_key(ecx, rbml_w, def_id);
1161 encode_family(rbml_w, 'i');
1162 encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
1163 encode_name(rbml_w, item.name);
1164 encode_attributes(rbml_w, &item.attrs);
1165 encode_unsafety(rbml_w, unsafety);
1166 encode_polarity(rbml_w, polarity);
1168 match tcx.custom_coerce_unsized_kinds.borrow().get(&ecx.tcx.map.local_def_id(item.id)) {
1170 rbml_w.start_tag(tag_impl_coerce_unsized_kind);
1171 kind.encode(rbml_w);
1177 for &item_def_id in items {
1178 rbml_w.start_tag(tag_item_impl_item);
1180 ty::ConstTraitItemId(item_def_id) => {
1181 encode_def_id(rbml_w, item_def_id);
1182 encode_item_sort(rbml_w, 'C');
1184 ty::MethodTraitItemId(item_def_id) => {
1185 encode_def_id(rbml_w, item_def_id);
1186 encode_item_sort(rbml_w, 'r');
1188 ty::TypeTraitItemId(item_def_id) => {
1189 encode_def_id(rbml_w, item_def_id);
1190 encode_item_sort(rbml_w, 't');
1195 if let Some(trait_ref) = tcx.impl_trait_ref(ecx.tcx.map.local_def_id(item.id)) {
1196 encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
1198 encode_path(rbml_w, path.clone());
1199 encode_stability(rbml_w, stab);
1200 encode_deprecation(rbml_w, depr);
1203 // Iterate down the trait items, emitting them. We rely on the
1204 // assumption that all of the actually implemented trait items
1205 // appear first in the impl structure, in the same order they do
1206 // in the ast. This is a little sketchy.
1207 let num_implemented_methods = ast_items.len();
1208 for (i, &trait_item_def_id) in items.iter().enumerate() {
1209 let ast_item = if i < num_implemented_methods {
1215 match tcx.impl_or_trait_item(trait_item_def_id.def_id()) {
1216 ty::ConstTraitItem(ref associated_const) => {
1217 encode_info_for_associated_const(ecx,
1225 ty::MethodTraitItem(ref method_type) => {
1226 encode_info_for_method(ecx,
1235 ty::TypeTraitItem(ref associated_type) => {
1236 encode_info_for_associated_type(ecx,
1247 hir::ItemTrait(_, _, _, ref ms) => {
1248 index.record(def_id, rbml_w);
1249 rbml_w.start_tag(tag_items_data_item);
1250 encode_def_id_and_key(ecx, rbml_w, def_id);
1251 encode_family(rbml_w, 'I');
1252 encode_item_variances(rbml_w, ecx, item.id);
1253 let trait_def = tcx.lookup_trait_def(def_id);
1254 let trait_predicates = tcx.lookup_predicates(def_id);
1255 encode_unsafety(rbml_w, trait_def.unsafety);
1256 encode_paren_sugar(rbml_w, trait_def.paren_sugar);
1257 encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id));
1258 encode_associated_type_names(rbml_w, &trait_def.associated_type_names);
1259 encode_generics(rbml_w, ecx, index,
1260 &trait_def.generics, &trait_predicates,
1262 encode_predicates(rbml_w, ecx, index,
1263 &tcx.lookup_super_predicates(def_id),
1264 tag_item_super_predicates);
1265 encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
1266 encode_name(rbml_w, item.name);
1267 encode_attributes(rbml_w, &item.attrs);
1268 encode_visibility(rbml_w, vis);
1269 encode_stability(rbml_w, stab);
1270 encode_deprecation(rbml_w, depr);
1271 for &method_def_id in tcx.trait_item_def_ids(def_id).iter() {
1272 rbml_w.start_tag(tag_item_trait_item);
1273 match method_def_id {
1274 ty::ConstTraitItemId(const_def_id) => {
1275 encode_def_id(rbml_w, const_def_id);
1276 encode_item_sort(rbml_w, 'C');
1278 ty::MethodTraitItemId(method_def_id) => {
1279 encode_def_id(rbml_w, method_def_id);
1280 encode_item_sort(rbml_w, 'r');
1282 ty::TypeTraitItemId(type_def_id) => {
1283 encode_def_id(rbml_w, type_def_id);
1284 encode_item_sort(rbml_w, 't');
1289 rbml_w.wr_tagged_u64(tag_mod_child,
1290 def_to_u64(method_def_id.def_id()));
1292 encode_path(rbml_w, path.clone());
1294 // Encode inherent implementations for this trait.
1295 encode_inherent_implementations(ecx, rbml_w, def_id);
1299 // Now output the trait item info for each trait item.
1300 let r = tcx.trait_item_def_ids(def_id);
1301 for (i, &item_def_id) in r.iter().enumerate() {
1302 assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE);
1304 index.record(item_def_id.def_id(), rbml_w);
1305 rbml_w.start_tag(tag_items_data_item);
1307 encode_parent_item(rbml_w, def_id);
1309 let stab = stability::lookup_stability(tcx, item_def_id.def_id());
1310 let depr = stability::lookup_deprecation(tcx, item_def_id.def_id());
1311 encode_stability(rbml_w, stab);
1312 encode_deprecation(rbml_w, depr);
1314 let trait_item_type =
1315 tcx.impl_or_trait_item(item_def_id.def_id());
1316 let is_nonstatic_method;
1317 match trait_item_type {
1318 ty::ConstTraitItem(associated_const) => {
1319 encode_name(rbml_w, associated_const.name);
1320 encode_def_id_and_key(ecx, rbml_w, associated_const.def_id);
1321 encode_visibility(rbml_w, associated_const.vis);
1323 let elem = ast_map::PathName(associated_const.name);
1325 path.clone().chain(Some(elem)));
1327 encode_family(rbml_w, 'C');
1329 encode_bounds_and_type_for_item(rbml_w, ecx, index,
1330 ecx.local_id(associated_const.def_id));
1332 is_nonstatic_method = false;
1334 ty::MethodTraitItem(method_ty) => {
1335 let method_def_id = item_def_id.def_id();
1337 encode_method_ty_fields(ecx, rbml_w, index, &*method_ty);
1339 let elem = ast_map::PathName(method_ty.name);
1341 path.clone().chain(Some(elem)));
1343 match method_ty.explicit_self {
1344 ty::StaticExplicitSelfCategory => {
1345 encode_family(rbml_w,
1346 STATIC_METHOD_FAMILY);
1349 encode_family(rbml_w,
1353 encode_bounds_and_type_for_item(rbml_w, ecx, index,
1354 ecx.local_id(method_def_id));
1356 is_nonstatic_method = method_ty.explicit_self !=
1357 ty::StaticExplicitSelfCategory;
1359 ty::TypeTraitItem(associated_type) => {
1360 encode_name(rbml_w, associated_type.name);
1361 encode_def_id_and_key(ecx, rbml_w, associated_type.def_id);
1363 let elem = ast_map::PathName(associated_type.name);
1365 path.clone().chain(Some(elem)));
1367 encode_item_sort(rbml_w, 't');
1368 encode_family(rbml_w, 'y');
1370 if let Some(ty) = associated_type.ty {
1371 encode_type(ecx, rbml_w, ty);
1374 is_nonstatic_method = false;
1378 let trait_item = &ms[i];
1379 encode_attributes(rbml_w, &trait_item.attrs);
1380 match trait_item.node {
1381 hir::ConstTraitItem(_, ref default) => {
1382 if default.is_some() {
1383 encode_item_sort(rbml_w, 'C');
1385 encode_item_sort(rbml_w, 'c');
1388 encode_inlined_item(ecx, rbml_w,
1389 InlinedItemRef::TraitItem(def_id, trait_item));
1391 hir::MethodTraitItem(ref sig, ref body) => {
1392 // If this is a static method, we've already
1394 if is_nonstatic_method {
1395 // FIXME: I feel like there is something funny
1397 encode_bounds_and_type_for_item(rbml_w, ecx, index,
1398 ecx.local_id(item_def_id.def_id()));
1402 encode_item_sort(rbml_w, 'p');
1403 encode_inlined_item(ecx, rbml_w,
1404 InlinedItemRef::TraitItem(def_id, trait_item));
1406 encode_item_sort(rbml_w, 'r');
1408 encode_method_argument_names(rbml_w, &sig.decl);
1411 hir::TypeTraitItem(..) => {}
1417 hir::ItemExternCrate(_) | hir::ItemUse(_) => {
1418 // these are encoded separately
1423 fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
1424 rbml_w: &mut Encoder,
1425 nitem: &hir::ForeignItem,
1426 index: &mut CrateIndex<'tcx>,
1429 let def_id = ecx.tcx.map.local_def_id(nitem.id);
1431 index.record(def_id, rbml_w);
1432 rbml_w.start_tag(tag_items_data_item);
1433 encode_def_id_and_key(ecx, rbml_w, def_id);
1434 encode_visibility(rbml_w, nitem.vis);
1436 hir::ForeignItemFn(ref fndecl, _) => {
1437 encode_family(rbml_w, FN_FAMILY);
1438 encode_bounds_and_type_for_item(rbml_w, ecx, index, nitem.id);
1439 encode_name(rbml_w, nitem.name);
1440 if abi == abi::RustIntrinsic || abi == abi::PlatformIntrinsic {
1441 encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(nitem));
1443 encode_attributes(rbml_w, &*nitem.attrs);
1444 let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
1445 let depr = stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
1446 encode_stability(rbml_w, stab);
1447 encode_deprecation(rbml_w, depr);
1448 encode_symbol(ecx, rbml_w, nitem.id);
1449 encode_method_argument_names(rbml_w, &*fndecl);
1451 hir::ForeignItemStatic(_, mutbl) => {
1453 encode_family(rbml_w, 'b');
1455 encode_family(rbml_w, 'c');
1457 encode_bounds_and_type_for_item(rbml_w, ecx, index, nitem.id);
1458 encode_attributes(rbml_w, &*nitem.attrs);
1459 let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
1460 let depr = stability::lookup_deprecation(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id));
1461 encode_stability(rbml_w, stab);
1462 encode_deprecation(rbml_w, depr);
1463 encode_symbol(ecx, rbml_w, nitem.id);
1464 encode_name(rbml_w, nitem.name);
1467 encode_path(rbml_w, path);
1471 fn my_visit_expr(expr: &hir::Expr,
1472 rbml_w: &mut Encoder,
1473 ecx: &EncodeContext,
1474 index: &mut CrateIndex) {
1476 hir::ExprClosure(..) => {
1477 let def_id = ecx.tcx.map.local_def_id(expr.id);
1479 index.record(def_id, rbml_w);
1481 rbml_w.start_tag(tag_items_data_item);
1482 encode_def_id_and_key(ecx, rbml_w, def_id);
1484 rbml_w.start_tag(tag_items_closure_ty);
1485 write_closure_type(ecx, rbml_w, &ecx.tcx.tables.borrow().closure_tys[&def_id]);
1488 rbml_w.start_tag(tag_items_closure_kind);
1489 ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap();
1492 ecx.tcx.map.with_path(expr.id, |path| encode_path(rbml_w, path));
1500 fn my_visit_item<'a, 'tcx>(i: &hir::Item,
1501 rbml_w: &mut Encoder,
1502 ecx: &EncodeContext<'a, 'tcx>,
1503 index: &mut CrateIndex<'tcx>) {
1504 ecx.tcx.map.with_path(i.id, |path| {
1505 encode_info_for_item(ecx, rbml_w, i, index, path, i.vis);
1509 fn my_visit_foreign_item<'a, 'tcx>(ni: &hir::ForeignItem,
1510 rbml_w: &mut Encoder,
1511 ecx: &EncodeContext<'a, 'tcx>,
1512 index: &mut CrateIndex<'tcx>) {
1513 debug!("writing foreign item {}::{}",
1514 ecx.tcx.map.path_to_string(ni.id),
1517 let abi = ecx.tcx.map.get_foreign_abi(ni.id);
1518 ecx.tcx.map.with_path(ni.id, |path| {
1519 encode_info_for_foreign_item(ecx, rbml_w,
1525 struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
1526 rbml_w_for_visit_item: &'a mut Encoder<'b>,
1527 ecx: &'a EncodeContext<'c,'tcx>,
1528 index: &'a mut CrateIndex<'tcx>,
1531 impl<'a, 'b, 'c, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'c, 'tcx> {
1532 fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
1533 intravisit::walk_expr(self, ex);
1534 my_visit_expr(ex, self.rbml_w_for_visit_item, self.ecx, self.index);
1536 fn visit_item(&mut self, i: &'tcx hir::Item) {
1537 intravisit::walk_item(self, i);
1538 my_visit_item(i, self.rbml_w_for_visit_item, self.ecx, self.index);
1540 fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) {
1541 intravisit::walk_foreign_item(self, ni);
1542 my_visit_foreign_item(ni, self.rbml_w_for_visit_item, self.ecx, self.index);
1546 fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
1547 rbml_w: &mut Encoder)
1548 -> CrateIndex<'tcx> {
1549 let krate = ecx.tcx.map.krate();
1551 let mut index = CrateIndex {
1552 items: IndexData::new(ecx.tcx.map.num_local_def_ids()),
1555 rbml_w.start_tag(tag_items_data);
1557 index.record(DefId::local(CRATE_DEF_INDEX), rbml_w);
1558 encode_info_for_mod(ecx,
1563 [].iter().cloned().chain(LinkedPath::empty()),
1564 syntax::parse::token::intern(&ecx.link_meta.crate_name),
1567 krate.visit_all_items(&mut EncodeVisitor {
1570 rbml_w_for_visit_item: &mut *rbml_w,
1577 fn encode_item_index(rbml_w: &mut Encoder, index: IndexData) {
1578 rbml_w.start_tag(tag_index);
1579 index.write_index(rbml_w.writer);
1583 fn encode_meta_item(rbml_w: &mut Encoder, mi: &ast::MetaItem) {
1585 ast::MetaWord(ref name) => {
1586 rbml_w.start_tag(tag_meta_item_word);
1587 rbml_w.wr_tagged_str(tag_meta_item_name, name);
1590 ast::MetaNameValue(ref name, ref value) => {
1592 ast::LitStr(ref value, _) => {
1593 rbml_w.start_tag(tag_meta_item_name_value);
1594 rbml_w.wr_tagged_str(tag_meta_item_name, name);
1595 rbml_w.wr_tagged_str(tag_meta_item_value, value);
1598 _ => {/* FIXME (#623): encode other variants */ }
1601 ast::MetaList(ref name, ref items) => {
1602 rbml_w.start_tag(tag_meta_item_list);
1603 rbml_w.wr_tagged_str(tag_meta_item_name, name);
1604 for inner_item in items {
1605 encode_meta_item(rbml_w, &**inner_item);
1612 fn encode_attributes(rbml_w: &mut Encoder, attrs: &[ast::Attribute]) {
1613 rbml_w.start_tag(tag_attributes);
1615 rbml_w.start_tag(tag_attribute);
1616 rbml_w.wr_tagged_u8(tag_attribute_is_sugared_doc, attr.node.is_sugared_doc as u8);
1617 encode_meta_item(rbml_w, &*attr.node.value);
1623 fn encode_unsafety(rbml_w: &mut Encoder, unsafety: hir::Unsafety) {
1624 let byte: u8 = match unsafety {
1625 hir::Unsafety::Normal => 0,
1626 hir::Unsafety::Unsafe => 1,
1628 rbml_w.wr_tagged_u8(tag_unsafety, byte);
1631 fn encode_paren_sugar(rbml_w: &mut Encoder, paren_sugar: bool) {
1632 let byte: u8 = if paren_sugar {1} else {0};
1633 rbml_w.wr_tagged_u8(tag_paren_sugar, byte);
1636 fn encode_defaulted(rbml_w: &mut Encoder, is_defaulted: bool) {
1637 let byte: u8 = if is_defaulted {1} else {0};
1638 rbml_w.wr_tagged_u8(tag_defaulted_trait, byte);
1641 fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[Name]) {
1642 rbml_w.start_tag(tag_associated_type_names);
1643 for &name in names {
1644 rbml_w.wr_tagged_str(tag_associated_type_name, &name.as_str());
1649 fn encode_polarity(rbml_w: &mut Encoder, polarity: hir::ImplPolarity) {
1650 let byte: u8 = match polarity {
1651 hir::ImplPolarity::Positive => 0,
1652 hir::ImplPolarity::Negative => 1,
1654 rbml_w.wr_tagged_u8(tag_polarity, byte);
1657 fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
1658 fn get_ordered_deps(cstore: &cstore::CStore)
1659 -> Vec<(CrateNum, Rc<cstore::crate_metadata>)> {
1660 // Pull the cnums and name,vers,hash out of cstore
1661 let mut deps = Vec::new();
1662 cstore.iter_crate_data(|cnum, val| {
1663 deps.push((cnum, val.clone()));
1667 deps.sort_by(|kv1, kv2| kv1.0.cmp(&kv2.0));
1669 // Sanity-check the crate numbers
1670 let mut expected_cnum = 1;
1671 for &(n, _) in &deps {
1672 assert_eq!(n, expected_cnum);
1679 // We're just going to write a list of crate 'name-hash-version's, with
1680 // the assumption that they are numbered 1 to n.
1681 // FIXME (#2166): This is not nearly enough to support correct versioning
1682 // but is enough to get transitive crate dependencies working.
1683 rbml_w.start_tag(tag_crate_deps);
1684 for (_cnum, dep) in get_ordered_deps(cstore) {
1685 encode_crate_dep(rbml_w, &dep);
1690 fn encode_lang_items(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1691 rbml_w.start_tag(tag_lang_items);
1693 for (i, &opt_def_id) in ecx.tcx.lang_items.items() {
1694 if let Some(def_id) = opt_def_id {
1695 if def_id.is_local() {
1696 rbml_w.start_tag(tag_lang_items_item);
1697 rbml_w.wr_tagged_u32(tag_lang_items_item_id, i as u32);
1698 rbml_w.wr_tagged_u32(tag_lang_items_item_index, def_id.index.as_u32());
1704 for i in &ecx.tcx.lang_items.missing {
1705 rbml_w.wr_tagged_u32(tag_lang_items_missing, *i as u32);
1708 rbml_w.end_tag(); // tag_lang_items
1711 fn encode_native_libraries(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1712 rbml_w.start_tag(tag_native_libraries);
1714 for &(ref lib, kind) in ecx.tcx.sess.cstore.used_libraries().iter() {
1716 cstore::NativeStatic => {} // these libraries are not propagated
1717 cstore::NativeFramework | cstore::NativeUnknown => {
1718 rbml_w.start_tag(tag_native_libraries_lib);
1719 rbml_w.wr_tagged_u32(tag_native_libraries_kind, kind as u32);
1720 rbml_w.wr_tagged_str(tag_native_libraries_name, lib);
1729 fn encode_plugin_registrar_fn(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1730 match ecx.tcx.sess.plugin_registrar_fn.get() {
1732 let def_id = ecx.tcx.map.local_def_id(id);
1733 rbml_w.wr_tagged_u32(tag_plugin_registrar_fn, def_id.index.as_u32());
1739 fn encode_codemap(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1740 rbml_w.start_tag(tag_codemap);
1741 let codemap = ecx.tcx.sess.codemap();
1743 for filemap in &codemap.files.borrow()[..] {
1745 if filemap.lines.borrow().is_empty() || filemap.is_imported() {
1746 // No need to export empty filemaps, as they can't contain spans
1747 // that need translation.
1748 // Also no need to re-export imported filemaps, as any downstream
1749 // crate will import them from their original source.
1753 rbml_w.start_tag(tag_codemap_filemap);
1754 filemap.encode(rbml_w);
1761 /// Serialize the text of the exported macros
1762 fn encode_macro_defs(rbml_w: &mut Encoder,
1763 krate: &hir::Crate) {
1764 rbml_w.start_tag(tag_macro_defs);
1765 for def in &krate.exported_macros {
1766 rbml_w.start_tag(tag_macro_def);
1768 encode_name(rbml_w, def.name);
1769 encode_attributes(rbml_w, &def.attrs);
1771 rbml_w.wr_tagged_str(tag_macro_def_body,
1772 &::syntax::print::pprust::tts_to_string(&def.body));
1779 fn encode_struct_field_attrs(ecx: &EncodeContext,
1780 rbml_w: &mut Encoder,
1781 krate: &hir::Crate) {
1782 struct StructFieldVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
1783 ecx: &'a EncodeContext<'b, 'tcx>,
1784 rbml_w: &'a mut Encoder<'c>,
1787 impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for StructFieldVisitor<'a, 'b, 'c, 'tcx> {
1788 fn visit_struct_field(&mut self, field: &hir::StructField) {
1789 self.rbml_w.start_tag(tag_struct_field);
1790 let def_id = self.ecx.tcx.map.local_def_id(field.node.id);
1791 encode_def_id(self.rbml_w, def_id);
1792 encode_attributes(self.rbml_w, &field.node.attrs);
1793 self.rbml_w.end_tag();
1797 rbml_w.start_tag(tag_struct_fields);
1798 krate.visit_all_items(&mut StructFieldVisitor { ecx: ecx, rbml_w: rbml_w });
1804 struct ImplVisitor<'a, 'tcx:'a> {
1805 tcx: &'a ty::ctxt<'tcx>,
1806 impls: FnvHashMap<DefId, Vec<DefId>>
1809 impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> {
1810 fn visit_item(&mut self, item: &hir::Item) {
1811 if let hir::ItemImpl(..) = item.node {
1812 let impl_id = self.tcx.map.local_def_id(item.id);
1813 if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) {
1814 self.impls.entry(trait_ref.def_id)
1822 /// Encodes an index, mapping each trait to its (local) implementations.
1823 fn encode_impls<'a>(ecx: &'a EncodeContext,
1825 rbml_w: &'a mut Encoder) {
1826 let mut visitor = ImplVisitor {
1830 krate.visit_all_items(&mut visitor);
1832 rbml_w.start_tag(tag_impls);
1833 for (trait_, trait_impls) in visitor.impls {
1834 rbml_w.start_tag(tag_impls_trait);
1835 encode_def_id(rbml_w, trait_);
1836 for impl_ in trait_impls {
1837 rbml_w.wr_tagged_u64(tag_impls_trait_impl, def_to_u64(impl_));
1844 fn encode_misc_info(ecx: &EncodeContext,
1846 rbml_w: &mut Encoder) {
1847 rbml_w.start_tag(tag_misc_info);
1848 rbml_w.start_tag(tag_misc_info_crate_items);
1849 for item_id in &krate.module.item_ids {
1850 rbml_w.wr_tagged_u64(tag_mod_child,
1851 def_to_u64(ecx.tcx.map.local_def_id(item_id.id)));
1853 let item = ecx.tcx.map.expect_item(item_id.id);
1854 each_auxiliary_node_id(item, |auxiliary_node_id| {
1855 rbml_w.wr_tagged_u64(tag_mod_child,
1856 def_to_u64(ecx.tcx.map.local_def_id(auxiliary_node_id)));
1861 // Encode reexports for the root module.
1862 encode_reexports(ecx, rbml_w, 0);
1868 // Encodes all reachable symbols in this crate into the metadata.
1870 // This pass is seeded off the reachability list calculated in the
1871 // middle::reachable module but filters out items that either don't have a
1872 // symbol associated with them (they weren't translated) or if they're an FFI
1873 // definition (as that's not defined in this crate).
1874 fn encode_reachable(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1875 rbml_w.start_tag(tag_reachable_ids);
1876 for &id in ecx.reachable {
1877 let def_id = ecx.tcx.map.local_def_id(id);
1878 rbml_w.wr_tagged_u32(tag_reachable_id, def_id.index.as_u32());
1883 fn encode_crate_dep(rbml_w: &mut Encoder,
1884 dep: &cstore::crate_metadata) {
1885 rbml_w.start_tag(tag_crate_dep);
1886 rbml_w.wr_tagged_str(tag_crate_dep_crate_name, &dep.name());
1887 let hash = decoder::get_crate_hash(dep.data());
1888 rbml_w.wr_tagged_str(tag_crate_dep_hash, hash.as_str());
1889 rbml_w.wr_tagged_u8(tag_crate_dep_explicitly_linked,
1890 dep.explicitly_linked.get() as u8);
1894 fn encode_hash(rbml_w: &mut Encoder, hash: &Svh) {
1895 rbml_w.wr_tagged_str(tag_crate_hash, hash.as_str());
1898 fn encode_rustc_version(rbml_w: &mut Encoder) {
1899 rbml_w.wr_tagged_str(tag_rustc_version, &rustc_version());
1902 fn encode_crate_name(rbml_w: &mut Encoder, crate_name: &str) {
1903 rbml_w.wr_tagged_str(tag_crate_crate_name, crate_name);
1906 fn encode_crate_triple(rbml_w: &mut Encoder, triple: &str) {
1907 rbml_w.wr_tagged_str(tag_crate_triple, triple);
1910 fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) {
1911 let tag = tag_dylib_dependency_formats;
1912 match ecx.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) {
1914 let s = arr.iter().enumerate().filter_map(|(i, slot)| {
1915 let kind = match *slot {
1916 Linkage::NotLinked |
1917 Linkage::IncludedFromDylib => return None,
1918 Linkage::Dynamic => "d",
1919 Linkage::Static => "s",
1921 Some(format!("{}:{}", i + 1, kind))
1922 }).collect::<Vec<String>>();
1923 rbml_w.wr_tagged_str(tag, &s.join(","));
1926 rbml_w.wr_tagged_str(tag, "");
1931 // NB: Increment this as you change the metadata encoding version.
1932 #[allow(non_upper_case_globals)]
1933 pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 2 ];
1935 pub fn encode_metadata(parms: EncodeParams, krate: &hir::Crate) -> Vec<u8> {
1942 encode_inlined_item,
1948 let ecx = EncodeContext {
1951 reexports: reexports,
1952 item_symbols: item_symbols,
1953 link_meta: link_meta,
1955 encode_inlined_item: RefCell::new(encode_inlined_item),
1956 type_abbrevs: RefCell::new(FnvHashMap()),
1957 reachable: reachable,
1961 let mut wr = Cursor::new(Vec::new());
1964 let mut rbml_w = Encoder::new(&mut wr);
1965 tls::enter_encoding_context(&ecx, &mut rbml_w, |_, rbml_w| {
1966 encode_metadata_inner(rbml_w, &ecx, krate)
1970 // RBML compacts the encoded bytes whenever appropriate,
1971 // so there are some garbages left after the end of the data.
1972 let metalen = wr.seek(SeekFrom::Current(0)).unwrap() as usize;
1973 let mut v = wr.into_inner();
1974 v.truncate(metalen);
1975 assert_eq!(v.len(), metalen);
1977 // And here we run into yet another obscure archive bug: in which metadata
1978 // loaded from archives may have trailing garbage bytes. Awhile back one of
1979 // our tests was failing sporadically on the OSX 64-bit builders (both nopt
1980 // and opt) by having rbml generate an out-of-bounds panic when looking at
1983 // Upon investigation it turned out that the metadata file inside of an rlib
1984 // (and ar archive) was being corrupted. Some compilations would generate a
1985 // metadata file which would end in a few extra bytes, while other
1986 // compilations would not have these extra bytes appended to the end. These
1987 // extra bytes were interpreted by rbml as an extra tag, so they ended up
1988 // being interpreted causing the out-of-bounds.
1990 // The root cause of why these extra bytes were appearing was never
1991 // discovered, and in the meantime the solution we're employing is to insert
1992 // the length of the metadata to the start of the metadata. Later on this
1993 // will allow us to slice the metadata to the precise length that we just
1994 // generated regardless of trailing bytes that end up in it.
1995 let len = v.len() as u32;
1996 v.insert(0, (len >> 0) as u8);
1997 v.insert(0, (len >> 8) as u8);
1998 v.insert(0, (len >> 16) as u8);
1999 v.insert(0, (len >> 24) as u8);
2003 fn encode_metadata_inner(rbml_w: &mut Encoder,
2004 ecx: &EncodeContext,
2005 krate: &hir::Crate) {
2009 lang_item_bytes: u64,
2010 native_lib_bytes: u64,
2011 plugin_registrar_fn_bytes: u64,
2013 macro_defs_bytes: u64,
2022 let mut stats = Stats {
2026 native_lib_bytes: 0,
2027 plugin_registrar_fn_bytes: 0,
2029 macro_defs_bytes: 0,
2039 encode_rustc_version(rbml_w);
2040 encode_crate_name(rbml_w, &ecx.link_meta.crate_name);
2041 encode_crate_triple(rbml_w, &ecx.tcx.sess.opts.target_triple);
2042 encode_hash(rbml_w, &ecx.link_meta.crate_hash);
2043 encode_dylib_dependency_formats(rbml_w, &ecx);
2045 let mut i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2046 encode_attributes(rbml_w, &krate.attrs);
2047 stats.attr_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2049 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2050 encode_crate_deps(rbml_w, ecx.cstore);
2051 stats.dep_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2053 // Encode the language items.
2054 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2055 encode_lang_items(&ecx, rbml_w);
2056 stats.lang_item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2058 // Encode the native libraries used
2059 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2060 encode_native_libraries(&ecx, rbml_w);
2061 stats.native_lib_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2063 // Encode the plugin registrar function
2064 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2065 encode_plugin_registrar_fn(&ecx, rbml_w);
2066 stats.plugin_registrar_fn_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2069 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2070 encode_codemap(&ecx, rbml_w);
2071 stats.codemap_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2073 // Encode macro definitions
2074 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2075 encode_macro_defs(rbml_w, krate);
2076 stats.macro_defs_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2078 // Encode the def IDs of impls, for coherence checking.
2079 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2080 encode_impls(&ecx, krate, rbml_w);
2081 stats.impl_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2083 // Encode miscellaneous info.
2084 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2085 encode_misc_info(&ecx, krate, rbml_w);
2086 encode_reachable(&ecx, rbml_w);
2087 stats.misc_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2089 // Encode and index the items.
2090 rbml_w.start_tag(tag_items);
2091 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2092 let index = encode_info_for_items(&ecx, rbml_w);
2093 stats.item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2096 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2097 encode_item_index(rbml_w, index.items);
2098 stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2100 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2101 encode_xrefs(&ecx, rbml_w, index.xrefs);
2102 stats.xref_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2104 encode_struct_field_attrs(&ecx, rbml_w, krate);
2106 stats.total_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2108 if ecx.tcx.sess.meta_stats() {
2109 for e in rbml_w.writer.get_ref() {
2111 stats.zero_bytes += 1;
2115 println!("metadata stats:");
2116 println!(" attribute bytes: {}", stats.attr_bytes);
2117 println!(" dep bytes: {}", stats.dep_bytes);
2118 println!(" lang item bytes: {}", stats.lang_item_bytes);
2119 println!(" native bytes: {}", stats.native_lib_bytes);
2120 println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
2121 println!(" codemap bytes: {}", stats.codemap_bytes);
2122 println!(" macro def bytes: {}", stats.macro_defs_bytes);
2123 println!(" impl bytes: {}", stats.impl_bytes);
2124 println!(" misc bytes: {}", stats.misc_bytes);
2125 println!(" item bytes: {}", stats.item_bytes);
2126 println!(" index bytes: {}", stats.index_bytes);
2127 println!(" xref bytes: {}", stats.xref_bytes);
2128 println!(" zero bytes: {}", stats.zero_bytes);
2129 println!(" total bytes: {}", stats.total_bytes);
2133 // Get the encoded string for a type
2134 pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> Vec<u8> {
2135 let mut wr = Cursor::new(Vec::new());
2136 tyencode::enc_ty(&mut Encoder::new(&mut wr), &tyencode::ctxt {
2137 diag: tcx.sess.diagnostic(),
2140 abbrevs: &RefCell::new(FnvHashMap())