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
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
45 conv_def_id
: DefIdConvert
<'a
>,
48 impl<'a
,'tcx
> TyDecoder
<'a
,'tcx
> {
49 pub fn with_doc(tcx
: TyCtxt
<'a
, 'tcx
, '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
: TyCtxt
<'a
, 'tcx
, '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 let issue32330
= match self.next() {
164 assert_eq
!(self.next(), '
]'
);
165 ty
::Issue32330
::WontChange
168 ty
::Issue32330
::WillChange
{
169 fn_def_id
: self.parse_def(),
170 region_name
: token
::intern(&self.parse_str('
]'
)),
173 c
=> panic
!("expected n or y not {}", c
)
175 ty
::BrNamed(def
, name
, issue32330
)
178 let id
= self.parse_u32();
179 assert_eq
!(self.next(), '
|'
);
183 _
=> bug
!("parse_bound_region: bad input")
187 pub fn parse_region(&mut self) -> ty
::Region
{
190 assert_eq
!(self.next(), '
['
);
191 let id
= ty
::DebruijnIndex
::new(self.parse_u32());
192 assert_eq
!(self.next(), '
|'
);
193 let br
= self.parse_bound_region();
194 assert_eq
!(self.next(), '
]'
);
195 ty
::ReLateBound(id
, br
)
198 assert_eq
!(self.next(), '
['
);
199 let space
= self.parse_param_space();
200 assert_eq
!(self.next(), '
|'
);
201 let index
= self.parse_u32();
202 assert_eq
!(self.next(), '
|'
);
203 let name
= token
::intern(&self.parse_str('
]'
));
204 ty
::ReEarlyBound(ty
::EarlyBoundRegion
{
211 assert_eq
!(self.next(), '
['
);
212 let scope
= self.parse_scope();
213 assert_eq
!(self.next(), '
|'
);
214 let br
= self.parse_bound_region();
215 assert_eq
!(self.next(), '
]'
);
216 ty
::ReFree(ty
::FreeRegion
{ scope
: scope
,
220 let scope
= self.parse_scope();
221 assert_eq
!(self.next(), '
|'
);
227 _
=> bug
!("parse_region: bad input")
231 fn parse_scope(&mut self) -> region
::CodeExtent
{
232 self.tcx
.region_maps
.bogus_code_extent(match self.next() {
233 // This creates scopes with the wrong NodeId. This isn't
234 // actually a problem because scopes only exist *within*
235 // functions, and functions aren't loaded until trans which
236 // doesn't care about regions.
238 // May still be worth fixing though.
240 assert_eq
!(self.next(), '
['
);
241 let fn_id
= self.parse_uint() as ast
::NodeId
;
242 assert_eq
!(self.next(), '
|'
);
243 let body_id
= self.parse_uint() as ast
::NodeId
;
244 assert_eq
!(self.next(), '
]'
);
245 region
::CodeExtentData
::CallSiteScope
{
246 fn_id
: fn_id
, body_id
: body_id
249 // This creates scopes with the wrong NodeId. (See note above.)
251 assert_eq
!(self.next(), '
['
);
252 let fn_id
= self.parse_uint() as ast
::NodeId
;
253 assert_eq
!(self.next(), '
|'
);
254 let body_id
= self.parse_uint() as ast
::NodeId
;
255 assert_eq
!(self.next(), '
]'
);
256 region
::CodeExtentData
::ParameterScope
{
257 fn_id
: fn_id
, body_id
: body_id
261 let node_id
= self.parse_uint() as ast
::NodeId
;
262 region
::CodeExtentData
::Misc(node_id
)
265 let node_id
= self.parse_uint() as ast
::NodeId
;
266 region
::CodeExtentData
::DestructionScope(node_id
)
269 assert_eq
!(self.next(), '
['
);
270 let node_id
= self.parse_uint() as ast
::NodeId
;
271 assert_eq
!(self.next(), '
|'
);
272 let first_stmt_index
= self.parse_u32();
273 assert_eq
!(self.next(), '
]'
);
274 let block_remainder
= region
::BlockRemainder
{
275 block
: node_id
, first_statement_index
: first_stmt_index
,
277 region
::CodeExtentData
::Remainder(block_remainder
)
279 _
=> bug
!("parse_scope: bad input")
283 fn parse_opt
<T
, F
>(&mut self, f
: F
) -> Option
<T
>
284 where F
: FnOnce(&mut TyDecoder
<'a
, 'tcx
>) -> T
,
288 's'
=> Some(f(self)),
289 _
=> bug
!("parse_opt: bad input")
293 fn parse_str(&mut self, term
: char) -> String
{
294 let mut result
= String
::new();
295 while self.peek() != term
{
297 result
.as_mut_vec().extend_from_slice(&[self.next_byte()])
304 pub fn parse_trait_ref(&mut self) -> ty
::TraitRef
<'tcx
> {
305 let def
= self.parse_def();
306 let substs
= self.tcx
.mk_substs(self.parse_substs());
307 ty
::TraitRef {def_id: def, substs: substs}
310 pub fn parse_ty(&mut self) -> Ty
<'tcx
> {
313 'b'
=> return tcx
.types
.bool
,
314 '
!'
=> return tcx
.types
.never
,
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 _
=> bug
!("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 let substs
= self.tcx
.mk_substs(self.parse_substs());
384 return tcx
.mk_fn_def(def_id
, substs
, self.parse_bare_fn_ty());
387 return tcx
.mk_fn_ptr(self.parse_bare_fn_ty());
390 // This is a hacky little caching scheme. The idea is that if we encode
391 // the same type twice, the second (and third, and fourth...) time we will
392 // just write `#123`, where `123` is the offset in the metadata of the
393 // first appearance. Now when we are *decoding*, if we see a `#123`, we
394 // can first check a cache (`tcx.rcache`) for that offset. If we find something,
395 // we return it (modulo closure types, see below). But if not, then we
396 // jump to offset 123 and read the type from there.
398 let pos
= self.parse_vuint();
399 let key
= ty
::CReaderCacheKey { cnum: self.krate, pos: pos }
;
400 if let Some(tt
) = 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() {
409 let mut substate
= TyDecoder
::new(self.data
,
414 let tt
= substate
.parse_ty();
415 tcx
.rcache
.borrow_mut().insert(key
, tt
);
419 let _
= self.parse_def();
420 let inner
= self.parse_ty();
424 assert_eq
!(self.next(), '
['
);
425 let did
= self.parse_def();
426 let substs
= self.parse_substs();
427 assert_eq
!(self.next(), '
]'
);
428 let def
= self.tcx
.lookup_adt_def(did
);
429 return self.tcx
.mk_struct(def
, self.tcx
.mk_substs(substs
));
432 assert_eq
!(self.next(), '
['
);
433 let did
= self.parse_def();
434 let substs
= self.parse_substs();
435 let mut tys
= vec
![];
436 while self.peek() != '
.'
{
437 tys
.push(self.parse_ty());
439 assert_eq
!(self.next(), '
.'
);
440 assert_eq
!(self.next(), '
]'
);
441 return self.tcx
.mk_closure(did
, self.tcx
.mk_substs(substs
), tys
);
444 assert_eq
!(self.next(), '
['
);
445 let trait_ref
= self.parse_trait_ref();
446 let name
= token
::intern(&self.parse_str('
]'
));
447 return tcx
.mk_projection(trait_ref
, name
);
450 assert_eq
!(self.next(), '
['
);
451 let def_id
= self.parse_def();
452 let substs
= self.parse_substs();
453 assert_eq
!(self.next(), '
]'
);
454 return self.tcx
.mk_anon(def_id
, self.tcx
.mk_substs(substs
));
457 return tcx
.types
.err
;
459 c
=> { bug!("unexpected char in type string: {}
", c);}
463 fn parse_mutability(&mut self) -> hir::Mutability {
465 'm' => { self.next(); hir::MutMutable }
466 _ => { hir::MutImmutable }
470 fn parse_mt(&mut self) -> ty::TypeAndMut<'tcx> {
471 let m = self.parse_mutability();
472 ty::TypeAndMut { ty: self.parse_ty(), mutbl: m }
475 fn parse_def(&mut self) -> DefId {
476 let def_id = parse_defid(self.scan(|c| c == '|'));
477 return (self.conv_def_id)(def_id);
480 fn parse_uint(&mut self) -> usize {
483 let cur = self.peek();
484 if cur < '0' || cur > '9' { return n; }
485 self.pos = self.pos + 1;
487 n += (cur as usize) - ('0' as usize);
491 fn parse_u32(&mut self) -> u32 {
492 let n = self.parse_uint();
494 assert_eq!(m as usize, n);
498 fn parse_param_space(&mut self) -> subst::ParamSpace {
499 subst::ParamSpace::from_uint(self.parse_uint())
502 fn parse_abi_set(&mut self) -> abi::Abi {
503 assert_eq!(self.next(), '[');
504 let bytes = self.scan(|c| c == ']');
505 let abi_str = str::from_utf8(bytes).unwrap();
506 abi::lookup(&abi_str[..]).expect(abi_str)
509 pub fn parse_closure_ty(&mut self) -> ty::ClosureTy<'tcx> {
510 let unsafety = parse_unsafety(self.next());
511 let sig = self.parse_sig();
512 let abi = self.parse_abi_set();
520 pub fn parse_bare_fn_ty(&mut self) -> &'tcx ty::BareFnTy<'tcx> {
521 let unsafety = parse_unsafety(self.next());
522 let abi = self.parse_abi_set();
523 let sig = self.parse_sig();
524 self.tcx.mk_bare_fn(ty::BareFnTy {
531 fn parse_sig(&mut self) -> ty::PolyFnSig<'tcx> {
532 assert_eq!(self.next(), '[');
533 let mut inputs = Vec::new();
534 while self.peek() != ']' {
535 inputs.push(self.parse_ty());
537 self.pos += 1; // eat the ']'
538 let variadic = match self.next() {
541 r => bug!("bad variadic
: {}
", r),
543 let output = self.parse_ty();
544 ty::Binder(ty::FnSig {inputs: inputs,
549 pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> {
551 't' => ty::Binder(self.parse_trait_ref()).to_predicate(),
552 'e' => ty::Binder(ty::EquatePredicate(self.parse_ty(),
553 self.parse_ty())).to_predicate(),
554 'r' => ty::Binder(ty::OutlivesPredicate(self.parse_region(),
555 self.parse_region())).to_predicate(),
556 'o' => ty::Binder(ty::OutlivesPredicate(self.parse_ty(),
557 self.parse_region())).to_predicate(),
558 'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(),
559 'w' => ty::Predicate::WellFormed(self.parse_ty()),
561 let def_id = self.parse_def();
562 assert_eq!(self.next(), '|');
563 ty::Predicate::ObjectSafe(def_id)
566 let def_id = self.parse_def();
567 assert_eq!(self.next(), '|');
568 let kind = match self.next() {
569 'f' => ty::ClosureKind::Fn,
570 'm' => ty::ClosureKind::FnMut,
571 'o' => ty::ClosureKind::FnOnce,
572 c => bug!("Encountered invalid character
in metadata
: {}
", c)
574 assert_eq!(self.next(), '|');
575 ty::Predicate::ClosureKind(def_id, kind)
577 c => bug!("Encountered invalid character
in metadata
: {}
", c)
581 fn parse_projection_predicate(&mut self) -> ty::ProjectionPredicate<'tcx> {
582 ty::ProjectionPredicate {
583 projection_ty: ty::ProjectionTy {
584 trait_ref: self.parse_trait_ref(),
585 item_name: token::intern(&self.parse_str('|')),
591 pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
592 let name = self.parse_name(':');
593 let def_id = self.parse_def();
594 let space = self.parse_param_space();
595 assert_eq!(self.next(), '|');
596 let index = self.parse_u32();
597 assert_eq!(self.next(), '|');
598 let default_def_id = self.parse_def();
599 let default = self.parse_opt(|this| this.parse_ty());
600 let object_lifetime_default = self.parse_object_lifetime_default();
602 ty::TypeParameterDef {
607 default_def_id: default_def_id,
609 object_lifetime_default: object_lifetime_default,
613 pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
614 let name = self.parse_name(':');
615 let def_id = self.parse_def();
616 let space = self.parse_param_space();
617 assert_eq!(self.next(), '|');
618 let index = self.parse_u32();
619 assert_eq!(self.next(), '|');
620 let mut bounds = vec![];
623 'R' => bounds.push(self.parse_region()),
626 bug!("parse_region_param_def
: bad
bounds ('{}'
)", c)
630 ty::RegionParameterDef {
640 fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault {
642 'a' => ty::ObjectLifetimeDefault::Ambiguous,
643 'b' => ty::ObjectLifetimeDefault::BaseDefault,
645 let region = self.parse_region();
646 ty::ObjectLifetimeDefault::Specific(region)
648 _ => bug!("parse_object_lifetime_default
: bad input
")
652 pub fn parse_existential_bounds(&mut self) -> ty::ExistentialBounds<'tcx> {
653 let builtin_bounds = self.parse_builtin_bounds();
654 let region_bound = self.parse_region();
655 let mut projection_bounds = Vec::new();
660 projection_bounds.push(ty::Binder(self.parse_projection_predicate()));
664 bug!("parse_bounds
: bad
bounds ('{}'
)", c)
669 ty::ExistentialBounds::new(
670 region_bound, builtin_bounds, projection_bounds)
673 fn parse_builtin_bounds(&mut self) -> ty::BuiltinBounds {
674 let mut builtin_bounds = ty::BuiltinBounds::empty();
678 builtin_bounds.insert(ty::BoundSend);
681 builtin_bounds.insert(ty::BoundSized);
684 builtin_bounds.insert(ty::BoundCopy);
687 builtin_bounds.insert(ty::BoundSync);
690 return builtin_bounds;
693 bug!("parse_bounds
: bad builtin
bounds ('{}'
)", c)
700 // Rust metadata parsing
701 fn parse_defid(buf: &[u8]) -> DefId {
702 let mut colon_idx = 0;
704 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; }
705 if colon_idx == len {
706 error!("didn't find '
:' when parsing def id
");
710 let crate_part = &buf[0..colon_idx];
711 let def_part = &buf[colon_idx + 1..len];
713 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
714 s.parse::<usize>().ok()
716 Some(cn) => cn as ast::CrateNum,
717 None => bug!("internal error
: parse_defid
: crate number expected
, found {:?}
",
720 let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
721 s.parse::<usize>().ok()
724 None => bug!("internal error
: parse_defid
: id expected
, found {:?}
",
727 let index = DefIndex::new(def_num);
728 DefId { krate: crate_num, index: index }
731 fn parse_unsafety(c: char) -> hir::Unsafety {
733 'u' => hir::Unsafety::Unsafe,
734 'n' => hir::Unsafety::Normal,
735 _ => bug!("parse_unsafety
: bad unsafety {}
", c)