]> git.lizzy.rs Git - rust.git/blob - src/librustc/metadata/encoder.rs
librustc: Update the serializer to work properly with INHTWAMA, removing mutable...
[rust.git] / src / librustc / metadata / encoder.rs
1 // Copyright 2012 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 use metadata::common::*;
14 use metadata::cstore;
15 use metadata::decoder;
16 use metadata::tyencode;
17 use middle::trans::reachable;
18 use middle::ty::node_id_to_type;
19 use middle::ty;
20 use middle;
21 use util::ppaux::ty_to_str;
22
23 use core::flate;
24 use core::hash::HashUtil;
25 use core::hashmap::HashMap;
26 use std::serialize::Encodable;
27 use std;
28 use syntax::abi::AbiSet;
29 use syntax::ast::*;
30 use syntax::ast;
31 use syntax::ast_map;
32 use syntax::ast_util::*;
33 use syntax::attr;
34 use syntax::diagnostic::span_handler;
35 use syntax::parse::token::special_idents;
36 use syntax::{ast_util, visit};
37 use syntax::opt_vec::OptVec;
38 use syntax::opt_vec;
39 use syntax;
40 use writer = std::ebml::writer;
41
42 // used by astencode:
43 type abbrev_map = @mut HashMap<ty::t, tyencode::ty_abbrev>;
44
45 #[cfg(stage0)]
46 pub type encode_inlined_item = @fn(ecx: @EncodeContext,
47                                    ebml_w: &writer::Encoder,
48                                    path: &[ast_map::path_elt],
49                                    ii: ast::inlined_item);
50
51 #[cfg(not(stage0))]
52 pub type encode_inlined_item = @fn(ecx: @EncodeContext,
53                                    ebml_w: &mut writer::Encoder,
54                                    path: &[ast_map::path_elt],
55                                    ii: ast::inlined_item);
56
57 pub struct EncodeParams {
58     diag: @span_handler,
59     tcx: ty::ctxt,
60     reachable: reachable::map,
61     reexports2: middle::resolve::ExportMap2,
62     item_symbols: @mut HashMap<ast::node_id, ~str>,
63     discrim_symbols: @mut HashMap<ast::node_id, @~str>,
64     link_meta: LinkMeta,
65     cstore: @mut cstore::CStore,
66     encode_inlined_item: encode_inlined_item
67 }
68
69 struct Stats {
70     inline_bytes: uint,
71     attr_bytes: uint,
72     dep_bytes: uint,
73     lang_item_bytes: uint,
74     link_args_bytes: uint,
75     item_bytes: uint,
76     index_bytes: uint,
77     zero_bytes: uint,
78     total_bytes: uint,
79
80     n_inlines: uint
81 }
82
83 pub struct EncodeContext {
84     diag: @span_handler,
85     tcx: ty::ctxt,
86     stats: @mut Stats,
87     reachable: reachable::map,
88     reexports2: middle::resolve::ExportMap2,
89     item_symbols: @mut HashMap<ast::node_id, ~str>,
90     discrim_symbols: @mut HashMap<ast::node_id, @~str>,
91     link_meta: LinkMeta,
92     cstore: @mut cstore::CStore,
93     encode_inlined_item: encode_inlined_item,
94     type_abbrevs: abbrev_map
95 }
96
97 pub fn reachable(ecx: @EncodeContext, id: node_id) -> bool {
98     ecx.reachable.contains(&id)
99 }
100
101 #[cfg(stage0)]
102 fn encode_name(ecx: @EncodeContext, ebml_w: &writer::Encoder, name: ident) {
103     ebml_w.wr_tagged_str(tag_paths_data_name, *ecx.tcx.sess.str_of(name));
104 }
105
106 #[cfg(not(stage0))]
107 fn encode_name(ecx: @EncodeContext,
108                ebml_w: &mut writer::Encoder,
109                name: ident) {
110     ebml_w.wr_tagged_str(tag_paths_data_name, *ecx.tcx.sess.str_of(name));
111 }
112
113 #[cfg(stage0)]
114 fn encode_impl_type_basename(ecx: @EncodeContext,
115                              ebml_w: &writer::Encoder,
116                              name: ident) {
117     ebml_w.wr_tagged_str(tag_item_impl_type_basename,
118                          *ecx.tcx.sess.str_of(name));
119 }
120
121 #[cfg(not(stage0))]
122 fn encode_impl_type_basename(ecx: @EncodeContext,
123                              ebml_w: &mut writer::Encoder,
124                              name: ident) {
125     ebml_w.wr_tagged_str(tag_item_impl_type_basename,
126                          *ecx.tcx.sess.str_of(name));
127 }
128
129 #[cfg(stage0)]
130 pub fn encode_def_id(ebml_w: &writer::Encoder, id: def_id) {
131     ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
132 }
133
134 #[cfg(not(stage0))]
135 pub fn encode_def_id(ebml_w: &mut writer::Encoder, id: def_id) {
136     ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
137 }
138
139 #[cfg(stage0)]
140 fn encode_region_param(ecx: @EncodeContext,
141                        ebml_w: &writer::Encoder,
142                        it: @ast::item) {
143     let opt_rp = ecx.tcx.region_paramd_items.find(&it.id);
144     for opt_rp.each |rp| {
145         do ebml_w.wr_tag(tag_region_param) {
146             rp.encode(ebml_w);
147         }
148     }
149 }
150
151 #[cfg(not(stage0))]
152 fn encode_region_param(ecx: @EncodeContext,
153                        ebml_w: &mut writer::Encoder,
154                        it: @ast::item) {
155     let opt_rp = ecx.tcx.region_paramd_items.find(&it.id);
156     for opt_rp.each |rp| {
157         ebml_w.start_tag(tag_region_param);
158         rp.encode(ebml_w);
159         ebml_w.end_tag();
160     }
161 }
162
163 #[cfg(stage0)]
164 fn encode_mutability(ebml_w: &writer::Encoder, mt: struct_mutability) {
165     do ebml_w.wr_tag(tag_struct_mut) {
166         let val = match mt {
167           struct_immutable => 'a',
168           struct_mutable => 'm'
169         };
170         ebml_w.writer.write(&[val as u8]);
171     }
172 }
173
174 #[cfg(not(stage0))]
175 fn encode_mutability(ebml_w: &mut writer::Encoder, mt: struct_mutability) {
176     ebml_w.start_tag(tag_struct_mut);
177     let val = match mt {
178       struct_immutable => 'a',
179       struct_mutable => 'm'
180     };
181     ebml_w.writer.write(&[val as u8]);
182     ebml_w.end_tag();
183 }
184
185 struct entry<T> {
186     val: T,
187     pos: uint
188 }
189
190 #[cfg(stage0)]
191 fn add_to_index(ecx: @EncodeContext,
192                 ebml_w: &writer::Encoder,
193                 path: &[ident],
194                 index: &mut ~[entry<~str>],
195                 name: ident) {
196     let mut full_path = ~[];
197     full_path.push_all(path);
198     full_path.push(name);
199     index.push(
200         entry {
201             val: ast_util::path_name_i(full_path,
202                                        ecx.tcx.sess.parse_sess.interner),
203             pos: ebml_w.writer.tell()
204         });
205 }
206
207 #[cfg(not(stage0))]
208 fn add_to_index(ecx: @EncodeContext,
209                 ebml_w: &mut writer::Encoder,
210                 path: &[ident],
211                 index: &mut ~[entry<~str>],
212                 name: ident) {
213     let mut full_path = ~[];
214     full_path.push_all(path);
215     full_path.push(name);
216     index.push(
217         entry {
218             val: ast_util::path_name_i(full_path,
219                                        ecx.tcx.sess.parse_sess.interner),
220             pos: ebml_w.writer.tell()
221         });
222 }
223
224 #[cfg(stage0)]
225 fn encode_trait_ref(ebml_w: &writer::Encoder,
226                     ecx: @EncodeContext,
227                     trait_ref: &ty::TraitRef,
228                     tag: uint) {
229     let ty_str_ctxt = @tyencode::ctxt {
230         diag: ecx.diag,
231         ds: def_to_str,
232         tcx: ecx.tcx,
233         reachable: |a| reachable(ecx, a),
234         abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
235
236     ebml_w.start_tag(tag);
237     tyencode::enc_trait_ref(ebml_w.writer, ty_str_ctxt, trait_ref);
238     ebml_w.end_tag();
239 }
240
241 #[cfg(not(stage0))]
242 fn encode_trait_ref(ebml_w: &mut writer::Encoder,
243                     ecx: @EncodeContext,
244                     trait_ref: &ty::TraitRef,
245                     tag: uint) {
246     let ty_str_ctxt = @tyencode::ctxt {
247         diag: ecx.diag,
248         ds: def_to_str,
249         tcx: ecx.tcx,
250         reachable: |a| reachable(ecx, a),
251         abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
252
253     ebml_w.start_tag(tag);
254     tyencode::enc_trait_ref(ebml_w.writer, ty_str_ctxt, trait_ref);
255     ebml_w.end_tag();
256 }
257
258 // Item info table encoding
259 #[cfg(stage0)]
260 fn encode_family(ebml_w: &writer::Encoder, c: char) {
261     ebml_w.start_tag(tag_items_data_item_family);
262     ebml_w.writer.write(&[c as u8]);
263     ebml_w.end_tag();
264 }
265
266 // Item info table encoding
267 #[cfg(not(stage0))]
268 fn encode_family(ebml_w: &mut writer::Encoder, c: char) {
269     ebml_w.start_tag(tag_items_data_item_family);
270     ebml_w.writer.write(&[c as u8]);
271     ebml_w.end_tag();
272 }
273
274 pub fn def_to_str(did: def_id) -> ~str {
275     fmt!("%d:%d", did.crate, did.node)
276 }
277
278 #[cfg(stage0)]
279 fn encode_ty_type_param_defs(ebml_w: &writer::Encoder,
280                              ecx: @EncodeContext,
281                              params: @~[ty::TypeParameterDef],
282                              tag: uint) {
283     let ty_str_ctxt = @tyencode::ctxt {
284         diag: ecx.diag,
285         ds: def_to_str,
286         tcx: ecx.tcx,
287         reachable: |a| reachable(ecx, a),
288         abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
289     for params.each |param| {
290         ebml_w.start_tag(tag);
291         tyencode::enc_type_param_def(ebml_w.writer, ty_str_ctxt, param);
292         ebml_w.end_tag();
293     }
294 }
295
296 #[cfg(not(stage0))]
297 fn encode_ty_type_param_defs(ebml_w: &mut writer::Encoder,
298                              ecx: @EncodeContext,
299                              params: @~[ty::TypeParameterDef],
300                              tag: uint) {
301     let ty_str_ctxt = @tyencode::ctxt {
302         diag: ecx.diag,
303         ds: def_to_str,
304         tcx: ecx.tcx,
305         reachable: |a| reachable(ecx, a),
306         abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
307     for params.each |param| {
308         ebml_w.start_tag(tag);
309         tyencode::enc_type_param_def(ebml_w.writer, ty_str_ctxt, param);
310         ebml_w.end_tag();
311     }
312 }
313
314 #[cfg(stage0)]
315 fn encode_type_param_bounds(ebml_w: &writer::Encoder,
316                             ecx: @EncodeContext,
317                             params: &OptVec<TyParam>) {
318     let ty_param_defs =
319         @params.map_to_vec(|param| *ecx.tcx.ty_param_defs.get(&param.id));
320     encode_ty_type_param_defs(ebml_w, ecx, ty_param_defs,
321                               tag_items_data_item_ty_param_bounds);
322 }
323
324 #[cfg(not(stage0))]
325 fn encode_type_param_bounds(ebml_w: &mut writer::Encoder,
326                             ecx: @EncodeContext,
327                             params: &OptVec<TyParam>) {
328     let ty_param_defs =
329         @params.map_to_vec(|param| *ecx.tcx.ty_param_defs.get(&param.id));
330     encode_ty_type_param_defs(ebml_w, ecx, ty_param_defs,
331                               tag_items_data_item_ty_param_bounds);
332 }
333
334 #[cfg(stage0)]
335 fn encode_variant_id(ebml_w: &writer::Encoder, vid: def_id) {
336     ebml_w.start_tag(tag_items_data_item_variant);
337     ebml_w.writer.write(str::to_bytes(def_to_str(vid)));
338     ebml_w.end_tag();
339 }
340
341 #[cfg(not(stage0))]
342 fn encode_variant_id(ebml_w: &mut writer::Encoder, vid: def_id) {
343     ebml_w.start_tag(tag_items_data_item_variant);
344     ebml_w.writer.write(str::to_bytes(def_to_str(vid)));
345     ebml_w.end_tag();
346 }
347
348 #[cfg(stage0)]
349 pub fn write_type(ecx: @EncodeContext, ebml_w: &writer::Encoder, typ: ty::t) {
350     let ty_str_ctxt = @tyencode::ctxt {
351         diag: ecx.diag,
352         ds: def_to_str,
353         tcx: ecx.tcx,
354         reachable: |a| reachable(ecx, a),
355         abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
356     tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
357 }
358
359 #[cfg(not(stage0))]
360 pub fn write_type(ecx: @EncodeContext,
361                   ebml_w: &mut writer::Encoder,
362                   typ: ty::t) {
363     let ty_str_ctxt = @tyencode::ctxt {
364         diag: ecx.diag,
365         ds: def_to_str,
366         tcx: ecx.tcx,
367         reachable: |a| reachable(ecx, a),
368         abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
369     tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
370 }
371
372 #[cfg(stage0)]
373 pub fn write_vstore(ecx: @EncodeContext,
374                     ebml_w: &writer::Encoder,
375                     vstore: ty::vstore) {
376     let ty_str_ctxt = @tyencode::ctxt {
377         diag: ecx.diag,
378         ds: def_to_str,
379         tcx: ecx.tcx,
380         reachable: |a| reachable(ecx, a),
381         abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
382     tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore);
383 }
384
385 #[cfg(not(stage0))]
386 pub fn write_vstore(ecx: @EncodeContext,
387                     ebml_w: &mut writer::Encoder,
388                     vstore: ty::vstore) {
389     let ty_str_ctxt = @tyencode::ctxt {
390         diag: ecx.diag,
391         ds: def_to_str,
392         tcx: ecx.tcx,
393         reachable: |a| reachable(ecx, a),
394         abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
395     tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore);
396 }
397
398 #[cfg(stage0)]
399 fn encode_type(ecx: @EncodeContext, ebml_w: &writer::Encoder, typ: ty::t) {
400     ebml_w.start_tag(tag_items_data_item_type);
401     write_type(ecx, ebml_w, typ);
402     ebml_w.end_tag();
403 }
404
405 #[cfg(not(stage0))]
406 fn encode_type(ecx: @EncodeContext,
407                ebml_w: &mut writer::Encoder,
408                typ: ty::t) {
409     ebml_w.start_tag(tag_items_data_item_type);
410     write_type(ecx, ebml_w, typ);
411     ebml_w.end_tag();
412 }
413
414 #[cfg(stage0)]
415 fn encode_transformed_self_ty(ecx: @EncodeContext,
416                               ebml_w: &writer::Encoder,
417                               opt_typ: Option<ty::t>) {
418     for opt_typ.each |&typ| {
419         ebml_w.start_tag(tag_item_method_transformed_self_ty);
420         write_type(ecx, ebml_w, typ);
421         ebml_w.end_tag();
422     }
423 }
424
425 #[cfg(not(stage0))]
426 fn encode_transformed_self_ty(ecx: @EncodeContext,
427                               ebml_w: &mut writer::Encoder,
428                               opt_typ: Option<ty::t>) {
429     for opt_typ.each |&typ| {
430         ebml_w.start_tag(tag_item_method_transformed_self_ty);
431         write_type(ecx, ebml_w, typ);
432         ebml_w.end_tag();
433     }
434 }
435
436 #[cfg(stage0)]
437 fn encode_method_fty(ecx: @EncodeContext,
438                      ebml_w: &writer::Encoder,
439                      typ: &ty::BareFnTy) {
440     ebml_w.start_tag(tag_item_method_fty);
441
442     let ty_str_ctxt = @tyencode::ctxt {
443         diag: ecx.diag,
444         ds: def_to_str,
445         tcx: ecx.tcx,
446         reachable: |a| reachable(ecx, a),
447         abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
448     tyencode::enc_bare_fn_ty(ebml_w.writer, ty_str_ctxt, typ);
449
450     ebml_w.end_tag();
451 }
452
453 #[cfg(not(stage0))]
454 fn encode_method_fty(ecx: @EncodeContext,
455                      ebml_w: &mut writer::Encoder,
456                      typ: &ty::BareFnTy) {
457     ebml_w.start_tag(tag_item_method_fty);
458
459     let ty_str_ctxt = @tyencode::ctxt {
460         diag: ecx.diag,
461         ds: def_to_str,
462         tcx: ecx.tcx,
463         reachable: |a| reachable(ecx, a),
464         abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
465     tyencode::enc_bare_fn_ty(ebml_w.writer, ty_str_ctxt, typ);
466
467     ebml_w.end_tag();
468 }
469
470 #[cfg(stage0)]
471 fn encode_symbol(ecx: @EncodeContext, ebml_w: &writer::Encoder, id: node_id) {
472     ebml_w.start_tag(tag_items_data_item_symbol);
473     match ecx.item_symbols.find(&id) {
474         Some(x) => {
475             debug!("encode_symbol(id=%?, str=%s)", id, *x);
476             ebml_w.writer.write(str::to_bytes(*x));
477         }
478         None => {
479             ecx.diag.handler().bug(
480                 fmt!("encode_symbol: id not found %d", id));
481         }
482     }
483     ebml_w.end_tag();
484 }
485
486 #[cfg(not(stage0))]
487 fn encode_symbol(ecx: @EncodeContext,
488                  ebml_w: &mut writer::Encoder,
489                  id: node_id) {
490     ebml_w.start_tag(tag_items_data_item_symbol);
491     match ecx.item_symbols.find(&id) {
492         Some(x) => {
493             debug!("encode_symbol(id=%?, str=%s)", id, *x);
494             ebml_w.writer.write(str::to_bytes(*x));
495         }
496         None => {
497             ecx.diag.handler().bug(
498                 fmt!("encode_symbol: id not found %d", id));
499         }
500     }
501     ebml_w.end_tag();
502 }
503
504 #[cfg(stage0)]
505 fn encode_discriminant(ecx: @EncodeContext,
506                        ebml_w: &writer::Encoder,
507                        id: node_id) {
508     ebml_w.start_tag(tag_items_data_item_symbol);
509     ebml_w.writer.write(str::to_bytes(**ecx.discrim_symbols.get(&id)));
510     ebml_w.end_tag();
511 }
512
513 #[cfg(not(stage0))]
514 fn encode_discriminant(ecx: @EncodeContext,
515                        ebml_w: &mut writer::Encoder,
516                        id: node_id) {
517     ebml_w.start_tag(tag_items_data_item_symbol);
518     ebml_w.writer.write(str::to_bytes(**ecx.discrim_symbols.get(&id)));
519     ebml_w.end_tag();
520 }
521
522 #[cfg(stage0)]
523 fn encode_disr_val(_: @EncodeContext,
524                    ebml_w: &writer::Encoder,
525                    disr_val: int) {
526     ebml_w.start_tag(tag_disr_val);
527     ebml_w.writer.write(str::to_bytes(int::to_str(disr_val)));
528     ebml_w.end_tag();
529 }
530
531 #[cfg(not(stage0))]
532 fn encode_disr_val(_: @EncodeContext,
533                    ebml_w: &mut writer::Encoder,
534                    disr_val: int) {
535     ebml_w.start_tag(tag_disr_val);
536     ebml_w.writer.write(str::to_bytes(int::to_str(disr_val)));
537     ebml_w.end_tag();
538 }
539
540 #[cfg(stage0)]
541 fn encode_parent_item(ebml_w: &writer::Encoder, id: def_id) {
542     ebml_w.start_tag(tag_items_data_parent_item);
543     ebml_w.writer.write(str::to_bytes(def_to_str(id)));
544     ebml_w.end_tag();
545 }
546
547 #[cfg(not(stage0))]
548 fn encode_parent_item(ebml_w: &mut writer::Encoder, id: def_id) {
549     ebml_w.start_tag(tag_items_data_parent_item);
550     ebml_w.writer.write(str::to_bytes(def_to_str(id)));
551     ebml_w.end_tag();
552 }
553
554 #[cfg(stage0)]
555 fn encode_enum_variant_info(ecx: @EncodeContext,
556                             ebml_w: &writer::Encoder,
557                             id: node_id,
558                             variants: &[variant],
559                             path: &[ast_map::path_elt],
560                             index: @mut ~[entry<int>],
561                             generics: &ast::Generics) {
562     debug!("encode_enum_variant_info(id=%?)", id);
563
564     let mut disr_val = 0;
565     let mut i = 0;
566     let vi = ty::enum_variants(ecx.tcx,
567                                ast::def_id { crate: local_crate, node: id });
568     for variants.each |variant| {
569         index.push(entry {val: variant.node.id, pos: ebml_w.writer.tell()});
570         ebml_w.start_tag(tag_items_data_item);
571         encode_def_id(ebml_w, local_def(variant.node.id));
572         encode_family(ebml_w, 'v');
573         encode_name(ecx, ebml_w, variant.node.name);
574         encode_parent_item(ebml_w, local_def(id));
575         encode_type(ecx, ebml_w,
576                     node_id_to_type(ecx.tcx, variant.node.id));
577         match variant.node.kind {
578             ast::tuple_variant_kind(ref args)
579                     if args.len() > 0 && generics.ty_params.len() == 0 => {
580                 encode_symbol(ecx, ebml_w, variant.node.id);
581             }
582             ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) => {}
583         }
584         encode_discriminant(ecx, ebml_w, variant.node.id);
585         if vi[i].disr_val != disr_val {
586             encode_disr_val(ecx, ebml_w, vi[i].disr_val);
587             disr_val = vi[i].disr_val;
588         }
589         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
590         encode_path(ecx, ebml_w, path,
591                     ast_map::path_name(variant.node.name));
592         ebml_w.end_tag();
593         disr_val += 1;
594         i += 1;
595     }
596 }
597
598 #[cfg(not(stage0))]
599 fn encode_enum_variant_info(ecx: @EncodeContext,
600                             ebml_w: &mut writer::Encoder,
601                             id: node_id,
602                             variants: &[variant],
603                             path: &[ast_map::path_elt],
604                             index: @mut ~[entry<int>],
605                             generics: &ast::Generics) {
606     debug!("encode_enum_variant_info(id=%?)", id);
607
608     let mut disr_val = 0;
609     let mut i = 0;
610     let vi = ty::enum_variants(ecx.tcx,
611                                ast::def_id { crate: local_crate, node: id });
612     for variants.each |variant| {
613         index.push(entry {val: variant.node.id, pos: ebml_w.writer.tell()});
614         ebml_w.start_tag(tag_items_data_item);
615         encode_def_id(ebml_w, local_def(variant.node.id));
616         encode_family(ebml_w, 'v');
617         encode_name(ecx, ebml_w, variant.node.name);
618         encode_parent_item(ebml_w, local_def(id));
619         encode_type(ecx, ebml_w,
620                     node_id_to_type(ecx.tcx, variant.node.id));
621         match variant.node.kind {
622             ast::tuple_variant_kind(ref args)
623                     if args.len() > 0 && generics.ty_params.len() == 0 => {
624                 encode_symbol(ecx, ebml_w, variant.node.id);
625             }
626             ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) => {}
627         }
628         encode_discriminant(ecx, ebml_w, variant.node.id);
629         if vi[i].disr_val != disr_val {
630             encode_disr_val(ecx, ebml_w, vi[i].disr_val);
631             disr_val = vi[i].disr_val;
632         }
633         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
634         encode_path(ecx, ebml_w, path,
635                     ast_map::path_name(variant.node.name));
636         ebml_w.end_tag();
637         disr_val += 1;
638         i += 1;
639     }
640 }
641
642 #[cfg(stage0)]
643 fn encode_path(ecx: @EncodeContext,
644                ebml_w: &writer::Encoder,
645                path: &[ast_map::path_elt],
646                name: ast_map::path_elt) {
647     fn encode_path_elt(ecx: @EncodeContext, ebml_w: &writer::Encoder,
648                        elt: ast_map::path_elt) {
649         let (tag, name) = match elt {
650           ast_map::path_mod(name) => (tag_path_elt_mod, name),
651           ast_map::path_name(name) => (tag_path_elt_name, name)
652         };
653
654         ebml_w.wr_tagged_str(tag, *ecx.tcx.sess.str_of(name));
655     }
656
657     do ebml_w.wr_tag(tag_path) {
658         ebml_w.wr_tagged_u32(tag_path_len, (path.len() + 1) as u32);
659         for path.each |pe| {
660             encode_path_elt(ecx, ebml_w, *pe);
661         }
662         encode_path_elt(ecx, ebml_w, name);
663     }
664 }
665
666 #[cfg(not(stage0))]
667 fn encode_path(ecx: @EncodeContext,
668                ebml_w: &mut writer::Encoder,
669                path: &[ast_map::path_elt],
670                name: ast_map::path_elt) {
671     fn encode_path_elt(ecx: @EncodeContext,
672                        ebml_w: &mut writer::Encoder,
673                        elt: ast_map::path_elt) {
674         let (tag, name) = match elt {
675           ast_map::path_mod(name) => (tag_path_elt_mod, name),
676           ast_map::path_name(name) => (tag_path_elt_name, name)
677         };
678
679         ebml_w.wr_tagged_str(tag, *ecx.tcx.sess.str_of(name));
680     }
681
682     ebml_w.start_tag(tag_path);
683     ebml_w.wr_tagged_u32(tag_path_len, (path.len() + 1) as u32);
684     for path.each |pe| {
685         encode_path_elt(ecx, ebml_w, *pe);
686     }
687     encode_path_elt(ecx, ebml_w, name);
688     ebml_w.end_tag();
689 }
690
691 #[cfg(stage0)]
692 fn encode_info_for_mod(ecx: @EncodeContext,
693                        ebml_w: &writer::Encoder,
694                        md: &_mod,
695                        id: node_id,
696                        path: &[ast_map::path_elt],
697                        name: ident) {
698     ebml_w.start_tag(tag_items_data_item);
699     encode_def_id(ebml_w, local_def(id));
700     encode_family(ebml_w, 'm');
701     encode_name(ecx, ebml_w, name);
702     debug!("(encoding info for module) encoding info for module ID %d", id);
703
704     // Encode info about all the module children.
705     for md.items.each |item| {
706         match item.node {
707             item_impl(*) => {
708                 let (ident, did) = (item.ident, item.id);
709                 debug!("(encoding info for module) ... encoding impl %s \
710                         (%?/%?)",
711                         *ecx.tcx.sess.str_of(ident),
712                         did,
713                         ast_map::node_id_to_str(ecx.tcx.items, did, ecx.tcx
714                                                 .sess.parse_sess.interner));
715
716                 ebml_w.start_tag(tag_mod_impl);
717                 ebml_w.wr_str(def_to_str(local_def(did)));
718                 ebml_w.end_tag();
719             }
720             _ => {} // FIXME #4573: Encode these too.
721         }
722     }
723
724     encode_path(ecx, ebml_w, path, ast_map::path_mod(name));
725
726     // Encode the reexports of this module.
727     debug!("(encoding info for module) encoding reexports for %d", id);
728     match ecx.reexports2.find(&id) {
729         Some(ref exports) => {
730             debug!("(encoding info for module) found reexports for %d", id);
731             for exports.each |exp| {
732                 debug!("(encoding info for module) reexport '%s' for %d",
733                        *exp.name, id);
734                 ebml_w.start_tag(tag_items_data_item_reexport);
735                 ebml_w.start_tag(tag_items_data_item_reexport_def_id);
736                 ebml_w.wr_str(def_to_str(exp.def_id));
737                 ebml_w.end_tag();
738                 ebml_w.start_tag(tag_items_data_item_reexport_name);
739                 ebml_w.wr_str(*exp.name);
740                 ebml_w.end_tag();
741                 ebml_w.end_tag();
742             }
743         }
744         None => {
745             debug!("(encoding info for module) found no reexports for %d",
746                    id);
747         }
748     }
749
750     ebml_w.end_tag();
751 }
752
753 #[cfg(not(stage0))]
754 fn encode_info_for_mod(ecx: @EncodeContext,
755                        ebml_w: &mut writer::Encoder,
756                        md: &_mod,
757                        id: node_id,
758                        path: &[ast_map::path_elt],
759                        name: ident) {
760     ebml_w.start_tag(tag_items_data_item);
761     encode_def_id(ebml_w, local_def(id));
762     encode_family(ebml_w, 'm');
763     encode_name(ecx, ebml_w, name);
764     debug!("(encoding info for module) encoding info for module ID %d", id);
765
766     // Encode info about all the module children.
767     for md.items.each |item| {
768         match item.node {
769             item_impl(*) => {
770                 let (ident, did) = (item.ident, item.id);
771                 debug!("(encoding info for module) ... encoding impl %s \
772                         (%?/%?)",
773                         *ecx.tcx.sess.str_of(ident),
774                         did,
775                         ast_map::node_id_to_str(ecx.tcx.items, did, ecx.tcx
776                                                 .sess.parse_sess.interner));
777
778                 ebml_w.start_tag(tag_mod_impl);
779                 ebml_w.wr_str(def_to_str(local_def(did)));
780                 ebml_w.end_tag();
781             }
782             _ => {} // FIXME #4573: Encode these too.
783         }
784     }
785
786     encode_path(ecx, ebml_w, path, ast_map::path_mod(name));
787
788     // Encode the reexports of this module.
789     debug!("(encoding info for module) encoding reexports for %d", id);
790     match ecx.reexports2.find(&id) {
791         Some(ref exports) => {
792             debug!("(encoding info for module) found reexports for %d", id);
793             for exports.each |exp| {
794                 debug!("(encoding info for module) reexport '%s' for %d",
795                        *exp.name, id);
796                 ebml_w.start_tag(tag_items_data_item_reexport);
797                 ebml_w.start_tag(tag_items_data_item_reexport_def_id);
798                 ebml_w.wr_str(def_to_str(exp.def_id));
799                 ebml_w.end_tag();
800                 ebml_w.start_tag(tag_items_data_item_reexport_name);
801                 ebml_w.wr_str(*exp.name);
802                 ebml_w.end_tag();
803                 ebml_w.end_tag();
804             }
805         }
806         None => {
807             debug!("(encoding info for module) found no reexports for %d",
808                    id);
809         }
810     }
811
812     ebml_w.end_tag();
813 }
814
815 #[cfg(stage0)]
816 fn encode_struct_field_family(ebml_w: &writer::Encoder,
817                               visibility: visibility) {
818     encode_family(ebml_w, match visibility {
819         public => 'g',
820         private => 'j',
821         inherited => 'N'
822     });
823 }
824
825 #[cfg(not(stage0))]
826 fn encode_struct_field_family(ebml_w: &mut writer::Encoder,
827                               visibility: visibility) {
828     encode_family(ebml_w, match visibility {
829         public => 'g',
830         private => 'j',
831         inherited => 'N'
832     });
833 }
834
835 #[cfg(stage0)]
836 fn encode_visibility(ebml_w: &writer::Encoder, visibility: visibility) {
837     ebml_w.start_tag(tag_items_data_item_visibility);
838     let ch = match visibility {
839         public => 'y',
840         private => 'n',
841         inherited => 'i',
842     };
843     ebml_w.wr_str(str::from_char(ch));
844     ebml_w.end_tag();
845 }
846
847 #[cfg(not(stage0))]
848 fn encode_visibility(ebml_w: &mut writer::Encoder, visibility: visibility) {
849     ebml_w.start_tag(tag_items_data_item_visibility);
850     let ch = match visibility {
851         public => 'y',
852         private => 'n',
853         inherited => 'i',
854     };
855     ebml_w.wr_str(str::from_char(ch));
856     ebml_w.end_tag();
857 }
858
859 #[cfg(stage0)]
860 fn encode_self_type(ebml_w: &writer::Encoder, self_type: ast::self_ty_) {
861     ebml_w.start_tag(tag_item_trait_method_self_ty);
862
863     // Encode the base self type.
864     match self_type {
865         sty_static => {
866             ebml_w.writer.write(&[ 's' as u8 ]);
867         }
868         sty_value => {
869             ebml_w.writer.write(&[ 'v' as u8 ]);
870         }
871         sty_region(_, m) => {
872             // FIXME(#4846) encode custom lifetime
873             ebml_w.writer.write(&[ '&' as u8 ]);
874             encode_mutability(ebml_w, m);
875         }
876         sty_box(m) => {
877             ebml_w.writer.write(&[ '@' as u8 ]);
878             encode_mutability(ebml_w, m);
879         }
880         sty_uniq(m) => {
881             ebml_w.writer.write(&[ '~' as u8 ]);
882             encode_mutability(ebml_w, m);
883         }
884     }
885
886     ebml_w.end_tag();
887
888     fn encode_mutability(ebml_w: &writer::Encoder,
889                          m: ast::mutability) {
890         match m {
891             m_imm => {
892                 ebml_w.writer.write(&[ 'i' as u8 ]);
893             }
894             m_mutbl => {
895                 ebml_w.writer.write(&[ 'm' as u8 ]);
896             }
897             m_const => {
898                 ebml_w.writer.write(&[ 'c' as u8 ]);
899             }
900         }
901     }
902 }
903
904 #[cfg(not(stage0))]
905 fn encode_self_type(ebml_w: &mut writer::Encoder, self_type: ast::self_ty_) {
906     ebml_w.start_tag(tag_item_trait_method_self_ty);
907
908     // Encode the base self type.
909     match self_type {
910         sty_static => {
911             ebml_w.writer.write(&[ 's' as u8 ]);
912         }
913         sty_value => {
914             ebml_w.writer.write(&[ 'v' as u8 ]);
915         }
916         sty_region(_, m) => {
917             // FIXME(#4846) encode custom lifetime
918             ebml_w.writer.write(&[ '&' as u8 ]);
919             encode_mutability(ebml_w, m);
920         }
921         sty_box(m) => {
922             ebml_w.writer.write(&[ '@' as u8 ]);
923             encode_mutability(ebml_w, m);
924         }
925         sty_uniq(m) => {
926             ebml_w.writer.write(&[ '~' as u8 ]);
927             encode_mutability(ebml_w, m);
928         }
929     }
930
931     ebml_w.end_tag();
932
933     fn encode_mutability(ebml_w: &writer::Encoder,
934                          m: ast::mutability) {
935         match m {
936             m_imm => {
937                 ebml_w.writer.write(&[ 'i' as u8 ]);
938             }
939             m_mutbl => {
940                 ebml_w.writer.write(&[ 'm' as u8 ]);
941             }
942             m_const => {
943                 ebml_w.writer.write(&[ 'c' as u8 ]);
944             }
945         }
946     }
947 }
948
949 #[cfg(stage0)]
950 fn encode_method_sort(ebml_w: &writer::Encoder, sort: char) {
951     ebml_w.start_tag(tag_item_trait_method_sort);
952     ebml_w.writer.write(&[ sort as u8 ]);
953     ebml_w.end_tag();
954 }
955
956 #[cfg(not(stage0))]
957 fn encode_method_sort(ebml_w: &mut writer::Encoder, sort: char) {
958     ebml_w.start_tag(tag_item_trait_method_sort);
959     ebml_w.writer.write(&[ sort as u8 ]);
960     ebml_w.end_tag();
961 }
962
963 /* Returns an index of items in this class */
964 #[cfg(stage0)]
965 fn encode_info_for_struct(ecx: @EncodeContext,
966                           ebml_w: &writer::Encoder,
967                           path: &[ast_map::path_elt],
968                           fields: &[@struct_field],
969                           global_index: @mut~[entry<int>])
970                           -> ~[entry<int>] {
971     /* Each class has its own index, since different classes
972        may have fields with the same name */
973     let index = @mut ~[];
974     let tcx = ecx.tcx;
975      /* We encode both private and public fields -- need to include
976         private fields to get the offsets right */
977     for fields.each |field| {
978         let (nm, mt, vis) = match field.node.kind {
979             named_field(nm, mt, vis) => (nm, mt, vis),
980             unnamed_field => (
981                 special_idents::unnamed_field,
982                 struct_immutable,
983                 inherited
984             )
985         };
986
987         let id = field.node.id;
988         index.push(entry {val: id, pos: ebml_w.writer.tell()});
989         global_index.push(entry {val: id, pos: ebml_w.writer.tell()});
990         ebml_w.start_tag(tag_items_data_item);
991         debug!("encode_info_for_struct: doing %s %d",
992                *tcx.sess.str_of(nm), id);
993         encode_struct_field_family(ebml_w, vis);
994         encode_name(ecx, ebml_w, nm);
995         encode_path(ecx, ebml_w, path, ast_map::path_name(nm));
996         encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
997         encode_mutability(ebml_w, mt);
998         encode_def_id(ebml_w, local_def(id));
999         ebml_w.end_tag();
1000     }
1001     /*bad*/copy *index
1002 }
1003
1004 #[cfg(not(stage0))]
1005 fn encode_info_for_struct(ecx: @EncodeContext,
1006                           ebml_w: &mut writer::Encoder,
1007                           path: &[ast_map::path_elt],
1008                           fields: &[@struct_field],
1009                           global_index: @mut ~[entry<int>])
1010                           -> ~[entry<int>] {
1011     /* Each class has its own index, since different classes
1012        may have fields with the same name */
1013     let index = @mut ~[];
1014     let tcx = ecx.tcx;
1015      /* We encode both private and public fields -- need to include
1016         private fields to get the offsets right */
1017     for fields.each |field| {
1018         let (nm, mt, vis) = match field.node.kind {
1019             named_field(nm, mt, vis) => (nm, mt, vis),
1020             unnamed_field => (
1021                 special_idents::unnamed_field,
1022                 struct_immutable,
1023                 inherited
1024             )
1025         };
1026
1027         let id = field.node.id;
1028         index.push(entry {val: id, pos: ebml_w.writer.tell()});
1029         global_index.push(entry {val: id, pos: ebml_w.writer.tell()});
1030         ebml_w.start_tag(tag_items_data_item);
1031         debug!("encode_info_for_struct: doing %s %d",
1032                *tcx.sess.str_of(nm), id);
1033         encode_struct_field_family(ebml_w, vis);
1034         encode_name(ecx, ebml_w, nm);
1035         encode_path(ecx, ebml_w, path, ast_map::path_name(nm));
1036         encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
1037         encode_mutability(ebml_w, mt);
1038         encode_def_id(ebml_w, local_def(id));
1039         ebml_w.end_tag();
1040     }
1041     /*bad*/copy *index
1042 }
1043
1044 // This is for encoding info for ctors and dtors
1045 #[cfg(stage0)]
1046 fn encode_info_for_ctor(ecx: @EncodeContext,
1047                         ebml_w: &writer::Encoder,
1048                         id: node_id,
1049                         ident: ident,
1050                         path: &[ast_map::path_elt],
1051                         item: Option<inlined_item>,
1052                         generics: &ast::Generics) {
1053         ebml_w.start_tag(tag_items_data_item);
1054         encode_name(ecx, ebml_w, ident);
1055         encode_def_id(ebml_w, local_def(id));
1056         encode_family(ebml_w, purity_fn_family(ast::impure_fn));
1057         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1058         let its_ty = node_id_to_type(ecx.tcx, id);
1059         debug!("fn name = %s ty = %s its node id = %d",
1060                *ecx.tcx.sess.str_of(ident),
1061                ty_to_str(ecx.tcx, its_ty), id);
1062         encode_type(ecx, ebml_w, its_ty);
1063         encode_path(ecx, ebml_w, path, ast_map::path_name(ident));
1064         match item {
1065            Some(it) => {
1066              (ecx.encode_inlined_item)(ecx, ebml_w, path, it);
1067            }
1068            None => {
1069              encode_symbol(ecx, ebml_w, id);
1070            }
1071         }
1072         ebml_w.end_tag();
1073 }
1074
1075 #[cfg(not(stage0))]
1076 fn encode_info_for_ctor(ecx: @EncodeContext,
1077                         ebml_w: &mut writer::Encoder,
1078                         id: node_id,
1079                         ident: ident,
1080                         path: &[ast_map::path_elt],
1081                         item: Option<inlined_item>,
1082                         generics: &ast::Generics) {
1083         ebml_w.start_tag(tag_items_data_item);
1084         encode_name(ecx, ebml_w, ident);
1085         encode_def_id(ebml_w, local_def(id));
1086         encode_family(ebml_w, purity_fn_family(ast::impure_fn));
1087         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1088         let its_ty = node_id_to_type(ecx.tcx, id);
1089         debug!("fn name = %s ty = %s its node id = %d",
1090                *ecx.tcx.sess.str_of(ident),
1091                ty_to_str(ecx.tcx, its_ty), id);
1092         encode_type(ecx, ebml_w, its_ty);
1093         encode_path(ecx, ebml_w, path, ast_map::path_name(ident));
1094         match item {
1095            Some(it) => {
1096              (ecx.encode_inlined_item)(ecx, ebml_w, path, it);
1097            }
1098            None => {
1099              encode_symbol(ecx, ebml_w, id);
1100            }
1101         }
1102         ebml_w.end_tag();
1103 }
1104
1105 #[cfg(stage0)]
1106 fn encode_info_for_struct_ctor(ecx: @EncodeContext,
1107                                ebml_w: &writer::Encoder,
1108                                path: &[ast_map::path_elt],
1109                                name: ast::ident,
1110                                ctor_id: node_id,
1111                                index: @mut ~[entry<int>]) {
1112     index.push(entry { val: ctor_id, pos: ebml_w.writer.tell() });
1113
1114     ebml_w.start_tag(tag_items_data_item);
1115     encode_def_id(ebml_w, local_def(ctor_id));
1116     encode_family(ebml_w, 'f');
1117     encode_name(ecx, ebml_w, name);
1118     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, ctor_id));
1119     encode_path(ecx, ebml_w, path, ast_map::path_name(name));
1120
1121     if ecx.item_symbols.contains_key(&ctor_id) {
1122         encode_symbol(ecx, ebml_w, ctor_id);
1123     }
1124
1125     ebml_w.end_tag();
1126 }
1127
1128 #[cfg(not(stage0))]
1129 fn encode_info_for_struct_ctor(ecx: @EncodeContext,
1130                                ebml_w: &mut writer::Encoder,
1131                                path: &[ast_map::path_elt],
1132                                name: ast::ident,
1133                                ctor_id: node_id,
1134                                index: @mut ~[entry<int>]) {
1135     index.push(entry { val: ctor_id, pos: ebml_w.writer.tell() });
1136
1137     ebml_w.start_tag(tag_items_data_item);
1138     encode_def_id(ebml_w, local_def(ctor_id));
1139     encode_family(ebml_w, 'f');
1140     encode_name(ecx, ebml_w, name);
1141     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, ctor_id));
1142     encode_path(ecx, ebml_w, path, ast_map::path_name(name));
1143
1144     if ecx.item_symbols.contains_key(&ctor_id) {
1145         encode_symbol(ecx, ebml_w, ctor_id);
1146     }
1147
1148     ebml_w.end_tag();
1149 }
1150
1151 #[cfg(stage0)]
1152 fn encode_method_ty_fields(ecx: @EncodeContext,
1153                            ebml_w: &writer::Encoder,
1154                            method_ty: &ty::method) {
1155     encode_def_id(ebml_w, method_ty.def_id);
1156     encode_name(ecx, ebml_w, method_ty.ident);
1157     encode_ty_type_param_defs(ebml_w, ecx,
1158                               method_ty.generics.type_param_defs,
1159                               tag_item_method_tps);
1160     encode_transformed_self_ty(ecx, ebml_w, method_ty.transformed_self_ty);
1161     encode_method_fty(ecx, ebml_w, &method_ty.fty);
1162     encode_visibility(ebml_w, method_ty.vis);
1163     encode_self_type(ebml_w, method_ty.self_ty);
1164 }
1165
1166 #[cfg(not(stage0))]
1167 fn encode_method_ty_fields(ecx: @EncodeContext,
1168                            ebml_w: &mut writer::Encoder,
1169                            method_ty: &ty::method) {
1170     encode_def_id(ebml_w, method_ty.def_id);
1171     encode_name(ecx, ebml_w, method_ty.ident);
1172     encode_ty_type_param_defs(ebml_w, ecx,
1173                               method_ty.generics.type_param_defs,
1174                               tag_item_method_tps);
1175     encode_transformed_self_ty(ecx, ebml_w, method_ty.transformed_self_ty);
1176     encode_method_fty(ecx, ebml_w, &method_ty.fty);
1177     encode_visibility(ebml_w, method_ty.vis);
1178     encode_self_type(ebml_w, method_ty.self_ty);
1179 }
1180
1181 #[cfg(stage0)]
1182 fn encode_info_for_method(ecx: @EncodeContext,
1183                           ebml_w: &writer::Encoder,
1184                           impl_path: &[ast_map::path_elt],
1185                           should_inline: bool,
1186                           parent_id: node_id,
1187                           m: @method,
1188                           owner_generics: &ast::Generics,
1189                           method_generics: &ast::Generics) {
1190     debug!("encode_info_for_method: %d %s %u %u", m.id,
1191            *ecx.tcx.sess.str_of(m.ident),
1192            owner_generics.ty_params.len(),
1193            method_generics.ty_params.len());
1194     ebml_w.start_tag(tag_items_data_item);
1195
1196     let method_def_id = local_def(m.id);
1197     let method_ty: @ty::method = ty::method(ecx.tcx, method_def_id);
1198     encode_method_ty_fields(ecx, ebml_w, method_ty);
1199
1200     match m.self_ty.node {
1201         ast::sty_static => {
1202             encode_family(ebml_w, purity_static_method_family(m.purity));
1203         }
1204         _ => encode_family(ebml_w, purity_fn_family(m.purity))
1205     }
1206
1207     let mut combined_ty_params = opt_vec::Empty;
1208     combined_ty_params.push_all(&owner_generics.ty_params);
1209     combined_ty_params.push_all(&method_generics.ty_params);
1210     let len = combined_ty_params.len();
1211     encode_type_param_bounds(ebml_w, ecx, &combined_ty_params);
1212
1213     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id));
1214     encode_path(ecx, ebml_w, impl_path, ast_map::path_name(m.ident));
1215
1216     if len > 0u || should_inline {
1217         (ecx.encode_inlined_item)(
1218            ecx, ebml_w, impl_path,
1219            ii_method(local_def(parent_id), m));
1220     } else {
1221         encode_symbol(ecx, ebml_w, m.id);
1222     }
1223
1224     ebml_w.end_tag();
1225 }
1226
1227 #[cfg(not(stage0))]
1228 fn encode_info_for_method(ecx: @EncodeContext,
1229                           ebml_w: &mut writer::Encoder,
1230                           impl_path: &[ast_map::path_elt],
1231                           should_inline: bool,
1232                           parent_id: node_id,
1233                           m: @method,
1234                           owner_generics: &ast::Generics,
1235                           method_generics: &ast::Generics) {
1236     debug!("encode_info_for_method: %d %s %u %u", m.id,
1237            *ecx.tcx.sess.str_of(m.ident),
1238            owner_generics.ty_params.len(),
1239            method_generics.ty_params.len());
1240     ebml_w.start_tag(tag_items_data_item);
1241
1242     let method_def_id = local_def(m.id);
1243     let method_ty: @ty::method = ty::method(ecx.tcx, method_def_id);
1244     encode_method_ty_fields(ecx, ebml_w, method_ty);
1245
1246     match m.self_ty.node {
1247         ast::sty_static => {
1248             encode_family(ebml_w, purity_static_method_family(m.purity));
1249         }
1250         _ => encode_family(ebml_w, purity_fn_family(m.purity))
1251     }
1252
1253     let mut combined_ty_params = opt_vec::Empty;
1254     combined_ty_params.push_all(&owner_generics.ty_params);
1255     combined_ty_params.push_all(&method_generics.ty_params);
1256     let len = combined_ty_params.len();
1257     encode_type_param_bounds(ebml_w, ecx, &combined_ty_params);
1258
1259     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id));
1260     encode_path(ecx, ebml_w, impl_path, ast_map::path_name(m.ident));
1261
1262     if len > 0u || should_inline {
1263         (ecx.encode_inlined_item)(
1264            ecx, ebml_w, impl_path,
1265            ii_method(local_def(parent_id), m));
1266     } else {
1267         encode_symbol(ecx, ebml_w, m.id);
1268     }
1269
1270     ebml_w.end_tag();
1271 }
1272
1273 fn purity_fn_family(p: purity) -> char {
1274     match p {
1275       unsafe_fn => 'u',
1276       pure_fn => 'p',
1277       impure_fn => 'f',
1278       extern_fn => 'e'
1279     }
1280 }
1281
1282 fn purity_static_method_family(p: purity) -> char {
1283     match p {
1284       unsafe_fn => 'U',
1285       pure_fn => 'P',
1286       impure_fn => 'F',
1287       _ => fail!(~"extern fn can't be static")
1288     }
1289 }
1290
1291
1292 fn should_inline(attrs: &[attribute]) -> bool {
1293     match attr::find_inline_attr(attrs) {
1294         attr::ia_none | attr::ia_never  => false,
1295         attr::ia_hint | attr::ia_always => true
1296     }
1297 }
1298
1299 #[cfg(stage0)]
1300 fn encode_info_for_item(ecx: @EncodeContext,
1301                         ebml_w: &writer::Encoder,
1302                         item: @item,
1303                         index: @mut ~[entry<int>],
1304                         path: &[ast_map::path_elt]) {
1305     let tcx = ecx.tcx;
1306     let must_write =
1307         match item.node {
1308           item_enum(_, _) | item_impl(*) | item_trait(*) | item_struct(*) |
1309           item_mod(*) | item_foreign_mod(*) | item_const(*) => true,
1310           _ => false
1311         };
1312     if !must_write && !reachable(ecx, item.id) { return; }
1313
1314     fn add_to_index_(item: @item, ebml_w: &writer::Encoder,
1315                      index: @mut ~[entry<int>]) {
1316         index.push(entry { val: item.id, pos: ebml_w.writer.tell() });
1317     }
1318     let add_to_index: &fn() = || add_to_index_(item, ebml_w, index);
1319
1320     debug!("encoding info for item at %s",
1321            ecx.tcx.sess.codemap.span_to_str(item.span));
1322
1323     match item.node {
1324       item_const(_, _) => {
1325         add_to_index();
1326         ebml_w.start_tag(tag_items_data_item);
1327         encode_def_id(ebml_w, local_def(item.id));
1328         encode_family(ebml_w, 'c');
1329         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1330         encode_symbol(ecx, ebml_w, item.id);
1331         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1332         (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
1333         ebml_w.end_tag();
1334       }
1335       item_fn(_, purity, _, ref generics, _) => {
1336         add_to_index();
1337         ebml_w.start_tag(tag_items_data_item);
1338         encode_def_id(ebml_w, local_def(item.id));
1339         encode_family(ebml_w, purity_fn_family(purity));
1340         let tps_len = generics.ty_params.len();
1341         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1342         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1343         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1344         encode_attributes(ebml_w, item.attrs);
1345         if tps_len > 0u || should_inline(item.attrs) {
1346             (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
1347         } else {
1348             encode_symbol(ecx, ebml_w, item.id);
1349         }
1350         ebml_w.end_tag();
1351       }
1352       item_mod(ref m) => {
1353         add_to_index();
1354         encode_info_for_mod(ecx, ebml_w, m, item.id, path, item.ident);
1355       }
1356       item_foreign_mod(_) => {
1357         add_to_index();
1358         ebml_w.start_tag(tag_items_data_item);
1359         encode_def_id(ebml_w, local_def(item.id));
1360         encode_family(ebml_w, 'n');
1361         encode_name(ecx, ebml_w, item.ident);
1362         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1363         ebml_w.end_tag();
1364       }
1365       item_ty(_, ref generics) => {
1366         add_to_index();
1367         ebml_w.start_tag(tag_items_data_item);
1368         encode_def_id(ebml_w, local_def(item.id));
1369         encode_family(ebml_w, 'y');
1370         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1371         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1372         encode_name(ecx, ebml_w, item.ident);
1373         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1374         encode_region_param(ecx, ebml_w, item);
1375         ebml_w.end_tag();
1376       }
1377       item_enum(ref enum_definition, ref generics) => {
1378         add_to_index();
1379         do ebml_w.wr_tag(tag_items_data_item) {
1380             encode_def_id(ebml_w, local_def(item.id));
1381             encode_family(ebml_w, 't');
1382             encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1383             encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1384             encode_name(ecx, ebml_w, item.ident);
1385             for (*enum_definition).variants.each |v| {
1386                 encode_variant_id(ebml_w, local_def(v.node.id));
1387             }
1388             (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
1389             encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1390             encode_region_param(ecx, ebml_w, item);
1391         }
1392         encode_enum_variant_info(ecx,
1393                                  ebml_w,
1394                                  item.id,
1395                                  (*enum_definition).variants,
1396                                  path,
1397                                  index,
1398                                  generics);
1399       }
1400       item_struct(struct_def, ref generics) => {
1401         /* First, encode the fields
1402            These come first because we need to write them to make
1403            the index, and the index needs to be in the item for the
1404            class itself */
1405         let idx = encode_info_for_struct(ecx, ebml_w, path,
1406                                          struct_def.fields, index);
1407
1408         /* Index the class*/
1409         add_to_index();
1410
1411         /* Now, make an item for the class itself */
1412         ebml_w.start_tag(tag_items_data_item);
1413         encode_def_id(ebml_w, local_def(item.id));
1414         encode_family(ebml_w, 'S');
1415         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1416         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1417
1418         // If this is a tuple- or enum-like struct, encode the type of the
1419         // constructor.
1420         if struct_def.fields.len() > 0 &&
1421                 struct_def.fields[0].node.kind == ast::unnamed_field {
1422             let ctor_id = match struct_def.ctor_id {
1423                 Some(ctor_id) => ctor_id,
1424                 None => ecx.tcx.sess.bug(~"struct def didn't have ctor id"),
1425             };
1426
1427             encode_info_for_struct_ctor(ecx,
1428                                         ebml_w,
1429                                         path,
1430                                         item.ident,
1431                                         ctor_id,
1432                                         index);
1433         }
1434
1435         encode_name(ecx, ebml_w, item.ident);
1436         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1437         encode_region_param(ecx, ebml_w, item);
1438
1439         /* Encode def_ids for each field and method
1440          for methods, write all the stuff get_trait_method
1441         needs to know*/
1442         for struct_def.fields.each |f| {
1443             match f.node.kind {
1444                 named_field(ident, _, vis) => {
1445                    ebml_w.start_tag(tag_item_field);
1446                    encode_struct_field_family(ebml_w, vis);
1447                    encode_name(ecx, ebml_w, ident);
1448                    encode_def_id(ebml_w, local_def(f.node.id));
1449                    ebml_w.end_tag();
1450                 }
1451                 unnamed_field => {
1452                     ebml_w.start_tag(tag_item_unnamed_field);
1453                     encode_def_id(ebml_w, local_def(f.node.id));
1454                     ebml_w.end_tag();
1455                 }
1456             }
1457         }
1458
1459         /* Each class has its own index -- encode it */
1460         let bkts = create_index(idx);
1461         encode_index(ebml_w, bkts, write_int);
1462         ebml_w.end_tag();
1463       }
1464       item_impl(ref generics, opt_trait, ty, ref methods) => {
1465         add_to_index();
1466         ebml_w.start_tag(tag_items_data_item);
1467         encode_def_id(ebml_w, local_def(item.id));
1468         encode_family(ebml_w, 'i');
1469         encode_region_param(ecx, ebml_w, item);
1470         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1471         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1472         encode_name(ecx, ebml_w, item.ident);
1473         encode_attributes(ebml_w, item.attrs);
1474         match ty.node {
1475             ast::ty_path(path, _) if path.idents.len() == 1 => {
1476                 encode_impl_type_basename(ecx, ebml_w,
1477                                           ast_util::path_to_ident(path));
1478             }
1479             _ => {}
1480         }
1481         for methods.each |m| {
1482             ebml_w.start_tag(tag_item_impl_method);
1483             let method_def_id = local_def(m.id);
1484             ebml_w.writer.write(str::to_bytes(def_to_str(method_def_id)));
1485             ebml_w.end_tag();
1486         }
1487         for opt_trait.each |ast_trait_ref| {
1488             let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
1489             encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_trait_ref);
1490         }
1491         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1492         ebml_w.end_tag();
1493
1494         // >:-<
1495         let mut impl_path = vec::append(~[], path);
1496         impl_path += ~[ast_map::path_name(item.ident)];
1497
1498         for methods.each |m| {
1499             index.push(entry {val: m.id, pos: ebml_w.writer.tell()});
1500             encode_info_for_method(ecx,
1501                                    ebml_w,
1502                                    impl_path,
1503                                    should_inline(m.attrs),
1504                                    item.id,
1505                                    *m,
1506                                    generics,
1507                                    &m.generics);
1508         }
1509       }
1510       item_trait(ref generics, ref super_traits, ref ms) => {
1511         add_to_index();
1512         ebml_w.start_tag(tag_items_data_item);
1513         encode_def_id(ebml_w, local_def(item.id));
1514         encode_family(ebml_w, 'I');
1515         encode_region_param(ecx, ebml_w, item);
1516         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1517         let trait_def = ty::lookup_trait_def(tcx, local_def(item.id));
1518         encode_trait_ref(ebml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
1519         encode_name(ecx, ebml_w, item.ident);
1520         encode_attributes(ebml_w, item.attrs);
1521         for ty::trait_method_def_ids(tcx, local_def(item.id)).each |&method_def_id| {
1522             ebml_w.start_tag(tag_item_trait_method);
1523             encode_def_id(ebml_w, method_def_id);
1524             ebml_w.end_tag();
1525         }
1526         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1527         for super_traits.each |ast_trait_ref| {
1528             let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
1529             encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref);
1530         }
1531         ebml_w.end_tag();
1532
1533         // Now output the method info for each method.
1534         for ty::trait_method_def_ids(tcx, local_def(item.id)).eachi |i, &method_def_id| {
1535             assert!(method_def_id.crate == ast::local_crate);
1536
1537             let method_ty: @ty::method = ty::method(tcx, method_def_id);
1538
1539             index.push(entry {val: method_def_id.node, pos: ebml_w.writer.tell()});
1540
1541             ebml_w.start_tag(tag_items_data_item);
1542
1543             encode_method_ty_fields(ecx, ebml_w, method_ty);
1544
1545             encode_parent_item(ebml_w, local_def(item.id));
1546
1547             let mut trait_path = vec::append(~[], path);
1548             trait_path.push(ast_map::path_name(item.ident));
1549             encode_path(ecx, ebml_w, trait_path, ast_map::path_name(method_ty.ident));
1550
1551             match method_ty.self_ty {
1552                 sty_static => {
1553                     encode_family(ebml_w,
1554                                   purity_static_method_family(
1555                                       method_ty.fty.purity));
1556
1557                     let tpt = ty::lookup_item_type(tcx, method_def_id);
1558                     encode_ty_type_param_defs(ebml_w, ecx,
1559                                               tpt.generics.type_param_defs,
1560                                               tag_items_data_item_ty_param_bounds);
1561                     encode_type(ecx, ebml_w, tpt.ty);
1562                 }
1563
1564                 _ => {
1565                     encode_family(ebml_w,
1566                                   purity_fn_family(
1567                                       method_ty.fty.purity));
1568                 }
1569             }
1570
1571             match ms[i] {
1572                 required(_) => {
1573                     encode_method_sort(ebml_w, 'r');
1574                 }
1575
1576                 provided(m) => {
1577                     // This is obviously a bogus assert but I don't think this
1578                     // ever worked before anyhow...near as I can tell, before
1579                     // we would emit two items.
1580                     if method_ty.self_ty == sty_static {
1581                         tcx.sess.span_unimpl(
1582                             item.span,
1583                             fmt!("Method %s is both provided and static",
1584                                  *tcx.sess.intr().get(method_ty.ident)));
1585                     }
1586                     encode_type_param_bounds(ebml_w, ecx,
1587                                              &m.generics.ty_params);
1588                     encode_method_sort(ebml_w, 'p');
1589                     (ecx.encode_inlined_item)(
1590                         ecx, ebml_w, path,
1591                         ii_method(local_def(item.id), m));
1592                 }
1593             }
1594
1595             ebml_w.end_tag();
1596         }
1597       }
1598       item_mac(*) => fail!(~"item macros unimplemented")
1599     }
1600 }
1601
1602 #[cfg(not(stage0))]
1603 fn encode_info_for_item(ecx: @EncodeContext,
1604                         ebml_w: &mut writer::Encoder,
1605                         item: @item,
1606                         index: @mut ~[entry<int>],
1607                         path: &[ast_map::path_elt]) {
1608     let tcx = ecx.tcx;
1609     let must_write =
1610         match item.node {
1611           item_enum(_, _) | item_impl(*) | item_trait(*) | item_struct(*) |
1612           item_mod(*) | item_foreign_mod(*) | item_const(*) => true,
1613           _ => false
1614         };
1615     if !must_write && !reachable(ecx, item.id) { return; }
1616
1617     fn add_to_index_(item: @item, ebml_w: &writer::Encoder,
1618                      index: @mut ~[entry<int>]) {
1619         index.push(entry { val: item.id, pos: ebml_w.writer.tell() });
1620     }
1621     let add_to_index: &fn() = || add_to_index_(item, ebml_w, index);
1622
1623     debug!("encoding info for item at %s",
1624            ecx.tcx.sess.codemap.span_to_str(item.span));
1625
1626     match item.node {
1627       item_const(_, _) => {
1628         add_to_index();
1629         ebml_w.start_tag(tag_items_data_item);
1630         encode_def_id(ebml_w, local_def(item.id));
1631         encode_family(ebml_w, 'c');
1632         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1633         encode_symbol(ecx, ebml_w, item.id);
1634         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1635         (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
1636         ebml_w.end_tag();
1637       }
1638       item_fn(_, purity, _, ref generics, _) => {
1639         add_to_index();
1640         ebml_w.start_tag(tag_items_data_item);
1641         encode_def_id(ebml_w, local_def(item.id));
1642         encode_family(ebml_w, purity_fn_family(purity));
1643         let tps_len = generics.ty_params.len();
1644         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1645         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1646         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1647         encode_attributes(ebml_w, item.attrs);
1648         if tps_len > 0u || should_inline(item.attrs) {
1649             (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
1650         } else {
1651             encode_symbol(ecx, ebml_w, item.id);
1652         }
1653         ebml_w.end_tag();
1654       }
1655       item_mod(ref m) => {
1656         add_to_index();
1657         encode_info_for_mod(ecx, ebml_w, m, item.id, path, item.ident);
1658       }
1659       item_foreign_mod(_) => {
1660         add_to_index();
1661         ebml_w.start_tag(tag_items_data_item);
1662         encode_def_id(ebml_w, local_def(item.id));
1663         encode_family(ebml_w, 'n');
1664         encode_name(ecx, ebml_w, item.ident);
1665         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1666         ebml_w.end_tag();
1667       }
1668       item_ty(_, ref generics) => {
1669         add_to_index();
1670         ebml_w.start_tag(tag_items_data_item);
1671         encode_def_id(ebml_w, local_def(item.id));
1672         encode_family(ebml_w, 'y');
1673         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1674         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1675         encode_name(ecx, ebml_w, item.ident);
1676         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1677         encode_region_param(ecx, ebml_w, item);
1678         ebml_w.end_tag();
1679       }
1680       item_enum(ref enum_definition, ref generics) => {
1681         add_to_index();
1682
1683         ebml_w.start_tag(tag_items_data_item);
1684         encode_def_id(ebml_w, local_def(item.id));
1685         encode_family(ebml_w, 't');
1686         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1687         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1688         encode_name(ecx, ebml_w, item.ident);
1689         for (*enum_definition).variants.each |v| {
1690             encode_variant_id(ebml_w, local_def(v.node.id));
1691         }
1692         (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
1693         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1694         encode_region_param(ecx, ebml_w, item);
1695         ebml_w.end_tag();
1696
1697         encode_enum_variant_info(ecx,
1698                                  ebml_w,
1699                                  item.id,
1700                                  (*enum_definition).variants,
1701                                  path,
1702                                  index,
1703                                  generics);
1704       }
1705       item_struct(struct_def, ref generics) => {
1706         /* First, encode the fields
1707            These come first because we need to write them to make
1708            the index, and the index needs to be in the item for the
1709            class itself */
1710         let idx = encode_info_for_struct(ecx, ebml_w, path,
1711                                          struct_def.fields, index);
1712
1713         /* Index the class*/
1714         add_to_index();
1715
1716         /* Now, make an item for the class itself */
1717         ebml_w.start_tag(tag_items_data_item);
1718         encode_def_id(ebml_w, local_def(item.id));
1719         encode_family(ebml_w, 'S');
1720         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1721         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1722
1723         // If this is a tuple- or enum-like struct, encode the type of the
1724         // constructor.
1725         if struct_def.fields.len() > 0 &&
1726                 struct_def.fields[0].node.kind == ast::unnamed_field {
1727             let ctor_id = match struct_def.ctor_id {
1728                 Some(ctor_id) => ctor_id,
1729                 None => ecx.tcx.sess.bug(~"struct def didn't have ctor id"),
1730             };
1731
1732             encode_info_for_struct_ctor(ecx,
1733                                         ebml_w,
1734                                         path,
1735                                         item.ident,
1736                                         ctor_id,
1737                                         index);
1738         }
1739
1740         encode_name(ecx, ebml_w, item.ident);
1741         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1742         encode_region_param(ecx, ebml_w, item);
1743
1744         /* Encode def_ids for each field and method
1745          for methods, write all the stuff get_trait_method
1746         needs to know*/
1747         for struct_def.fields.each |f| {
1748             match f.node.kind {
1749                 named_field(ident, _, vis) => {
1750                    ebml_w.start_tag(tag_item_field);
1751                    encode_struct_field_family(ebml_w, vis);
1752                    encode_name(ecx, ebml_w, ident);
1753                    encode_def_id(ebml_w, local_def(f.node.id));
1754                    ebml_w.end_tag();
1755                 }
1756                 unnamed_field => {
1757                     ebml_w.start_tag(tag_item_unnamed_field);
1758                     encode_def_id(ebml_w, local_def(f.node.id));
1759                     ebml_w.end_tag();
1760                 }
1761             }
1762         }
1763
1764         /* Each class has its own index -- encode it */
1765         let bkts = create_index(idx);
1766         encode_index(ebml_w, bkts, write_int);
1767         ebml_w.end_tag();
1768       }
1769       item_impl(ref generics, opt_trait, ty, ref methods) => {
1770         add_to_index();
1771         ebml_w.start_tag(tag_items_data_item);
1772         encode_def_id(ebml_w, local_def(item.id));
1773         encode_family(ebml_w, 'i');
1774         encode_region_param(ecx, ebml_w, item);
1775         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1776         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
1777         encode_name(ecx, ebml_w, item.ident);
1778         encode_attributes(ebml_w, item.attrs);
1779         match ty.node {
1780             ast::ty_path(path, _) if path.idents.len() == 1 => {
1781                 encode_impl_type_basename(ecx, ebml_w,
1782                                           ast_util::path_to_ident(path));
1783             }
1784             _ => {}
1785         }
1786         for methods.each |m| {
1787             ebml_w.start_tag(tag_item_impl_method);
1788             let method_def_id = local_def(m.id);
1789             ebml_w.writer.write(str::to_bytes(def_to_str(method_def_id)));
1790             ebml_w.end_tag();
1791         }
1792         for opt_trait.each |ast_trait_ref| {
1793             let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
1794             encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_trait_ref);
1795         }
1796         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1797         ebml_w.end_tag();
1798
1799         // >:-<
1800         let mut impl_path = vec::append(~[], path);
1801         impl_path += ~[ast_map::path_name(item.ident)];
1802
1803         for methods.each |m| {
1804             index.push(entry {val: m.id, pos: ebml_w.writer.tell()});
1805             encode_info_for_method(ecx,
1806                                    ebml_w,
1807                                    impl_path,
1808                                    should_inline(m.attrs),
1809                                    item.id,
1810                                    *m,
1811                                    generics,
1812                                    &m.generics);
1813         }
1814       }
1815       item_trait(ref generics, ref super_traits, ref ms) => {
1816         add_to_index();
1817         ebml_w.start_tag(tag_items_data_item);
1818         encode_def_id(ebml_w, local_def(item.id));
1819         encode_family(ebml_w, 'I');
1820         encode_region_param(ecx, ebml_w, item);
1821         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1822         let trait_def = ty::lookup_trait_def(tcx, local_def(item.id));
1823         encode_trait_ref(ebml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
1824         encode_name(ecx, ebml_w, item.ident);
1825         encode_attributes(ebml_w, item.attrs);
1826         for ty::trait_method_def_ids(tcx, local_def(item.id)).each |&method_def_id| {
1827             ebml_w.start_tag(tag_item_trait_method);
1828             encode_def_id(ebml_w, method_def_id);
1829             ebml_w.end_tag();
1830         }
1831         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1832         for super_traits.each |ast_trait_ref| {
1833             let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
1834             encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref);
1835         }
1836         ebml_w.end_tag();
1837
1838         // Now output the method info for each method.
1839         for ty::trait_method_def_ids(tcx, local_def(item.id)).eachi |i, &method_def_id| {
1840             assert!(method_def_id.crate == ast::local_crate);
1841
1842             let method_ty: @ty::method = ty::method(tcx, method_def_id);
1843
1844             index.push(entry {val: method_def_id.node, pos: ebml_w.writer.tell()});
1845
1846             ebml_w.start_tag(tag_items_data_item);
1847
1848             encode_method_ty_fields(ecx, ebml_w, method_ty);
1849
1850             encode_parent_item(ebml_w, local_def(item.id));
1851
1852             let mut trait_path = vec::append(~[], path);
1853             trait_path.push(ast_map::path_name(item.ident));
1854             encode_path(ecx, ebml_w, trait_path, ast_map::path_name(method_ty.ident));
1855
1856             match method_ty.self_ty {
1857                 sty_static => {
1858                     encode_family(ebml_w,
1859                                   purity_static_method_family(
1860                                       method_ty.fty.purity));
1861
1862                     let tpt = ty::lookup_item_type(tcx, method_def_id);
1863                     encode_ty_type_param_defs(ebml_w, ecx,
1864                                               tpt.generics.type_param_defs,
1865                                               tag_items_data_item_ty_param_bounds);
1866                     encode_type(ecx, ebml_w, tpt.ty);
1867                 }
1868
1869                 _ => {
1870                     encode_family(ebml_w,
1871                                   purity_fn_family(
1872                                       method_ty.fty.purity));
1873                 }
1874             }
1875
1876             match ms[i] {
1877                 required(_) => {
1878                     encode_method_sort(ebml_w, 'r');
1879                 }
1880
1881                 provided(m) => {
1882                     // This is obviously a bogus assert but I don't think this
1883                     // ever worked before anyhow...near as I can tell, before
1884                     // we would emit two items.
1885                     if method_ty.self_ty == sty_static {
1886                         tcx.sess.span_unimpl(
1887                             item.span,
1888                             fmt!("Method %s is both provided and static",
1889                                  *tcx.sess.intr().get(method_ty.ident)));
1890                     }
1891                     encode_type_param_bounds(ebml_w, ecx,
1892                                              &m.generics.ty_params);
1893                     encode_method_sort(ebml_w, 'p');
1894                     (ecx.encode_inlined_item)(
1895                         ecx, ebml_w, path,
1896                         ii_method(local_def(item.id), m));
1897                 }
1898             }
1899
1900             ebml_w.end_tag();
1901         }
1902       }
1903       item_mac(*) => fail!(~"item macros unimplemented")
1904     }
1905 }
1906
1907 #[cfg(stage0)]
1908 fn encode_info_for_foreign_item(ecx: @EncodeContext,
1909                                 ebml_w: &writer::Encoder,
1910                                 nitem: @foreign_item,
1911                                 index: @mut ~[entry<int>],
1912                                 path: ast_map::path,
1913                                 abi: AbiSet) {
1914     if !reachable(ecx, nitem.id) { return; }
1915     index.push(entry { val: nitem.id, pos: ebml_w.writer.tell() });
1916
1917     ebml_w.start_tag(tag_items_data_item);
1918     match nitem.node {
1919       foreign_item_fn(_, purity, ref generics) => {
1920         encode_def_id(ebml_w, local_def(nitem.id));
1921         encode_family(ebml_w, purity_fn_family(purity));
1922         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1923         encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
1924         if abi.is_intrinsic() {
1925             (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_foreign(nitem));
1926         } else {
1927             encode_symbol(ecx, ebml_w, nitem.id);
1928         }
1929         encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
1930       }
1931       foreign_item_const(*) => {
1932         encode_def_id(ebml_w, local_def(nitem.id));
1933         encode_family(ebml_w, 'c');
1934         encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
1935         encode_symbol(ecx, ebml_w, nitem.id);
1936         encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
1937       }
1938     }
1939     ebml_w.end_tag();
1940 }
1941
1942 #[cfg(not(stage0))]
1943 fn encode_info_for_foreign_item(ecx: @EncodeContext,
1944                                 ebml_w: &mut writer::Encoder,
1945                                 nitem: @foreign_item,
1946                                 index: @mut ~[entry<int>],
1947                                 path: ast_map::path,
1948                                 abi: AbiSet) {
1949     if !reachable(ecx, nitem.id) { return; }
1950     index.push(entry { val: nitem.id, pos: ebml_w.writer.tell() });
1951
1952     ebml_w.start_tag(tag_items_data_item);
1953     match nitem.node {
1954       foreign_item_fn(_, purity, ref generics) => {
1955         encode_def_id(ebml_w, local_def(nitem.id));
1956         encode_family(ebml_w, purity_fn_family(purity));
1957         encode_type_param_bounds(ebml_w, ecx, &generics.ty_params);
1958         encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
1959         if abi.is_intrinsic() {
1960             (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_foreign(nitem));
1961         } else {
1962             encode_symbol(ecx, ebml_w, nitem.id);
1963         }
1964         encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
1965       }
1966       foreign_item_const(*) => {
1967         encode_def_id(ebml_w, local_def(nitem.id));
1968         encode_family(ebml_w, 'c');
1969         encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
1970         encode_symbol(ecx, ebml_w, nitem.id);
1971         encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
1972       }
1973     }
1974     ebml_w.end_tag();
1975 }
1976
1977 #[cfg(stage0)]
1978 fn encode_info_for_items(ecx: @EncodeContext,
1979                          ebml_w: &writer::Encoder,
1980                          crate: &crate)
1981                          -> ~[entry<int>] {
1982     let index = @mut ~[];
1983     ebml_w.start_tag(tag_items_data);
1984     index.push(entry { val: crate_node_id, pos: ebml_w.writer.tell() });
1985     encode_info_for_mod(ecx, ebml_w, &crate.node.module,
1986                         crate_node_id, ~[],
1987                         syntax::parse::token::special_idents::invalid);
1988     visit::visit_crate(crate, (), visit::mk_vt(@visit::Visitor {
1989         visit_expr: |_e, _cx, _v| { },
1990         visit_item: {
1991             let ebml_w = copy *ebml_w;
1992             |i, cx, v| {
1993                 visit::visit_item(i, cx, v);
1994                 match *ecx.tcx.items.get(&i.id) {
1995                     ast_map::node_item(_, pt) => {
1996                         encode_info_for_item(ecx, &ebml_w, i,
1997                                              index, *pt);
1998                     }
1999                     _ => fail!(~"bad item")
2000                 }
2001             }
2002         },
2003         visit_foreign_item: {
2004             let ebml_w = copy *ebml_w;
2005             |ni, cx, v| {
2006                 visit::visit_foreign_item(ni, cx, v);
2007                 match *ecx.tcx.items.get(&ni.id) {
2008                     ast_map::node_foreign_item(_, abi, _, pt) => {
2009                         encode_info_for_foreign_item(ecx, &ebml_w, ni,
2010                                                      index, /*bad*/copy *pt,
2011                                                      abi);
2012                     }
2013                     // case for separate item and foreign-item tables
2014                     _ => fail!(~"bad foreign item")
2015                 }
2016             }
2017         },
2018         ..*visit::default_visitor()
2019     }));
2020     ebml_w.end_tag();
2021     return /*bad*/copy *index;
2022 }
2023
2024 #[cfg(not(stage0))]
2025 fn encode_info_for_items(ecx: @EncodeContext,
2026                          ebml_w: &mut writer::Encoder,
2027                          crate: &crate)
2028                          -> ~[entry<int>] {
2029     let index = @mut ~[];
2030     ebml_w.start_tag(tag_items_data);
2031     index.push(entry { val: crate_node_id, pos: ebml_w.writer.tell() });
2032     encode_info_for_mod(ecx, ebml_w, &crate.node.module,
2033                         crate_node_id, ~[],
2034                         syntax::parse::token::special_idents::invalid);
2035     visit::visit_crate(crate, (), visit::mk_vt(@visit::Visitor {
2036         visit_expr: |_e, _cx, _v| { },
2037         visit_item: {
2038             let ebml_w = copy *ebml_w;
2039             |i, cx, v| {
2040                 visit::visit_item(i, cx, v);
2041                 match *ecx.tcx.items.get(&i.id) {
2042                     ast_map::node_item(_, pt) => {
2043                         let mut ebml_w = copy ebml_w;
2044                         encode_info_for_item(ecx, &mut ebml_w, i, index, *pt);
2045                     }
2046                     _ => fail!(~"bad item")
2047                 }
2048             }
2049         },
2050         visit_foreign_item: {
2051             let ebml_w = copy *ebml_w;
2052             |ni, cx, v| {
2053                 visit::visit_foreign_item(ni, cx, v);
2054                 match *ecx.tcx.items.get(&ni.id) {
2055                     ast_map::node_foreign_item(_, abi, _, pt) => {
2056                         let mut ebml_w = copy ebml_w;
2057                         encode_info_for_foreign_item(ecx,
2058                                                      &mut ebml_w,
2059                                                      ni,
2060                                                      index,
2061                                                      /*bad*/copy *pt,
2062                                                      abi);
2063                     }
2064                     // case for separate item and foreign-item tables
2065                     _ => fail!(~"bad foreign item")
2066                 }
2067             }
2068         },
2069         ..*visit::default_visitor()
2070     }));
2071     ebml_w.end_tag();
2072     return /*bad*/copy *index;
2073 }
2074
2075
2076 // Path and definition ID indexing
2077
2078 fn create_index<T:Copy + Hash + IterBytes>(index: ~[entry<T>]) ->
2079    ~[@~[entry<T>]] {
2080     let mut buckets: ~[@mut ~[entry<T>]] = ~[];
2081     for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); };
2082     for index.each |elt| {
2083         let h = elt.val.hash() as uint;
2084         buckets[h % 256].push(*elt);
2085     }
2086
2087     let mut buckets_frozen = ~[];
2088     for buckets.each |bucket| {
2089         buckets_frozen.push(@/*bad*/copy **bucket);
2090     }
2091     return buckets_frozen;
2092 }
2093
2094 #[cfg(stage0)]
2095 fn encode_index<T>(ebml_w: &writer::Encoder,
2096                    buckets: ~[@~[entry<T>]],
2097                    write_fn: &fn(@io::Writer, &T)) {
2098     let writer = ebml_w.writer;
2099     ebml_w.start_tag(tag_index);
2100     let mut bucket_locs: ~[uint] = ~[];
2101     ebml_w.start_tag(tag_index_buckets);
2102     for buckets.each |bucket| {
2103         bucket_locs.push(ebml_w.writer.tell());
2104         ebml_w.start_tag(tag_index_buckets_bucket);
2105         for vec::each(**bucket) |elt| {
2106             ebml_w.start_tag(tag_index_buckets_bucket_elt);
2107             assert!(elt.pos < 0xffff_ffff);
2108             writer.write_be_u32(elt.pos as u32);
2109             write_fn(writer, &elt.val);
2110             ebml_w.end_tag();
2111         }
2112         ebml_w.end_tag();
2113     }
2114     ebml_w.end_tag();
2115     ebml_w.start_tag(tag_index_table);
2116     for bucket_locs.each |pos| {
2117         assert!(*pos < 0xffff_ffff);
2118         writer.write_be_u32(*pos as u32);
2119     }
2120     ebml_w.end_tag();
2121     ebml_w.end_tag();
2122 }
2123
2124 #[cfg(not(stage0))]
2125 fn encode_index<T>(ebml_w: &mut writer::Encoder,
2126                    buckets: ~[@~[entry<T>]],
2127                    write_fn: &fn(@io::Writer, &T)) {
2128     let writer = ebml_w.writer;
2129     ebml_w.start_tag(tag_index);
2130     let mut bucket_locs: ~[uint] = ~[];
2131     ebml_w.start_tag(tag_index_buckets);
2132     for buckets.each |bucket| {
2133         bucket_locs.push(ebml_w.writer.tell());
2134         ebml_w.start_tag(tag_index_buckets_bucket);
2135         for vec::each(**bucket) |elt| {
2136             ebml_w.start_tag(tag_index_buckets_bucket_elt);
2137             assert!(elt.pos < 0xffff_ffff);
2138             writer.write_be_u32(elt.pos as u32);
2139             write_fn(writer, &elt.val);
2140             ebml_w.end_tag();
2141         }
2142         ebml_w.end_tag();
2143     }
2144     ebml_w.end_tag();
2145     ebml_w.start_tag(tag_index_table);
2146     for bucket_locs.each |pos| {
2147         assert!(*pos < 0xffff_ffff);
2148         writer.write_be_u32(*pos as u32);
2149     }
2150     ebml_w.end_tag();
2151     ebml_w.end_tag();
2152 }
2153
2154 fn write_str(writer: @io::Writer, s: ~str) {
2155     writer.write_str(s);
2156 }
2157
2158 fn write_int(writer: @io::Writer, &n: &int) {
2159     assert!(n < 0x7fff_ffff);
2160     writer.write_be_u32(n as u32);
2161 }
2162
2163 #[cfg(stage0)]
2164 fn encode_meta_item(ebml_w: &writer::Encoder, mi: @meta_item) {
2165     match mi.node {
2166       meta_word(name) => {
2167         ebml_w.start_tag(tag_meta_item_word);
2168         ebml_w.start_tag(tag_meta_item_name);
2169         ebml_w.writer.write(str::to_bytes(*name));
2170         ebml_w.end_tag();
2171         ebml_w.end_tag();
2172       }
2173       meta_name_value(name, value) => {
2174         match value.node {
2175           lit_str(value) => {
2176             ebml_w.start_tag(tag_meta_item_name_value);
2177             ebml_w.start_tag(tag_meta_item_name);
2178             ebml_w.writer.write(str::to_bytes(*name));
2179             ebml_w.end_tag();
2180             ebml_w.start_tag(tag_meta_item_value);
2181             ebml_w.writer.write(str::to_bytes(*value));
2182             ebml_w.end_tag();
2183             ebml_w.end_tag();
2184           }
2185           _ => {/* FIXME (#623): encode other variants */ }
2186         }
2187       }
2188       meta_list(name, ref items) => {
2189         ebml_w.start_tag(tag_meta_item_list);
2190         ebml_w.start_tag(tag_meta_item_name);
2191         ebml_w.writer.write(str::to_bytes(*name));
2192         ebml_w.end_tag();
2193         for items.each |inner_item| {
2194             encode_meta_item(ebml_w, *inner_item);
2195         }
2196         ebml_w.end_tag();
2197       }
2198     }
2199 }
2200
2201 #[cfg(not(stage0))]
2202 fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @meta_item) {
2203     match mi.node {
2204       meta_word(name) => {
2205         ebml_w.start_tag(tag_meta_item_word);
2206         ebml_w.start_tag(tag_meta_item_name);
2207         ebml_w.writer.write(str::to_bytes(*name));
2208         ebml_w.end_tag();
2209         ebml_w.end_tag();
2210       }
2211       meta_name_value(name, value) => {
2212         match value.node {
2213           lit_str(value) => {
2214             ebml_w.start_tag(tag_meta_item_name_value);
2215             ebml_w.start_tag(tag_meta_item_name);
2216             ebml_w.writer.write(str::to_bytes(*name));
2217             ebml_w.end_tag();
2218             ebml_w.start_tag(tag_meta_item_value);
2219             ebml_w.writer.write(str::to_bytes(*value));
2220             ebml_w.end_tag();
2221             ebml_w.end_tag();
2222           }
2223           _ => {/* FIXME (#623): encode other variants */ }
2224         }
2225       }
2226       meta_list(name, ref items) => {
2227         ebml_w.start_tag(tag_meta_item_list);
2228         ebml_w.start_tag(tag_meta_item_name);
2229         ebml_w.writer.write(str::to_bytes(*name));
2230         ebml_w.end_tag();
2231         for items.each |inner_item| {
2232             encode_meta_item(ebml_w, *inner_item);
2233         }
2234         ebml_w.end_tag();
2235       }
2236     }
2237 }
2238
2239 #[cfg(stage0)]
2240 fn encode_attributes(ebml_w: &writer::Encoder, attrs: &[attribute]) {
2241     ebml_w.start_tag(tag_attributes);
2242     for attrs.each |attr| {
2243         ebml_w.start_tag(tag_attribute);
2244         encode_meta_item(ebml_w, attr.node.value);
2245         ebml_w.end_tag();
2246     }
2247     ebml_w.end_tag();
2248 }
2249
2250 #[cfg(not(stage0))]
2251 fn encode_attributes(ebml_w: &mut writer::Encoder, attrs: &[attribute]) {
2252     ebml_w.start_tag(tag_attributes);
2253     for attrs.each |attr| {
2254         ebml_w.start_tag(tag_attribute);
2255         encode_meta_item(ebml_w, attr.node.value);
2256         ebml_w.end_tag();
2257     }
2258     ebml_w.end_tag();
2259 }
2260
2261 // So there's a special crate attribute called 'link' which defines the
2262 // metadata that Rust cares about for linking crates. This attribute requires
2263 // 'name' and 'vers' items, so if the user didn't provide them we will throw
2264 // them in anyway with default values.
2265 fn synthesize_crate_attrs(ecx: @EncodeContext,
2266                           crate: &crate) -> ~[attribute] {
2267
2268     fn synthesize_link_attr(ecx: @EncodeContext, items: ~[@meta_item]) ->
2269        attribute {
2270
2271         assert!(!ecx.link_meta.name.is_empty());
2272         assert!(!ecx.link_meta.vers.is_empty());
2273
2274         let name_item =
2275             attr::mk_name_value_item_str(@~"name",
2276                                          @ecx.link_meta.name.to_owned());
2277         let vers_item =
2278             attr::mk_name_value_item_str(@~"vers",
2279                                          @ecx.link_meta.vers.to_owned());
2280
2281         let other_items =
2282             {
2283                 let tmp = attr::remove_meta_items_by_name(items, ~"name");
2284                 attr::remove_meta_items_by_name(tmp, ~"vers")
2285             };
2286
2287         let meta_items = vec::append(~[name_item, vers_item], other_items);
2288         let link_item = attr::mk_list_item(@~"link", meta_items);
2289
2290         return attr::mk_attr(link_item);
2291     }
2292
2293     let mut attrs: ~[attribute] = ~[];
2294     let mut found_link_attr = false;
2295     for crate.node.attrs.each |attr| {
2296         attrs.push(
2297             if *attr::get_attr_name(attr) != ~"link" {
2298                 /*bad*/copy *attr
2299             } else {
2300                 match attr.node.value.node {
2301                   meta_list(_, ref l) => {
2302                     found_link_attr = true;;
2303                     synthesize_link_attr(ecx, /*bad*/copy *l)
2304                   }
2305                   _ => /*bad*/copy *attr
2306                 }
2307             });
2308     }
2309
2310     if !found_link_attr { attrs.push(synthesize_link_attr(ecx, ~[])); }
2311
2312     return attrs;
2313 }
2314
2315 #[cfg(stage0)]
2316 fn encode_crate_deps(ecx: @EncodeContext,
2317                      ebml_w: &writer::Encoder,
2318                      cstore: @mut cstore::CStore) {
2319     fn get_ordered_deps(ecx: @EncodeContext, cstore: @mut cstore::CStore)
2320                      -> ~[decoder::crate_dep] {
2321         type numdep = decoder::crate_dep;
2322
2323         // Pull the cnums and name,vers,hash out of cstore
2324         let mut deps = ~[];
2325         do cstore::iter_crate_data(cstore) |key, val| {
2326             let dep = decoder::crate_dep {cnum: key,
2327                        name: ecx.tcx.sess.ident_of(/*bad*/ copy *val.name),
2328                        vers: decoder::get_crate_vers(val.data),
2329                        hash: decoder::get_crate_hash(val.data)};
2330             deps.push(dep);
2331         };
2332
2333         // Sort by cnum
2334         std::sort::quick_sort(deps, |kv1, kv2| kv1.cnum <= kv2.cnum);
2335
2336         // Sanity-check the crate numbers
2337         let mut expected_cnum = 1;
2338         for deps.each |n| {
2339             assert!((n.cnum == expected_cnum));
2340             expected_cnum += 1;
2341         }
2342
2343         // mut -> immutable hack for vec::map
2344         deps.slice(0, deps.len()).to_owned()
2345     }
2346
2347     // We're just going to write a list of crate 'name-hash-version's, with
2348     // the assumption that they are numbered 1 to n.
2349     // FIXME (#2166): This is not nearly enough to support correct versioning
2350     // but is enough to get transitive crate dependencies working.
2351     ebml_w.start_tag(tag_crate_deps);
2352     for get_ordered_deps(ecx, cstore).each |dep| {
2353         encode_crate_dep(ecx, ebml_w, *dep);
2354     }
2355     ebml_w.end_tag();
2356 }
2357
2358 #[cfg(not(stage0))]
2359 fn encode_crate_deps(ecx: @EncodeContext,
2360                      ebml_w: &mut writer::Encoder,
2361                      cstore: @mut cstore::CStore) {
2362     fn get_ordered_deps(ecx: @EncodeContext, cstore: @mut cstore::CStore)
2363                      -> ~[decoder::crate_dep] {
2364         type numdep = decoder::crate_dep;
2365
2366         // Pull the cnums and name,vers,hash out of cstore
2367         let mut deps = ~[];
2368         do cstore::iter_crate_data(cstore) |key, val| {
2369             let dep = decoder::crate_dep {cnum: key,
2370                        name: ecx.tcx.sess.ident_of(/*bad*/ copy *val.name),
2371                        vers: decoder::get_crate_vers(val.data),
2372                        hash: decoder::get_crate_hash(val.data)};
2373             deps.push(dep);
2374         };
2375
2376         // Sort by cnum
2377         std::sort::quick_sort(deps, |kv1, kv2| kv1.cnum <= kv2.cnum);
2378
2379         // Sanity-check the crate numbers
2380         let mut expected_cnum = 1;
2381         for deps.each |n| {
2382             assert!((n.cnum == expected_cnum));
2383             expected_cnum += 1;
2384         }
2385
2386         // mut -> immutable hack for vec::map
2387         deps.slice(0, deps.len()).to_owned()
2388     }
2389
2390     // We're just going to write a list of crate 'name-hash-version's, with
2391     // the assumption that they are numbered 1 to n.
2392     // FIXME (#2166): This is not nearly enough to support correct versioning
2393     // but is enough to get transitive crate dependencies working.
2394     ebml_w.start_tag(tag_crate_deps);
2395     for get_ordered_deps(ecx, cstore).each |dep| {
2396         encode_crate_dep(ecx, ebml_w, *dep);
2397     }
2398     ebml_w.end_tag();
2399 }
2400
2401 #[cfg(stage0)]
2402 fn encode_lang_items(ecx: @EncodeContext, ebml_w: &writer::Encoder) {
2403     ebml_w.start_tag(tag_lang_items);
2404
2405     for ecx.tcx.lang_items.each_item |def_id, i| {
2406         if def_id.crate != local_crate {
2407             loop;
2408         }
2409
2410         ebml_w.start_tag(tag_lang_items_item);
2411
2412         ebml_w.start_tag(tag_lang_items_item_id);
2413         ebml_w.writer.write_be_u32(i as u32);
2414         ebml_w.end_tag();   // tag_lang_items_item_id
2415
2416         ebml_w.start_tag(tag_lang_items_item_node_id);
2417         ebml_w.writer.write_be_u32(def_id.node as u32);
2418         ebml_w.end_tag();   // tag_lang_items_item_node_id
2419
2420         ebml_w.end_tag();   // tag_lang_items_item
2421     }
2422
2423     ebml_w.end_tag();   // tag_lang_items
2424 }
2425
2426 #[cfg(not(stage0))]
2427 fn encode_lang_items(ecx: @EncodeContext, ebml_w: &mut writer::Encoder) {
2428     ebml_w.start_tag(tag_lang_items);
2429
2430     for ecx.tcx.lang_items.each_item |def_id, i| {
2431         if def_id.crate != local_crate {
2432             loop;
2433         }
2434
2435         ebml_w.start_tag(tag_lang_items_item);
2436
2437         ebml_w.start_tag(tag_lang_items_item_id);
2438         ebml_w.writer.write_be_u32(i as u32);
2439         ebml_w.end_tag();   // tag_lang_items_item_id
2440
2441         ebml_w.start_tag(tag_lang_items_item_node_id);
2442         ebml_w.writer.write_be_u32(def_id.node as u32);
2443         ebml_w.end_tag();   // tag_lang_items_item_node_id
2444
2445         ebml_w.end_tag();   // tag_lang_items_item
2446     }
2447
2448     ebml_w.end_tag();   // tag_lang_items
2449 }
2450
2451 #[cfg(stage0)]
2452 fn encode_link_args(ecx: @EncodeContext, ebml_w: &writer::Encoder) {
2453     ebml_w.start_tag(tag_link_args);
2454
2455     let link_args = cstore::get_used_link_args(ecx.cstore);
2456     for link_args.each |link_arg| {
2457         ebml_w.start_tag(tag_link_args_arg);
2458         ebml_w.writer.write_str(link_arg.to_str());
2459         ebml_w.end_tag();
2460     }
2461
2462     ebml_w.end_tag();
2463 }
2464
2465 #[cfg(not(stage0))]
2466 fn encode_link_args(ecx: @EncodeContext, ebml_w: &mut writer::Encoder) {
2467     ebml_w.start_tag(tag_link_args);
2468
2469     let link_args = cstore::get_used_link_args(ecx.cstore);
2470     for link_args.each |link_arg| {
2471         ebml_w.start_tag(tag_link_args_arg);
2472         ebml_w.writer.write_str(link_arg.to_str());
2473         ebml_w.end_tag();
2474     }
2475
2476     ebml_w.end_tag();
2477 }
2478
2479 #[cfg(stage0)]
2480 fn encode_crate_dep(ecx: @EncodeContext,
2481                     ebml_w: &writer::Encoder,
2482                     dep: decoder::crate_dep) {
2483     ebml_w.start_tag(tag_crate_dep);
2484     ebml_w.start_tag(tag_crate_dep_name);
2485     ebml_w.writer.write(str::to_bytes(*ecx.tcx.sess.str_of(dep.name)));
2486     ebml_w.end_tag();
2487     ebml_w.start_tag(tag_crate_dep_vers);
2488     ebml_w.writer.write(str::to_bytes(*dep.vers));
2489     ebml_w.end_tag();
2490     ebml_w.start_tag(tag_crate_dep_hash);
2491     ebml_w.writer.write(str::to_bytes(*dep.hash));
2492     ebml_w.end_tag();
2493     ebml_w.end_tag();
2494 }
2495
2496 #[cfg(not(stage0))]
2497 fn encode_crate_dep(ecx: @EncodeContext,
2498                     ebml_w: &mut writer::Encoder,
2499                     dep: decoder::crate_dep) {
2500     ebml_w.start_tag(tag_crate_dep);
2501     ebml_w.start_tag(tag_crate_dep_name);
2502     ebml_w.writer.write(str::to_bytes(*ecx.tcx.sess.str_of(dep.name)));
2503     ebml_w.end_tag();
2504     ebml_w.start_tag(tag_crate_dep_vers);
2505     ebml_w.writer.write(str::to_bytes(*dep.vers));
2506     ebml_w.end_tag();
2507     ebml_w.start_tag(tag_crate_dep_hash);
2508     ebml_w.writer.write(str::to_bytes(*dep.hash));
2509     ebml_w.end_tag();
2510     ebml_w.end_tag();
2511 }
2512
2513 #[cfg(stage0)]
2514 fn encode_hash(ebml_w: &writer::Encoder, hash: &str) {
2515     ebml_w.start_tag(tag_crate_hash);
2516     ebml_w.writer.write(str::to_bytes(hash));
2517     ebml_w.end_tag();
2518 }
2519
2520 #[cfg(not(stage0))]
2521 fn encode_hash(ebml_w: &mut writer::Encoder, hash: &str) {
2522     ebml_w.start_tag(tag_crate_hash);
2523     ebml_w.writer.write(str::to_bytes(hash));
2524     ebml_w.end_tag();
2525 }
2526
2527 // NB: Increment this as you change the metadata encoding version.
2528 pub static metadata_encoding_version : &'static [u8] =
2529     &[0x72, //'r' as u8,
2530       0x75, //'u' as u8,
2531       0x73, //'s' as u8,
2532       0x74, //'t' as u8,
2533       0, 0, 0, 1 ];
2534
2535 #[cfg(stage0)]
2536 pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
2537     let wr = @io::BytesWriter();
2538     let stats = Stats {
2539         inline_bytes: 0,
2540         attr_bytes: 0,
2541         dep_bytes: 0,
2542         lang_item_bytes: 0,
2543         link_args_bytes: 0,
2544         item_bytes: 0,
2545         index_bytes: 0,
2546         zero_bytes: 0,
2547         total_bytes: 0,
2548         n_inlines: 0
2549     };
2550     let EncodeParams{item_symbols, diag, tcx, reachable, reexports2,
2551                      discrim_symbols, cstore, encode_inlined_item,
2552                      link_meta, _} = parms;
2553     let ecx = @EncodeContext {
2554         diag: diag,
2555         tcx: tcx,
2556         stats: @mut stats,
2557         reachable: reachable,
2558         reexports2: reexports2,
2559         item_symbols: item_symbols,
2560         discrim_symbols: discrim_symbols,
2561         link_meta: link_meta,
2562         cstore: cstore,
2563         encode_inlined_item: encode_inlined_item,
2564         type_abbrevs: @mut HashMap::new()
2565      };
2566
2567     let ebml_w = writer::Encoder(wr as @io::Writer);
2568
2569     encode_hash(&ebml_w, ecx.link_meta.extras_hash);
2570
2571     let mut i = wr.pos;
2572     let crate_attrs = synthesize_crate_attrs(ecx, crate);
2573     encode_attributes(&ebml_w, crate_attrs);
2574     ecx.stats.attr_bytes = wr.pos - i;
2575
2576     i = wr.pos;
2577     encode_crate_deps(ecx, &ebml_w, ecx.cstore);
2578     ecx.stats.dep_bytes = wr.pos - i;
2579
2580     // Encode the language items.
2581     i = wr.pos;
2582     encode_lang_items(ecx, &ebml_w);
2583     ecx.stats.lang_item_bytes = wr.pos - i;
2584
2585     // Encode the link args.
2586     i = wr.pos;
2587     encode_link_args(ecx, &ebml_w);
2588     ecx.stats.link_args_bytes = wr.pos - i;
2589
2590     // Encode and index the items.
2591     ebml_w.start_tag(tag_items);
2592     i = wr.pos;
2593     let items_index = encode_info_for_items(ecx, &ebml_w, crate);
2594     ecx.stats.item_bytes = wr.pos - i;
2595
2596     i = wr.pos;
2597     let items_buckets = create_index(items_index);
2598     encode_index(&ebml_w, items_buckets, write_int);
2599     ecx.stats.index_bytes = wr.pos - i;
2600     ebml_w.end_tag();
2601
2602     ecx.stats.total_bytes = wr.pos;
2603
2604     if (tcx.sess.meta_stats()) {
2605
2606         do wr.bytes.each |e| {
2607             if *e == 0 {
2608                 ecx.stats.zero_bytes += 1;
2609             }
2610             true
2611         }
2612
2613         io::println("metadata stats:");
2614         io::println(fmt!("    inline bytes: %u", ecx.stats.inline_bytes));
2615         io::println(fmt!(" attribute bytes: %u", ecx.stats.attr_bytes));
2616         io::println(fmt!("       dep bytes: %u", ecx.stats.dep_bytes));
2617         io::println(fmt!(" lang item bytes: %u", ecx.stats.lang_item_bytes));
2618         io::println(fmt!(" link args bytes: %u", ecx.stats.link_args_bytes));
2619         io::println(fmt!("      item bytes: %u", ecx.stats.item_bytes));
2620         io::println(fmt!("     index bytes: %u", ecx.stats.index_bytes));
2621         io::println(fmt!("      zero bytes: %u", ecx.stats.zero_bytes));
2622         io::println(fmt!("     total bytes: %u", ecx.stats.total_bytes));
2623     }
2624
2625     // Pad this, since something (LLVM, presumably) is cutting off the
2626     // remaining % 4 bytes.
2627     wr.write(&[0u8, 0u8, 0u8, 0u8]);
2628
2629     // FIXME #3396: weird bug here, for reasons unclear this emits random
2630     // looking bytes (mostly 0x1) if we use the version byte-array constant
2631     // above; so we use a string constant inline instead.
2632     //
2633     // Should be:
2634     //
2635     //   vec::from_slice(metadata_encoding_version) +
2636
2637     (do str::as_bytes(&~"rust\x00\x00\x00\x01") |bytes| {
2638         vec::slice(*bytes, 0, 8).to_vec()
2639     }) + flate::deflate_bytes(wr.bytes)
2640 }
2641
2642 #[cfg(not(stage0))]
2643 pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
2644     let wr = @io::BytesWriter();
2645     let stats = Stats {
2646         inline_bytes: 0,
2647         attr_bytes: 0,
2648         dep_bytes: 0,
2649         lang_item_bytes: 0,
2650         link_args_bytes: 0,
2651         item_bytes: 0,
2652         index_bytes: 0,
2653         zero_bytes: 0,
2654         total_bytes: 0,
2655         n_inlines: 0
2656     };
2657     let EncodeParams{item_symbols, diag, tcx, reachable, reexports2,
2658                      discrim_symbols, cstore, encode_inlined_item,
2659                      link_meta, _} = parms;
2660     let ecx = @EncodeContext {
2661         diag: diag,
2662         tcx: tcx,
2663         stats: @mut stats,
2664         reachable: reachable,
2665         reexports2: reexports2,
2666         item_symbols: item_symbols,
2667         discrim_symbols: discrim_symbols,
2668         link_meta: link_meta,
2669         cstore: cstore,
2670         encode_inlined_item: encode_inlined_item,
2671         type_abbrevs: @mut HashMap::new()
2672      };
2673
2674     let mut ebml_w = writer::Encoder(wr as @io::Writer);
2675
2676     encode_hash(&mut ebml_w, ecx.link_meta.extras_hash);
2677
2678     let mut i = wr.pos;
2679     let crate_attrs = synthesize_crate_attrs(ecx, crate);
2680     encode_attributes(&mut ebml_w, crate_attrs);
2681     ecx.stats.attr_bytes = wr.pos - i;
2682
2683     i = wr.pos;
2684     encode_crate_deps(ecx, &mut ebml_w, ecx.cstore);
2685     ecx.stats.dep_bytes = wr.pos - i;
2686
2687     // Encode the language items.
2688     i = wr.pos;
2689     encode_lang_items(ecx, &mut ebml_w);
2690     ecx.stats.lang_item_bytes = wr.pos - i;
2691
2692     // Encode the link args.
2693     i = wr.pos;
2694     encode_link_args(ecx, &mut ebml_w);
2695     ecx.stats.link_args_bytes = wr.pos - i;
2696
2697     // Encode and index the items.
2698     ebml_w.start_tag(tag_items);
2699     i = wr.pos;
2700     let items_index = encode_info_for_items(ecx, &mut ebml_w, crate);
2701     ecx.stats.item_bytes = wr.pos - i;
2702
2703     i = wr.pos;
2704     let items_buckets = create_index(items_index);
2705     encode_index(&mut ebml_w, items_buckets, write_int);
2706     ecx.stats.index_bytes = wr.pos - i;
2707     ebml_w.end_tag();
2708
2709     ecx.stats.total_bytes = wr.pos;
2710
2711     if (tcx.sess.meta_stats()) {
2712
2713         do wr.bytes.each |e| {
2714             if *e == 0 {
2715                 ecx.stats.zero_bytes += 1;
2716             }
2717             true
2718         }
2719
2720         io::println("metadata stats:");
2721         io::println(fmt!("    inline bytes: %u", ecx.stats.inline_bytes));
2722         io::println(fmt!(" attribute bytes: %u", ecx.stats.attr_bytes));
2723         io::println(fmt!("       dep bytes: %u", ecx.stats.dep_bytes));
2724         io::println(fmt!(" lang item bytes: %u", ecx.stats.lang_item_bytes));
2725         io::println(fmt!(" link args bytes: %u", ecx.stats.link_args_bytes));
2726         io::println(fmt!("      item bytes: %u", ecx.stats.item_bytes));
2727         io::println(fmt!("     index bytes: %u", ecx.stats.index_bytes));
2728         io::println(fmt!("      zero bytes: %u", ecx.stats.zero_bytes));
2729         io::println(fmt!("     total bytes: %u", ecx.stats.total_bytes));
2730     }
2731
2732     // Pad this, since something (LLVM, presumably) is cutting off the
2733     // remaining % 4 bytes.
2734     wr.write(&[0u8, 0u8, 0u8, 0u8]);
2735
2736     // FIXME #3396: weird bug here, for reasons unclear this emits random
2737     // looking bytes (mostly 0x1) if we use the version byte-array constant
2738     // above; so we use a string constant inline instead.
2739     //
2740     // Should be:
2741     //
2742     //   vec::from_slice(metadata_encoding_version) +
2743
2744     (do str::as_bytes(&~"rust\x00\x00\x00\x01") |bytes| {
2745         vec::slice(*bytes, 0, 8).to_vec()
2746     }) + flate::deflate_bytes(wr.bytes)
2747 }
2748
2749 // Get the encoded string for a type
2750 pub fn encoded_ty(tcx: ty::ctxt, t: ty::t) -> ~str {
2751     let cx = @tyencode::ctxt {
2752         diag: tcx.diag,
2753         ds: def_to_str,
2754         tcx: tcx,
2755         reachable: |_id| false,
2756         abbrevs: tyencode::ac_no_abbrevs};
2757     do io::with_str_writer |wr| {
2758         tyencode::enc_ty(wr, cx, t);
2759     }
2760 }