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::{mod, 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 #[deriving(Copy, Show)]
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 pub type conv_did<'a> =
65 |source: DefIdSource, ast::DefId|: 'a -> ast::DefId;
67 pub struct PState<'a, 'tcx: 'a> {
71 tcx: &'a ty::ctxt<'tcx>
74 fn peek(st: &PState) -> char {
75 st.data[st.pos] as char
78 fn next(st: &mut PState) -> char {
79 let ch = st.data[st.pos] as char;
84 fn next_byte(st: &mut PState) -> u8 {
85 let b = st.data[st.pos];
90 fn scan<R, F, G>(st: &mut PState, mut is_last: F, op: G) -> R where
91 F: FnMut(char) -> bool,
92 G: FnOnce(&[u8]) -> R,
94 let start_pos = st.pos;
95 debug!("scan: '{}' (start)", st.data[st.pos] as char);
96 while !is_last(st.data[st.pos] as char) {
98 debug!("scan: '{}'", st.data[st.pos] as char);
100 let end_pos = st.pos;
102 return op(st.data[start_pos..end_pos]);
105 pub fn parse_ident(st: &mut PState, last: char) -> ast::Ident {
106 ast::Ident::new(parse_name(st, last))
109 pub fn parse_name(st: &mut PState, last: char) -> ast::Name {
110 fn is_last(b: char, c: char) -> bool { return c == b; }
111 parse_name_(st, |a| is_last(last, a) )
114 fn parse_name_<F>(st: &mut PState, is_last: F) -> ast::Name where
115 F: FnMut(char) -> bool,
117 scan(st, is_last, |bytes| {
118 token::intern(str::from_utf8(bytes).unwrap())
122 pub fn parse_state_from_data<'a, 'tcx>(data: &'a [u8], crate_num: ast::CrateNum,
123 pos: uint, tcx: &'a ty::ctxt<'tcx>)
124 -> PState<'a, 'tcx> {
133 fn data_log_string(data: &[u8], pos: uint) -> String {
134 let mut buf = String::new();
136 for i in range(pos, data.len()) {
138 if c > 0x20 && c <= 0x7F {
148 pub fn parse_ty_closure_data<'tcx>(data: &[u8],
149 crate_num: ast::CrateNum,
151 tcx: &ty::ctxt<'tcx>,
153 -> ty::ClosureTy<'tcx> {
154 let mut st = parse_state_from_data(data, crate_num, pos, tcx);
155 parse_closure_ty(&mut st, conv)
158 pub fn parse_ty_data<'tcx>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
159 tcx: &ty::ctxt<'tcx>, conv: conv_did) -> Ty<'tcx> {
160 debug!("parse_ty_data {}", data_log_string(data, pos));
161 let mut st = parse_state_from_data(data, crate_num, pos, tcx);
162 parse_ty(&mut st, conv)
165 pub fn parse_region_data(data: &[u8], crate_num: ast::CrateNum, pos: uint, tcx: &ty::ctxt,
166 conv: conv_did) -> ty::Region {
167 debug!("parse_region_data {}", data_log_string(data, pos));
168 let mut st = parse_state_from_data(data, crate_num, pos, tcx);
169 parse_region(&mut st, conv)
172 pub fn parse_bare_fn_ty_data<'tcx>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
173 tcx: &ty::ctxt<'tcx>, conv: conv_did)
174 -> ty::BareFnTy<'tcx> {
175 debug!("parse_bare_fn_ty_data {}", data_log_string(data, pos));
176 let mut st = parse_state_from_data(data, crate_num, pos, tcx);
177 parse_bare_fn_ty(&mut st, conv)
180 pub fn parse_trait_ref_data<'tcx>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
181 tcx: &ty::ctxt<'tcx>, conv: conv_did)
182 -> Rc<ty::TraitRef<'tcx>> {
183 debug!("parse_trait_ref_data {}", data_log_string(data, pos));
184 let mut st = parse_state_from_data(data, crate_num, pos, tcx);
185 parse_trait_ref(&mut st, conv)
188 pub fn parse_substs_data<'tcx>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
189 tcx: &ty::ctxt<'tcx>, conv: conv_did) -> subst::Substs<'tcx> {
190 debug!("parse_substs_data {}", data_log_string(data, pos));
191 let mut st = parse_state_from_data(data, crate_num, pos, tcx);
192 parse_substs(&mut st, conv)
195 pub fn parse_bounds_data<'tcx>(data: &[u8], crate_num: ast::CrateNum,
196 pos: uint, tcx: &ty::ctxt<'tcx>, conv: conv_did)
197 -> ty::ParamBounds<'tcx> {
198 let mut st = parse_state_from_data(data, crate_num, pos, tcx);
199 parse_bounds(&mut st, conv)
202 pub fn parse_existential_bounds_data<'tcx>(data: &[u8], crate_num: ast::CrateNum,
203 pos: uint, tcx: &ty::ctxt<'tcx>, conv: conv_did)
204 -> ty::ExistentialBounds<'tcx> {
205 let mut st = parse_state_from_data(data, crate_num, pos, tcx);
206 parse_existential_bounds(&mut st, conv)
209 pub fn parse_builtin_bounds_data(data: &[u8], crate_num: ast::CrateNum,
210 pos: uint, tcx: &ty::ctxt, conv: conv_did)
211 -> ty::BuiltinBounds {
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<uint> {
217 assert_eq!(next(st), '/');
220 assert_eq!(next(st), '|');
223 let n = parse_uint(st);
224 assert_eq!(next(st), '|');
229 fn parse_trait_store(st: &mut PState, conv: conv_did) -> ty::TraitStore {
231 '~' => ty::UniqTraitStore,
232 '&' => ty::RegionTraitStore(parse_region(st, conv), parse_mutability(st)),
234 st.tcx.sess.bug(format!("parse_trait_store(): bad input '{}'",
240 fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>,
242 -> VecPerParamSpace<T> where
243 F: FnMut(&mut PState<'a, 'tcx>) -> T,
245 let mut r = VecPerParamSpace::empty();
246 for &space in subst::ParamSpace::all().iter() {
247 assert_eq!(next(st), '[');
248 while peek(st) != ']' {
249 r.push(space, f(st));
251 assert_eq!(next(st), ']');
256 fn parse_substs<'a, 'tcx>(st: &mut PState<'a, 'tcx>,
257 conv: conv_did) -> subst::Substs<'tcx> {
259 parse_region_substs(st, |x,y| conv(x,y));
262 parse_vec_per_param_space(st, |st| parse_ty(st, |x,y| conv(x,y)));
264 subst::Substs { types: types,
268 fn parse_region_substs(st: &mut PState, conv: conv_did) -> subst::RegionSubsts {
270 'e' => subst::ErasedRegions,
272 subst::NonerasedRegions(
273 parse_vec_per_param_space(
274 st, |st| parse_region(st, |x,y| conv(x,y))))
276 _ => panic!("parse_bound_region: bad input")
280 fn parse_bound_region(st: &mut PState, conv: conv_did) -> ty::BoundRegion {
283 let id = parse_u32(st);
284 assert_eq!(next(st), '|');
288 let def = parse_def(st, RegionParameter, |x,y| conv(x,y));
289 let ident = token::str_to_ident(parse_str(st, ']')[]);
290 ty::BrNamed(def, ident.name)
293 let id = parse_u32(st);
294 assert_eq!(next(st), '|');
298 _ => panic!("parse_bound_region: bad input")
302 fn parse_region(st: &mut PState, conv: conv_did) -> ty::Region {
305 assert_eq!(next(st), '[');
306 let id = ty::DebruijnIndex::new(parse_u32(st));
307 assert_eq!(next(st), '|');
308 let br = parse_bound_region(st, |x,y| conv(x,y));
309 assert_eq!(next(st), ']');
310 ty::ReLateBound(id, br)
313 assert_eq!(next(st), '[');
314 let node_id = parse_uint(st) as ast::NodeId;
315 assert_eq!(next(st), '|');
316 let space = parse_param_space(st);
317 assert_eq!(next(st), '|');
318 let index = parse_u32(st);
319 assert_eq!(next(st), '|');
320 let nm = token::str_to_ident(parse_str(st, ']')[]);
321 ty::ReEarlyBound(node_id, space, index, nm.name)
324 assert_eq!(next(st), '[');
325 let scope = parse_scope(st);
326 assert_eq!(next(st), '|');
327 let br = parse_bound_region(st, |x,y| conv(x,y));
328 assert_eq!(next(st), ']');
329 ty::ReFree(ty::FreeRegion { scope: scope,
333 let scope = parse_scope(st);
334 assert_eq!(next(st), '|');
343 _ => panic!("parse_region: bad input")
347 fn parse_scope(st: &mut PState) -> region::CodeExtent {
350 let node_id = parse_uint(st) as ast::NodeId;
351 region::CodeExtent::Misc(node_id)
353 _ => panic!("parse_scope: bad input")
357 fn parse_opt<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, f: F) -> Option<T> where
358 F: FnOnce(&mut PState<'a, 'tcx>) -> T,
363 _ => panic!("parse_opt: bad input")
367 fn parse_str(st: &mut PState, term: char) -> String {
368 let mut result = String::new();
369 while peek(st) != term {
371 result.as_mut_vec().push_all(&[next_byte(st)])
378 fn parse_trait_ref<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did)
379 -> Rc<ty::TraitRef<'tcx>> {
380 let def = parse_def(st, NominalType, |x,y| conv(x,y));
381 let substs = st.tcx.mk_substs(parse_substs(st, |x,y| conv(x,y)));
382 Rc::new(ty::TraitRef {def_id: def, substs: substs})
385 fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
388 'b' => return tcx.types.bool,
389 'i' => return tcx.types.int,
390 'u' => return tcx.types.uint,
393 'b' => return tcx.types.u8,
394 'w' => return tcx.types.u16,
395 'l' => return tcx.types.u32,
396 'd' => return tcx.types.u64,
397 'B' => return tcx.types.i8,
398 'W' => return tcx.types.i16,
399 'L' => return tcx.types.i32,
400 'D' => return tcx.types.i64,
401 'f' => return tcx.types.f32,
402 'F' => return tcx.types.f64,
403 _ => panic!("parse_ty: bad numeric type")
406 'c' => return tcx.types.char,
408 assert_eq!(next(st), '[');
409 let def = parse_def(st, NominalType, |x,y| conv(x,y));
410 let substs = parse_substs(st, |x,y| conv(x,y));
411 assert_eq!(next(st), ']');
412 return ty::mk_enum(tcx, def, st.tcx.mk_substs(substs));
415 assert_eq!(next(st), '[');
416 let trait_ref = ty::Binder(parse_trait_ref(st, |x,y| conv(x,y)));
417 let bounds = parse_existential_bounds(st, |x,y| conv(x,y));
418 assert_eq!(next(st), ']');
419 return ty::mk_trait(tcx, trait_ref, bounds);
422 assert_eq!(next(st), '[');
423 let index = parse_u32(st);
424 assert_eq!(next(st), '|');
425 let space = parse_param_space(st);
426 assert_eq!(next(st), '|');
427 let name = token::intern(parse_str(st, ']')[]);
428 return ty::mk_param(tcx, space, index, name);
430 '~' => return ty::mk_uniq(tcx, parse_ty(st, |x,y| conv(x,y))),
431 '*' => return ty::mk_ptr(tcx, parse_mt(st, |x,y| conv(x,y))),
433 let r = parse_region(st, |x,y| conv(x,y));
434 let mt = parse_mt(st, |x,y| conv(x,y));
435 return ty::mk_rptr(tcx, tcx.mk_region(r), mt);
438 let t = parse_ty(st, |x,y| conv(x,y));
439 let sz = parse_size(st);
440 return ty::mk_vec(tcx, t, sz);
443 return ty::mk_str(tcx);
446 assert_eq!(next(st), '[');
447 let mut params = Vec::new();
448 while peek(st) != ']' { params.push(parse_ty(st, |x,y| conv(x,y))); }
449 st.pos = st.pos + 1u;
450 return ty::mk_tup(tcx, params);
453 return ty::mk_closure(tcx, parse_closure_ty(st, |x,y| conv(x,y)));
456 let def_id = parse_def(st, NominalType, |x,y| conv(x,y));
457 return ty::mk_bare_fn(tcx, Some(def_id),
458 tcx.mk_bare_fn(parse_bare_fn_ty(st, |x,y| conv(x,y))));
461 return ty::mk_bare_fn(tcx, None,
462 tcx.mk_bare_fn(parse_bare_fn_ty(st, |x,y| conv(x,y))));
465 let pos = parse_hex(st);
466 assert_eq!(next(st), ':');
467 let len = parse_hex(st);
468 assert_eq!(next(st), '#');
469 let key = ty::creader_cache_key {cnum: st.krate,
473 match tcx.rcache.borrow().get(&key).cloned() {
474 Some(tt) => return tt,
477 let mut ps = PState {
481 let tt = parse_ty(&mut ps, |x,y| conv(x,y));
482 tcx.rcache.borrow_mut().insert(key, tt);
486 let _ = parse_def(st, TypeWithId, |x,y| conv(x,y));
487 let inner = parse_ty(st, |x,y| conv(x,y));
491 assert_eq!(next(st), '[');
492 let did = parse_def(st, NominalType, |x,y| conv(x,y));
493 let substs = parse_substs(st, |x,y| conv(x,y));
494 assert_eq!(next(st), ']');
495 return ty::mk_struct(st.tcx, did, st.tcx.mk_substs(substs));
498 assert_eq!(next(st), '[');
499 let did = parse_def(st, UnboxedClosureSource, |x,y| conv(x,y));
500 let region = parse_region(st, |x,y| conv(x,y));
501 let substs = parse_substs(st, |x,y| conv(x,y));
502 assert_eq!(next(st), ']');
503 return ty::mk_unboxed_closure(st.tcx, did,
504 st.tcx.mk_region(region), st.tcx.mk_substs(substs));
507 assert_eq!(next(st), '[');
508 let trait_ref = parse_trait_ref(st, |x,y| conv(x,y));
509 let name = token::intern(parse_str(st, ']').as_slice());
510 return ty::mk_projection(tcx, trait_ref, name);
513 return tcx.types.err;
515 c => { panic!("unexpected char in type string: {}", c);}
519 fn parse_mutability(st: &mut PState) -> ast::Mutability {
521 'm' => { next(st); ast::MutMutable }
522 _ => { ast::MutImmutable }
526 fn parse_mt<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> ty::mt<'tcx> {
527 let m = parse_mutability(st);
528 ty::mt { ty: parse_ty(st, |x,y| conv(x,y)), mutbl: m }
531 fn parse_def(st: &mut PState, source: DefIdSource,
532 conv: conv_did) -> ast::DefId {
533 return conv(source, scan(st, |c| { c == '|' }, parse_def_id));
536 fn parse_uint(st: &mut PState) -> uint {
540 if cur < '0' || cur > '9' { return n; }
541 st.pos = st.pos + 1u;
543 n += (cur as uint) - ('0' as uint);
547 fn parse_u32(st: &mut PState) -> u32 {
548 let n = parse_uint(st);
550 assert_eq!(m as uint, n);
554 fn parse_param_space(st: &mut PState) -> subst::ParamSpace {
555 subst::ParamSpace::from_uint(parse_uint(st))
558 fn parse_hex(st: &mut PState) -> uint {
562 if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; }
563 st.pos = st.pos + 1u;
565 if '0' <= cur && cur <= '9' {
566 n += (cur as uint) - ('0' as uint);
567 } else { n += 10u + (cur as uint) - ('a' as uint); }
571 fn parse_unsafety(c: char) -> ast::Unsafety {
573 'u' => ast::Unsafety::Unsafe,
574 'n' => ast::Unsafety::Normal,
575 _ => panic!("parse_unsafety: bad unsafety {}", c)
579 fn parse_abi_set(st: &mut PState) -> abi::Abi {
580 assert_eq!(next(st), '[');
581 scan(st, |c| c == ']', |bytes| {
582 let abi_str = str::from_utf8(bytes).unwrap();
583 abi::lookup(abi_str[]).expect(abi_str)
587 fn parse_onceness(c: char) -> ast::Onceness {
591 _ => panic!("parse_onceness: bad onceness")
595 fn parse_closure_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>,
596 conv: conv_did) -> ty::ClosureTy<'tcx> {
597 let unsafety = parse_unsafety(next(st));
598 let onceness = parse_onceness(next(st));
599 let store = parse_trait_store(st, |x,y| conv(x,y));
600 let bounds = parse_existential_bounds(st, |x,y| conv(x,y));
601 let sig = parse_sig(st, |x,y| conv(x,y));
602 let abi = parse_abi_set(st);
613 fn parse_bare_fn_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>,
614 conv: conv_did) -> ty::BareFnTy<'tcx> {
615 let unsafety = parse_unsafety(next(st));
616 let abi = parse_abi_set(st);
617 let sig = parse_sig(st, |x,y| conv(x,y));
625 fn parse_sig<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> ty::PolyFnSig<'tcx> {
626 assert_eq!(next(st), '[');
627 let mut inputs = Vec::new();
628 while peek(st) != ']' {
629 inputs.push(parse_ty(st, |x,y| conv(x,y)));
631 st.pos += 1u; // eat the ']'
632 let variadic = match next(st) {
635 r => panic!(format!("bad variadic: {}", r)),
637 let output = match peek(st) {
642 _ => ty::FnConverging(parse_ty(st, |x,y| conv(x,y)))
644 ty::Binder(ty::FnSig {inputs: inputs,
649 // Rust metadata parsing
650 pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
651 let mut colon_idx = 0u;
653 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1u; }
654 if colon_idx == len {
655 error!("didn't find ':' when parsing def id");
659 let crate_part = buf[0u..colon_idx];
660 let def_part = buf[colon_idx + 1u..len];
662 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| s.parse::<uint>()) {
663 Some(cn) => cn as ast::CrateNum,
664 None => panic!("internal error: parse_def_id: crate number expected, found {}",
667 let def_num = match str::from_utf8(def_part).ok().and_then(|s| s.parse::<uint>()) {
668 Some(dn) => dn as ast::NodeId,
669 None => panic!("internal error: parse_def_id: id expected, found {}",
672 ast::DefId { krate: crate_num, node: def_num }
675 pub fn parse_predicate_data<'tcx>(data: &[u8],
677 crate_num: ast::CrateNum,
678 tcx: &ty::ctxt<'tcx>,
680 -> ty::Predicate<'tcx>
682 let mut st = parse_state_from_data(data, crate_num, start, tcx);
683 parse_predicate(&mut st, conv)
686 pub fn parse_predicate<'a,'tcx>(st: &mut PState<'a, 'tcx>,
688 -> ty::Predicate<'tcx>
691 't' => ty::Binder(parse_trait_ref(st, conv)).as_predicate(),
692 'e' => ty::Binder(ty::EquatePredicate(parse_ty(st, |x,y| conv(x,y)),
693 parse_ty(st, |x,y| conv(x,y)))).as_predicate(),
694 'r' => ty::Binder(ty::OutlivesPredicate(parse_region(st, |x,y| conv(x,y)),
695 parse_region(st, |x,y| conv(x,y)))).as_predicate(),
696 'o' => ty::Binder(ty::OutlivesPredicate(parse_ty(st, |x,y| conv(x,y)),
697 parse_region(st, |x,y| conv(x,y)))).as_predicate(),
698 'p' => ty::Binder(parse_projection_predicate(st, conv)).as_predicate(),
699 c => panic!("Encountered invalid character in metadata: {}", c)
703 fn parse_projection_predicate<'a,'tcx>(
704 st: &mut PState<'a, 'tcx>,
706 -> ty::ProjectionPredicate<'tcx>
708 ty::ProjectionPredicate {
709 projection_ty: ty::ProjectionTy {
710 trait_ref: parse_trait_ref(st, |x,y| conv(x,y)),
711 item_name: token::str_to_ident(parse_str(st, '|').as_slice()).name,
713 ty: parse_ty(st, |x,y| conv(x,y)),
717 pub fn parse_type_param_def_data<'tcx>(data: &[u8], start: uint,
718 crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>,
719 conv: conv_did) -> ty::TypeParameterDef<'tcx>
721 let mut st = parse_state_from_data(data, crate_num, start, tcx);
722 parse_type_param_def(&mut st, conv)
725 fn parse_type_param_def<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did)
726 -> ty::TypeParameterDef<'tcx> {
727 let name = parse_name(st, ':');
728 let def_id = parse_def(st, NominalType, |x,y| conv(x,y));
729 let space = parse_param_space(st);
730 assert_eq!(next(st), '|');
731 let index = parse_u32(st);
732 assert_eq!(next(st), '|');
733 let bounds = parse_bounds(st, |x,y| conv(x,y));
734 let default = parse_opt(st, |st| parse_ty(st, |x,y| conv(x,y)));
736 ty::TypeParameterDef {
746 fn parse_existential_bounds<'a,'tcx>(st: &mut PState<'a,'tcx>,
748 -> ty::ExistentialBounds<'tcx>
750 let ty::ParamBounds { trait_bounds, mut region_bounds, builtin_bounds, projection_bounds } =
751 parse_bounds(st, conv);
752 assert_eq!(region_bounds.len(), 1);
753 assert_eq!(trait_bounds.len(), 0);
754 let region_bound = region_bounds.pop().unwrap();
755 return ty::ExistentialBounds { region_bound: region_bound,
756 builtin_bounds: builtin_bounds,
757 projection_bounds: projection_bounds };
760 fn parse_builtin_bounds(st: &mut PState, _conv: conv_did) -> ty::BuiltinBounds {
761 let mut builtin_bounds = ty::empty_builtin_bounds();
766 builtin_bounds.insert(ty::BoundSend);
769 builtin_bounds.insert(ty::BoundSized);
772 builtin_bounds.insert(ty::BoundCopy);
775 builtin_bounds.insert(ty::BoundSync);
778 return builtin_bounds;
781 panic!("parse_bounds: bad builtin bounds ('{}')", c)
787 fn parse_bounds<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did)
788 -> ty::ParamBounds<'tcx> {
789 let builtin_bounds = parse_builtin_bounds(st, |x,y| conv(x,y));
791 let mut param_bounds = ty::ParamBounds {
792 region_bounds: Vec::new(),
793 builtin_bounds: builtin_bounds,
794 trait_bounds: Vec::new(),
795 projection_bounds: Vec::new(),
800 param_bounds.region_bounds.push(
801 parse_region(st, |x, y| conv (x, y)));
804 param_bounds.trait_bounds.push(
805 ty::Binder(parse_trait_ref(st, |x,y| conv(x,y))));
808 param_bounds.projection_bounds.push(
809 ty::Binder(parse_projection_predicate(st, |x,y| conv(x,y))));
815 panic!("parse_bounds: bad bounds ('{}')", c)