]>
Commit | Line | Data |
---|---|---|
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 |
16 | use common::*; |
17 | use cstore; | |
18 | use decoder; | |
19 | use tyencode; | |
20 | use index::{self, IndexData}; | |
21 | ||
9cc50fc6 | 22 | use middle::cstore::{LOCAL_CRATE, CrateStore, InlinedItemRef, LinkMeta, tls}; |
1a4d82fc | 23 | use middle::def; |
b039eaaf | 24 | use middle::def_id::{CRATE_DEF_INDEX, DefId}; |
e9174d1e | 25 | use middle::dependency_format::Linkage; |
1a4d82fc | 26 | use middle::stability; |
b039eaaf | 27 | use middle::subst; |
e9174d1e | 28 | use middle::ty::{self, Ty}; |
92a42be0 SL |
29 | |
30 | use rustc::back::svh::Svh; | |
31 | use rustc::front::map::{LinkedPath, PathElem, PathElems}; | |
32 | use rustc::front::map as ast_map; | |
7453a54e | 33 | use rustc::mir::mir_map::MirMap; |
92a42be0 SL |
34 | use rustc::session::config; |
35 | use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet}; | |
1a4d82fc JJ |
36 | |
37 | use serialize::Encodable; | |
38 | use std::cell::RefCell; | |
c34b1796 AL |
39 | use std::io::prelude::*; |
40 | use std::io::{Cursor, SeekFrom}; | |
e9174d1e | 41 | use std::rc::Rc; |
b039eaaf | 42 | use std::u32; |
7453a54e | 43 | use syntax::abi::Abi; |
b039eaaf | 44 | use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum}; |
7453a54e | 45 | use syntax::codemap::BytePos; |
b039eaaf SL |
46 | use syntax::attr; |
47 | use syntax::attr::AttrMetaMethods; | |
9cc50fc6 | 48 | use syntax::errors::Handler; |
970d7e83 | 49 | use syntax::parse::token::special_idents; |
223e47cc | 50 | use syntax; |
c34b1796 | 51 | use rbml::writer::Encoder; |
1a4d82fc | 52 | |
7453a54e | 53 | use rustc_front::hir::{self, PatKind}; |
92a42be0 SL |
54 | use rustc_front::intravisit::Visitor; |
55 | use rustc_front::intravisit; | |
1a4d82fc | 56 | |
1a4d82fc JJ |
57 | pub type EncodeInlinedItem<'a> = |
58 | Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>; | |
59 | ||
60 | pub 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 | ||
72 | pub 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 |
85 | impl<'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)] | |
93 | pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } | |
94 | ||
95 | struct CrateIndex<'tcx> { | |
96 | items: IndexData, | |
97 | xrefs: FnvHashMap<XRef<'tcx>, u32>, // sequentially-assigned | |
223e47cc LB |
98 | } |
99 | ||
b039eaaf SL |
100 | impl<'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 | ||
112 | fn 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 |
116 | fn 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. | |
122 | fn 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 | ||
130 | fn 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 |
140 | fn 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 | 151 | fn 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 | 155 | pub 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 | 160 | pub fn def_to_string(did: DefId) -> String { |
b039eaaf | 161 | format!("{}:{}", did.krate, did.index.as_usize()) |
970d7e83 | 162 | } |
223e47cc | 163 | |
1a4d82fc JJ |
164 | fn 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 |
173 | fn 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 |
184 | fn 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 | ||
194 | fn 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 | 200 | fn 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 |
207 | fn 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 |
216 | fn 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 | 225 | fn 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 | 239 | fn 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 | ||
245 | fn 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 | ||
249 | fn 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 |
264 | fn 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 |
321 | fn 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 | 339 | fn 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 | ||
356 | fn 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 | ||
381 | fn 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 | 426 | fn 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 | 434 | fn 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 | 442 | fn 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 |
452 | fn 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 | 482 | fn 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 | 486 | fn 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 |
509 | fn 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 | ||
548 | fn 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 ¶m.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 | ||
593 | fn 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 |
610 | fn 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 | ||
621 | fn 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 |
640 | fn 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 |
684 | fn 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 |
737 | fn 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 | 781 | fn 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 | ||
796 | fn 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 | ||
809 | fn 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 | ||
826 | fn 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 |
838 | const FN_FAMILY: char = 'f'; |
839 | const STATIC_METHOD_FAMILY: char = 'F'; | |
840 | const METHOD_FAMILY: char = 'h'; | |
841 | ||
1a4d82fc JJ |
842 | // Encodes the inherent implementations of a structure, enumeration, or trait. |
843 | fn 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 | 858 | fn 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 |
866 | fn 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 |
874 | fn 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 | ||
896 | fn 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 |
1379 | fn 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 | 1427 | fn 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 | ||
1459 | fn 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 |
1468 | fn 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 | ||
1484 | struct 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 |
1490 | impl<'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 | 1505 | fn 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 | 1536 | fn 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 | 1542 | fn 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 |
1571 | fn 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 | 1582 | fn 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 |
1590 | fn 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 |
1595 | fn 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 | 1600 | fn 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 | 1608 | fn 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 | 1616 | fn 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 | ||
1649 | fn 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 |
1670 | fn 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 | ||
1688 | fn 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 |
1698 | fn 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 |
1723 | fn 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 |
1744 | fn 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 |
1769 | struct ImplVisitor<'a, 'tcx:'a> { |
1770 | tcx: &'a ty::ctxt<'tcx>, | |
1771 | impls: FnvHashMap<DefId, Vec<DefId>> | |
1a4d82fc JJ |
1772 | } |
1773 | ||
b039eaaf SL |
1774 | impl<'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 | 1788 | fn 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 | ||
1809 | fn 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). | |
1839 | fn 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 | ||
1848 | fn 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 | ||
1859 | fn 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 |
1863 | fn encode_rustc_version(rbml_w: &mut Encoder) { |
1864 | rbml_w.wr_tagged_str(tag_rustc_version, &rustc_version()); | |
1865 | } | |
1866 | ||
1a4d82fc | 1867 | fn 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 | 1871 | fn 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 | 1875 | fn 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 | 1898 | pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 2 ]; |
1a4d82fc | 1899 | |
b039eaaf | 1900 | pub 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 |
1966 | fn 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 | 2097 | pub 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 | } |