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)]
21 use middle::def_id::{DefId, DefIndex};
24 use middle::subst::VecPerParamSpace;
25 use middle::ty::{self, ToPredicate, Ty, TypeFoldable};
32 use syntax::parse::token;
34 // Compact string representation for Ty values. API TyStr &
35 // parse_from_str. Extra parameters are for converting to/from def_ids in the
36 // data buffer. Whatever format you choose should not contain pipe characters.
38 pub type DefIdConvert<'a> = &'a mut FnMut(DefId) -> DefId;
40 pub struct TyDecoder<'a, 'tcx: 'a> {
44 tcx: &'a ty::ctxt<'tcx>,
45 conv_def_id: DefIdConvert<'a>,
48 impl<'a,'tcx> TyDecoder<'a,'tcx> {
49 pub fn with_doc(tcx: &'a ty::ctxt<'tcx>,
50 crate_num: ast::CrateNum,
52 conv: DefIdConvert<'a>)
53 -> TyDecoder<'a,'tcx> {
54 TyDecoder::new(doc.data, crate_num, doc.start, tcx, conv)
57 pub fn new(data: &'a [u8],
58 crate_num: ast::CrateNum,
60 tcx: &'a ty::ctxt<'tcx>,
61 conv: DefIdConvert<'a>)
62 -> TyDecoder<'a, 'tcx> {
72 pub fn position(&self) -> usize {
76 fn peek(&self) -> char {
77 self.data[self.pos] as char
80 fn next(&mut self) -> char {
81 let ch = self.data[self.pos] as char;
82 self.pos = self.pos + 1;
86 fn next_byte(&mut self) -> u8 {
87 let b = self.data[self.pos];
88 self.pos = self.pos + 1;
92 fn scan<F>(&mut self, mut is_last: F) -> &'a [u8]
93 where F: FnMut(char) -> bool,
95 let start_pos = self.pos;
96 debug!("scan: '{}' (start)", self.data[self.pos] as char);
97 while !is_last(self.data[self.pos] as char) {
99 debug!("scan: '{}'", self.data[self.pos] as char);
101 let end_pos = self.pos;
103 return &self.data[start_pos..end_pos];
106 fn parse_vuint(&mut self) -> usize {
107 let (value, bytes_read) = leb128::read_unsigned_leb128(self.data,
109 self.pos += bytes_read;
113 fn parse_name(&mut self, last: char) -> ast::Name {
114 fn is_last(b: char, c: char) -> bool { return c == b; }
115 let bytes = self.scan(|a| is_last(last, a));
116 token::intern(str::from_utf8(bytes).unwrap())
119 fn parse_size(&mut self) -> Option<usize> {
120 assert_eq!(self.next(), '/');
122 if self.peek() == '|' {
123 assert_eq!(self.next(), '|');
126 let n = self.parse_uint();
127 assert_eq!(self.next(), '|');
132 fn parse_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
133 F: FnMut(&mut TyDecoder<'a, 'tcx>) -> T,
135 let mut r = VecPerParamSpace::empty();
136 for &space in &subst::ParamSpace::all() {
137 assert_eq!(self.next(), '[');
138 while self.peek() != ']' {
139 r.push(space, f(self));
141 assert_eq!(self.next(), ']');
146 pub fn parse_substs(&mut self) -> subst::Substs<'tcx> {
147 let regions = self.parse_region_substs();
148 let types = self.parse_vec_per_param_space(|this| this.parse_ty());
149 subst::Substs { types: types, regions: regions }
152 fn parse_region_substs(&mut self) -> subst::RegionSubsts {
154 'e' => subst::ErasedRegions,
156 subst::NonerasedRegions(
157 self.parse_vec_per_param_space(|this| this.parse_region()))
159 _ => panic!("parse_bound_region: bad input")
163 fn parse_bound_region(&mut self) -> ty::BoundRegion {
166 let id = self.parse_u32();
167 assert_eq!(self.next(), '|');
171 let def = self.parse_def();
172 let name = token::intern(&self.parse_str(']'));
173 ty::BrNamed(def, name)
176 let id = self.parse_u32();
177 assert_eq!(self.next(), '|');
181 _ => panic!("parse_bound_region: bad input")
185 pub fn parse_region(&mut self) -> ty::Region {
188 assert_eq!(self.next(), '[');
189 let id = ty::DebruijnIndex::new(self.parse_u32());
190 assert_eq!(self.next(), '|');
191 let br = self.parse_bound_region();
192 assert_eq!(self.next(), ']');
193 ty::ReLateBound(id, br)
196 assert_eq!(self.next(), '[');
197 let space = self.parse_param_space();
198 assert_eq!(self.next(), '|');
199 let index = self.parse_u32();
200 assert_eq!(self.next(), '|');
201 let name = token::intern(&self.parse_str(']'));
202 ty::ReEarlyBound(ty::EarlyBoundRegion {
209 assert_eq!(self.next(), '[');
210 let scope = self.parse_scope();
211 assert_eq!(self.next(), '|');
212 let br = self.parse_bound_region();
213 assert_eq!(self.next(), ']');
214 ty::ReFree(ty::FreeRegion { scope: scope,
218 let scope = self.parse_scope();
219 assert_eq!(self.next(), '|');
228 _ => panic!("parse_region: bad input")
232 fn parse_scope(&mut self) -> region::CodeExtent {
233 self.tcx.region_maps.bogus_code_extent(match self.next() {
234 // This creates scopes with the wrong NodeId. This isn't
235 // actually a problem because scopes only exist *within*
236 // functions, and functions aren't loaded until trans which
237 // doesn't care about regions.
239 // May still be worth fixing though.
241 assert_eq!(self.next(), '[');
242 let fn_id = self.parse_uint() as ast::NodeId;
243 assert_eq!(self.next(), '|');
244 let body_id = self.parse_uint() as ast::NodeId;
245 assert_eq!(self.next(), ']');
246 region::CodeExtentData::CallSiteScope {
247 fn_id: fn_id, body_id: body_id
250 // This creates scopes with the wrong NodeId. (See note above.)
252 assert_eq!(self.next(), '[');
253 let fn_id = self.parse_uint() as ast::NodeId;
254 assert_eq!(self.next(), '|');
255 let body_id = self.parse_uint() as ast::NodeId;
256 assert_eq!(self.next(), ']');
257 region::CodeExtentData::ParameterScope {
258 fn_id: fn_id, body_id: body_id
262 let node_id = self.parse_uint() as ast::NodeId;
263 region::CodeExtentData::Misc(node_id)
266 let node_id = self.parse_uint() as ast::NodeId;
267 region::CodeExtentData::DestructionScope(node_id)
270 assert_eq!(self.next(), '[');
271 let node_id = self.parse_uint() as ast::NodeId;
272 assert_eq!(self.next(), '|');
273 let first_stmt_index = self.parse_u32();
274 assert_eq!(self.next(), ']');
275 let block_remainder = region::BlockRemainder {
276 block: node_id, first_statement_index: first_stmt_index,
278 region::CodeExtentData::Remainder(block_remainder)
280 _ => panic!("parse_scope: bad input")
284 fn parse_opt<T, F>(&mut self, f: F) -> Option<T>
285 where F: FnOnce(&mut TyDecoder<'a, 'tcx>) -> T,
289 's' => Some(f(self)),
290 _ => panic!("parse_opt: bad input")
294 fn parse_str(&mut self, term: char) -> String {
295 let mut result = String::new();
296 while self.peek() != term {
298 result.as_mut_vec().extend_from_slice(&[self.next_byte()])
305 pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> {
306 let def = self.parse_def();
307 let substs = self.tcx.mk_substs(self.parse_substs());
308 ty::TraitRef {def_id: def, substs: substs}
311 pub fn parse_ty(&mut self) -> Ty<'tcx> {
314 'b' => return tcx.types.bool,
315 'i' => { /* eat the s of is */ self.next(); return tcx.types.isize },
316 'u' => { /* eat the s of us */ self.next(); return tcx.types.usize },
319 'b' => return tcx.types.u8,
320 'w' => return tcx.types.u16,
321 'l' => return tcx.types.u32,
322 'd' => return tcx.types.u64,
323 'B' => return tcx.types.i8,
324 'W' => return tcx.types.i16,
325 'L' => return tcx.types.i32,
326 'D' => return tcx.types.i64,
327 'f' => return tcx.types.f32,
328 'F' => return tcx.types.f64,
329 _ => panic!("parse_ty: bad numeric type")
332 'c' => return tcx.types.char,
334 assert_eq!(self.next(), '[');
335 let did = self.parse_def();
336 let substs = self.parse_substs();
337 assert_eq!(self.next(), ']');
338 let def = self.tcx.lookup_adt_def(did);
339 return tcx.mk_enum(def, self.tcx.mk_substs(substs));
342 assert_eq!(self.next(), '[');
343 let trait_ref = ty::Binder(self.parse_trait_ref());
344 let bounds = self.parse_existential_bounds();
345 assert_eq!(self.next(), ']');
346 return tcx.mk_trait(trait_ref, bounds);
349 assert_eq!(self.next(), '[');
350 let index = self.parse_u32();
351 assert_eq!(self.next(), '|');
352 let space = self.parse_param_space();
353 assert_eq!(self.next(), '|');
354 let name = token::intern(&self.parse_str(']'));
355 return tcx.mk_param(space, index, name);
357 '~' => return tcx.mk_box(self.parse_ty()),
358 '*' => return tcx.mk_ptr(self.parse_mt()),
360 let r = self.parse_region();
361 let mt = self.parse_mt();
362 return tcx.mk_ref(tcx.mk_region(r), mt);
365 let t = self.parse_ty();
366 return match self.parse_size() {
367 Some(n) => tcx.mk_array(t, n),
368 None => tcx.mk_slice(t)
375 assert_eq!(self.next(), '[');
376 let mut params = Vec::new();
377 while self.peek() != ']' { params.push(self.parse_ty()); }
378 self.pos = self.pos + 1;
379 return tcx.mk_tup(params);
382 let def_id = self.parse_def();
383 return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(self.parse_bare_fn_ty()));
386 return tcx.mk_fn(None, tcx.mk_bare_fn(self.parse_bare_fn_ty()));
389 // This is a hacky little caching scheme. The idea is that if we encode
390 // the same type twice, the second (and third, and fourth...) time we will
391 // just write `#123`, where `123` is the offset in the metadata of the
392 // first appearance. Now when we are *decoding*, if we see a `#123`, we
393 // can first check a cache (`tcx.rcache`) for that offset. If we find something,
394 // we return it (modulo closure types, see below). But if not, then we
395 // jump to offset 123 and read the type from there.
397 let pos = self.parse_vuint();
398 let key = ty::CReaderCacheKey { cnum: self.krate, pos: pos };
399 match tcx.rcache.borrow().get(&key).cloned() {
401 // If there is a closure buried in the type some where, then we
402 // need to re-convert any def ids (see case 'k', below). That means
403 // we can't reuse the cached version.
404 if !tt.has_closure_types() {
411 let mut substate = TyDecoder::new(self.data,
416 let tt = substate.parse_ty();
417 tcx.rcache.borrow_mut().insert(key, tt);
421 let _ = self.parse_def();
422 let inner = self.parse_ty();
426 assert_eq!(self.next(), '[');
427 let did = self.parse_def();
428 let substs = self.parse_substs();
429 assert_eq!(self.next(), ']');
430 let def = self.tcx.lookup_adt_def(did);
431 return self.tcx.mk_struct(def, self.tcx.mk_substs(substs));
434 assert_eq!(self.next(), '[');
435 let did = self.parse_def();
436 let substs = self.parse_substs();
437 let mut tys = vec![];
438 while self.peek() != '.' {
439 tys.push(self.parse_ty());
441 assert_eq!(self.next(), '.');
442 assert_eq!(self.next(), ']');
443 return self.tcx.mk_closure(did, self.tcx.mk_substs(substs), tys);
446 assert_eq!(self.next(), '[');
447 let trait_ref = self.parse_trait_ref();
448 let name = token::intern(&self.parse_str(']'));
449 return tcx.mk_projection(trait_ref, name);
452 return tcx.types.err;
454 c => { panic!("unexpected char in type string: {}", c);}
458 fn parse_mutability(&mut self) -> hir::Mutability {
460 'm' => { self.next(); hir::MutMutable }
461 _ => { hir::MutImmutable }
465 fn parse_mt(&mut self) -> ty::TypeAndMut<'tcx> {
466 let m = self.parse_mutability();
467 ty::TypeAndMut { ty: self.parse_ty(), mutbl: m }
470 fn parse_def(&mut self) -> DefId {
471 let def_id = parse_defid(self.scan(|c| c == '|'));
472 return (self.conv_def_id)(def_id);
475 fn parse_uint(&mut self) -> usize {
478 let cur = self.peek();
479 if cur < '0' || cur > '9' { return n; }
480 self.pos = self.pos + 1;
482 n += (cur as usize) - ('0' as usize);
486 fn parse_u32(&mut self) -> u32 {
487 let n = self.parse_uint();
489 assert_eq!(m as usize, n);
493 fn parse_param_space(&mut self) -> subst::ParamSpace {
494 subst::ParamSpace::from_uint(self.parse_uint())
497 fn parse_abi_set(&mut self) -> abi::Abi {
498 assert_eq!(self.next(), '[');
499 let bytes = self.scan(|c| c == ']');
500 let abi_str = str::from_utf8(bytes).unwrap();
501 abi::lookup(&abi_str[..]).expect(abi_str)
504 pub fn parse_closure_ty(&mut self) -> ty::ClosureTy<'tcx> {
505 let unsafety = parse_unsafety(self.next());
506 let sig = self.parse_sig();
507 let abi = self.parse_abi_set();
515 pub fn parse_bare_fn_ty(&mut self) -> ty::BareFnTy<'tcx> {
516 let unsafety = parse_unsafety(self.next());
517 let abi = self.parse_abi_set();
518 let sig = self.parse_sig();
526 fn parse_sig(&mut self) -> ty::PolyFnSig<'tcx> {
527 assert_eq!(self.next(), '[');
528 let mut inputs = Vec::new();
529 while self.peek() != ']' {
530 inputs.push(self.parse_ty());
532 self.pos += 1; // eat the ']'
533 let variadic = match self.next() {
536 r => panic!(format!("bad variadic: {}", r)),
538 let output = match self.peek() {
543 _ => ty::FnConverging(self.parse_ty())
545 ty::Binder(ty::FnSig {inputs: inputs,
550 pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> {
552 't' => ty::Binder(self.parse_trait_ref()).to_predicate(),
553 'e' => ty::Binder(ty::EquatePredicate(self.parse_ty(),
554 self.parse_ty())).to_predicate(),
555 'r' => ty::Binder(ty::OutlivesPredicate(self.parse_region(),
556 self.parse_region())).to_predicate(),
557 'o' => ty::Binder(ty::OutlivesPredicate(self.parse_ty(),
558 self.parse_region())).to_predicate(),
559 'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(),
560 'w' => ty::Predicate::WellFormed(self.parse_ty()),
562 let def_id = self.parse_def();
563 assert_eq!(self.next(), '|');
564 ty::Predicate::ObjectSafe(def_id)
566 c => panic!("Encountered invalid character in metadata: {}", c)
570 fn parse_projection_predicate(&mut self) -> ty::ProjectionPredicate<'tcx> {
571 ty::ProjectionPredicate {
572 projection_ty: ty::ProjectionTy {
573 trait_ref: self.parse_trait_ref(),
574 item_name: token::intern(&self.parse_str('|')),
580 pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
581 let name = self.parse_name(':');
582 let def_id = self.parse_def();
583 let space = self.parse_param_space();
584 assert_eq!(self.next(), '|');
585 let index = self.parse_u32();
586 assert_eq!(self.next(), '|');
587 let default_def_id = self.parse_def();
588 let default = self.parse_opt(|this| this.parse_ty());
589 let object_lifetime_default = self.parse_object_lifetime_default();
591 ty::TypeParameterDef {
596 default_def_id: default_def_id,
598 object_lifetime_default: object_lifetime_default,
602 pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
603 let name = self.parse_name(':');
604 let def_id = self.parse_def();
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 mut bounds = vec![];
612 'R' => bounds.push(self.parse_region()),
615 panic!("parse_region_param_def: bad bounds ('{}')", c)
619 ty::RegionParameterDef {
629 fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault {
631 'a' => ty::ObjectLifetimeDefault::Ambiguous,
632 'b' => ty::ObjectLifetimeDefault::BaseDefault,
634 let region = self.parse_region();
635 ty::ObjectLifetimeDefault::Specific(region)
637 _ => panic!("parse_object_lifetime_default: bad input")
641 pub fn parse_existential_bounds(&mut self) -> ty::ExistentialBounds<'tcx> {
642 let builtin_bounds = self.parse_builtin_bounds();
643 let region_bound = self.parse_region();
644 let mut projection_bounds = Vec::new();
649 projection_bounds.push(ty::Binder(self.parse_projection_predicate()));
653 panic!("parse_bounds: bad bounds ('{}')", c)
658 ty::ExistentialBounds::new(
659 region_bound, builtin_bounds, projection_bounds)
662 fn parse_builtin_bounds(&mut self) -> ty::BuiltinBounds {
663 let mut builtin_bounds = ty::BuiltinBounds::empty();
667 builtin_bounds.insert(ty::BoundSend);
670 builtin_bounds.insert(ty::BoundSized);
673 builtin_bounds.insert(ty::BoundCopy);
676 builtin_bounds.insert(ty::BoundSync);
679 return builtin_bounds;
682 panic!("parse_bounds: bad builtin bounds ('{}')", c)
689 // Rust metadata parsing
690 fn parse_defid(buf: &[u8]) -> DefId {
691 let mut colon_idx = 0;
693 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; }
694 if colon_idx == len {
695 error!("didn't find ':' when parsing def id");
699 let crate_part = &buf[0..colon_idx];
700 let def_part = &buf[colon_idx + 1..len];
702 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
703 s.parse::<usize>().ok()
705 Some(cn) => cn as ast::CrateNum,
706 None => panic!("internal error: parse_defid: crate number expected, found {:?}",
709 let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
710 s.parse::<usize>().ok()
713 None => panic!("internal error: parse_defid: id expected, found {:?}",
716 let index = DefIndex::new(def_num);
717 DefId { krate: crate_num, index: index }
720 fn parse_unsafety(c: char) -> hir::Unsafety {
722 'u' => hir::Unsafety::Unsafe,
723 'n' => hir::Unsafety::Normal,
724 _ => panic!("parse_unsafety: bad unsafety {}", c)