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