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