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