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 TyStr &
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 region parameter (`fn foo<'X>() { ... }`).
56 // Identifies a closure
60 // type conv_did = impl FnMut(DefIdSource, ast::DefId) -> ast::DefId;
62 pub struct PState
<'a
, 'tcx
: 'a
> {
66 tcx
: &'a ty
::ctxt
<'tcx
>
69 fn peek(st
: &PState
) -> char {
70 st
.data
[st
.pos
] as char
73 fn next(st
: &mut PState
) -> char {
74 let ch
= st
.data
[st
.pos
] as char;
79 fn next_byte(st
: &mut PState
) -> u8 {
80 let b
= st
.data
[st
.pos
];
85 fn scan
<R
, F
, G
>(st
: &mut PState
, mut is_last
: F
, op
: G
) -> R
where
86 F
: FnMut(char) -> bool
,
87 G
: FnOnce(&[u8]) -> R
,
89 let start_pos
= st
.pos
;
90 debug
!("scan: '{}' (start)", st
.data
[st
.pos
] as char);
91 while !is_last(st
.data
[st
.pos
] as char) {
93 debug
!("scan: '{}'", st
.data
[st
.pos
] as char);
97 return op(&st
.data
[start_pos
..end_pos
]);
100 pub fn parse_name(st
: &mut PState
, last
: char) -> ast
::Name
{
101 fn is_last(b
: char, c
: char) -> bool { return c == b; }
102 parse_name_(st
, |a
| is_last(last
, a
) )
105 fn parse_name_
<F
>(st
: &mut PState
, is_last
: F
) -> ast
::Name
where
106 F
: FnMut(char) -> bool
,
108 scan(st
, is_last
, |bytes
| {
109 token
::intern(str::from_utf8(bytes
).unwrap())
113 pub fn parse_state_from_data
<'a
, 'tcx
>(data
: &'a
[u8], crate_num
: ast
::CrateNum
,
114 pos
: usize, tcx
: &'a ty
::ctxt
<'tcx
>)
115 -> PState
<'a
, 'tcx
> {
124 fn data_log_string(data
: &[u8], pos
: usize) -> String
{
125 let mut buf
= String
::new();
127 for i
in pos
..data
.len() {
129 if c
> 0x20 && c
<= 0x7F {
139 pub fn parse_ty_closure_data
<'tcx
, F
>(data
: &[u8],
140 crate_num
: ast
::CrateNum
,
142 tcx
: &ty
::ctxt
<'tcx
>,
144 -> ty
::ClosureTy
<'tcx
> where
145 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
147 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
148 parse_closure_ty(&mut st
, conv
)
151 pub fn parse_ty_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: usize,
152 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
) -> Ty
<'tcx
> where
153 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
155 debug
!("parse_ty_data {}", data_log_string(data
, pos
));
156 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
157 parse_ty(&mut st
, conv
)
160 pub fn parse_region_data
<F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: usize, tcx
: &ty
::ctxt
,
161 conv
: F
) -> ty
::Region
where
162 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
164 debug
!("parse_region_data {}", data_log_string(data
, pos
));
165 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
166 parse_region(&mut st
, conv
)
169 pub fn parse_bare_fn_ty_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: usize,
170 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
)
171 -> ty
::BareFnTy
<'tcx
> where
172 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
174 debug
!("parse_bare_fn_ty_data {}", data_log_string(data
, pos
));
175 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
176 parse_bare_fn_ty(&mut st
, conv
)
179 pub fn parse_trait_ref_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: usize,
180 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
)
181 -> ty
::TraitRef
<'tcx
> where
182 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
184 debug
!("parse_trait_ref_data {}", data_log_string(data
, pos
));
185 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
186 parse_trait_ref(&mut st
, conv
)
189 pub fn parse_substs_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: usize,
190 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
) -> subst
::Substs
<'tcx
> where
191 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
193 debug
!("parse_substs_data{}", data_log_string(data
, pos
));
194 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
195 parse_substs(&mut st
, conv
)
198 pub fn parse_existential_bounds_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
,
199 pos
: usize, tcx
: &ty
::ctxt
<'tcx
>, conv
: F
)
200 -> ty
::ExistentialBounds
<'tcx
> where
201 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
203 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
204 parse_existential_bounds(&mut st
, conv
)
207 pub fn parse_builtin_bounds_data
<F
>(data
: &[u8], crate_num
: ast
::CrateNum
,
208 pos
: usize, tcx
: &ty
::ctxt
, conv
: F
)
209 -> ty
::BuiltinBounds
where
210 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
212 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
213 parse_builtin_bounds(&mut st
, conv
)
216 fn parse_size(st
: &mut PState
) -> Option
<usize> {
217 assert_eq
!(next(st
), '
/'
);
220 assert_eq
!(next(st
), '
|'
);
223 let n
= parse_uint(st
);
224 assert_eq
!(next(st
), '
|'
);
229 fn parse_vec_per_param_space
<'a
, 'tcx
, T
, F
>(st
: &mut PState
<'a
, 'tcx
>,
231 -> VecPerParamSpace
<T
> where
232 F
: FnMut(&mut PState
<'a
, 'tcx
>) -> T
,
234 let mut r
= VecPerParamSpace
::empty();
235 for &space
in &subst
::ParamSpace
::all() {
236 assert_eq
!(next(st
), '
['
);
237 while peek(st
) != '
]'
{
238 r
.push(space
, f(st
));
240 assert_eq
!(next(st
), '
]'
);
245 fn parse_substs
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>,
246 mut conv
: F
) -> subst
::Substs
<'tcx
> where
247 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
249 parse_substs_(st
, &mut conv
)
252 fn parse_substs_
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>,
253 conv
: &mut F
) -> subst
::Substs
<'tcx
> where
254 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
257 parse_region_substs_(st
, conv
);
260 parse_vec_per_param_space(st
, |st
| parse_ty_(st
, conv
));
262 subst
::Substs
{ types
: types
,
266 fn parse_region_substs_
<F
>(st
: &mut PState
, conv
: &mut F
) -> subst
::RegionSubsts
where
267 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
270 'e'
=> subst
::ErasedRegions
,
272 subst
::NonerasedRegions(
273 parse_vec_per_param_space(
274 st
, |st
| parse_region_(st
, conv
)))
276 _
=> panic
!("parse_bound_region: bad input")
280 fn parse_bound_region_
<F
>(st
: &mut PState
, conv
: &mut F
) -> ty
::BoundRegion
where
281 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
285 let id
= parse_u32(st
);
286 assert_eq
!(next(st
), '
|'
);
290 let def
= parse_def_(st
, RegionParameter
, conv
);
291 let ident
= token
::str_to_ident(&parse_str(st
, '
]'
));
292 ty
::BrNamed(def
, ident
.name
)
295 let id
= parse_u32(st
);
296 assert_eq
!(next(st
), '
|'
);
300 _
=> panic
!("parse_bound_region: bad input")
304 fn parse_region
<F
>(st
: &mut PState
, mut conv
: F
) -> ty
::Region
where
305 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
307 parse_region_(st
, &mut conv
)
310 fn parse_region_
<F
>(st
: &mut PState
, conv
: &mut F
) -> ty
::Region
where
311 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
315 assert_eq
!(next(st
), '
['
);
316 let id
= ty
::DebruijnIndex
::new(parse_u32(st
));
317 assert_eq
!(next(st
), '
|'
);
318 let br
= parse_bound_region_(st
, conv
);
319 assert_eq
!(next(st
), '
]'
);
320 ty
::ReLateBound(id
, br
)
323 assert_eq
!(next(st
), '
['
);
324 let node_id
= parse_uint(st
) as ast
::NodeId
;
325 assert_eq
!(next(st
), '
|'
);
326 let space
= parse_param_space(st
);
327 assert_eq
!(next(st
), '
|'
);
328 let index
= parse_u32(st
);
329 assert_eq
!(next(st
), '
|'
);
330 let nm
= token
::str_to_ident(&parse_str(st
, '
]'
));
331 ty
::ReEarlyBound(ty
::EarlyBoundRegion
{
339 assert_eq
!(next(st
), '
['
);
340 let scope
= parse_destruction_scope_data(st
);
341 assert_eq
!(next(st
), '
|'
);
342 let br
= parse_bound_region_(st
, conv
);
343 assert_eq
!(next(st
), '
]'
);
344 ty
::ReFree(ty
::FreeRegion
{ scope
: scope
,
348 let scope
= parse_scope(st
);
349 assert_eq
!(next(st
), '
|'
);
358 _
=> panic
!("parse_region: bad input")
362 fn parse_scope(st
: &mut PState
) -> region
::CodeExtent
{
365 assert_eq
!(next(st
), '
['
);
366 let fn_id
= parse_uint(st
) as ast
::NodeId
;
367 assert_eq
!(next(st
), '
|'
);
368 let body_id
= parse_uint(st
) as ast
::NodeId
;
369 assert_eq
!(next(st
), '
]'
);
370 region
::CodeExtent
::ParameterScope
{
371 fn_id
: fn_id
, body_id
: body_id
375 let node_id
= parse_uint(st
) as ast
::NodeId
;
376 region
::CodeExtent
::Misc(node_id
)
379 let node_id
= parse_uint(st
) as ast
::NodeId
;
380 region
::CodeExtent
::DestructionScope(node_id
)
383 assert_eq
!(next(st
), '
['
);
384 let node_id
= parse_uint(st
) as ast
::NodeId
;
385 assert_eq
!(next(st
), '
|'
);
386 let first_stmt_index
= parse_uint(st
);
387 assert_eq
!(next(st
), '
]'
);
388 let block_remainder
= region
::BlockRemainder
{
389 block
: node_id
, first_statement_index
: first_stmt_index
,
391 region
::CodeExtent
::Remainder(block_remainder
)
393 _
=> panic
!("parse_scope: bad input")
397 fn parse_destruction_scope_data(st
: &mut PState
) -> region
::DestructionScopeData
{
398 let node_id
= parse_uint(st
) as ast
::NodeId
;
399 region
::DestructionScopeData
::new(node_id
)
402 fn parse_opt
<'a
, 'tcx
, T
, F
>(st
: &mut PState
<'a
, 'tcx
>, f
: F
) -> Option
<T
> where
403 F
: FnOnce(&mut PState
<'a
, 'tcx
>) -> T
,
408 _
=> panic
!("parse_opt: bad input")
412 fn parse_str(st
: &mut PState
, term
: char) -> String
{
413 let mut result
= String
::new();
414 while peek(st
) != term
{
416 result
.as_mut_vec().push_all(&[next_byte(st
)])
423 fn parse_trait_ref
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, mut conv
: F
)
424 -> ty
::TraitRef
<'tcx
> where
425 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
427 parse_trait_ref_(st
, &mut conv
)
430 fn parse_trait_ref_
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, conv
: &mut F
)
431 -> ty
::TraitRef
<'tcx
> where
432 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
434 let def
= parse_def_(st
, NominalType
, conv
);
435 let substs
= st
.tcx
.mk_substs(parse_substs_(st
, conv
));
436 ty
::TraitRef {def_id: def, substs: substs}
439 fn parse_ty
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, mut conv
: F
) -> Ty
<'tcx
> where
440 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
442 parse_ty_(st
, &mut conv
)
445 fn parse_ty_
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, conv
: &mut F
) -> Ty
<'tcx
> where
446 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
450 'b'
=> return tcx
.types
.bool
,
451 'i'
=> { /* eat the s of is */ next(st); return tcx.types.isize }
,
452 'u'
=> { /* eat the s of us */ next(st); return tcx.types.usize }
,
455 'b'
=> return tcx
.types
.u8,
456 'w'
=> return tcx
.types
.u16,
457 'l'
=> return tcx
.types
.u32,
458 'd'
=> return tcx
.types
.u64,
459 'B'
=> return tcx
.types
.i8,
460 'W'
=> return tcx
.types
.i16,
461 'L'
=> return tcx
.types
.i32,
462 'D'
=> return tcx
.types
.i64,
463 'f'
=> return tcx
.types
.f32,
464 'F'
=> return tcx
.types
.f64,
465 _
=> panic
!("parse_ty: bad numeric type")
468 'c'
=> return tcx
.types
.char,
470 assert_eq
!(next(st
), '
['
);
471 let def
= parse_def_(st
, NominalType
, conv
);
472 let substs
= parse_substs_(st
, conv
);
473 assert_eq
!(next(st
), '
]'
);
474 return ty
::mk_enum(tcx
, def
, st
.tcx
.mk_substs(substs
));
477 assert_eq
!(next(st
), '
['
);
478 let trait_ref
= ty
::Binder(parse_trait_ref_(st
, conv
));
479 let bounds
= parse_existential_bounds_(st
, conv
);
480 assert_eq
!(next(st
), '
]'
);
481 return ty
::mk_trait(tcx
, trait_ref
, bounds
);
484 assert_eq
!(next(st
), '
['
);
485 let index
= parse_u32(st
);
486 assert_eq
!(next(st
), '
|'
);
487 let space
= parse_param_space(st
);
488 assert_eq
!(next(st
), '
|'
);
489 let name
= token
::intern(&parse_str(st
, '
]'
));
490 return ty
::mk_param(tcx
, space
, index
, name
);
492 '
~'
=> return ty
::mk_uniq(tcx
, parse_ty_(st
, conv
)),
493 '
*'
=> return ty
::mk_ptr(tcx
, parse_mt_(st
, conv
)),
495 let r
= parse_region_(st
, conv
);
496 let mt
= parse_mt_(st
, conv
);
497 return ty
::mk_rptr(tcx
, tcx
.mk_region(r
), mt
);
500 let t
= parse_ty_(st
, conv
);
501 let sz
= parse_size(st
);
502 return ty
::mk_vec(tcx
, t
, sz
);
505 return ty
::mk_str(tcx
);
508 assert_eq
!(next(st
), '
['
);
509 let mut params
= Vec
::new();
510 while peek(st
) != '
]' { params.push(parse_ty_(st, conv)); }
512 return ty
::mk_tup(tcx
, params
);
515 let def_id
= parse_def_(st
, NominalType
, conv
);
516 return ty
::mk_bare_fn(tcx
, Some(def_id
),
517 tcx
.mk_bare_fn(parse_bare_fn_ty_(st
, conv
)));
520 return ty
::mk_bare_fn(tcx
, None
,
521 tcx
.mk_bare_fn(parse_bare_fn_ty_(st
, conv
)));
524 let pos
= parse_hex(st
);
525 assert_eq
!(next(st
), '
:'
);
526 let len
= parse_hex(st
);
527 assert_eq
!(next(st
), '
#');
528 let key
= ty
::creader_cache_key
{cnum
: st
.krate
,
532 match tcx
.rcache
.borrow().get(&key
).cloned() {
534 // If there is a closure buried in the type some where, then we
535 // need to re-convert any def ids (see case 'k', below). That means
536 // we can't reuse the cached version.
537 if !ty
::type_has_ty_closure(tt
) {
543 let mut ps
= PState
{
547 let tt
= parse_ty_(&mut ps
, conv
);
548 tcx
.rcache
.borrow_mut().insert(key
, tt
);
552 let _
= parse_def_(st
, TypeWithId
, conv
);
553 let inner
= parse_ty_(st
, conv
);
557 assert_eq
!(next(st
), '
['
);
558 let did
= parse_def_(st
, NominalType
, conv
);
559 let substs
= parse_substs_(st
, conv
);
560 assert_eq
!(next(st
), '
]'
);
561 return ty
::mk_struct(st
.tcx
, did
, st
.tcx
.mk_substs(substs
));
564 assert_eq
!(next(st
), '
['
);
565 let did
= parse_def_(st
, ClosureSource
, conv
);
566 let substs
= parse_substs_(st
, conv
);
567 assert_eq
!(next(st
), '
]'
);
568 return ty
::mk_closure(st
.tcx
, did
, st
.tcx
.mk_substs(substs
));
571 assert_eq
!(next(st
), '
['
);
572 let trait_ref
= parse_trait_ref_(st
, conv
);
573 let name
= token
::intern(&parse_str(st
, '
]'
));
574 return ty
::mk_projection(tcx
, trait_ref
, name
);
577 return tcx
.types
.err
;
579 c
=> { panic!("unexpected char in type string: {}
", c);}
583 fn parse_mutability(st: &mut PState) -> ast::Mutability {
585 'm' => { next(st); ast::MutMutable }
586 _ => { ast::MutImmutable }
590 fn parse_mt_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::mt<'tcx> where
591 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
593 let m = parse_mutability(st);
594 ty::mt { ty: parse_ty_(st, conv), mutbl: m }
597 fn parse_def_<F>(st: &mut PState, source: DefIdSource, conv: &mut F) -> ast::DefId where
598 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
600 return (*conv)(source, scan(st, |c| { c == '|' }, parse_def_id));
603 fn parse_uint(st: &mut PState) -> usize {
607 if cur < '0' || cur > '9' { return n; }
610 n += (cur as usize) - ('0' as usize);
614 fn parse_u32(st: &mut PState) -> u32 {
615 let n = parse_uint(st);
617 assert_eq!(m as usize, n);
621 fn parse_param_space(st: &mut PState) -> subst::ParamSpace {
622 subst::ParamSpace::from_uint(parse_uint(st))
625 fn parse_hex(st: &mut PState) -> usize {
629 if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; }
632 if '0' <= cur && cur <= '9' {
633 n += (cur as usize) - ('0' as usize);
634 } else { n += 10 + (cur as usize) - ('a' as usize); }
638 fn parse_unsafety(c: char) -> ast::Unsafety {
640 'u' => ast::Unsafety::Unsafe,
641 'n' => ast::Unsafety::Normal,
642 _ => panic!("parse_unsafety
: bad unsafety {}
", c)
646 fn parse_abi_set(st: &mut PState) -> abi::Abi {
647 assert_eq!(next(st), '[');
648 scan(st, |c| c == ']', |bytes| {
649 let abi_str = str::from_utf8(bytes).unwrap();
650 abi::lookup(&abi_str[..]).expect(abi_str)
654 fn parse_closure_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
655 mut conv: F) -> ty::ClosureTy<'tcx> where
656 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
658 parse_closure_ty_(st, &mut conv)
661 fn parse_closure_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
662 conv: &mut F) -> ty::ClosureTy<'tcx> where
663 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
665 let unsafety = parse_unsafety(next(st));
666 let sig = parse_sig_(st, conv);
667 let abi = parse_abi_set(st);
675 fn parse_bare_fn_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
676 mut conv: F) -> ty::BareFnTy<'tcx> where
677 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
679 parse_bare_fn_ty_(st, &mut conv)
682 fn parse_bare_fn_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
683 conv: &mut F) -> ty::BareFnTy<'tcx> where
684 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
686 let unsafety = parse_unsafety(next(st));
687 let abi = parse_abi_set(st);
688 let sig = parse_sig_(st, conv);
696 fn parse_sig_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::PolyFnSig<'tcx> where
697 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
699 assert_eq!(next(st), '[');
700 let mut inputs = Vec::new();
701 while peek(st) != ']' {
702 inputs.push(parse_ty_(st, conv));
704 st.pos += 1; // eat the ']'
705 let variadic = match next(st) {
708 r => panic!(format!("bad variadic
: {}
", r)),
710 let output = match peek(st) {
715 _ => ty::FnConverging(parse_ty_(st, conv))
717 ty::Binder(ty::FnSig {inputs: inputs,
722 // Rust metadata parsing
723 pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
724 let mut colon_idx = 0;
726 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; }
727 if colon_idx == len {
728 error!("didn't find '
:' when parsing def id
");
732 let crate_part = &buf[0..colon_idx];
733 let def_part = &buf[colon_idx + 1..len];
735 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
736 s.parse::<usize>().ok()
738 Some(cn) => cn as ast::CrateNum,
739 None => panic!("internal error
: parse_def_id
: crate number expected
, found {:?}
",
742 let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
743 s.parse::<usize>().ok()
745 Some(dn) => dn as ast::NodeId,
746 None => panic!("internal error
: parse_def_id
: id expected
, found {:?}
",
749 ast::DefId { krate: crate_num, node: def_num }
752 pub fn parse_predicate_data<'tcx, F>(data: &[u8],
754 crate_num: ast::CrateNum,
755 tcx: &ty::ctxt<'tcx>,
757 -> ty::Predicate<'tcx> where
758 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
760 let mut st = parse_state_from_data(data, crate_num, start, tcx);
761 parse_predicate(&mut st, conv)
764 pub fn parse_predicate<'a,'tcx, F>(st: &mut PState<'a, 'tcx>,
766 -> ty::Predicate<'tcx> where
767 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
769 parse_predicate_(st, &mut conv)
772 fn parse_predicate_<'a,'tcx, F>(st: &mut PState<'a, 'tcx>,
774 -> ty::Predicate<'tcx> where
775 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
778 't' => ty::Binder(parse_trait_ref_(st, conv)).as_predicate(),
779 'e' => ty::Binder(ty::EquatePredicate(parse_ty_(st, conv),
780 parse_ty_(st, conv))).as_predicate(),
781 'r' => ty::Binder(ty::OutlivesPredicate(parse_region_(st, conv),
782 parse_region_(st, conv))).as_predicate(),
783 'o' => ty::Binder(ty::OutlivesPredicate(parse_ty_(st, conv),
784 parse_region_(st, conv))).as_predicate(),
785 'p' => ty::Binder(parse_projection_predicate_(st, conv)).as_predicate(),
786 c => panic!("Encountered invalid character
in metadata
: {}
", c)
790 fn parse_projection_predicate_<'a,'tcx, F>(
791 st: &mut PState<'a, 'tcx>,
793 ) -> ty::ProjectionPredicate<'tcx> where
794 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
796 ty::ProjectionPredicate {
797 projection_ty: ty::ProjectionTy {
798 trait_ref: parse_trait_ref_(st, conv),
799 item_name: token::str_to_ident(&parse_str(st, '|')).name,
801 ty: parse_ty_(st, conv),
805 pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: usize,
806 crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>,
807 conv: F) -> ty::TypeParameterDef<'tcx> where
808 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
810 let mut st = parse_state_from_data(data, crate_num, start, tcx);
811 parse_type_param_def(&mut st, conv)
814 fn parse_type_param_def<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
815 -> ty::TypeParameterDef<'tcx> where
816 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
818 parse_type_param_def_(st, &mut conv)
821 fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
822 -> ty::TypeParameterDef<'tcx> where
823 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
825 let name = parse_name(st, ':');
826 let def_id = parse_def_(st, NominalType, conv);
827 let space = parse_param_space(st);
828 assert_eq!(next(st), '|');
829 let index = parse_u32(st);
830 assert_eq!(next(st), '|');
831 let default = parse_opt(st, |st| parse_ty_(st, conv));
832 let object_lifetime_default = parse_object_lifetime_default(st, conv);
834 ty::TypeParameterDef {
840 object_lifetime_default: object_lifetime_default,
844 fn parse_object_lifetime_default<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
846 -> ty::ObjectLifetimeDefault
847 where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
850 'a' => ty::ObjectLifetimeDefault::Ambiguous,
851 'b' => ty::ObjectLifetimeDefault::BaseDefault,
853 let region = parse_region_(st, conv);
854 ty::ObjectLifetimeDefault::Specific(region)
856 _ => panic!("parse_object_lifetime_default
: bad input
")
860 fn parse_existential_bounds<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
862 -> ty::ExistentialBounds<'tcx> where
863 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
865 parse_existential_bounds_(st, &mut conv)
868 fn parse_existential_bounds_<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
870 -> ty::ExistentialBounds<'tcx> where
871 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
873 let builtin_bounds = parse_builtin_bounds_(st, conv);
874 let region_bound = parse_region_(st, conv);
875 let mut projection_bounds = Vec::new();
880 projection_bounds.push(
881 ty::Binder(parse_projection_predicate_(st, conv)));
885 panic!("parse_bounds
: bad
bounds ('{}'
)", c)
890 let region_bound_will_change = match next(st) {
893 c => panic!("parse_ty
: expected y
/n not '{}'
", c)
896 return ty::ExistentialBounds { region_bound: region_bound,
897 builtin_bounds: builtin_bounds,
898 projection_bounds: projection_bounds,
899 region_bound_will_change: region_bound_will_change };
902 fn parse_builtin_bounds<F>(st: &mut PState, mut _conv: F) -> ty::BuiltinBounds where
903 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
905 parse_builtin_bounds_(st, &mut _conv)
908 fn parse_builtin_bounds_<F>(st: &mut PState, _conv: &mut F) -> ty::BuiltinBounds where
909 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
911 let mut builtin_bounds = ty::BuiltinBounds::empty();
916 builtin_bounds.insert(ty::BoundSend);
919 builtin_bounds.insert(ty::BoundSized);
922 builtin_bounds.insert(ty::BoundCopy);
925 builtin_bounds.insert(ty::BoundSync);
928 return builtin_bounds;
931 panic!("parse_bounds
: bad builtin
bounds ('{}'
)", c)