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_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().iter() {
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_scope(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)
380 _ => panic!("parse_scope: bad input")
384 fn parse_opt<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, f: F) -> Option<T> where
385 F: FnOnce(&mut PState<'a, 'tcx>) -> T,
390 _ => panic!("parse_opt: bad input")
394 fn parse_str(st: &mut PState, term: char) -> String {
395 let mut result = String::new();
396 while peek(st) != term {
398 result.as_mut_vec().push_all(&[next_byte(st)])
405 fn parse_trait_ref<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
406 -> Rc<ty::TraitRef<'tcx>> where
407 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
409 parse_trait_ref_(st, &mut conv)
412 fn parse_trait_ref_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
413 -> Rc<ty::TraitRef<'tcx>> where
414 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
416 let def = parse_def_(st, NominalType, conv);
417 let substs = st.tcx.mk_substs(parse_substs_(st, conv));
418 Rc::new(ty::TraitRef {def_id: def, substs: substs})
421 fn parse_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F) -> Ty<'tcx> where
422 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
424 parse_ty_(st, &mut conv)
427 fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> where
428 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
432 'b' => return tcx.types.bool,
433 'i' => { /* eat the s of is */ next(st); return tcx.types.int },
434 'u' => { /* eat the s of us */ next(st); return tcx.types.uint },
437 'b' => return tcx.types.u8,
438 'w' => return tcx.types.u16,
439 'l' => return tcx.types.u32,
440 'd' => return tcx.types.u64,
441 'B' => return tcx.types.i8,
442 'W' => return tcx.types.i16,
443 'L' => return tcx.types.i32,
444 'D' => return tcx.types.i64,
445 'f' => return tcx.types.f32,
446 'F' => return tcx.types.f64,
447 _ => panic!("parse_ty: bad numeric type")
450 'c' => return tcx.types.char,
452 assert_eq!(next(st), '[');
453 let def = parse_def_(st, NominalType, conv);
454 let substs = parse_substs_(st, conv);
455 assert_eq!(next(st), ']');
456 return ty::mk_enum(tcx, def, st.tcx.mk_substs(substs));
459 assert_eq!(next(st), '[');
460 let trait_ref = ty::Binder(parse_trait_ref_(st, conv));
461 let bounds = parse_existential_bounds_(st, conv);
462 assert_eq!(next(st), ']');
463 return ty::mk_trait(tcx, trait_ref, bounds);
466 assert_eq!(next(st), '[');
467 let index = parse_u32(st);
468 assert_eq!(next(st), '|');
469 let space = parse_param_space(st);
470 assert_eq!(next(st), '|');
471 let name = token::intern(&parse_str(st, ']')[]);
472 return ty::mk_param(tcx, space, index, name);
474 '~' => return ty::mk_uniq(tcx, parse_ty_(st, conv)),
475 '*' => return ty::mk_ptr(tcx, parse_mt_(st, conv)),
477 let r = parse_region_(st, conv);
478 let mt = parse_mt_(st, conv);
479 return ty::mk_rptr(tcx, tcx.mk_region(r), mt);
482 let t = parse_ty_(st, conv);
483 let sz = parse_size(st);
484 return ty::mk_vec(tcx, t, sz);
487 return ty::mk_str(tcx);
490 assert_eq!(next(st), '[');
491 let mut params = Vec::new();
492 while peek(st) != ']' { params.push(parse_ty_(st, conv)); }
493 st.pos = st.pos + 1u;
494 return ty::mk_tup(tcx, params);
497 let def_id = parse_def_(st, NominalType, conv);
498 return ty::mk_bare_fn(tcx, Some(def_id),
499 tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv)));
502 return ty::mk_bare_fn(tcx, None,
503 tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv)));
506 let pos = parse_hex(st);
507 assert_eq!(next(st), ':');
508 let len = parse_hex(st);
509 assert_eq!(next(st), '#');
510 let key = ty::creader_cache_key {cnum: st.krate,
514 match tcx.rcache.borrow().get(&key).cloned() {
515 Some(tt) => return tt,
518 let mut ps = PState {
522 let tt = parse_ty_(&mut ps, conv);
523 tcx.rcache.borrow_mut().insert(key, tt);
527 let _ = parse_def_(st, TypeWithId, conv);
528 let inner = parse_ty_(st, conv);
532 assert_eq!(next(st), '[');
533 let did = parse_def_(st, NominalType, conv);
534 let substs = parse_substs_(st, conv);
535 assert_eq!(next(st), ']');
536 return ty::mk_struct(st.tcx, did, st.tcx.mk_substs(substs));
539 assert_eq!(next(st), '[');
540 let did = parse_def_(st, UnboxedClosureSource, conv);
541 let region = parse_region_(st, conv);
542 let substs = parse_substs_(st, conv);
543 assert_eq!(next(st), ']');
544 return ty::mk_unboxed_closure(st.tcx, did,
545 st.tcx.mk_region(region), st.tcx.mk_substs(substs));
548 assert_eq!(next(st), '[');
549 let trait_ref = parse_trait_ref_(st, conv);
550 let name = token::intern(parse_str(st, ']').as_slice());
551 return ty::mk_projection(tcx, trait_ref, name);
554 return tcx.types.err;
556 c => { panic!("unexpected char in type string: {}", c);}
560 fn parse_mutability(st: &mut PState) -> ast::Mutability {
562 'm' => { next(st); ast::MutMutable }
563 _ => { ast::MutImmutable }
567 fn parse_mt_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::mt<'tcx> where
568 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
570 let m = parse_mutability(st);
571 ty::mt { ty: parse_ty_(st, conv), mutbl: m }
574 fn parse_def_<F>(st: &mut PState, source: DefIdSource, conv: &mut F) -> ast::DefId where
575 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
577 return (*conv)(source, scan(st, |c| { c == '|' }, parse_def_id));
580 fn parse_uint(st: &mut PState) -> uint {
584 if cur < '0' || cur > '9' { return n; }
585 st.pos = st.pos + 1u;
587 n += (cur as uint) - ('0' as uint);
591 fn parse_u32(st: &mut PState) -> u32 {
592 let n = parse_uint(st);
594 assert_eq!(m as uint, n);
598 fn parse_param_space(st: &mut PState) -> subst::ParamSpace {
599 subst::ParamSpace::from_uint(parse_uint(st))
602 fn parse_hex(st: &mut PState) -> uint {
606 if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; }
607 st.pos = st.pos + 1u;
609 if '0' <= cur && cur <= '9' {
610 n += (cur as uint) - ('0' as uint);
611 } else { n += 10u + (cur as uint) - ('a' as uint); }
615 fn parse_unsafety(c: char) -> ast::Unsafety {
617 'u' => ast::Unsafety::Unsafe,
618 'n' => ast::Unsafety::Normal,
619 _ => panic!("parse_unsafety: bad unsafety {}", c)
623 fn parse_abi_set(st: &mut PState) -> abi::Abi {
624 assert_eq!(next(st), '[');
625 scan(st, |c| c == ']', |bytes| {
626 let abi_str = str::from_utf8(bytes).unwrap();
627 abi::lookup(&abi_str[]).expect(abi_str)
631 fn parse_closure_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
632 mut conv: F) -> ty::ClosureTy<'tcx> where
633 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
635 parse_closure_ty_(st, &mut conv)
638 fn parse_closure_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
639 conv: &mut F) -> ty::ClosureTy<'tcx> where
640 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
642 let unsafety = parse_unsafety(next(st));
643 let sig = parse_sig_(st, conv);
644 let abi = parse_abi_set(st);
652 fn parse_bare_fn_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
653 mut conv: F) -> ty::BareFnTy<'tcx> where
654 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
656 parse_bare_fn_ty_(st, &mut conv)
659 fn parse_bare_fn_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
660 conv: &mut F) -> ty::BareFnTy<'tcx> where
661 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
663 let unsafety = parse_unsafety(next(st));
664 let abi = parse_abi_set(st);
665 let sig = parse_sig_(st, conv);
673 fn parse_sig_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::PolyFnSig<'tcx> where
674 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
676 assert_eq!(next(st), '[');
677 let mut inputs = Vec::new();
678 while peek(st) != ']' {
679 inputs.push(parse_ty_(st, conv));
681 st.pos += 1u; // eat the ']'
682 let variadic = match next(st) {
685 r => panic!(format!("bad variadic: {}", r)),
687 let output = match peek(st) {
692 _ => ty::FnConverging(parse_ty_(st, conv))
694 ty::Binder(ty::FnSig {inputs: inputs,
699 // Rust metadata parsing
700 pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
701 let mut colon_idx = 0u;
703 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1u; }
704 if colon_idx == len {
705 error!("didn't find ':' when parsing def id");
709 let crate_part = &buf[0u..colon_idx];
710 let def_part = &buf[colon_idx + 1u..len];
712 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| s.parse::<uint>()) {
713 Some(cn) => cn as ast::CrateNum,
714 None => panic!("internal error: parse_def_id: crate number expected, found {:?}",
717 let def_num = match str::from_utf8(def_part).ok().and_then(|s| s.parse::<uint>()) {
718 Some(dn) => dn as ast::NodeId,
719 None => panic!("internal error: parse_def_id: id expected, found {:?}",
722 ast::DefId { krate: crate_num, node: def_num }
725 pub fn parse_predicate_data<'tcx, F>(data: &[u8],
727 crate_num: ast::CrateNum,
728 tcx: &ty::ctxt<'tcx>,
730 -> ty::Predicate<'tcx> where
731 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
733 let mut st = parse_state_from_data(data, crate_num, start, tcx);
734 parse_predicate(&mut st, conv)
737 pub fn parse_predicate<'a,'tcx, F>(st: &mut PState<'a, 'tcx>,
739 -> ty::Predicate<'tcx> where
740 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
742 parse_predicate_(st, &mut conv)
745 fn parse_predicate_<'a,'tcx, F>(st: &mut PState<'a, 'tcx>,
747 -> ty::Predicate<'tcx> where
748 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
751 't' => ty::Binder(parse_trait_ref_(st, conv)).as_predicate(),
752 'e' => ty::Binder(ty::EquatePredicate(parse_ty_(st, conv),
753 parse_ty_(st, conv))).as_predicate(),
754 'r' => ty::Binder(ty::OutlivesPredicate(parse_region_(st, conv),
755 parse_region_(st, conv))).as_predicate(),
756 'o' => ty::Binder(ty::OutlivesPredicate(parse_ty_(st, conv),
757 parse_region_(st, conv))).as_predicate(),
758 'p' => ty::Binder(parse_projection_predicate_(st, conv)).as_predicate(),
759 c => panic!("Encountered invalid character in metadata: {}", c)
763 fn parse_projection_predicate_<'a,'tcx, F>(
764 st: &mut PState<'a, 'tcx>,
766 ) -> ty::ProjectionPredicate<'tcx> where
767 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
769 ty::ProjectionPredicate {
770 projection_ty: ty::ProjectionTy {
771 trait_ref: parse_trait_ref_(st, conv),
772 item_name: token::str_to_ident(parse_str(st, '|').as_slice()).name,
774 ty: parse_ty_(st, conv),
778 pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: uint,
779 crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>,
780 conv: F) -> ty::TypeParameterDef<'tcx> where
781 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
783 let mut st = parse_state_from_data(data, crate_num, start, tcx);
784 parse_type_param_def(&mut st, conv)
787 fn parse_type_param_def<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
788 -> ty::TypeParameterDef<'tcx> where
789 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
791 parse_type_param_def_(st, &mut conv)
794 fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
795 -> ty::TypeParameterDef<'tcx> where
796 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
798 let name = parse_name(st, ':');
799 let def_id = parse_def_(st, NominalType, conv);
800 let space = parse_param_space(st);
801 assert_eq!(next(st), '|');
802 let index = parse_u32(st);
803 assert_eq!(next(st), '|');
804 let bounds = parse_bounds_(st, conv);
805 let default = parse_opt(st, |st| parse_ty_(st, conv));
807 ty::TypeParameterDef {
817 fn parse_existential_bounds<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
819 -> ty::ExistentialBounds<'tcx> where
820 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
822 parse_existential_bounds_(st, &mut conv)
825 fn parse_existential_bounds_<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
827 -> ty::ExistentialBounds<'tcx> where
828 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
830 let ty::ParamBounds { trait_bounds, mut region_bounds, builtin_bounds, projection_bounds } =
831 parse_bounds_(st, conv);
832 assert_eq!(region_bounds.len(), 1);
833 assert_eq!(trait_bounds.len(), 0);
834 let region_bound = region_bounds.pop().unwrap();
835 return ty::ExistentialBounds { region_bound: region_bound,
836 builtin_bounds: builtin_bounds,
837 projection_bounds: projection_bounds };
840 fn parse_builtin_bounds<F>(st: &mut PState, mut _conv: F) -> ty::BuiltinBounds where
841 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
843 parse_builtin_bounds_(st, &mut _conv)
846 fn parse_builtin_bounds_<F>(st: &mut PState, _conv: &mut F) -> ty::BuiltinBounds where
847 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
849 let mut builtin_bounds = ty::empty_builtin_bounds();
854 builtin_bounds.insert(ty::BoundSend);
857 builtin_bounds.insert(ty::BoundSized);
860 builtin_bounds.insert(ty::BoundCopy);
863 builtin_bounds.insert(ty::BoundSync);
866 return builtin_bounds;
869 panic!("parse_bounds: bad builtin bounds ('{}')", c)
875 fn parse_bounds<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
876 -> ty::ParamBounds<'tcx> where
877 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
879 parse_bounds_(st, &mut conv)
882 fn parse_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
883 -> ty::ParamBounds<'tcx> where
884 F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
886 let builtin_bounds = parse_builtin_bounds_(st, conv);
888 let mut param_bounds = ty::ParamBounds {
889 region_bounds: Vec::new(),
890 builtin_bounds: builtin_bounds,
891 trait_bounds: Vec::new(),
892 projection_bounds: Vec::new(),
897 param_bounds.region_bounds.push(
898 parse_region_(st, conv));
901 param_bounds.trait_bounds.push(
902 ty::Binder(parse_trait_ref_(st, conv)));
905 param_bounds.projection_bounds.push(
906 ty::Binder(parse_projection_predicate_(st, conv)));
912 panic!("parse_bounds: bad bounds ('{}')", c)