]> git.lizzy.rs Git - rust.git/blob - src/librustc/metadata/encoder.rs
Ignore tests broken by failing on ICE
[rust.git] / src / librustc / metadata / encoder.rs
1 // Copyright 2012-2014 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.
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
11 // Metadata encoding
12
13 #![allow(unused_must_use)] // everything is just a MemWriter, can't fail
14 #![allow(non_camel_case_types)]
15
16 use back::svh::Svh;
17 use metadata::common::*;
18 use metadata::cstore;
19 use metadata::decoder;
20 use metadata::tyencode;
21 use middle::ty::{node_id_to_type, lookup_item_type};
22 use middle::astencode;
23 use middle::ty;
24 use middle::typeck;
25 use middle;
26 use util::nodemap::{NodeMap, NodeSet};
27
28 use serialize::Encodable;
29 use std::cast;
30 use std::cell::RefCell;
31 use std::hash;
32 use std::hash::Hash;
33 use std::io::MemWriter;
34 use std::str;
35 use collections::HashMap;
36 use syntax::abi;
37 use syntax::ast::*;
38 use syntax::ast;
39 use syntax::ast_map::{PathElem, PathElems};
40 use syntax::ast_map;
41 use syntax::ast_util::*;
42 use syntax::ast_util;
43 use syntax::attr::AttrMetaMethods;
44 use syntax::attr;
45 use syntax::crateid::CrateId;
46 use syntax::diagnostic::SpanHandler;
47 use syntax::parse::token::InternedString;
48 use syntax::parse::token::special_idents;
49 use syntax::parse::token;
50 use syntax::visit::Visitor;
51 use syntax::visit;
52 use syntax;
53 use writer = serialize::ebml::writer;
54
55 /// A borrowed version of ast::InlinedItem.
56 pub enum InlinedItemRef<'a> {
57     IIItemRef(&'a ast::Item),
58     IIMethodRef(ast::DefId, bool, &'a ast::Method),
59     IIForeignRef(&'a ast::ForeignItem)
60 }
61
62 pub type Encoder<'a> = writer::Encoder<'a, MemWriter>;
63
64 pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
65                                   ebml_w: &mut Encoder,
66                                   ii: InlinedItemRef|: 'a;
67
68 pub struct EncodeParams<'a> {
69     pub diag: &'a SpanHandler,
70     pub tcx: &'a ty::ctxt,
71     pub reexports2: &'a middle::resolve::ExportMap2,
72     pub item_symbols: &'a RefCell<NodeMap<~str>>,
73     pub non_inlineable_statics: &'a RefCell<NodeSet>,
74     pub link_meta: &'a LinkMeta,
75     pub cstore: &'a cstore::CStore,
76     pub encode_inlined_item: EncodeInlinedItem<'a>,
77 }
78
79 pub struct EncodeContext<'a> {
80     pub diag: &'a SpanHandler,
81     pub tcx: &'a ty::ctxt,
82     pub reexports2: &'a middle::resolve::ExportMap2,
83     pub item_symbols: &'a RefCell<NodeMap<~str>>,
84     pub non_inlineable_statics: &'a RefCell<NodeSet>,
85     pub link_meta: &'a LinkMeta,
86     pub cstore: &'a cstore::CStore,
87     pub encode_inlined_item: RefCell<EncodeInlinedItem<'a>>,
88     pub type_abbrevs: tyencode::abbrev_map,
89 }
90
91 fn encode_name(ebml_w: &mut Encoder, name: Name) {
92     ebml_w.wr_tagged_str(tag_paths_data_name, token::get_name(name).get());
93 }
94
95 fn encode_impl_type_basename(ebml_w: &mut Encoder, name: Ident) {
96     ebml_w.wr_tagged_str(tag_item_impl_type_basename, token::get_ident(name).get());
97 }
98
99 pub fn encode_def_id(ebml_w: &mut Encoder, id: DefId) {
100     ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
101 }
102
103 #[deriving(Clone)]
104 struct entry<T> {
105     val: T,
106     pos: u64
107 }
108
109 fn encode_trait_ref(ebml_w: &mut Encoder,
110                     ecx: &EncodeContext,
111                     trait_ref: &ty::TraitRef,
112                     tag: uint) {
113     let ty_str_ctxt = &tyencode::ctxt {
114         diag: ecx.diag,
115         ds: def_to_str,
116         tcx: ecx.tcx,
117         abbrevs: &ecx.type_abbrevs
118     };
119
120     ebml_w.start_tag(tag);
121     tyencode::enc_trait_ref(ebml_w.writer, ty_str_ctxt, trait_ref);
122     ebml_w.end_tag();
123 }
124
125 fn encode_impl_vtables(ebml_w: &mut Encoder,
126                        ecx: &EncodeContext,
127                        vtables: &typeck::impl_res) {
128     ebml_w.start_tag(tag_item_impl_vtables);
129     astencode::encode_vtable_res(ecx, ebml_w, &vtables.trait_vtables);
130     astencode::encode_vtable_param_res(ecx, ebml_w, &vtables.self_vtables);
131     ebml_w.end_tag();
132 }
133
134 // Item info table encoding
135 fn encode_family(ebml_w: &mut Encoder, c: char) {
136     ebml_w.start_tag(tag_items_data_item_family);
137     ebml_w.writer.write(&[c as u8]);
138     ebml_w.end_tag();
139 }
140
141 pub fn def_to_str(did: DefId) -> ~str {
142     format!("{}:{}", did.krate, did.node)
143 }
144
145 fn encode_ty_type_param_defs(ebml_w: &mut Encoder,
146                              ecx: &EncodeContext,
147                              params: &[ty::TypeParameterDef],
148                              tag: uint) {
149     let ty_str_ctxt = &tyencode::ctxt {
150         diag: ecx.diag,
151         ds: def_to_str,
152         tcx: ecx.tcx,
153         abbrevs: &ecx.type_abbrevs
154     };
155     for param in params.iter() {
156         ebml_w.start_tag(tag);
157         tyencode::enc_type_param_def(ebml_w.writer, ty_str_ctxt, param);
158         ebml_w.end_tag();
159     }
160 }
161
162 fn encode_region_param_defs(ebml_w: &mut Encoder,
163                             params: &[ty::RegionParameterDef]) {
164     for param in params.iter() {
165         ebml_w.start_tag(tag_region_param_def);
166
167         ebml_w.start_tag(tag_region_param_def_ident);
168         encode_name(ebml_w, param.name);
169         ebml_w.end_tag();
170
171         ebml_w.wr_tagged_str(tag_region_param_def_def_id,
172                              def_to_str(param.def_id));
173
174         ebml_w.end_tag();
175     }
176 }
177
178 fn encode_item_variances(ebml_w: &mut Encoder,
179                          ecx: &EncodeContext,
180                          id: ast::NodeId) {
181     let v = ty::item_variances(ecx.tcx, ast_util::local_def(id));
182     ebml_w.start_tag(tag_item_variances);
183     v.encode(ebml_w);
184     ebml_w.end_tag();
185 }
186
187 fn encode_bounds_and_type(ebml_w: &mut Encoder,
188                           ecx: &EncodeContext,
189                           tpt: &ty::ty_param_bounds_and_ty) {
190     encode_ty_type_param_defs(ebml_w, ecx, tpt.generics.type_param_defs(),
191                               tag_items_data_item_ty_param_bounds);
192     encode_region_param_defs(ebml_w, tpt.generics.region_param_defs());
193     encode_type(ecx, ebml_w, tpt.ty);
194 }
195
196 fn encode_variant_id(ebml_w: &mut Encoder, vid: DefId) {
197     ebml_w.start_tag(tag_items_data_item_variant);
198     let s = def_to_str(vid);
199     ebml_w.writer.write(s.as_bytes());
200     ebml_w.end_tag();
201 }
202
203 pub fn write_type(ecx: &EncodeContext,
204                   ebml_w: &mut Encoder,
205                   typ: ty::t) {
206     let ty_str_ctxt = &tyencode::ctxt {
207         diag: ecx.diag,
208         ds: def_to_str,
209         tcx: ecx.tcx,
210         abbrevs: &ecx.type_abbrevs
211     };
212     tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
213 }
214
215 fn encode_type(ecx: &EncodeContext,
216                ebml_w: &mut Encoder,
217                typ: ty::t) {
218     ebml_w.start_tag(tag_items_data_item_type);
219     write_type(ecx, ebml_w, typ);
220     ebml_w.end_tag();
221 }
222
223 fn encode_method_fty(ecx: &EncodeContext,
224                      ebml_w: &mut Encoder,
225                      typ: &ty::BareFnTy) {
226     ebml_w.start_tag(tag_item_method_fty);
227
228     let ty_str_ctxt = &tyencode::ctxt {
229         diag: ecx.diag,
230         ds: def_to_str,
231         tcx: ecx.tcx,
232         abbrevs: &ecx.type_abbrevs
233     };
234     tyencode::enc_bare_fn_ty(ebml_w.writer, ty_str_ctxt, typ);
235
236     ebml_w.end_tag();
237 }
238
239 fn encode_symbol(ecx: &EncodeContext,
240                  ebml_w: &mut Encoder,
241                  id: NodeId) {
242     ebml_w.start_tag(tag_items_data_item_symbol);
243     match ecx.item_symbols.borrow().find(&id) {
244         Some(x) => {
245             debug!("encode_symbol(id={:?}, str={})", id, *x);
246             ebml_w.writer.write(x.as_bytes());
247         }
248         None => {
249             ecx.diag.handler().bug(
250                 format!("encode_symbol: id not found {}", id));
251         }
252     }
253     ebml_w.end_tag();
254 }
255
256 fn encode_disr_val(_: &EncodeContext,
257                    ebml_w: &mut Encoder,
258                    disr_val: ty::Disr) {
259     ebml_w.start_tag(tag_disr_val);
260     let s = disr_val.to_str();
261     ebml_w.writer.write(s.as_bytes());
262     ebml_w.end_tag();
263 }
264
265 fn encode_parent_item(ebml_w: &mut Encoder, id: DefId) {
266     ebml_w.start_tag(tag_items_data_parent_item);
267     let s = def_to_str(id);
268     ebml_w.writer.write(s.as_bytes());
269     ebml_w.end_tag();
270 }
271
272 fn encode_struct_fields(ebml_w: &mut Encoder,
273                         fields: &[ty::field_ty],
274                         origin: DefId) {
275     for f in fields.iter() {
276         if f.name == special_idents::unnamed_field.name {
277             ebml_w.start_tag(tag_item_unnamed_field);
278         } else {
279             ebml_w.start_tag(tag_item_field);
280             encode_name(ebml_w, f.name);
281         }
282         encode_struct_field_family(ebml_w, f.vis);
283         encode_def_id(ebml_w, f.id);
284         ebml_w.start_tag(tag_item_field_origin);
285         let s = def_to_str(origin);
286         ebml_w.writer.write(s.as_bytes());
287         ebml_w.end_tag();
288         ebml_w.end_tag();
289     }
290 }
291
292 fn encode_enum_variant_info(ecx: &EncodeContext,
293                             ebml_w: &mut Encoder,
294                             id: NodeId,
295                             variants: &[P<Variant>],
296                             index: &mut Vec<entry<i64>>,
297                             generics: &ast::Generics) {
298     debug!("encode_enum_variant_info(id={:?})", id);
299
300     let mut disr_val = 0;
301     let mut i = 0;
302     let vi = ty::enum_variants(ecx.tcx,
303                                ast::DefId { krate: LOCAL_CRATE, node: id });
304     for variant in variants.iter() {
305         let def_id = local_def(variant.node.id);
306         index.push(entry {
307             val: variant.node.id as i64,
308             pos: ebml_w.writer.tell().unwrap(),
309         });
310         ebml_w.start_tag(tag_items_data_item);
311         encode_def_id(ebml_w, def_id);
312         match variant.node.kind {
313             ast::TupleVariantKind(_) => encode_family(ebml_w, 'v'),
314             ast::StructVariantKind(_) => encode_family(ebml_w, 'V')
315         }
316         encode_name(ebml_w, variant.node.name.name);
317         encode_parent_item(ebml_w, local_def(id));
318         encode_visibility(ebml_w, variant.node.vis);
319         encode_attributes(ebml_w, variant.node.attrs.as_slice());
320         match variant.node.kind {
321             ast::TupleVariantKind(ref args)
322                     if args.len() > 0 && generics.ty_params.len() == 0 => {
323                 encode_symbol(ecx, ebml_w, variant.node.id);
324             }
325             ast::TupleVariantKind(_) => {},
326             ast::StructVariantKind(_) => {
327                 let fields = ty::lookup_struct_fields(ecx.tcx, def_id);
328                 let idx = encode_info_for_struct(ecx,
329                                                  ebml_w,
330                                                  fields.as_slice(),
331                                                  index);
332                 encode_struct_fields(ebml_w, fields.as_slice(), def_id);
333                 encode_index(ebml_w, idx, write_i64);
334             }
335         }
336         if vi.get(i).disr_val != disr_val {
337             encode_disr_val(ecx, ebml_w, vi.get(i).disr_val);
338             disr_val = vi.get(i).disr_val;
339         }
340         encode_bounds_and_type(ebml_w, ecx,
341                                &lookup_item_type(ecx.tcx, def_id));
342
343         ecx.tcx.map.with_path(variant.node.id, |path| encode_path(ebml_w, path));
344         ebml_w.end_tag();
345         disr_val += 1;
346         i += 1;
347     }
348 }
349
350 fn encode_path<PI: Iterator<PathElem> + Clone>(ebml_w: &mut Encoder,
351                                                mut path: PI) {
352     ebml_w.start_tag(tag_path);
353     ebml_w.wr_tagged_u32(tag_path_len, path.clone().len() as u32);
354     for pe in path {
355         let tag = match pe {
356             ast_map::PathMod(_) => tag_path_elem_mod,
357             ast_map::PathName(_) => tag_path_elem_name
358         };
359         ebml_w.wr_tagged_str(tag, token::get_name(pe.name()).get());
360     }
361     ebml_w.end_tag();
362 }
363
364 fn encode_reexported_static_method(ebml_w: &mut Encoder,
365                                    exp: &middle::resolve::Export2,
366                                    method_def_id: DefId,
367                                    method_ident: Ident) {
368     debug!("(encode reexported static method) {}::{}",
369             exp.name, token::get_ident(method_ident));
370     ebml_w.start_tag(tag_items_data_item_reexport);
371     ebml_w.start_tag(tag_items_data_item_reexport_def_id);
372     ebml_w.wr_str(def_to_str(method_def_id));
373     ebml_w.end_tag();
374     ebml_w.start_tag(tag_items_data_item_reexport_name);
375     ebml_w.wr_str(format!("{}::{}", exp.name, token::get_ident(method_ident)));
376     ebml_w.end_tag();
377     ebml_w.end_tag();
378 }
379
380 fn encode_reexported_static_base_methods(ecx: &EncodeContext,
381                                          ebml_w: &mut Encoder,
382                                          exp: &middle::resolve::Export2)
383                                          -> bool {
384     let impl_methods = ecx.tcx.impl_methods.borrow();
385     match ecx.tcx.inherent_impls.borrow().find(&exp.def_id) {
386         Some(implementations) => {
387             for base_impl_did in implementations.borrow().iter() {
388                 for &method_did in impl_methods.get(base_impl_did).iter() {
389                     let m = ty::method(ecx.tcx, method_did);
390                     if m.explicit_self == ast::SelfStatic {
391                         encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
392                     }
393                 }
394             }
395
396             true
397         }
398         None => { false }
399     }
400 }
401
402 fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
403                                           ebml_w: &mut Encoder,
404                                           exp: &middle::resolve::Export2)
405                                           -> bool {
406     match ecx.tcx.trait_methods_cache.borrow().find(&exp.def_id) {
407         Some(methods) => {
408             for m in methods.iter() {
409                 if m.explicit_self == ast::SelfStatic {
410                     encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
411                 }
412             }
413
414             true
415         }
416         None => { false }
417     }
418 }
419
420 fn encode_reexported_static_methods(ecx: &EncodeContext,
421                                     ebml_w: &mut Encoder,
422                                     mod_path: PathElems,
423                                     exp: &middle::resolve::Export2) {
424     match ecx.tcx.map.find(exp.def_id.node) {
425         Some(ast_map::NodeItem(item)) => {
426             let original_name = token::get_ident(item.ident);
427
428             let path_differs = ecx.tcx.map.with_path(exp.def_id.node, |path| {
429                 let (mut a, mut b) = (path, mod_path.clone());
430                 loop {
431                     match (a.next(), b.next()) {
432                         (None, None) => return true,
433                         (None, _) | (_, None) => return false,
434                         (Some(x), Some(y)) => if x != y { return false },
435                     }
436                 }
437             });
438
439             //
440             // We don't need to reexport static methods on items
441             // declared in the same module as our `pub use ...` since
442             // that's done when we encode the item itself.
443             //
444             // The only exception is when the reexport *changes* the
445             // name e.g. `pub use Foo = self::Bar` -- we have
446             // encoded metadata for static methods relative to Bar,
447             // but not yet for Foo.
448             //
449             if path_differs || original_name.get() != exp.name {
450                 if !encode_reexported_static_base_methods(ecx, ebml_w, exp) {
451                     if encode_reexported_static_trait_methods(ecx, ebml_w, exp) {
452                         debug!("(encode reexported static methods) {} \
453                                  [trait]",
454                                 original_name);
455                     }
456                 }
457                 else {
458                     debug!("(encode reexported static methods) {} [base]",
459                             original_name);
460                 }
461             }
462         }
463         _ => {}
464     }
465 }
466
467 /// Iterates through "auxiliary node IDs", which are node IDs that describe
468 /// top-level items that are sub-items of the given item. Specifically:
469 ///
470 /// * For enums, iterates through the node IDs of the variants.
471 ///
472 /// * For newtype structs, iterates through the node ID of the constructor.
473 fn each_auxiliary_node_id(item: @Item, callback: |NodeId| -> bool) -> bool {
474     let mut continue_ = true;
475     match item.node {
476         ItemEnum(ref enum_def, _) => {
477             for variant in enum_def.variants.iter() {
478                 continue_ = callback(variant.node.id);
479                 if !continue_ {
480                     break
481                 }
482             }
483         }
484         ItemStruct(struct_def, _) => {
485             // If this is a newtype struct, return the constructor.
486             match struct_def.ctor_id {
487                 Some(ctor_id) if struct_def.fields.len() > 0 &&
488                         struct_def.fields.get(0).node.kind.is_unnamed() => {
489                     continue_ = callback(ctor_id);
490                 }
491                 _ => {}
492             }
493         }
494         _ => {}
495     }
496
497     continue_
498 }
499
500 fn encode_reexports(ecx: &EncodeContext,
501                     ebml_w: &mut Encoder,
502                     id: NodeId,
503                     path: PathElems) {
504     debug!("(encoding info for module) encoding reexports for {}", id);
505     match ecx.reexports2.borrow().find(&id) {
506         Some(ref exports) => {
507             debug!("(encoding info for module) found reexports for {}", id);
508             for exp in exports.iter() {
509                 debug!("(encoding info for module) reexport '{}' ({}/{}) for \
510                         {}",
511                        exp.name,
512                        exp.def_id.krate,
513                        exp.def_id.node,
514                        id);
515                 ebml_w.start_tag(tag_items_data_item_reexport);
516                 ebml_w.start_tag(tag_items_data_item_reexport_def_id);
517                 ebml_w.wr_str(def_to_str(exp.def_id));
518                 ebml_w.end_tag();
519                 ebml_w.start_tag(tag_items_data_item_reexport_name);
520                 ebml_w.wr_str(exp.name);
521                 ebml_w.end_tag();
522                 ebml_w.end_tag();
523                 encode_reexported_static_methods(ecx, ebml_w, path.clone(), exp);
524             }
525         }
526         None => {
527             debug!("(encoding info for module) found no reexports for {}",
528                    id);
529         }
530     }
531 }
532
533 fn encode_info_for_mod(ecx: &EncodeContext,
534                        ebml_w: &mut Encoder,
535                        md: &Mod,
536                        id: NodeId,
537                        path: PathElems,
538                        name: Ident,
539                        vis: Visibility) {
540     ebml_w.start_tag(tag_items_data_item);
541     encode_def_id(ebml_w, local_def(id));
542     encode_family(ebml_w, 'm');
543     encode_name(ebml_w, name.name);
544     debug!("(encoding info for module) encoding info for module ID {}", id);
545
546     // Encode info about all the module children.
547     for item in md.items.iter() {
548         ebml_w.start_tag(tag_mod_child);
549         ebml_w.wr_str(def_to_str(local_def(item.id)));
550         ebml_w.end_tag();
551
552         each_auxiliary_node_id(*item, |auxiliary_node_id| {
553             ebml_w.start_tag(tag_mod_child);
554             ebml_w.wr_str(def_to_str(local_def(auxiliary_node_id)));
555             ebml_w.end_tag();
556             true
557         });
558
559         match item.node {
560             ItemImpl(..) => {
561                 let (ident, did) = (item.ident, item.id);
562                 debug!("(encoding info for module) ... encoding impl {} \
563                         ({:?}/{:?})",
564                         token::get_ident(ident),
565                         did, ecx.tcx.map.node_to_str(did));
566
567                 ebml_w.start_tag(tag_mod_impl);
568                 ebml_w.wr_str(def_to_str(local_def(did)));
569                 ebml_w.end_tag();
570             }
571             _ => {}
572         }
573     }
574
575     encode_path(ebml_w, path.clone());
576     encode_visibility(ebml_w, vis);
577
578     // Encode the reexports of this module, if this module is public.
579     if vis == Public {
580         debug!("(encoding info for module) encoding reexports for {}", id);
581         encode_reexports(ecx, ebml_w, id, path);
582     }
583
584     ebml_w.end_tag();
585 }
586
587 fn encode_struct_field_family(ebml_w: &mut Encoder,
588                               visibility: Visibility) {
589     encode_family(ebml_w, match visibility {
590         Public => 'g',
591         Inherited => 'N'
592     });
593 }
594
595 fn encode_visibility(ebml_w: &mut Encoder, visibility: Visibility) {
596     ebml_w.start_tag(tag_items_data_item_visibility);
597     let ch = match visibility {
598         Public => 'y',
599         Inherited => 'i',
600     };
601     ebml_w.wr_str(str::from_char(ch));
602     ebml_w.end_tag();
603 }
604
605 fn encode_explicit_self(ebml_w: &mut Encoder, explicit_self: ast::ExplicitSelf_) {
606     ebml_w.start_tag(tag_item_trait_method_explicit_self);
607
608     // Encode the base self type.
609     match explicit_self {
610         SelfStatic => { ebml_w.writer.write(&[ 's' as u8 ]); }
611         SelfValue  => { ebml_w.writer.write(&[ 'v' as u8 ]); }
612         SelfUniq   => { ebml_w.writer.write(&[ '~' as u8 ]); }
613         SelfRegion(_, m) => {
614             // FIXME(#4846) encode custom lifetime
615             ebml_w.writer.write(&['&' as u8]);
616             encode_mutability(ebml_w, m);
617         }
618     }
619
620     ebml_w.end_tag();
621
622     fn encode_mutability(ebml_w: &mut Encoder,
623                          m: ast::Mutability) {
624         match m {
625             MutImmutable => { ebml_w.writer.write(&[ 'i' as u8 ]); }
626             MutMutable => { ebml_w.writer.write(&[ 'm' as u8 ]); }
627         }
628     }
629 }
630
631 fn encode_method_sort(ebml_w: &mut Encoder, sort: char) {
632     ebml_w.start_tag(tag_item_trait_method_sort);
633     ebml_w.writer.write(&[ sort as u8 ]);
634     ebml_w.end_tag();
635 }
636
637 fn encode_provided_source(ebml_w: &mut Encoder,
638                           source_opt: Option<DefId>) {
639     for source in source_opt.iter() {
640         ebml_w.start_tag(tag_item_method_provided_source);
641         let s = def_to_str(*source);
642         ebml_w.writer.write(s.as_bytes());
643         ebml_w.end_tag();
644     }
645 }
646
647 /* Returns an index of items in this class */
648 fn encode_info_for_struct(ecx: &EncodeContext,
649                           ebml_w: &mut Encoder,
650                           fields: &[ty::field_ty],
651                           global_index: &mut Vec<entry<i64>>)
652                           -> Vec<entry<i64>> {
653     /* Each class has its own index, since different classes
654        may have fields with the same name */
655     let mut index = Vec::new();
656     let tcx = ecx.tcx;
657      /* We encode both private and public fields -- need to include
658         private fields to get the offsets right */
659     for field in fields.iter() {
660         let nm = field.name;
661         let id = field.id.node;
662
663         index.push(entry {val: id as i64, pos: ebml_w.writer.tell().unwrap()});
664         global_index.push(entry {
665             val: id as i64,
666             pos: ebml_w.writer.tell().unwrap(),
667         });
668         ebml_w.start_tag(tag_items_data_item);
669         debug!("encode_info_for_struct: doing {} {}",
670                token::get_name(nm), id);
671         encode_struct_field_family(ebml_w, field.vis);
672         encode_name(ebml_w, nm);
673         encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
674         encode_def_id(ebml_w, local_def(id));
675         ebml_w.end_tag();
676     }
677     index
678 }
679
680 fn encode_info_for_struct_ctor(ecx: &EncodeContext,
681                                ebml_w: &mut Encoder,
682                                name: ast::Ident,
683                                ctor_id: NodeId,
684                                index: &mut Vec<entry<i64>>,
685                                struct_id: NodeId) {
686     index.push(entry {
687         val: ctor_id as i64,
688         pos: ebml_w.writer.tell().unwrap(),
689     });
690
691     ebml_w.start_tag(tag_items_data_item);
692     encode_def_id(ebml_w, local_def(ctor_id));
693     encode_family(ebml_w, 'f');
694     encode_bounds_and_type(ebml_w, ecx,
695                            &lookup_item_type(ecx.tcx, local_def(ctor_id)));
696     encode_name(ebml_w, name.name);
697     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, ctor_id));
698     ecx.tcx.map.with_path(ctor_id, |path| encode_path(ebml_w, path));
699     encode_parent_item(ebml_w, local_def(struct_id));
700
701     if ecx.item_symbols.borrow().contains_key(&ctor_id) {
702         encode_symbol(ecx, ebml_w, ctor_id);
703     }
704
705     // indicate that this is a tuple struct ctor, because downstream users will normally want
706     // the tuple struct definition, but without this there is no way for them to tell that
707     // they actually have a ctor rather than a normal function
708     ebml_w.start_tag(tag_items_data_item_is_tuple_struct_ctor);
709     ebml_w.end_tag();
710
711     ebml_w.end_tag();
712 }
713
714 fn encode_method_ty_fields(ecx: &EncodeContext,
715                            ebml_w: &mut Encoder,
716                            method_ty: &ty::Method) {
717     encode_def_id(ebml_w, method_ty.def_id);
718     encode_name(ebml_w, method_ty.ident.name);
719     encode_ty_type_param_defs(ebml_w, ecx,
720                               method_ty.generics.type_param_defs(),
721                               tag_item_method_tps);
722     encode_method_fty(ecx, ebml_w, &method_ty.fty);
723     encode_visibility(ebml_w, method_ty.vis);
724     encode_explicit_self(ebml_w, method_ty.explicit_self);
725     let fn_style = method_ty.fty.fn_style;
726     match method_ty.explicit_self {
727         ast::SelfStatic => {
728             encode_family(ebml_w, fn_style_static_method_family(fn_style));
729         }
730         _ => encode_family(ebml_w, style_fn_family(fn_style))
731     }
732     encode_provided_source(ebml_w, method_ty.provided_source);
733 }
734
735 fn encode_info_for_method(ecx: &EncodeContext,
736                           ebml_w: &mut Encoder,
737                           m: &ty::Method,
738                           impl_path: PathElems,
739                           is_default_impl: bool,
740                           parent_id: NodeId,
741                           ast_method_opt: Option<@Method>) {
742
743     debug!("encode_info_for_method: {:?} {}", m.def_id,
744            token::get_ident(m.ident));
745     ebml_w.start_tag(tag_items_data_item);
746
747     encode_method_ty_fields(ecx, ebml_w, m);
748     encode_parent_item(ebml_w, local_def(parent_id));
749
750     // The type for methods gets encoded twice, which is unfortunate.
751     let tpt = lookup_item_type(ecx.tcx, m.def_id);
752     encode_bounds_and_type(ebml_w, ecx, &tpt);
753
754     let elem = ast_map::PathName(m.ident.name);
755     encode_path(ebml_w, impl_path.chain(Some(elem).move_iter()));
756     match ast_method_opt {
757         Some(ast_method) => {
758             encode_attributes(ebml_w, ast_method.attrs.as_slice())
759         }
760         None => ()
761     }
762
763     for &ast_method in ast_method_opt.iter() {
764         let num_params = tpt.generics.type_param_defs().len();
765         if num_params > 0u ||
766                 is_default_impl ||
767                 should_inline(ast_method.attrs.as_slice()) {
768             encode_inlined_item(ecx, ebml_w,
769                                 IIMethodRef(local_def(parent_id), false, ast_method));
770         } else {
771             encode_symbol(ecx, ebml_w, m.def_id.node);
772         }
773     }
774
775     ebml_w.end_tag();
776 }
777
778 fn encode_inlined_item(ecx: &EncodeContext,
779                        ebml_w: &mut Encoder,
780                        ii: InlinedItemRef) {
781     let mut eii = ecx.encode_inlined_item.borrow_mut();
782     let eii: &mut EncodeInlinedItem = &mut *eii;
783     (*eii)(ecx, ebml_w, ii)
784 }
785
786 fn style_fn_family(s: FnStyle) -> char {
787     match s {
788         UnsafeFn => 'u',
789         NormalFn => 'f',
790         ExternFn => 'e'
791     }
792 }
793
794 fn fn_style_static_method_family(s: FnStyle) -> char {
795     match s {
796         UnsafeFn => 'U',
797         NormalFn => 'F',
798         _ => fail!("extern fn can't be static")
799     }
800 }
801
802
803 fn should_inline(attrs: &[Attribute]) -> bool {
804     use syntax::attr::*;
805     match find_inline_attr(attrs) {
806         InlineNone | InlineNever  => false,
807         InlineHint | InlineAlways => true
808     }
809 }
810
811 // Encodes the inherent implementations of a structure, enumeration, or trait.
812 fn encode_inherent_implementations(ecx: &EncodeContext,
813                                    ebml_w: &mut Encoder,
814                                    def_id: DefId) {
815     match ecx.tcx.inherent_impls.borrow().find(&def_id) {
816         None => {}
817         Some(implementations) => {
818             for &impl_def_id in implementations.borrow().iter() {
819                 ebml_w.start_tag(tag_items_data_item_inherent_impl);
820                 encode_def_id(ebml_w, impl_def_id);
821                 ebml_w.end_tag();
822             }
823         }
824     }
825 }
826
827 // Encodes the implementations of a trait defined in this crate.
828 fn encode_extension_implementations(ecx: &EncodeContext,
829                                     ebml_w: &mut Encoder,
830                                     trait_def_id: DefId) {
831     match ecx.tcx.trait_impls.borrow().find(&trait_def_id) {
832         None => {}
833         Some(implementations) => {
834             for &impl_def_id in implementations.borrow().iter() {
835                 ebml_w.start_tag(tag_items_data_item_extension_impl);
836                 encode_def_id(ebml_w, impl_def_id);
837                 ebml_w.end_tag();
838             }
839         }
840     }
841 }
842
843 fn encode_sized(ebml_w: &mut Encoder, sized: Sized) {
844     ebml_w.start_tag(tag_items_data_item_sized);
845     let ch = match sized {
846         DynSize => 'd',
847         StaticSize => 's',
848     };
849     ebml_w.wr_str(str::from_char(ch));
850     ebml_w.end_tag();
851 }
852
853 fn encode_info_for_item(ecx: &EncodeContext,
854                         ebml_w: &mut Encoder,
855                         item: &Item,
856                         index: &mut Vec<entry<i64>>,
857                         path: PathElems,
858                         vis: ast::Visibility) {
859     let tcx = ecx.tcx;
860
861     fn add_to_index(item: &Item, ebml_w: &Encoder,
862                     index: &mut Vec<entry<i64>>) {
863         index.push(entry {
864             val: item.id as i64,
865             pos: ebml_w.writer.tell().unwrap(),
866         });
867     }
868
869     debug!("encoding info for item at {}",
870            ecx.tcx.sess.codemap().span_to_str(item.span));
871
872     let def_id = local_def(item.id);
873     match item.node {
874       ItemStatic(_, m, _) => {
875         add_to_index(item, ebml_w, index);
876         ebml_w.start_tag(tag_items_data_item);
877         encode_def_id(ebml_w, def_id);
878         if m == ast::MutMutable {
879             encode_family(ebml_w, 'b');
880         } else {
881             encode_family(ebml_w, 'c');
882         }
883         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
884         encode_symbol(ecx, ebml_w, item.id);
885         encode_name(ebml_w, item.ident.name);
886         encode_path(ebml_w, path);
887
888         let inlineable = !ecx.non_inlineable_statics.borrow().contains(&item.id);
889
890         if inlineable {
891             encode_inlined_item(ecx, ebml_w, IIItemRef(item));
892         }
893         encode_visibility(ebml_w, vis);
894         ebml_w.end_tag();
895       }
896       ItemFn(_, fn_style, _, ref generics, _) => {
897         add_to_index(item, ebml_w, index);
898         ebml_w.start_tag(tag_items_data_item);
899         encode_def_id(ebml_w, def_id);
900         encode_family(ebml_w, style_fn_family(fn_style));
901         let tps_len = generics.ty_params.len();
902         encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
903         encode_name(ebml_w, item.ident.name);
904         encode_path(ebml_w, path);
905         encode_attributes(ebml_w, item.attrs.as_slice());
906         if tps_len > 0u || should_inline(item.attrs.as_slice()) {
907             encode_inlined_item(ecx, ebml_w, IIItemRef(item));
908         } else {
909             encode_symbol(ecx, ebml_w, item.id);
910         }
911         encode_visibility(ebml_w, vis);
912         ebml_w.end_tag();
913       }
914       ItemMod(ref m) => {
915         add_to_index(item, ebml_w, index);
916         encode_info_for_mod(ecx,
917                             ebml_w,
918                             m,
919                             item.id,
920                             path,
921                             item.ident,
922                             item.vis);
923       }
924       ItemForeignMod(ref fm) => {
925         add_to_index(item, ebml_w, index);
926         ebml_w.start_tag(tag_items_data_item);
927         encode_def_id(ebml_w, def_id);
928         encode_family(ebml_w, 'n');
929         encode_name(ebml_w, item.ident.name);
930         encode_path(ebml_w, path);
931
932         // Encode all the items in this module.
933         for foreign_item in fm.items.iter() {
934             ebml_w.start_tag(tag_mod_child);
935             ebml_w.wr_str(def_to_str(local_def(foreign_item.id)));
936             ebml_w.end_tag();
937         }
938         encode_visibility(ebml_w, vis);
939         ebml_w.end_tag();
940       }
941       ItemTy(..) => {
942         add_to_index(item, ebml_w, index);
943         ebml_w.start_tag(tag_items_data_item);
944         encode_def_id(ebml_w, def_id);
945         encode_family(ebml_w, 'y');
946         encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
947         encode_name(ebml_w, item.ident.name);
948         encode_path(ebml_w, path);
949         encode_visibility(ebml_w, vis);
950         ebml_w.end_tag();
951       }
952       ItemEnum(ref enum_definition, ref generics) => {
953         add_to_index(item, ebml_w, index);
954
955         ebml_w.start_tag(tag_items_data_item);
956         encode_def_id(ebml_w, def_id);
957         encode_family(ebml_w, 't');
958         encode_item_variances(ebml_w, ecx, item.id);
959         encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
960         encode_name(ebml_w, item.ident.name);
961         encode_attributes(ebml_w, item.attrs.as_slice());
962         for v in (*enum_definition).variants.iter() {
963             encode_variant_id(ebml_w, local_def(v.node.id));
964         }
965         encode_inlined_item(ecx, ebml_w, IIItemRef(item));
966         encode_path(ebml_w, path);
967
968         // Encode inherent implementations for this enumeration.
969         encode_inherent_implementations(ecx, ebml_w, def_id);
970
971         encode_visibility(ebml_w, vis);
972         ebml_w.end_tag();
973
974         encode_enum_variant_info(ecx,
975                                  ebml_w,
976                                  item.id,
977                                  (*enum_definition).variants.as_slice(),
978                                  index,
979                                  generics);
980       }
981       ItemStruct(struct_def, _) => {
982         let fields = ty::lookup_struct_fields(tcx, def_id);
983
984         /* First, encode the fields
985            These come first because we need to write them to make
986            the index, and the index needs to be in the item for the
987            class itself */
988         let idx = encode_info_for_struct(ecx,
989                                          ebml_w,
990                                          fields.as_slice(),
991                                          index);
992
993         /* Index the class*/
994         add_to_index(item, ebml_w, index);
995
996         /* Now, make an item for the class itself */
997         ebml_w.start_tag(tag_items_data_item);
998         encode_def_id(ebml_w, def_id);
999         encode_family(ebml_w, 'S');
1000         encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
1001
1002         encode_item_variances(ebml_w, ecx, item.id);
1003         encode_name(ebml_w, item.ident.name);
1004         encode_attributes(ebml_w, item.attrs.as_slice());
1005         encode_path(ebml_w, path.clone());
1006         encode_visibility(ebml_w, vis);
1007
1008         /* Encode def_ids for each field and method
1009          for methods, write all the stuff get_trait_method
1010         needs to know*/
1011         encode_struct_fields(ebml_w, fields.as_slice(), def_id);
1012
1013         encode_inlined_item(ecx, ebml_w, IIItemRef(item));
1014
1015         // Encode inherent implementations for this structure.
1016         encode_inherent_implementations(ecx, ebml_w, def_id);
1017
1018         /* Each class has its own index -- encode it */
1019         encode_index(ebml_w, idx, write_i64);
1020         ebml_w.end_tag();
1021
1022         // If this is a tuple-like struct, encode the type of the constructor.
1023         match struct_def.ctor_id {
1024             Some(ctor_id) => {
1025                 encode_info_for_struct_ctor(ecx, ebml_w, item.ident,
1026                                             ctor_id, index, def_id.node);
1027             }
1028             None => {}
1029         }
1030       }
1031       ItemImpl(_, ref opt_trait, ty, ref ast_methods) => {
1032         // We need to encode information about the default methods we
1033         // have inherited, so we drive this based on the impl structure.
1034         let impl_methods = tcx.impl_methods.borrow();
1035         let methods = impl_methods.get(&def_id);
1036
1037         add_to_index(item, ebml_w, index);
1038         ebml_w.start_tag(tag_items_data_item);
1039         encode_def_id(ebml_w, def_id);
1040         encode_family(ebml_w, 'i');
1041         encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
1042         encode_name(ebml_w, item.ident.name);
1043         encode_attributes(ebml_w, item.attrs.as_slice());
1044         match ty.node {
1045             ast::TyPath(ref path, ref bounds, _) if path.segments
1046                                                         .len() == 1 => {
1047                 assert!(bounds.is_none());
1048                 encode_impl_type_basename(ebml_w, ast_util::path_to_ident(path));
1049             }
1050             _ => {}
1051         }
1052         for &method_def_id in methods.iter() {
1053             ebml_w.start_tag(tag_item_impl_method);
1054             let s = def_to_str(method_def_id);
1055             ebml_w.writer.write(s.as_bytes());
1056             ebml_w.end_tag();
1057         }
1058         for ast_trait_ref in opt_trait.iter() {
1059             let trait_ref = ty::node_id_to_trait_ref(
1060                 tcx, ast_trait_ref.ref_id);
1061             encode_trait_ref(ebml_w, ecx, &*trait_ref, tag_item_trait_ref);
1062             let impl_vtables = ty::lookup_impl_vtables(tcx, def_id);
1063             encode_impl_vtables(ebml_w, ecx, &impl_vtables);
1064         }
1065         encode_path(ebml_w, path.clone());
1066         ebml_w.end_tag();
1067
1068         // Iterate down the methods, emitting them. We rely on the
1069         // assumption that all of the actually implemented methods
1070         // appear first in the impl structure, in the same order they do
1071         // in the ast. This is a little sketchy.
1072         let num_implemented_methods = ast_methods.len();
1073         for (i, &method_def_id) in methods.iter().enumerate() {
1074             let ast_method = if i < num_implemented_methods {
1075                 Some(*ast_methods.get(i))
1076             } else { None };
1077
1078             index.push(entry {
1079                 val: method_def_id.node as i64,
1080                 pos: ebml_w.writer.tell().unwrap(),
1081             });
1082             encode_info_for_method(ecx,
1083                                    ebml_w,
1084                                    &*ty::method(tcx, method_def_id),
1085                                    path.clone(),
1086                                    false,
1087                                    item.id,
1088                                    ast_method)
1089         }
1090       }
1091       ItemTrait(_, sized, ref super_traits, ref ms) => {
1092         add_to_index(item, ebml_w, index);
1093         ebml_w.start_tag(tag_items_data_item);
1094         encode_def_id(ebml_w, def_id);
1095         encode_family(ebml_w, 'I');
1096         encode_item_variances(ebml_w, ecx, item.id);
1097         let trait_def = ty::lookup_trait_def(tcx, def_id);
1098         encode_ty_type_param_defs(ebml_w, ecx,
1099                                   trait_def.generics.type_param_defs(),
1100                                   tag_items_data_item_ty_param_bounds);
1101         encode_region_param_defs(ebml_w, trait_def.generics.region_param_defs());
1102         encode_trait_ref(ebml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
1103         encode_name(ebml_w, item.ident.name);
1104         encode_attributes(ebml_w, item.attrs.as_slice());
1105         // When we fix the rest of the supertrait nastiness (FIXME(#8559)), we
1106         // should no longer need this ugly little hack either.
1107         encode_sized(ebml_w, sized);
1108         encode_visibility(ebml_w, vis);
1109         for &method_def_id in ty::trait_method_def_ids(tcx, def_id).iter() {
1110             ebml_w.start_tag(tag_item_trait_method);
1111             encode_def_id(ebml_w, method_def_id);
1112             ebml_w.end_tag();
1113
1114             ebml_w.start_tag(tag_mod_child);
1115             ebml_w.wr_str(def_to_str(method_def_id));
1116             ebml_w.end_tag();
1117         }
1118         encode_path(ebml_w, path.clone());
1119         // FIXME(#8559): This should use the tcx's supertrait cache instead of
1120         // reading the AST's list, because the former has already filtered out
1121         // the builtin-kinds-as-supertraits. See corresponding fixme in decoder.
1122         for ast_trait_ref in super_traits.iter() {
1123             let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
1124             encode_trait_ref(ebml_w, ecx, &*trait_ref, tag_item_super_trait_ref);
1125         }
1126
1127         // Encode the implementations of this trait.
1128         encode_extension_implementations(ecx, ebml_w, def_id);
1129
1130         ebml_w.end_tag();
1131
1132         // Now output the method info for each method.
1133         let r = ty::trait_method_def_ids(tcx, def_id);
1134         for (i, &method_def_id) in r.iter().enumerate() {
1135             assert_eq!(method_def_id.krate, ast::LOCAL_CRATE);
1136
1137             let method_ty = ty::method(tcx, method_def_id);
1138
1139             index.push(entry {
1140                 val: method_def_id.node as i64,
1141                 pos: ebml_w.writer.tell().unwrap(),
1142             });
1143
1144             ebml_w.start_tag(tag_items_data_item);
1145
1146             encode_method_ty_fields(ecx, ebml_w, &*method_ty);
1147
1148             encode_parent_item(ebml_w, def_id);
1149
1150             let elem = ast_map::PathName(method_ty.ident.name);
1151             encode_path(ebml_w, path.clone().chain(Some(elem).move_iter()));
1152
1153             match method_ty.explicit_self {
1154                 SelfStatic => {
1155                     encode_family(ebml_w,
1156                                   fn_style_static_method_family(
1157                                       method_ty.fty.fn_style));
1158
1159                     let tpt = ty::lookup_item_type(tcx, method_def_id);
1160                     encode_bounds_and_type(ebml_w, ecx, &tpt);
1161                 }
1162
1163                 _ => {
1164                     encode_family(ebml_w,
1165                                   style_fn_family(
1166                                       method_ty.fty.fn_style));
1167                 }
1168             }
1169
1170             match ms.get(i) {
1171                 &Required(ref tm) => {
1172                     encode_attributes(ebml_w, tm.attrs.as_slice());
1173                     encode_method_sort(ebml_w, 'r');
1174                 }
1175
1176                 &Provided(m) => {
1177                     encode_attributes(ebml_w, m.attrs.as_slice());
1178                     // If this is a static method, we've already encoded
1179                     // this.
1180                     if method_ty.explicit_self != SelfStatic {
1181                         // FIXME: I feel like there is something funny going on.
1182                         let tpt = ty::lookup_item_type(tcx, method_def_id);
1183                         encode_bounds_and_type(ebml_w, ecx, &tpt);
1184                     }
1185                     encode_method_sort(ebml_w, 'p');
1186                     encode_inlined_item(ecx, ebml_w,
1187                                         IIMethodRef(def_id, true, m));
1188                 }
1189             }
1190
1191             ebml_w.end_tag();
1192         }
1193
1194         // Encode inherent implementations for this trait.
1195         encode_inherent_implementations(ecx, ebml_w, def_id);
1196       }
1197       ItemMac(..) => {
1198         // macros are encoded separately
1199       }
1200     }
1201 }
1202
1203 fn encode_info_for_foreign_item(ecx: &EncodeContext,
1204                                 ebml_w: &mut Encoder,
1205                                 nitem: &ForeignItem,
1206                                 index: &mut Vec<entry<i64>>,
1207                                 path: PathElems,
1208                                 abi: abi::Abi) {
1209     index.push(entry {
1210         val: nitem.id as i64,
1211         pos: ebml_w.writer.tell().unwrap(),
1212     });
1213
1214     ebml_w.start_tag(tag_items_data_item);
1215     encode_def_id(ebml_w, local_def(nitem.id));
1216     match nitem.node {
1217       ForeignItemFn(..) => {
1218         encode_family(ebml_w, style_fn_family(NormalFn));
1219         encode_bounds_and_type(ebml_w, ecx,
1220                                &lookup_item_type(ecx.tcx,local_def(nitem.id)));
1221         encode_name(ebml_w, nitem.ident.name);
1222         if abi == abi::RustIntrinsic {
1223             encode_inlined_item(ecx, ebml_w, IIForeignRef(nitem));
1224         } else {
1225             encode_symbol(ecx, ebml_w, nitem.id);
1226         }
1227       }
1228       ForeignItemStatic(_, mutbl) => {
1229         if mutbl {
1230             encode_family(ebml_w, 'b');
1231         } else {
1232             encode_family(ebml_w, 'c');
1233         }
1234         encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
1235         encode_symbol(ecx, ebml_w, nitem.id);
1236         encode_name(ebml_w, nitem.ident.name);
1237       }
1238     }
1239     encode_path(ebml_w, path);
1240     ebml_w.end_tag();
1241 }
1242
1243 fn my_visit_expr(_e: &Expr) { }
1244
1245 fn my_visit_item(i: &Item,
1246                  ebml_w: &mut Encoder,
1247                  ecx_ptr: *int,
1248                  index: &mut Vec<entry<i64>>) {
1249     let mut ebml_w = unsafe { ebml_w.unsafe_clone() };
1250     // See above
1251     let ecx: &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
1252     ecx.tcx.map.with_path(i.id, |path| {
1253         encode_info_for_item(ecx, &mut ebml_w, i, index, path, i.vis);
1254     });
1255 }
1256
1257 fn my_visit_foreign_item(ni: &ForeignItem,
1258                          ebml_w: &mut Encoder,
1259                          ecx_ptr:*int,
1260                          index: &mut Vec<entry<i64>>) {
1261     // See above
1262     let ecx: &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
1263     debug!("writing foreign item {}::{}",
1264             ecx.tcx.map.path_to_str(ni.id),
1265             token::get_ident(ni.ident));
1266
1267     let mut ebml_w = unsafe {
1268         ebml_w.unsafe_clone()
1269     };
1270     let abi = ecx.tcx.map.get_foreign_abi(ni.id);
1271     ecx.tcx.map.with_path(ni.id, |path| {
1272         encode_info_for_foreign_item(ecx, &mut ebml_w,
1273                                      ni, index,
1274                                      path, abi);
1275     });
1276 }
1277
1278 struct EncodeVisitor<'a,'b> {
1279     ebml_w_for_visit_item: &'a mut Encoder<'b>,
1280     ecx_ptr:*int,
1281     index: &'a mut Vec<entry<i64>>,
1282 }
1283
1284 impl<'a,'b> visit::Visitor<()> for EncodeVisitor<'a,'b> {
1285     fn visit_expr(&mut self, ex: &Expr, _: ()) {
1286         visit::walk_expr(self, ex, ());
1287         my_visit_expr(ex);
1288     }
1289     fn visit_item(&mut self, i: &Item, _: ()) {
1290         visit::walk_item(self, i, ());
1291         my_visit_item(i,
1292                       self.ebml_w_for_visit_item,
1293                       self.ecx_ptr,
1294                       self.index);
1295     }
1296     fn visit_foreign_item(&mut self, ni: &ForeignItem, _: ()) {
1297         visit::walk_foreign_item(self, ni, ());
1298         my_visit_foreign_item(ni,
1299                               self.ebml_w_for_visit_item,
1300                               self.ecx_ptr,
1301                               self.index);
1302     }
1303 }
1304
1305 fn encode_info_for_items(ecx: &EncodeContext,
1306                          ebml_w: &mut Encoder,
1307                          krate: &Crate)
1308                          -> Vec<entry<i64>> {
1309     let mut index = Vec::new();
1310     ebml_w.start_tag(tag_items_data);
1311     index.push(entry {
1312         val: CRATE_NODE_ID as i64,
1313         pos: ebml_w.writer.tell().unwrap(),
1314     });
1315     encode_info_for_mod(ecx,
1316                         ebml_w,
1317                         &krate.module,
1318                         CRATE_NODE_ID,
1319                         ast_map::Values([].iter()).chain(None),
1320                         syntax::parse::token::special_idents::invalid,
1321                         Public);
1322
1323     // See comment in `encode_side_tables_for_ii` in astencode
1324     let ecx_ptr: *int = unsafe { cast::transmute(ecx) };
1325     visit::walk_crate(&mut EncodeVisitor {
1326         index: &mut index,
1327         ecx_ptr: ecx_ptr,
1328         ebml_w_for_visit_item: &mut *ebml_w,
1329     }, krate, ());
1330
1331     ebml_w.end_tag();
1332     index
1333 }
1334
1335
1336 // Path and definition ID indexing
1337
1338 fn encode_index<T: Hash>(ebml_w: &mut Encoder, index: Vec<entry<T>>,
1339                          write_fn: |&mut MemWriter, &T|) {
1340     let mut buckets: Vec<Vec<entry<T>>> = Vec::from_fn(256, |_| Vec::new());
1341     for elt in index.move_iter() {
1342         let h = hash::hash(&elt.val) as uint;
1343         buckets.get_mut(h % 256).push(elt);
1344     }
1345
1346     ebml_w.start_tag(tag_index);
1347     let mut bucket_locs = Vec::new();
1348     ebml_w.start_tag(tag_index_buckets);
1349     for bucket in buckets.iter() {
1350         bucket_locs.push(ebml_w.writer.tell().unwrap());
1351         ebml_w.start_tag(tag_index_buckets_bucket);
1352         for elt in bucket.iter() {
1353             ebml_w.start_tag(tag_index_buckets_bucket_elt);
1354             assert!(elt.pos < 0xffff_ffff);
1355             {
1356                 let wr: &mut MemWriter = ebml_w.writer;
1357                 wr.write_be_u32(elt.pos as u32);
1358             }
1359             write_fn(ebml_w.writer, &elt.val);
1360             ebml_w.end_tag();
1361         }
1362         ebml_w.end_tag();
1363     }
1364     ebml_w.end_tag();
1365     ebml_w.start_tag(tag_index_table);
1366     for pos in bucket_locs.iter() {
1367         assert!(*pos < 0xffff_ffff);
1368         let wr: &mut MemWriter = ebml_w.writer;
1369         wr.write_be_u32(*pos as u32);
1370     }
1371     ebml_w.end_tag();
1372     ebml_w.end_tag();
1373 }
1374
1375 fn write_i64(writer: &mut MemWriter, &n: &i64) {
1376     let wr: &mut MemWriter = writer;
1377     assert!(n < 0x7fff_ffff);
1378     wr.write_be_u32(n as u32);
1379 }
1380
1381 fn encode_meta_item(ebml_w: &mut Encoder, mi: @MetaItem) {
1382     match mi.node {
1383       MetaWord(ref name) => {
1384         ebml_w.start_tag(tag_meta_item_word);
1385         ebml_w.start_tag(tag_meta_item_name);
1386         ebml_w.writer.write(name.get().as_bytes());
1387         ebml_w.end_tag();
1388         ebml_w.end_tag();
1389       }
1390       MetaNameValue(ref name, ref value) => {
1391         match value.node {
1392           LitStr(ref value, _) => {
1393             ebml_w.start_tag(tag_meta_item_name_value);
1394             ebml_w.start_tag(tag_meta_item_name);
1395             ebml_w.writer.write(name.get().as_bytes());
1396             ebml_w.end_tag();
1397             ebml_w.start_tag(tag_meta_item_value);
1398             ebml_w.writer.write(value.get().as_bytes());
1399             ebml_w.end_tag();
1400             ebml_w.end_tag();
1401           }
1402           _ => {/* FIXME (#623): encode other variants */ }
1403         }
1404       }
1405       MetaList(ref name, ref items) => {
1406         ebml_w.start_tag(tag_meta_item_list);
1407         ebml_w.start_tag(tag_meta_item_name);
1408         ebml_w.writer.write(name.get().as_bytes());
1409         ebml_w.end_tag();
1410         for inner_item in items.iter() {
1411             encode_meta_item(ebml_w, *inner_item);
1412         }
1413         ebml_w.end_tag();
1414       }
1415     }
1416 }
1417
1418 fn encode_attributes(ebml_w: &mut Encoder, attrs: &[Attribute]) {
1419     ebml_w.start_tag(tag_attributes);
1420     for attr in attrs.iter() {
1421         ebml_w.start_tag(tag_attribute);
1422         encode_meta_item(ebml_w, attr.node.value);
1423         ebml_w.end_tag();
1424     }
1425     ebml_w.end_tag();
1426 }
1427
1428 // So there's a special crate attribute called 'crate_id' which defines the
1429 // metadata that Rust cares about for linking crates. If the user didn't
1430 // provide it we will throw it in anyway with a default value.
1431 fn synthesize_crate_attrs(ecx: &EncodeContext,
1432                           krate: &Crate) -> Vec<Attribute> {
1433
1434     fn synthesize_crateid_attr(ecx: &EncodeContext) -> Attribute {
1435         assert!(!ecx.link_meta.crateid.name.is_empty());
1436
1437         attr::mk_attr(
1438             attr::mk_name_value_item_str(
1439                 InternedString::new("crate_id"),
1440                 token::intern_and_get_ident(ecx.link_meta.crateid.to_str())))
1441     }
1442
1443     let mut attrs = Vec::new();
1444     for attr in krate.attrs.iter() {
1445         if !attr.name().equiv(&("crate_id")) {
1446             attrs.push(*attr);
1447         }
1448     }
1449     attrs.push(synthesize_crateid_attr(ecx));
1450
1451     attrs
1452 }
1453
1454 fn encode_crate_deps(ebml_w: &mut Encoder, cstore: &cstore::CStore) {
1455     fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
1456         // Pull the cnums and name,vers,hash out of cstore
1457         let mut deps = Vec::new();
1458         cstore.iter_crate_data(|key, val| {
1459             let dep = decoder::CrateDep {
1460                 cnum: key,
1461                 crate_id: decoder::get_crate_id(val.data()),
1462                 hash: decoder::get_crate_hash(val.data())
1463             };
1464             deps.push(dep);
1465         });
1466
1467         // Sort by cnum
1468         deps.sort_by(|kv1, kv2| kv1.cnum.cmp(&kv2.cnum));
1469
1470         // Sanity-check the crate numbers
1471         let mut expected_cnum = 1;
1472         for n in deps.iter() {
1473             assert_eq!(n.cnum, expected_cnum);
1474             expected_cnum += 1;
1475         }
1476
1477         deps
1478     }
1479
1480     // We're just going to write a list of crate 'name-hash-version's, with
1481     // the assumption that they are numbered 1 to n.
1482     // FIXME (#2166): This is not nearly enough to support correct versioning
1483     // but is enough to get transitive crate dependencies working.
1484     ebml_w.start_tag(tag_crate_deps);
1485     let r = get_ordered_deps(cstore);
1486     for dep in r.iter() {
1487         encode_crate_dep(ebml_w, (*dep).clone());
1488     }
1489     ebml_w.end_tag();
1490 }
1491
1492 fn encode_lang_items(ecx: &EncodeContext, ebml_w: &mut Encoder) {
1493     ebml_w.start_tag(tag_lang_items);
1494
1495     for (i, def_id) in ecx.tcx.lang_items.items() {
1496         for id in def_id.iter() {
1497             if id.krate == LOCAL_CRATE {
1498                 ebml_w.start_tag(tag_lang_items_item);
1499
1500                 ebml_w.start_tag(tag_lang_items_item_id);
1501                 {
1502                     let wr: &mut MemWriter = ebml_w.writer;
1503                     wr.write_be_u32(i as u32);
1504                 }
1505                 ebml_w.end_tag();   // tag_lang_items_item_id
1506
1507                 ebml_w.start_tag(tag_lang_items_item_node_id);
1508                 {
1509                     let wr: &mut MemWriter = ebml_w.writer;
1510                     wr.write_be_u32(id.node as u32);
1511                 }
1512                 ebml_w.end_tag();   // tag_lang_items_item_node_id
1513
1514                 ebml_w.end_tag();   // tag_lang_items_item
1515             }
1516         }
1517     }
1518
1519     ebml_w.end_tag();   // tag_lang_items
1520 }
1521
1522 fn encode_native_libraries(ecx: &EncodeContext, ebml_w: &mut Encoder) {
1523     ebml_w.start_tag(tag_native_libraries);
1524
1525     for &(ref lib, kind) in ecx.tcx.sess.cstore.get_used_libraries()
1526                                .borrow().iter() {
1527         match kind {
1528             cstore::NativeStatic => {} // these libraries are not propagated
1529             cstore::NativeFramework | cstore::NativeUnknown => {
1530                 ebml_w.start_tag(tag_native_libraries_lib);
1531
1532                 ebml_w.start_tag(tag_native_libraries_kind);
1533                 ebml_w.writer.write_be_u32(kind as u32);
1534                 ebml_w.end_tag();
1535
1536                 ebml_w.start_tag(tag_native_libraries_name);
1537                 ebml_w.writer.write(lib.as_bytes());
1538                 ebml_w.end_tag();
1539
1540                 ebml_w.end_tag();
1541             }
1542         }
1543     }
1544
1545     ebml_w.end_tag();
1546 }
1547
1548 fn encode_macro_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) {
1549     match ecx.tcx.sess.macro_registrar_fn.get() {
1550         Some(id) => { ebml_w.wr_tagged_u32(tag_macro_registrar_fn, id); }
1551         None => {}
1552     }
1553 }
1554
1555 struct MacroDefVisitor<'a, 'b, 'c> {
1556     ecx: &'a EncodeContext<'b>,
1557     ebml_w: &'a mut Encoder<'c>
1558 }
1559
1560 impl<'a, 'b, 'c> Visitor<()> for MacroDefVisitor<'a, 'b, 'c> {
1561     fn visit_item(&mut self, item: &Item, _: ()) {
1562         match item.node {
1563             ItemMac(..) => {
1564                 let def = self.ecx.tcx.sess.codemap().span_to_snippet(item.span)
1565                     .expect("Unable to find source for macro");
1566                 self.ebml_w.start_tag(tag_macro_def);
1567                 self.ebml_w.wr_str(def);
1568                 self.ebml_w.end_tag();
1569             }
1570             _ => {}
1571         }
1572         visit::walk_item(self, item, ());
1573     }
1574 }
1575
1576 fn encode_macro_defs<'a>(ecx: &'a EncodeContext,
1577                          krate: &Crate,
1578                          ebml_w: &'a mut Encoder) {
1579     ebml_w.start_tag(tag_exported_macros);
1580     {
1581         let mut visitor = MacroDefVisitor {
1582             ecx: ecx,
1583             ebml_w: ebml_w,
1584         };
1585         visit::walk_crate(&mut visitor, krate, ());
1586     }
1587     ebml_w.end_tag();
1588 }
1589
1590 struct ImplVisitor<'a,'b,'c> {
1591     ecx: &'a EncodeContext<'b>,
1592     ebml_w: &'a mut Encoder<'c>,
1593 }
1594
1595 impl<'a,'b,'c> Visitor<()> for ImplVisitor<'a,'b,'c> {
1596     fn visit_item(&mut self, item: &Item, _: ()) {
1597         match item.node {
1598             ItemImpl(_, Some(ref trait_ref), _, _) => {
1599                 let def_map = &self.ecx.tcx.def_map;
1600                 let trait_def = def_map.borrow().get_copy(&trait_ref.ref_id);
1601                 let def_id = ast_util::def_id_of_def(trait_def);
1602
1603                 // Load eagerly if this is an implementation of the Drop trait
1604                 // or if the trait is not defined in this crate.
1605                 if Some(def_id) == self.ecx.tcx.lang_items.drop_trait() ||
1606                         def_id.krate != LOCAL_CRATE {
1607                     self.ebml_w.start_tag(tag_impls_impl);
1608                     encode_def_id(self.ebml_w, local_def(item.id));
1609                     self.ebml_w.end_tag();
1610                 }
1611             }
1612             _ => {}
1613         }
1614         visit::walk_item(self, item, ());
1615     }
1616 }
1617
1618 /// Encodes implementations that are eagerly loaded.
1619 ///
1620 /// None of this is necessary in theory; we can load all implementations
1621 /// lazily. However, in two cases the optimizations to lazily load
1622 /// implementations are not yet implemented. These two cases, which require us
1623 /// to load implementations eagerly, are:
1624 ///
1625 /// * Destructors (implementations of the Drop trait).
1626 ///
1627 /// * Implementations of traits not defined in this crate.
1628 fn encode_impls<'a>(ecx: &'a EncodeContext,
1629                     krate: &Crate,
1630                     ebml_w: &'a mut Encoder) {
1631     ebml_w.start_tag(tag_impls);
1632
1633     {
1634         let mut visitor = ImplVisitor {
1635             ecx: ecx,
1636             ebml_w: ebml_w,
1637         };
1638         visit::walk_crate(&mut visitor, krate, ());
1639     }
1640
1641     ebml_w.end_tag();
1642 }
1643
1644 fn encode_misc_info(ecx: &EncodeContext,
1645                     krate: &Crate,
1646                     ebml_w: &mut Encoder) {
1647     ebml_w.start_tag(tag_misc_info);
1648     ebml_w.start_tag(tag_misc_info_crate_items);
1649     for &item in krate.module.items.iter() {
1650         ebml_w.start_tag(tag_mod_child);
1651         ebml_w.wr_str(def_to_str(local_def(item.id)));
1652         ebml_w.end_tag();
1653
1654         each_auxiliary_node_id(item, |auxiliary_node_id| {
1655             ebml_w.start_tag(tag_mod_child);
1656             ebml_w.wr_str(def_to_str(local_def(auxiliary_node_id)));
1657             ebml_w.end_tag();
1658             true
1659         });
1660     }
1661
1662     // Encode reexports for the root module.
1663     encode_reexports(ecx, ebml_w, 0, ast_map::Values([].iter()).chain(None));
1664
1665     ebml_w.end_tag();
1666     ebml_w.end_tag();
1667 }
1668
1669 fn encode_crate_dep(ebml_w: &mut Encoder,
1670                     dep: decoder::CrateDep) {
1671     ebml_w.start_tag(tag_crate_dep);
1672     ebml_w.start_tag(tag_crate_dep_crateid);
1673     ebml_w.writer.write(dep.crate_id.to_str().as_bytes());
1674     ebml_w.end_tag();
1675     ebml_w.start_tag(tag_crate_dep_hash);
1676     ebml_w.writer.write(dep.hash.as_str().as_bytes());
1677     ebml_w.end_tag();
1678     ebml_w.end_tag();
1679 }
1680
1681 fn encode_hash(ebml_w: &mut Encoder, hash: &Svh) {
1682     ebml_w.start_tag(tag_crate_hash);
1683     ebml_w.writer.write(hash.as_str().as_bytes());
1684     ebml_w.end_tag();
1685 }
1686
1687 fn encode_crate_id(ebml_w: &mut Encoder, crate_id: &CrateId) {
1688     ebml_w.start_tag(tag_crate_crateid);
1689     ebml_w.writer.write(crate_id.to_str().as_bytes());
1690     ebml_w.end_tag();
1691 }
1692
1693 fn encode_crate_triple(ebml_w: &mut Encoder, triple: &str) {
1694     ebml_w.start_tag(tag_crate_triple);
1695     ebml_w.writer.write(triple.as_bytes());
1696     ebml_w.end_tag();
1697 }
1698
1699 // NB: Increment this as you change the metadata encoding version.
1700 pub static metadata_encoding_version : &'static [u8] =
1701     &[0x72, //'r' as u8,
1702       0x75, //'u' as u8,
1703       0x73, //'s' as u8,
1704       0x74, //'t' as u8,
1705       0, 0, 0, 1 ];
1706
1707 pub fn encode_metadata(parms: EncodeParams, krate: &Crate) -> Vec<u8> {
1708     let mut wr = MemWriter::new();
1709     encode_metadata_inner(&mut wr, parms, krate);
1710     wr.unwrap().move_iter().collect()
1711 }
1712
1713 fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate) {
1714     struct Stats {
1715         attr_bytes: u64,
1716         dep_bytes: u64,
1717         lang_item_bytes: u64,
1718         native_lib_bytes: u64,
1719         macro_registrar_fn_bytes: u64,
1720         macro_defs_bytes: u64,
1721         impl_bytes: u64,
1722         misc_bytes: u64,
1723         item_bytes: u64,
1724         index_bytes: u64,
1725         zero_bytes: u64,
1726         total_bytes: u64,
1727     }
1728     let mut stats = Stats {
1729         attr_bytes: 0,
1730         dep_bytes: 0,
1731         lang_item_bytes: 0,
1732         native_lib_bytes: 0,
1733         macro_registrar_fn_bytes: 0,
1734         macro_defs_bytes: 0,
1735         impl_bytes: 0,
1736         misc_bytes: 0,
1737         item_bytes: 0,
1738         index_bytes: 0,
1739         zero_bytes: 0,
1740         total_bytes: 0,
1741     };
1742     let EncodeParams {
1743         item_symbols,
1744         diag,
1745         tcx,
1746         reexports2,
1747         cstore,
1748         encode_inlined_item,
1749         link_meta,
1750         non_inlineable_statics,
1751         ..
1752     } = parms;
1753     let ecx = EncodeContext {
1754         diag: diag,
1755         tcx: tcx,
1756         reexports2: reexports2,
1757         item_symbols: item_symbols,
1758         non_inlineable_statics: non_inlineable_statics,
1759         link_meta: link_meta,
1760         cstore: cstore,
1761         encode_inlined_item: RefCell::new(encode_inlined_item),
1762         type_abbrevs: RefCell::new(HashMap::new()),
1763      };
1764
1765     let mut ebml_w = writer::Encoder(wr);
1766
1767     encode_crate_id(&mut ebml_w, &ecx.link_meta.crateid);
1768     encode_crate_triple(&mut ebml_w, tcx.sess.targ_cfg.target_strs.target_triple);
1769     encode_hash(&mut ebml_w, &ecx.link_meta.crate_hash);
1770
1771     let mut i = ebml_w.writer.tell().unwrap();
1772     let crate_attrs = synthesize_crate_attrs(&ecx, krate);
1773     encode_attributes(&mut ebml_w, crate_attrs.as_slice());
1774     stats.attr_bytes = ebml_w.writer.tell().unwrap() - i;
1775
1776     i = ebml_w.writer.tell().unwrap();
1777     encode_crate_deps(&mut ebml_w, ecx.cstore);
1778     stats.dep_bytes = ebml_w.writer.tell().unwrap() - i;
1779
1780     // Encode the language items.
1781     i = ebml_w.writer.tell().unwrap();
1782     encode_lang_items(&ecx, &mut ebml_w);
1783     stats.lang_item_bytes = ebml_w.writer.tell().unwrap() - i;
1784
1785     // Encode the native libraries used
1786     i = ebml_w.writer.tell().unwrap();
1787     encode_native_libraries(&ecx, &mut ebml_w);
1788     stats.native_lib_bytes = ebml_w.writer.tell().unwrap() - i;
1789
1790     // Encode the macro registrar function
1791     i = ebml_w.writer.tell().unwrap();
1792     encode_macro_registrar_fn(&ecx, &mut ebml_w);
1793     stats.macro_registrar_fn_bytes = ebml_w.writer.tell().unwrap() - i;
1794
1795     // Encode macro definitions
1796     i = ebml_w.writer.tell().unwrap();
1797     encode_macro_defs(&ecx, krate, &mut ebml_w);
1798     stats.macro_defs_bytes = ebml_w.writer.tell().unwrap() - i;
1799
1800     // Encode the def IDs of impls, for coherence checking.
1801     i = ebml_w.writer.tell().unwrap();
1802     encode_impls(&ecx, krate, &mut ebml_w);
1803     stats.impl_bytes = ebml_w.writer.tell().unwrap() - i;
1804
1805     // Encode miscellaneous info.
1806     i = ebml_w.writer.tell().unwrap();
1807     encode_misc_info(&ecx, krate, &mut ebml_w);
1808     stats.misc_bytes = ebml_w.writer.tell().unwrap() - i;
1809
1810     // Encode and index the items.
1811     ebml_w.start_tag(tag_items);
1812     i = ebml_w.writer.tell().unwrap();
1813     let items_index = encode_info_for_items(&ecx, &mut ebml_w, krate);
1814     stats.item_bytes = ebml_w.writer.tell().unwrap() - i;
1815
1816     i = ebml_w.writer.tell().unwrap();
1817     encode_index(&mut ebml_w, items_index, write_i64);
1818     stats.index_bytes = ebml_w.writer.tell().unwrap() - i;
1819     ebml_w.end_tag();
1820
1821     stats.total_bytes = ebml_w.writer.tell().unwrap();
1822
1823     if tcx.sess.meta_stats() {
1824         for e in ebml_w.writer.get_ref().iter() {
1825             if *e == 0 {
1826                 stats.zero_bytes += 1;
1827             }
1828         }
1829
1830         println!("metadata stats:");
1831         println!("      attribute bytes: {}", stats.attr_bytes);
1832         println!("            dep bytes: {}", stats.dep_bytes);
1833         println!("      lang item bytes: {}", stats.lang_item_bytes);
1834         println!("         native bytes: {}", stats.native_lib_bytes);
1835         println!("macro registrar bytes: {}", stats.macro_registrar_fn_bytes);
1836         println!("      macro def bytes: {}", stats.macro_defs_bytes);
1837         println!("           impl bytes: {}", stats.impl_bytes);
1838         println!("           misc bytes: {}", stats.misc_bytes);
1839         println!("           item bytes: {}", stats.item_bytes);
1840         println!("          index bytes: {}", stats.index_bytes);
1841         println!("           zero bytes: {}", stats.zero_bytes);
1842         println!("          total bytes: {}", stats.total_bytes);
1843     }
1844 }
1845
1846 // Get the encoded string for a type
1847 pub fn encoded_ty(tcx: &ty::ctxt, t: ty::t) -> ~str {
1848     let mut wr = MemWriter::new();
1849     tyencode::enc_ty(&mut wr, &tyencode::ctxt {
1850         diag: tcx.sess.diagnostic(),
1851         ds: def_to_str,
1852         tcx: tcx,
1853         abbrevs: &RefCell::new(HashMap::new())
1854     }, t);
1855     str::from_utf8_owned(wr.get_ref().to_owned()).unwrap()
1856 }