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