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.
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 an unboxed 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 range(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_trait_store_<F>(st: &mut PState, conv: &mut F) -> ty::TraitStore where
247 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
250 '~' => ty::UniqTraitStore,
251 '&' => ty::RegionTraitStore(parse_region_(st, conv), parse_mutability(st)),
253 st.tcx.sess.bug(format!("parse_trait_store(): bad input '{}'",
259 fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>,
261 -> VecPerParamSpace<T> where
262 F: FnMut(&mut PState<'a, 'tcx>) -> T,
264 let mut r = VecPerParamSpace::empty();
265 for &space in subst::ParamSpace::all().iter() {
266 assert_eq!(next(st), '[');
267 while peek(st) != ']' {
268 r.push(space, f(st));
270 assert_eq!(next(st), ']');
275 fn parse_substs<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
276 mut conv: F) -> subst::Substs<'tcx> where
277 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
279 parse_substs_(st, &mut conv)
282 fn parse_substs_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
283 conv: &mut F) -> subst::Substs<'tcx> where
284 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
287 parse_region_substs_(st, conv);
290 parse_vec_per_param_space(st, |st| parse_ty_(st, conv));
292 subst::Substs { types: types,
296 fn parse_region_substs_<F>(st: &mut PState, conv: &mut F) -> subst::RegionSubsts where
297 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
300 'e' => subst::ErasedRegions,
302 subst::NonerasedRegions(
303 parse_vec_per_param_space(
304 st, |st| parse_region_(st, conv)))
306 _ => panic!("parse_bound_region: bad input")
310 fn parse_bound_region_<F>(st: &mut PState, conv: &mut F) -> ty::BoundRegion where
311 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
315 let id = parse_u32(st);
316 assert_eq!(next(st), '|');
320 let def = parse_def_(st, RegionParameter, conv);
321 let ident = token::str_to_ident(parse_str(st, ']')[]);
322 ty::BrNamed(def, ident.name)
325 let id = parse_u32(st);
326 assert_eq!(next(st), '|');
330 _ => panic!("parse_bound_region: bad input")
334 fn parse_region<F>(st: &mut PState, mut conv: F) -> ty::Region where
335 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
337 parse_region_(st, &mut conv)
340 fn parse_region_<F>(st: &mut PState, conv: &mut F) -> ty::Region where
341 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
345 assert_eq!(next(st), '[');
346 let id = ty::DebruijnIndex::new(parse_u32(st));
347 assert_eq!(next(st), '|');
348 let br = parse_bound_region_(st, conv);
349 assert_eq!(next(st), ']');
350 ty::ReLateBound(id, br)
353 assert_eq!(next(st), '[');
354 let node_id = parse_uint(st) as ast::NodeId;
355 assert_eq!(next(st), '|');
356 let space = parse_param_space(st);
357 assert_eq!(next(st), '|');
358 let index = parse_u32(st);
359 assert_eq!(next(st), '|');
360 let nm = token::str_to_ident(parse_str(st, ']')[]);
361 ty::ReEarlyBound(node_id, space, index, nm.name)
364 assert_eq!(next(st), '[');
365 let scope = parse_scope(st);
366 assert_eq!(next(st), '|');
367 let br = parse_bound_region_(st, conv);
368 assert_eq!(next(st), ']');
369 ty::ReFree(ty::FreeRegion { scope: scope,
373 let scope = parse_scope(st);
374 assert_eq!(next(st), '|');
383 _ => panic!("parse_region: bad input")
387 fn parse_scope(st: &mut PState) -> region::CodeExtent {
390 let node_id = parse_uint(st) as ast::NodeId;
391 region::CodeExtent::Misc(node_id)
393 _ => panic!("parse_scope: bad input")
397 fn parse_opt<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, f: F) -> Option<T> where
398 F: FnOnce(&mut PState<'a, 'tcx>) -> T,
403 _ => panic!("parse_opt: bad input")
407 fn parse_str(st: &mut PState, term: char) -> String {
408 let mut result = String::new();
409 while peek(st) != term {
411 result.as_mut_vec().push_all(&[next_byte(st)])
418 fn parse_trait_ref<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
419 -> Rc<ty::TraitRef<'tcx>> where
420 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
422 parse_trait_ref_(st, &mut conv)
425 fn parse_trait_ref_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
426 -> Rc<ty::TraitRef<'tcx>> where
427 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
429 let def = parse_def_(st, NominalType, conv);
430 let substs = st.tcx.mk_substs(parse_substs_(st, conv));
431 Rc::new(ty::TraitRef {def_id: def, substs: substs})
434 fn parse_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F) -> Ty<'tcx> where
435 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
437 parse_ty_(st, &mut conv)
440 fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> where
441 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
445 'b' => return tcx.types.bool,
446 'i' => return tcx.types.int,
447 'u' => return tcx.types.uint,
450 'b' => return tcx.types.u8,
451 'w' => return tcx.types.u16,
452 'l' => return tcx.types.u32,
453 'd' => return tcx.types.u64,
454 'B' => return tcx.types.i8,
455 'W' => return tcx.types.i16,
456 'L' => return tcx.types.i32,
457 'D' => return tcx.types.i64,
458 'f' => return tcx.types.f32,
459 'F' => return tcx.types.f64,
460 _ => panic!("parse_ty: bad numeric type")
463 'c' => return tcx.types.char,
465 assert_eq!(next(st), '[');
466 let def = parse_def_(st, NominalType, conv);
467 let substs = parse_substs_(st, conv);
468 assert_eq!(next(st), ']');
469 return ty::mk_enum(tcx, def, st.tcx.mk_substs(substs));
472 assert_eq!(next(st), '[');
473 let trait_ref = ty::Binder(parse_trait_ref_(st, conv));
474 let bounds = parse_existential_bounds_(st, conv);
475 assert_eq!(next(st), ']');
476 return ty::mk_trait(tcx, trait_ref, bounds);
479 assert_eq!(next(st), '[');
480 let index = parse_u32(st);
481 assert_eq!(next(st), '|');
482 let space = parse_param_space(st);
483 assert_eq!(next(st), '|');
484 let name = token::intern(parse_str(st, ']')[]);
485 return ty::mk_param(tcx, space, index, name);
487 '~' => return ty::mk_uniq(tcx, parse_ty_(st, conv)),
488 '*' => return ty::mk_ptr(tcx, parse_mt_(st, conv)),
490 let r = parse_region_(st, conv);
491 let mt = parse_mt_(st, conv);
492 return ty::mk_rptr(tcx, tcx.mk_region(r), mt);
495 let t = parse_ty_(st, conv);
496 let sz = parse_size(st);
497 return ty::mk_vec(tcx, t, sz);
500 return ty::mk_str(tcx);
503 assert_eq!(next(st), '[');
504 let mut params = Vec::new();
505 while peek(st) != ']' { params.push(parse_ty_(st, conv)); }
506 st.pos = st.pos + 1u;
507 return ty::mk_tup(tcx, params);
510 let def_id = parse_def_(st, NominalType, conv);
511 return ty::mk_bare_fn(tcx, Some(def_id),
512 tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv)));
515 return ty::mk_bare_fn(tcx, None,
516 tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv)));
519 let pos = parse_hex(st);
520 assert_eq!(next(st), ':');
521 let len = parse_hex(st);
522 assert_eq!(next(st), '#');
523 let key = ty::creader_cache_key {cnum: st.krate,
527 match tcx.rcache.borrow().get(&key).cloned() {
528 Some(tt) => return tt,
531 let mut ps = PState {
535 let tt = parse_ty_(&mut ps, conv);
536 tcx.rcache.borrow_mut().insert(key, tt);
540 let _ = parse_def_(st, TypeWithId, conv);
541 let inner = parse_ty_(st, conv);
545 assert_eq!(next(st), '[');
546 let did = parse_def_(st, NominalType, conv);
547 let substs = parse_substs_(st, conv);
548 assert_eq!(next(st), ']');
549 return ty::mk_struct(st.tcx, did, st.tcx.mk_substs(substs));
552 assert_eq!(next(st), '[');
553 let did = parse_def_(st, UnboxedClosureSource, conv);
554 let region = parse_region_(st, conv);
555 let substs = parse_substs_(st, conv);
556 assert_eq!(next(st), ']');
557 return ty::mk_unboxed_closure(st.tcx, did,
558 st.tcx.mk_region(region), st.tcx.mk_substs(substs));
561 assert_eq!(next(st), '[');
562 let trait_ref = parse_trait_ref_(st, conv);
563 let name = token::intern(parse_str(st, ']').as_slice());
564 return ty::mk_projection(tcx, trait_ref, name);
567 return tcx.types.err;
569 c => { panic!("unexpected char in type string: {}", c);}
573 fn parse_mutability(st: &mut PState) -> ast::Mutability {
575 'm' => { next(st); ast::MutMutable }
576 _ => { ast::MutImmutable }
580 fn parse_mt_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::mt<'tcx> where
581 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
583 let m = parse_mutability(st);
584 ty::mt { ty: parse_ty_(st, conv), mutbl: m }
587 fn parse_def_<F>(st: &mut PState, source: DefIdSource, conv: &mut F) -> ast::DefId where
588 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
590 return (*conv)(source, scan(st, |c| { c == '|' }, parse_def_id));
593 fn parse_uint(st: &mut PState) -> uint {
597 if cur < '0' || cur > '9' { return n; }
598 st.pos = st.pos + 1u;
600 n += (cur as uint) - ('0' as uint);
604 fn parse_u32(st: &mut PState) -> u32 {
605 let n = parse_uint(st);
607 assert_eq!(m as uint, n);
611 fn parse_param_space(st: &mut PState) -> subst::ParamSpace {
612 subst::ParamSpace::from_uint(parse_uint(st))
615 fn parse_hex(st: &mut PState) -> uint {
619 if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; }
620 st.pos = st.pos + 1u;
622 if '0' <= cur && cur <= '9' {
623 n += (cur as uint) - ('0' as uint);
624 } else { n += 10u + (cur as uint) - ('a' as uint); }
628 fn parse_unsafety(c: char) -> ast::Unsafety {
630 'u' => ast::Unsafety::Unsafe,
631 'n' => ast::Unsafety::Normal,
632 _ => panic!("parse_unsafety: bad unsafety {}", c)
636 fn parse_abi_set(st: &mut PState) -> abi::Abi {
637 assert_eq!(next(st), '[');
638 scan(st, |c| c == ']', |bytes| {
639 let abi_str = str::from_utf8(bytes).unwrap();
640 abi::lookup(abi_str[]).expect(abi_str)
644 fn parse_onceness(c: char) -> ast::Onceness {
648 _ => panic!("parse_onceness: bad onceness")
652 fn parse_closure_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
653 mut conv: F) -> ty::ClosureTy<'tcx> where
654 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
656 parse_closure_ty_(st, &mut conv)
659 fn parse_closure_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
660 conv: &mut F) -> ty::ClosureTy<'tcx> where
661 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
663 let unsafety = parse_unsafety(next(st));
664 let onceness = parse_onceness(next(st));
665 let store = parse_trait_store_(st, conv);
666 let bounds = parse_existential_bounds_(st, conv);
667 let sig = parse_sig_(st, conv);
668 let abi = parse_abi_set(st);
679 fn parse_bare_fn_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
680 mut conv: F) -> ty::BareFnTy<'tcx> where
681 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
683 parse_bare_fn_ty_(st, &mut conv)
686 fn parse_bare_fn_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
687 conv: &mut F) -> ty::BareFnTy<'tcx> where
688 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
690 let unsafety = parse_unsafety(next(st));
691 let abi = parse_abi_set(st);
692 let sig = parse_sig_(st, conv);
700 fn parse_sig_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::PolyFnSig<'tcx> where
701 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
703 assert_eq!(next(st), '[');
704 let mut inputs = Vec::new();
705 while peek(st) != ']' {
706 inputs.push(parse_ty_(st, conv));
708 st.pos += 1u; // eat the ']'
709 let variadic = match next(st) {
712 r => panic!(format!("bad variadic: {}", r)),
714 let output = match peek(st) {
719 _ => ty::FnConverging(parse_ty_(st, conv))
721 ty::Binder(ty::FnSig {inputs: inputs,
726 // Rust metadata parsing
727 pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
728 let mut colon_idx = 0u;
730 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1u; }
731 if colon_idx == len {
732 error!("didn't find ':' when parsing def id");
736 let crate_part = buf[0u..colon_idx];
737 let def_part = buf[colon_idx + 1u..len];
739 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| s.parse::<uint>()) {
740 Some(cn) => cn as ast::CrateNum,
741 None => panic!("internal error: parse_def_id: crate number expected, found {}",
744 let def_num = match str::from_utf8(def_part).ok().and_then(|s| s.parse::<uint>()) {
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, '|').as_slice()).name,
801 ty: parse_ty_(st, conv),
805 pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: uint,
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 bounds = parse_bounds_(st, conv);
832 let default = parse_opt(st, |st| parse_ty_(st, conv));
834 ty::TypeParameterDef {
844 fn parse_existential_bounds<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
846 -> ty::ExistentialBounds<'tcx> where
847 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
849 parse_existential_bounds_(st, &mut conv)
852 fn parse_existential_bounds_<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
854 -> ty::ExistentialBounds<'tcx> where
855 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
857 let ty::ParamBounds { trait_bounds, mut region_bounds, builtin_bounds, projection_bounds } =
858 parse_bounds_(st, conv);
859 assert_eq!(region_bounds.len(), 1);
860 assert_eq!(trait_bounds.len(), 0);
861 let region_bound = region_bounds.pop().unwrap();
862 return ty::ExistentialBounds { region_bound: region_bound,
863 builtin_bounds: builtin_bounds,
864 projection_bounds: projection_bounds };
867 fn parse_builtin_bounds<F>(st: &mut PState, mut _conv: F) -> ty::BuiltinBounds where
868 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
870 parse_builtin_bounds_(st, &mut _conv)
873 fn parse_builtin_bounds_<F>(st: &mut PState, _conv: &mut F) -> ty::BuiltinBounds where
874 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
876 let mut builtin_bounds = ty::empty_builtin_bounds();
881 builtin_bounds.insert(ty::BoundSend);
884 builtin_bounds.insert(ty::BoundSized);
887 builtin_bounds.insert(ty::BoundCopy);
890 builtin_bounds.insert(ty::BoundSync);
893 return builtin_bounds;
896 panic!("parse_bounds: bad builtin bounds ('{}')", c)
902 fn parse_bounds<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
903 -> ty::ParamBounds<'tcx> where
904 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
906 parse_bounds_(st, &mut conv)
909 fn parse_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
910 -> ty::ParamBounds<'tcx> where
911 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
913 let builtin_bounds = parse_builtin_bounds_(st, conv);
915 let mut param_bounds = ty::ParamBounds {
916 region_bounds: Vec::new(),
917 builtin_bounds: builtin_bounds,
918 trait_bounds: Vec::new(),
919 projection_bounds: Vec::new(),
924 param_bounds.region_bounds.push(
925 parse_region_(st, conv));
928 param_bounds.trait_bounds.push(
929 ty::Binder(parse_trait_ref_(st, conv)));
932 param_bounds.projection_bounds.push(
933 ty::Binder(parse_projection_predicate_(st, conv)));
939 panic!("parse_bounds: bad bounds ('{}')", c)