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