1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 #![allow(unused_must_use)] // everything is just a MemWriter, can't fail
14 #![allow(non_camel_case_types)]
18 use metadata::common::*;
20 use metadata::decoder;
21 use metadata::tyencode;
22 use metadata::index::{self, IndexEntry};
23 use metadata::inline::InlinedItemRef;
25 use middle::def_id::{DefId, LOCAL_CRATE};
26 use middle::dependency_format::Linkage;
27 use middle::stability;
28 use middle::ty::{self, Ty};
29 use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
31 use serialize::Encodable;
32 use std::cell::RefCell;
33 use std::io::prelude::*;
34 use std::io::{Cursor, SeekFrom};
37 use syntax::ast::{NodeId, Name, CRATE_NODE_ID, CrateNum};
38 use syntax::diagnostic::SpanHandler;
39 use syntax::parse::token::special_idents;
41 use rbml::writer::Encoder;
43 use rustc_front::hir as ast;
44 use rustc_front::visit::Visitor;
45 use rustc_front::visit;
46 use rustc_front::attr;
47 use rustc_front::attr::AttrMetaMethods;
48 use front::map::{LinkedPath, PathElem, PathElems};
49 use front::map as ast_map;
51 pub type EncodeInlinedItem<'a> =
52 Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
54 pub struct EncodeParams<'a, 'tcx: 'a> {
55 pub diag: &'a SpanHandler,
56 pub tcx: &'a ty::ctxt<'tcx>,
57 pub reexports: &'a def::ExportMap,
58 pub item_symbols: &'a RefCell<NodeMap<String>>,
59 pub link_meta: &'a LinkMeta,
60 pub cstore: &'a cstore::CStore,
61 pub encode_inlined_item: EncodeInlinedItem<'a>,
62 pub reachable: &'a NodeSet,
65 pub struct EncodeContext<'a, 'tcx: 'a> {
66 pub diag: &'a SpanHandler,
67 pub tcx: &'a ty::ctxt<'tcx>,
68 pub reexports: &'a def::ExportMap,
69 pub item_symbols: &'a RefCell<NodeMap<String>>,
70 pub link_meta: &'a LinkMeta,
71 pub cstore: &'a cstore::CStore,
72 pub encode_inlined_item: RefCell<EncodeInlinedItem<'a>>,
73 pub type_abbrevs: tyencode::abbrev_map<'tcx>,
74 pub reachable: &'a NodeSet,
77 fn encode_name(rbml_w: &mut Encoder, name: Name) {
78 rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str());
81 fn encode_impl_type_basename(rbml_w: &mut Encoder, name: Name) {
82 rbml_w.wr_tagged_str(tag_item_impl_type_basename, &name.as_str());
85 fn encode_def_id(rbml_w: &mut Encoder, id: DefId) {
86 rbml_w.wr_tagged_u64(tag_def_id, def_to_u64(id));
89 fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder,
90 ecx: &EncodeContext<'a, 'tcx>,
91 trait_ref: ty::TraitRef<'tcx>,
93 let ty_str_ctxt = &tyencode::ctxt {
97 abbrevs: &ecx.type_abbrevs
100 rbml_w.start_tag(tag);
101 tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref);
105 // Item info table encoding
106 fn encode_family(rbml_w: &mut Encoder, c: char) {
107 rbml_w.wr_tagged_u8(tag_items_data_item_family, c as u8);
110 pub fn def_to_u64(did: DefId) -> u64 {
111 (did.krate as u64) << 32 | (did.node as u64)
114 pub fn def_to_string(did: DefId) -> String {
115 format!("{}:{}", did.krate, did.node)
118 fn encode_item_variances(rbml_w: &mut Encoder,
121 let v = ecx.tcx.item_variances(DefId::local(id));
122 rbml_w.start_tag(tag_item_variances);
127 fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder,
128 ecx: &EncodeContext<'a, 'tcx>,
130 encode_bounds_and_type(rbml_w,
132 &ecx.tcx.lookup_item_type(DefId::local(id)),
133 &ecx.tcx.lookup_predicates(DefId::local(id)));
136 fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder,
137 ecx: &EncodeContext<'a, 'tcx>,
138 scheme: &ty::TypeScheme<'tcx>,
139 predicates: &ty::GenericPredicates<'tcx>) {
140 encode_generics(rbml_w, ecx, &scheme.generics, &predicates, tag_item_generics);
141 encode_type(ecx, rbml_w, scheme.ty);
144 fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) {
145 let id = def_to_u64(vid);
146 rbml_w.wr_tagged_u64(tag_items_data_item_variant, id);
147 rbml_w.wr_tagged_u64(tag_mod_child, id);
150 pub fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
151 rbml_w: &mut Encoder,
152 closure_type: &ty::ClosureTy<'tcx>) {
153 let ty_str_ctxt = &tyencode::ctxt {
157 abbrevs: &ecx.type_abbrevs
159 tyencode::enc_closure_ty(rbml_w, ty_str_ctxt, closure_type);
162 pub fn write_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
163 rbml_w: &mut Encoder,
165 let ty_str_ctxt = &tyencode::ctxt {
169 abbrevs: &ecx.type_abbrevs
171 tyencode::enc_ty(rbml_w, ty_str_ctxt, typ);
174 pub fn write_trait_ref<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
175 rbml_w: &mut Encoder,
176 trait_ref: &ty::TraitRef<'tcx>) {
177 let ty_str_ctxt = &tyencode::ctxt {
181 abbrevs: &ecx.type_abbrevs
183 tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, *trait_ref);
186 pub fn write_region(ecx: &EncodeContext,
187 rbml_w: &mut Encoder,
189 let ty_str_ctxt = &tyencode::ctxt {
193 abbrevs: &ecx.type_abbrevs
195 tyencode::enc_region(rbml_w, ty_str_ctxt, r);
198 fn encode_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
199 rbml_w: &mut Encoder,
201 rbml_w.start_tag(tag_items_data_item_type);
202 write_type(ecx, rbml_w, typ);
206 fn encode_region(ecx: &EncodeContext,
207 rbml_w: &mut Encoder,
209 rbml_w.start_tag(tag_items_data_region);
210 write_region(ecx, rbml_w, r);
214 fn encode_method_fty<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
215 rbml_w: &mut Encoder,
216 typ: &ty::BareFnTy<'tcx>) {
217 rbml_w.start_tag(tag_item_method_fty);
219 let ty_str_ctxt = &tyencode::ctxt {
223 abbrevs: &ecx.type_abbrevs
225 tyencode::enc_bare_fn_ty(rbml_w, ty_str_ctxt, typ);
230 fn encode_symbol(ecx: &EncodeContext,
231 rbml_w: &mut Encoder,
233 match ecx.item_symbols.borrow().get(&id) {
235 debug!("encode_symbol(id={}, str={})", id, *x);
236 rbml_w.wr_tagged_str(tag_items_data_item_symbol, x);
239 ecx.diag.handler().bug(
240 &format!("encode_symbol: id not found {}", id));
245 fn encode_disr_val(_: &EncodeContext,
246 rbml_w: &mut Encoder,
247 disr_val: ty::Disr) {
248 rbml_w.wr_tagged_str(tag_disr_val, &disr_val.to_string());
251 fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) {
252 rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(id));
255 fn encode_struct_fields(rbml_w: &mut Encoder,
256 variant: ty::VariantDef,
258 for f in &variant.fields {
259 if f.name == special_idents::unnamed_field.name {
260 rbml_w.start_tag(tag_item_unnamed_field);
262 rbml_w.start_tag(tag_item_field);
263 encode_name(rbml_w, f.name);
265 encode_struct_field_family(rbml_w, f.vis);
266 encode_def_id(rbml_w, f.did);
267 rbml_w.wr_tagged_u64(tag_item_field_origin, def_to_u64(origin));
272 fn encode_enum_variant_info(ecx: &EncodeContext,
273 rbml_w: &mut Encoder,
275 vis: ast::Visibility,
276 index: &mut Vec<IndexEntry>) {
277 debug!("encode_enum_variant_info(id={})", id);
279 let mut disr_val = 0;
280 let def = ecx.tcx.lookup_adt_def(DefId::local(id));
281 for variant in &def.variants {
282 let vid = variant.did;
283 assert!(vid.is_local());
285 if let ty::VariantKind::Dict = variant.kind() {
286 // tuple-like enum variant fields aren't really items so
287 // don't try to encode them.
288 for field in &variant.fields {
289 encode_field(ecx, rbml_w, field, index);
293 index.push(IndexEntry {
295 pos: rbml_w.mark_stable_position(),
297 rbml_w.start_tag(tag_items_data_item);
298 encode_def_id(rbml_w, vid);
299 encode_family(rbml_w, match variant.kind() {
300 ty::VariantKind::Unit | ty::VariantKind::Tuple => 'v',
301 ty::VariantKind::Dict => 'V'
303 encode_name(rbml_w, variant.name);
304 encode_parent_item(rbml_w, DefId::local(id));
305 encode_visibility(rbml_w, vis);
307 let attrs = ecx.tcx.get_attrs(vid);
308 encode_attributes(rbml_w, &attrs);
309 encode_repr_attrs(rbml_w, ecx, &attrs);
311 let stab = stability::lookup(ecx.tcx, vid);
312 encode_stability(rbml_w, stab);
314 encode_struct_fields(rbml_w, variant, vid);
316 let specified_disr_val = variant.disr_val;
317 if specified_disr_val != disr_val {
318 encode_disr_val(ecx, rbml_w, specified_disr_val);
319 disr_val = specified_disr_val;
321 encode_bounds_and_type_for_item(rbml_w, ecx, vid.node);
323 ecx.tcx.map.with_path(vid.node, |path| encode_path(rbml_w, path));
325 disr_val = disr_val.wrapping_add(1);
329 fn encode_path<PI: Iterator<Item=PathElem>>(rbml_w: &mut Encoder, path: PI) {
330 let path = path.collect::<Vec<_>>();
331 rbml_w.start_tag(tag_path);
332 rbml_w.wr_tagged_u32(tag_path_len, path.len() as u32);
334 let tag = match *pe {
335 ast_map::PathMod(_) => tag_path_elem_mod,
336 ast_map::PathName(_) => tag_path_elem_name
338 rbml_w.wr_tagged_str(tag, &pe.name().as_str());
343 fn encode_reexported_static_method(rbml_w: &mut Encoder,
345 method_def_id: DefId,
347 debug!("(encode reexported static method) {}::{}",
348 exp.name, method_name);
349 rbml_w.start_tag(tag_items_data_item_reexport);
350 rbml_w.wr_tagged_u64(tag_items_data_item_reexport_def_id,
351 def_to_u64(method_def_id));
352 rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
353 &format!("{}::{}", exp.name,
358 fn encode_reexported_static_base_methods(ecx: &EncodeContext,
359 rbml_w: &mut Encoder,
362 let impl_items = ecx.tcx.impl_items.borrow();
363 match ecx.tcx.inherent_impls.borrow().get(&exp.def_id) {
364 Some(implementations) => {
365 for base_impl_did in implementations.iter() {
366 for &method_did in impl_items.get(base_impl_did).unwrap() {
367 let impl_item = ecx.tcx.impl_or_trait_item(method_did.def_id());
368 if let ty::MethodTraitItem(ref m) = impl_item {
369 encode_reexported_static_method(rbml_w,
383 fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
384 rbml_w: &mut Encoder,
387 match ecx.tcx.trait_items_cache.borrow().get(&exp.def_id) {
388 Some(trait_items) => {
389 for trait_item in trait_items.iter() {
390 if let ty::MethodTraitItem(ref m) = *trait_item {
391 encode_reexported_static_method(rbml_w,
403 fn encode_reexported_static_methods(ecx: &EncodeContext,
404 rbml_w: &mut Encoder,
407 if let Some(ast_map::NodeItem(item)) = ecx.tcx.map.find(exp.def_id.node) {
408 let path_differs = ecx.tcx.map.with_path(exp.def_id.node, |path| {
409 let (mut a, mut b) = (path, mod_path.clone());
411 match (a.next(), b.next()) {
412 (None, None) => return true,
413 (None, _) | (_, None) => return false,
414 (Some(x), Some(y)) => if x != y { return false },
420 // We don't need to reexport static methods on items
421 // declared in the same module as our `pub use ...` since
422 // that's done when we encode the item itself.
424 // The only exception is when the reexport *changes* the
425 // name e.g. `pub use Foo = self::Bar` -- we have
426 // encoded metadata for static methods relative to Bar,
427 // but not yet for Foo.
429 if path_differs || item.ident.name != exp.name {
430 if !encode_reexported_static_base_methods(ecx, rbml_w, exp) {
431 if encode_reexported_static_trait_methods(ecx, rbml_w, exp) {
432 debug!("(encode reexported static methods) {} [trait]",
437 debug!("(encode reexported static methods) {} [base]",
444 /// Iterates through "auxiliary node IDs", which are node IDs that describe
445 /// top-level items that are sub-items of the given item. Specifically:
447 /// * For newtype structs, iterates through the node ID of the constructor.
448 fn each_auxiliary_node_id<F>(item: &ast::Item, callback: F) -> bool where
449 F: FnOnce(NodeId) -> bool,
451 let mut continue_ = true;
453 ast::ItemStruct(ref struct_def, _) => {
454 // If this is a newtype struct, return the constructor.
455 match struct_def.ctor_id {
456 Some(ctor_id) if !struct_def.fields.is_empty() &&
457 struct_def.fields[0].node.kind.is_unnamed() => {
458 continue_ = callback(ctor_id);
469 fn encode_reexports(ecx: &EncodeContext,
470 rbml_w: &mut Encoder,
473 debug!("(encoding info for module) encoding reexports for {}", id);
474 match ecx.reexports.get(&id) {
476 debug!("(encoding info for module) found reexports for {}", id);
478 debug!("(encoding info for module) reexport '{}' ({}/{}) for \
484 rbml_w.start_tag(tag_items_data_item_reexport);
485 rbml_w.wr_tagged_u64(tag_items_data_item_reexport_def_id,
486 def_to_u64(exp.def_id));
487 rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
490 encode_reexported_static_methods(ecx, rbml_w, path.clone(), exp);
493 None => debug!("(encoding info for module) found no reexports for {}", id),
497 fn encode_info_for_mod(ecx: &EncodeContext,
498 rbml_w: &mut Encoder,
500 attrs: &[ast::Attribute],
504 vis: ast::Visibility) {
505 rbml_w.start_tag(tag_items_data_item);
506 encode_def_id(rbml_w, DefId::local(id));
507 encode_family(rbml_w, 'm');
508 encode_name(rbml_w, name);
509 debug!("(encoding info for module) encoding info for module ID {}", id);
511 // Encode info about all the module children.
512 for item in &md.items {
513 rbml_w.wr_tagged_u64(tag_mod_child,
514 def_to_u64(DefId::local(item.id)));
516 each_auxiliary_node_id(&**item, |auxiliary_node_id| {
517 rbml_w.wr_tagged_u64(tag_mod_child,
518 def_to_u64(DefId::local(auxiliary_node_id)));
522 if let ast::ItemImpl(..) = item.node {
523 let (ident, did) = (item.ident, item.id);
524 debug!("(encoding info for module) ... encoding impl {} ({}/{})",
526 did, ecx.tcx.map.node_to_string(did));
528 rbml_w.wr_tagged_u64(tag_mod_impl, def_to_u64(DefId::local(did)));
532 encode_path(rbml_w, path.clone());
533 encode_visibility(rbml_w, vis);
535 let stab = stability::lookup(ecx.tcx, DefId::local(id));
536 encode_stability(rbml_w, stab);
538 // Encode the reexports of this module, if this module is public.
539 if vis == ast::Public {
540 debug!("(encoding info for module) encoding reexports for {}", id);
541 encode_reexports(ecx, rbml_w, id, path);
543 encode_attributes(rbml_w, attrs);
548 fn encode_struct_field_family(rbml_w: &mut Encoder,
549 visibility: ast::Visibility) {
550 encode_family(rbml_w, match visibility {
552 ast::Inherited => 'N'
556 fn encode_visibility(rbml_w: &mut Encoder, visibility: ast::Visibility) {
557 let ch = match visibility {
559 ast::Inherited => 'i',
561 rbml_w.wr_tagged_u8(tag_items_data_item_visibility, ch as u8);
564 fn encode_constness(rbml_w: &mut Encoder, constness: ast::Constness) {
565 rbml_w.start_tag(tag_items_data_item_constness);
566 let ch = match constness {
567 ast::Constness::Const => 'c',
568 ast::Constness::NotConst => 'n',
570 rbml_w.wr_str(&ch.to_string());
574 fn encode_explicit_self(rbml_w: &mut Encoder,
575 explicit_self: &ty::ExplicitSelfCategory) {
576 let tag = tag_item_trait_method_explicit_self;
578 // Encode the base self type.
579 match *explicit_self {
580 ty::StaticExplicitSelfCategory => {
581 rbml_w.wr_tagged_bytes(tag, &['s' as u8]);
583 ty::ByValueExplicitSelfCategory => {
584 rbml_w.wr_tagged_bytes(tag, &['v' as u8]);
586 ty::ByBoxExplicitSelfCategory => {
587 rbml_w.wr_tagged_bytes(tag, &['~' as u8]);
589 ty::ByReferenceExplicitSelfCategory(_, m) => {
590 // FIXME(#4846) encode custom lifetime
591 let ch = encode_mutability(m);
592 rbml_w.wr_tagged_bytes(tag, &['&' as u8, ch]);
596 fn encode_mutability(m: ast::Mutability) -> u8 {
598 ast::MutImmutable => 'i' as u8,
599 ast::MutMutable => 'm' as u8,
604 fn encode_item_sort(rbml_w: &mut Encoder, sort: char) {
605 rbml_w.wr_tagged_u8(tag_item_trait_item_sort, sort as u8);
608 fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) {
609 rbml_w.wr_tagged_u8(tag_item_trait_parent_sort, sort as u8);
612 fn encode_provided_source(rbml_w: &mut Encoder,
613 source_opt: Option<DefId>) {
614 if let Some(source) = source_opt {
615 rbml_w.wr_tagged_u64(tag_item_method_provided_source, def_to_u64(source));
619 fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
620 rbml_w: &mut Encoder,
621 field: ty::FieldDef<'tcx>,
622 global_index: &mut Vec<IndexEntry>) {
624 let id = field.did.node;
626 let pos = rbml_w.mark_stable_position();
627 global_index.push(IndexEntry {
631 rbml_w.start_tag(tag_items_data_item);
632 debug!("encode_field: encoding {} {}", nm, id);
633 encode_struct_field_family(rbml_w, field.vis);
634 encode_name(rbml_w, nm);
635 encode_bounds_and_type_for_item(rbml_w, ecx, id);
636 encode_def_id(rbml_w, DefId::local(id));
638 let stab = stability::lookup(ecx.tcx, field.did);
639 encode_stability(rbml_w, stab);
644 fn encode_info_for_struct_ctor(ecx: &EncodeContext,
645 rbml_w: &mut Encoder,
648 index: &mut Vec<IndexEntry>,
650 index.push(IndexEntry {
652 pos: rbml_w.mark_stable_position(),
655 rbml_w.start_tag(tag_items_data_item);
656 encode_def_id(rbml_w, DefId::local(ctor_id));
657 encode_family(rbml_w, 'o');
658 encode_bounds_and_type_for_item(rbml_w, ecx, ctor_id);
659 encode_name(rbml_w, name);
660 ecx.tcx.map.with_path(ctor_id, |path| encode_path(rbml_w, path));
661 encode_parent_item(rbml_w, DefId::local(struct_id));
663 if ecx.item_symbols.borrow().contains_key(&ctor_id) {
664 encode_symbol(ecx, rbml_w, ctor_id);
667 let stab = stability::lookup(ecx.tcx, DefId::local(ctor_id));
668 encode_stability(rbml_w, stab);
670 // indicate that this is a tuple struct ctor, because downstream users will normally want
671 // the tuple struct definition, but without this there is no way for them to tell that
672 // they actually have a ctor rather than a normal function
673 rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]);
678 fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
679 ecx: &EncodeContext<'a, 'tcx>,
680 generics: &ty::Generics<'tcx>,
681 predicates: &ty::GenericPredicates<'tcx>,
684 rbml_w.start_tag(tag);
687 let ty_str_ctxt = &tyencode::ctxt {
691 abbrevs: &ecx.type_abbrevs
694 for param in &generics.types {
695 rbml_w.start_tag(tag_type_param_def);
696 tyencode::enc_type_param_def(rbml_w, ty_str_ctxt, param);
701 for param in &generics.regions {
702 rbml_w.start_tag(tag_region_param_def);
704 rbml_w.start_tag(tag_region_param_def_ident);
705 encode_name(rbml_w, param.name);
708 rbml_w.wr_tagged_u64(tag_region_param_def_def_id,
709 def_to_u64(param.def_id));
711 rbml_w.wr_tagged_u64(tag_region_param_def_space,
712 param.space.to_uint() as u64);
714 rbml_w.wr_tagged_u64(tag_region_param_def_index,
717 for &bound_region in ¶m.bounds {
718 encode_region(ecx, rbml_w, bound_region);
724 encode_predicates_in_current_doc(rbml_w, ecx, predicates);
729 fn encode_predicates_in_current_doc<'a,'tcx>(rbml_w: &mut Encoder,
730 ecx: &EncodeContext<'a,'tcx>,
731 predicates: &ty::GenericPredicates<'tcx>)
733 let ty_str_ctxt = &tyencode::ctxt {
737 abbrevs: &ecx.type_abbrevs
740 for (space, _, predicate) in predicates.predicates.iter_enumerated() {
741 rbml_w.start_tag(tag_predicate);
743 rbml_w.wr_tagged_u8(tag_predicate_space, space as u8);
745 rbml_w.start_tag(tag_predicate_data);
746 tyencode::enc_predicate(rbml_w, ty_str_ctxt, predicate);
753 fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder,
754 ecx: &EncodeContext<'a,'tcx>,
755 predicates: &ty::GenericPredicates<'tcx>,
758 rbml_w.start_tag(tag);
759 encode_predicates_in_current_doc(rbml_w, ecx, predicates);
763 fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
764 rbml_w: &mut Encoder,
765 method_ty: &ty::Method<'tcx>) {
766 encode_def_id(rbml_w, method_ty.def_id);
767 encode_name(rbml_w, method_ty.name);
768 encode_generics(rbml_w, ecx, &method_ty.generics, &method_ty.predicates,
769 tag_method_ty_generics);
770 encode_method_fty(ecx, rbml_w, &method_ty.fty);
771 encode_visibility(rbml_w, method_ty.vis);
772 encode_explicit_self(rbml_w, &method_ty.explicit_self);
773 match method_ty.explicit_self {
774 ty::StaticExplicitSelfCategory => {
775 encode_family(rbml_w, STATIC_METHOD_FAMILY);
777 _ => encode_family(rbml_w, METHOD_FAMILY)
779 encode_provided_source(rbml_w, method_ty.provided_source);
782 fn encode_info_for_associated_const(ecx: &EncodeContext,
783 rbml_w: &mut Encoder,
784 associated_const: &ty::AssociatedConst,
785 impl_path: PathElems,
787 impl_item_opt: Option<&ast::ImplItem>) {
788 debug!("encode_info_for_associated_const({:?},{:?})",
789 associated_const.def_id,
790 associated_const.name);
792 rbml_w.start_tag(tag_items_data_item);
794 encode_def_id(rbml_w, associated_const.def_id);
795 encode_name(rbml_w, associated_const.name);
796 encode_visibility(rbml_w, associated_const.vis);
797 encode_family(rbml_w, 'C');
798 encode_provided_source(rbml_w, associated_const.default);
800 encode_parent_item(rbml_w, DefId::local(parent_id));
801 encode_item_sort(rbml_w, 'C');
803 encode_bounds_and_type_for_item(rbml_w, ecx, associated_const.def_id.local_id());
805 let stab = stability::lookup(ecx.tcx, associated_const.def_id);
806 encode_stability(rbml_w, stab);
808 let elem = ast_map::PathName(associated_const.name);
809 encode_path(rbml_w, impl_path.chain(Some(elem)));
811 if let Some(ii) = impl_item_opt {
812 encode_attributes(rbml_w, &ii.attrs);
813 encode_inlined_item(ecx, rbml_w, InlinedItemRef::ImplItem(DefId::local(parent_id), ii));
819 fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
820 rbml_w: &mut Encoder,
821 m: &ty::Method<'tcx>,
822 impl_path: PathElems,
823 is_default_impl: bool,
825 impl_item_opt: Option<&ast::ImplItem>) {
827 debug!("encode_info_for_method: {:?} {:?}", m.def_id,
829 rbml_w.start_tag(tag_items_data_item);
831 encode_method_ty_fields(ecx, rbml_w, m);
832 encode_parent_item(rbml_w, DefId::local(parent_id));
833 encode_item_sort(rbml_w, 'r');
835 let stab = stability::lookup(ecx.tcx, m.def_id);
836 encode_stability(rbml_w, stab);
838 // The type for methods gets encoded twice, which is unfortunate.
839 encode_bounds_and_type_for_item(rbml_w, ecx, m.def_id.local_id());
841 let elem = ast_map::PathName(m.name);
842 encode_path(rbml_w, impl_path.chain(Some(elem)));
843 if let Some(impl_item) = impl_item_opt {
844 if let ast::MethodImplItem(ref sig, _) = impl_item.node {
845 encode_attributes(rbml_w, &impl_item.attrs);
846 let scheme = ecx.tcx.lookup_item_type(m.def_id);
847 let any_types = !scheme.generics.types.is_empty();
848 let needs_inline = any_types || is_default_impl ||
849 attr::requests_inline(&impl_item.attrs);
850 if needs_inline || sig.constness == ast::Constness::Const {
851 encode_inlined_item(ecx, rbml_w, InlinedItemRef::ImplItem(DefId::local(parent_id),
854 encode_constness(rbml_w, sig.constness);
856 encode_symbol(ecx, rbml_w, m.def_id.node);
858 encode_method_argument_names(rbml_w, &sig.decl);
865 fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
866 rbml_w: &mut Encoder,
867 associated_type: &ty::AssociatedType<'tcx>,
868 impl_path: PathElems,
870 impl_item_opt: Option<&ast::ImplItem>) {
871 debug!("encode_info_for_associated_type({:?},{:?})",
872 associated_type.def_id,
873 associated_type.name);
875 rbml_w.start_tag(tag_items_data_item);
877 encode_def_id(rbml_w, associated_type.def_id);
878 encode_name(rbml_w, associated_type.name);
879 encode_visibility(rbml_w, associated_type.vis);
880 encode_family(rbml_w, 'y');
881 encode_parent_item(rbml_w, DefId::local(parent_id));
882 encode_item_sort(rbml_w, 't');
884 let stab = stability::lookup(ecx.tcx, associated_type.def_id);
885 encode_stability(rbml_w, stab);
887 let elem = ast_map::PathName(associated_type.name);
888 encode_path(rbml_w, impl_path.chain(Some(elem)));
890 if let Some(ii) = impl_item_opt {
891 encode_attributes(rbml_w, &ii.attrs);
893 encode_predicates(rbml_w, ecx,
894 &ecx.tcx.lookup_predicates(associated_type.def_id),
898 if let Some(ty) = associated_type.ty {
899 encode_type(ecx, rbml_w, ty);
905 fn encode_method_argument_names(rbml_w: &mut Encoder,
906 decl: &ast::FnDecl) {
907 rbml_w.start_tag(tag_method_argument_names);
908 for arg in &decl.inputs {
909 let tag = tag_method_argument_name;
910 if let ast::PatIdent(_, ref path1, _) = arg.pat.node {
911 let name = path1.node.name.as_str();
912 rbml_w.wr_tagged_bytes(tag, name.as_bytes());
914 rbml_w.wr_tagged_bytes(tag, &[]);
920 fn encode_repr_attrs(rbml_w: &mut Encoder,
922 attrs: &[ast::Attribute]) {
923 let mut repr_attrs = Vec::new();
925 repr_attrs.extend(attr::find_repr_attrs(ecx.tcx.sess.diagnostic(),
928 rbml_w.start_tag(tag_items_data_item_repr);
929 repr_attrs.encode(rbml_w);
933 fn encode_inlined_item(ecx: &EncodeContext,
934 rbml_w: &mut Encoder,
935 ii: InlinedItemRef) {
936 let mut eii = ecx.encode_inlined_item.borrow_mut();
937 let eii: &mut EncodeInlinedItem = &mut *eii;
941 const FN_FAMILY: char = 'f';
942 const STATIC_METHOD_FAMILY: char = 'F';
943 const METHOD_FAMILY: char = 'h';
945 // Encodes the inherent implementations of a structure, enumeration, or trait.
946 fn encode_inherent_implementations(ecx: &EncodeContext,
947 rbml_w: &mut Encoder,
949 match ecx.tcx.inherent_impls.borrow().get(&def_id) {
951 Some(implementations) => {
952 for &impl_def_id in implementations.iter() {
953 rbml_w.start_tag(tag_items_data_item_inherent_impl);
954 encode_def_id(rbml_w, impl_def_id);
961 // Encodes the implementations of a trait defined in this crate.
962 fn encode_extension_implementations(ecx: &EncodeContext,
963 rbml_w: &mut Encoder,
964 trait_def_id: DefId) {
965 assert!(trait_def_id.is_local());
966 let def = ecx.tcx.lookup_trait_def(trait_def_id);
968 def.for_each_impl(ecx.tcx, |impl_def_id| {
969 rbml_w.start_tag(tag_items_data_item_extension_impl);
970 encode_def_id(rbml_w, impl_def_id);
975 fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<&attr::Stability>) {
976 stab_opt.map(|stab| {
977 rbml_w.start_tag(tag_items_data_item_stability);
978 stab.encode(rbml_w).unwrap();
983 fn encode_info_for_item(ecx: &EncodeContext,
984 rbml_w: &mut Encoder,
986 index: &mut Vec<IndexEntry>,
988 vis: ast::Visibility) {
991 fn add_to_index(item: &ast::Item, rbml_w: &mut Encoder,
992 index: &mut Vec<IndexEntry>) {
993 index.push(IndexEntry {
995 pos: rbml_w.mark_stable_position(),
999 debug!("encoding info for item at {}",
1000 tcx.sess.codemap().span_to_string(item.span));
1002 let def_id = DefId::local(item.id);
1003 let stab = stability::lookup(tcx, DefId::local(item.id));
1006 ast::ItemStatic(_, m, _) => {
1007 add_to_index(item, rbml_w, index);
1008 rbml_w.start_tag(tag_items_data_item);
1009 encode_def_id(rbml_w, def_id);
1010 if m == ast::MutMutable {
1011 encode_family(rbml_w, 'b');
1013 encode_family(rbml_w, 'c');
1015 encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
1016 encode_symbol(ecx, rbml_w, item.id);
1017 encode_name(rbml_w, item.ident.name);
1018 encode_path(rbml_w, path);
1019 encode_visibility(rbml_w, vis);
1020 encode_stability(rbml_w, stab);
1021 encode_attributes(rbml_w, &item.attrs);
1024 ast::ItemConst(_, _) => {
1025 add_to_index(item, rbml_w, index);
1026 rbml_w.start_tag(tag_items_data_item);
1027 encode_def_id(rbml_w, def_id);
1028 encode_family(rbml_w, 'C');
1029 encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
1030 encode_name(rbml_w, item.ident.name);
1031 encode_path(rbml_w, path);
1032 encode_attributes(rbml_w, &item.attrs);
1033 encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
1034 encode_visibility(rbml_w, vis);
1035 encode_stability(rbml_w, stab);
1038 ast::ItemFn(ref decl, _, constness, _, ref generics, _) => {
1039 add_to_index(item, rbml_w, index);
1040 rbml_w.start_tag(tag_items_data_item);
1041 encode_def_id(rbml_w, def_id);
1042 encode_family(rbml_w, FN_FAMILY);
1043 let tps_len = generics.ty_params.len();
1044 encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
1045 encode_name(rbml_w, item.ident.name);
1046 encode_path(rbml_w, path);
1047 encode_attributes(rbml_w, &item.attrs);
1048 let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs);
1049 if needs_inline || constness == ast::Constness::Const {
1050 encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
1053 encode_symbol(ecx, rbml_w, item.id);
1055 encode_constness(rbml_w, constness);
1056 encode_visibility(rbml_w, vis);
1057 encode_stability(rbml_w, stab);
1058 encode_method_argument_names(rbml_w, &**decl);
1061 ast::ItemMod(ref m) => {
1062 add_to_index(item, rbml_w, index);
1063 encode_info_for_mod(ecx,
1072 ast::ItemForeignMod(ref fm) => {
1073 add_to_index(item, rbml_w, index);
1074 rbml_w.start_tag(tag_items_data_item);
1075 encode_def_id(rbml_w, def_id);
1076 encode_family(rbml_w, 'n');
1077 encode_name(rbml_w, item.ident.name);
1078 encode_path(rbml_w, path);
1080 // Encode all the items in this module.
1081 for foreign_item in &fm.items {
1082 rbml_w.wr_tagged_u64(tag_mod_child,
1083 def_to_u64(DefId::local(foreign_item.id)));
1085 encode_visibility(rbml_w, vis);
1086 encode_stability(rbml_w, stab);
1089 ast::ItemTy(..) => {
1090 add_to_index(item, rbml_w, index);
1091 rbml_w.start_tag(tag_items_data_item);
1092 encode_def_id(rbml_w, def_id);
1093 encode_family(rbml_w, 'y');
1094 encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
1095 encode_name(rbml_w, item.ident.name);
1096 encode_path(rbml_w, path);
1097 encode_visibility(rbml_w, vis);
1098 encode_stability(rbml_w, stab);
1101 ast::ItemEnum(ref enum_definition, _) => {
1102 add_to_index(item, rbml_w, index);
1104 rbml_w.start_tag(tag_items_data_item);
1105 encode_def_id(rbml_w, def_id);
1106 encode_family(rbml_w, 't');
1107 encode_item_variances(rbml_w, ecx, item.id);
1108 encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
1109 encode_name(rbml_w, item.ident.name);
1110 encode_attributes(rbml_w, &item.attrs);
1111 encode_repr_attrs(rbml_w, ecx, &item.attrs);
1112 for v in &enum_definition.variants {
1113 encode_variant_id(rbml_w, DefId::local(v.node.id));
1115 encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
1116 encode_path(rbml_w, path);
1118 // Encode inherent implementations for this enumeration.
1119 encode_inherent_implementations(ecx, rbml_w, def_id);
1121 encode_visibility(rbml_w, vis);
1122 encode_stability(rbml_w, stab);
1125 encode_enum_variant_info(ecx,
1131 ast::ItemStruct(ref struct_def, _) => {
1132 let def = ecx.tcx.lookup_adt_def(def_id);
1133 let variant = def.struct_variant();
1135 for field in &variant.fields {
1136 encode_field(ecx, rbml_w, field, index);
1139 /* Index the class*/
1140 add_to_index(item, rbml_w, index);
1142 /* Now, make an item for the class itself */
1143 rbml_w.start_tag(tag_items_data_item);
1144 encode_def_id(rbml_w, def_id);
1145 encode_family(rbml_w, 'S');
1146 encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
1148 encode_item_variances(rbml_w, ecx, item.id);
1149 encode_name(rbml_w, item.ident.name);
1150 encode_attributes(rbml_w, &item.attrs);
1151 encode_path(rbml_w, path.clone());
1152 encode_stability(rbml_w, stab);
1153 encode_visibility(rbml_w, vis);
1154 encode_repr_attrs(rbml_w, ecx, &item.attrs);
1156 /* Encode def_ids for each field and method
1157 for methods, write all the stuff get_trait_method
1159 encode_struct_fields(rbml_w, variant, def_id);
1161 encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
1163 // Encode inherent implementations for this structure.
1164 encode_inherent_implementations(ecx, rbml_w, def_id);
1168 // If this is a tuple-like struct, encode the type of the constructor.
1169 match struct_def.ctor_id {
1171 encode_info_for_struct_ctor(ecx, rbml_w, item.ident.name,
1172 ctor_id, index, def_id.node);
1177 ast::ItemDefaultImpl(unsafety, _) => {
1178 add_to_index(item, rbml_w, index);
1179 rbml_w.start_tag(tag_items_data_item);
1180 encode_def_id(rbml_w, def_id);
1181 encode_family(rbml_w, 'd');
1182 encode_name(rbml_w, item.ident.name);
1183 encode_unsafety(rbml_w, unsafety);
1185 let trait_ref = tcx.impl_trait_ref(DefId::local(item.id)).unwrap();
1186 encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
1189 ast::ItemImpl(unsafety, polarity, _, _, ref ty, ref ast_items) => {
1190 // We need to encode information about the default methods we
1191 // have inherited, so we drive this based on the impl structure.
1192 let impl_items = tcx.impl_items.borrow();
1193 let items = impl_items.get(&def_id).unwrap();
1195 add_to_index(item, rbml_w, index);
1196 rbml_w.start_tag(tag_items_data_item);
1197 encode_def_id(rbml_w, def_id);
1198 encode_family(rbml_w, 'i');
1199 encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
1200 encode_name(rbml_w, item.ident.name);
1201 encode_attributes(rbml_w, &item.attrs);
1202 encode_unsafety(rbml_w, unsafety);
1203 encode_polarity(rbml_w, polarity);
1205 match tcx.custom_coerce_unsized_kinds.borrow().get(&DefId::local(item.id)) {
1207 rbml_w.start_tag(tag_impl_coerce_unsized_kind);
1208 kind.encode(rbml_w);
1215 ast::TyPath(None, ref path) if path.segments.len() == 1 => {
1216 let name = path.segments.last().unwrap().identifier.name;
1217 encode_impl_type_basename(rbml_w, name);
1221 for &item_def_id in items {
1222 rbml_w.start_tag(tag_item_impl_item);
1224 ty::ConstTraitItemId(item_def_id) => {
1225 encode_def_id(rbml_w, item_def_id);
1226 encode_item_sort(rbml_w, 'C');
1228 ty::MethodTraitItemId(item_def_id) => {
1229 encode_def_id(rbml_w, item_def_id);
1230 encode_item_sort(rbml_w, 'r');
1232 ty::TypeTraitItemId(item_def_id) => {
1233 encode_def_id(rbml_w, item_def_id);
1234 encode_item_sort(rbml_w, 't');
1239 if let Some(trait_ref) = tcx.impl_trait_ref(DefId::local(item.id)) {
1240 encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
1242 encode_path(rbml_w, path.clone());
1243 encode_stability(rbml_w, stab);
1246 // Iterate down the trait items, emitting them. We rely on the
1247 // assumption that all of the actually implemented trait items
1248 // appear first in the impl structure, in the same order they do
1249 // in the ast. This is a little sketchy.
1250 let num_implemented_methods = ast_items.len();
1251 for (i, &trait_item_def_id) in items.iter().enumerate() {
1252 let ast_item = if i < num_implemented_methods {
1253 Some(&*ast_items[i])
1258 index.push(IndexEntry {
1259 node: trait_item_def_id.def_id().node,
1260 pos: rbml_w.mark_stable_position(),
1263 match tcx.impl_or_trait_item(trait_item_def_id.def_id()) {
1264 ty::ConstTraitItem(ref associated_const) => {
1265 encode_info_for_associated_const(ecx,
1272 ty::MethodTraitItem(ref method_type) => {
1273 encode_info_for_method(ecx,
1281 ty::TypeTraitItem(ref associated_type) => {
1282 encode_info_for_associated_type(ecx,
1292 ast::ItemTrait(_, _, _, ref ms) => {
1293 add_to_index(item, rbml_w, index);
1294 rbml_w.start_tag(tag_items_data_item);
1295 encode_def_id(rbml_w, def_id);
1296 encode_family(rbml_w, 'I');
1297 encode_item_variances(rbml_w, ecx, item.id);
1298 let trait_def = tcx.lookup_trait_def(def_id);
1299 let trait_predicates = tcx.lookup_predicates(def_id);
1300 encode_unsafety(rbml_w, trait_def.unsafety);
1301 encode_paren_sugar(rbml_w, trait_def.paren_sugar);
1302 encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id));
1303 encode_associated_type_names(rbml_w, &trait_def.associated_type_names);
1304 encode_generics(rbml_w, ecx, &trait_def.generics, &trait_predicates,
1306 encode_predicates(rbml_w, ecx, &tcx.lookup_super_predicates(def_id),
1307 tag_item_super_predicates);
1308 encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
1309 encode_name(rbml_w, item.ident.name);
1310 encode_attributes(rbml_w, &item.attrs);
1311 encode_visibility(rbml_w, vis);
1312 encode_stability(rbml_w, stab);
1313 for &method_def_id in tcx.trait_item_def_ids(def_id).iter() {
1314 rbml_w.start_tag(tag_item_trait_item);
1315 match method_def_id {
1316 ty::ConstTraitItemId(const_def_id) => {
1317 encode_def_id(rbml_w, const_def_id);
1318 encode_item_sort(rbml_w, 'C');
1320 ty::MethodTraitItemId(method_def_id) => {
1321 encode_def_id(rbml_w, method_def_id);
1322 encode_item_sort(rbml_w, 'r');
1324 ty::TypeTraitItemId(type_def_id) => {
1325 encode_def_id(rbml_w, type_def_id);
1326 encode_item_sort(rbml_w, 't');
1331 rbml_w.wr_tagged_u64(tag_mod_child,
1332 def_to_u64(method_def_id.def_id()));
1334 encode_path(rbml_w, path.clone());
1336 // Encode the implementations of this trait.
1337 encode_extension_implementations(ecx, rbml_w, def_id);
1339 // Encode inherent implementations for this trait.
1340 encode_inherent_implementations(ecx, rbml_w, def_id);
1344 // Now output the trait item info for each trait item.
1345 let r = tcx.trait_item_def_ids(def_id);
1346 for (i, &item_def_id) in r.iter().enumerate() {
1347 assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE);
1349 index.push(IndexEntry {
1350 node: item_def_id.def_id().node,
1351 pos: rbml_w.mark_stable_position(),
1354 rbml_w.start_tag(tag_items_data_item);
1356 encode_parent_item(rbml_w, def_id);
1358 let stab = stability::lookup(tcx, item_def_id.def_id());
1359 encode_stability(rbml_w, stab);
1361 let trait_item_type =
1362 tcx.impl_or_trait_item(item_def_id.def_id());
1363 let is_nonstatic_method;
1364 match trait_item_type {
1365 ty::ConstTraitItem(associated_const) => {
1366 encode_name(rbml_w, associated_const.name);
1367 encode_def_id(rbml_w, associated_const.def_id);
1368 encode_visibility(rbml_w, associated_const.vis);
1370 encode_provided_source(rbml_w, associated_const.default);
1372 let elem = ast_map::PathName(associated_const.name);
1374 path.clone().chain(Some(elem)));
1376 encode_item_sort(rbml_w, 'C');
1377 encode_family(rbml_w, 'C');
1379 encode_bounds_and_type_for_item(rbml_w, ecx,
1380 associated_const.def_id.local_id());
1382 is_nonstatic_method = false;
1384 ty::MethodTraitItem(method_ty) => {
1385 let method_def_id = item_def_id.def_id();
1387 encode_method_ty_fields(ecx, rbml_w, &*method_ty);
1389 let elem = ast_map::PathName(method_ty.name);
1391 path.clone().chain(Some(elem)));
1393 match method_ty.explicit_self {
1394 ty::StaticExplicitSelfCategory => {
1395 encode_family(rbml_w,
1396 STATIC_METHOD_FAMILY);
1399 encode_family(rbml_w,
1403 encode_bounds_and_type_for_item(rbml_w, ecx, method_def_id.local_id());
1405 is_nonstatic_method = method_ty.explicit_self !=
1406 ty::StaticExplicitSelfCategory;
1408 ty::TypeTraitItem(associated_type) => {
1409 encode_name(rbml_w, associated_type.name);
1410 encode_def_id(rbml_w, associated_type.def_id);
1412 let elem = ast_map::PathName(associated_type.name);
1414 path.clone().chain(Some(elem)));
1416 encode_item_sort(rbml_w, 't');
1417 encode_family(rbml_w, 'y');
1419 if let Some(ty) = associated_type.ty {
1420 encode_type(ecx, rbml_w, ty);
1423 is_nonstatic_method = false;
1427 encode_parent_sort(rbml_w, 't');
1429 let trait_item = &*ms[i];
1430 encode_attributes(rbml_w, &trait_item.attrs);
1431 match trait_item.node {
1432 ast::ConstTraitItem(_, _) => {
1433 encode_inlined_item(ecx, rbml_w,
1434 InlinedItemRef::TraitItem(def_id, trait_item));
1436 ast::MethodTraitItem(ref sig, ref body) => {
1437 // If this is a static method, we've already
1439 if is_nonstatic_method {
1440 // FIXME: I feel like there is something funny
1442 encode_bounds_and_type_for_item(rbml_w, ecx,
1443 item_def_id.def_id().local_id());
1447 encode_item_sort(rbml_w, 'p');
1448 encode_inlined_item(ecx, rbml_w,
1449 InlinedItemRef::TraitItem(def_id, trait_item));
1451 encode_item_sort(rbml_w, 'r');
1453 encode_method_argument_names(rbml_w, &sig.decl);
1456 ast::TypeTraitItem(..) => {}
1462 ast::ItemExternCrate(_) | ast::ItemUse(_) => {
1463 // these are encoded separately
1468 fn encode_info_for_foreign_item(ecx: &EncodeContext,
1469 rbml_w: &mut Encoder,
1470 nitem: &ast::ForeignItem,
1471 index: &mut Vec<IndexEntry>,
1474 index.push(IndexEntry {
1476 pos: rbml_w.mark_stable_position(),
1479 rbml_w.start_tag(tag_items_data_item);
1480 encode_def_id(rbml_w, DefId::local(nitem.id));
1481 encode_visibility(rbml_w, nitem.vis);
1483 ast::ForeignItemFn(ref fndecl, _) => {
1484 encode_family(rbml_w, FN_FAMILY);
1485 encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id);
1486 encode_name(rbml_w, nitem.ident.name);
1487 if abi == abi::RustIntrinsic || abi == abi::PlatformIntrinsic {
1488 encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(nitem));
1490 encode_attributes(rbml_w, &*nitem.attrs);
1491 let stab = stability::lookup(ecx.tcx, DefId::local(nitem.id));
1492 encode_stability(rbml_w, stab);
1493 encode_symbol(ecx, rbml_w, nitem.id);
1494 encode_method_argument_names(rbml_w, &*fndecl);
1496 ast::ForeignItemStatic(_, mutbl) => {
1498 encode_family(rbml_w, 'b');
1500 encode_family(rbml_w, 'c');
1502 encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id);
1503 encode_attributes(rbml_w, &*nitem.attrs);
1504 let stab = stability::lookup(ecx.tcx, DefId::local(nitem.id));
1505 encode_stability(rbml_w, stab);
1506 encode_symbol(ecx, rbml_w, nitem.id);
1507 encode_name(rbml_w, nitem.ident.name);
1510 encode_path(rbml_w, path);
1514 fn my_visit_expr(_e: &ast::Expr) { }
1516 fn my_visit_item(i: &ast::Item,
1517 rbml_w: &mut Encoder,
1518 ecx: &EncodeContext,
1519 index: &mut Vec<IndexEntry>) {
1520 ecx.tcx.map.with_path(i.id, |path| {
1521 encode_info_for_item(ecx, rbml_w, i, index, path, i.vis);
1525 fn my_visit_foreign_item(ni: &ast::ForeignItem,
1526 rbml_w: &mut Encoder,
1527 ecx: &EncodeContext,
1528 index: &mut Vec<IndexEntry>) {
1529 debug!("writing foreign item {}::{}",
1530 ecx.tcx.map.path_to_string(ni.id),
1533 let abi = ecx.tcx.map.get_foreign_abi(ni.id);
1534 ecx.tcx.map.with_path(ni.id, |path| {
1535 encode_info_for_foreign_item(ecx, rbml_w,
1541 struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
1542 rbml_w_for_visit_item: &'a mut Encoder<'b>,
1543 ecx: &'a EncodeContext<'c,'tcx>,
1544 index: &'a mut Vec<IndexEntry>,
1547 impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for EncodeVisitor<'a, 'b, 'c, 'tcx> {
1548 fn visit_expr(&mut self, ex: &ast::Expr) {
1549 visit::walk_expr(self, ex);
1552 fn visit_item(&mut self, i: &ast::Item) {
1553 visit::walk_item(self, i);
1555 self.rbml_w_for_visit_item,
1559 fn visit_foreign_item(&mut self, ni: &ast::ForeignItem) {
1560 visit::walk_foreign_item(self, ni);
1561 my_visit_foreign_item(ni,
1562 self.rbml_w_for_visit_item,
1568 fn encode_info_for_items(ecx: &EncodeContext,
1569 rbml_w: &mut Encoder,
1571 -> Vec<IndexEntry> {
1572 let mut index = Vec::new();
1573 rbml_w.start_tag(tag_items_data);
1574 index.push(IndexEntry {
1575 node: CRATE_NODE_ID,
1576 pos: rbml_w.mark_stable_position(),
1578 encode_info_for_mod(ecx,
1583 [].iter().cloned().chain(LinkedPath::empty()),
1584 syntax::parse::token::special_idents::invalid.name,
1587 visit::walk_crate(&mut EncodeVisitor {
1590 rbml_w_for_visit_item: &mut *rbml_w,
1600 fn encode_index(rbml_w: &mut Encoder, index: Vec<IndexEntry>)
1602 rbml_w.start_tag(tag_index);
1603 index::write_index(index, rbml_w.writer);
1607 fn encode_meta_item(rbml_w: &mut Encoder, mi: &ast::MetaItem) {
1609 ast::MetaWord(ref name) => {
1610 rbml_w.start_tag(tag_meta_item_word);
1611 rbml_w.wr_tagged_str(tag_meta_item_name, name);
1614 ast::MetaNameValue(ref name, ref value) => {
1616 ast::LitStr(ref value, _) => {
1617 rbml_w.start_tag(tag_meta_item_name_value);
1618 rbml_w.wr_tagged_str(tag_meta_item_name, name);
1619 rbml_w.wr_tagged_str(tag_meta_item_value, value);
1622 _ => {/* FIXME (#623): encode other variants */ }
1625 ast::MetaList(ref name, ref items) => {
1626 rbml_w.start_tag(tag_meta_item_list);
1627 rbml_w.wr_tagged_str(tag_meta_item_name, name);
1628 for inner_item in items {
1629 encode_meta_item(rbml_w, &**inner_item);
1636 fn encode_attributes(rbml_w: &mut Encoder, attrs: &[ast::Attribute]) {
1637 rbml_w.start_tag(tag_attributes);
1639 rbml_w.start_tag(tag_attribute);
1640 rbml_w.wr_tagged_u8(tag_attribute_is_sugared_doc, attr.node.is_sugared_doc as u8);
1641 encode_meta_item(rbml_w, &*attr.node.value);
1647 fn encode_unsafety(rbml_w: &mut Encoder, unsafety: ast::Unsafety) {
1648 let byte: u8 = match unsafety {
1649 ast::Unsafety::Normal => 0,
1650 ast::Unsafety::Unsafe => 1,
1652 rbml_w.wr_tagged_u8(tag_unsafety, byte);
1655 fn encode_paren_sugar(rbml_w: &mut Encoder, paren_sugar: bool) {
1656 let byte: u8 = if paren_sugar {1} else {0};
1657 rbml_w.wr_tagged_u8(tag_paren_sugar, byte);
1660 fn encode_defaulted(rbml_w: &mut Encoder, is_defaulted: bool) {
1661 let byte: u8 = if is_defaulted {1} else {0};
1662 rbml_w.wr_tagged_u8(tag_defaulted_trait, byte);
1665 fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[Name]) {
1666 rbml_w.start_tag(tag_associated_type_names);
1667 for &name in names {
1668 rbml_w.wr_tagged_str(tag_associated_type_name, &name.as_str());
1673 fn encode_polarity(rbml_w: &mut Encoder, polarity: ast::ImplPolarity) {
1674 let byte: u8 = match polarity {
1675 ast::ImplPolarity::Positive => 0,
1676 ast::ImplPolarity::Negative => 1,
1678 rbml_w.wr_tagged_u8(tag_polarity, byte);
1681 fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
1682 fn get_ordered_deps(cstore: &cstore::CStore)
1683 -> Vec<(CrateNum, Rc<cstore::crate_metadata>)> {
1684 // Pull the cnums and name,vers,hash out of cstore
1685 let mut deps = Vec::new();
1686 cstore.iter_crate_data(|cnum, val| {
1687 deps.push((cnum, val.clone()));
1691 deps.sort_by(|kv1, kv2| kv1.0.cmp(&kv2.0));
1693 // Sanity-check the crate numbers
1694 let mut expected_cnum = 1;
1695 for &(n, _) in &deps {
1696 assert_eq!(n, expected_cnum);
1703 // We're just going to write a list of crate 'name-hash-version's, with
1704 // the assumption that they are numbered 1 to n.
1705 // FIXME (#2166): This is not nearly enough to support correct versioning
1706 // but is enough to get transitive crate dependencies working.
1707 rbml_w.start_tag(tag_crate_deps);
1708 for (_cnum, dep) in get_ordered_deps(cstore) {
1709 encode_crate_dep(rbml_w, &dep);
1714 fn encode_lang_items(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1715 rbml_w.start_tag(tag_lang_items);
1717 for (i, &def_id) in ecx.tcx.lang_items.items() {
1718 if let Some(id) = def_id {
1720 rbml_w.start_tag(tag_lang_items_item);
1721 rbml_w.wr_tagged_u32(tag_lang_items_item_id, i as u32);
1722 rbml_w.wr_tagged_u32(tag_lang_items_item_node_id, id.node as u32);
1728 for i in &ecx.tcx.lang_items.missing {
1729 rbml_w.wr_tagged_u32(tag_lang_items_missing, *i as u32);
1732 rbml_w.end_tag(); // tag_lang_items
1735 fn encode_native_libraries(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1736 rbml_w.start_tag(tag_native_libraries);
1738 for &(ref lib, kind) in ecx.tcx.sess.cstore.get_used_libraries()
1741 cstore::NativeStatic => {} // these libraries are not propagated
1742 cstore::NativeFramework | cstore::NativeUnknown => {
1743 rbml_w.start_tag(tag_native_libraries_lib);
1744 rbml_w.wr_tagged_u32(tag_native_libraries_kind, kind as u32);
1745 rbml_w.wr_tagged_str(tag_native_libraries_name, lib);
1754 fn encode_plugin_registrar_fn(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1755 match ecx.tcx.sess.plugin_registrar_fn.get() {
1756 Some(id) => { rbml_w.wr_tagged_u32(tag_plugin_registrar_fn, id); }
1761 fn encode_codemap(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1762 rbml_w.start_tag(tag_codemap);
1763 let codemap = ecx.tcx.sess.codemap();
1765 for filemap in &codemap.files.borrow()[..] {
1767 if filemap.lines.borrow().is_empty() || filemap.is_imported() {
1768 // No need to export empty filemaps, as they can't contain spans
1769 // that need translation.
1770 // Also no need to re-export imported filemaps, as any downstream
1771 // crate will import them from their original source.
1775 rbml_w.start_tag(tag_codemap_filemap);
1776 filemap.encode(rbml_w);
1783 /// Serialize the text of the exported macros
1784 fn encode_macro_defs(rbml_w: &mut Encoder,
1785 krate: &ast::Crate) {
1786 rbml_w.start_tag(tag_macro_defs);
1787 for def in &krate.exported_macros {
1788 rbml_w.start_tag(tag_macro_def);
1790 encode_name(rbml_w, def.ident.name);
1791 encode_attributes(rbml_w, &def.attrs);
1793 rbml_w.wr_tagged_str(tag_macro_def_body,
1794 &::syntax::print::pprust::tts_to_string(&def.body));
1801 fn encode_struct_field_attrs(rbml_w: &mut Encoder, krate: &ast::Crate) {
1802 struct StructFieldVisitor<'a, 'b:'a> {
1803 rbml_w: &'a mut Encoder<'b>,
1806 impl<'a, 'b, 'v> Visitor<'v> for StructFieldVisitor<'a, 'b> {
1807 fn visit_struct_field(&mut self, field: &ast::StructField) {
1808 self.rbml_w.start_tag(tag_struct_field);
1809 self.rbml_w.wr_tagged_u32(tag_struct_field_id, field.node.id);
1810 encode_attributes(self.rbml_w, &field.node.attrs);
1811 self.rbml_w.end_tag();
1815 rbml_w.start_tag(tag_struct_fields);
1816 visit::walk_crate(&mut StructFieldVisitor {
1824 struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
1825 ecx: &'a EncodeContext<'b, 'tcx>,
1826 rbml_w: &'a mut Encoder<'c>,
1829 impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
1830 fn visit_item(&mut self, item: &ast::Item) {
1831 if let ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
1832 let def_id = self.ecx.tcx.def_map.borrow().get(&trait_ref.ref_id).unwrap().def_id();
1834 // Load eagerly if this is an implementation of the Drop trait
1835 // or if the trait is not defined in this crate.
1836 if Some(def_id) == self.ecx.tcx.lang_items.drop_trait() ||
1837 def_id.krate != LOCAL_CRATE {
1838 self.rbml_w.start_tag(tag_impls_impl);
1839 encode_def_id(self.rbml_w, DefId::local(item.id));
1840 self.rbml_w.wr_tagged_u64(tag_impls_impl_trait_def_id, def_to_u64(def_id));
1841 self.rbml_w.end_tag();
1844 visit::walk_item(self, item);
1848 /// Encodes implementations that are eagerly loaded.
1850 /// None of this is necessary in theory; we can load all implementations
1851 /// lazily. However, in two cases the optimizations to lazily load
1852 /// implementations are not yet implemented. These two cases, which require us
1853 /// to load implementations eagerly, are:
1855 /// * Destructors (implementations of the Drop trait).
1857 /// * Implementations of traits not defined in this crate.
1858 fn encode_impls<'a>(ecx: &'a EncodeContext,
1860 rbml_w: &'a mut Encoder) {
1861 rbml_w.start_tag(tag_impls);
1864 let mut visitor = ImplVisitor {
1868 visit::walk_crate(&mut visitor, krate);
1874 fn encode_misc_info(ecx: &EncodeContext,
1876 rbml_w: &mut Encoder) {
1877 rbml_w.start_tag(tag_misc_info);
1878 rbml_w.start_tag(tag_misc_info_crate_items);
1879 for item in &krate.module.items {
1880 rbml_w.wr_tagged_u64(tag_mod_child,
1881 def_to_u64(DefId::local(item.id)));
1883 each_auxiliary_node_id(&**item, |auxiliary_node_id| {
1884 rbml_w.wr_tagged_u64(tag_mod_child,
1885 def_to_u64(DefId::local(auxiliary_node_id)));
1890 // Encode reexports for the root module.
1891 encode_reexports(ecx, rbml_w, 0, [].iter().cloned().chain(LinkedPath::empty()));
1897 // Encodes all reachable symbols in this crate into the metadata.
1899 // This pass is seeded off the reachability list calculated in the
1900 // middle::reachable module but filters out items that either don't have a
1901 // symbol associated with them (they weren't translated) or if they're an FFI
1902 // definition (as that's not defined in this crate).
1903 fn encode_reachable(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1904 rbml_w.start_tag(tag_reachable_ids);
1905 for id in ecx.reachable {
1906 rbml_w.wr_tagged_u32(tag_reachable_id, *id);
1911 fn encode_crate_dep(rbml_w: &mut Encoder,
1912 dep: &cstore::crate_metadata) {
1913 rbml_w.start_tag(tag_crate_dep);
1914 rbml_w.wr_tagged_str(tag_crate_dep_crate_name, &dep.name());
1915 let hash = decoder::get_crate_hash(dep.data());
1916 rbml_w.wr_tagged_str(tag_crate_dep_hash, hash.as_str());
1917 rbml_w.wr_tagged_u8(tag_crate_dep_explicitly_linked,
1918 dep.explicitly_linked.get() as u8);
1922 fn encode_hash(rbml_w: &mut Encoder, hash: &Svh) {
1923 rbml_w.wr_tagged_str(tag_crate_hash, hash.as_str());
1926 fn encode_crate_name(rbml_w: &mut Encoder, crate_name: &str) {
1927 rbml_w.wr_tagged_str(tag_crate_crate_name, crate_name);
1930 fn encode_crate_triple(rbml_w: &mut Encoder, triple: &str) {
1931 rbml_w.wr_tagged_str(tag_crate_triple, triple);
1934 fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) {
1935 let tag = tag_dylib_dependency_formats;
1936 match ecx.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) {
1938 let s = arr.iter().enumerate().filter_map(|(i, slot)| {
1939 let kind = match *slot {
1940 Linkage::NotLinked |
1941 Linkage::IncludedFromDylib => return None,
1942 Linkage::Dynamic => "d",
1943 Linkage::Static => "s",
1945 Some(format!("{}:{}", i + 1, kind))
1946 }).collect::<Vec<String>>();
1947 rbml_w.wr_tagged_str(tag, &s.join(","));
1950 rbml_w.wr_tagged_str(tag, "");
1955 // NB: Increment this as you change the metadata encoding version.
1956 #[allow(non_upper_case_globals)]
1957 pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 2 ];
1959 pub fn encode_metadata(parms: EncodeParams, krate: &ast::Crate) -> Vec<u8> {
1960 let mut wr = Cursor::new(Vec::new());
1961 encode_metadata_inner(&mut wr, parms, krate);
1963 // RBML compacts the encoded bytes whenever appropriate,
1964 // so there are some garbages left after the end of the data.
1965 let metalen = wr.seek(SeekFrom::Current(0)).unwrap() as usize;
1966 let mut v = wr.into_inner();
1967 v.truncate(metalen);
1968 assert_eq!(v.len(), metalen);
1970 // And here we run into yet another obscure archive bug: in which metadata
1971 // loaded from archives may have trailing garbage bytes. Awhile back one of
1972 // our tests was failing sporadically on the OSX 64-bit builders (both nopt
1973 // and opt) by having rbml generate an out-of-bounds panic when looking at
1976 // Upon investigation it turned out that the metadata file inside of an rlib
1977 // (and ar archive) was being corrupted. Some compilations would generate a
1978 // metadata file which would end in a few extra bytes, while other
1979 // compilations would not have these extra bytes appended to the end. These
1980 // extra bytes were interpreted by rbml as an extra tag, so they ended up
1981 // being interpreted causing the out-of-bounds.
1983 // The root cause of why these extra bytes were appearing was never
1984 // discovered, and in the meantime the solution we're employing is to insert
1985 // the length of the metadata to the start of the metadata. Later on this
1986 // will allow us to slice the metadata to the precise length that we just
1987 // generated regardless of trailing bytes that end up in it.
1988 let len = v.len() as u32;
1989 v.insert(0, (len >> 0) as u8);
1990 v.insert(0, (len >> 8) as u8);
1991 v.insert(0, (len >> 16) as u8);
1992 v.insert(0, (len >> 24) as u8);
1996 fn encode_metadata_inner(wr: &mut Cursor<Vec<u8>>,
1997 parms: EncodeParams,
1998 krate: &ast::Crate) {
2002 lang_item_bytes: u64,
2003 native_lib_bytes: u64,
2004 plugin_registrar_fn_bytes: u64,
2006 macro_defs_bytes: u64,
2014 let mut stats = Stats {
2018 native_lib_bytes: 0,
2019 plugin_registrar_fn_bytes: 0,
2021 macro_defs_bytes: 0,
2035 encode_inlined_item,
2040 let ecx = EncodeContext {
2043 reexports: reexports,
2044 item_symbols: item_symbols,
2045 link_meta: link_meta,
2047 encode_inlined_item: RefCell::new(encode_inlined_item),
2048 type_abbrevs: RefCell::new(FnvHashMap()),
2049 reachable: reachable,
2052 let mut rbml_w = Encoder::new(wr);
2054 encode_crate_name(&mut rbml_w, &ecx.link_meta.crate_name);
2055 encode_crate_triple(&mut rbml_w, &tcx.sess.opts.target_triple);
2056 encode_hash(&mut rbml_w, &ecx.link_meta.crate_hash);
2057 encode_dylib_dependency_formats(&mut rbml_w, &ecx);
2059 let mut i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2060 encode_attributes(&mut rbml_w, &krate.attrs);
2061 stats.attr_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2063 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2064 encode_crate_deps(&mut rbml_w, ecx.cstore);
2065 stats.dep_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2067 // Encode the language items.
2068 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2069 encode_lang_items(&ecx, &mut rbml_w);
2070 stats.lang_item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2072 // Encode the native libraries used
2073 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2074 encode_native_libraries(&ecx, &mut rbml_w);
2075 stats.native_lib_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2077 // Encode the plugin registrar function
2078 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2079 encode_plugin_registrar_fn(&ecx, &mut rbml_w);
2080 stats.plugin_registrar_fn_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2083 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2084 encode_codemap(&ecx, &mut rbml_w);
2085 stats.codemap_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2087 // Encode macro definitions
2088 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2089 encode_macro_defs(&mut rbml_w, krate);
2090 stats.macro_defs_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2092 // Encode the def IDs of impls, for coherence checking.
2093 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2094 encode_impls(&ecx, krate, &mut rbml_w);
2095 stats.impl_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2097 // Encode miscellaneous info.
2098 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2099 encode_misc_info(&ecx, krate, &mut rbml_w);
2100 encode_reachable(&ecx, &mut rbml_w);
2101 stats.misc_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2103 // Encode and index the items.
2104 rbml_w.start_tag(tag_items);
2105 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2106 let items_index = encode_info_for_items(&ecx, &mut rbml_w, krate);
2107 stats.item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2110 i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2111 encode_index(&mut rbml_w, items_index);
2112 stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
2114 encode_struct_field_attrs(&mut rbml_w, krate);
2116 stats.total_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
2118 if tcx.sess.meta_stats() {
2119 for e in rbml_w.writer.get_ref() {
2121 stats.zero_bytes += 1;
2125 println!("metadata stats:");
2126 println!(" attribute bytes: {}", stats.attr_bytes);
2127 println!(" dep bytes: {}", stats.dep_bytes);
2128 println!(" lang item bytes: {}", stats.lang_item_bytes);
2129 println!(" native bytes: {}", stats.native_lib_bytes);
2130 println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
2131 println!(" codemap bytes: {}", stats.codemap_bytes);
2132 println!(" macro def bytes: {}", stats.macro_defs_bytes);
2133 println!(" impl bytes: {}", stats.impl_bytes);
2134 println!(" misc bytes: {}", stats.misc_bytes);
2135 println!(" item bytes: {}", stats.item_bytes);
2136 println!(" index bytes: {}", stats.index_bytes);
2137 println!(" zero bytes: {}", stats.zero_bytes);
2138 println!(" total bytes: {}", stats.total_bytes);
2142 // Get the encoded string for a type
2143 pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String {
2144 let mut wr = Cursor::new(Vec::new());
2145 tyencode::enc_ty(&mut Encoder::new(&mut wr), &tyencode::ctxt {
2146 diag: tcx.sess.diagnostic(),
2149 abbrevs: &RefCell::new(FnvHashMap())
2151 String::from_utf8(wr.into_inner()).unwrap()