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