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, HasTypeFlags};
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: &'a ty::ctxt<'tcx>,
44 conv_def_id: DefIdConvert<'a>,
47 impl<'a,'tcx> TyDecoder<'a,'tcx> {
48 pub fn with_doc(tcx: &'a ty::ctxt<'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: &'a ty::ctxt<'tcx>,
60 conv: DefIdConvert<'a>)
61 -> TyDecoder<'a, 'tcx> {
71 fn peek(&self) -> char {
72 self.data[self.pos] as char
75 fn next(&mut self) -> char {
76 let ch = self.data[self.pos] as char;
77 self.pos = self.pos + 1;
81 fn next_byte(&mut self) -> u8 {
82 let b = self.data[self.pos];
83 self.pos = self.pos + 1;
87 fn scan<F>(&mut self, mut is_last: F) -> &'a [u8]
88 where F: FnMut(char) -> bool,
90 let start_pos = self.pos;
91 debug!("scan: '{}' (start)", self.data[self.pos] as char);
92 while !is_last(self.data[self.pos] as char) {
94 debug!("scan: '{}'", self.data[self.pos] as char);
96 let end_pos = self.pos;
98 return &self.data[start_pos..end_pos];
101 fn parse_vuint(&mut self) -> usize {
102 let res = rbml::reader::vuint_at(self.data, self.pos).unwrap();
107 fn parse_name(&mut self, last: char) -> ast::Name {
108 fn is_last(b: char, c: char) -> bool { return c == b; }
109 let bytes = self.scan(|a| is_last(last, a));
110 token::intern(str::from_utf8(bytes).unwrap())
113 fn parse_size(&mut self) -> Option<usize> {
114 assert_eq!(self.next(), '/');
116 if self.peek() == '|' {
117 assert_eq!(self.next(), '|');
120 let n = self.parse_uint();
121 assert_eq!(self.next(), '|');
126 fn parse_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
127 F: FnMut(&mut TyDecoder<'a, 'tcx>) -> T,
129 let mut r = VecPerParamSpace::empty();
130 for &space in &subst::ParamSpace::all() {
131 assert_eq!(self.next(), '[');
132 while self.peek() != ']' {
133 r.push(space, f(self));
135 assert_eq!(self.next(), ']');
140 pub fn parse_substs(&mut self) -> subst::Substs<'tcx> {
141 let regions = self.parse_region_substs();
142 let types = self.parse_vec_per_param_space(|this| this.parse_ty());
143 subst::Substs { types: types, regions: regions }
146 fn parse_region_substs(&mut self) -> subst::RegionSubsts {
148 'e' => subst::ErasedRegions,
150 subst::NonerasedRegions(
151 self.parse_vec_per_param_space(|this| this.parse_region()))
153 _ => panic!("parse_bound_region: bad input")
157 fn parse_bound_region(&mut self) -> ty::BoundRegion {
160 let id = self.parse_u32();
161 assert_eq!(self.next(), '|');
165 let def = self.parse_def();
166 let name = token::intern(&self.parse_str(']'));
167 ty::BrNamed(def, name)
170 let id = self.parse_u32();
171 assert_eq!(self.next(), '|');
175 _ => panic!("parse_bound_region: bad input")
179 pub fn parse_region(&mut self) -> ty::Region {
182 assert_eq!(self.next(), '[');
183 let id = ty::DebruijnIndex::new(self.parse_u32());
184 assert_eq!(self.next(), '|');
185 let br = self.parse_bound_region();
186 assert_eq!(self.next(), ']');
187 ty::ReLateBound(id, br)
190 assert_eq!(self.next(), '[');
191 let def_id = self.parse_def();
192 let space = self.parse_param_space();
193 assert_eq!(self.next(), '|');
194 let index = self.parse_u32();
195 assert_eq!(self.next(), '|');
196 let name = token::intern(&self.parse_str(']'));
197 ty::ReEarlyBound(ty::EarlyBoundRegion {
205 assert_eq!(self.next(), '[');
206 let scope = self.parse_scope();
207 assert_eq!(self.next(), '|');
208 let br = self.parse_bound_region();
209 assert_eq!(self.next(), ']');
210 ty::ReFree(ty::FreeRegion { scope: scope,
214 let scope = self.parse_scope();
215 assert_eq!(self.next(), '|');
224 _ => panic!("parse_region: bad input")
228 fn parse_scope(&mut self) -> region::CodeExtent {
229 self.tcx.region_maps.bogus_code_extent(match self.next() {
230 // This creates scopes with the wrong NodeId. This isn't
231 // actually a problem because scopes only exist *within*
232 // functions, and functions aren't loaded until trans which
233 // doesn't care about regions.
235 // May still be worth fixing though.
237 assert_eq!(self.next(), '[');
238 let fn_id = self.parse_uint() as ast::NodeId;
239 assert_eq!(self.next(), '|');
240 let body_id = self.parse_uint() as ast::NodeId;
241 assert_eq!(self.next(), ']');
242 region::CodeExtentData::ParameterScope {
243 fn_id: fn_id, body_id: body_id
247 let node_id = self.parse_uint() as ast::NodeId;
248 region::CodeExtentData::Misc(node_id)
251 let node_id = self.parse_uint() as ast::NodeId;
252 region::CodeExtentData::DestructionScope(node_id)
255 assert_eq!(self.next(), '[');
256 let node_id = self.parse_uint() as ast::NodeId;
257 assert_eq!(self.next(), '|');
258 let first_stmt_index = self.parse_u32();
259 assert_eq!(self.next(), ']');
260 let block_remainder = region::BlockRemainder {
261 block: node_id, first_statement_index: first_stmt_index,
263 region::CodeExtentData::Remainder(block_remainder)
265 _ => panic!("parse_scope: bad input")
269 fn parse_opt<T, F>(&mut self, f: F) -> Option<T>
270 where F: FnOnce(&mut TyDecoder<'a, 'tcx>) -> T,
274 's' => Some(f(self)),
275 _ => panic!("parse_opt: bad input")
279 fn parse_str(&mut self, term: char) -> String {
280 let mut result = String::new();
281 while self.peek() != term {
283 result.as_mut_vec().push_all(&[self.next_byte()])
290 pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> {
291 let def = self.parse_def();
292 let substs = self.tcx.mk_substs(self.parse_substs());
293 ty::TraitRef {def_id: def, substs: substs}
296 pub fn parse_ty(&mut self) -> Ty<'tcx> {
299 'b' => return tcx.types.bool,
300 'i' => { /* eat the s of is */ self.next(); return tcx.types.isize },
301 'u' => { /* eat the s of us */ self.next(); return tcx.types.usize },
304 'b' => return tcx.types.u8,
305 'w' => return tcx.types.u16,
306 'l' => return tcx.types.u32,
307 'd' => return tcx.types.u64,
308 'B' => return tcx.types.i8,
309 'W' => return tcx.types.i16,
310 'L' => return tcx.types.i32,
311 'D' => return tcx.types.i64,
312 'f' => return tcx.types.f32,
313 'F' => return tcx.types.f64,
314 _ => panic!("parse_ty: bad numeric type")
317 'c' => return tcx.types.char,
319 assert_eq!(self.next(), '[');
320 let did = self.parse_def();
321 let substs = self.parse_substs();
322 assert_eq!(self.next(), ']');
323 let def = self.tcx.lookup_adt_def(did);
324 return tcx.mk_enum(def, self.tcx.mk_substs(substs));
327 assert_eq!(self.next(), '[');
328 let trait_ref = ty::Binder(self.parse_trait_ref());
329 let bounds = self.parse_existential_bounds();
330 assert_eq!(self.next(), ']');
331 return tcx.mk_trait(trait_ref, bounds);
334 assert_eq!(self.next(), '[');
335 let index = self.parse_u32();
336 assert_eq!(self.next(), '|');
337 let space = self.parse_param_space();
338 assert_eq!(self.next(), '|');
339 let name = token::intern(&self.parse_str(']'));
340 return tcx.mk_param(space, index, name);
342 '~' => return tcx.mk_box(self.parse_ty()),
343 '*' => return tcx.mk_ptr(self.parse_mt()),
345 let r = self.parse_region();
346 let mt = self.parse_mt();
347 return tcx.mk_ref(tcx.mk_region(r), mt);
350 let t = self.parse_ty();
351 return match self.parse_size() {
352 Some(n) => tcx.mk_array(t, n),
353 None => tcx.mk_slice(t)
360 assert_eq!(self.next(), '[');
361 let mut params = Vec::new();
362 while self.peek() != ']' { params.push(self.parse_ty()); }
363 self.pos = self.pos + 1;
364 return tcx.mk_tup(params);
367 let def_id = self.parse_def();
368 return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(self.parse_bare_fn_ty()));
371 return tcx.mk_fn(None, tcx.mk_bare_fn(self.parse_bare_fn_ty()));
374 // This is a hacky little caching scheme. The idea is that if we encode
375 // the same type twice, the second (and third, and fourth...) time we will
376 // just write `#123`, where `123` is the offset in the metadata of the
377 // first appearance. Now when we are *decoding*, if we see a `#123`, we
378 // can first check a cache (`tcx.rcache`) for that offset. If we find something,
379 // we return it (modulo closure types, see below). But if not, then we
380 // jump to offset 123 and read the type from there.
382 let pos = self.parse_vuint();
383 let key = ty::CReaderCacheKey { cnum: self.krate, pos: pos };
384 match tcx.rcache.borrow().get(&key).cloned() {
386 // If there is a closure buried in the type some where, then we
387 // need to re-convert any def ids (see case 'k', below). That means
388 // we can't reuse the cached version.
389 if !tt.has_closure_types() {
396 let mut substate = TyDecoder::new(self.data,
401 let tt = substate.parse_ty();
402 tcx.rcache.borrow_mut().insert(key, tt);
406 let _ = self.parse_def();
407 let inner = self.parse_ty();
411 assert_eq!(self.next(), '[');
412 let did = self.parse_def();
413 let substs = self.parse_substs();
414 assert_eq!(self.next(), ']');
415 let def = self.tcx.lookup_adt_def(did);
416 return self.tcx.mk_struct(def, self.tcx.mk_substs(substs));
419 assert_eq!(self.next(), '[');
420 let did = self.parse_def();
421 let substs = self.parse_substs();
422 let mut tys = vec![];
423 while self.peek() != '.' {
424 tys.push(self.parse_ty());
426 assert_eq!(self.next(), '.');
427 assert_eq!(self.next(), ']');
428 return self.tcx.mk_closure(did, self.tcx.mk_substs(substs), tys);
431 assert_eq!(self.next(), '[');
432 let trait_ref = self.parse_trait_ref();
433 let name = token::intern(&self.parse_str(']'));
434 return tcx.mk_projection(trait_ref, name);
437 return tcx.types.err;
439 c => { panic!("unexpected char in type string: {}", c);}
443 fn parse_mutability(&mut self) -> hir::Mutability {
445 'm' => { self.next(); hir::MutMutable }
446 _ => { hir::MutImmutable }
450 fn parse_mt(&mut self) -> ty::TypeAndMut<'tcx> {
451 let m = self.parse_mutability();
452 ty::TypeAndMut { ty: self.parse_ty(), mutbl: m }
455 fn parse_def(&mut self) -> DefId {
456 let def_id = parse_defid(self.scan(|c| c == '|'));
457 return (self.conv_def_id)(def_id);
460 fn parse_uint(&mut self) -> usize {
463 let cur = self.peek();
464 if cur < '0' || cur > '9' { return n; }
465 self.pos = self.pos + 1;
467 n += (cur as usize) - ('0' as usize);
471 fn parse_u32(&mut self) -> u32 {
472 let n = self.parse_uint();
474 assert_eq!(m as usize, n);
478 fn parse_param_space(&mut self) -> subst::ParamSpace {
479 subst::ParamSpace::from_uint(self.parse_uint())
482 fn parse_abi_set(&mut self) -> abi::Abi {
483 assert_eq!(self.next(), '[');
484 let bytes = self.scan(|c| c == ']');
485 let abi_str = str::from_utf8(bytes).unwrap();
486 abi::lookup(&abi_str[..]).expect(abi_str)
489 pub fn parse_closure_ty(&mut self) -> ty::ClosureTy<'tcx> {
490 let unsafety = parse_unsafety(self.next());
491 let sig = self.parse_sig();
492 let abi = self.parse_abi_set();
500 pub fn parse_bare_fn_ty(&mut self) -> ty::BareFnTy<'tcx> {
501 let unsafety = parse_unsafety(self.next());
502 let abi = self.parse_abi_set();
503 let sig = self.parse_sig();
511 fn parse_sig(&mut self) -> ty::PolyFnSig<'tcx> {
512 assert_eq!(self.next(), '[');
513 let mut inputs = Vec::new();
514 while self.peek() != ']' {
515 inputs.push(self.parse_ty());
517 self.pos += 1; // eat the ']'
518 let variadic = match self.next() {
521 r => panic!(format!("bad variadic: {}", r)),
523 let output = match self.peek() {
528 _ => ty::FnConverging(self.parse_ty())
530 ty::Binder(ty::FnSig {inputs: inputs,
535 pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> {
537 't' => ty::Binder(self.parse_trait_ref()).to_predicate(),
538 'e' => ty::Binder(ty::EquatePredicate(self.parse_ty(),
539 self.parse_ty())).to_predicate(),
540 'r' => ty::Binder(ty::OutlivesPredicate(self.parse_region(),
541 self.parse_region())).to_predicate(),
542 'o' => ty::Binder(ty::OutlivesPredicate(self.parse_ty(),
543 self.parse_region())).to_predicate(),
544 'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(),
545 'w' => ty::Predicate::WellFormed(self.parse_ty()),
547 let def_id = self.parse_def();
548 assert_eq!(self.next(), '|');
549 ty::Predicate::ObjectSafe(def_id)
551 c => panic!("Encountered invalid character in metadata: {}", c)
555 fn parse_projection_predicate(&mut self) -> ty::ProjectionPredicate<'tcx> {
556 ty::ProjectionPredicate {
557 projection_ty: ty::ProjectionTy {
558 trait_ref: self.parse_trait_ref(),
559 item_name: token::intern(&self.parse_str('|')),
565 pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
566 let name = self.parse_name(':');
567 let def_id = self.parse_def();
568 let space = self.parse_param_space();
569 assert_eq!(self.next(), '|');
570 let index = self.parse_u32();
571 assert_eq!(self.next(), '|');
572 let default_def_id = self.parse_def();
573 let default = self.parse_opt(|this| this.parse_ty());
574 let object_lifetime_default = self.parse_object_lifetime_default();
576 ty::TypeParameterDef {
581 default_def_id: default_def_id,
583 object_lifetime_default: object_lifetime_default,
587 pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
588 let name = self.parse_name(':');
589 let def_id = self.parse_def();
590 let space = self.parse_param_space();
591 assert_eq!(self.next(), '|');
592 let index = self.parse_u32();
593 assert_eq!(self.next(), '|');
594 let mut bounds = vec![];
597 'R' => bounds.push(self.parse_region()),
600 panic!("parse_region_param_def: bad bounds ('{}')", c)
604 ty::RegionParameterDef {
614 fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault {
616 'a' => ty::ObjectLifetimeDefault::Ambiguous,
617 'b' => ty::ObjectLifetimeDefault::BaseDefault,
619 let region = self.parse_region();
620 ty::ObjectLifetimeDefault::Specific(region)
622 _ => panic!("parse_object_lifetime_default: bad input")
626 pub fn parse_existential_bounds(&mut self) -> ty::ExistentialBounds<'tcx> {
627 let builtin_bounds = self.parse_builtin_bounds();
628 let region_bound = self.parse_region();
629 let mut projection_bounds = Vec::new();
634 projection_bounds.push(ty::Binder(self.parse_projection_predicate()));
638 panic!("parse_bounds: bad bounds ('{}')", c)
643 ty::ExistentialBounds::new(
644 region_bound, builtin_bounds, projection_bounds)
647 fn parse_builtin_bounds(&mut self) -> ty::BuiltinBounds {
648 let mut builtin_bounds = ty::BuiltinBounds::empty();
652 builtin_bounds.insert(ty::BoundSend);
655 builtin_bounds.insert(ty::BoundSized);
658 builtin_bounds.insert(ty::BoundCopy);
661 builtin_bounds.insert(ty::BoundSync);
664 return builtin_bounds;
667 panic!("parse_bounds: bad builtin bounds ('{}')", c)
674 // Rust metadata parsing
675 fn parse_defid(buf: &[u8]) -> DefId {
676 let mut colon_idx = 0;
678 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; }
679 if colon_idx == len {
680 error!("didn't find ':' when parsing def id");
684 let crate_part = &buf[0..colon_idx];
685 let def_part = &buf[colon_idx + 1..len];
687 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
688 s.parse::<usize>().ok()
690 Some(cn) => cn as ast::CrateNum,
691 None => panic!("internal error: parse_defid: crate number expected, found {:?}",
694 let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
695 s.parse::<usize>().ok()
698 None => panic!("internal error: parse_defid: id expected, found {:?}",
701 let index = DefIndex::new(def_num);
702 DefId { krate: crate_num, index: index }
705 fn parse_unsafety(c: char) -> hir::Unsafety {
707 'u' => hir::Unsafety::Unsafe,
708 'n' => hir::Unsafety::Normal,
709 _ => panic!("parse_unsafety: bad unsafety {}", c)