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 rustc::hir::def_id::{DefId, DefIndex};
23 use rustc::ty::subst::Substs;
24 use rustc::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
31 use syntax::parse::token;
33 // Compact string representation for Ty values. API TyStr &
34 // parse_from_str. Extra parameters are for converting to/from def_ids in the
35 // data buffer. Whatever format you choose should not contain pipe characters.
37 pub type DefIdConvert<'a> = &'a mut FnMut(DefId) -> DefId;
39 pub struct TyDecoder<'a, 'tcx: 'a> {
43 tcx: TyCtxt<'a, 'tcx, 'tcx>,
44 conv_def_id: DefIdConvert<'a>,
47 impl<'a,'tcx> TyDecoder<'a,'tcx> {
48 pub fn with_doc(tcx: TyCtxt<'a, 'tcx, 'tcx>,
49 crate_num: ast::CrateNum,
51 conv: DefIdConvert<'a>)
52 -> TyDecoder<'a,'tcx> {
53 TyDecoder::new(doc.data, crate_num, doc.start, tcx, conv)
56 pub fn new(data: &'a [u8],
57 crate_num: ast::CrateNum,
59 tcx: TyCtxt<'a, 'tcx, 'tcx>,
60 conv: DefIdConvert<'a>)
61 -> TyDecoder<'a, 'tcx> {
71 pub fn position(&self) -> usize {
75 fn peek(&self) -> char {
76 self.data[self.pos] as char
79 fn next(&mut self) -> char {
80 let ch = self.data[self.pos] as char;
81 self.pos = self.pos + 1;
85 fn next_byte(&mut self) -> u8 {
86 let b = self.data[self.pos];
87 self.pos = self.pos + 1;
91 fn scan<F>(&mut self, mut is_last: F) -> &'a [u8]
92 where F: FnMut(char) -> bool,
94 let start_pos = self.pos;
95 debug!("scan: '{}' (start)", self.data[self.pos] as char);
96 while !is_last(self.data[self.pos] as char) {
98 debug!("scan: '{}'", self.data[self.pos] as char);
100 let end_pos = self.pos;
102 return &self.data[start_pos..end_pos];
105 fn parse_vuint(&mut self) -> usize {
106 let (value, bytes_read) = leb128::read_unsigned_leb128(self.data,
108 self.pos += bytes_read;
112 fn parse_name(&mut self, last: char) -> ast::Name {
113 fn is_last(b: char, c: char) -> bool { return c == b; }
114 let bytes = self.scan(|a| is_last(last, a));
115 token::intern(str::from_utf8(bytes).unwrap())
118 fn parse_size(&mut self) -> Option<usize> {
119 assert_eq!(self.next(), '/');
121 if self.peek() == '|' {
122 assert_eq!(self.next(), '|');
125 let n = self.parse_uint();
126 assert_eq!(self.next(), '|');
131 pub fn parse_substs(&mut self) -> &'tcx Substs<'tcx> {
132 let mut regions = vec![];
133 let mut types = vec![];
134 assert_eq!(self.next(), '[');
135 while self.peek() != '|' {
136 regions.push(self.parse_region());
138 assert_eq!(self.next(), '|');
139 while self.peek() != ']' {
140 types.push(self.parse_ty());
142 assert_eq!(self.next(), ']');
144 Substs::new(self.tcx, types, regions)
147 pub fn parse_generics(&mut self) -> &'tcx ty::Generics<'tcx> {
148 let parent = self.parse_opt(|this| this.parse_def());
149 let parent_regions = self.parse_u32();
150 assert_eq!(self.next(), '|');
151 let parent_types = self.parse_u32();
153 let mut regions = vec![];
154 let mut types = vec![];
155 assert_eq!(self.next(), '[');
156 while self.peek() != '|' {
157 regions.push(self.parse_region_param_def());
159 assert_eq!(self.next(), '|');
160 while self.peek() != ']' {
161 types.push(self.parse_type_param_def());
163 assert_eq!(self.next(), ']');
165 self.tcx.alloc_generics(ty::Generics {
167 parent_regions: parent_regions,
168 parent_types: parent_types,
171 has_self: self.next() == 'S'
175 fn parse_bound_region(&mut self) -> ty::BoundRegion {
178 let id = self.parse_u32();
179 assert_eq!(self.next(), '|');
183 let def = self.parse_def();
184 let name = token::intern(&self.parse_str('|'));
185 let issue32330 = match self.next() {
187 assert_eq!(self.next(), ']');
188 ty::Issue32330::WontChange
191 ty::Issue32330::WillChange {
192 fn_def_id: self.parse_def(),
193 region_name: token::intern(&self.parse_str(']')),
196 c => panic!("expected n or y not {}", c)
198 ty::BrNamed(def, name, issue32330)
201 let id = self.parse_u32();
202 assert_eq!(self.next(), '|');
206 _ => bug!("parse_bound_region: bad input")
210 pub fn parse_region(&mut self) -> ty::Region {
213 assert_eq!(self.next(), '[');
214 let id = ty::DebruijnIndex::new(self.parse_u32());
215 assert_eq!(self.next(), '|');
216 let br = self.parse_bound_region();
217 assert_eq!(self.next(), ']');
218 ty::ReLateBound(id, br)
221 assert_eq!(self.next(), '[');
222 let index = self.parse_u32();
223 assert_eq!(self.next(), '|');
224 let name = token::intern(&self.parse_str(']'));
225 ty::ReEarlyBound(ty::EarlyBoundRegion {
231 assert_eq!(self.next(), '[');
232 let scope = self.parse_scope();
233 assert_eq!(self.next(), '|');
234 let br = self.parse_bound_region();
235 assert_eq!(self.next(), ']');
236 ty::ReFree(ty::FreeRegion { scope: scope,
240 let scope = self.parse_scope();
241 assert_eq!(self.next(), '|');
247 _ => bug!("parse_region: bad input")
251 fn parse_scope(&mut self) -> region::CodeExtent {
252 self.tcx.region_maps.bogus_code_extent(match self.next() {
253 // This creates scopes with the wrong NodeId. This isn't
254 // actually a problem because scopes only exist *within*
255 // functions, and functions aren't loaded until trans which
256 // doesn't care about regions.
258 // May still be worth fixing though.
260 assert_eq!(self.next(), '[');
261 let fn_id = self.parse_uint() as ast::NodeId;
262 assert_eq!(self.next(), '|');
263 let body_id = self.parse_uint() as ast::NodeId;
264 assert_eq!(self.next(), ']');
265 region::CodeExtentData::CallSiteScope {
266 fn_id: fn_id, body_id: body_id
269 // This creates scopes with the wrong NodeId. (See note above.)
271 assert_eq!(self.next(), '[');
272 let fn_id = self.parse_uint() as ast::NodeId;
273 assert_eq!(self.next(), '|');
274 let body_id = self.parse_uint() as ast::NodeId;
275 assert_eq!(self.next(), ']');
276 region::CodeExtentData::ParameterScope {
277 fn_id: fn_id, body_id: body_id
281 let node_id = self.parse_uint() as ast::NodeId;
282 region::CodeExtentData::Misc(node_id)
285 let node_id = self.parse_uint() as ast::NodeId;
286 region::CodeExtentData::DestructionScope(node_id)
289 assert_eq!(self.next(), '[');
290 let node_id = self.parse_uint() as ast::NodeId;
291 assert_eq!(self.next(), '|');
292 let first_stmt_index = self.parse_u32();
293 assert_eq!(self.next(), ']');
294 let block_remainder = region::BlockRemainder {
295 block: node_id, first_statement_index: first_stmt_index,
297 region::CodeExtentData::Remainder(block_remainder)
299 _ => bug!("parse_scope: bad input")
303 fn parse_opt<T, F>(&mut self, f: F) -> Option<T>
304 where F: FnOnce(&mut TyDecoder<'a, 'tcx>) -> T,
308 's' => Some(f(self)),
309 _ => bug!("parse_opt: bad input")
313 fn parse_str(&mut self, term: char) -> String {
314 let mut result = String::new();
315 while self.peek() != term {
317 result.as_mut_vec().extend_from_slice(&[self.next_byte()])
324 pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> {
326 def_id: self.parse_def(),
327 substs: self.parse_substs()
331 pub fn parse_existential_trait_ref(&mut self) -> ty::ExistentialTraitRef<'tcx> {
332 ty::ExistentialTraitRef {
333 def_id: self.parse_def(),
334 substs: self.parse_substs()
338 pub fn parse_ty(&mut self) -> Ty<'tcx> {
341 'b' => return tcx.types.bool,
342 '!' => return tcx.types.never,
343 'i' => { /* eat the s of is */ self.next(); return tcx.types.isize },
344 'u' => { /* eat the s of us */ self.next(); return tcx.types.usize },
347 'b' => return tcx.types.u8,
348 'w' => return tcx.types.u16,
349 'l' => return tcx.types.u32,
350 'd' => return tcx.types.u64,
351 'B' => return tcx.types.i8,
352 'W' => return tcx.types.i16,
353 'L' => return tcx.types.i32,
354 'D' => return tcx.types.i64,
355 'f' => return tcx.types.f32,
356 'F' => return tcx.types.f64,
357 _ => bug!("parse_ty: bad numeric type")
360 'c' => return tcx.types.char,
362 assert_eq!(self.next(), '[');
363 let did = self.parse_def();
364 let substs = self.parse_substs();
365 assert_eq!(self.next(), ']');
366 let def = self.tcx.lookup_adt_def(did);
367 return tcx.mk_enum(def, substs);
370 assert_eq!(self.next(), '[');
371 let trait_ref = ty::Binder(self.parse_existential_trait_ref());
372 let builtin_bounds = self.parse_builtin_bounds();
373 let region_bound = self.parse_region();
374 let mut projection_bounds = Vec::new();
379 let bound = self.parse_existential_projection();
380 projection_bounds.push(ty::Binder(bound));
384 bug!("parse_bounds: bad bounds ('{}')", c)
388 assert_eq!(self.next(), ']');
389 return tcx.mk_trait(ty::TraitObject {
390 principal: trait_ref,
391 region_bound: region_bound,
392 builtin_bounds: builtin_bounds,
393 projection_bounds: projection_bounds
397 assert_eq!(self.next(), '[');
398 let index = self.parse_u32();
399 assert_eq!(self.next(), '|');
400 let name = token::intern(&self.parse_str(']'));
401 return tcx.mk_param(index, name);
403 '~' => return tcx.mk_box(self.parse_ty()),
404 '*' => return tcx.mk_ptr(self.parse_mt()),
406 let r = self.parse_region();
407 let mt = self.parse_mt();
408 return tcx.mk_ref(tcx.mk_region(r), mt);
411 let t = self.parse_ty();
412 return match self.parse_size() {
413 Some(n) => tcx.mk_array(t, n),
414 None => tcx.mk_slice(t)
421 assert_eq!(self.next(), '[');
422 let mut params = Vec::new();
423 while self.peek() != ']' { params.push(self.parse_ty()); }
424 self.pos = self.pos + 1;
425 return tcx.mk_tup(params);
428 let def_id = self.parse_def();
429 let substs = self.parse_substs();
430 return tcx.mk_fn_def(def_id, substs, self.parse_bare_fn_ty());
433 return tcx.mk_fn_ptr(self.parse_bare_fn_ty());
436 // This is a hacky little caching scheme. The idea is that if we encode
437 // the same type twice, the second (and third, and fourth...) time we will
438 // just write `#123`, where `123` is the offset in the metadata of the
439 // first appearance. Now when we are *decoding*, if we see a `#123`, we
440 // can first check a cache (`tcx.rcache`) for that offset. If we find something,
441 // we return it (modulo closure types, see below). But if not, then we
442 // jump to offset 123 and read the type from there.
444 let pos = self.parse_vuint();
445 let key = ty::CReaderCacheKey { cnum: self.krate, pos: pos };
446 if let Some(tt) = tcx.rcache.borrow().get(&key).cloned() {
447 // If there is a closure buried in the type some where, then we
448 // need to re-convert any def ids (see case 'k', below). That means
449 // we can't reuse the cached version.
450 if !tt.has_closure_types() {
455 let mut substate = TyDecoder::new(self.data,
460 let tt = substate.parse_ty();
461 tcx.rcache.borrow_mut().insert(key, tt);
465 let _ = self.parse_def();
466 let inner = self.parse_ty();
470 assert_eq!(self.next(), '[');
471 let did = self.parse_def();
472 let substs = self.parse_substs();
473 assert_eq!(self.next(), ']');
474 let def = self.tcx.lookup_adt_def(did);
475 return self.tcx.mk_struct(def, substs);
478 assert_eq!(self.next(), '[');
479 let did = self.parse_def();
480 let substs = self.parse_substs();
481 let mut tys = vec![];
482 while self.peek() != '.' {
483 tys.push(self.parse_ty());
485 assert_eq!(self.next(), '.');
486 assert_eq!(self.next(), ']');
487 return self.tcx.mk_closure(did, substs, tys);
490 assert_eq!(self.next(), '[');
491 let trait_ref = self.parse_trait_ref();
492 let name = token::intern(&self.parse_str(']'));
493 return tcx.mk_projection(trait_ref, name);
496 assert_eq!(self.next(), '[');
497 let def_id = self.parse_def();
498 let substs = self.parse_substs();
499 assert_eq!(self.next(), ']');
500 return self.tcx.mk_anon(def_id, substs);
503 return tcx.types.err;
505 c => { bug!("unexpected char in type string: {}", c);}
509 fn parse_mutability(&mut self) -> hir::Mutability {
511 'm' => { self.next(); hir::MutMutable }
512 _ => { hir::MutImmutable }
516 fn parse_mt(&mut self) -> ty::TypeAndMut<'tcx> {
517 let m = self.parse_mutability();
518 ty::TypeAndMut { ty: self.parse_ty(), mutbl: m }
521 fn parse_def(&mut self) -> DefId {
522 let def_id = parse_defid(self.scan(|c| c == '|'));
523 return (self.conv_def_id)(def_id);
526 fn parse_uint(&mut self) -> usize {
529 let cur = self.peek();
530 if cur < '0' || cur > '9' { return n; }
531 self.pos = self.pos + 1;
533 n += (cur as usize) - ('0' as usize);
537 fn parse_u32(&mut self) -> u32 {
538 let n = self.parse_uint();
540 assert_eq!(m as usize, n);
544 fn parse_abi_set(&mut self) -> abi::Abi {
545 assert_eq!(self.next(), '[');
546 let bytes = self.scan(|c| c == ']');
547 let abi_str = str::from_utf8(bytes).unwrap();
548 abi::lookup(&abi_str[..]).expect(abi_str)
551 pub fn parse_closure_ty(&mut self) -> ty::ClosureTy<'tcx> {
552 let unsafety = parse_unsafety(self.next());
553 let sig = self.parse_sig();
554 let abi = self.parse_abi_set();
562 pub fn parse_bare_fn_ty(&mut self) -> &'tcx ty::BareFnTy<'tcx> {
563 let unsafety = parse_unsafety(self.next());
564 let abi = self.parse_abi_set();
565 let sig = self.parse_sig();
566 self.tcx.mk_bare_fn(ty::BareFnTy {
573 fn parse_sig(&mut self) -> ty::PolyFnSig<'tcx> {
574 assert_eq!(self.next(), '[');
575 let mut inputs = Vec::new();
576 while self.peek() != ']' {
577 inputs.push(self.parse_ty());
579 self.pos += 1; // eat the ']'
580 let variadic = match self.next() {
583 r => bug!("bad variadic: {}", r),
585 let output = self.parse_ty();
586 ty::Binder(ty::FnSig {inputs: inputs,
591 pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> {
593 't' => ty::Binder(self.parse_trait_ref()).to_predicate(),
594 'e' => ty::Binder(ty::EquatePredicate(self.parse_ty(),
595 self.parse_ty())).to_predicate(),
596 'r' => ty::Binder(ty::OutlivesPredicate(self.parse_region(),
597 self.parse_region())).to_predicate(),
598 'o' => ty::Binder(ty::OutlivesPredicate(self.parse_ty(),
599 self.parse_region())).to_predicate(),
600 'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(),
601 'w' => ty::Predicate::WellFormed(self.parse_ty()),
603 let def_id = self.parse_def();
604 assert_eq!(self.next(), '|');
605 ty::Predicate::ObjectSafe(def_id)
608 let def_id = self.parse_def();
609 assert_eq!(self.next(), '|');
610 let kind = match self.next() {
611 'f' => ty::ClosureKind::Fn,
612 'm' => ty::ClosureKind::FnMut,
613 'o' => ty::ClosureKind::FnOnce,
614 c => bug!("Encountered invalid character in metadata: {}", c)
616 assert_eq!(self.next(), '|');
617 ty::Predicate::ClosureKind(def_id, kind)
619 c => bug!("Encountered invalid character in metadata: {}", c)
623 fn parse_projection_predicate(&mut self) -> ty::ProjectionPredicate<'tcx> {
624 ty::ProjectionPredicate {
625 projection_ty: ty::ProjectionTy {
626 trait_ref: self.parse_trait_ref(),
627 item_name: token::intern(&self.parse_str('|')),
633 fn parse_existential_projection(&mut self) -> ty::ExistentialProjection<'tcx> {
634 ty::ExistentialProjection {
635 trait_ref: self.parse_existential_trait_ref(),
636 item_name: token::intern(&self.parse_str('|')),
641 fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
642 let name = self.parse_name(':');
643 let def_id = self.parse_def();
644 let index = self.parse_u32();
645 assert_eq!(self.next(), '|');
646 let default_def_id = self.parse_def();
647 let default = self.parse_opt(|this| this.parse_ty());
648 let object_lifetime_default = self.parse_object_lifetime_default();
650 ty::TypeParameterDef {
654 default_def_id: default_def_id,
656 object_lifetime_default: object_lifetime_default,
660 fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
661 let name = self.parse_name(':');
662 let def_id = self.parse_def();
663 let index = self.parse_u32();
664 assert_eq!(self.next(), '|');
665 let mut bounds = vec![];
668 'R' => bounds.push(self.parse_region()),
671 bug!("parse_region_param_def: bad bounds ('{}')", c)
675 ty::RegionParameterDef {
684 fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault {
686 'a' => ty::ObjectLifetimeDefault::Ambiguous,
687 'b' => ty::ObjectLifetimeDefault::BaseDefault,
689 let region = self.parse_region();
690 ty::ObjectLifetimeDefault::Specific(region)
692 _ => bug!("parse_object_lifetime_default: bad input")
696 fn parse_builtin_bounds(&mut self) -> ty::BuiltinBounds {
697 let mut builtin_bounds = ty::BuiltinBounds::empty();
701 builtin_bounds.insert(ty::BoundSend);
704 builtin_bounds.insert(ty::BoundSized);
707 builtin_bounds.insert(ty::BoundCopy);
710 builtin_bounds.insert(ty::BoundSync);
713 return builtin_bounds;
716 bug!("parse_bounds: bad builtin bounds ('{}')", c)
723 // Rust metadata parsing
724 fn parse_defid(buf: &[u8]) -> DefId {
725 let mut colon_idx = 0;
727 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; }
728 if colon_idx == len {
729 error!("didn't find ':' when parsing def id");
733 let crate_part = &buf[0..colon_idx];
734 let def_part = &buf[colon_idx + 1..len];
736 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
737 s.parse::<usize>().ok()
739 Some(cn) => cn as ast::CrateNum,
740 None => bug!("internal error: parse_defid: crate number expected, found {:?}",
743 let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
744 s.parse::<usize>().ok()
747 None => bug!("internal error: parse_defid: id expected, found {:?}",
750 let index = DefIndex::new(def_num);
751 DefId { krate: crate_num, index: index }
754 fn parse_unsafety(c: char) -> hir::Unsafety {
756 'u' => hir::Unsafety::Unsafe,
757 'n' => hir::Unsafety::Normal,
758 _ => bug!("parse_unsafety: bad unsafety {}", c)