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}
;
30 use syntax
::parse
::token
;
32 // Compact string representation for Ty values. API ty_str &
33 // parse_from_str. Extra parameters are for converting to/from def_ids in the
34 // data buffer. Whatever format you choose should not contain pipe characters.
36 // Def id conversion: when we encounter def-ids, they have to be translated.
37 // For example, the crate number must be converted from the crate number used
38 // in the library we are reading from into the local crate numbers in use
39 // here. To perform this translation, the type decoder is supplied with a
40 // conversion function of type `conv_did`.
42 // Sometimes, particularly when inlining, the correct translation of the
43 // def-id will depend on where it originated from. Therefore, the conversion
44 // function is given an indicator of the source of the def-id. See
45 // astencode.rs for more information.
46 #[derive(Copy, Debug)]
47 pub enum DefIdSource
{
48 // Identifies a struct, trait, enum, etc.
51 // Identifies a type alias (`type X = ...`).
54 // Identifies a type parameter (`fn foo<X>() { ... }`).
57 // Identifies a region parameter (`fn foo<'X>() { ... }`).
60 // Identifies a closure
64 // type conv_did = impl FnMut(DefIdSource, ast::DefId) -> ast::DefId;
66 pub struct PState
<'a
, 'tcx
: 'a
> {
70 tcx
: &'a ty
::ctxt
<'tcx
>
73 fn peek(st
: &PState
) -> char {
74 st
.data
[st
.pos
] as char
77 fn next(st
: &mut PState
) -> char {
78 let ch
= st
.data
[st
.pos
] as char;
83 fn next_byte(st
: &mut PState
) -> u8 {
84 let b
= st
.data
[st
.pos
];
89 fn scan
<R
, F
, G
>(st
: &mut PState
, mut is_last
: F
, op
: G
) -> R
where
90 F
: FnMut(char) -> bool
,
91 G
: FnOnce(&[u8]) -> R
,
93 let start_pos
= st
.pos
;
94 debug
!("scan: '{}' (start)", st
.data
[st
.pos
] as char);
95 while !is_last(st
.data
[st
.pos
] as char) {
97 debug
!("scan: '{}'", st
.data
[st
.pos
] as char);
101 return op(&st
.data
[start_pos
..end_pos
]);
104 pub fn parse_ident(st
: &mut PState
, last
: char) -> ast
::Ident
{
105 ast
::Ident
::new(parse_name(st
, last
))
108 pub fn parse_name(st
: &mut PState
, last
: char) -> ast
::Name
{
109 fn is_last(b
: char, c
: char) -> bool { return c == b; }
110 parse_name_(st
, |a
| is_last(last
, a
) )
113 fn parse_name_
<F
>(st
: &mut PState
, is_last
: F
) -> ast
::Name
where
114 F
: FnMut(char) -> bool
,
116 scan(st
, is_last
, |bytes
| {
117 token
::intern(str::from_utf8(bytes
).unwrap())
121 pub fn parse_state_from_data
<'a
, 'tcx
>(data
: &'a
[u8], crate_num
: ast
::CrateNum
,
122 pos
: uint
, tcx
: &'a ty
::ctxt
<'tcx
>)
123 -> PState
<'a
, 'tcx
> {
132 fn data_log_string(data
: &[u8], pos
: uint
) -> String
{
133 let mut buf
= String
::new();
135 for i
in pos
..data
.len() {
137 if c
> 0x20 && c
<= 0x7F {
147 pub fn parse_ty_closure_data
<'tcx
, F
>(data
: &[u8],
148 crate_num
: ast
::CrateNum
,
150 tcx
: &ty
::ctxt
<'tcx
>,
152 -> ty
::ClosureTy
<'tcx
> where
153 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
155 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
156 parse_closure_ty(&mut st
, conv
)
159 pub fn parse_ty_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: uint
,
160 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
) -> Ty
<'tcx
> where
161 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
163 debug
!("parse_ty_data {}", data_log_string(data
, pos
));
164 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
165 parse_ty(&mut st
, conv
)
168 pub fn parse_region_data
<F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: uint
, tcx
: &ty
::ctxt
,
169 conv
: F
) -> ty
::Region
where
170 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
172 debug
!("parse_region_data {}", data_log_string(data
, pos
));
173 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
174 parse_region(&mut st
, conv
)
177 pub fn parse_bare_fn_ty_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: uint
,
178 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
)
179 -> ty
::BareFnTy
<'tcx
> where
180 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
182 debug
!("parse_bare_fn_ty_data {}", data_log_string(data
, pos
));
183 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
184 parse_bare_fn_ty(&mut st
, conv
)
187 pub fn parse_trait_ref_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: uint
,
188 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
)
189 -> Rc
<ty
::TraitRef
<'tcx
>> where
190 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
192 debug
!("parse_trait_ref_data {}", data_log_string(data
, pos
));
193 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
194 parse_trait_ref(&mut st
, conv
)
197 pub fn parse_substs_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
, pos
: uint
,
198 tcx
: &ty
::ctxt
<'tcx
>, conv
: F
) -> subst
::Substs
<'tcx
> where
199 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
201 debug
!("parse_substs_data {}", data_log_string(data
, pos
));
202 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
203 parse_substs(&mut st
, conv
)
206 pub fn parse_bounds_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
,
207 pos
: uint
, tcx
: &ty
::ctxt
<'tcx
>, conv
: F
)
208 -> ty
::ParamBounds
<'tcx
> where
209 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
211 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
212 parse_bounds(&mut st
, conv
)
215 pub fn parse_existential_bounds_data
<'tcx
, F
>(data
: &[u8], crate_num
: ast
::CrateNum
,
216 pos
: uint
, tcx
: &ty
::ctxt
<'tcx
>, conv
: F
)
217 -> ty
::ExistentialBounds
<'tcx
> where
218 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
220 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
221 parse_existential_bounds(&mut st
, conv
)
224 pub fn parse_builtin_bounds_data
<F
>(data
: &[u8], crate_num
: ast
::CrateNum
,
225 pos
: uint
, tcx
: &ty
::ctxt
, conv
: F
)
226 -> ty
::BuiltinBounds
where
227 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
229 let mut st
= parse_state_from_data(data
, crate_num
, pos
, tcx
);
230 parse_builtin_bounds(&mut st
, conv
)
233 fn parse_size(st
: &mut PState
) -> Option
<uint
> {
234 assert_eq
!(next(st
), '
/'
);
237 assert_eq
!(next(st
), '
|'
);
240 let n
= parse_uint(st
);
241 assert_eq
!(next(st
), '
|'
);
246 fn parse_vec_per_param_space
<'a
, 'tcx
, T
, F
>(st
: &mut PState
<'a
, 'tcx
>,
248 -> VecPerParamSpace
<T
> where
249 F
: FnMut(&mut PState
<'a
, 'tcx
>) -> T
,
251 let mut r
= VecPerParamSpace
::empty();
252 for &space
in &subst
::ParamSpace
::all() {
253 assert_eq
!(next(st
), '
['
);
254 while peek(st
) != '
]'
{
255 r
.push(space
, f(st
));
257 assert_eq
!(next(st
), '
]'
);
262 fn parse_substs
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>,
263 mut conv
: F
) -> subst
::Substs
<'tcx
> where
264 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
266 parse_substs_(st
, &mut conv
)
269 fn parse_substs_
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>,
270 conv
: &mut F
) -> subst
::Substs
<'tcx
> where
271 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
274 parse_region_substs_(st
, conv
);
277 parse_vec_per_param_space(st
, |st
| parse_ty_(st
, conv
));
279 subst
::Substs
{ types
: types
,
283 fn parse_region_substs_
<F
>(st
: &mut PState
, conv
: &mut F
) -> subst
::RegionSubsts
where
284 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
287 'e'
=> subst
::ErasedRegions
,
289 subst
::NonerasedRegions(
290 parse_vec_per_param_space(
291 st
, |st
| parse_region_(st
, conv
)))
293 _
=> panic
!("parse_bound_region: bad input")
297 fn parse_bound_region_
<F
>(st
: &mut PState
, conv
: &mut F
) -> ty
::BoundRegion
where
298 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
302 let id
= parse_u32(st
);
303 assert_eq
!(next(st
), '
|'
);
307 let def
= parse_def_(st
, RegionParameter
, conv
);
308 let ident
= token
::str_to_ident(&parse_str(st
, '
]'
)[]);
309 ty
::BrNamed(def
, ident
.name
)
312 let id
= parse_u32(st
);
313 assert_eq
!(next(st
), '
|'
);
317 _
=> panic
!("parse_bound_region: bad input")
321 fn parse_region
<F
>(st
: &mut PState
, mut conv
: F
) -> ty
::Region
where
322 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
324 parse_region_(st
, &mut conv
)
327 fn parse_region_
<F
>(st
: &mut PState
, conv
: &mut F
) -> ty
::Region
where
328 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
332 assert_eq
!(next(st
), '
['
);
333 let id
= ty
::DebruijnIndex
::new(parse_u32(st
));
334 assert_eq
!(next(st
), '
|'
);
335 let br
= parse_bound_region_(st
, conv
);
336 assert_eq
!(next(st
), '
]'
);
337 ty
::ReLateBound(id
, br
)
340 assert_eq
!(next(st
), '
['
);
341 let node_id
= parse_uint(st
) as ast
::NodeId
;
342 assert_eq
!(next(st
), '
|'
);
343 let space
= parse_param_space(st
);
344 assert_eq
!(next(st
), '
|'
);
345 let index
= parse_u32(st
);
346 assert_eq
!(next(st
), '
|'
);
347 let nm
= token
::str_to_ident(&parse_str(st
, '
]'
)[]);
348 ty
::ReEarlyBound(node_id
, space
, index
, nm
.name
)
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 let node_id
= parse_uint(st
) as ast
::NodeId
;
378 region
::CodeExtent
::Misc(node_id
)
381 let node_id
= parse_uint(st
) as ast
::NodeId
;
382 region
::CodeExtent
::DestructionScope(node_id
)
385 let node_id
= parse_uint(st
) as ast
::NodeId
;
386 let first_stmt_index
= parse_uint(st
);
387 let block_remainder
= region
::BlockRemainder
{
388 block
: node_id
, first_statement_index
: first_stmt_index
,
390 region
::CodeExtent
::Remainder(block_remainder
)
392 _
=> panic
!("parse_scope: bad input")
396 fn parse_destruction_scope_data(st
: &mut PState
) -> region
::DestructionScopeData
{
397 let node_id
= parse_uint(st
) as ast
::NodeId
;
398 region
::DestructionScopeData
::new(node_id
)
401 fn parse_opt
<'a
, 'tcx
, T
, F
>(st
: &mut PState
<'a
, 'tcx
>, f
: F
) -> Option
<T
> where
402 F
: FnOnce(&mut PState
<'a
, 'tcx
>) -> T
,
407 _
=> panic
!("parse_opt: bad input")
411 fn parse_str(st
: &mut PState
, term
: char) -> String
{
412 let mut result
= String
::new();
413 while peek(st
) != term
{
415 result
.as_mut_vec().push_all(&[next_byte(st
)])
422 fn parse_trait_ref
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, mut conv
: F
)
423 -> Rc
<ty
::TraitRef
<'tcx
>> where
424 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
426 parse_trait_ref_(st
, &mut conv
)
429 fn parse_trait_ref_
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, conv
: &mut F
)
430 -> Rc
<ty
::TraitRef
<'tcx
>> where
431 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
433 let def
= parse_def_(st
, NominalType
, conv
);
434 let substs
= st
.tcx
.mk_substs(parse_substs_(st
, conv
));
435 Rc
::new(ty
::TraitRef {def_id: def, substs: substs}
)
438 fn parse_ty
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, mut conv
: F
) -> Ty
<'tcx
> where
439 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
441 parse_ty_(st
, &mut conv
)
444 fn parse_ty_
<'a
, 'tcx
, F
>(st
: &mut PState
<'a
, 'tcx
>, conv
: &mut F
) -> Ty
<'tcx
> where
445 F
: FnMut(DefIdSource
, ast
::DefId
) -> ast
::DefId
,
449 'b'
=> return tcx
.types
.bool
,
450 'i'
=> { /* eat the s of is */ next(st); return tcx.types.int }
,
451 'u'
=> { /* eat the s of us */ next(st); return tcx.types.uint }
,
454 'b'
=> return tcx
.types
.u8,
455 'w'
=> return tcx
.types
.u16,
456 'l'
=> return tcx
.types
.u32,
457 'd'
=> return tcx
.types
.u64,
458 'B'
=> return tcx
.types
.i8,
459 'W'
=> return tcx
.types
.i16,
460 'L'
=> return tcx
.types
.i32,
461 'D'
=> return tcx
.types
.i64,
462 'f'
=> return tcx
.types
.f32,
463 'F'
=> return tcx
.types
.f64,
464 _
=> panic
!("parse_ty: bad numeric type")
467 'c'
=> return tcx
.types
.char,
469 assert_eq
!(next(st
), '
['
);
470 let def
= parse_def_(st
, NominalType
, conv
);
471 let substs
= parse_substs_(st
, conv
);
472 assert_eq
!(next(st
), '
]'
);
473 return ty
::mk_enum(tcx
, def
, st
.tcx
.mk_substs(substs
));
476 assert_eq
!(next(st
), '
['
);
477 let trait_ref
= ty
::Binder(parse_trait_ref_(st
, conv
));
478 let bounds
= parse_existential_bounds_(st
, conv
);
479 assert_eq
!(next(st
), '
]'
);
480 return ty
::mk_trait(tcx
, trait_ref
, bounds
);
483 assert_eq
!(next(st
), '
['
);
484 let index
= parse_u32(st
);
485 assert_eq
!(next(st
), '
|'
);
486 let space
= parse_param_space(st
);
487 assert_eq
!(next(st
), '
|'
);
488 let name
= token
::intern(&parse_str(st
, '
]'
)[]);
489 return ty
::mk_param(tcx
, space
, index
, name
);
491 '
~'
=> return ty
::mk_uniq(tcx
, parse_ty_(st
, conv
)),
492 '
*'
=> return ty
::mk_ptr(tcx
, parse_mt_(st
, conv
)),
494 let r
= parse_region_(st
, conv
);
495 let mt
= parse_mt_(st
, conv
);
496 return ty
::mk_rptr(tcx
, tcx
.mk_region(r
), mt
);
499 let t
= parse_ty_(st
, conv
);
500 let sz
= parse_size(st
);
501 return ty
::mk_vec(tcx
, t
, sz
);
504 return ty
::mk_str(tcx
);
507 assert_eq
!(next(st
), '
['
);
508 let mut params
= Vec
::new();
509 while peek(st
) != '
]' { params.push(parse_ty_(st, conv)); }
511 return ty
::mk_tup(tcx
, params
);
514 let def_id
= parse_def_(st
, NominalType
, conv
);
515 return ty
::mk_bare_fn(tcx
, Some(def_id
),
516 tcx
.mk_bare_fn(parse_bare_fn_ty_(st
, conv
)));
519 return ty
::mk_bare_fn(tcx
, None
,
520 tcx
.mk_bare_fn(parse_bare_fn_ty_(st
, conv
)));
523 let pos
= parse_hex(st
);
524 assert_eq
!(next(st
), '
:'
);
525 let len
= parse_hex(st
);
526 assert_eq
!(next(st
), '
#');
527 let key
= ty
::creader_cache_key
{cnum
: st
.krate
,
531 match tcx
.rcache
.borrow().get(&key
).cloned() {
532 Some(tt
) => return tt
,
535 let mut ps
= PState
{
539 let tt
= parse_ty_(&mut ps
, conv
);
540 tcx
.rcache
.borrow_mut().insert(key
, tt
);
544 let _
= parse_def_(st
, TypeWithId
, conv
);
545 let inner
= parse_ty_(st
, conv
);
549 assert_eq
!(next(st
), '
['
);
550 let did
= parse_def_(st
, NominalType
, conv
);
551 let substs
= parse_substs_(st
, conv
);
552 assert_eq
!(next(st
), '
]'
);
553 return ty
::mk_struct(st
.tcx
, did
, st
.tcx
.mk_substs(substs
));
556 assert_eq
!(next(st
), '
['
);
557 let did
= parse_def_(st
, ClosureSource
, conv
);
558 let region
= parse_region_(st
, conv
);
559 let substs
= parse_substs_(st
, conv
);
560 assert_eq
!(next(st
), '
]'
);
561 return ty
::mk_closure(st
.tcx
, did
,
562 st
.tcx
.mk_region(region
), st
.tcx
.mk_substs(substs
));
565 assert_eq
!(next(st
), '
['
);
566 let trait_ref
= parse_trait_ref_(st
, conv
);
567 let name
= token
::intern(&parse_str(st
, '
]'
));
568 return ty
::mk_projection(tcx
, trait_ref
, name
);
571 return tcx
.types
.err
;
573 c
=> { panic!("unexpected char in type string: {}
", c);}
577 fn parse_mutability(st: &mut PState) -> ast::Mutability {
579 'm' => { next(st); ast::MutMutable }
580 _ => { ast::MutImmutable }
584 fn parse_mt_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::mt<'tcx> where
585 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
587 let m = parse_mutability(st);
588 ty::mt { ty: parse_ty_(st, conv), mutbl: m }
591 fn parse_def_<F>(st: &mut PState, source: DefIdSource, conv: &mut F) -> ast::DefId where
592 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
594 return (*conv)(source, scan(st, |c| { c == '|' }, parse_def_id));
597 fn parse_uint(st: &mut PState) -> uint {
601 if cur < '0' || cur > '9' { return n; }
604 n += (cur as uint) - ('0' as uint);
608 fn parse_u32(st: &mut PState) -> u32 {
609 let n = parse_uint(st);
611 assert_eq!(m as uint, n);
615 fn parse_param_space(st: &mut PState) -> subst::ParamSpace {
616 subst::ParamSpace::from_uint(parse_uint(st))
619 fn parse_hex(st: &mut PState) -> uint {
623 if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; }
626 if '0' <= cur && cur <= '9' {
627 n += (cur as uint) - ('0' as uint);
628 } else { n += 10 + (cur as uint) - ('a' as uint); }
632 fn parse_unsafety(c: char) -> ast::Unsafety {
634 'u' => ast::Unsafety::Unsafe,
635 'n' => ast::Unsafety::Normal,
636 _ => panic!("parse_unsafety
: bad unsafety {}
", c)
640 fn parse_abi_set(st: &mut PState) -> abi::Abi {
641 assert_eq!(next(st), '[');
642 scan(st, |c| c == ']', |bytes| {
643 let abi_str = str::from_utf8(bytes).unwrap();
644 abi::lookup(&abi_str[..]).expect(abi_str)
648 fn parse_closure_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
649 mut conv: F) -> ty::ClosureTy<'tcx> where
650 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
652 parse_closure_ty_(st, &mut conv)
655 fn parse_closure_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
656 conv: &mut F) -> ty::ClosureTy<'tcx> where
657 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
659 let unsafety = parse_unsafety(next(st));
660 let sig = parse_sig_(st, conv);
661 let abi = parse_abi_set(st);
669 fn parse_bare_fn_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
670 mut conv: F) -> ty::BareFnTy<'tcx> where
671 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
673 parse_bare_fn_ty_(st, &mut conv)
676 fn parse_bare_fn_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
677 conv: &mut F) -> ty::BareFnTy<'tcx> where
678 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
680 let unsafety = parse_unsafety(next(st));
681 let abi = parse_abi_set(st);
682 let sig = parse_sig_(st, conv);
690 fn parse_sig_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::PolyFnSig<'tcx> where
691 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
693 assert_eq!(next(st), '[');
694 let mut inputs = Vec::new();
695 while peek(st) != ']' {
696 inputs.push(parse_ty_(st, conv));
698 st.pos += 1; // eat the ']'
699 let variadic = match next(st) {
702 r => panic!(format!("bad variadic
: {}
", r)),
704 let output = match peek(st) {
709 _ => ty::FnConverging(parse_ty_(st, conv))
711 ty::Binder(ty::FnSig {inputs: inputs,
716 // Rust metadata parsing
717 pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
718 let mut colon_idx = 0;
720 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; }
721 if colon_idx == len {
722 error!("didn't find '
:' when parsing def id
");
726 let crate_part = &buf[0..colon_idx];
727 let def_part = &buf[colon_idx + 1..len];
729 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
730 s.parse::<uint>().ok()
732 Some(cn) => cn as ast::CrateNum,
733 None => panic!("internal error
: parse_def_id
: crate number expected
, found {:?}
",
736 let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
737 s.parse::<uint>().ok()
739 Some(dn) => dn as ast::NodeId,
740 None => panic!("internal error
: parse_def_id
: id expected
, found {:?}
",
743 ast::DefId { krate: crate_num, node: def_num }
746 pub fn parse_predicate_data<'tcx, F>(data: &[u8],
748 crate_num: ast::CrateNum,
749 tcx: &ty::ctxt<'tcx>,
751 -> ty::Predicate<'tcx> where
752 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
754 let mut st = parse_state_from_data(data, crate_num, start, tcx);
755 parse_predicate(&mut st, conv)
758 pub fn parse_predicate<'a,'tcx, F>(st: &mut PState<'a, 'tcx>,
760 -> ty::Predicate<'tcx> where
761 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
763 parse_predicate_(st, &mut conv)
766 fn parse_predicate_<'a,'tcx, F>(st: &mut PState<'a, 'tcx>,
768 -> ty::Predicate<'tcx> where
769 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
772 't' => ty::Binder(parse_trait_ref_(st, conv)).as_predicate(),
773 'e' => ty::Binder(ty::EquatePredicate(parse_ty_(st, conv),
774 parse_ty_(st, conv))).as_predicate(),
775 'r' => ty::Binder(ty::OutlivesPredicate(parse_region_(st, conv),
776 parse_region_(st, conv))).as_predicate(),
777 'o' => ty::Binder(ty::OutlivesPredicate(parse_ty_(st, conv),
778 parse_region_(st, conv))).as_predicate(),
779 'p' => ty::Binder(parse_projection_predicate_(st, conv)).as_predicate(),
780 c => panic!("Encountered invalid character
in metadata
: {}
", c)
784 fn parse_projection_predicate_<'a,'tcx, F>(
785 st: &mut PState<'a, 'tcx>,
787 ) -> ty::ProjectionPredicate<'tcx> where
788 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
790 ty::ProjectionPredicate {
791 projection_ty: ty::ProjectionTy {
792 trait_ref: parse_trait_ref_(st, conv),
793 item_name: token::str_to_ident(&parse_str(st, '|')).name,
795 ty: parse_ty_(st, conv),
799 pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: uint,
800 crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>,
801 conv: F) -> ty::TypeParameterDef<'tcx> where
802 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
804 let mut st = parse_state_from_data(data, crate_num, start, tcx);
805 parse_type_param_def(&mut st, conv)
808 fn parse_type_param_def<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
809 -> ty::TypeParameterDef<'tcx> where
810 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
812 parse_type_param_def_(st, &mut conv)
815 fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
816 -> ty::TypeParameterDef<'tcx> where
817 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
819 let name = parse_name(st, ':');
820 let def_id = parse_def_(st, NominalType, conv);
821 let space = parse_param_space(st);
822 assert_eq!(next(st), '|');
823 let index = parse_u32(st);
824 assert_eq!(next(st), '|');
825 let bounds = parse_bounds_(st, conv);
826 let default = parse_opt(st, |st| parse_ty_(st, conv));
827 let object_lifetime_default = parse_object_lifetime_default(st, conv);
829 ty::TypeParameterDef {
836 object_lifetime_default: object_lifetime_default,
840 fn parse_object_lifetime_default<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
842 -> Option<ty::ObjectLifetimeDefault>
843 where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
847 'a' => Some(ty::ObjectLifetimeDefault::Ambiguous),
849 let region = parse_region_(st, conv);
850 Some(ty::ObjectLifetimeDefault::Specific(region))
852 _ => panic!("parse_object_lifetime_default
: bad input
")
856 fn parse_existential_bounds<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
858 -> ty::ExistentialBounds<'tcx> where
859 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
861 parse_existential_bounds_(st, &mut conv)
864 fn parse_existential_bounds_<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
866 -> ty::ExistentialBounds<'tcx> where
867 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
869 let ty::ParamBounds { trait_bounds, mut region_bounds, builtin_bounds, projection_bounds } =
870 parse_bounds_(st, conv);
871 assert_eq!(region_bounds.len(), 1);
872 assert_eq!(trait_bounds.len(), 0);
873 let region_bound = region_bounds.pop().unwrap();
874 return ty::ExistentialBounds { region_bound: region_bound,
875 builtin_bounds: builtin_bounds,
876 projection_bounds: projection_bounds };
879 fn parse_builtin_bounds<F>(st: &mut PState, mut _conv: F) -> ty::BuiltinBounds where
880 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
882 parse_builtin_bounds_(st, &mut _conv)
885 fn parse_builtin_bounds_<F>(st: &mut PState, _conv: &mut F) -> ty::BuiltinBounds where
886 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
888 let mut builtin_bounds = ty::empty_builtin_bounds();
893 builtin_bounds.insert(ty::BoundSend);
896 builtin_bounds.insert(ty::BoundSized);
899 builtin_bounds.insert(ty::BoundCopy);
902 builtin_bounds.insert(ty::BoundSync);
905 return builtin_bounds;
908 panic!("parse_bounds
: bad builtin
bounds ('{}'
)", c)
914 fn parse_bounds<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
915 -> ty::ParamBounds<'tcx> where
916 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
918 parse_bounds_(st, &mut conv)
921 fn parse_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
922 -> ty::ParamBounds<'tcx> where
923 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
925 let builtin_bounds = parse_builtin_bounds_(st, conv);
927 let mut param_bounds = ty::ParamBounds {
928 region_bounds: Vec::new(),
929 builtin_bounds: builtin_bounds,
930 trait_bounds: Vec::new(),
931 projection_bounds: Vec::new(),
936 param_bounds.region_bounds.push(
937 parse_region_(st, conv));
940 param_bounds.trait_bounds.push(
941 ty::Binder(parse_trait_ref_(st, conv)));
944 param_bounds.projection_bounds.push(
945 ty::Binder(parse_projection_predicate_(st, conv)));
951 panic!("parse_bounds
: bad
bounds ('{}'
)", c)