]> git.proxmox.com Git - rustc.git/blame - src/librustc/metadata/tydecode.rs
Imported Upstream version 1.5.0+dfsg1
[rustc.git] / src / librustc / metadata / tydecode.rs
CommitLineData
1a4d82fc 1// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
223e47cc
LB
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
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.
10
11
12// Type decoding
13
14// tjc note: Would be great to have a `match check` macro equivalent
15// for some of these
16
1a4d82fc 17#![allow(non_camel_case_types)]
223e47cc 18
e9174d1e
SL
19use rustc_front::hir;
20
b039eaaf 21use middle::def_id::{DefId, DefIndex};
1a4d82fc
JJ
22use middle::region;
23use middle::subst;
24use middle::subst::VecPerParamSpace;
c1a9b12d 25use middle::ty::{self, ToPredicate, Ty, HasTypeFlags};
1a4d82fc 26
e9174d1e 27use rbml;
970d7e83 28use std::str;
223e47cc
LB
29use syntax::abi;
30use syntax::ast;
1a4d82fc 31use syntax::parse::token;
223e47cc 32
62682a34 33// Compact string representation for Ty values. API TyStr &
223e47cc
LB
34// parse_from_str. Extra parameters are for converting to/from def_ids in the
35// data buffer. Whatever format you choose should not contain pipe characters.
36
b039eaaf 37pub type DefIdConvert<'a> = &'a mut FnMut(DefId) -> DefId;
1a4d82fc 38
e9174d1e 39pub struct TyDecoder<'a, 'tcx: 'a> {
1a4d82fc
JJ
40 data: &'a [u8],
41 krate: ast::CrateNum,
c34b1796 42 pos: usize,
e9174d1e
SL
43 tcx: &'a ty::ctxt<'tcx>,
44 conv_def_id: DefIdConvert<'a>,
223e47cc
LB
45}
46
e9174d1e
SL
47impl<'a,'tcx> TyDecoder<'a,'tcx> {
48 pub fn with_doc(tcx: &'a ty::ctxt<'tcx>,
49 crate_num: ast::CrateNum,
50 doc: rbml::Doc<'a>,
51 conv: DefIdConvert<'a>)
52 -> TyDecoder<'a,'tcx> {
53 TyDecoder::new(doc.data, crate_num, doc.start, tcx, conv)
54 }
223e47cc 55
e9174d1e
SL
56 pub fn new(data: &'a [u8],
57 crate_num: ast::CrateNum,
58 pos: usize,
59 tcx: &'a ty::ctxt<'tcx>,
60 conv: DefIdConvert<'a>)
61 -> TyDecoder<'a, 'tcx> {
62 TyDecoder {
63 data: data,
64 krate: crate_num,
65 pos: pos,
66 tcx: tcx,
67 conv_def_id: conv,
68 }
69 }
1a4d82fc 70
e9174d1e
SL
71 fn peek(&self) -> char {
72 self.data[self.pos] as char
73 }
223e47cc 74
e9174d1e
SL
75 fn next(&mut self) -> char {
76 let ch = self.data[self.pos] as char;
77 self.pos = self.pos + 1;
78 return ch;
79 }
223e47cc 80
e9174d1e
SL
81 fn next_byte(&mut self) -> u8 {
82 let b = self.data[self.pos];
83 self.pos = self.pos + 1;
84 return b;
223e47cc 85 }
223e47cc 86
e9174d1e
SL
87 fn scan<F>(&mut self, mut is_last: F) -> &'a [u8]
88 where F: FnMut(char) -> bool,
89 {
90 let start_pos = self.pos;
91 debug!("scan: '{}' (start)", self.data[self.pos] as char);
92 while !is_last(self.data[self.pos] as char) {
93 self.pos += 1;
94 debug!("scan: '{}'", self.data[self.pos] as char);
1a4d82fc 95 }
e9174d1e
SL
96 let end_pos = self.pos;
97 self.pos += 1;
98 return &self.data[start_pos..end_pos];
1a4d82fc 99 }
1a4d82fc 100
b039eaaf
SL
101 fn parse_vuint(&mut self) -> usize {
102 let res = rbml::reader::vuint_at(self.data, self.pos).unwrap();
103 self.pos = res.next;
104 res.val
105 }
106
e9174d1e
SL
107 fn parse_name(&mut self, last: char) -> ast::Name {
108 fn is_last(b: char, c: char) -> bool { return c == b; }
109 let bytes = self.scan(|a| is_last(last, a));
110 token::intern(str::from_utf8(bytes).unwrap())
111 }
223e47cc 112
e9174d1e
SL
113 fn parse_size(&mut self) -> Option<usize> {
114 assert_eq!(self.next(), '/');
1a4d82fc 115
e9174d1e
SL
116 if self.peek() == '|' {
117 assert_eq!(self.next(), '|');
118 None
119 } else {
120 let n = self.parse_uint();
121 assert_eq!(self.next(), '|');
122 Some(n)
123 }
124 }
223e47cc 125
e9174d1e
SL
126 fn parse_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
127 F: FnMut(&mut TyDecoder<'a, 'tcx>) -> T,
128 {
129 let mut r = VecPerParamSpace::empty();
130 for &space in &subst::ParamSpace::all() {
131 assert_eq!(self.next(), '[');
132 while self.peek() != ']' {
133 r.push(space, f(self));
134 }
135 assert_eq!(self.next(), ']');
136 }
137 r
138 }
970d7e83 139
e9174d1e
SL
140 pub fn parse_substs(&mut self) -> subst::Substs<'tcx> {
141 let regions = self.parse_region_substs();
142 let types = self.parse_vec_per_param_space(|this| this.parse_ty());
143 subst::Substs { types: types, regions: regions }
144 }
223e47cc 145
e9174d1e
SL
146 fn parse_region_substs(&mut self) -> subst::RegionSubsts {
147 match self.next() {
148 'e' => subst::ErasedRegions,
149 'n' => {
150 subst::NonerasedRegions(
151 self.parse_vec_per_param_space(|this| this.parse_region()))
152 }
153 _ => panic!("parse_bound_region: bad input")
154 }
155 }
223e47cc 156
e9174d1e
SL
157 fn parse_bound_region(&mut self) -> ty::BoundRegion {
158 match self.next() {
159 'a' => {
160 let id = self.parse_u32();
161 assert_eq!(self.next(), '|');
162 ty::BrAnon(id)
163 }
164 '[' => {
b039eaaf
SL
165 let def = self.parse_def();
166 let name = token::intern(&self.parse_str(']'));
167 ty::BrNamed(def, name)
e9174d1e
SL
168 }
169 'f' => {
170 let id = self.parse_u32();
171 assert_eq!(self.next(), '|');
172 ty::BrFresh(id)
173 }
174 'e' => ty::BrEnv,
175 _ => panic!("parse_bound_region: bad input")
176 }
177 }
1a4d82fc 178
e9174d1e
SL
179 pub fn parse_region(&mut self) -> ty::Region {
180 match self.next() {
181 'b' => {
182 assert_eq!(self.next(), '[');
183 let id = ty::DebruijnIndex::new(self.parse_u32());
184 assert_eq!(self.next(), '|');
185 let br = self.parse_bound_region();
186 assert_eq!(self.next(), ']');
187 ty::ReLateBound(id, br)
188 }
189 'B' => {
190 assert_eq!(self.next(), '[');
b039eaaf 191 let def_id = self.parse_def();
e9174d1e
SL
192 let space = self.parse_param_space();
193 assert_eq!(self.next(), '|');
194 let index = self.parse_u32();
195 assert_eq!(self.next(), '|');
b039eaaf 196 let name = token::intern(&self.parse_str(']'));
e9174d1e 197 ty::ReEarlyBound(ty::EarlyBoundRegion {
b039eaaf 198 def_id: def_id,
e9174d1e
SL
199 space: space,
200 index: index,
b039eaaf 201 name: name
e9174d1e
SL
202 })
203 }
204 'f' => {
205 assert_eq!(self.next(), '[');
206 let scope = self.parse_scope();
207 assert_eq!(self.next(), '|');
208 let br = self.parse_bound_region();
209 assert_eq!(self.next(), ']');
210 ty::ReFree(ty::FreeRegion { scope: scope,
211 bound_region: br})
212 }
213 's' => {
214 let scope = self.parse_scope();
215 assert_eq!(self.next(), '|');
216 ty::ReScope(scope)
217 }
218 't' => {
219 ty::ReStatic
220 }
221 'e' => {
222 ty::ReStatic
223 }
224 _ => panic!("parse_region: bad input")
225 }
226 }
223e47cc 227
e9174d1e
SL
228 fn parse_scope(&mut self) -> region::CodeExtent {
229 self.tcx.region_maps.bogus_code_extent(match self.next() {
230 // This creates scopes with the wrong NodeId. This isn't
231 // actually a problem because scopes only exist *within*
232 // functions, and functions aren't loaded until trans which
233 // doesn't care about regions.
234 //
235 // May still be worth fixing though.
236 'P' => {
237 assert_eq!(self.next(), '[');
238 let fn_id = self.parse_uint() as ast::NodeId;
239 assert_eq!(self.next(), '|');
240 let body_id = self.parse_uint() as ast::NodeId;
241 assert_eq!(self.next(), ']');
242 region::CodeExtentData::ParameterScope {
243 fn_id: fn_id, body_id: body_id
244 }
245 }
246 'M' => {
247 let node_id = self.parse_uint() as ast::NodeId;
248 region::CodeExtentData::Misc(node_id)
249 }
250 'D' => {
251 let node_id = self.parse_uint() as ast::NodeId;
252 region::CodeExtentData::DestructionScope(node_id)
253 }
254 'B' => {
255 assert_eq!(self.next(), '[');
256 let node_id = self.parse_uint() as ast::NodeId;
257 assert_eq!(self.next(), '|');
258 let first_stmt_index = self.parse_u32();
259 assert_eq!(self.next(), ']');
260 let block_remainder = region::BlockRemainder {
261 block: node_id, first_statement_index: first_stmt_index,
262 };
263 region::CodeExtentData::Remainder(block_remainder)
264 }
265 _ => panic!("parse_scope: bad input")
266 })
223e47cc
LB
267 }
268
e9174d1e
SL
269 fn parse_opt<T, F>(&mut self, f: F) -> Option<T>
270 where F: FnOnce(&mut TyDecoder<'a, 'tcx>) -> T,
271 {
272 match self.next() {
273 'n' => None,
274 's' => Some(f(self)),
275 _ => panic!("parse_opt: bad input")
1a4d82fc 276 }
223e47cc 277 }
223e47cc 278
e9174d1e
SL
279 fn parse_str(&mut self, term: char) -> String {
280 let mut result = String::new();
281 while self.peek() != term {
282 unsafe {
283 result.as_mut_vec().push_all(&[self.next_byte()])
284 }
285 }
286 self.next();
287 result
288 }
223e47cc 289
e9174d1e 290 pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> {
b039eaaf 291 let def = self.parse_def();
e9174d1e
SL
292 let substs = self.tcx.mk_substs(self.parse_substs());
293 ty::TraitRef {def_id: def, substs: substs}
294 }
223e47cc 295
e9174d1e
SL
296 pub fn parse_ty(&mut self) -> Ty<'tcx> {
297 let tcx = self.tcx;
298 match self.next() {
299 'b' => return tcx.types.bool,
300 'i' => { /* eat the s of is */ self.next(); return tcx.types.isize },
301 'u' => { /* eat the s of us */ self.next(); return tcx.types.usize },
302 'M' => {
303 match self.next() {
304 'b' => return tcx.types.u8,
305 'w' => return tcx.types.u16,
306 'l' => return tcx.types.u32,
307 'd' => return tcx.types.u64,
308 'B' => return tcx.types.i8,
309 'W' => return tcx.types.i16,
310 'L' => return tcx.types.i32,
311 'D' => return tcx.types.i64,
312 'f' => return tcx.types.f32,
313 'F' => return tcx.types.f64,
314 _ => panic!("parse_ty: bad numeric type")
315 }
316 }
317 'c' => return tcx.types.char,
318 't' => {
319 assert_eq!(self.next(), '[');
b039eaaf 320 let did = self.parse_def();
e9174d1e
SL
321 let substs = self.parse_substs();
322 assert_eq!(self.next(), ']');
323 let def = self.tcx.lookup_adt_def(did);
324 return tcx.mk_enum(def, self.tcx.mk_substs(substs));
325 }
326 'x' => {
327 assert_eq!(self.next(), '[');
328 let trait_ref = ty::Binder(self.parse_trait_ref());
329 let bounds = self.parse_existential_bounds();
330 assert_eq!(self.next(), ']');
331 return tcx.mk_trait(trait_ref, bounds);
332 }
333 'p' => {
334 assert_eq!(self.next(), '[');
335 let index = self.parse_u32();
336 assert_eq!(self.next(), '|');
337 let space = self.parse_param_space();
338 assert_eq!(self.next(), '|');
339 let name = token::intern(&self.parse_str(']'));
340 return tcx.mk_param(space, index, name);
341 }
342 '~' => return tcx.mk_box(self.parse_ty()),
343 '*' => return tcx.mk_ptr(self.parse_mt()),
344 '&' => {
345 let r = self.parse_region();
346 let mt = self.parse_mt();
347 return tcx.mk_ref(tcx.mk_region(r), mt);
348 }
349 'V' => {
350 let t = self.parse_ty();
351 return match self.parse_size() {
352 Some(n) => tcx.mk_array(t, n),
353 None => tcx.mk_slice(t)
354 };
355 }
356 'v' => {
357 return tcx.mk_str();
358 }
359 'T' => {
360 assert_eq!(self.next(), '[');
361 let mut params = Vec::new();
362 while self.peek() != ']' { params.push(self.parse_ty()); }
363 self.pos = self.pos + 1;
364 return tcx.mk_tup(params);
365 }
366 'F' => {
b039eaaf 367 let def_id = self.parse_def();
e9174d1e
SL
368 return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(self.parse_bare_fn_ty()));
369 }
370 'G' => {
371 return tcx.mk_fn(None, tcx.mk_bare_fn(self.parse_bare_fn_ty()));
372 }
373 '#' => {
374 // This is a hacky little caching scheme. The idea is that if we encode
375 // the same type twice, the second (and third, and fourth...) time we will
376 // just write `#123`, where `123` is the offset in the metadata of the
377 // first appearance. Now when we are *decoding*, if we see a `#123`, we
378 // can first check a cache (`tcx.rcache`) for that offset. If we find something,
379 // we return it (modulo closure types, see below). But if not, then we
380 // jump to offset 123 and read the type from there.
381
b039eaaf
SL
382 let pos = self.parse_vuint();
383 let key = ty::CReaderCacheKey { cnum: self.krate, pos: pos };
e9174d1e
SL
384 match tcx.rcache.borrow().get(&key).cloned() {
385 Some(tt) => {
386 // If there is a closure buried in the type some where, then we
387 // need to re-convert any def ids (see case 'k', below). That means
388 // we can't reuse the cached version.
389 if !tt.has_closure_types() {
390 return tt;
391 }
392 }
393 None => {}
394 }
223e47cc 395
e9174d1e
SL
396 let mut substate = TyDecoder::new(self.data,
397 self.krate,
398 pos,
399 self.tcx,
400 self.conv_def_id);
401 let tt = substate.parse_ty();
402 tcx.rcache.borrow_mut().insert(key, tt);
403 return tt;
404 }
405 '\"' => {
b039eaaf 406 let _ = self.parse_def();
e9174d1e
SL
407 let inner = self.parse_ty();
408 inner
409 }
410 'a' => {
411 assert_eq!(self.next(), '[');
b039eaaf 412 let did = self.parse_def();
e9174d1e
SL
413 let substs = self.parse_substs();
414 assert_eq!(self.next(), ']');
415 let def = self.tcx.lookup_adt_def(did);
416 return self.tcx.mk_struct(def, self.tcx.mk_substs(substs));
417 }
418 'k' => {
419 assert_eq!(self.next(), '[');
b039eaaf 420 let did = self.parse_def();
e9174d1e
SL
421 let substs = self.parse_substs();
422 let mut tys = vec![];
423 while self.peek() != '.' {
424 tys.push(self.parse_ty());
425 }
426 assert_eq!(self.next(), '.');
427 assert_eq!(self.next(), ']');
428 return self.tcx.mk_closure(did, self.tcx.mk_substs(substs), tys);
429 }
430 'P' => {
431 assert_eq!(self.next(), '[');
432 let trait_ref = self.parse_trait_ref();
433 let name = token::intern(&self.parse_str(']'));
434 return tcx.mk_projection(trait_ref, name);
435 }
436 'e' => {
437 return tcx.types.err;
438 }
439 c => { panic!("unexpected char in type string: {}", c);}
1a4d82fc 440 }
1a4d82fc 441 }
1a4d82fc 442
e9174d1e
SL
443 fn parse_mutability(&mut self) -> hir::Mutability {
444 match self.peek() {
445 'm' => { self.next(); hir::MutMutable }
446 _ => { hir::MutImmutable }
1a4d82fc 447 }
223e47cc 448 }
223e47cc 449
e9174d1e
SL
450 fn parse_mt(&mut self) -> ty::TypeAndMut<'tcx> {
451 let m = self.parse_mutability();
452 ty::TypeAndMut { ty: self.parse_ty(), mutbl: m }
453 }
1a4d82fc 454
b039eaaf 455 fn parse_def(&mut self) -> DefId {
e9174d1e 456 let def_id = parse_defid(self.scan(|c| c == '|'));
b039eaaf 457 return (self.conv_def_id)(def_id);
223e47cc 458 }
223e47cc 459
e9174d1e
SL
460 fn parse_uint(&mut self) -> usize {
461 let mut n = 0;
462 loop {
463 let cur = self.peek();
464 if cur < '0' || cur > '9' { return n; }
465 self.pos = self.pos + 1;
466 n *= 10;
467 n += (cur as usize) - ('0' as usize);
468 };
1a4d82fc 469 }
1a4d82fc 470
e9174d1e
SL
471 fn parse_u32(&mut self) -> u32 {
472 let n = self.parse_uint();
473 let m = n as u32;
474 assert_eq!(m as usize, n);
475 m
476 }
85aaf69f 477
e9174d1e
SL
478 fn parse_param_space(&mut self) -> subst::ParamSpace {
479 subst::ParamSpace::from_uint(self.parse_uint())
223e47cc 480 }
223e47cc 481
e9174d1e
SL
482 fn parse_abi_set(&mut self) -> abi::Abi {
483 assert_eq!(self.next(), '[');
484 let bytes = self.scan(|c| c == ']');
485 let abi_str = str::from_utf8(bytes).unwrap();
486 abi::lookup(&abi_str[..]).expect(abi_str)
487 }
1a4d82fc 488
e9174d1e
SL
489 pub fn parse_closure_ty(&mut self) -> ty::ClosureTy<'tcx> {
490 let unsafety = parse_unsafety(self.next());
491 let sig = self.parse_sig();
492 let abi = self.parse_abi_set();
493 ty::ClosureTy {
494 unsafety: unsafety,
495 sig: sig,
496 abi: abi,
497 }
498 }
223e47cc 499
e9174d1e
SL
500 pub fn parse_bare_fn_ty(&mut self) -> ty::BareFnTy<'tcx> {
501 let unsafety = parse_unsafety(self.next());
502 let abi = self.parse_abi_set();
503 let sig = self.parse_sig();
504 ty::BareFnTy {
505 unsafety: unsafety,
506 abi: abi,
507 sig: sig
508 }
509 }
970d7e83 510
e9174d1e
SL
511 fn parse_sig(&mut self) -> ty::PolyFnSig<'tcx> {
512 assert_eq!(self.next(), '[');
513 let mut inputs = Vec::new();
514 while self.peek() != ']' {
515 inputs.push(self.parse_ty());
223e47cc 516 }
e9174d1e
SL
517 self.pos += 1; // eat the ']'
518 let variadic = match self.next() {
519 'V' => true,
520 'N' => false,
521 r => panic!(format!("bad variadic: {}", r)),
c1a9b12d 522 };
e9174d1e
SL
523 let output = match self.peek() {
524 'z' => {
525 self.pos += 1;
526 ty::FnDiverging
62682a34 527 }
e9174d1e 528 _ => ty::FnConverging(self.parse_ty())
1a4d82fc 529 };
e9174d1e
SL
530 ty::Binder(ty::FnSig {inputs: inputs,
531 output: output,
532 variadic: variadic})
223e47cc 533 }
223e47cc 534
e9174d1e
SL
535 pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> {
536 match self.next() {
537 't' => ty::Binder(self.parse_trait_ref()).to_predicate(),
538 'e' => ty::Binder(ty::EquatePredicate(self.parse_ty(),
539 self.parse_ty())).to_predicate(),
540 'r' => ty::Binder(ty::OutlivesPredicate(self.parse_region(),
541 self.parse_region())).to_predicate(),
542 'o' => ty::Binder(ty::OutlivesPredicate(self.parse_ty(),
543 self.parse_region())).to_predicate(),
544 'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(),
545 'w' => ty::Predicate::WellFormed(self.parse_ty()),
546 'O' => {
b039eaaf 547 let def_id = self.parse_def();
e9174d1e
SL
548 assert_eq!(self.next(), '|');
549 ty::Predicate::ObjectSafe(def_id)
550 }
551 c => panic!("Encountered invalid character in metadata: {}", c)
552 }
223e47cc 553 }
1a4d82fc 554
e9174d1e
SL
555 fn parse_projection_predicate(&mut self) -> ty::ProjectionPredicate<'tcx> {
556 ty::ProjectionPredicate {
557 projection_ty: ty::ProjectionTy {
558 trait_ref: self.parse_trait_ref(),
b039eaaf 559 item_name: token::intern(&self.parse_str('|')),
e9174d1e
SL
560 },
561 ty: self.parse_ty(),
562 }
563 }
223e47cc 564
e9174d1e
SL
565 pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
566 let name = self.parse_name(':');
b039eaaf 567 let def_id = self.parse_def();
e9174d1e
SL
568 let space = self.parse_param_space();
569 assert_eq!(self.next(), '|');
570 let index = self.parse_u32();
571 assert_eq!(self.next(), '|');
b039eaaf 572 let default_def_id = self.parse_def();
e9174d1e
SL
573 let default = self.parse_opt(|this| this.parse_ty());
574 let object_lifetime_default = self.parse_object_lifetime_default();
575
576 ty::TypeParameterDef {
577 name: name,
578 def_id: def_id,
579 space: space,
580 index: index,
581 default_def_id: default_def_id,
582 default: default,
583 object_lifetime_default: object_lifetime_default,
584 }
223e47cc 585 }
223e47cc 586
e9174d1e
SL
587 pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
588 let name = self.parse_name(':');
b039eaaf 589 let def_id = self.parse_def();
e9174d1e
SL
590 let space = self.parse_param_space();
591 assert_eq!(self.next(), '|');
592 let index = self.parse_u32();
593 assert_eq!(self.next(), '|');
594 let mut bounds = vec![];
595 loop {
596 match self.next() {
597 'R' => bounds.push(self.parse_region()),
598 '.' => { break; }
599 c => {
600 panic!("parse_region_param_def: bad bounds ('{}')", c)
601 }
602 }
603 }
604 ty::RegionParameterDef {
605 name: name,
606 def_id: def_id,
607 space: space,
608 index: index,
609 bounds: bounds
610 }
611 }
223e47cc 612
1a4d82fc 613
e9174d1e
SL
614 fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault {
615 match self.next() {
616 'a' => ty::ObjectLifetimeDefault::Ambiguous,
617 'b' => ty::ObjectLifetimeDefault::BaseDefault,
618 's' => {
619 let region = self.parse_region();
620 ty::ObjectLifetimeDefault::Specific(region)
621 }
622 _ => panic!("parse_object_lifetime_default: bad input")
623 }
223e47cc 624 }
223e47cc 625
e9174d1e
SL
626 pub fn parse_existential_bounds(&mut self) -> ty::ExistentialBounds<'tcx> {
627 let builtin_bounds = self.parse_builtin_bounds();
628 let region_bound = self.parse_region();
629 let mut projection_bounds = Vec::new();
1a4d82fc 630
e9174d1e
SL
631 loop {
632 match self.next() {
633 'P' => {
634 projection_bounds.push(ty::Binder(self.parse_projection_predicate()));
635 }
636 '.' => { break; }
637 c => {
638 panic!("parse_bounds: bad bounds ('{}')", c)
639 }
640 }
641 }
642
643 ty::ExistentialBounds::new(
644 region_bound, builtin_bounds, projection_bounds)
223e47cc 645 }
223e47cc 646
e9174d1e
SL
647 fn parse_builtin_bounds(&mut self) -> ty::BuiltinBounds {
648 let mut builtin_bounds = ty::BuiltinBounds::empty();
649 loop {
650 match self.next() {
651 'S' => {
652 builtin_bounds.insert(ty::BoundSend);
653 }
654 'Z' => {
655 builtin_bounds.insert(ty::BoundSized);
656 }
657 'P' => {
658 builtin_bounds.insert(ty::BoundCopy);
659 }
660 'T' => {
661 builtin_bounds.insert(ty::BoundSync);
662 }
663 '.' => {
664 return builtin_bounds;
665 }
666 c => {
667 panic!("parse_bounds: bad builtin bounds ('{}')", c)
668 }
669 }
1a4d82fc 670 }
e9174d1e 671 }
223e47cc
LB
672}
673
674// Rust metadata parsing
e9174d1e 675fn parse_defid(buf: &[u8]) -> DefId {
85aaf69f 676 let mut colon_idx = 0;
970d7e83 677 let len = buf.len();
85aaf69f 678 while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; }
223e47cc
LB
679 if colon_idx == len {
680 error!("didn't find ':' when parsing def id");
1a4d82fc 681 panic!();
223e47cc
LB
682 }
683
85aaf69f
SL
684 let crate_part = &buf[0..colon_idx];
685 let def_part = &buf[colon_idx + 1..len];
223e47cc 686
85aaf69f 687 let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
c34b1796 688 s.parse::<usize>().ok()
85aaf69f 689 }) {
e9174d1e
SL
690 Some(cn) => cn as ast::CrateNum,
691 None => panic!("internal error: parse_defid: crate number expected, found {:?}",
692 crate_part)
223e47cc 693 };
85aaf69f 694 let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
c34b1796 695 s.parse::<usize>().ok()
85aaf69f 696 }) {
b039eaaf 697 Some(dn) => dn,
e9174d1e
SL
698 None => panic!("internal error: parse_defid: id expected, found {:?}",
699 def_part)
223e47cc 700 };
b039eaaf
SL
701 let index = DefIndex::new(def_num);
702 DefId { krate: crate_num, index: index }
85aaf69f
SL
703}
704
e9174d1e
SL
705fn parse_unsafety(c: char) -> hir::Unsafety {
706 match c {
707 'u' => hir::Unsafety::Unsafe,
708 'n' => hir::Unsafety::Normal,
709 _ => panic!("parse_unsafety: bad unsafety {}", c)
1a4d82fc
JJ
710 }
711}