(index<- )        ./librustc/metadata/encoder.rs

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


librustc/metadata/encoder.rs:215:1-215:1 -fn- definition:
fn encode_type(ecx: &EncodeContext,
               ebml_w: &mut Encoder,
               typ: ty::t) {
references:- 5
673:         encode_name(ebml_w, nm);
674:         encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
675:         encode_def_id(ebml_w, local_def(id));
--
697:     encode_name(ebml_w, name.name);
698:     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, ctor_id));
699:     ecx.tcx.map.with_path(ctor_id, |path| encode_path(ebml_w, path));
--
1232:         }
1233:         encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
1234:         encode_symbol(ecx, ebml_w, nitem.id);


librustc/metadata/encoder.rs:793:1-793:1 -fn- definition:
fn fn_style_static_method_family(s: FnStyle) -> char {
    match s {
        UnsafeFn => 'U',
references:- 2
728:         ast::SelfStatic => {
729:             encode_family(ebml_w, fn_style_static_method_family(fn_style));
730:         }
--
1154:                     encode_family(ebml_w,
1155:                                   fn_style_static_method_family(
1156:                                       method_ty.fty.fn_style));


librustc/metadata/encoder.rs:648:46-648:46 -fn- definition:
/* Returns an index of items in this class */
fn encode_info_for_struct(ecx: &EncodeContext,
                          ebml_w: &mut Encoder,
references:- 2
328:                 let fields = ty::lookup_struct_fields(ecx.tcx, def_id);
329:                 let idx = encode_info_for_struct(ecx,
330:                                                  ebml_w,
--
986:            class itself */
987:         let idx = encode_info_for_struct(ecx,
988:                                          ebml_w,


librustc/metadata/encoder.rs:860:4-860:4 -fn- definition:
    fn add_to_index(item: &Item, ebml_w: &Encoder,
                    index: &mut Vec<entry<i64>>) {
        index.push(entry {
references:- 9
992:         /* Index the class*/
993:         add_to_index(item, ebml_w, index);
--
1036:         add_to_index(item, ebml_w, index);
1037:         ebml_w.start_tag(tag_items_data_item);
--
1090:       ItemTrait(_, sized, ref super_traits, ref ms) => {
1091:         add_to_index(item, ebml_w, index);
1092:         ebml_w.start_tag(tag_items_data_item);


librustc/metadata/encoder.rs:62:1-62:1 -NK_AS_STR_TODO- definition:
pub type Encoder<'a> = writer::Encoder<'a, MemWriter>;
pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
                                  ebml_w: &mut Encoder,
references:- 65


librustc/metadata/encoder.rs:141:1-141:1 -fn- definition:
pub fn def_to_str(did: DefId) -> ~str {
    format!("{}:{}", did.krate, did.node)
}
references:- 22
933:             ebml_w.start_tag(tag_mod_child);
934:             ebml_w.wr_str(def_to_str(local_def(foreign_item.id)));
935:             ebml_w.end_tag();
--
1113:             ebml_w.start_tag(tag_mod_child);
1114:             ebml_w.wr_str(def_to_str(method_def_id));
1115:             ebml_w.end_tag();
--
1867:         diag: tcx.sess.diagnostic(),
1868:         ds: def_to_str,
1869:         tcx: tcx,
librustc/middle/astencode.rs:
782:             diag: self.tcx.sess.diagnostic(),
783:             ds: e::def_to_str,
784:             tcx: self.tcx,
librustc/metadata/encoder.rs:
568:                 ebml_w.start_tag(tag_mod_impl);
569:                 ebml_w.wr_str(def_to_str(local_def(did)));
570:                 ebml_w.end_tag();


librustc/metadata/encoder.rs:99:1-99:1 -fn- definition:
pub fn encode_def_id(ebml_w: &mut Encoder, id: DefId) {
    ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
}
references:- 19
692:     ebml_w.start_tag(tag_items_data_item);
693:     encode_def_id(ebml_w, local_def(ctor_id));
694:     encode_family(ebml_w, 'f');
--
1213:     ebml_w.start_tag(tag_items_data_item);
1214:     encode_def_id(ebml_w, local_def(nitem.id));
1215:     match nitem.node {
--
1606:                     self.ebml_w.start_tag(tag_impls_impl);
1607:                     encode_def_id(self.ebml_w, local_def(item.id));
1608:                     self.ebml_w.end_tag();


librustc/metadata/encoder.rs:500:1-500:1 -fn- definition:
fn encode_reexports(ecx: &EncodeContext,
                    ebml_w: &mut Encoder,
                    id: NodeId,
references:- 2
1661:     // Encode reexports for the root module.
1662:     encode_reexports(ecx, ebml_w, 0, ast_map::Values([].iter()).chain(None));


librustc/metadata/encoder.rs:1336:1-1336:1 -fn- definition:
fn encode_index<T: Hash>(ebml_w: &mut Encoder, index: Vec<entry<T>>,
                         write_fn: |&mut MemWriter, &T|) {
    let mut buckets: Vec<Vec<entry<T>>> = Vec::from_fn(256, |_| Vec::new());
references:- 3
333:                 encode_struct_fields(ebml_w, fields.as_slice(), def_id);
334:                 encode_index(ebml_w, idx, write_i64);
335:             }
--
1017:         /* Each class has its own index -- encode it */
1018:         encode_index(ebml_w, idx, write_i64);
1019:         ebml_w.end_tag();
--
1833:     i = ebml_w.writer.tell().unwrap();
1834:     encode_index(&mut ebml_w, items_index, write_i64);
1835:     stats.index_bytes = ebml_w.writer.tell().unwrap() - i;


librustc/metadata/encoder.rs:91:1-91:1 -fn- definition:
fn encode_name(ebml_w: &mut Encoder, name: Name) {
    ebml_w.wr_tagged_str(tag_paths_data_name, token::get_name(name).get());
}
references:- 17
543:     encode_family(ebml_w, 'm');
544:     encode_name(ebml_w, name.name);
545:     debug!("(encoding info for module) encoding info for module ID {}", id);
--
1219:                                &lookup_item_type(ecx.tcx,local_def(nitem.id)));
1220:         encode_name(ebml_w, nitem.ident.name);
1221:         if abi == abi::RustIntrinsic {
--
1234:         encode_symbol(ecx, ebml_w, nitem.id);
1235:         encode_name(ebml_w, nitem.ident.name);
1236:       }


librustc/metadata/encoder.rs:104:19-104:19 -struct- definition:
struct entry<T> {
    val: T,
    pos: u64
references:- 26
664:         index.push(entry {val: id as i64, pos: ebml_w.writer.tell().unwrap()});
665:         global_index.push(entry {
--
1207:                                 abi: abi::Abi) {
1208:     index.push(entry {
1209:         val: nitem.id as i64,
--
1309:     ebml_w.start_tag(tag_items_data);
1310:     index.push(entry {
1311:         val: CRATE_NODE_ID as i64,
--
1338:                          write_fn: |&mut MemWriter, &T|) {
1339:     let mut buckets: Vec<Vec<entry<T>>> = Vec::from_fn(256, |_| Vec::new());
1340:     for elt in index.move_iter() {


librustc/metadata/encoder.rs:272:1-272:1 -fn- definition:
fn encode_struct_fields(ebml_w: &mut Encoder,
                        fields: &[ty::field_ty],
                        origin: DefId) {
references:- 2
332:                                                  index);
333:                 encode_struct_fields(ebml_w, fields.as_slice(), def_id);
334:                 encode_index(ebml_w, idx, write_i64);
--
1009:         needs to know*/
1010:         encode_struct_fields(ebml_w, fields.as_slice(), def_id);


librustc/metadata/encoder.rs:350:1-350:1 -fn- definition:
fn encode_path<PI: Iterator<PathElem> + Clone>(ebml_w: &mut Encoder,
                                               mut path: PI) {
    ebml_w.start_tag(tag_path);
references:- 14
576:     encode_path(ebml_w, path.clone());
577:     encode_visibility(ebml_w, vis);
--
1063:         }
1064:         encode_path(ebml_w, path.clone());
1065:         ebml_w.end_tag();
--
1149:             let elem = ast_map::PathName(method_ty.ident.name);
1150:             encode_path(ebml_w, path.clone().chain(Some(elem).move_iter()));
--
1237:     }
1238:     encode_path(ebml_w, path);
1239:     ebml_w.end_tag();


librustc/metadata/encoder.rs:778:1-778:1 -fn- definition:
fn encode_inlined_item(ecx: &EncodeContext,
                       ebml_w: &mut Encoder,
                       ii: InlinedItemRef) {
references:- 7
1184:                     encode_method_sort(ebml_w, 'p');
1185:                     encode_inlined_item(ecx, ebml_w,
1186:                                         IIMethodRef(def_id, true, m));
--
1221:         if abi == abi::RustIntrinsic {
1222:             encode_inlined_item(ecx, ebml_w, IIForeignRef(nitem));
1223:         } else {


librustc/metadata/encoder.rs:587:1-587:1 -fn- definition:
fn encode_struct_field_family(ebml_w: &mut Encoder,
                              visibility: Visibility) {
    encode_family(ebml_w, match visibility {
references:- 2
282:         }
283:         encode_struct_field_family(ebml_w, f.vis);
284:         encode_def_id(ebml_w, f.id);
--
671:                token::get_name(nm), id);
672:         encode_struct_field_family(ebml_w, field.vis);
673:         encode_name(ebml_w, nm);


librustc/metadata/encoder.rs:1373:1-1373:1 -fn- definition:
fn write_i64(writer: &mut MemWriter, &n: &i64) {
    let wr: &mut MemWriter = writer;
    assert!(n < 0x7fff_ffff);
references:- 3
1833:     i = ebml_w.writer.tell().unwrap();
1834:     encode_index(&mut ebml_w, items_index, write_i64);
1835:     stats.index_bytes = ebml_w.writer.tell().unwrap() - i;


librustc/metadata/encoder.rs:1553:1-1553:1 -struct- definition:
struct MacroDefVisitor<'a, 'b, 'c> {
    ecx: &'a EncodeContext<'b>,
    ebml_w: &'a mut Encoder<'c>
references:- 2
1559: impl<'a, 'b, 'c> Visitor<()> for MacroDefVisitor<'a, 'b, 'c> {
1560:     fn visit_item(&mut self, item: &Item, _: ()) {
--
1579:     {
1580:         let mut visitor = MacroDefVisitor {
1581:             ecx: ecx,


librustc/metadata/encoder.rs:364:1-364:1 -fn- definition:
fn encode_reexported_static_method(ebml_w: &mut Encoder,
                                   exp: &middle::resolve::Export2,
                                   method_def_id: DefId,
references:- 2
391:                     if m.explicit_self == ast::SelfStatic {
392:                         encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
393:                     }
--
410:                 if m.explicit_self == ast::SelfStatic {
411:                     encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
412:                 }


librustc/metadata/encoder.rs:786:1-786:1 -fn- definition:
fn style_fn_family(s: FnStyle) -> char {
    match s {
        UnsafeFn => 'u',
references:- 4
898:         encode_def_id(ebml_w, def_id);
899:         encode_family(ebml_w, style_fn_family(fn_style));
900:         let tps_len = generics.ty_params.len();
--
1163:                     encode_family(ebml_w,
1164:                                   style_fn_family(
1165:                                       method_ty.fty.fn_style));
--
1216:       ForeignItemFn(..) => {
1217:         encode_family(ebml_w, style_fn_family(NormalFn));
1218:         encode_bounds_and_type(ebml_w, ecx,


librustc/metadata/encoder.rs:56:44-56:44 -enum- definition:
/// A borrowed version of ast::InlinedItem.
pub enum InlinedItemRef<'a> {
    IIItemRef(&'a ast::Item),
references:- 4
780:                        ebml_w: &mut Encoder,
781:                        ii: InlinedItemRef) {
782:     let mut eii = ecx.encode_inlined_item.borrow_mut();
librustc/middle/astencode.rs:
78:                            ebml_w: &mut Encoder,
79:                            ii: e::InlinedItemRef) {
80:     let id = match ii {
--
337: // inlined items.
338: fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem {
339:     let mut fld = NestedItemsDropper;
librustc/metadata/encoder.rs:
66:                                   ebml_w: &mut Encoder,
67:                                   ii: InlinedItemRef|: 'a;


librustc/metadata/encoder.rs:109:1-109:1 -fn- definition:
fn encode_trait_ref(ebml_w: &mut Encoder,
                    ecx: &EncodeContext,
                    trait_ref: &ty::TraitRef,
references:- 3
1122:             let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
1123:             encode_trait_ref(ebml_w, ecx, &*trait_ref, tag_item_super_trait_ref);
1124:         }


librustc/metadata/encoder.rs:79:1-79:1 -struct- definition:
pub struct EncodeContext<'a> {
    pub diag: &'a SpanHandler,
    pub tcx: &'a ty::ctxt,
references:- 63
librustc/middle/astencode.rs:


librustc/metadata/encoder.rs:145:1-145:1 -fn- definition:
fn encode_ty_type_param_defs(ebml_w: &mut Encoder,
                             ecx: &EncodeContext,
                             params: &[ty::TypeParameterDef],
references:- 3
719:     encode_name(ebml_w, method_ty.ident.name);
720:     encode_ty_type_param_defs(ebml_w, ecx,
721:                               method_ty.generics.type_param_defs(),
--
1096:         let trait_def = ty::lookup_trait_def(tcx, def_id);
1097:         encode_ty_type_param_defs(ebml_w, ecx,
1098:                                   trait_def.generics.type_param_defs(),


librustc/metadata/encoder.rs:533:1-533:1 -fn- definition:
fn encode_info_for_mod(ecx: &EncodeContext,
                       ebml_w: &mut Encoder,
                       md: &Mod,
references:- 2
1313:     });
1314:     encode_info_for_mod(ecx,
1315:                         ebml_w,


librustc/metadata/encoder.rs:203:1-203:1 -fn- definition:
pub fn write_type(ecx: &EncodeContext,
                  ebml_w: &mut Encoder,
                  typ: ty::t) {
references:- 2
librustc/middle/astencode.rs:
804:     fn emit_ty(&mut self, ecx: &e::EncodeContext, ty: ty::t) {
805:         self.emit_opaque(|this| Ok(e::write_type(ecx, this, ty)));
806:     }
librustc/metadata/encoder.rs:
219:     ebml_w.start_tag(tag_items_data_item_type);
220:     write_type(ecx, ebml_w, typ);
221:     ebml_w.end_tag();


librustc/metadata/encoder.rs:714:1-714:1 -fn- definition:
fn encode_method_ty_fields(ecx: &EncodeContext,
                           ebml_w: &mut Encoder,
                           method_ty: &ty::Method) {
references:- 2
1145:             encode_method_ty_fields(ecx, ebml_w, &*method_ty);


librustc/metadata/encoder.rs:473:76-473:76 -fn- definition:
/// * For newtype structs, iterates through the node ID of the constructor.
fn each_auxiliary_node_id(item: @Item, callback: |NodeId| -> bool) -> bool {
    let mut continue_ = true;
references:- 2
553:         each_auxiliary_node_id(*item, |auxiliary_node_id| {
554:             ebml_w.start_tag(tag_mod_child);
--
1653:         each_auxiliary_node_id(item, |auxiliary_node_id| {
1654:             ebml_w.start_tag(tag_mod_child);


librustc/metadata/encoder.rs:68:1-68:1 -struct- definition:
pub struct EncodeParams<'a> {
    pub diag: &'a SpanHandler,
    pub tcx: &'a ty::ctxt,
references:- 5
1723: pub fn encode_metadata(parms: EncodeParams, krate: &Crate) -> Vec<u8> {
1724:     let mut wr = MemWriter::new();
--
1757:     };
1758:     let EncodeParams {
1759:         item_symbols,
librustc/middle/trans/base.rs:
2084: pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::EncodeInlinedItem<'r>)
2085:     -> encoder::EncodeParams<'r> {
2086:         encoder::EncodeParams {
2087:             diag: cx.sess().diagnostic(),


librustc/metadata/encoder.rs:801:1-801:1 -fn- definition:
fn should_inline(attrs: &[Attribute]) -> bool {
    use syntax::attr::*;
    match find_inline_attr(attrs) {
references:- 2
904:         encode_attributes(ebml_w, item.attrs.as_slice());
905:         if tps_len > 0u || should_inline(item.attrs.as_slice()) {
906:             encode_inlined_item(ecx, ebml_w, IIItemRef(item));


librustc/metadata/encoder.rs:187:1-187:1 -fn- definition:
fn encode_bounds_and_type(ebml_w: &mut Encoder,
                          ecx: &EncodeContext,
                          tpt: &ty::ty_param_bounds_and_ty) {
references:- 11
957:         encode_item_variances(ebml_w, ecx, item.id);
958:         encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(tcx, def_id));
959:         encode_name(ebml_w, item.ident.name);
--
1217:         encode_family(ebml_w, style_fn_family(NormalFn));
1218:         encode_bounds_and_type(ebml_w, ecx,
1219:                                &lookup_item_type(ecx.tcx,local_def(nitem.id)));


librustc/metadata/encoder.rs:178:1-178:1 -fn- definition:
fn encode_item_variances(ebml_w: &mut Encoder,
                         ecx: &EncodeContext,
                         id: ast::NodeId) {
references:- 3
1094:         encode_family(ebml_w, 'I');
1095:         encode_item_variances(ebml_w, ecx, item.id);
1096:         let trait_def = ty::lookup_trait_def(tcx, def_id);


librustc/metadata/encoder.rs:135:28-135:28 -fn- definition:
// Item info table encoding
fn encode_family(ebml_w: &mut Encoder, c: char) {
    ebml_w.start_tag(tag_items_data_item_family);
references:- 21
877:         if m == ast::MutMutable {
878:             encode_family(ebml_w, 'b');
879:         } else {
--
1228:         if mutbl {
1229:             encode_family(ebml_w, 'b');
1230:         } else {
1231:             encode_family(ebml_w, 'c');
1232:         }


librustc/metadata/encoder.rs:631:1-631:1 -fn- definition:
fn encode_method_sort(ebml_w: &mut Encoder, sort: char) {
    ebml_w.start_tag(tag_item_trait_method_sort);
    ebml_w.writer.write(&[ sort as u8 ]);
references:- 2
1171:                     encode_attributes(ebml_w, tm.attrs.as_slice());
1172:                     encode_method_sort(ebml_w, 'r');
1173:                 }
--
1183:                     }
1184:                     encode_method_sort(ebml_w, 'p');
1185:                     encode_inlined_item(ecx, ebml_w,


librustc/metadata/encoder.rs:1276:1-1276:1 -struct- definition:
struct EncodeVisitor<'a,'b> {
    ebml_w_for_visit_item: &'a mut Encoder<'b>,
    ecx_ptr:*int,
references:- 2
1323:     let ecx_ptr: *int = unsafe { cast::transmute(ecx) };
1324:     visit::walk_crate(&mut EncodeVisitor {
1325:         index: &mut index,


librustc/metadata/encoder.rs:239:1-239:1 -fn- definition:
fn encode_symbol(ecx: &EncodeContext,
                 ebml_w: &mut Encoder,
                 id: NodeId) {
references:- 7
323:                     if args.len() > 0 && generics.ty_params.len() == 0 => {
324:                 encode_symbol(ecx, ebml_w, variant.node.id);
325:             }
--
882:         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
883:         encode_symbol(ecx, ebml_w, item.id);
884:         encode_name(ebml_w, item.ident.name);
--
1233:         encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
1234:         encode_symbol(ecx, ebml_w, nitem.id);
1235:         encode_name(ebml_w, nitem.ident.name);


librustc/metadata/encoder.rs:810:79-810:79 -fn- definition:
// Encodes the inherent implementations of a structure, enumeration, or trait.
fn encode_inherent_implementations(ecx: &EncodeContext,
                                   ebml_w: &mut Encoder,
references:- 3
1014:         // Encode inherent implementations for this structure.
1015:         encode_inherent_implementations(ecx, ebml_w, def_id);
--
1193:         // Encode inherent implementations for this trait.
1194:         encode_inherent_implementations(ecx, ebml_w, def_id);
1195:       }


librustc/metadata/encoder.rs:64:1-64:1 -NK_AS_STR_TODO- definition:
pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
                                  ebml_w: &mut Encoder,
                                  ii: InlinedItemRef|: 'a;
references:- 5
76:     pub cstore: &'a cstore::CStore,
77:     pub encode_inlined_item: EncodeInlinedItem<'a>,
78: }
--
87:     pub cstore: &'a cstore::CStore,
88:     pub encode_inlined_item: RefCell<EncodeInlinedItem<'a>>,
89:     pub type_abbrevs: tyencode::abbrev_map,
--
782:     let mut eii = ecx.encode_inlined_item.borrow_mut();
783:     let eii: &mut EncodeInlinedItem = &mut *eii;
784:     (*eii)(ecx, ebml_w, ii)
librustc/middle/trans/base.rs:
2084: pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::EncodeInlinedItem<'r>)
2085:     -> encoder::EncodeParams<'r> {
--
2108:     let encode_inlined_item: encoder::EncodeInlinedItem =
2109:         |ecx, ebml_w, ii| astencode::encode_inlined_item(ecx, ebml_w, ii);


librustc/metadata/encoder.rs:265:1-265:1 -fn- definition:
fn encode_parent_item(ebml_w: &mut Encoder, id: DefId) {
    ebml_w.start_tag(tag_items_data_parent_item);
    let s = def_to_str(id);
references:- 4
748:     encode_method_ty_fields(ecx, ebml_w, m);
749:     encode_parent_item(ebml_w, local_def(parent_id));
--
1147:             encode_parent_item(ebml_w, def_id);


librustc/metadata/encoder.rs:595:1-595:1 -fn- definition:
fn encode_visibility(ebml_w: &mut Encoder, visibility: Visibility) {
    ebml_w.start_tag(tag_items_data_item_visibility);
    let ch = match visibility {
references:- 10
891:         }
892:         encode_visibility(ebml_w, vis);
893:         ebml_w.end_tag();
--
936:         }
937:         encode_visibility(ebml_w, vis);
938:         ebml_w.end_tag();
--
970:         encode_visibility(ebml_w, vis);
971:         ebml_w.end_tag();
--
1106:         encode_sized(ebml_w, sized);
1107:         encode_visibility(ebml_w, vis);
1108:         for &method_def_id in ty::trait_method_def_ids(tcx, def_id).iter() {


librustc/metadata/encoder.rs:162:1-162:1 -fn- definition:
fn encode_region_param_defs(ebml_w: &mut Encoder,
                            params: &[ty::RegionParameterDef]) {
    for param in params.iter() {
references:- 2
192:                               tag_items_data_item_ty_param_bounds);
193:     encode_region_param_defs(ebml_w, tpt.generics.region_param_defs());
194:     encode_type(ecx, ebml_w, tpt.ty);
--
1099:                                   tag_items_data_item_ty_param_bounds);
1100:         encode_region_param_defs(ebml_w, trait_def.generics.region_param_defs());
1101:         encode_trait_ref(ebml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);


librustc/metadata/encoder.rs:1588:1-1588:1 -struct- definition:
struct ImplVisitor<'a,'b,'c> {
    ecx: &'a EncodeContext<'b>,
    ebml_w: &'a mut Encoder<'c>,
references:- 2
1594: impl<'a,'b,'c> Visitor<()> for ImplVisitor<'a,'b,'c> {
1595:     fn visit_item(&mut self, item: &Item, _: ()) {
--
1632:     {
1633:         let mut visitor = ImplVisitor {
1634:             ecx: ecx,


librustc/metadata/encoder.rs:1416:1-1416:1 -fn- definition:
fn encode_attributes(ebml_w: &mut Encoder, attrs: &[Attribute]) {
    ebml_w.start_tag(tag_attributes);
    for attr in attrs.iter() {
references:- 10
1002:         encode_name(ebml_w, item.ident.name);
1003:         encode_attributes(ebml_w, item.attrs.as_slice());
1004:         encode_path(ebml_w, path.clone());
--
1041:         encode_name(ebml_w, item.ident.name);
1042:         encode_attributes(ebml_w, item.attrs.as_slice());
1043:         match ty.node {
--
1170:                 &Required(ref tm) => {
1171:                     encode_attributes(ebml_w, tm.attrs.as_slice());
1172:                     encode_method_sort(ebml_w, 'r');
--
1789:     let crate_attrs = synthesize_crate_attrs(&ecx, krate);
1790:     encode_attributes(&mut ebml_w, crate_attrs.as_slice());
1791:     stats.attr_bytes = ebml_w.writer.tell().unwrap() - i;


librustc/metadata/encoder.rs:1379:1-1379:1 -fn- definition:
fn encode_meta_item(ebml_w: &mut Encoder, mi: @MetaItem) {
    match mi.node {
      MetaWord(ref name) => {
references:- 2
1420:         ebml_w.start_tag(tag_attribute);
1421:         encode_meta_item(ebml_w, attr.node.value);
1422:         ebml_w.end_tag();