1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
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.
14 // tjc note: Would be great to have a `match check` macro equivalent
17 #![allow(non_camel_case_types)]
19 pub use self::DefIdSource::*;
23 use middle::def_id::DefId;
26 use middle::subst::VecPerParamSpace;
27 use middle::ty::{self, ToPredicate, Ty, HasTypeFlags};
33 use syntax::parse::token;
35 // Compact string representation for Ty values. API TyStr &
36 // parse_from_str. Extra parameters are for converting to/from def_ids in the
37 // data buffer. Whatever format you choose should not contain pipe characters.
39 // Def id conversion: when we encounter def-ids, they have to be translated.
40 // For example, the crate number must be converted from the crate number used
41 // in the library we are reading from into the local crate numbers in use
42 // here. To perform this translation, the type decoder is supplied with a
43 // conversion function of type `conv_did`.
45 // Sometimes, particularly when inlining, the correct translation of the
46 // def-id will depend on where it originated from. Therefore, the conversion
47 // function is given an indicator of the source of the def-id. See
48 // astencode.rs for more information.
49 #[derive(Copy, Clone, Debug)]
50 pub enum DefIdSource {
51 // Identifies a struct, trait, enum, etc.
54 // Identifies a type alias (`type X = ...`).
57 // Identifies a region parameter (`fn foo<'X>() { ... }`).
60 // Identifies a closure
64 pub type DefIdConvert<'a> = &'a mut FnMut(DefIdSource, DefId) -> DefId;
66 pub struct TyDecoder<'a, 'tcx: 'a> {
70 tcx: &'a ty::ctxt<'tcx>,
71 conv_def_id: DefIdConvert<'a>,
74 impl<'a,'tcx> TyDecoder<'a,'tcx> {
75 pub fn with_doc(tcx: &'a ty::ctxt<'tcx>,
76 crate_num: ast::CrateNum,
78 conv: DefIdConvert<'a>)
79 -> TyDecoder<'a,'tcx> {
80 TyDecoder::new(doc.data, crate_num, doc.start, tcx, conv)
83 pub fn new(data: &'a [u8],
84 crate_num: ast::CrateNum,
86 tcx: &'a ty::ctxt<'tcx>,
87 conv: DefIdConvert<'a>)
88 -> TyDecoder<'a, 'tcx> {
98 fn peek(&self) -> char {
99 self.data[self.pos] as char
102 fn next(&mut self) -> char {
103 let ch = self.data[self.pos] as char;
104 self.pos = self.pos + 1;
108 fn next_byte(&mut self) -> u8 {
109 let b = self.data[self.pos];
110 self.pos = self.pos + 1;
114 fn scan<F>(&mut self, mut is_last: F) -> &'a [u8]
115 where F: FnMut(char) -> bool,
117 let start_pos = self.pos;
118 debug!("scan: '{}' (start)", self.data[self.pos] as char);
119 while !is_last(self.data[self.pos] as char) {
121 debug!("scan: '{}'", self.data[self.pos] as char);
123 let end_pos = self.pos;
125 return &self.data[start_pos..end_pos];
128 fn parse_name(&mut self, last: char) -> ast::Name {
129 fn is_last(b: char, c: char) -> bool { return c == b; }
130 let bytes = self.scan(|a| is_last(last, a));
131 token::intern(str::from_utf8(bytes).unwrap())
134 fn parse_size(&mut self) -> Option<usize> {
135 assert_eq!(self.next(), '/');
137 if self.peek() == '|' {
138 assert_eq!(self.next(), '|');
141 let n = self.parse_uint();
142 assert_eq!(self.next(), '|');
147 fn parse_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
148 F: FnMut(&mut TyDecoder<'a, 'tcx>) -> T,
150 let mut r = VecPerParamSpace::empty();
151 for &space in &subst::ParamSpace::all() {
152 assert_eq!(self.next(), '[');
153 while self.peek() != ']' {
154 r.push(space, f(self));
156 assert_eq!(self.next(), ']');
161 pub fn parse_substs(&mut self) -> subst::Substs<'tcx> {
162 let regions = self.parse_region_substs();
163 let types = self.parse_vec_per_param_space(|this| this.parse_ty());
164 subst::Substs { types: types, regions: regions }
167 fn parse_region_substs(&mut self) -> subst::RegionSubsts {
169 'e' => subst::ErasedRegions,
171 subst::NonerasedRegions(
172 self.parse_vec_per_param_space(|this| this.parse_region()))
174 _ => panic!("parse_bound_region: bad input")
178 fn parse_bound_region(&mut self) -> ty::BoundRegion {
181 let id = self.parse_u32();
182 assert_eq!(self.next(), '|');
186 let def = self.parse_def(RegionParameter);
187 let name = token::intern(&self.parse_str(']'));
188 ty::BrNamed(def, name)
191 let id = self.parse_u32();
192 assert_eq!(self.next(), '|');
196 _ => panic!("parse_bound_region: bad input")
200 pub fn parse_region(&mut self) -> ty::Region {
203 assert_eq!(self.next(), '[');
204 let id = ty::DebruijnIndex::new(self.parse_u32());
205 assert_eq!(self.next(), '|');
206 let br = self.parse_bound_region();
207 assert_eq!(self.next(), ']');
208 ty::ReLateBound(id, br)
211 assert_eq!(self.next(), '[');
212 let def_id = self.parse_def(NominalType);
213 let space = self.parse_param_space();
214 assert_eq!(self.next(), '|');
215 let index = self.parse_u32();
216 assert_eq!(self.next(), '|');
217 let name = token::intern(&self.parse_str(']'));
218 ty::ReEarlyBound(ty::EarlyBoundRegion {
226 assert_eq!(self.next(), '[');
227 let scope = self.parse_scope();
228 assert_eq!(self.next(), '|');
229 let br = self.parse_bound_region();
230 assert_eq!(self.next(), ']');
231 ty::ReFree(ty::FreeRegion { scope: scope,
235 let scope = self.parse_scope();
236 assert_eq!(self.next(), '|');
245 _ => panic!("parse_region: bad input")
249 fn parse_scope(&mut self) -> region::CodeExtent {
250 self.tcx.region_maps.bogus_code_extent(match self.next() {
251 // This creates scopes with the wrong NodeId. This isn't
252 // actually a problem because scopes only exist *within*
253 // functions, and functions aren't loaded until trans which
254 // doesn't care about regions.
256 // May still be worth fixing though.
258 assert_eq!(self.next(), '[');
259 let fn_id = self.parse_uint() as ast::NodeId;
260 assert_eq!(self.next(), '|');
261 let body_id = self.parse_uint() as ast::NodeId;
262 assert_eq!(self.next(), ']');
263 region::CodeExtentData::ParameterScope {
264 fn_id: fn_id, body_id: body_id
268 let node_id = self.parse_uint() as ast::NodeId;
269 region::CodeExtentData::Misc(node_id)
272 let node_id = self.parse_uint() as ast::NodeId;
273 region::CodeExtentData::DestructionScope(node_id)
276 assert_eq!(self.next(), '[');
277 let node_id = self.parse_uint() as ast::NodeId;
278 assert_eq!(self.next(), '|');
279 let first_stmt_index = self.parse_u32();
280 assert_eq!(self.next(), ']');
281 let block_remainder = region::BlockRemainder {
282 block: node_id, first_statement_index: first_stmt_index,
284 region::CodeExtentData::Remainder(block_remainder)
286 _ => panic!("parse_scope: bad input")
290 fn parse_opt<T, F>(&mut self, f: F) -> Option<T>
291 where F: FnOnce(&mut TyDecoder<'a, 'tcx>) -> T,
295 's' => Some(f(self)),
296 _ => panic!("parse_opt: bad input")
300 fn parse_str(&mut self, term: char) -> String {
301 let mut result = String::new();
302 while self.peek() != term {
304 result.as_mut_vec().push_all(&[self.next_byte()])
311 pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> {
312 let def = self.parse_def(NominalType);
313 let substs = self.tcx.mk_substs(self.parse_substs());
314 ty::TraitRef {def_id: def, substs: substs}
317 pub fn parse_ty(&mut self) -> Ty<'tcx> {
320 'b' => return tcx.types.bool,
321 'i' => { /* eat the s of is */ self.next(); return tcx.types.isize },
322 'u' => { /* eat the s of us */ self.next(); return tcx.types.usize },
325 'b' => return tcx.types.u8,
326 'w' => return tcx.types.u16,
327 'l' => return tcx.types.u32,
328 'd' => return tcx.types.u64,
329 'B' => return tcx.types.i8,
330 'W' => return tcx.types.i16,
331 'L' => return tcx.types.i32,
332 'D' => return tcx.types.i64,
333 'f' => return tcx.types.f32,
334 'F' => return tcx.types.f64,
335 _ => panic!("parse_ty: bad numeric type")
338 'c' => return tcx.types.char,
340 assert_eq!(self.next(), '[');
341 let did = self.parse_def(NominalType);
342 let substs = self.parse_substs();
343 assert_eq!(self.next(), ']');
344 let def = self.tcx.lookup_adt_def(did);
345 return tcx.mk_enum(def, self.tcx.mk_substs(substs));
348 assert_eq!(self.next(), '[');
349 let trait_ref = ty::Binder(self.parse_trait_ref());
350 let bounds = self.parse_existential_bounds();
351 assert_eq!(self.next(), ']');
352 return tcx.mk_trait(trait_ref, bounds);
355 assert_eq!(self.next(), '[');
356 let index = self.parse_u32();
357 assert_eq!(self.next(), '|');
358 let space = self.parse_param_space();
359 assert_eq!(self.next(), '|');
360 let name = token::intern(&self.parse_str(']'));
361 return tcx.mk_param(space, index, name);
363 '~' => return tcx.mk_box(self.parse_ty()),
364 '*' => return tcx.mk_ptr(self.parse_mt()),
366 let r = self.parse_region();
367 let mt = self.parse_mt();
368 return tcx.mk_ref(tcx.mk_region(r), mt);
371 let t = self.parse_ty();
372 return match self.parse_size() {
373 Some(n) => tcx.mk_array(t, n),
374 None => tcx.mk_slice(t)
381 assert_eq!(self.next(), '[');
382 let mut params = Vec::new();
383 while self.peek() != ']' { params.push(self.parse_ty()); }
384 self.pos = self.pos + 1;
385 return tcx.mk_tup(params);
388 let def_id = self.parse_def(NominalType);
389 return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(self.parse_bare_fn_ty()));
392 return tcx.mk_fn(None, tcx.mk_bare_fn(self.parse_bare_fn_ty()));
395 // This is a hacky little caching scheme. The idea is that if we encode
396 // the same type twice, the second (and third, and fourth...) time we will
397 // just write `#123`, where `123` is the offset in the metadata of the
398 // first appearance. Now when we are *decoding*, if we see a `#123`, we
399 // can first check a cache (`tcx.rcache`) for that offset. If we find something,
400 // we return it (modulo closure types, see below). But if not, then we
401 // jump to offset 123 and read the type from there.
403 let pos = self.parse_hex();
404 assert_eq!(self.next(), ':');
405 let len = self.parse_hex();
406 assert_eq!(self.next(), '#');
407 let key = ty::CReaderCacheKey {cnum: self.krate, pos: pos, len: len };
408 match tcx.rcache.borrow().get(&key).cloned() {
410 // If there is a closure buried in the type some where, then we
411 // need to re-convert any def ids (see case 'k', below). That means
412 // we can't reuse the cached version.
413 if !tt.has_closure_types() {
420 let mut substate = TyDecoder::new(self.data,
425 let tt = substate.parse_ty();
426 tcx.rcache.borrow_mut().insert(key, tt);
430 let _ = self.parse_def(TypeWithId);
431 let inner = self.parse_ty();
435 assert_eq!(self.next(), '[');
436 let did = self.parse_def(NominalType);
437 let substs = self.parse_substs();
438 assert_eq!(self.next(), ']');
439 let def = self.tcx.lookup_adt_def(did);
440 return self.tcx.mk_struct(def, self.tcx.mk_substs(substs));
443 assert_eq!(self.next(), '[');
444 let did = self.parse_def(ClosureSource);
445 let substs = self.parse_substs();
446 let mut tys = vec![];
447 while self.peek() != '.' {
448 tys.push(self.parse_ty());
450 assert_eq!(self.next(), '.');
451 assert_eq!(self.next(), ']');
452 return self.tcx.mk_closure(did, self.tcx.mk_substs(substs), tys);
455 assert_eq!(self.next(), '[');
456 let trait_ref = self.parse_trait_ref();
457 let name = token::intern(&self.parse_str(']'));
458 return tcx.mk_projection(trait_ref, name);
461 return tcx.types.err;
463 c => { panic!("unexpected char in type string: {}", c);}
467 fn parse_mutability(&mut self) -> hir::Mutability {
469 'm' => { self.next(); hir::MutMutable }
470 _ => { hir::MutImmutable }
474 fn parse_mt(&mut self) -> ty::TypeAndMut<'tcx> {
475 let m = self.parse_mutability();
476 ty::TypeAndMut { ty: self.parse_ty(), mutbl: m }
479 fn parse_def(&mut self, source: DefIdSource) -> DefId {
480 let def_id = parse_defid(self.scan(|c| c == '|'));
481 return (self.conv_def_id)(source, def_id);
484 fn parse_uint(&mut self) -> usize {
487 let cur = self.peek();
488 if cur < '0' || cur > '9' { return n; }
489 self.pos = self.pos + 1;
491 n += (cur as usize) - ('0' as usize);
495 fn parse_u32(&mut self) -> u32 {
496 let n = self.parse_uint();
498 assert_eq!(m as usize, n);
502 fn parse_param_space(&mut self) -> subst::ParamSpace {
503 subst::ParamSpace::from_uint(self.parse_uint())
506 fn parse_hex(&mut self) -> usize {
509 let cur = self.peek();
510 if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; }
511 self.pos = self.pos + 1;
513 if '0' <= cur && cur <= '9' {
514 n += (cur as usize) - ('0' as usize);
515 } else { n += 10 + (cur as usize) - ('a' as usize); }
519 fn parse_abi_set(&mut self) -> abi::Abi {
520 assert_eq!(self.next(), '[');
521 let bytes = self.scan(|c| c == ']');
522 let abi_str = str::from_utf8(bytes).unwrap();
523 abi::lookup(&abi_str[..]).expect(abi_str)
526 pub fn parse_closure_ty(&mut self) -> ty::ClosureTy<'tcx> {
527 let unsafety = parse_unsafety(self.next());
528 let sig = self.parse_sig();
529 let abi = self.parse_abi_set();
537 pub fn parse_bare_fn_ty(&mut self) -> ty::BareFnTy<'tcx> {
538 let unsafety = parse_unsafety(self.next());
539 let abi = self.parse_abi_set();
540 let sig = self.parse_sig();
548 fn parse_sig(&mut self) -> ty::PolyFnSig<'tcx> {
549 assert_eq!(self.next(), '[');
550 let mut inputs = Vec::new();
551 while self.peek() != ']' {
552 inputs.push(self.parse_ty());
554 self.pos += 1; // eat the ']'
555 let variadic = match self.next() {
558 r => panic!(format!("bad variadic: {}", r)),
560 let output = match self.peek() {
565 _ => ty::FnConverging(self.parse_ty())
567 ty::Binder(ty::FnSig {inputs: inputs,
572 pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> {
574 't' => ty::Binder(self.parse_trait_ref()).to_predicate(),
575 'e' => ty::Binder(ty::EquatePredicate(self.parse_ty(),
576 self.parse_ty())).to_predicate(),
577 'r' => ty::Binder(ty::OutlivesPredicate(self.parse_region(),
578 self.parse_region())).to_predicate(),
579 'o' => ty::Binder(ty::OutlivesPredicate(self.parse_ty(),
580 self.parse_region())).to_predicate(),
581 'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(),
582 'w' => ty::Predicate::WellFormed(self.parse_ty()),
584 let def_id = self.parse_def(NominalType);
585 assert_eq!(self.next(), '|');
586 ty::Predicate::ObjectSafe(def_id)
588 c => panic!("Encountered invalid character in metadata: {}", c)
592 fn parse_projection_predicate(&mut self) -> ty::ProjectionPredicate<'tcx> {
593 ty::ProjectionPredicate {
594 projection_ty: ty::ProjectionTy {
595 trait_ref: self.parse_trait_ref(),
596 item_name: token::intern(&self.parse_str('|')),
602 pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
603 let name = self.parse_name(':');
604 let def_id = self.parse_def(NominalType);
605 let space = self.parse_param_space();
606 assert_eq!(self.next(), '|');
607 let index = self.parse_u32();
608 assert_eq!(self.next(), '|');
609 let default_def_id = self.parse_def(NominalType);
610 let default = self.parse_opt(|this| this.parse_ty());
611 let object_lifetime_default = self.parse_object_lifetime_default();
613 ty::TypeParameterDef {
618 default_def_id: default_def_id,
620 object_lifetime_default: object_lifetime_default,
624 pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
625 let name = self.parse_name(':');
626 let def_id = self.parse_def(NominalType);
627 let space = self.parse_param_space();
628 assert_eq!(self.next(), '|');
629 let index = self.parse_u32();
630 assert_eq!(self.next(), '|');
631 let mut bounds = vec![];
634 'R' => bounds.push(self.parse_region()),
637 panic!("parse_region_param_def: bad bounds ('{}')", c)
641 ty::RegionParameterDef {
651 fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault {
653 'a' => ty::ObjectLifetimeDefault::Ambiguous,
654 'b' => ty::ObjectLifetimeDefault::BaseDefault,
656 let region = self.parse_region();
657 ty::ObjectLifetimeDefault::Specific(region)
659 _ => panic!("parse_object_lifetime_default: bad input")
663 pub fn parse_existential_bounds(&mut self) -> ty::ExistentialBounds<'tcx> {
664 let builtin_bounds = self.parse_builtin_bounds();
665 let region_bound = self.parse_region();
666 let mut projection_bounds = Vec::new();
671 projection_bounds.push(ty::Binder(self.parse_projection_predicate()));
675 panic!("parse_bounds: bad bounds ('{}')", c)
680 ty::ExistentialBounds::new(
681 region_bound, builtin_bounds, projection_bounds)
684 fn parse_builtin_bounds(&mut self) -> ty::BuiltinBounds {
685 let mut builtin_bounds = ty::BuiltinBounds::empty();
689 builtin_bounds.insert(ty::BoundSend);
692 builtin_bounds.insert(ty::BoundSized);
695 builtin_bounds.insert(ty::BoundCopy);
698 builtin_bounds.insert(ty::BoundSync);
701 return builtin_bounds;
704 panic!("parse_bounds: bad builtin bounds ('{}')", c)
711 // Rust metadata parsing
712 fn parse_defid(buf: &[u8]) -> DefId {
713 let mut colon_idx = 0;
715 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; }
716 if colon_idx == len {
717 error!("didn't find ':' when parsing def id");
721 let crate_part = &buf[0..colon_idx];
722 let def_part = &buf[colon_idx + 1..len];
724 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
725 s.parse::<usize>().ok()
727 Some(cn) => cn as ast::CrateNum,
728 None => panic!("internal error: parse_defid: crate number expected, found {:?}",
731 let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
732 s.parse::<usize>().ok()
734 Some(dn) => dn as ast::NodeId,
735 None => panic!("internal error: parse_defid: id expected, found {:?}",
738 DefId { krate: crate_num, xxx_node: def_num }
741 fn parse_unsafety(c: char) -> hir::Unsafety {
743 'u' => hir::Unsafety::Unsafe,
744 'n' => hir::Unsafety::Normal,
745 _ => panic!("parse_unsafety: bad unsafety {}", c)