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)]
19 pub use self::DefIdSource
::*;
23 use middle
::subst
::VecPerParamSpace
;
24 use middle
::ty
::{self, AsPredicate, Ty}
;
29 use syntax
::parse
::token
;
31 // Compact string representation for Ty values. API ty_str &
32 // parse_from_str. Extra parameters are for converting to/from def_ids in the
33 // data buffer. Whatever format you choose should not contain pipe characters.
35 // Def id conversion: when we encounter def-ids, they have to be translated.
36 // For example, the crate number must be converted from the crate number used
37 // in the library we are reading from into the local crate numbers in use
38 // here. To perform this translation, the type decoder is supplied with a
39 // conversion function of type `conv_did`.
41 // Sometimes, particularly when inlining, the correct translation of the
42 // def-id will depend on where it originated from. Therefore, the conversion
43 // function is given an indicator of the source of the def-id. See
44 // astencode.rs for more information.
45 #[derive(Copy, Clone, Debug)]
46 pub enum DefIdSource
{
47 // Identifies a struct, trait, enum, etc.
50 // Identifies a type alias (`type X = ...`).
53 // Identifies a type parameter (`fn foo<X>() { ... }`).
56 // Identifies a region parameter (`fn foo<'X>() { ... }`).
59 // Identifies a closure
63 // type conv_did = impl FnMut(DefIdSource, ast::DefId) -> ast::DefId;
65 pub struct PState
<'a
, 'tcx
: 'a
> {
69 tcx
: &'a ty
::ctxt
<'tcx
>
72 fn peek(st
: &PState
) -> char {
73 st
.data
[st
.pos
] as char
76 fn next(st
: &mut PState
) -> char {
77 let ch
= st
.data
[st
.pos
] as char;
82 fn next_byte(st
: &mut PState
) -> u8 {
83 let b
= st
.data
[st
.pos
];
88 fn scan
<R
, F
, G
>(st
: &mut PState
, mut is_last
: F
, op
: G
) -> R
where
89 F
: FnMut(char) -> bool
,
90 G
: FnOnce(&[u8]) -> R
,
92 let start_pos
= st
.pos
;
93 debug
!("scan: '{}' (start)", st
.data
[st
.pos
] as char);
94 while !is_last(st
.data
[st
.pos
] as char) {
96 debug
!("scan: '{}'", st
.data
[st
.pos
] as char);
100 return op(&st
.data
[start_pos
..end_pos
]);
103 pub fn parse_name(st
: &mut PState
, last
: char) -> ast
::Name
{
104 fn is_last(b
: char, c
: char) -> bool { return c == b; }
105 parse_name_(st
, |a
| is_last(last
, a
) )
108 fn parse_name_
<F
>(st
: &mut PState
, is_last
: F
) -> ast
::Name
where
109 F
: FnMut(char) -> bool
,
111 scan(st
, is_last
, |bytes
| {
112 token
::intern(str::from_utf8(bytes
).unwrap())
116 pub fn parse_state_from_data
<'a
, 'tcx
>(data
: &'a
[u8], crate_num
: ast
::CrateNum
,
117 pos
: usize, tcx
: &'a ty
::ctxt
<'tcx
>)
118 -> PState
<'a
, 'tcx
> {
127 fn data_log_string(data
: &[u8], pos
: usize) -> String
{
128 let mut buf
= String
::new();
130 for i
in pos
..data
.len() {
132 if c
> 0x20 && c
<= 0x7F {
142 pub fn parse_ty_closure_data
<'tcx
, F
>(data
: &[u8],
143 crate_num
: ast
::CrateNum
,
145 tcx
: &ty
::ctxt
<'tcx
>,
147 -> ty
::ClosureTy
<'tcx
> where
148 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
150 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
151 parse_closure_ty(&mut st
, conv
)
154 pub fn parse_ty_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: usize,
155 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
) -> Ty
<'tcx
> where
156 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
158 debug
!("parse_ty_data {}", data_log_string(data
, pos
));
159 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
160 parse_ty(&mut st
, conv
)
163 pub fn parse_region_data
<F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: usize, tcx
: &ty
::ctxt
,
164 conv
: F
) -> ty
::Region
where
165 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
167 debug
!("parse_region_data {}", data_log_string(data
, pos
));
168 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
169 parse_region(&mut st
, conv
)
172 pub fn parse_bare_fn_ty_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: usize,
173 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
)
174 -> ty
::BareFnTy
<'tcx
> where
175 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
177 debug
!("parse_bare_fn_ty_data {}", data_log_string(data
, pos
));
178 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
179 parse_bare_fn_ty(&mut st
, conv
)
182 pub fn parse_trait_ref_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: usize,
183 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
)
184 -> ty
::TraitRef
<'tcx
> where
185 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
187 debug
!("parse_trait_ref_data {}", data_log_string(data
, pos
));
188 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
189 parse_trait_ref(&mut st
, conv
)
192 pub fn parse_substs_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: usize,
193 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
) -> subst
::Substs
<'tcx
> where
194 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
196 debug
!("parse_substs_data {}", data_log_string(data
, pos
));
197 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
198 parse_substs(&mut st
, conv
)
201 pub fn parse_bounds_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
,
202 pos
: usize, tcx
: &ty
::ctxt
<'tcx
>, conv
: F
)
203 -> ty
::ParamBounds
<'tcx
> where
204 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
206 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
207 parse_bounds(&mut st
, conv
)
210 pub fn parse_existential_bounds_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
,
211 pos
: usize, tcx
: &ty
::ctxt
<'tcx
>, conv
: F
)
212 -> ty
::ExistentialBounds
<'tcx
> where
213 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
215 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
216 parse_existential_bounds(&mut st
, conv
)
219 pub fn parse_builtin_bounds_data
<F
>(data
: &[u8], crate_num
: ast
::CrateNum
,
220 pos
: usize, tcx
: &ty
::ctxt
, conv
: F
)
221 -> ty
::BuiltinBounds
where
222 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
224 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
225 parse_builtin_bounds(&mut st
, conv
)
228 fn parse_size(st
: &mut PState
) -> Option
<usize> {
229 assert_eq
!(next(st
), '
/'
);
232 assert_eq
!(next(st
), '
|'
);
235 let n
= parse_uint(st
);
236 assert_eq
!(next(st
), '
|'
);
241 fn parse_vec_per_param_space
<'a
, 'tcx
, T
, F
>(st
: &mut PState
<'a
, 'tcx
>,
243 -> VecPerParamSpace
<T
> where
244 F
: FnMut(&mut PState
<'a
, 'tcx
>) -> T
,
246 let mut r
= VecPerParamSpace
::empty();
247 for &space
in &subst
::ParamSpace
::all() {
248 assert_eq
!(next(st
), '
['
);
249 while peek(st
) != '
]'
{
250 r
.push(space
, f(st
));
252 assert_eq
!(next(st
), '
]'
);
257 fn parse_substs
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>,
258 mut conv
: F
) -> subst
::Substs
<'tcx
> where
259 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
261 parse_substs_(st
, &mut conv
)
264 fn parse_substs_
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>,
265 conv
: &mut F
) -> subst
::Substs
<'tcx
> where
266 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
269 parse_region_substs_(st
, conv
);
272 parse_vec_per_param_space(st
, |st
| parse_ty_(st
, conv
));
274 subst
::Substs
{ types
: types
,
278 fn parse_region_substs_
<F
>(st
: &mut PState
, conv
: &mut F
) -> subst
::RegionSubsts
where
279 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
282 'e'
=> subst
::ErasedRegions
,
284 subst
::NonerasedRegions(
285 parse_vec_per_param_space(
286 st
, |st
| parse_region_(st
, conv
)))
288 _
=> panic
!("parse_bound_region: bad input")
292 fn parse_bound_region_
<F
>(st
: &mut PState
, conv
: &mut F
) -> ty
::BoundRegion
where
293 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
297 let id
= parse_u32(st
);
298 assert_eq
!(next(st
), '
|'
);
302 let def
= parse_def_(st
, RegionParameter
, conv
);
303 let ident
= token
::str_to_ident(&parse_str(st
, '
]'
));
304 ty
::BrNamed(def
, ident
.name
)
307 let id
= parse_u32(st
);
308 assert_eq
!(next(st
), '
|'
);
312 _
=> panic
!("parse_bound_region: bad input")
316 fn parse_region
<F
>(st
: &mut PState
, mut conv
: F
) -> ty
::Region
where
317 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
319 parse_region_(st
, &mut conv
)
322 fn parse_region_
<F
>(st
: &mut PState
, conv
: &mut F
) -> ty
::Region
where
323 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
327 assert_eq
!(next(st
), '
['
);
328 let id
= ty
::DebruijnIndex
::new(parse_u32(st
));
329 assert_eq
!(next(st
), '
|'
);
330 let br
= parse_bound_region_(st
, conv
);
331 assert_eq
!(next(st
), '
]'
);
332 ty
::ReLateBound(id
, br
)
335 assert_eq
!(next(st
), '
['
);
336 let node_id
= parse_uint(st
) as ast
::NodeId
;
337 assert_eq
!(next(st
), '
|'
);
338 let space
= parse_param_space(st
);
339 assert_eq
!(next(st
), '
|'
);
340 let index
= parse_u32(st
);
341 assert_eq
!(next(st
), '
|'
);
342 let nm
= token
::str_to_ident(&parse_str(st
, '
]'
));
343 ty
::ReEarlyBound(ty
::EarlyBoundRegion
{
351 assert_eq
!(next(st
), '
['
);
352 let scope
= parse_destruction_scope_data(st
);
353 assert_eq
!(next(st
), '
|'
);
354 let br
= parse_bound_region_(st
, conv
);
355 assert_eq
!(next(st
), '
]'
);
356 ty
::ReFree(ty
::FreeRegion
{ scope
: scope
,
360 let scope
= parse_scope(st
);
361 assert_eq
!(next(st
), '
|'
);
370 _
=> panic
!("parse_region: bad input")
374 fn parse_scope(st
: &mut PState
) -> region
::CodeExtent
{
377 assert_eq
!(next(st
), '
['
);
378 let fn_id
= parse_uint(st
) as ast
::NodeId
;
379 assert_eq
!(next(st
), '
|'
);
380 let body_id
= parse_uint(st
) as ast
::NodeId
;
381 assert_eq
!(next(st
), '
]'
);
382 region
::CodeExtent
::ParameterScope
{
383 fn_id
: fn_id
, body_id
: body_id
387 let node_id
= parse_uint(st
) as ast
::NodeId
;
388 region
::CodeExtent
::Misc(node_id
)
391 let node_id
= parse_uint(st
) as ast
::NodeId
;
392 region
::CodeExtent
::DestructionScope(node_id
)
395 assert_eq
!(next(st
), '
['
);
396 let node_id
= parse_uint(st
) as ast
::NodeId
;
397 assert_eq
!(next(st
), '
|'
);
398 let first_stmt_index
= parse_uint(st
);
399 assert_eq
!(next(st
), '
]'
);
400 let block_remainder
= region
::BlockRemainder
{
401 block
: node_id
, first_statement_index
: first_stmt_index
,
403 region
::CodeExtent
::Remainder(block_remainder
)
405 _
=> panic
!("parse_scope: bad input")
409 fn parse_destruction_scope_data(st
: &mut PState
) -> region
::DestructionScopeData
{
410 let node_id
= parse_uint(st
) as ast
::NodeId
;
411 region
::DestructionScopeData
::new(node_id
)
414 fn parse_opt
<'a
, 'tcx
, T
, F
>(st
: &mut PState
<'a
, 'tcx
>, f
: F
) -> Option
<T
> where
415 F
: FnOnce(&mut PState
<'a
, 'tcx
>) -> T
,
420 _
=> panic
!("parse_opt: bad input")
424 fn parse_str(st
: &mut PState
, term
: char) -> String
{
425 let mut result
= String
::new();
426 while peek(st
) != term
{
428 result
.as_mut_vec().push_all(&[next_byte(st
)])
435 fn parse_trait_ref
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, mut conv
: F
)
436 -> ty
::TraitRef
<'tcx
> where
437 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
439 parse_trait_ref_(st
, &mut conv
)
442 fn parse_trait_ref_
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, conv
: &mut F
)
443 -> ty
::TraitRef
<'tcx
> where
444 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
446 let def
= parse_def_(st
, NominalType
, conv
);
447 let substs
= st
.tcx
.mk_substs(parse_substs_(st
, conv
));
448 ty
::TraitRef {def_id: def, substs: substs}
451 fn parse_ty
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, mut conv
: F
) -> Ty
<'tcx
> where
452 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
454 parse_ty_(st
, &mut conv
)
457 fn parse_ty_
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, conv
: &mut F
) -> Ty
<'tcx
> where
458 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
462 'b'
=> return tcx
.types
.bool
,
463 'i'
=> { /* eat the s of is */ next(st); return tcx.types.isize }
,
464 'u'
=> { /* eat the s of us */ next(st); return tcx.types.usize }
,
467 'b'
=> return tcx
.types
.u8,
468 'w'
=> return tcx
.types
.u16,
469 'l'
=> return tcx
.types
.u32,
470 'd'
=> return tcx
.types
.u64,
471 'B'
=> return tcx
.types
.i8,
472 'W'
=> return tcx
.types
.i16,
473 'L'
=> return tcx
.types
.i32,
474 'D'
=> return tcx
.types
.i64,
475 'f'
=> return tcx
.types
.f32,
476 'F'
=> return tcx
.types
.f64,
477 _
=> panic
!("parse_ty: bad numeric type")
480 'c'
=> return tcx
.types
.char,
482 assert_eq
!(next(st
), '
['
);
483 let def
= parse_def_(st
, NominalType
, conv
);
484 let substs
= parse_substs_(st
, conv
);
485 assert_eq
!(next(st
), '
]'
);
486 return ty
::mk_enum(tcx
, def
, st
.tcx
.mk_substs(substs
));
489 assert_eq
!(next(st
), '
['
);
490 let trait_ref
= ty
::Binder(parse_trait_ref_(st
, conv
));
491 let bounds
= parse_existential_bounds_(st
, conv
);
492 assert_eq
!(next(st
), '
]'
);
493 return ty
::mk_trait(tcx
, trait_ref
, bounds
);
496 assert_eq
!(next(st
), '
['
);
497 let index
= parse_u32(st
);
498 assert_eq
!(next(st
), '
|'
);
499 let space
= parse_param_space(st
);
500 assert_eq
!(next(st
), '
|'
);
501 let name
= token
::intern(&parse_str(st
, '
]'
));
502 return ty
::mk_param(tcx
, space
, index
, name
);
504 '
~'
=> return ty
::mk_uniq(tcx
, parse_ty_(st
, conv
)),
505 '
*'
=> return ty
::mk_ptr(tcx
, parse_mt_(st
, conv
)),
507 let r
= parse_region_(st
, conv
);
508 let mt
= parse_mt_(st
, conv
);
509 return ty
::mk_rptr(tcx
, tcx
.mk_region(r
), mt
);
512 let t
= parse_ty_(st
, conv
);
513 let sz
= parse_size(st
);
514 return ty
::mk_vec(tcx
, t
, sz
);
517 return ty
::mk_str(tcx
);
520 assert_eq
!(next(st
), '
['
);
521 let mut params
= Vec
::new();
522 while peek(st
) != '
]' { params.push(parse_ty_(st, conv)); }
524 return ty
::mk_tup(tcx
, params
);
527 let def_id
= parse_def_(st
, NominalType
, conv
);
528 return ty
::mk_bare_fn(tcx
, Some(def_id
),
529 tcx
.mk_bare_fn(parse_bare_fn_ty_(st
, conv
)));
532 return ty
::mk_bare_fn(tcx
, None
,
533 tcx
.mk_bare_fn(parse_bare_fn_ty_(st
, conv
)));
536 let pos
= parse_hex(st
);
537 assert_eq
!(next(st
), '
:'
);
538 let len
= parse_hex(st
);
539 assert_eq
!(next(st
), '
#');
540 let key
= ty
::creader_cache_key
{cnum
: st
.krate
,
544 match tcx
.rcache
.borrow().get(&key
).cloned() {
545 Some(tt
) => return tt
,
548 let mut ps
= PState
{
552 let tt
= parse_ty_(&mut ps
, conv
);
553 tcx
.rcache
.borrow_mut().insert(key
, tt
);
557 let _
= parse_def_(st
, TypeWithId
, conv
);
558 let inner
= parse_ty_(st
, conv
);
562 assert_eq
!(next(st
), '
['
);
563 let did
= parse_def_(st
, NominalType
, conv
);
564 let substs
= parse_substs_(st
, conv
);
565 assert_eq
!(next(st
), '
]'
);
566 return ty
::mk_struct(st
.tcx
, did
, st
.tcx
.mk_substs(substs
));
569 assert_eq
!(next(st
), '
['
);
570 let did
= parse_def_(st
, ClosureSource
, conv
);
571 let substs
= parse_substs_(st
, conv
);
572 assert_eq
!(next(st
), '
]'
);
573 return ty
::mk_closure(st
.tcx
, did
, st
.tcx
.mk_substs(substs
));
576 assert_eq
!(next(st
), '
['
);
577 let trait_ref
= parse_trait_ref_(st
, conv
);
578 let name
= token
::intern(&parse_str(st
, '
]'
));
579 return ty
::mk_projection(tcx
, trait_ref
, name
);
582 return tcx
.types
.err
;
584 c
=> { panic!("unexpected char in type string: {}
", c);}
588 fn parse_mutability(st: &mut PState) -> ast::Mutability {
590 'm' => { next(st); ast::MutMutable }
591 _ => { ast::MutImmutable }
595 fn parse_mt_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::mt<'tcx> where
596 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
598 let m = parse_mutability(st);
599 ty::mt { ty: parse_ty_(st, conv), mutbl: m }
602 fn parse_def_<F>(st: &mut PState, source: DefIdSource, conv: &mut F) -> ast::DefId where
603 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
605 return (*conv)(source, scan(st, |c| { c == '|' }, parse_def_id));
608 fn parse_uint(st: &mut PState) -> usize {
612 if cur < '0' || cur > '9' { return n; }
615 n += (cur as usize) - ('0' as usize);
619 fn parse_u32(st: &mut PState) -> u32 {
620 let n = parse_uint(st);
622 assert_eq!(m as usize, n);
626 fn parse_param_space(st: &mut PState) -> subst::ParamSpace {
627 subst::ParamSpace::from_uint(parse_uint(st))
630 fn parse_hex(st: &mut PState) -> usize {
634 if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; }
637 if '0' <= cur && cur <= '9' {
638 n += (cur as usize) - ('0' as usize);
639 } else { n += 10 + (cur as usize) - ('a' as usize); }
643 fn parse_unsafety(c: char) -> ast::Unsafety {
645 'u' => ast::Unsafety::Unsafe,
646 'n' => ast::Unsafety::Normal,
647 _ => panic!("parse_unsafety
: bad unsafety {}
", c)
651 fn parse_abi_set(st: &mut PState) -> abi::Abi {
652 assert_eq!(next(st), '[');
653 scan(st, |c| c == ']', |bytes| {
654 let abi_str = str::from_utf8(bytes).unwrap();
655 abi::lookup(&abi_str[..]).expect(abi_str)
659 fn parse_closure_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
660 mut conv: F) -> ty::ClosureTy<'tcx> where
661 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
663 parse_closure_ty_(st, &mut conv)
666 fn parse_closure_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
667 conv: &mut F) -> ty::ClosureTy<'tcx> where
668 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
670 let unsafety = parse_unsafety(next(st));
671 let sig = parse_sig_(st, conv);
672 let abi = parse_abi_set(st);
680 fn parse_bare_fn_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
681 mut conv: F) -> ty::BareFnTy<'tcx> where
682 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
684 parse_bare_fn_ty_(st, &mut conv)
687 fn parse_bare_fn_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
688 conv: &mut F) -> ty::BareFnTy<'tcx> where
689 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
691 let unsafety = parse_unsafety(next(st));
692 let abi = parse_abi_set(st);
693 let sig = parse_sig_(st, conv);
701 fn parse_sig_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::PolyFnSig<'tcx> where
702 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
704 assert_eq!(next(st), '[');
705 let mut inputs = Vec::new();
706 while peek(st) != ']' {
707 inputs.push(parse_ty_(st, conv));
709 st.pos += 1; // eat the ']'
710 let variadic = match next(st) {
713 r => panic!(format!("bad variadic
: {}
", r)),
715 let output = match peek(st) {
720 _ => ty::FnConverging(parse_ty_(st, conv))
722 ty::Binder(ty::FnSig {inputs: inputs,
727 // Rust metadata parsing
728 pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
729 let mut colon_idx = 0;
731 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; }
732 if colon_idx == len {
733 error!("didn't find '
:' when parsing def id
");
737 let crate_part = &buf[0..colon_idx];
738 let def_part = &buf[colon_idx + 1..len];
740 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
741 s.parse::<usize>().ok()
743 Some(cn) => cn as ast::CrateNum,
744 None => panic!("internal error
: parse_def_id
: crate number expected
, found {:?}
",
747 let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
748 s.parse::<usize>().ok()
750 Some(dn) => dn as ast::NodeId,
751 None => panic!("internal error
: parse_def_id
: id expected
, found {:?}
",
754 ast::DefId { krate: crate_num, node: def_num }
757 pub fn parse_predicate_data<'tcx, F>(data: &[u8],
759 crate_num: ast::CrateNum,
760 tcx: &ty::ctxt<'tcx>,
762 -> ty::Predicate<'tcx> where
763 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
765 let mut st = parse_state_from_data(data, crate_num, start, tcx);
766 parse_predicate(&mut st, conv)
769 pub fn parse_predicate<'a,'tcx, F>(st: &mut PState<'a, 'tcx>,
771 -> ty::Predicate<'tcx> where
772 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
774 parse_predicate_(st, &mut conv)
777 fn parse_predicate_<'a,'tcx, F>(st: &mut PState<'a, 'tcx>,
779 -> ty::Predicate<'tcx> where
780 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
783 't' => ty::Binder(parse_trait_ref_(st, conv)).as_predicate(),
784 'e' => ty::Binder(ty::EquatePredicate(parse_ty_(st, conv),
785 parse_ty_(st, conv))).as_predicate(),
786 'r' => ty::Binder(ty::OutlivesPredicate(parse_region_(st, conv),
787 parse_region_(st, conv))).as_predicate(),
788 'o' => ty::Binder(ty::OutlivesPredicate(parse_ty_(st, conv),
789 parse_region_(st, conv))).as_predicate(),
790 'p' => ty::Binder(parse_projection_predicate_(st, conv)).as_predicate(),
791 c => panic!("Encountered invalid character
in metadata
: {}
", c)
795 fn parse_projection_predicate_<'a,'tcx, F>(
796 st: &mut PState<'a, 'tcx>,
798 ) -> ty::ProjectionPredicate<'tcx> where
799 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
801 ty::ProjectionPredicate {
802 projection_ty: ty::ProjectionTy {
803 trait_ref: parse_trait_ref_(st, conv),
804 item_name: token::str_to_ident(&parse_str(st, '|')).name,
806 ty: parse_ty_(st, conv),
810 pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: usize,
811 crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>,
812 conv: F) -> ty::TypeParameterDef<'tcx> where
813 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
815 let mut st = parse_state_from_data(data, crate_num, start, tcx);
816 parse_type_param_def(&mut st, conv)
819 fn parse_type_param_def<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
820 -> ty::TypeParameterDef<'tcx> where
821 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
823 parse_type_param_def_(st, &mut conv)
826 fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
827 -> ty::TypeParameterDef<'tcx> where
828 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
830 let name = parse_name(st, ':');
831 let def_id = parse_def_(st, NominalType, conv);
832 let space = parse_param_space(st);
833 assert_eq!(next(st), '|');
834 let index = parse_u32(st);
835 assert_eq!(next(st), '|');
836 let default = parse_opt(st, |st| parse_ty_(st, conv));
837 let object_lifetime_default = parse_object_lifetime_default(st, conv);
839 ty::TypeParameterDef {
845 object_lifetime_default: object_lifetime_default,
849 fn parse_object_lifetime_default<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
851 -> Option<ty::ObjectLifetimeDefault>
852 where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
856 'a' => Some(ty::ObjectLifetimeDefault::Ambiguous),
858 let region = parse_region_(st, conv);
859 Some(ty::ObjectLifetimeDefault::Specific(region))
861 _ => panic!("parse_object_lifetime_default
: bad input
")
865 fn parse_existential_bounds<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
867 -> ty::ExistentialBounds<'tcx> where
868 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
870 parse_existential_bounds_(st, &mut conv)
873 fn parse_existential_bounds_<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
875 -> ty::ExistentialBounds<'tcx> where
876 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
878 let ty::ParamBounds { trait_bounds, mut region_bounds, builtin_bounds, projection_bounds } =
879 parse_bounds_(st, conv);
880 assert_eq!(region_bounds.len(), 1);
881 assert_eq!(trait_bounds.len(), 0);
882 let region_bound = region_bounds.pop().unwrap();
883 return ty::ExistentialBounds { region_bound: region_bound,
884 builtin_bounds: builtin_bounds,
885 projection_bounds: projection_bounds };
888 fn parse_builtin_bounds<F>(st: &mut PState, mut _conv: F) -> ty::BuiltinBounds where
889 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
891 parse_builtin_bounds_(st, &mut _conv)
894 fn parse_builtin_bounds_<F>(st: &mut PState, _conv: &mut F) -> ty::BuiltinBounds where
895 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
897 let mut builtin_bounds = ty::empty_builtin_bounds();
902 builtin_bounds.insert(ty::BoundSend);
905 builtin_bounds.insert(ty::BoundSized);
908 builtin_bounds.insert(ty::BoundCopy);
911 builtin_bounds.insert(ty::BoundSync);
914 return builtin_bounds;
917 panic!("parse_bounds
: bad builtin
bounds ('{}'
)", c)
923 fn parse_bounds<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
924 -> ty::ParamBounds<'tcx> where
925 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
927 parse_bounds_(st, &mut conv)
930 fn parse_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
931 -> ty::ParamBounds<'tcx> where
932 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
934 let builtin_bounds = parse_builtin_bounds_(st, conv);
936 let region_bounds = parse_region_bounds_(st, conv);
938 let mut param_bounds = ty::ParamBounds {
939 region_bounds: region_bounds,
940 builtin_bounds: builtin_bounds,
941 trait_bounds: Vec::new(),
942 projection_bounds: Vec::new(),
949 param_bounds.trait_bounds.push(
950 ty::Binder(parse_trait_ref_(st, conv)));
953 param_bounds.projection_bounds.push(
954 ty::Binder(parse_projection_predicate_(st, conv)));
960 panic!("parse_bounds
: bad
bounds ('{}'
)", c)
966 fn parse_region_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
967 -> Vec<ty::Region> where
968 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
970 let mut region_bounds = Vec::new();
973 'R' => { region_bounds.push(parse_region_(st, conv)); }
974 '.' => { return region_bounds; }
975 c => { panic!("parse_bounds: bad bounds ('{}')", c
); }