]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/astencode.rs
core: Fix size_hint for signed integer Range<T> iterators
[rust.git] / src / librustc / middle / astencode.rs
1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
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 #![allow(non_camel_case_types)]
12 // FIXME: remove this after snapshot, and Results are handled
13 #![allow(unused_must_use)]
14
15 use metadata::common as c;
16 use metadata::cstore as cstore;
17 use session::Session;
18 use metadata::decoder;
19 use middle::def;
20 use metadata::encoder as e;
21 use middle::region;
22 use metadata::tydecode;
23 use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter};
24 use metadata::tydecode::{RegionParameter, ClosureSource};
25 use metadata::tyencode;
26 use middle::check_const::ConstQualif;
27 use middle::mem_categorization::Typer;
28 use middle::privacy::{AllPublic, LastMod};
29 use middle::subst;
30 use middle::subst::VecPerParamSpace;
31 use middle::ty::{self, Ty, MethodCall, MethodCallee, MethodOrigin};
32 use util::ppaux::ty_to_string;
33
34 use syntax::{ast, ast_map, ast_util, codemap, fold};
35 use syntax::codemap::Span;
36 use syntax::fold::Folder;
37 use syntax::parse::token;
38 use syntax::ptr::P;
39 use syntax;
40
41 use std::cell::Cell;
42 use std::io::SeekFrom;
43 use std::io::prelude::*;
44 use std::rc::Rc;
45 use std::fmt::Debug;
46
47 use rbml::reader;
48 use rbml::writer::Encoder;
49 use rbml;
50 use serialize;
51 use serialize::{Decodable, Decoder, DecoderHelpers, Encodable};
52 use serialize::EncoderHelpers;
53
54 #[cfg(test)] use std::io::Cursor;
55 #[cfg(test)] use syntax::parse;
56 #[cfg(test)] use syntax::print::pprust;
57
58 struct DecodeContext<'a, 'b, 'tcx: 'a> {
59     tcx: &'a ty::ctxt<'tcx>,
60     cdata: &'b cstore::crate_metadata,
61     from_id_range: ast_util::IdRange,
62     to_id_range: ast_util::IdRange,
63     // Cache the last used filemap for translating spans as an optimization.
64     last_filemap_index: Cell<usize>,
65 }
66
67 trait tr {
68     fn tr(&self, dcx: &DecodeContext) -> Self;
69 }
70
71 trait tr_intern {
72     fn tr_intern(&self, dcx: &DecodeContext) -> ast::DefId;
73 }
74
75 // ______________________________________________________________________
76 // Top-level methods.
77
78 pub fn encode_inlined_item(ecx: &e::EncodeContext,
79                            rbml_w: &mut Encoder,
80                            ii: e::InlinedItemRef) {
81     let id = match ii {
82         e::IIItemRef(i) => i.id,
83         e::IIForeignRef(i) => i.id,
84         e::IITraitItemRef(_, ti) => ti.id,
85         e::IIImplItemRef(_, ii) => ii.id,
86     };
87     debug!("> Encoding inlined item: {} ({:?})",
88            ecx.tcx.map.path_to_string(id),
89            rbml_w.writer.seek(SeekFrom::Current(0)));
90
91     // Folding could be avoided with a smarter encoder.
92     let ii = simplify_ast(ii);
93     let id_range = ast_util::compute_id_range_for_inlined_item(&ii);
94
95     rbml_w.start_tag(c::tag_ast as usize);
96     id_range.encode(rbml_w);
97     encode_ast(rbml_w, &ii);
98     encode_side_tables_for_ii(ecx, rbml_w, &ii);
99     rbml_w.end_tag();
100
101     debug!("< Encoded inlined fn: {} ({:?})",
102            ecx.tcx.map.path_to_string(id),
103            rbml_w.writer.seek(SeekFrom::Current(0)));
104 }
105
106 impl<'a, 'b, 'c, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'c, 'tcx> {
107     fn new_id(&self, id: ast::NodeId) -> ast::NodeId {
108         if id == ast::DUMMY_NODE_ID {
109             // Used by ast_map to map the NodeInlinedParent.
110             self.tcx.sess.next_node_id()
111         } else {
112             self.tr_id(id)
113         }
114     }
115     fn new_def_id(&self, def_id: ast::DefId) -> ast::DefId {
116         self.tr_def_id(def_id)
117     }
118     fn new_span(&self, span: Span) -> Span {
119         self.tr_span(span)
120     }
121 }
122
123 /// Decodes an item from its AST in the cdata's metadata and adds it to the
124 /// ast-map.
125 pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
126                                  tcx: &ty::ctxt<'tcx>,
127                                  path: Vec<ast_map::PathElem>,
128                                  par_doc: rbml::Doc)
129                                  -> Result<&'tcx ast::InlinedItem, Vec<ast_map::PathElem>> {
130     match par_doc.opt_child(c::tag_ast) {
131       None => Err(path),
132       Some(ast_doc) => {
133         let mut path_as_str = None;
134         debug!("> Decoding inlined fn: {:?}::?",
135         {
136             // Do an Option dance to use the path after it is moved below.
137             let s = ast_map::path_to_string(path.iter().cloned());
138             path_as_str = Some(s);
139             path_as_str.as_ref().map(|x| &x[..])
140         });
141         let mut ast_dsr = reader::Decoder::new(ast_doc);
142         let from_id_range = Decodable::decode(&mut ast_dsr).unwrap();
143         let to_id_range = reserve_id_range(&tcx.sess, from_id_range);
144         let dcx = &DecodeContext {
145             cdata: cdata,
146             tcx: tcx,
147             from_id_range: from_id_range,
148             to_id_range: to_id_range,
149             last_filemap_index: Cell::new(0)
150         };
151         let raw_ii = decode_ast(ast_doc);
152         let ii = ast_map::map_decoded_item(&dcx.tcx.map, path, raw_ii, dcx);
153
154         let ident = match *ii {
155             ast::IIItem(ref i) => i.ident,
156             ast::IIForeign(ref i) => i.ident,
157             ast::IITraitItem(_, ref ti) => ti.ident,
158             ast::IIImplItem(_, ref ii) => ii.ident
159         };
160         debug!("Fn named: {}", token::get_ident(ident));
161         debug!("< Decoded inlined fn: {}::{}",
162                path_as_str.unwrap(),
163                token::get_ident(ident));
164         region::resolve_inlined_item(&tcx.sess, &tcx.region_maps, ii);
165         decode_side_tables(dcx, ast_doc);
166         match *ii {
167           ast::IIItem(ref i) => {
168             debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<",
169                    syntax::print::pprust::item_to_string(&**i));
170           }
171           _ => { }
172         }
173         Ok(ii)
174       }
175     }
176 }
177
178 // ______________________________________________________________________
179 // Enumerating the IDs which appear in an AST
180
181 fn reserve_id_range(sess: &Session,
182                     from_id_range: ast_util::IdRange) -> ast_util::IdRange {
183     // Handle the case of an empty range:
184     if from_id_range.empty() { return from_id_range; }
185     let cnt = from_id_range.max - from_id_range.min;
186     let to_id_min = sess.reserve_node_ids(cnt);
187     let to_id_max = to_id_min + cnt;
188     ast_util::IdRange { min: to_id_min, max: to_id_max }
189 }
190
191 impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> {
192     /// Translates an internal id, meaning a node id that is known to refer to some part of the
193     /// item currently being inlined, such as a local variable or argument.  All naked node-ids
194     /// that appear in types have this property, since if something might refer to an external item
195     /// we would use a def-id to allow for the possibility that the item resides in another crate.
196     pub fn tr_id(&self, id: ast::NodeId) -> ast::NodeId {
197         // from_id_range should be non-empty
198         assert!(!self.from_id_range.empty());
199         // Use wrapping arithmetic because otherwise it introduces control flow.
200         // Maybe we should just have the control flow? -- aatch
201         (id.wrapping_sub(self.from_id_range.min).wrapping_add(self.to_id_range.min))
202     }
203
204     /// Translates an EXTERNAL def-id, converting the crate number from the one used in the encoded
205     /// data to the current crate numbers..  By external, I mean that it be translated to a
206     /// reference to the item in its original crate, as opposed to being translated to a reference
207     /// to the inlined version of the item.  This is typically, but not always, what you want,
208     /// because most def-ids refer to external things like types or other fns that may or may not
209     /// be inlined.  Note that even when the inlined function is referencing itself recursively, we
210     /// would want `tr_def_id` for that reference--- conceptually the function calls the original,
211     /// non-inlined version, and trans deals with linking that recursive call to the inlined copy.
212     ///
213     /// However, there are a *few* cases where def-ids are used but we know that the thing being
214     /// referenced is in fact *internal* to the item being inlined.  In those cases, you should use
215     /// `tr_intern_def_id()` below.
216     pub fn tr_def_id(&self, did: ast::DefId) -> ast::DefId {
217
218         decoder::translate_def_id(self.cdata, did)
219     }
220
221     /// Translates an INTERNAL def-id, meaning a def-id that is
222     /// known to refer to some part of the item currently being
223     /// inlined.  In that case, we want to convert the def-id to
224     /// refer to the current crate and to the new, inlined node-id.
225     pub fn tr_intern_def_id(&self, did: ast::DefId) -> ast::DefId {
226         assert_eq!(did.krate, ast::LOCAL_CRATE);
227         ast::DefId { krate: ast::LOCAL_CRATE, node: self.tr_id(did.node) }
228     }
229
230     /// Translates a `Span` from an extern crate to the corresponding `Span`
231     /// within the local crate's codemap. `creader::import_codemap()` will
232     /// already have allocated any additionally needed FileMaps in the local
233     /// codemap as a side-effect of creating the crate_metadata's
234     /// `codemap_import_info`.
235     pub fn tr_span(&self, span: Span) -> Span {
236         let imported_filemaps = &self.cdata.codemap_import_info[..];
237
238         let span = if span.lo > span.hi {
239             // Currently macro expansion sometimes produces invalid Span values
240             // where lo > hi. In order not to crash the compiler when trying to
241             // translate these values, let's transform them into something we
242             // can handle (and which will produce useful debug locations at
243             // least some of the time).
244             // This workaround is only necessary as long as macro expansion is
245             // not fixed. FIXME(#23480)
246             codemap::mk_sp(span.lo, span.lo)
247         } else {
248             span
249         };
250
251         let filemap_index = {
252             // Optimize for the case that most spans within a translated item
253             // originate from the same filemap.
254             let last_filemap_index = self.last_filemap_index.get();
255
256             if span.lo >= imported_filemaps[last_filemap_index].original_start_pos &&
257                span.lo <= imported_filemaps[last_filemap_index].original_end_pos &&
258                span.hi >= imported_filemaps[last_filemap_index].original_start_pos &&
259                span.hi <= imported_filemaps[last_filemap_index].original_end_pos {
260                 last_filemap_index
261             } else {
262                 let mut a = 0;
263                 let mut b = imported_filemaps.len();
264
265                 while b - a > 1 {
266                     let m = (a + b) / 2;
267                     if imported_filemaps[m].original_start_pos > span.lo {
268                         b = m;
269                     } else {
270                         a = m;
271                     }
272                 }
273
274                 self.last_filemap_index.set(a);
275                 a
276             }
277         };
278
279         let lo = (span.lo - imported_filemaps[filemap_index].original_start_pos) +
280                   imported_filemaps[filemap_index].translated_filemap.start_pos;
281         let hi = (span.hi - imported_filemaps[filemap_index].original_start_pos) +
282                   imported_filemaps[filemap_index].translated_filemap.start_pos;
283
284         codemap::mk_sp(lo, hi)
285     }
286 }
287
288 impl tr_intern for ast::DefId {
289     fn tr_intern(&self, dcx: &DecodeContext) -> ast::DefId {
290         dcx.tr_intern_def_id(*self)
291     }
292 }
293
294 impl tr for ast::DefId {
295     fn tr(&self, dcx: &DecodeContext) -> ast::DefId {
296         dcx.tr_def_id(*self)
297     }
298 }
299
300 impl tr for Option<ast::DefId> {
301     fn tr(&self, dcx: &DecodeContext) -> Option<ast::DefId> {
302         self.map(|d| dcx.tr_def_id(d))
303     }
304 }
305
306 impl tr for Span {
307     fn tr(&self, dcx: &DecodeContext) -> Span {
308         dcx.tr_span(*self)
309     }
310 }
311
312 trait def_id_encoder_helpers {
313     fn emit_def_id(&mut self, did: ast::DefId);
314 }
315
316 impl<S:serialize::Encoder> def_id_encoder_helpers for S
317     where <S as serialize::serialize::Encoder>::Error: Debug
318 {
319     fn emit_def_id(&mut self, did: ast::DefId) {
320         did.encode(self).unwrap()
321     }
322 }
323
324 trait def_id_decoder_helpers {
325     fn read_def_id(&mut self, dcx: &DecodeContext) -> ast::DefId;
326     fn read_def_id_nodcx(&mut self,
327                          cdata: &cstore::crate_metadata) -> ast::DefId;
328 }
329
330 impl<D:serialize::Decoder> def_id_decoder_helpers for D
331     where <D as serialize::serialize::Decoder>::Error: Debug
332 {
333     fn read_def_id(&mut self, dcx: &DecodeContext) -> ast::DefId {
334         let did: ast::DefId = Decodable::decode(self).unwrap();
335         did.tr(dcx)
336     }
337
338     fn read_def_id_nodcx(&mut self,
339                          cdata: &cstore::crate_metadata)
340                          -> ast::DefId {
341         let did: ast::DefId = Decodable::decode(self).unwrap();
342         decoder::translate_def_id(cdata, did)
343     }
344 }
345
346 // ______________________________________________________________________
347 // Encoding and decoding the AST itself
348 //
349 // The hard work is done by an autogenerated module astencode_gen.  To
350 // regenerate astencode_gen, run src/etc/gen-astencode.  It will
351 // replace astencode_gen with a dummy file and regenerate its
352 // contents.  If you get compile errors, the dummy file
353 // remains---resolve the errors and then rerun astencode_gen.
354 // Annoying, I know, but hopefully only temporary.
355 //
356 // When decoding, we have to renumber the AST so that the node ids that
357 // appear within are disjoint from the node ids in our existing ASTs.
358 // We also have to adjust the spans: for now we just insert a dummy span,
359 // but eventually we should add entries to the local codemap as required.
360
361 fn encode_ast(rbml_w: &mut Encoder, item: &ast::InlinedItem) {
362     rbml_w.start_tag(c::tag_tree as usize);
363     item.encode(rbml_w);
364     rbml_w.end_tag();
365 }
366
367 struct NestedItemsDropper;
368
369 impl Folder for NestedItemsDropper {
370     fn fold_block(&mut self, blk: P<ast::Block>) -> P<ast::Block> {
371         blk.and_then(|ast::Block {id, stmts, expr, rules, span, ..}| {
372             let stmts_sans_items = stmts.into_iter().filter_map(|stmt| {
373                 let use_stmt = match stmt.node {
374                     ast::StmtExpr(_, _) | ast::StmtSemi(_, _) => true,
375                     ast::StmtDecl(ref decl, _) => {
376                         match decl.node {
377                             ast::DeclLocal(_) => true,
378                             ast::DeclItem(_) => false,
379                         }
380                     }
381                     ast::StmtMac(..) => panic!("unexpanded macro in astencode")
382                 };
383                 if use_stmt {
384                     Some(stmt)
385                 } else {
386                     None
387                 }
388             }).collect();
389             let blk_sans_items = P(ast::Block {
390                 stmts: stmts_sans_items,
391                 expr: expr,
392                 id: id,
393                 rules: rules,
394                 span: span,
395             });
396             fold::noop_fold_block(blk_sans_items, self)
397         })
398     }
399 }
400
401 // Produces a simplified copy of the AST which does not include things
402 // that we do not need to or do not want to export.  For example, we
403 // do not include any nested items: if these nested items are to be
404 // inlined, their AST will be exported separately (this only makes
405 // sense because, in Rust, nested items are independent except for
406 // their visibility).
407 //
408 // As it happens, trans relies on the fact that we do not export
409 // nested items, as otherwise it would get confused when translating
410 // inlined items.
411 fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem {
412     let mut fld = NestedItemsDropper;
413
414     match ii {
415         // HACK we're not dropping items.
416         e::IIItemRef(i) => {
417             ast::IIItem(fold::noop_fold_item(P(i.clone()), &mut fld)
418                             .expect_one("expected one item"))
419         }
420         e::IITraitItemRef(d, ti) => {
421             ast::IITraitItem(d,
422                 fold::noop_fold_trait_item(P(ti.clone()), &mut fld)
423                     .expect_one("noop_fold_trait_item must produce \
424                                  exactly one trait item"))
425         }
426         e::IIImplItemRef(d, ii) => {
427             ast::IIImplItem(d,
428                 fold::noop_fold_impl_item(P(ii.clone()), &mut fld)
429                     .expect_one("noop_fold_impl_item must produce \
430                                  exactly one impl item"))
431         }
432         e::IIForeignRef(i) => {
433             ast::IIForeign(fold::noop_fold_foreign_item(P(i.clone()), &mut fld))
434         }
435     }
436 }
437
438 fn decode_ast(par_doc: rbml::Doc) -> ast::InlinedItem {
439     let chi_doc = par_doc.get(c::tag_tree as usize);
440     let mut d = reader::Decoder::new(chi_doc);
441     Decodable::decode(&mut d).unwrap()
442 }
443
444 // ______________________________________________________________________
445 // Encoding and decoding of ast::def
446
447 fn decode_def(dcx: &DecodeContext, dsr: &mut reader::Decoder) -> def::Def {
448     let def: def::Def = Decodable::decode(dsr).unwrap();
449     def.tr(dcx)
450 }
451
452 impl tr for def::Def {
453     fn tr(&self, dcx: &DecodeContext) -> def::Def {
454         match *self {
455           def::DefFn(did, is_ctor) => def::DefFn(did.tr(dcx), is_ctor),
456           def::DefMethod(did, p) => {
457             def::DefMethod(did.tr(dcx), p.map(|did2| did2.tr(dcx)))
458           }
459           def::DefSelfTy(opt_did, impl_ids) => { def::DefSelfTy(opt_did.map(|did| did.tr(dcx)),
460                                                                 impl_ids.map(|(nid1, nid2)| {
461                                                                     (dcx.tr_id(nid1),
462                                                                      dcx.tr_id(nid2))
463                                                                 })) }
464           def::DefMod(did) => { def::DefMod(did.tr(dcx)) }
465           def::DefForeignMod(did) => { def::DefForeignMod(did.tr(dcx)) }
466           def::DefStatic(did, m) => { def::DefStatic(did.tr(dcx), m) }
467           def::DefConst(did) => { def::DefConst(did.tr(dcx)) }
468           def::DefLocal(nid) => { def::DefLocal(dcx.tr_id(nid)) }
469           def::DefVariant(e_did, v_did, is_s) => {
470             def::DefVariant(e_did.tr(dcx), v_did.tr(dcx), is_s)
471           },
472           def::DefTrait(did) => def::DefTrait(did.tr(dcx)),
473           def::DefTy(did, is_enum) => def::DefTy(did.tr(dcx), is_enum),
474           def::DefAssociatedTy(trait_did, did) =>
475               def::DefAssociatedTy(trait_did.tr(dcx), did.tr(dcx)),
476           def::DefPrimTy(p) => def::DefPrimTy(p),
477           def::DefTyParam(s, index, def_id, n) => def::DefTyParam(s, index, def_id.tr(dcx), n),
478           def::DefUse(did) => def::DefUse(did.tr(dcx)),
479           def::DefUpvar(nid1, nid2) => {
480             def::DefUpvar(dcx.tr_id(nid1), dcx.tr_id(nid2))
481           }
482           def::DefStruct(did) => def::DefStruct(did.tr(dcx)),
483           def::DefRegion(nid) => def::DefRegion(dcx.tr_id(nid)),
484           def::DefLabel(nid) => def::DefLabel(dcx.tr_id(nid))
485         }
486     }
487 }
488
489 // ______________________________________________________________________
490 // Encoding and decoding of ancillary information
491
492 impl tr for ty::Region {
493     fn tr(&self, dcx: &DecodeContext) -> ty::Region {
494         match *self {
495             ty::ReLateBound(debruijn, br) => {
496                 ty::ReLateBound(debruijn, br.tr(dcx))
497             }
498             ty::ReEarlyBound(data) => {
499                 ty::ReEarlyBound(ty::EarlyBoundRegion {
500                     param_id: dcx.tr_id(data.param_id),
501                     space: data.space,
502                     index: data.index,
503                     name: data.name,
504                 })
505             }
506             ty::ReScope(scope) => {
507                 ty::ReScope(scope.tr(dcx))
508             }
509             ty::ReEmpty | ty::ReStatic | ty::ReInfer(..) => {
510                 *self
511             }
512             ty::ReFree(ref fr) => {
513                 ty::ReFree(fr.tr(dcx))
514             }
515         }
516     }
517 }
518
519 impl tr for ty::FreeRegion {
520     fn tr(&self, dcx: &DecodeContext) -> ty::FreeRegion {
521         ty::FreeRegion { scope: self.scope.tr(dcx),
522                          bound_region: self.bound_region.tr(dcx) }
523     }
524 }
525
526 impl tr for region::CodeExtent {
527     fn tr(&self, dcx: &DecodeContext) -> region::CodeExtent {
528         self.map_id(|id| dcx.tr_id(id))
529     }
530 }
531
532 impl tr for region::DestructionScopeData {
533     fn tr(&self, dcx: &DecodeContext) -> region::DestructionScopeData {
534         region::DestructionScopeData { node_id: dcx.tr_id(self.node_id) }
535     }
536 }
537
538 impl tr for ty::BoundRegion {
539     fn tr(&self, dcx: &DecodeContext) -> ty::BoundRegion {
540         match *self {
541             ty::BrAnon(_) |
542             ty::BrFresh(_) |
543             ty::BrEnv => *self,
544             ty::BrNamed(id, ident) => ty::BrNamed(dcx.tr_def_id(id),
545                                                     ident),
546         }
547     }
548 }
549
550 // ______________________________________________________________________
551 // Encoding and decoding of freevar information
552
553 fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &ty::Freevar) {
554     (*fv).encode(rbml_w).unwrap();
555 }
556
557 trait rbml_decoder_helper {
558     fn read_freevar_entry(&mut self, dcx: &DecodeContext)
559                           -> ty::Freevar;
560     fn read_capture_mode(&mut self) -> ast::CaptureClause;
561 }
562
563 impl<'a> rbml_decoder_helper for reader::Decoder<'a> {
564     fn read_freevar_entry(&mut self, dcx: &DecodeContext)
565                           -> ty::Freevar {
566         let fv: ty::Freevar = Decodable::decode(self).unwrap();
567         fv.tr(dcx)
568     }
569
570     fn read_capture_mode(&mut self) -> ast::CaptureClause {
571         let cm: ast::CaptureClause = Decodable::decode(self).unwrap();
572         cm
573     }
574 }
575
576 impl tr for ty::Freevar {
577     fn tr(&self, dcx: &DecodeContext) -> ty::Freevar {
578         ty::Freevar {
579             def: self.def.tr(dcx),
580             span: self.span.tr(dcx),
581         }
582     }
583 }
584
585 impl tr for ty::UpvarBorrow {
586     fn tr(&self, dcx: &DecodeContext) -> ty::UpvarBorrow {
587         ty::UpvarBorrow {
588             kind: self.kind,
589             region: self.region.tr(dcx)
590         }
591     }
592 }
593
594 impl tr for ty::UpvarCapture {
595     fn tr(&self, dcx: &DecodeContext) -> ty::UpvarCapture {
596         match *self {
597             ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
598             ty::UpvarCapture::ByRef(ref data) => ty::UpvarCapture::ByRef(data.tr(dcx)),
599         }
600     }
601 }
602
603 // ______________________________________________________________________
604 // Encoding and decoding of MethodCallee
605
606 trait read_method_callee_helper<'tcx> {
607     fn read_method_callee<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
608                                   -> (u32, MethodCallee<'tcx>);
609 }
610
611 fn encode_method_callee<'a, 'tcx>(ecx: &e::EncodeContext<'a, 'tcx>,
612                                   rbml_w: &mut Encoder,
613                                   autoderef: u32,
614                                   method: &MethodCallee<'tcx>) {
615     use serialize::Encoder;
616
617     rbml_w.emit_struct("MethodCallee", 4, |rbml_w| {
618         rbml_w.emit_struct_field("autoderef", 0, |rbml_w| {
619             autoderef.encode(rbml_w)
620         });
621         rbml_w.emit_struct_field("origin", 1, |rbml_w| {
622             Ok(rbml_w.emit_method_origin(ecx, &method.origin))
623         });
624         rbml_w.emit_struct_field("ty", 2, |rbml_w| {
625             Ok(rbml_w.emit_ty(ecx, method.ty))
626         });
627         rbml_w.emit_struct_field("substs", 3, |rbml_w| {
628             Ok(rbml_w.emit_substs(ecx, &method.substs))
629         })
630     }).unwrap();
631 }
632
633 impl<'a, 'tcx> read_method_callee_helper<'tcx> for reader::Decoder<'a> {
634     fn read_method_callee<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
635                                   -> (u32, MethodCallee<'tcx>) {
636
637         self.read_struct("MethodCallee", 4, |this| {
638             let autoderef = this.read_struct_field("autoderef", 0, |this| {
639                 Decodable::decode(this)
640             }).unwrap();
641             Ok((autoderef, MethodCallee {
642                 origin: this.read_struct_field("origin", 1, |this| {
643                     Ok(this.read_method_origin(dcx))
644                 }).unwrap(),
645                 ty: this.read_struct_field("ty", 2, |this| {
646                     Ok(this.read_ty(dcx))
647                 }).unwrap(),
648                 substs: this.read_struct_field("substs", 3, |this| {
649                     Ok(this.read_substs(dcx))
650                 }).unwrap()
651             }))
652         }).unwrap()
653     }
654 }
655
656 impl<'tcx> tr for MethodOrigin<'tcx> {
657     fn tr(&self, dcx: &DecodeContext) -> MethodOrigin<'tcx> {
658         match *self {
659             ty::MethodStatic(did) => ty::MethodStatic(did.tr(dcx)),
660             ty::MethodStaticClosure(did) => {
661                 ty::MethodStaticClosure(did.tr(dcx))
662             }
663             ty::MethodTypeParam(ref mp) => {
664                 ty::MethodTypeParam(
665                     ty::MethodParam {
666                         // def-id is already translated when we read it out
667                         trait_ref: mp.trait_ref.clone(),
668                         method_num: mp.method_num,
669                         impl_def_id: mp.impl_def_id.tr(dcx),
670                     }
671                 )
672             }
673             ty::MethodTraitObject(ref mo) => {
674                 ty::MethodTraitObject(
675                     ty::MethodObject {
676                         trait_ref: mo.trait_ref.clone(),
677                         .. *mo
678                     }
679                 )
680             }
681         }
682     }
683 }
684
685 pub fn encode_closure_kind(ebml_w: &mut Encoder, kind: ty::ClosureKind) {
686     kind.encode(ebml_w).unwrap();
687 }
688
689 pub trait vtable_decoder_helpers<'tcx> {
690     fn read_vec_per_param_space<T, F>(&mut self, f: F) -> VecPerParamSpace<T> where
691         F: FnMut(&mut Self) -> T;
692     fn read_vtable_res_with_key(&mut self,
693                                 tcx: &ty::ctxt<'tcx>,
694                                 cdata: &cstore::crate_metadata)
695                                 -> (u32, ty::vtable_res<'tcx>);
696     fn read_vtable_res(&mut self,
697                        tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata)
698                       -> ty::vtable_res<'tcx>;
699     fn read_vtable_param_res(&mut self,
700                        tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata)
701                       -> ty::vtable_param_res<'tcx>;
702     fn read_vtable_origin(&mut self,
703                           tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata)
704                           -> ty::vtable_origin<'tcx>;
705 }
706
707 impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
708     fn read_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
709         F: FnMut(&mut reader::Decoder<'a>) -> T,
710     {
711         let types = self.read_to_vec(|this| Ok(f(this))).unwrap();
712         let selfs = self.read_to_vec(|this| Ok(f(this))).unwrap();
713         let fns = self.read_to_vec(|this| Ok(f(this))).unwrap();
714         VecPerParamSpace::new(types, selfs, fns)
715     }
716
717     fn read_vtable_res_with_key(&mut self,
718                                 tcx: &ty::ctxt<'tcx>,
719                                 cdata: &cstore::crate_metadata)
720                                 -> (u32, ty::vtable_res<'tcx>) {
721         self.read_struct("VtableWithKey", 2, |this| {
722             let autoderef = this.read_struct_field("autoderef", 0, |this| {
723                 Decodable::decode(this)
724             }).unwrap();
725             Ok((autoderef, this.read_struct_field("vtable_res", 1, |this| {
726                 Ok(this.read_vtable_res(tcx, cdata))
727             }).unwrap()))
728         }).unwrap()
729     }
730
731     fn read_vtable_res(&mut self,
732                        tcx: &ty::ctxt<'tcx>,
733                        cdata: &cstore::crate_metadata)
734                        -> ty::vtable_res<'tcx>
735     {
736         self.read_vec_per_param_space(
737             |this| this.read_vtable_param_res(tcx, cdata))
738     }
739
740     fn read_vtable_param_res(&mut self,
741                              tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata)
742                       -> ty::vtable_param_res<'tcx> {
743         self.read_to_vec(|this| Ok(this.read_vtable_origin(tcx, cdata)))
744              .unwrap().into_iter().collect()
745     }
746
747     fn read_vtable_origin(&mut self,
748                           tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata)
749         -> ty::vtable_origin<'tcx> {
750         self.read_enum("vtable_origin", |this| {
751             this.read_enum_variant(&["vtable_static",
752                                      "vtable_param",
753                                      "vtable_error",
754                                      "vtable_closure"],
755                                    |this, i| {
756                 Ok(match i {
757                   0 => {
758                     ty::vtable_static(
759                         this.read_enum_variant_arg(0, |this| {
760                             Ok(this.read_def_id_nodcx(cdata))
761                         }).unwrap(),
762                         this.read_enum_variant_arg(1, |this| {
763                             Ok(this.read_substs_nodcx(tcx, cdata))
764                         }).unwrap(),
765                         this.read_enum_variant_arg(2, |this| {
766                             Ok(this.read_vtable_res(tcx, cdata))
767                         }).unwrap()
768                     )
769                   }
770                   1 => {
771                     ty::vtable_param(
772                         this.read_enum_variant_arg(0, |this| {
773                             Decodable::decode(this)
774                         }).unwrap(),
775                         this.read_enum_variant_arg(1, |this| {
776                             this.read_uint()
777                         }).unwrap()
778                     )
779                   }
780                   2 => {
781                     ty::vtable_closure(
782                         this.read_enum_variant_arg(0, |this| {
783                             Ok(this.read_def_id_nodcx(cdata))
784                         }).unwrap()
785                     )
786                   }
787                   3 => {
788                     ty::vtable_error
789                   }
790                   _ => panic!("bad enum variant")
791                 })
792             })
793         }).unwrap()
794     }
795 }
796
797 // ___________________________________________________________________________
798 //
799
800 fn encode_vec_per_param_space<T, F>(rbml_w: &mut Encoder,
801                                     v: &subst::VecPerParamSpace<T>,
802                                     mut f: F) where
803     F: FnMut(&mut Encoder, &T),
804 {
805     for &space in &subst::ParamSpace::all() {
806         rbml_w.emit_from_vec(v.get_slice(space),
807                              |rbml_w, n| Ok(f(rbml_w, n))).unwrap();
808     }
809 }
810
811 // ______________________________________________________________________
812 // Encoding and decoding the side tables
813
814 trait get_ty_str_ctxt<'tcx> {
815     fn ty_str_ctxt<'a>(&'a self) -> tyencode::ctxt<'a, 'tcx>;
816 }
817
818 impl<'a, 'tcx> get_ty_str_ctxt<'tcx> for e::EncodeContext<'a, 'tcx> {
819     fn ty_str_ctxt<'b>(&'b self) -> tyencode::ctxt<'b, 'tcx> {
820         tyencode::ctxt {
821             diag: self.tcx.sess.diagnostic(),
822             ds: e::def_to_string,
823             tcx: self.tcx,
824             abbrevs: &self.type_abbrevs
825         }
826     }
827 }
828
829 trait rbml_writer_helpers<'tcx> {
830     fn emit_closure_type<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
831                              closure_type: &ty::ClosureTy<'tcx>);
832     fn emit_method_origin<'a>(&mut self,
833                               ecx: &e::EncodeContext<'a, 'tcx>,
834                               method_origin: &ty::MethodOrigin<'tcx>);
835     fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>);
836     fn emit_tys<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, tys: &[Ty<'tcx>]);
837     fn emit_type_param_def<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
838                                type_param_def: &ty::TypeParameterDef<'tcx>);
839     fn emit_predicate<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
840                           predicate: &ty::Predicate<'tcx>);
841     fn emit_trait_ref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
842                           ty: &ty::TraitRef<'tcx>);
843     fn emit_type_scheme<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
844                             type_scheme: ty::TypeScheme<'tcx>);
845     fn emit_substs<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
846                        substs: &subst::Substs<'tcx>);
847     fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>,
848                                    bounds: &ty::ExistentialBounds<'tcx>);
849     fn emit_builtin_bounds(&mut self, ecx: &e::EncodeContext, bounds: &ty::BuiltinBounds);
850     fn emit_auto_adjustment<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
851                                 adj: &ty::AutoAdjustment<'tcx>);
852     fn emit_autoref<'a>(&mut self, autoref: &ty::AutoRef<'tcx>);
853     fn emit_auto_deref_ref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
854                                auto_deref_ref: &ty::AutoDerefRef<'tcx>);
855 }
856
857 impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
858     fn emit_closure_type<'b>(&mut self,
859                              ecx: &e::EncodeContext<'b, 'tcx>,
860                              closure_type: &ty::ClosureTy<'tcx>) {
861         self.emit_opaque(|this| {
862             Ok(e::write_closure_type(ecx, this, closure_type))
863         });
864     }
865
866     fn emit_method_origin<'b>(&mut self,
867                               ecx: &e::EncodeContext<'b, 'tcx>,
868                               method_origin: &ty::MethodOrigin<'tcx>)
869     {
870         use serialize::Encoder;
871
872         self.emit_enum("MethodOrigin", |this| {
873             match *method_origin {
874                 ty::MethodStatic(def_id) => {
875                     this.emit_enum_variant("MethodStatic", 0, 1, |this| {
876                         Ok(this.emit_def_id(def_id))
877                     })
878                 }
879
880                 ty::MethodStaticClosure(def_id) => {
881                     this.emit_enum_variant("MethodStaticClosure", 1, 1, |this| {
882                         Ok(this.emit_def_id(def_id))
883                     })
884                 }
885
886                 ty::MethodTypeParam(ref p) => {
887                     this.emit_enum_variant("MethodTypeParam", 2, 1, |this| {
888                         this.emit_struct("MethodParam", 2, |this| {
889                             try!(this.emit_struct_field("trait_ref", 0, |this| {
890                                 Ok(this.emit_trait_ref(ecx, &*p.trait_ref))
891                             }));
892                             try!(this.emit_struct_field("method_num", 0, |this| {
893                                 this.emit_uint(p.method_num)
894                             }));
895                             try!(this.emit_struct_field("impl_def_id", 0, |this| {
896                                 this.emit_option(|this| {
897                                     match p.impl_def_id {
898                                         None => this.emit_option_none(),
899                                         Some(did) => this.emit_option_some(|this| {
900                                             Ok(this.emit_def_id(did))
901                                         })
902                                     }
903                                 })
904                             }));
905                             Ok(())
906                         })
907                     })
908                 }
909
910                 ty::MethodTraitObject(ref o) => {
911                     this.emit_enum_variant("MethodTraitObject", 3, 1, |this| {
912                         this.emit_struct("MethodObject", 2, |this| {
913                             try!(this.emit_struct_field("trait_ref", 0, |this| {
914                                 Ok(this.emit_trait_ref(ecx, &*o.trait_ref))
915                             }));
916                             try!(this.emit_struct_field("object_trait_id", 0, |this| {
917                                 Ok(this.emit_def_id(o.object_trait_id))
918                             }));
919                             try!(this.emit_struct_field("method_num", 0, |this| {
920                                 this.emit_uint(o.method_num)
921                             }));
922                             try!(this.emit_struct_field("vtable_index", 0, |this| {
923                                 this.emit_uint(o.vtable_index)
924                             }));
925                             Ok(())
926                         })
927                     })
928                 }
929             }
930         });
931     }
932
933     fn emit_ty<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, ty: Ty<'tcx>) {
934         self.emit_opaque(|this| Ok(e::write_type(ecx, this, ty)));
935     }
936
937     fn emit_tys<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, tys: &[Ty<'tcx>]) {
938         self.emit_from_vec(tys, |this, ty| Ok(this.emit_ty(ecx, *ty)));
939     }
940
941     fn emit_trait_ref<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
942                           trait_ref: &ty::TraitRef<'tcx>) {
943         self.emit_opaque(|this| Ok(e::write_trait_ref(ecx, this, trait_ref)));
944     }
945
946     fn emit_type_param_def<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
947                                type_param_def: &ty::TypeParameterDef<'tcx>) {
948         self.emit_opaque(|this| {
949             Ok(tyencode::enc_type_param_def(this,
950                                          &ecx.ty_str_ctxt(),
951                                          type_param_def))
952         });
953     }
954
955     fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
956                           predicate: &ty::Predicate<'tcx>) {
957         self.emit_opaque(|this| {
958             Ok(tyencode::enc_predicate(this,
959                                        &ecx.ty_str_ctxt(),
960                                        predicate))
961         });
962     }
963
964     fn emit_type_scheme<'b>(&mut self,
965                             ecx: &e::EncodeContext<'b, 'tcx>,
966                             type_scheme: ty::TypeScheme<'tcx>) {
967         use serialize::Encoder;
968
969         self.emit_struct("TypeScheme", 2, |this| {
970             this.emit_struct_field("generics", 0, |this| {
971                 this.emit_struct("Generics", 2, |this| {
972                     this.emit_struct_field("types", 0, |this| {
973                         Ok(encode_vec_per_param_space(
974                             this, &type_scheme.generics.types,
975                             |this, def| this.emit_type_param_def(ecx, def)))
976                     });
977                     this.emit_struct_field("regions", 1, |this| {
978                         Ok(encode_vec_per_param_space(
979                             this, &type_scheme.generics.regions,
980                             |this, def| def.encode(this).unwrap()))
981                     })
982                 })
983             });
984             this.emit_struct_field("ty", 1, |this| {
985                 Ok(this.emit_ty(ecx, type_scheme.ty))
986             })
987         });
988     }
989
990     fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>,
991                                    bounds: &ty::ExistentialBounds<'tcx>) {
992         self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this,
993                                                                     &ecx.ty_str_ctxt(),
994                                                                     bounds)));
995     }
996
997     fn emit_builtin_bounds(&mut self, ecx: &e::EncodeContext, bounds: &ty::BuiltinBounds) {
998         self.emit_opaque(|this| Ok(tyencode::enc_builtin_bounds(this,
999                                                                 &ecx.ty_str_ctxt(),
1000                                                                 bounds)));
1001     }
1002
1003     fn emit_substs<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
1004                        substs: &subst::Substs<'tcx>) {
1005         self.emit_opaque(|this| Ok(tyencode::enc_substs(this,
1006                                                            &ecx.ty_str_ctxt(),
1007                                                            substs)));
1008     }
1009
1010     fn emit_auto_adjustment<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
1011                                 adj: &ty::AutoAdjustment<'tcx>) {
1012         use serialize::Encoder;
1013
1014         self.emit_enum("AutoAdjustment", |this| {
1015             match *adj {
1016                 ty::AdjustReifyFnPointer=> {
1017                     this.emit_enum_variant("AdjustReifyFnPointer", 1, 0, |_| Ok(()))
1018                 }
1019
1020                 ty::AdjustUnsafeFnPointer => {
1021                     this.emit_enum_variant("AdjustUnsafeFnPointer", 2, 0, |_| {
1022                         Ok(())
1023                     })
1024                 }
1025
1026                 ty::AdjustDerefRef(ref auto_deref_ref) => {
1027                     this.emit_enum_variant("AdjustDerefRef", 3, 2, |this| {
1028                         this.emit_enum_variant_arg(0,
1029                             |this| Ok(this.emit_auto_deref_ref(ecx, auto_deref_ref)))
1030                     })
1031                 }
1032             }
1033         });
1034     }
1035
1036     fn emit_autoref<'b>(&mut self, autoref: &ty::AutoRef<'tcx>) {
1037         use serialize::Encoder;
1038
1039         self.emit_enum("AutoRef", |this| {
1040             match autoref {
1041                 &ty::AutoPtr(r, m) => {
1042                     this.emit_enum_variant("AutoPtr", 0, 2, |this| {
1043                         this.emit_enum_variant_arg(0, |this| r.encode(this));
1044                         this.emit_enum_variant_arg(1, |this| m.encode(this))
1045                     })
1046                 }
1047                 &ty::AutoUnsafe(m) => {
1048                     this.emit_enum_variant("AutoUnsafe", 1, 1, |this| {
1049                         this.emit_enum_variant_arg(0, |this| m.encode(this))
1050                     })
1051                 }
1052             }
1053         });
1054     }
1055
1056     fn emit_auto_deref_ref<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
1057                                auto_deref_ref: &ty::AutoDerefRef<'tcx>) {
1058         use serialize::Encoder;
1059
1060         self.emit_struct("AutoDerefRef", 2, |this| {
1061             this.emit_struct_field("autoderefs", 0, |this| auto_deref_ref.autoderefs.encode(this));
1062
1063             this.emit_struct_field("autoref", 1, |this| {
1064                 this.emit_option(|this| {
1065                     match auto_deref_ref.autoref {
1066                         None => this.emit_option_none(),
1067                         Some(ref a) => this.emit_option_some(|this| Ok(this.emit_autoref(a))),
1068                     }
1069                 })
1070             });
1071
1072             this.emit_struct_field("unsize", 2, |this| {
1073                 this.emit_option(|this| {
1074                     match auto_deref_ref.unsize {
1075                         None => this.emit_option_none(),
1076                         Some(target) => this.emit_option_some(|this| {
1077                             Ok(this.emit_ty(ecx, target))
1078                         })
1079                     }
1080                 })
1081             })
1082         });
1083     }
1084 }
1085
1086 trait write_tag_and_id {
1087     fn tag<F>(&mut self, tag_id: c::astencode_tag, f: F) where F: FnOnce(&mut Self);
1088     fn id(&mut self, id: ast::NodeId);
1089 }
1090
1091 impl<'a> write_tag_and_id for Encoder<'a> {
1092     fn tag<F>(&mut self,
1093               tag_id: c::astencode_tag,
1094               f: F) where
1095         F: FnOnce(&mut Encoder<'a>),
1096     {
1097         self.start_tag(tag_id as usize);
1098         f(self);
1099         self.end_tag();
1100     }
1101
1102     fn id(&mut self, id: ast::NodeId) {
1103         id.encode(self).unwrap();
1104     }
1105 }
1106
1107 struct SideTableEncodingIdVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
1108     ecx: &'a e::EncodeContext<'c, 'tcx>,
1109     rbml_w: &'a mut Encoder<'b>,
1110 }
1111
1112 impl<'a, 'b, 'c, 'tcx> ast_util::IdVisitingOperation for
1113         SideTableEncodingIdVisitor<'a, 'b, 'c, 'tcx> {
1114     fn visit_id(&mut self, id: ast::NodeId) {
1115         encode_side_tables_for_id(self.ecx, self.rbml_w, id)
1116     }
1117 }
1118
1119 fn encode_side_tables_for_ii(ecx: &e::EncodeContext,
1120                              rbml_w: &mut Encoder,
1121                              ii: &ast::InlinedItem) {
1122     rbml_w.start_tag(c::tag_table as usize);
1123     ast_util::visit_ids_for_inlined_item(ii, &mut SideTableEncodingIdVisitor {
1124         ecx: ecx,
1125         rbml_w: rbml_w
1126     });
1127     rbml_w.end_tag();
1128 }
1129
1130 fn encode_side_tables_for_id(ecx: &e::EncodeContext,
1131                              rbml_w: &mut Encoder,
1132                              id: ast::NodeId) {
1133     let tcx = ecx.tcx;
1134
1135     debug!("Encoding side tables for id {}", id);
1136
1137     if let Some(def) = tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
1138         rbml_w.tag(c::tag_table_def, |rbml_w| {
1139             rbml_w.id(id);
1140             def.encode(rbml_w).unwrap();
1141         })
1142     }
1143
1144     if let Some(ty) = tcx.node_types().get(&id) {
1145         rbml_w.tag(c::tag_table_node_type, |rbml_w| {
1146             rbml_w.id(id);
1147             rbml_w.emit_ty(ecx, *ty);
1148         })
1149     }
1150
1151     if let Some(item_substs) = tcx.item_substs.borrow().get(&id) {
1152         rbml_w.tag(c::tag_table_item_subst, |rbml_w| {
1153             rbml_w.id(id);
1154             rbml_w.emit_substs(ecx, &item_substs.substs);
1155         })
1156     }
1157
1158     if let Some(fv) = tcx.freevars.borrow().get(&id) {
1159         rbml_w.tag(c::tag_table_freevars, |rbml_w| {
1160             rbml_w.id(id);
1161             rbml_w.emit_from_vec(fv, |rbml_w, fv_entry| {
1162                 Ok(encode_freevar_entry(rbml_w, fv_entry))
1163             });
1164         });
1165
1166         for freevar in fv {
1167             rbml_w.tag(c::tag_table_upvar_capture_map, |rbml_w| {
1168                 rbml_w.id(id);
1169
1170                 let var_id = freevar.def.def_id().node;
1171                 let upvar_id = ty::UpvarId {
1172                     var_id: var_id,
1173                     closure_expr_id: id
1174                 };
1175                 let upvar_capture = tcx.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone();
1176                 var_id.encode(rbml_w);
1177                 upvar_capture.encode(rbml_w);
1178             })
1179         }
1180     }
1181
1182     let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
1183     if let Some(type_scheme) = tcx.tcache.borrow().get(&lid) {
1184         rbml_w.tag(c::tag_table_tcache, |rbml_w| {
1185             rbml_w.id(id);
1186             rbml_w.emit_type_scheme(ecx, type_scheme.clone());
1187         })
1188     }
1189
1190     if let Some(type_param_def) = tcx.ty_param_defs.borrow().get(&id) {
1191         rbml_w.tag(c::tag_table_param_defs, |rbml_w| {
1192             rbml_w.id(id);
1193             rbml_w.emit_type_param_def(ecx, type_param_def)
1194         })
1195     }
1196
1197     let method_call = MethodCall::expr(id);
1198     if let Some(method) = tcx.method_map.borrow().get(&method_call) {
1199         rbml_w.tag(c::tag_table_method_map, |rbml_w| {
1200             rbml_w.id(id);
1201             encode_method_callee(ecx, rbml_w, method_call.autoderef, method)
1202         })
1203     }
1204
1205     if let Some(trait_ref) = tcx.object_cast_map.borrow().get(&id) {
1206         rbml_w.tag(c::tag_table_object_cast_map, |rbml_w| {
1207             rbml_w.id(id);
1208             rbml_w.emit_trait_ref(ecx, &*trait_ref.0);
1209         })
1210     }
1211
1212     if let Some(adjustment) = tcx.adjustments.borrow().get(&id) {
1213         match *adjustment {
1214             ty::AdjustDerefRef(ref adj) => {
1215                 for autoderef in 0..adj.autoderefs {
1216                     let method_call = MethodCall::autoderef(id, autoderef as u32);
1217                     if let Some(method) = tcx.method_map.borrow().get(&method_call) {
1218                         rbml_w.tag(c::tag_table_method_map, |rbml_w| {
1219                             rbml_w.id(id);
1220                             encode_method_callee(ecx, rbml_w,
1221                                                  method_call.autoderef, method)
1222                         })
1223                     }
1224                 }
1225             }
1226             _ => {}
1227         }
1228
1229         rbml_w.tag(c::tag_table_adjustments, |rbml_w| {
1230             rbml_w.id(id);
1231             rbml_w.emit_auto_adjustment(ecx, adjustment);
1232         })
1233     }
1234
1235     if let Some(closure_type) = tcx.closure_tys.borrow().get(&ast_util::local_def(id)) {
1236         rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
1237             rbml_w.id(id);
1238             rbml_w.emit_closure_type(ecx, closure_type);
1239         })
1240     }
1241
1242     if let Some(closure_kind) = tcx.closure_kinds.borrow().get(&ast_util::local_def(id)) {
1243         rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
1244             rbml_w.id(id);
1245             encode_closure_kind(rbml_w, *closure_kind)
1246         })
1247     }
1248
1249     for &qualif in tcx.const_qualif_map.borrow().get(&id).iter() {
1250         rbml_w.tag(c::tag_table_const_qualif, |rbml_w| {
1251             rbml_w.id(id);
1252             qualif.encode(rbml_w).unwrap()
1253         })
1254     }
1255 }
1256
1257 trait doc_decoder_helpers {
1258     fn as_int(&self) -> isize;
1259     fn opt_child(&self, tag: c::astencode_tag) -> Option<Self>;
1260 }
1261
1262 impl<'a> doc_decoder_helpers for rbml::Doc<'a> {
1263     fn as_int(&self) -> isize { reader::doc_as_u64(*self) as isize }
1264     fn opt_child(&self, tag: c::astencode_tag) -> Option<rbml::Doc<'a>> {
1265         reader::maybe_get_doc(*self, tag as usize)
1266     }
1267 }
1268
1269 trait rbml_decoder_decoder_helpers<'tcx> {
1270     fn read_method_origin<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1271                                   -> ty::MethodOrigin<'tcx>;
1272     fn read_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Ty<'tcx>;
1273     fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Vec<Ty<'tcx>>;
1274     fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1275                               -> Rc<ty::TraitRef<'tcx>>;
1276     fn read_poly_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1277                                    -> ty::PolyTraitRef<'tcx>;
1278     fn read_type_param_def<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1279                                    -> ty::TypeParameterDef<'tcx>;
1280     fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1281                               -> ty::Predicate<'tcx>;
1282     fn read_type_scheme<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1283                                 -> ty::TypeScheme<'tcx>;
1284     fn read_existential_bounds<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1285                                        -> ty::ExistentialBounds<'tcx>;
1286     fn read_substs<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1287                            -> subst::Substs<'tcx>;
1288     fn read_auto_adjustment<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1289                                     -> ty::AutoAdjustment<'tcx>;
1290     fn read_closure_kind<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1291                                  -> ty::ClosureKind;
1292     fn read_closure_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1293                                -> ty::ClosureTy<'tcx>;
1294     fn read_auto_deref_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1295                                    -> ty::AutoDerefRef<'tcx>;
1296     fn read_autoref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1297                             -> ty::AutoRef<'tcx>;
1298     fn convert_def_id(&mut self,
1299                       dcx: &DecodeContext,
1300                       source: DefIdSource,
1301                       did: ast::DefId)
1302                       -> ast::DefId;
1303
1304     // Versions of the type reading functions that don't need the full
1305     // DecodeContext.
1306     fn read_ty_nodcx(&mut self,
1307                      tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata) -> Ty<'tcx>;
1308     fn read_tys_nodcx(&mut self,
1309                       tcx: &ty::ctxt<'tcx>,
1310                       cdata: &cstore::crate_metadata) -> Vec<Ty<'tcx>>;
1311     fn read_substs_nodcx(&mut self, tcx: &ty::ctxt<'tcx>,
1312                          cdata: &cstore::crate_metadata)
1313                          -> subst::Substs<'tcx>;
1314 }
1315
1316 impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
1317     fn read_ty_nodcx(&mut self,
1318                      tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata) -> Ty<'tcx> {
1319         self.read_opaque(|_, doc| {
1320             Ok(tydecode::parse_ty_data(
1321                 doc.data,
1322                 cdata.cnum,
1323                 doc.start,
1324                 tcx,
1325                 |_, id| decoder::translate_def_id(cdata, id)))
1326         }).unwrap()
1327     }
1328
1329     fn read_tys_nodcx(&mut self,
1330                       tcx: &ty::ctxt<'tcx>,
1331                       cdata: &cstore::crate_metadata) -> Vec<Ty<'tcx>> {
1332         self.read_to_vec(|this| Ok(this.read_ty_nodcx(tcx, cdata)) )
1333             .unwrap()
1334             .into_iter()
1335             .collect()
1336     }
1337
1338     fn read_substs_nodcx(&mut self,
1339                          tcx: &ty::ctxt<'tcx>,
1340                          cdata: &cstore::crate_metadata)
1341                          -> subst::Substs<'tcx>
1342     {
1343         self.read_opaque(|_, doc| {
1344             Ok(tydecode::parse_substs_data(
1345                 doc.data,
1346                 cdata.cnum,
1347                 doc.start,
1348                 tcx,
1349                 |_, id| decoder::translate_def_id(cdata, id)))
1350         }).unwrap()
1351     }
1352
1353     fn read_method_origin<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1354                                   -> ty::MethodOrigin<'tcx>
1355     {
1356         self.read_enum("MethodOrigin", |this| {
1357             let variants = &["MethodStatic", "MethodStaticClosure",
1358                              "MethodTypeParam", "MethodTraitObject"];
1359             this.read_enum_variant(variants, |this, i| {
1360                 Ok(match i {
1361                     0 => {
1362                         let def_id = this.read_def_id(dcx);
1363                         ty::MethodStatic(def_id)
1364                     }
1365
1366                     1 => {
1367                         let def_id = this.read_def_id(dcx);
1368                         ty::MethodStaticClosure(def_id)
1369                     }
1370
1371                     2 => {
1372                         this.read_struct("MethodTypeParam", 2, |this| {
1373                             Ok(ty::MethodTypeParam(
1374                                 ty::MethodParam {
1375                                     trait_ref: {
1376                                         this.read_struct_field("trait_ref", 0, |this| {
1377                                             Ok(this.read_trait_ref(dcx))
1378                                         }).unwrap()
1379                                     },
1380                                     method_num: {
1381                                         this.read_struct_field("method_num", 1, |this| {
1382                                             this.read_uint()
1383                                         }).unwrap()
1384                                     },
1385                                     impl_def_id: {
1386                                         this.read_struct_field("impl_def_id", 2, |this| {
1387                                             this.read_option(|this, b| {
1388                                                 if b {
1389                                                     Ok(Some(this.read_def_id(dcx)))
1390                                                 } else {
1391                                                     Ok(None)
1392                                                 }
1393                                             })
1394                                         }).unwrap()
1395                                     }
1396                                 }))
1397                         }).unwrap()
1398                     }
1399
1400                     3 => {
1401                         this.read_struct("MethodTraitObject", 2, |this| {
1402                             Ok(ty::MethodTraitObject(
1403                                 ty::MethodObject {
1404                                     trait_ref: {
1405                                         this.read_struct_field("trait_ref", 0, |this| {
1406                                             Ok(this.read_trait_ref(dcx))
1407                                         }).unwrap()
1408                                     },
1409                                     object_trait_id: {
1410                                         this.read_struct_field("object_trait_id", 1, |this| {
1411                                             Ok(this.read_def_id(dcx))
1412                                         }).unwrap()
1413                                     },
1414                                     method_num: {
1415                                         this.read_struct_field("method_num", 2, |this| {
1416                                             this.read_uint()
1417                                         }).unwrap()
1418                                     },
1419                                     vtable_index: {
1420                                         this.read_struct_field("vtable_index", 3, |this| {
1421                                             this.read_uint()
1422                                         }).unwrap()
1423                                     },
1424                                 }))
1425                         }).unwrap()
1426                     }
1427
1428                     _ => panic!("..")
1429                 })
1430             })
1431         }).unwrap()
1432     }
1433
1434
1435     fn read_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> Ty<'tcx> {
1436         // Note: regions types embed local node ids.  In principle, we
1437         // should translate these node ids into the new decode
1438         // context.  However, we do not bother, because region types
1439         // are not used during trans.
1440
1441         return self.read_opaque(|this, doc| {
1442             debug!("read_ty({})", type_string(doc));
1443
1444             let ty = tydecode::parse_ty_data(
1445                 doc.data,
1446                 dcx.cdata.cnum,
1447                 doc.start,
1448                 dcx.tcx,
1449                 |s, a| this.convert_def_id(dcx, s, a));
1450
1451             Ok(ty)
1452         }).unwrap();
1453
1454         fn type_string(doc: rbml::Doc) -> String {
1455             let mut str = String::new();
1456             for i in doc.start..doc.end {
1457                 str.push(doc.data[i] as char);
1458             }
1459             str
1460         }
1461     }
1462
1463     fn read_tys<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1464                         -> Vec<Ty<'tcx>> {
1465         self.read_to_vec(|this| Ok(this.read_ty(dcx))).unwrap().into_iter().collect()
1466     }
1467
1468     fn read_trait_ref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1469                               -> Rc<ty::TraitRef<'tcx>> {
1470         self.read_opaque(|this, doc| {
1471             let ty = tydecode::parse_trait_ref_data(
1472                 doc.data,
1473                 dcx.cdata.cnum,
1474                 doc.start,
1475                 dcx.tcx,
1476                 |s, a| this.convert_def_id(dcx, s, a));
1477             Ok(ty)
1478         }).unwrap()
1479     }
1480
1481     fn read_poly_trait_ref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1482                                    -> ty::PolyTraitRef<'tcx> {
1483         ty::Binder(self.read_opaque(|this, doc| {
1484             let ty = tydecode::parse_trait_ref_data(
1485                 doc.data,
1486                 dcx.cdata.cnum,
1487                 doc.start,
1488                 dcx.tcx,
1489                 |s, a| this.convert_def_id(dcx, s, a));
1490             Ok(ty)
1491         }).unwrap())
1492     }
1493
1494     fn read_type_param_def<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1495                                    -> ty::TypeParameterDef<'tcx> {
1496         self.read_opaque(|this, doc| {
1497             Ok(tydecode::parse_type_param_def_data(
1498                 doc.data,
1499                 doc.start,
1500                 dcx.cdata.cnum,
1501                 dcx.tcx,
1502                 |s, a| this.convert_def_id(dcx, s, a)))
1503         }).unwrap()
1504     }
1505
1506     fn read_predicate<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1507                               -> ty::Predicate<'tcx>
1508     {
1509         self.read_opaque(|this, doc| {
1510             Ok(tydecode::parse_predicate_data(doc.data, doc.start, dcx.cdata.cnum, dcx.tcx,
1511                                               |s, a| this.convert_def_id(dcx, s, a)))
1512         }).unwrap()
1513     }
1514
1515     fn read_type_scheme<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1516                                 -> ty::TypeScheme<'tcx> {
1517         self.read_struct("TypeScheme", 3, |this| {
1518             Ok(ty::TypeScheme {
1519                 generics: this.read_struct_field("generics", 0, |this| {
1520                     this.read_struct("Generics", 2, |this| {
1521                         Ok(ty::Generics {
1522                             types:
1523                             this.read_struct_field("types", 0, |this| {
1524                                 Ok(this.read_vec_per_param_space(
1525                                     |this| this.read_type_param_def(dcx)))
1526                             }).unwrap(),
1527
1528                             regions:
1529                             this.read_struct_field("regions", 1, |this| {
1530                                 Ok(this.read_vec_per_param_space(
1531                                     |this| Decodable::decode(this).unwrap()))
1532                             }).unwrap(),
1533                         })
1534                     })
1535                 }).unwrap(),
1536                 ty: this.read_struct_field("ty", 1, |this| {
1537                     Ok(this.read_ty(dcx))
1538                 }).unwrap()
1539             })
1540         }).unwrap()
1541     }
1542
1543     fn read_existential_bounds<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1544                                        -> ty::ExistentialBounds<'tcx>
1545     {
1546         self.read_opaque(|this, doc| {
1547             Ok(tydecode::parse_existential_bounds_data(doc.data,
1548                                                        dcx.cdata.cnum,
1549                                                        doc.start,
1550                                                        dcx.tcx,
1551                                                        |s, a| this.convert_def_id(dcx, s, a)))
1552         }).unwrap()
1553     }
1554
1555     fn read_substs<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1556                            -> subst::Substs<'tcx> {
1557         self.read_opaque(|this, doc| {
1558             Ok(tydecode::parse_substs_data(doc.data,
1559                                         dcx.cdata.cnum,
1560                                         doc.start,
1561                                         dcx.tcx,
1562                                         |s, a| this.convert_def_id(dcx, s, a)))
1563         }).unwrap()
1564     }
1565
1566     fn read_auto_adjustment<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1567                                     -> ty::AutoAdjustment<'tcx> {
1568         self.read_enum("AutoAdjustment", |this| {
1569             let variants = ["AdjustReifyFnPointer", "AdjustUnsafeFnPointer", "AdjustDerefRef"];
1570             this.read_enum_variant(&variants, |this, i| {
1571                 Ok(match i {
1572                     1 => ty::AdjustReifyFnPointer,
1573                     2 => ty::AdjustUnsafeFnPointer,
1574                     3 => {
1575                         let auto_deref_ref: ty::AutoDerefRef =
1576                             this.read_enum_variant_arg(0,
1577                                 |this| Ok(this.read_auto_deref_ref(dcx))).unwrap();
1578
1579                         ty::AdjustDerefRef(auto_deref_ref)
1580                     }
1581                     _ => panic!("bad enum variant for ty::AutoAdjustment")
1582                 })
1583             })
1584         }).unwrap()
1585     }
1586
1587     fn read_auto_deref_ref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1588                                    -> ty::AutoDerefRef<'tcx> {
1589         self.read_struct("AutoDerefRef", 2, |this| {
1590             Ok(ty::AutoDerefRef {
1591                 autoderefs: this.read_struct_field("autoderefs", 0, |this| {
1592                     Decodable::decode(this)
1593                 }).unwrap(),
1594                 autoref: this.read_struct_field("autoref", 1, |this| {
1595                     this.read_option(|this, b| {
1596                         if b {
1597                             Ok(Some(this.read_autoref(dcx)))
1598                         } else {
1599                             Ok(None)
1600                         }
1601                     })
1602                 }).unwrap(),
1603                 unsize: this.read_struct_field("unsize", 2, |this| {
1604                     this.read_option(|this, b| {
1605                         if b {
1606                             Ok(Some(this.read_ty(dcx)))
1607                         } else {
1608                             Ok(None)
1609                         }
1610                     })
1611                 }).unwrap(),
1612             })
1613         }).unwrap()
1614     }
1615
1616     fn read_autoref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1617                             -> ty::AutoRef<'tcx> {
1618         self.read_enum("AutoRef", |this| {
1619             let variants = ["AutoPtr", "AutoUnsafe"];
1620             this.read_enum_variant(&variants, |this, i| {
1621                 Ok(match i {
1622                     0 => {
1623                         let r: ty::Region =
1624                             this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
1625                         let m: ast::Mutability =
1626                             this.read_enum_variant_arg(1, |this| Decodable::decode(this)).unwrap();
1627
1628                         ty::AutoPtr(dcx.tcx.mk_region(r.tr(dcx)), m)
1629                     }
1630                     1 => {
1631                         let m: ast::Mutability =
1632                             this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
1633
1634                         ty::AutoUnsafe(m)
1635                     }
1636                     _ => panic!("bad enum variant for ty::AutoRef")
1637                 })
1638             })
1639         }).unwrap()
1640     }
1641
1642     fn read_closure_kind<'b, 'c>(&mut self, _dcx: &DecodeContext<'b, 'c, 'tcx>)
1643                                  -> ty::ClosureKind
1644     {
1645         Decodable::decode(self).unwrap()
1646     }
1647
1648     fn read_closure_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1649                                -> ty::ClosureTy<'tcx>
1650     {
1651         self.read_opaque(|this, doc| {
1652             Ok(tydecode::parse_ty_closure_data(
1653                 doc.data,
1654                 dcx.cdata.cnum,
1655                 doc.start,
1656                 dcx.tcx,
1657                 |s, a| this.convert_def_id(dcx, s, a)))
1658         }).unwrap()
1659     }
1660
1661     /// Converts a def-id that appears in a type.  The correct
1662     /// translation will depend on what kind of def-id this is.
1663     /// This is a subtle point: type definitions are not
1664     /// inlined into the current crate, so if the def-id names
1665     /// a nominal type or type alias, then it should be
1666     /// translated to refer to the source crate.
1667     ///
1668     /// However, *type parameters* are cloned along with the function
1669     /// they are attached to.  So we should translate those def-ids
1670     /// to refer to the new, cloned copy of the type parameter.
1671     /// We only see references to free type parameters in the body of
1672     /// an inlined function. In such cases, we need the def-id to
1673     /// be a local id so that the TypeContents code is able to lookup
1674     /// the relevant info in the ty_param_defs table.
1675     ///
1676     /// *Region parameters*, unfortunately, are another kettle of fish.
1677     /// In such cases, def_id's can appear in types to distinguish
1678     /// shadowed bound regions and so forth. It doesn't actually
1679     /// matter so much what we do to these, since regions are erased
1680     /// at trans time, but it's good to keep them consistent just in
1681     /// case. We translate them with `tr_def_id()` which will map
1682     /// the crate numbers back to the original source crate.
1683     ///
1684     /// Unboxed closures are cloned along with the function being
1685     /// inlined, and all side tables use interned node IDs, so we
1686     /// translate their def IDs accordingly.
1687     ///
1688     /// It'd be really nice to refactor the type repr to not include
1689     /// def-ids so that all these distinctions were unnecessary.
1690     fn convert_def_id(&mut self,
1691                       dcx: &DecodeContext,
1692                       source: tydecode::DefIdSource,
1693                       did: ast::DefId)
1694                       -> ast::DefId {
1695         let r = match source {
1696             NominalType | TypeWithId | RegionParameter => dcx.tr_def_id(did),
1697             TypeParameter | ClosureSource => dcx.tr_intern_def_id(did)
1698         };
1699         debug!("convert_def_id(source={:?}, did={:?})={:?}", source, did, r);
1700         return r;
1701     }
1702 }
1703
1704 fn decode_side_tables(dcx: &DecodeContext,
1705                       ast_doc: rbml::Doc) {
1706     let tbl_doc = ast_doc.get(c::tag_table as usize);
1707     reader::docs(tbl_doc, |tag, entry_doc| {
1708         let mut entry_dsr = reader::Decoder::new(entry_doc);
1709         let id0: ast::NodeId = Decodable::decode(&mut entry_dsr).unwrap();
1710         let id = dcx.tr_id(id0);
1711
1712         debug!(">> Side table document with tag 0x{:x} \
1713                 found for id {} (orig {})",
1714                tag, id, id0);
1715         let tag = tag as u32;
1716         let decoded_tag: Option<c::astencode_tag> = c::astencode_tag::from_u32(tag);
1717         match decoded_tag {
1718             None => {
1719                 dcx.tcx.sess.bug(
1720                     &format!("unknown tag found in side tables: {:x}",
1721                             tag));
1722             }
1723             Some(value) => {
1724                 let val_dsr = &mut entry_dsr;
1725
1726                 match value {
1727                     c::tag_table_def => {
1728                         let def = decode_def(dcx, val_dsr);
1729                         dcx.tcx.def_map.borrow_mut().insert(id, def::PathResolution {
1730                             base_def: def,
1731                             // This doesn't matter cross-crate.
1732                             last_private: LastMod(AllPublic),
1733                             depth: 0
1734                         });
1735                     }
1736                     c::tag_table_node_type => {
1737                         let ty = val_dsr.read_ty(dcx);
1738                         debug!("inserting ty for node {}: {}",
1739                                id, ty_to_string(dcx.tcx, ty));
1740                         dcx.tcx.node_type_insert(id, ty);
1741                     }
1742                     c::tag_table_item_subst => {
1743                         let item_substs = ty::ItemSubsts {
1744                             substs: val_dsr.read_substs(dcx)
1745                         };
1746                         dcx.tcx.item_substs.borrow_mut().insert(
1747                             id, item_substs);
1748                     }
1749                     c::tag_table_freevars => {
1750                         let fv_info = val_dsr.read_to_vec(|val_dsr| {
1751                             Ok(val_dsr.read_freevar_entry(dcx))
1752                         }).unwrap().into_iter().collect();
1753                         dcx.tcx.freevars.borrow_mut().insert(id, fv_info);
1754                     }
1755                     c::tag_table_upvar_capture_map => {
1756                         let var_id: ast::NodeId = Decodable::decode(val_dsr).unwrap();
1757                         let upvar_id = ty::UpvarId {
1758                             var_id: dcx.tr_id(var_id),
1759                             closure_expr_id: id
1760                         };
1761                         let ub: ty::UpvarCapture = Decodable::decode(val_dsr).unwrap();
1762                         dcx.tcx.upvar_capture_map.borrow_mut().insert(upvar_id, ub.tr(dcx));
1763                     }
1764                     c::tag_table_tcache => {
1765                         let type_scheme = val_dsr.read_type_scheme(dcx);
1766                         let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
1767                         dcx.tcx.tcache.borrow_mut().insert(lid, type_scheme);
1768                     }
1769                     c::tag_table_param_defs => {
1770                         let bounds = val_dsr.read_type_param_def(dcx);
1771                         dcx.tcx.ty_param_defs.borrow_mut().insert(id, bounds);
1772                     }
1773                     c::tag_table_method_map => {
1774                         let (autoderef, method) = val_dsr.read_method_callee(dcx);
1775                         let method_call = MethodCall {
1776                             expr_id: id,
1777                             autoderef: autoderef
1778                         };
1779                         dcx.tcx.method_map.borrow_mut().insert(method_call, method);
1780                     }
1781                     c::tag_table_object_cast_map => {
1782                         let trait_ref = val_dsr.read_poly_trait_ref(dcx);
1783                         dcx.tcx.object_cast_map.borrow_mut()
1784                                                .insert(id, trait_ref);
1785                     }
1786                     c::tag_table_adjustments => {
1787                         let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(dcx);
1788                         dcx.tcx.adjustments.borrow_mut().insert(id, adj);
1789                     }
1790                     c::tag_table_closure_tys => {
1791                         let closure_ty =
1792                             val_dsr.read_closure_ty(dcx);
1793                         dcx.tcx.closure_tys.borrow_mut().insert(ast_util::local_def(id),
1794                                                                 closure_ty);
1795                     }
1796                     c::tag_table_closure_kinds => {
1797                         let closure_kind =
1798                             val_dsr.read_closure_kind(dcx);
1799                         dcx.tcx.closure_kinds.borrow_mut().insert(ast_util::local_def(id),
1800                                                                   closure_kind);
1801                     }
1802                     c::tag_table_const_qualif => {
1803                         let qualif: ConstQualif = Decodable::decode(val_dsr).unwrap();
1804                         dcx.tcx.const_qualif_map.borrow_mut().insert(id, qualif);
1805                     }
1806                     _ => {
1807                         dcx.tcx.sess.bug(
1808                             &format!("unknown tag found in side tables: {:x}",
1809                                     tag));
1810                     }
1811                 }
1812             }
1813         }
1814
1815         debug!(">< Side table doc loaded");
1816         true
1817     });
1818 }
1819
1820 // ______________________________________________________________________
1821 // Testing of astencode_gen
1822
1823 #[cfg(test)]
1824 fn encode_item_ast(rbml_w: &mut Encoder, item: &ast::Item) {
1825     rbml_w.start_tag(c::tag_tree as usize);
1826     (*item).encode(rbml_w);
1827     rbml_w.end_tag();
1828 }
1829
1830 #[cfg(test)]
1831 fn decode_item_ast(par_doc: rbml::Doc) -> ast::Item {
1832     let chi_doc = par_doc.get(c::tag_tree as usize);
1833     let mut d = reader::Decoder::new(chi_doc);
1834     Decodable::decode(&mut d).unwrap()
1835 }
1836
1837 #[cfg(test)]
1838 trait fake_ext_ctxt {
1839     fn cfg(&self) -> ast::CrateConfig;
1840     fn parse_sess<'a>(&'a self) -> &'a parse::ParseSess;
1841     fn call_site(&self) -> Span;
1842     fn ident_of(&self, st: &str) -> ast::Ident;
1843 }
1844
1845 #[cfg(test)]
1846 impl fake_ext_ctxt for parse::ParseSess {
1847     fn cfg(&self) -> ast::CrateConfig {
1848         Vec::new()
1849     }
1850     fn parse_sess<'a>(&'a self) -> &'a parse::ParseSess { self }
1851     fn call_site(&self) -> Span {
1852         codemap::Span {
1853             lo: codemap::BytePos(0),
1854             hi: codemap::BytePos(0),
1855             expn_id: codemap::NO_EXPANSION
1856         }
1857     }
1858     fn ident_of(&self, st: &str) -> ast::Ident {
1859         token::str_to_ident(st)
1860     }
1861 }
1862
1863 #[cfg(test)]
1864 fn mk_ctxt() -> parse::ParseSess {
1865     parse::new_parse_sess()
1866 }
1867
1868 #[cfg(test)]
1869 fn roundtrip(in_item: Option<P<ast::Item>>) {
1870     let in_item = in_item.unwrap();
1871     let mut wr = Cursor::new(Vec::new());
1872     encode_item_ast(&mut Encoder::new(&mut wr), &*in_item);
1873     let rbml_doc = rbml::Doc::new(wr.get_ref());
1874     let out_item = decode_item_ast(rbml_doc);
1875
1876     assert!(*in_item == out_item);
1877 }
1878
1879 #[test]
1880 fn test_basic() {
1881     let cx = mk_ctxt();
1882     roundtrip(quote_item!(&cx,
1883         fn foo() {}
1884     ));
1885 }
1886 /* NOTE: When there's a snapshot, update this (yay quasiquoter!)
1887 #[test]
1888 fn test_smalltalk() {
1889     let cx = mk_ctxt();
1890     roundtrip(quote_item!(&cx,
1891         fn foo() -> isize { 3 + 4 } // first smalltalk program ever executed.
1892     ));
1893 }
1894 */
1895
1896 #[test]
1897 fn test_more() {
1898     let cx = mk_ctxt();
1899     roundtrip(quote_item!(&cx,
1900         fn foo(x: usize, y: usize) -> usize {
1901             let z = x + y;
1902             return z;
1903         }
1904     ));
1905 }
1906
1907 #[test]
1908 fn test_simplification() {
1909     let cx = mk_ctxt();
1910     let item = quote_item!(&cx,
1911         fn new_int_alist<B>() -> alist<isize, B> {
1912             fn eq_int(a: isize, b: isize) -> bool { a == b }
1913             return alist {eq_fn: eq_int, data: Vec::new()};
1914         }
1915     ).unwrap();
1916     let item_in = e::IIItemRef(&*item);
1917     let item_out = simplify_ast(item_in);
1918     let item_exp = ast::IIItem(quote_item!(&cx,
1919         fn new_int_alist<B>() -> alist<isize, B> {
1920             return alist {eq_fn: eq_int, data: Vec::new()};
1921         }
1922     ).unwrap());
1923     match (item_out, item_exp) {
1924       (ast::IIItem(item_out), ast::IIItem(item_exp)) => {
1925         assert!(pprust::item_to_string(&*item_out) ==
1926                 pprust::item_to_string(&*item_exp));
1927       }
1928       _ => panic!()
1929     }
1930 }