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}
;
24 use rustc
::ty
::subst
::VecPerParamSpace
;
25 use rustc
::ty
::{self, ToPredicate, Ty, TyCtxt, 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 TyCtxt
<'tcx
>,
45 conv_def_id
: DefIdConvert
<'a
>,
48 impl<'a
,'tcx
> TyDecoder
<'a
,'tcx
> {
49 pub fn with_doc(tcx
: &'a TyCtxt
<'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 TyCtxt
<'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_vec_per_param_space(|this
| this
.parse_region());
148 let types
= self.parse_vec_per_param_space(|this
| this
.parse_ty());
149 subst
::Substs { types: types, regions: regions }
152 fn parse_bound_region(&mut self) -> ty
::BoundRegion
{
155 let id
= self.parse_u32();
156 assert_eq
!(self.next(), '
|'
);
160 let def
= self.parse_def();
161 let name
= token
::intern(&self.parse_str('
]'
));
162 ty
::BrNamed(def
, name
)
165 let id
= self.parse_u32();
166 assert_eq
!(self.next(), '
|'
);
170 _
=> bug
!("parse_bound_region: bad input")
174 pub fn parse_region(&mut self) -> ty
::Region
{
177 assert_eq
!(self.next(), '
['
);
178 let id
= ty
::DebruijnIndex
::new(self.parse_u32());
179 assert_eq
!(self.next(), '
|'
);
180 let br
= self.parse_bound_region();
181 assert_eq
!(self.next(), '
]'
);
182 ty
::ReLateBound(id
, br
)
185 assert_eq
!(self.next(), '
['
);
186 let space
= self.parse_param_space();
187 assert_eq
!(self.next(), '
|'
);
188 let index
= self.parse_u32();
189 assert_eq
!(self.next(), '
|'
);
190 let name
= token
::intern(&self.parse_str('
]'
));
191 ty
::ReEarlyBound(ty
::EarlyBoundRegion
{
198 assert_eq
!(self.next(), '
['
);
199 let scope
= self.parse_scope();
200 assert_eq
!(self.next(), '
|'
);
201 let br
= self.parse_bound_region();
202 assert_eq
!(self.next(), '
]'
);
203 ty
::ReFree(ty
::FreeRegion
{ scope
: scope
,
207 let scope
= self.parse_scope();
208 assert_eq
!(self.next(), '
|'
);
217 _
=> bug
!("parse_region: bad input")
221 fn parse_scope(&mut self) -> region
::CodeExtent
{
222 self.tcx
.region_maps
.bogus_code_extent(match self.next() {
223 // This creates scopes with the wrong NodeId. This isn't
224 // actually a problem because scopes only exist *within*
225 // functions, and functions aren't loaded until trans which
226 // doesn't care about regions.
228 // May still be worth fixing though.
230 assert_eq
!(self.next(), '
['
);
231 let fn_id
= self.parse_uint() as ast
::NodeId
;
232 assert_eq
!(self.next(), '
|'
);
233 let body_id
= self.parse_uint() as ast
::NodeId
;
234 assert_eq
!(self.next(), '
]'
);
235 region
::CodeExtentData
::CallSiteScope
{
236 fn_id
: fn_id
, body_id
: body_id
239 // This creates scopes with the wrong NodeId. (See note above.)
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
::ParameterScope
{
247 fn_id
: fn_id
, body_id
: body_id
251 let node_id
= self.parse_uint() as ast
::NodeId
;
252 region
::CodeExtentData
::Misc(node_id
)
255 let node_id
= self.parse_uint() as ast
::NodeId
;
256 region
::CodeExtentData
::DestructionScope(node_id
)
259 assert_eq
!(self.next(), '
['
);
260 let node_id
= self.parse_uint() as ast
::NodeId
;
261 assert_eq
!(self.next(), '
|'
);
262 let first_stmt_index
= self.parse_u32();
263 assert_eq
!(self.next(), '
]'
);
264 let block_remainder
= region
::BlockRemainder
{
265 block
: node_id
, first_statement_index
: first_stmt_index
,
267 region
::CodeExtentData
::Remainder(block_remainder
)
269 _
=> bug
!("parse_scope: bad input")
273 fn parse_opt
<T
, F
>(&mut self, f
: F
) -> Option
<T
>
274 where F
: FnOnce(&mut TyDecoder
<'a
, 'tcx
>) -> T
,
278 's'
=> Some(f(self)),
279 _
=> bug
!("parse_opt: bad input")
283 fn parse_str(&mut self, term
: char) -> String
{
284 let mut result
= String
::new();
285 while self.peek() != term
{
287 result
.as_mut_vec().extend_from_slice(&[self.next_byte()])
294 pub fn parse_trait_ref(&mut self) -> ty
::TraitRef
<'tcx
> {
295 let def
= self.parse_def();
296 let substs
= self.tcx
.mk_substs(self.parse_substs());
297 ty
::TraitRef {def_id: def, substs: substs}
300 pub fn parse_ty(&mut self) -> Ty
<'tcx
> {
303 'b'
=> return tcx
.types
.bool
,
304 'i'
=> { /* eat the s of is */ self.next(); return tcx.types.isize }
,
305 'u'
=> { /* eat the s of us */ self.next(); return tcx.types.usize }
,
308 'b'
=> return tcx
.types
.u8,
309 'w'
=> return tcx
.types
.u16,
310 'l'
=> return tcx
.types
.u32,
311 'd'
=> return tcx
.types
.u64,
312 'B'
=> return tcx
.types
.i8,
313 'W'
=> return tcx
.types
.i16,
314 'L'
=> return tcx
.types
.i32,
315 'D'
=> return tcx
.types
.i64,
316 'f'
=> return tcx
.types
.f32,
317 'F'
=> return tcx
.types
.f64,
318 _
=> bug
!("parse_ty: bad numeric type")
321 'c'
=> return tcx
.types
.char,
323 assert_eq
!(self.next(), '
['
);
324 let did
= self.parse_def();
325 let substs
= self.parse_substs();
326 assert_eq
!(self.next(), '
]'
);
327 let def
= self.tcx
.lookup_adt_def(did
);
328 return tcx
.mk_enum(def
, self.tcx
.mk_substs(substs
));
331 assert_eq
!(self.next(), '
['
);
332 let trait_ref
= ty
::Binder(self.parse_trait_ref());
333 let bounds
= self.parse_existential_bounds();
334 assert_eq
!(self.next(), '
]'
);
335 return tcx
.mk_trait(trait_ref
, bounds
);
338 assert_eq
!(self.next(), '
['
);
339 let index
= self.parse_u32();
340 assert_eq
!(self.next(), '
|'
);
341 let space
= self.parse_param_space();
342 assert_eq
!(self.next(), '
|'
);
343 let name
= token
::intern(&self.parse_str('
]'
));
344 return tcx
.mk_param(space
, index
, name
);
346 '
~'
=> return tcx
.mk_box(self.parse_ty()),
347 '
*'
=> return tcx
.mk_ptr(self.parse_mt()),
349 let r
= self.parse_region();
350 let mt
= self.parse_mt();
351 return tcx
.mk_ref(tcx
.mk_region(r
), mt
);
354 let t
= self.parse_ty();
355 return match self.parse_size() {
356 Some(n
) => tcx
.mk_array(t
, n
),
357 None
=> tcx
.mk_slice(t
)
364 assert_eq
!(self.next(), '
['
);
365 let mut params
= Vec
::new();
366 while self.peek() != '
]' { params.push(self.parse_ty()); }
367 self.pos
= self.pos
+ 1;
368 return tcx
.mk_tup(params
);
371 let def_id
= self.parse_def();
372 let substs
= self.tcx
.mk_substs(self.parse_substs());
373 return tcx
.mk_fn_def(def_id
, substs
, self.parse_bare_fn_ty());
376 return tcx
.mk_fn_ptr(self.parse_bare_fn_ty());
379 // This is a hacky little caching scheme. The idea is that if we encode
380 // the same type twice, the second (and third, and fourth...) time we will
381 // just write `#123`, where `123` is the offset in the metadata of the
382 // first appearance. Now when we are *decoding*, if we see a `#123`, we
383 // can first check a cache (`tcx.rcache`) for that offset. If we find something,
384 // we return it (modulo closure types, see below). But if not, then we
385 // jump to offset 123 and read the type from there.
387 let pos
= self.parse_vuint();
388 let key
= ty
::CReaderCacheKey { cnum: self.krate, pos: pos }
;
389 match tcx
.rcache
.borrow().get(&key
).cloned() {
391 // If there is a closure buried in the type some where, then we
392 // need to re-convert any def ids (see case 'k', below). That means
393 // we can't reuse the cached version.
394 if !tt
.has_closure_types() {
401 let mut substate
= TyDecoder
::new(self.data
,
406 let tt
= substate
.parse_ty();
407 tcx
.rcache
.borrow_mut().insert(key
, tt
);
411 let _
= self.parse_def();
412 let inner
= self.parse_ty();
416 assert_eq
!(self.next(), '
['
);
417 let did
= self.parse_def();
418 let substs
= self.parse_substs();
419 assert_eq
!(self.next(), '
]'
);
420 let def
= self.tcx
.lookup_adt_def(did
);
421 return self.tcx
.mk_struct(def
, self.tcx
.mk_substs(substs
));
424 assert_eq
!(self.next(), '
['
);
425 let did
= self.parse_def();
426 let substs
= self.parse_substs();
427 let mut tys
= vec
![];
428 while self.peek() != '
.'
{
429 tys
.push(self.parse_ty());
431 assert_eq
!(self.next(), '
.'
);
432 assert_eq
!(self.next(), '
]'
);
433 return self.tcx
.mk_closure(did
, self.tcx
.mk_substs(substs
), tys
);
436 assert_eq
!(self.next(), '
['
);
437 let trait_ref
= self.parse_trait_ref();
438 let name
= token
::intern(&self.parse_str('
]'
));
439 return tcx
.mk_projection(trait_ref
, name
);
442 return tcx
.types
.err
;
444 c
=> { bug!("unexpected char in type string: {}
", c);}
448 fn parse_mutability(&mut self) -> hir::Mutability {
450 'm' => { self.next(); hir::MutMutable }
451 _ => { hir::MutImmutable }
455 fn parse_mt(&mut self) -> ty::TypeAndMut<'tcx> {
456 let m = self.parse_mutability();
457 ty::TypeAndMut { ty: self.parse_ty(), mutbl: m }
460 fn parse_def(&mut self) -> DefId {
461 let def_id = parse_defid(self.scan(|c| c == '|'));
462 return (self.conv_def_id)(def_id);
465 fn parse_uint(&mut self) -> usize {
468 let cur = self.peek();
469 if cur < '0' || cur > '9' { return n; }
470 self.pos = self.pos + 1;
472 n += (cur as usize) - ('0' as usize);
476 fn parse_u32(&mut self) -> u32 {
477 let n = self.parse_uint();
479 assert_eq!(m as usize, n);
483 fn parse_param_space(&mut self) -> subst::ParamSpace {
484 subst::ParamSpace::from_uint(self.parse_uint())
487 fn parse_abi_set(&mut self) -> abi::Abi {
488 assert_eq!(self.next(), '[');
489 let bytes = self.scan(|c| c == ']');
490 let abi_str = str::from_utf8(bytes).unwrap();
491 abi::lookup(&abi_str[..]).expect(abi_str)
494 pub fn parse_closure_ty(&mut self) -> ty::ClosureTy<'tcx> {
495 let unsafety = parse_unsafety(self.next());
496 let sig = self.parse_sig();
497 let abi = self.parse_abi_set();
505 pub fn parse_bare_fn_ty(&mut self) -> ty::BareFnTy<'tcx> {
506 let unsafety = parse_unsafety(self.next());
507 let abi = self.parse_abi_set();
508 let sig = self.parse_sig();
516 fn parse_sig(&mut self) -> ty::PolyFnSig<'tcx> {
517 assert_eq!(self.next(), '[');
518 let mut inputs = Vec::new();
519 while self.peek() != ']' {
520 inputs.push(self.parse_ty());
522 self.pos += 1; // eat the ']'
523 let variadic = match self.next() {
526 r => bug!("bad variadic
: {}
", r),
528 let output = match self.peek() {
533 _ => ty::FnConverging(self.parse_ty())
535 ty::Binder(ty::FnSig {inputs: inputs,
540 pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> {
542 't' => ty::Binder(self.parse_trait_ref()).to_predicate(),
543 'e' => ty::Binder(ty::EquatePredicate(self.parse_ty(),
544 self.parse_ty())).to_predicate(),
545 'r' => ty::Binder(ty::OutlivesPredicate(self.parse_region(),
546 self.parse_region())).to_predicate(),
547 'o' => ty::Binder(ty::OutlivesPredicate(self.parse_ty(),
548 self.parse_region())).to_predicate(),
549 'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(),
550 'w' => ty::Predicate::WellFormed(self.parse_ty()),
552 let def_id = self.parse_def();
553 assert_eq!(self.next(), '|');
554 ty::Predicate::ObjectSafe(def_id)
556 c => bug!("Encountered invalid character
in metadata
: {}
", c)
560 fn parse_projection_predicate(&mut self) -> ty::ProjectionPredicate<'tcx> {
561 ty::ProjectionPredicate {
562 projection_ty: ty::ProjectionTy {
563 trait_ref: self.parse_trait_ref(),
564 item_name: token::intern(&self.parse_str('|')),
570 pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
571 let name = self.parse_name(':');
572 let def_id = self.parse_def();
573 let space = self.parse_param_space();
574 assert_eq!(self.next(), '|');
575 let index = self.parse_u32();
576 assert_eq!(self.next(), '|');
577 let default_def_id = self.parse_def();
578 let default = self.parse_opt(|this| this.parse_ty());
579 let object_lifetime_default = self.parse_object_lifetime_default();
581 ty::TypeParameterDef {
586 default_def_id: default_def_id,
588 object_lifetime_default: object_lifetime_default,
592 pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
593 let name = self.parse_name(':');
594 let def_id = self.parse_def();
595 let space = self.parse_param_space();
596 assert_eq!(self.next(), '|');
597 let index = self.parse_u32();
598 assert_eq!(self.next(), '|');
599 let mut bounds = vec![];
602 'R' => bounds.push(self.parse_region()),
605 bug!("parse_region_param_def
: bad
bounds ('{}'
)", c)
609 ty::RegionParameterDef {
619 fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault {
621 'a' => ty::ObjectLifetimeDefault::Ambiguous,
622 'b' => ty::ObjectLifetimeDefault::BaseDefault,
624 let region = self.parse_region();
625 ty::ObjectLifetimeDefault::Specific(region)
627 _ => bug!("parse_object_lifetime_default
: bad input
")
631 pub fn parse_existential_bounds(&mut self) -> ty::ExistentialBounds<'tcx> {
632 let builtin_bounds = self.parse_builtin_bounds();
633 let region_bound = self.parse_region();
634 let mut projection_bounds = Vec::new();
639 projection_bounds.push(ty::Binder(self.parse_projection_predicate()));
643 bug!("parse_bounds
: bad
bounds ('{}'
)", c)
648 ty::ExistentialBounds::new(
649 region_bound, builtin_bounds, projection_bounds)
652 fn parse_builtin_bounds(&mut self) -> ty::BuiltinBounds {
653 let mut builtin_bounds = ty::BuiltinBounds::empty();
657 builtin_bounds.insert(ty::BoundSend);
660 builtin_bounds.insert(ty::BoundSized);
663 builtin_bounds.insert(ty::BoundCopy);
666 builtin_bounds.insert(ty::BoundSync);
669 return builtin_bounds;
672 bug!("parse_bounds
: bad builtin
bounds ('{}'
)", c)
679 // Rust metadata parsing
680 fn parse_defid(buf: &[u8]) -> DefId {
681 let mut colon_idx = 0;
683 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; }
684 if colon_idx == len {
685 error!("didn't find '
:' when parsing def id
");
689 let crate_part = &buf[0..colon_idx];
690 let def_part = &buf[colon_idx + 1..len];
692 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
693 s.parse::<usize>().ok()
695 Some(cn) => cn as ast::CrateNum,
696 None => bug!("internal error
: parse_defid
: crate number expected
, found {:?}
",
699 let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
700 s.parse::<usize>().ok()
703 None => bug!("internal error
: parse_defid
: id expected
, found {:?}
",
706 let index = DefIndex::new(def_num);
707 DefId { krate: crate_num, index: index }
710 fn parse_unsafety(c: char) -> hir::Unsafety {
712 'u' => hir::Unsafety::Unsafe,
713 'n' => hir::Unsafety::Normal,
714 _ => bug!("parse_unsafety
: bad unsafety {}
", c)