]> git.proxmox.com Git - rustc.git/blame - src/librustc_metadata/decoder.rs
Imported Upstream version 1.6.0+dfsg1
[rustc.git] / src / librustc_metadata / decoder.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
223e47cc
LB
11// Decoding metadata from a single crate's metadata
12
1a4d82fc 13#![allow(non_camel_case_types)]
223e47cc 14
1a4d82fc
JJ
15use self::Family::*;
16
92a42be0
SL
17use cstore::{self, crate_metadata};
18use common::*;
19use encoder::def_to_u64;
20use index;
21use tydecode::TyDecoder;
22
23use rustc::back::svh::Svh;
24use rustc::front::map as hir_map;
25use rustc::util::nodemap::FnvHashMap;
e9174d1e
SL
26use rustc_front::hir;
27
92a42be0
SL
28use middle::cstore::{LOCAL_CRATE, FoundAst, InlinedItem, LinkagePreference};
29use middle::cstore::{DefLike, DlDef, DlField, DlImpl};
1a4d82fc 30use middle::def;
b039eaaf 31use middle::def_id::{DefId, DefIndex};
1a4d82fc
JJ
32use middle::lang_items;
33use middle::subst;
34use middle::ty::{ImplContainer, TraitContainer};
e9174d1e 35use middle::ty::{self, RegionEscape, Ty};
1a4d82fc 36
d9579d0f 37use std::cell::{Cell, RefCell};
c34b1796
AL
38use std::io::prelude::*;
39use std::io;
1a4d82fc 40use std::rc::Rc;
970d7e83 41use std::str;
1a4d82fc
JJ
42
43use rbml::reader;
44use rbml;
45use serialize::Decodable;
b039eaaf 46use syntax::attr;
1a4d82fc
JJ
47use syntax::parse::token::{IdentInterner, special_idents};
48use syntax::parse::token;
1a4d82fc 49use syntax::ast;
e9174d1e 50use syntax::abi;
223e47cc 51use syntax::codemap;
b039eaaf 52use syntax::print::pprust;
1a4d82fc 53use syntax::ptr::P;
223e47cc 54
c34b1796 55
e9174d1e 56pub type Cmd<'a> = &'a crate_metadata;
223e47cc 57
e9174d1e 58impl crate_metadata {
b039eaaf 59 fn get_item(&self, item_id: DefIndex) -> Option<rbml::Doc> {
e9174d1e
SL
60 self.index.lookup_item(self.data(), item_id).map(|pos| {
61 reader::doc_at(self.data(), pos as usize).unwrap().doc
62 })
223e47cc 63 }
223e47cc 64
b039eaaf 65 fn lookup_item(&self, item_id: DefIndex) -> rbml::Doc {
e9174d1e 66 match self.get_item(item_id) {
b039eaaf 67 None => panic!("lookup_item: id not found: {:?}", item_id),
e9174d1e
SL
68 Some(d) => d
69 }
970d7e83 70 }
223e47cc
LB
71}
72
e9174d1e
SL
73pub fn load_index(data: &[u8]) -> index::Index {
74 let index = reader::get_doc(rbml::Doc::new(data), tag_index);
b039eaaf
SL
75 index::Index::from_rbml(index)
76}
77
78pub fn crate_rustc_version(data: &[u8]) -> Option<String> {
79 let doc = rbml::Doc::new(data);
80 reader::maybe_get_doc(doc, tag_rustc_version).map(|s| s.as_str())
81}
82
83pub fn load_xrefs(data: &[u8]) -> index::DenseIndex {
84 let index = reader::get_doc(rbml::Doc::new(data), tag_xref_index);
85 index::DenseIndex::from_buf(index.data, index.start, index.end)
223e47cc
LB
86}
87
e9174d1e 88#[derive(Debug, PartialEq)]
223e47cc 89enum Family {
970d7e83
LB
90 ImmStatic, // c
91 MutStatic, // b
223e47cc 92 Fn, // f
1a4d82fc 93 CtorFn, // o
223e47cc 94 StaticMethod, // F
1a4d82fc 95 Method, // h
223e47cc 96 Type, // y
223e47cc
LB
97 Mod, // m
98 ForeignMod, // n
99 Enum, // t
1a4d82fc
JJ
100 TupleVariant, // v
101 StructVariant, // V
223e47cc 102 Impl, // i
c34b1796 103 DefaultImpl, // d
223e47cc
LB
104 Trait, // I
105 Struct, // S
106 PublicField, // g
1a4d82fc
JJ
107 InheritedField, // N
108 Constant, // C
223e47cc
LB
109}
110
1a4d82fc 111fn item_family(item: rbml::Doc) -> Family {
223e47cc
LB
112 let fam = reader::get_doc(item, tag_items_data_item_family);
113 match reader::doc_as_u8(fam) as char {
1a4d82fc 114 'C' => Constant,
970d7e83
LB
115 'c' => ImmStatic,
116 'b' => MutStatic,
223e47cc 117 'f' => Fn,
1a4d82fc 118 'o' => CtorFn,
223e47cc 119 'F' => StaticMethod,
1a4d82fc 120 'h' => Method,
223e47cc 121 'y' => Type,
223e47cc
LB
122 'm' => Mod,
123 'n' => ForeignMod,
124 't' => Enum,
1a4d82fc
JJ
125 'v' => TupleVariant,
126 'V' => StructVariant,
223e47cc 127 'i' => Impl,
c34b1796 128 'd' => DefaultImpl,
223e47cc
LB
129 'I' => Trait,
130 'S' => Struct,
131 'g' => PublicField,
223e47cc 132 'N' => InheritedField,
1a4d82fc 133 c => panic!("unexpected family char: {}", c)
223e47cc
LB
134 }
135}
136
e9174d1e 137fn item_visibility(item: rbml::Doc) -> hir::Visibility {
223e47cc 138 match reader::maybe_get_doc(item, tag_items_data_item_visibility) {
e9174d1e 139 None => hir::Public,
223e47cc
LB
140 Some(visibility_doc) => {
141 match reader::doc_as_u8(visibility_doc) as char {
e9174d1e
SL
142 'y' => hir::Public,
143 'i' => hir::Inherited,
1a4d82fc 144 _ => panic!("unknown visibility character")
223e47cc
LB
145 }
146 }
147 }
148}
149
e9174d1e 150fn fn_constness(item: rbml::Doc) -> hir::Constness {
62682a34 151 match reader::maybe_get_doc(item, tag_items_data_item_constness) {
e9174d1e 152 None => hir::Constness::NotConst,
62682a34
SL
153 Some(constness_doc) => {
154 match reader::doc_as_u8(constness_doc) as char {
e9174d1e
SL
155 'c' => hir::Constness::Const,
156 'n' => hir::Constness::NotConst,
62682a34
SL
157 _ => panic!("unknown constness character")
158 }
159 }
160 }
161}
162
c34b1796 163fn item_sort(item: rbml::Doc) -> Option<char> {
62682a34
SL
164 reader::tagged_docs(item, tag_item_trait_item_sort).nth(0).map(|doc| {
165 doc.as_str_slice().as_bytes()[0] as char
166 })
223e47cc
LB
167}
168
1a4d82fc
JJ
169fn item_symbol(item: rbml::Doc) -> String {
170 reader::get_doc(item, tag_items_data_item_symbol).as_str().to_string()
223e47cc
LB
171}
172
e9174d1e 173fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId {
d9579d0f 174 let id = reader::doc_as_u64(d);
b039eaaf
SL
175 let index = DefIndex::new((id & 0xFFFF_FFFF) as usize);
176 let def_id = DefId { krate: (id >> 32) as u32, index: index };
d9579d0f
AL
177 translate_def_id(cdata, def_id)
178}
179
e9174d1e 180fn item_parent_item(cdata: Cmd, d: rbml::Doc) -> Option<DefId> {
62682a34
SL
181 reader::tagged_docs(d, tag_items_data_parent_item).nth(0).map(|did| {
182 translated_def_id(cdata, did)
183 })
223e47cc
LB
184}
185
e9174d1e 186fn item_require_parent_item(cdata: Cmd, d: rbml::Doc) -> DefId {
d9579d0f 187 translated_def_id(cdata, reader::get_doc(d, tag_items_data_parent_item))
223e47cc
LB
188}
189
e9174d1e 190fn item_def_id(d: rbml::Doc, cdata: Cmd) -> DefId {
d9579d0f 191 translated_def_id(cdata, reader::get_doc(d, tag_def_id))
223e47cc
LB
192}
193
62682a34
SL
194fn reexports<'a>(d: rbml::Doc<'a>) -> reader::TaggedDocsIterator<'a> {
195 reader::tagged_docs(d, tag_items_data_item_reexport)
223e47cc
LB
196}
197
1a4d82fc
JJ
198fn variant_disr_val(d: rbml::Doc) -> Option<ty::Disr> {
199 reader::maybe_get_doc(d, tag_disr_val).and_then(|val_doc| {
200 reader::with_doc_data(val_doc, |data| {
85aaf69f 201 str::from_utf8(data).ok().and_then(|s| s.parse().ok())
1a4d82fc
JJ
202 })
203 })
204}
205
206fn doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> {
223e47cc 207 let tp = reader::get_doc(doc, tag_items_data_item_type);
e9174d1e 208 TyDecoder::with_doc(tcx, cdata.cnum, tp,
b039eaaf 209 &mut |did| translate_def_id(cdata, did))
e9174d1e 210 .parse_ty()
223e47cc
LB
211}
212
62682a34
SL
213fn maybe_doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Option<Ty<'tcx>> {
214 reader::maybe_get_doc(doc, tag_items_data_item_type).map(|tp| {
e9174d1e 215 TyDecoder::with_doc(tcx, cdata.cnum, tp,
b039eaaf 216 &mut |did| translate_def_id(cdata, did))
e9174d1e 217 .parse_ty()
62682a34
SL
218 })
219}
220
e9174d1e 221pub fn item_type<'tcx>(_item_id: DefId, item: rbml::Doc,
1a4d82fc 222 tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> {
970d7e83
LB
223 doc_type(item, tcx, cdata)
224}
225
1a4d82fc 226fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
d9579d0f 227 -> ty::TraitRef<'tcx> {
e9174d1e 228 TyDecoder::with_doc(tcx, cdata.cnum, doc,
b039eaaf 229 &mut |did| translate_def_id(cdata, did))
e9174d1e 230 .parse_trait_ref()
223e47cc
LB
231}
232
1a4d82fc 233fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
d9579d0f 234 -> ty::TraitRef<'tcx> {
970d7e83
LB
235 let tp = reader::get_doc(doc, tag_item_trait_ref);
236 doc_trait_ref(tp, tcx, cdata)
237}
238
b039eaaf 239fn item_path(item_doc: rbml::Doc) -> Vec<hir_map::PathElem> {
223e47cc 240 let path_doc = reader::get_doc(item_doc, tag_path);
62682a34 241 reader::docs(path_doc).filter_map(|(tag, elt_doc)| {
1a4d82fc
JJ
242 if tag == tag_path_elem_mod {
243 let s = elt_doc.as_str_slice();
b039eaaf 244 Some(hir_map::PathMod(token::intern(s)))
1a4d82fc
JJ
245 } else if tag == tag_path_elem_name {
246 let s = elt_doc.as_str_slice();
b039eaaf 247 Some(hir_map::PathName(token::intern(s)))
223e47cc
LB
248 } else {
249 // ignore tag_path_len element
62682a34 250 None
223e47cc 251 }
62682a34 252 }).collect()
223e47cc
LB
253}
254
1a4d82fc 255fn item_name(intr: &IdentInterner, item: rbml::Doc) -> ast::Name {
223e47cc 256 let name = reader::get_doc(item, tag_paths_data_name);
970d7e83 257 let string = name.as_str_slice();
1a4d82fc
JJ
258 match intr.find(string) {
259 None => token::intern(string),
260 Some(val) => val,
970d7e83 261 }
223e47cc
LB
262}
263
e9174d1e 264fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: DefId) -> DefLike {
223e47cc
LB
265 let fam = item_family(item);
266 match fam {
d9579d0f
AL
267 Constant => {
268 // Check whether we have an associated const item.
b039eaaf
SL
269 match item_sort(item) {
270 Some('C') | Some('c') => {
271 DlDef(def::DefAssociatedConst(did))
272 }
273 _ => {
274 // Regular const item.
275 DlDef(def::DefConst(did))
276 }
d9579d0f
AL
277 }
278 }
1a4d82fc
JJ
279 ImmStatic => DlDef(def::DefStatic(did, false)),
280 MutStatic => DlDef(def::DefStatic(did, true)),
281 Struct => DlDef(def::DefStruct(did)),
282 Fn => DlDef(def::DefFn(did, false)),
283 CtorFn => DlDef(def::DefFn(did, true)),
284 Method | StaticMethod => {
c1a9b12d 285 DlDef(def::DefMethod(did))
c34b1796
AL
286 }
287 Type => {
288 if item_sort(item) == Some('t') {
d9579d0f 289 let trait_did = item_require_parent_item(cdata, item);
c34b1796
AL
290 DlDef(def::DefAssociatedTy(trait_did, did))
291 } else {
292 DlDef(def::DefTy(did, false))
1a4d82fc 293 }
223e47cc 294 }
1a4d82fc
JJ
295 Mod => DlDef(def::DefMod(did)),
296 ForeignMod => DlDef(def::DefForeignMod(did)),
297 StructVariant => {
d9579d0f 298 let enum_did = item_require_parent_item(cdata, item);
1a4d82fc 299 DlDef(def::DefVariant(enum_did, did, true))
223e47cc 300 }
1a4d82fc 301 TupleVariant => {
d9579d0f 302 let enum_did = item_require_parent_item(cdata, item);
1a4d82fc 303 DlDef(def::DefVariant(enum_did, did, false))
223e47cc 304 }
1a4d82fc
JJ
305 Trait => DlDef(def::DefTrait(did)),
306 Enum => DlDef(def::DefTy(did, true)),
c34b1796 307 Impl | DefaultImpl => DlImpl(did),
1a4d82fc
JJ
308 PublicField | InheritedField => DlField,
309 }
310}
311
e9174d1e 312fn parse_unsafety(item_doc: rbml::Doc) -> hir::Unsafety {
1a4d82fc
JJ
313 let unsafety_doc = reader::get_doc(item_doc, tag_unsafety);
314 if reader::doc_as_u8(unsafety_doc) != 0 {
e9174d1e 315 hir::Unsafety::Unsafe
1a4d82fc 316 } else {
e9174d1e 317 hir::Unsafety::Normal
223e47cc
LB
318 }
319}
320
85aaf69f
SL
321fn parse_paren_sugar(item_doc: rbml::Doc) -> bool {
322 let paren_sugar_doc = reader::get_doc(item_doc, tag_paren_sugar);
323 reader::doc_as_u8(paren_sugar_doc) != 0
324}
325
e9174d1e 326fn parse_polarity(item_doc: rbml::Doc) -> hir::ImplPolarity {
85aaf69f
SL
327 let polarity_doc = reader::get_doc(item_doc, tag_polarity);
328 if reader::doc_as_u8(polarity_doc) != 0 {
e9174d1e 329 hir::ImplPolarity::Negative
85aaf69f 330 } else {
e9174d1e 331 hir::ImplPolarity::Positive
85aaf69f
SL
332 }
333}
334
1a4d82fc
JJ
335fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
336 let names_doc = reader::get_doc(item_doc, tag_associated_type_names);
62682a34
SL
337 reader::tagged_docs(names_doc, tag_associated_type_name)
338 .map(|name_doc| token::intern(name_doc.as_str_slice()))
339 .collect()
223e47cc
LB
340}
341
1a4d82fc 342pub fn get_trait_def<'tcx>(cdata: Cmd,
b039eaaf 343 item_id: DefIndex,
1a4d82fc 344 tcx: &ty::ctxt<'tcx>) -> ty::TraitDef<'tcx>
970d7e83 345{
e9174d1e 346 let item_doc = cdata.lookup_item(item_id);
1a4d82fc 347 let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
1a4d82fc
JJ
348 let unsafety = parse_unsafety(item_doc);
349 let associated_type_names = parse_associated_type_names(item_doc);
85aaf69f 350 let paren_sugar = parse_paren_sugar(item_doc);
1a4d82fc 351
970d7e83 352 ty::TraitDef {
85aaf69f 353 paren_sugar: paren_sugar,
1a4d82fc
JJ
354 unsafety: unsafety,
355 generics: generics,
1a4d82fc
JJ
356 trait_ref: item_trait_ref(item_doc, tcx, cdata),
357 associated_type_names: associated_type_names,
d9579d0f
AL
358 nonblanket_impls: RefCell::new(FnvHashMap()),
359 blanket_impls: RefCell::new(vec![]),
360 flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
970d7e83
LB
361 }
362}
363
e9174d1e
SL
364pub fn get_adt_def<'tcx>(intr: &IdentInterner,
365 cdata: Cmd,
b039eaaf 366 item_id: DefIndex,
e9174d1e
SL
367 tcx: &ty::ctxt<'tcx>) -> ty::AdtDefMaster<'tcx>
368{
369 fn get_enum_variants<'tcx>(intr: &IdentInterner,
370 cdata: Cmd,
371 doc: rbml::Doc,
372 tcx: &ty::ctxt<'tcx>) -> Vec<ty::VariantDefData<'tcx, 'tcx>> {
373 let mut disr_val = 0;
374 reader::tagged_docs(doc, tag_items_data_item_variant).map(|p| {
375 let did = translated_def_id(cdata, p);
b039eaaf 376 let item = cdata.lookup_item(did.index);
e9174d1e
SL
377
378 if let Some(disr) = variant_disr_val(item) {
379 disr_val = disr;
380 }
381 let disr = disr_val;
382 disr_val = disr_val.wrapping_add(1);
383
384 ty::VariantDefData {
385 did: did,
386 name: item_name(intr, item),
387 fields: get_variant_fields(intr, cdata, item, tcx),
388 disr_val: disr
389 }
390 }).collect()
391 }
392 fn get_variant_fields<'tcx>(intr: &IdentInterner,
393 cdata: Cmd,
394 doc: rbml::Doc,
395 tcx: &ty::ctxt<'tcx>) -> Vec<ty::FieldDefData<'tcx, 'tcx>> {
396 reader::tagged_docs(doc, tag_item_field).map(|f| {
397 let ff = item_family(f);
398 match ff {
399 PublicField | InheritedField => {},
400 _ => tcx.sess.bug(&format!("expected field, found {:?}", ff))
401 };
402 ty::FieldDefData::new(item_def_id(f, cdata),
403 item_name(intr, f),
404 struct_field_family_to_visibility(ff))
405 }).chain(reader::tagged_docs(doc, tag_item_unnamed_field).map(|f| {
406 let ff = item_family(f);
407 ty::FieldDefData::new(item_def_id(f, cdata),
408 special_idents::unnamed_field.name,
409 struct_field_family_to_visibility(ff))
410 })).collect()
411 }
412 fn get_struct_variant<'tcx>(intr: &IdentInterner,
413 cdata: Cmd,
414 doc: rbml::Doc,
415 did: DefId,
416 tcx: &ty::ctxt<'tcx>) -> ty::VariantDefData<'tcx, 'tcx> {
417 ty::VariantDefData {
418 did: did,
419 name: item_name(intr, doc),
420 fields: get_variant_fields(intr, cdata, doc, tcx),
421 disr_val: 0
422 }
423 }
424
425 let doc = cdata.lookup_item(item_id);
b039eaaf 426 let did = DefId { krate: cdata.cnum, index: item_id };
e9174d1e 427 let (kind, variants) = match item_family(doc) {
b039eaaf
SL
428 Enum => {
429 (ty::AdtKind::Enum,
430 get_enum_variants(intr, cdata, doc, tcx))
431 }
432 Struct => {
433 let ctor_did =
434 reader::maybe_get_doc(doc, tag_items_data_item_struct_ctor).
435 map_or(did, |ctor_doc| translated_def_id(cdata, ctor_doc));
436 (ty::AdtKind::Struct,
437 vec![get_struct_variant(intr, cdata, doc, ctor_did, tcx)])
438 }
439 _ => tcx.sess.bug(
440 &format!("get_adt_def called on a non-ADT {:?} - {:?}",
441 item_family(doc), did))
e9174d1e
SL
442 };
443
444 let adt = tcx.intern_adt_def(did, kind, variants);
445
446 // this needs to be done *after* the variant is interned,
447 // to support recursive structures
448 for variant in &adt.variants {
449 if variant.kind() == ty::VariantKind::Tuple &&
450 adt.adt_kind() == ty::AdtKind::Enum {
451 // tuple-like enum variant fields aren't real items - get the types
452 // from the ctor.
453 debug!("evaluating the ctor-type of {:?}",
454 variant.name);
b039eaaf 455 let ctor_ty = get_type(cdata, variant.did.index, tcx).ty;
e9174d1e
SL
456 debug!("evaluating the ctor-type of {:?}.. {:?}",
457 variant.name,
458 ctor_ty);
459 let field_tys = match ctor_ty.sty {
460 ty::TyBareFn(_, &ty::BareFnTy { sig: ty::Binder(ty::FnSig {
461 ref inputs, ..
462 }), ..}) => {
463 // tuple-struct constructors don't have escaping regions
464 assert!(!inputs.has_escaping_regions());
465 inputs
466 },
467 _ => tcx.sess.bug("tuple-variant ctor is not an ADT")
468 };
469 for (field, &ty) in variant.fields.iter().zip(field_tys.iter()) {
470 field.fulfill_ty(ty);
471 }
472 } else {
473 for field in &variant.fields {
474 debug!("evaluating the type of {:?}::{:?}", variant.name, field.name);
b039eaaf 475 let ty = get_type(cdata, field.did.index, tcx).ty;
e9174d1e
SL
476 field.fulfill_ty(ty);
477 debug!("evaluating the type of {:?}::{:?}: {:?}",
478 variant.name, field.name, ty);
479 }
480 }
481 }
482
483 adt
484}
485
85aaf69f 486pub fn get_predicates<'tcx>(cdata: Cmd,
b039eaaf 487 item_id: DefIndex,
85aaf69f
SL
488 tcx: &ty::ctxt<'tcx>)
489 -> ty::GenericPredicates<'tcx>
490{
e9174d1e 491 let item_doc = cdata.lookup_item(item_id);
85aaf69f
SL
492 doc_predicates(item_doc, tcx, cdata, tag_item_generics)
493}
223e47cc 494
c34b1796 495pub fn get_super_predicates<'tcx>(cdata: Cmd,
b039eaaf 496 item_id: DefIndex,
c34b1796
AL
497 tcx: &ty::ctxt<'tcx>)
498 -> ty::GenericPredicates<'tcx>
499{
e9174d1e 500 let item_doc = cdata.lookup_item(item_id);
c34b1796
AL
501 doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates)
502}
503
b039eaaf 504pub fn get_type<'tcx>(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt<'tcx>)
85aaf69f
SL
505 -> ty::TypeScheme<'tcx>
506{
e9174d1e 507 let item_doc = cdata.lookup_item(id);
b039eaaf 508 let t = item_type(DefId { krate: cdata.cnum, index: id }, item_doc, tcx,
223e47cc 509 cdata);
85aaf69f 510 let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
1a4d82fc
JJ
511 ty::TypeScheme {
512 generics: generics,
223e47cc
LB
513 ty: t
514 }
515}
516
b039eaaf 517pub fn get_stability(cdata: Cmd, id: DefIndex) -> Option<attr::Stability> {
e9174d1e 518 let item = cdata.lookup_item(id);
1a4d82fc
JJ
519 reader::maybe_get_doc(item, tag_items_data_item_stability).map(|doc| {
520 let mut decoder = reader::Decoder::new(doc);
521 Decodable::decode(&mut decoder).unwrap()
522 })
223e47cc
LB
523}
524
b039eaaf 525pub fn get_repr_attrs(cdata: Cmd, id: DefIndex) -> Vec<attr::ReprAttr> {
e9174d1e 526 let item = cdata.lookup_item(id);
1a4d82fc
JJ
527 match reader::maybe_get_doc(item, tag_items_data_item_repr).map(|doc| {
528 let mut decoder = reader::Decoder::new(doc);
529 Decodable::decode(&mut decoder).unwrap()
530 }) {
531 Some(attrs) => attrs,
532 None => Vec::new(),
533 }
223e47cc
LB
534}
535
85aaf69f 536pub fn get_impl_polarity<'tcx>(cdata: Cmd,
b039eaaf 537 id: DefIndex)
e9174d1e 538 -> Option<hir::ImplPolarity>
85aaf69f 539{
e9174d1e 540 let item_doc = cdata.lookup_item(id);
85aaf69f
SL
541 let fam = item_family(item_doc);
542 match fam {
543 Family::Impl => {
544 Some(parse_polarity(item_doc))
545 }
546 _ => None
547 }
548}
549
e9174d1e
SL
550pub fn get_custom_coerce_unsized_kind<'tcx>(
551 cdata: Cmd,
b039eaaf 552 id: DefIndex)
e9174d1e
SL
553 -> Option<ty::adjustment::CustomCoerceUnsized>
554{
555 let item_doc = cdata.lookup_item(id);
d9579d0f
AL
556 reader::maybe_get_doc(item_doc, tag_impl_coerce_unsized_kind).map(|kind_doc| {
557 let mut decoder = reader::Decoder::new(kind_doc);
558 Decodable::decode(&mut decoder).unwrap()
559 })
560}
561
1a4d82fc 562pub fn get_impl_trait<'tcx>(cdata: Cmd,
b039eaaf 563 id: DefIndex,
1a4d82fc 564 tcx: &ty::ctxt<'tcx>)
d9579d0f 565 -> Option<ty::TraitRef<'tcx>>
970d7e83 566{
e9174d1e 567 let item_doc = cdata.lookup_item(id);
1a4d82fc
JJ
568 let fam = item_family(item_doc);
569 match fam {
c34b1796 570 Family::Impl | Family::DefaultImpl => {
1a4d82fc
JJ
571 reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
572 doc_trait_ref(tp, tcx, cdata)
573 })
574 }
575 _ => None
970d7e83 576 }
223e47cc
LB
577}
578
b039eaaf 579pub fn get_symbol(cdata: Cmd, id: DefIndex) -> String {
e9174d1e
SL
580 return item_symbol(cdata.lookup_item(id));
581}
582
583/// If you have a crate_metadata, call get_symbol instead
b039eaaf 584pub fn get_symbol_from_buf(data: &[u8], id: DefIndex) -> String {
e9174d1e
SL
585 let index = load_index(data);
586 let pos = index.lookup_item(data, id).unwrap();
587 let doc = reader::doc_at(data, pos as usize).unwrap().doc;
588 item_symbol(doc)
223e47cc
LB
589}
590
223e47cc 591/// Iterates over the language items in the given crate.
1a4d82fc 592pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
b039eaaf 593 F: FnMut(DefIndex, usize) -> bool,
1a4d82fc
JJ
594{
595 let root = rbml::Doc::new(cdata.data());
223e47cc 596 let lang_items = reader::get_doc(root, tag_lang_items);
62682a34 597 reader::tagged_docs(lang_items, tag_lang_items_item).all(|item_doc| {
223e47cc 598 let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
c34b1796 599 let id = reader::doc_as_u32(id_doc) as usize;
b039eaaf
SL
600 let index_doc = reader::get_doc(item_doc, tag_lang_items_item_index);
601 let index = DefIndex::from_u32(reader::doc_as_u32(index_doc));
223e47cc 602
b039eaaf 603 f(index, id)
1a4d82fc 604 })
223e47cc
LB
605}
606
1a4d82fc
JJ
607fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
608 cdata: Cmd,
609 item_doc: rbml::Doc,
610 mut get_crate_data: G,
611 mut callback: F) where
e9174d1e 612 F: FnMut(DefLike, ast::Name, hir::Visibility),
1a4d82fc
JJ
613 G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
614{
615 // Iterate over all children.
62682a34 616 for child_info_doc in reader::tagged_docs(item_doc, tag_mod_child) {
d9579d0f 617 let child_def_id = translated_def_id(cdata, child_info_doc);
1a4d82fc
JJ
618
619 // This item may be in yet another crate if it was the child of a
620 // reexport.
621 let crate_data = if child_def_id.krate == cdata.cnum {
622 None
623 } else {
624 Some(get_crate_data(child_def_id.krate))
625 };
626 let crate_data = match crate_data {
627 Some(ref cdata) => &**cdata,
628 None => cdata
629 };
970d7e83 630
1a4d82fc 631 // Get the item.
b039eaaf 632 match crate_data.get_item(child_def_id.index) {
1a4d82fc
JJ
633 None => {}
634 Some(child_item_doc) => {
635 // Hand off the item to the callback.
636 let child_name = item_name(&*intr, child_item_doc);
d9579d0f 637 let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
1a4d82fc
JJ
638 let visibility = item_visibility(child_item_doc);
639 callback(def_like, child_name, visibility);
970d7e83
LB
640 }
641 }
62682a34 642 }
1a4d82fc
JJ
643
644 // As a special case, iterate over all static methods of
645 // associated implementations too. This is a bit of a botch.
646 // --pcwalton
62682a34
SL
647 for inherent_impl_def_id_doc in reader::tagged_docs(item_doc,
648 tag_items_data_item_inherent_impl) {
649 let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc, cdata);
b039eaaf 650 if let Some(inherent_impl_doc) = cdata.get_item(inherent_impl_def_id.index) {
62682a34
SL
651 for impl_item_def_id_doc in reader::tagged_docs(inherent_impl_doc,
652 tag_item_impl_item) {
1a4d82fc
JJ
653 let impl_item_def_id = item_def_id(impl_item_def_id_doc,
654 cdata);
b039eaaf 655 if let Some(impl_method_doc) = cdata.get_item(impl_item_def_id.index) {
1a4d82fc
JJ
656 if let StaticMethod = item_family(impl_method_doc) {
657 // Hand off the static method to the callback.
658 let static_method_name = item_name(&*intr, impl_method_doc);
d9579d0f
AL
659 let static_method_def_like = item_to_def_like(cdata, impl_method_doc,
660 impl_item_def_id);
1a4d82fc
JJ
661 callback(static_method_def_like,
662 static_method_name,
663 item_visibility(impl_method_doc));
664 }
223e47cc 665 }
62682a34 666 }
970d7e83 667 }
62682a34 668 }
1a4d82fc 669
62682a34 670 for reexport_doc in reexports(item_doc) {
1a4d82fc
JJ
671 let def_id_doc = reader::get_doc(reexport_doc,
672 tag_items_data_item_reexport_def_id);
d9579d0f 673 let child_def_id = translated_def_id(cdata, def_id_doc);
1a4d82fc
JJ
674
675 let name_doc = reader::get_doc(reexport_doc,
676 tag_items_data_item_reexport_name);
677 let name = name_doc.as_str_slice();
678
679 // This reexport may be in yet another crate.
680 let crate_data = if child_def_id.krate == cdata.cnum {
681 None
970d7e83 682 } else {
1a4d82fc 683 Some(get_crate_data(child_def_id.krate))
970d7e83 684 };
1a4d82fc
JJ
685 let crate_data = match crate_data {
686 Some(ref cdata) => &**cdata,
687 None => cdata
970d7e83
LB
688 };
689
1a4d82fc 690 // Get the item.
b039eaaf 691 if let Some(child_item_doc) = crate_data.get_item(child_def_id.index) {
1a4d82fc 692 // Hand off the item to the callback.
d9579d0f 693 let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
1a4d82fc
JJ
694 // These items have a public visibility because they're part of
695 // a public re-export.
e9174d1e 696 callback(def_like, token::intern(name), hir::Public);
970d7e83 697 }
62682a34 698 }
1a4d82fc 699}
970d7e83 700
1a4d82fc
JJ
701/// Iterates over each child of the given item.
702pub fn each_child_of_item<F, G>(intr: Rc<IdentInterner>,
703 cdata: Cmd,
b039eaaf 704 id: DefIndex,
1a4d82fc
JJ
705 get_crate_data: G,
706 callback: F) where
e9174d1e 707 F: FnMut(DefLike, ast::Name, hir::Visibility),
1a4d82fc
JJ
708 G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
709{
710 // Find the item.
e9174d1e 711 let item_doc = match cdata.get_item(id) {
1a4d82fc
JJ
712 None => return,
713 Some(item_doc) => item_doc,
714 };
970d7e83 715
1a4d82fc
JJ
716 each_child_of_item_or_crate(intr,
717 cdata,
718 item_doc,
719 get_crate_data,
720 callback)
223e47cc
LB
721}
722
1a4d82fc
JJ
723/// Iterates over all the top-level crate items.
724pub fn each_top_level_item_of_crate<F, G>(intr: Rc<IdentInterner>,
725 cdata: Cmd,
726 get_crate_data: G,
727 callback: F) where
e9174d1e 728 F: FnMut(DefLike, ast::Name, hir::Visibility),
1a4d82fc
JJ
729 G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
730{
731 let root_doc = rbml::Doc::new(cdata.data());
970d7e83
LB
732 let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
733 let crate_items_doc = reader::get_doc(misc_info_doc,
734 tag_misc_info_crate_items);
735
1a4d82fc
JJ
736 each_child_of_item_or_crate(intr,
737 cdata,
738 crate_items_doc,
739 get_crate_data,
740 callback)
741}
742
b039eaaf 743pub fn get_item_path(cdata: Cmd, id: DefIndex) -> Vec<hir_map::PathElem> {
e9174d1e
SL
744 item_path(cdata.lookup_item(id))
745}
746
b039eaaf 747pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: DefIndex) -> ast::Name {
e9174d1e 748 item_name(intr, cdata.lookup_item(id))
1a4d82fc
JJ
749}
750
751pub type DecodeInlinedItem<'a> =
752 Box<for<'tcx> FnMut(Cmd,
753 &ty::ctxt<'tcx>,
b039eaaf
SL
754 Vec<hir_map::PathElem>,
755 hir_map::DefPath,
756 rbml::Doc,
757 DefId)
758 -> Result<&'tcx InlinedItem, (Vec<hir_map::PathElem>,
759 hir_map::DefPath)> + 'a>;
760
761pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: DefIndex,
1a4d82fc 762 mut decode_inlined_item: DecodeInlinedItem)
92a42be0 763 -> FoundAst<'tcx> {
b039eaaf 764 debug!("Looking up item: {:?}", id);
e9174d1e 765 let item_doc = cdata.lookup_item(id);
b039eaaf 766 let item_did = item_def_id(item_doc, cdata);
c1a9b12d 767 let path = item_path(item_doc).split_last().unwrap().1.to_vec();
b039eaaf
SL
768 let def_path = def_path(cdata, id);
769 match decode_inlined_item(cdata, tcx, path, def_path, item_doc, item_did) {
92a42be0 770 Ok(ii) => FoundAst::Found(ii),
b039eaaf 771 Err((path, def_path)) => {
d9579d0f 772 match item_parent_item(cdata, item_doc) {
1a4d82fc 773 Some(did) => {
b039eaaf
SL
774 let parent_item = cdata.lookup_item(did.index);
775 match decode_inlined_item(cdata, tcx, path, def_path, parent_item, did) {
92a42be0
SL
776 Ok(ii) => FoundAst::FoundParent(did, ii),
777 Err(_) => FoundAst::NotFound
1a4d82fc
JJ
778 }
779 }
92a42be0 780 None => FoundAst::NotFound
223e47cc 781 }
223e47cc 782 }
223e47cc
LB
783 }
784}
785
1a4d82fc 786fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
e9174d1e 787 fn get_mutability(ch: u8) -> hir::Mutability {
223e47cc 788 match ch as char {
e9174d1e
SL
789 'i' => hir::MutImmutable,
790 'm' => hir::MutMutable,
1a4d82fc 791 _ => panic!("unknown mutability character: `{}`", ch as char),
223e47cc
LB
792 }
793 }
794
970d7e83
LB
795 let explicit_self_doc = reader::get_doc(item, tag_item_trait_method_explicit_self);
796 let string = explicit_self_doc.as_str_slice();
223e47cc 797
1a4d82fc 798 let explicit_self_kind = string.as_bytes()[0];
970d7e83 799 match explicit_self_kind as char {
1a4d82fc
JJ
800 's' => ty::StaticExplicitSelfCategory,
801 'v' => ty::ByValueExplicitSelfCategory,
802 '~' => ty::ByBoxExplicitSelfCategory,
803 // FIXME(#4846) expl. region
223e47cc 804 '&' => {
1a4d82fc
JJ
805 ty::ByReferenceExplicitSelfCategory(
806 ty::ReEmpty,
807 get_mutability(string.as_bytes()[1]))
223e47cc 808 }
1a4d82fc 809 _ => panic!("unknown self type code: `{}`", explicit_self_kind as char)
223e47cc
LB
810 }
811}
812
1a4d82fc 813/// Returns the def IDs of all the items in the given implementation.
b039eaaf 814pub fn get_impl_items(cdata: Cmd, impl_id: DefIndex)
1a4d82fc 815 -> Vec<ty::ImplOrTraitItemId> {
e9174d1e 816 reader::tagged_docs(cdata.lookup_item(impl_id), tag_item_impl_item).map(|doc| {
1a4d82fc
JJ
817 let def_id = item_def_id(doc, cdata);
818 match item_sort(doc) {
b039eaaf 819 Some('C') | Some('c') => ty::ConstTraitItemId(def_id),
62682a34
SL
820 Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
821 Some('t') => ty::TypeTraitItemId(def_id),
1a4d82fc
JJ
822 _ => panic!("unknown impl item sort"),
823 }
62682a34 824 }).collect()
1a4d82fc
JJ
825}
826
827pub fn get_trait_name(intr: Rc<IdentInterner>,
828 cdata: Cmd,
b039eaaf 829 id: DefIndex)
1a4d82fc 830 -> ast::Name {
e9174d1e 831 let doc = cdata.lookup_item(id);
1a4d82fc
JJ
832 item_name(&*intr, doc)
833}
834
b039eaaf 835pub fn is_static_method(cdata: Cmd, id: DefIndex) -> bool {
e9174d1e 836 let doc = cdata.lookup_item(id);
1a4d82fc 837 match item_sort(doc) {
c34b1796
AL
838 Some('r') | Some('p') => {
839 get_explicit_self(doc) == ty::StaticExplicitSelfCategory
1a4d82fc 840 }
c34b1796 841 _ => false
223e47cc 842 }
223e47cc
LB
843}
844
1a4d82fc
JJ
845pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
846 cdata: Cmd,
b039eaaf 847 id: DefIndex,
1a4d82fc
JJ
848 tcx: &ty::ctxt<'tcx>)
849 -> ty::ImplOrTraitItem<'tcx> {
e9174d1e 850 let item_doc = cdata.lookup_item(id);
970d7e83 851
62682a34 852 let def_id = item_def_id(item_doc, cdata);
1a4d82fc 853
62682a34 854 let container_id = item_require_parent_item(cdata, item_doc);
b039eaaf 855 let container_doc = cdata.lookup_item(container_id.index);
1a4d82fc
JJ
856 let container = match item_family(container_doc) {
857 Trait => TraitContainer(container_id),
858 _ => ImplContainer(container_id),
859 };
860
62682a34
SL
861 let name = item_name(&*intr, item_doc);
862 let vis = item_visibility(item_doc);
1a4d82fc 863
62682a34 864 match item_sort(item_doc) {
b039eaaf 865 sort @ Some('C') | sort @ Some('c') => {
62682a34 866 let ty = doc_type(item_doc, tcx, cdata);
d9579d0f
AL
867 ty::ConstTraitItem(Rc::new(ty::AssociatedConst {
868 name: name,
869 ty: ty,
870 vis: vis,
871 def_id: def_id,
872 container: container,
b039eaaf 873 has_value: sort == Some('C')
d9579d0f
AL
874 }))
875 }
c34b1796 876 Some('r') | Some('p') => {
62682a34
SL
877 let generics = doc_generics(item_doc, tcx, cdata, tag_method_ty_generics);
878 let predicates = doc_predicates(item_doc, tcx, cdata, tag_method_ty_generics);
b039eaaf
SL
879 let ity = tcx.lookup_item_type(def_id).ty;
880 let fty = match ity.sty {
881 ty::TyBareFn(_, fty) => fty.clone(),
882 _ => tcx.sess.bug(&format!(
883 "the type {:?} of the method {:?} is not a function?",
884 ity, name))
885 };
62682a34 886 let explicit_self = get_explicit_self(item_doc);
1a4d82fc
JJ
887
888 ty::MethodTraitItem(Rc::new(ty::Method::new(name,
889 generics,
85aaf69f 890 predicates,
1a4d82fc
JJ
891 fty,
892 explicit_self,
893 vis,
894 def_id,
b039eaaf 895 container)))
1a4d82fc 896 }
c34b1796 897 Some('t') => {
62682a34 898 let ty = maybe_doc_type(item_doc, tcx, cdata);
1a4d82fc
JJ
899 ty::TypeTraitItem(Rc::new(ty::AssociatedType {
900 name: name,
62682a34 901 ty: ty,
1a4d82fc
JJ
902 vis: vis,
903 def_id: def_id,
904 container: container,
905 }))
906 }
907 _ => panic!("unknown impl/trait item sort"),
223e47cc 908 }
1a4d82fc
JJ
909}
910
b039eaaf 911pub fn get_trait_item_def_ids(cdata: Cmd, id: DefIndex)
1a4d82fc 912 -> Vec<ty::ImplOrTraitItemId> {
e9174d1e 913 let item = cdata.lookup_item(id);
62682a34 914 reader::tagged_docs(item, tag_item_trait_item).map(|mth| {
1a4d82fc
JJ
915 let def_id = item_def_id(mth, cdata);
916 match item_sort(mth) {
b039eaaf 917 Some('C') | Some('c') => ty::ConstTraitItemId(def_id),
62682a34
SL
918 Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
919 Some('t') => ty::TypeTraitItemId(def_id),
1a4d82fc
JJ
920 _ => panic!("unknown trait item sort"),
921 }
62682a34 922 }).collect()
223e47cc
LB
923}
924
b039eaaf 925pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> ty::ItemVariances {
e9174d1e 926 let item_doc = cdata.lookup_item(id);
1a4d82fc
JJ
927 let variance_doc = reader::get_doc(item_doc, tag_item_variances);
928 let mut decoder = reader::Decoder::new(variance_doc);
929 Decodable::decode(&mut decoder).unwrap()
930}
931
932pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
933 cdata: Cmd,
b039eaaf 934 id: DefIndex,
1a4d82fc
JJ
935 tcx: &ty::ctxt<'tcx>)
936 -> Vec<Rc<ty::Method<'tcx>>> {
e9174d1e 937 let item = cdata.lookup_item(id);
223e47cc 938
62682a34 939 reader::tagged_docs(item, tag_item_trait_item).filter_map(|mth_id| {
970d7e83 940 let did = item_def_id(mth_id, cdata);
b039eaaf 941 let mth = cdata.lookup_item(did.index);
223e47cc 942
c34b1796 943 if item_sort(mth) == Some('p') {
1a4d82fc
JJ
944 let trait_item = get_impl_or_trait_item(intr.clone(),
945 cdata,
b039eaaf 946 did.index,
1a4d82fc 947 tcx);
d9579d0f 948 if let ty::MethodTraitItem(ref method) = trait_item {
62682a34
SL
949 Some((*method).clone())
950 } else {
951 None
1a4d82fc 952 }
62682a34
SL
953 } else {
954 None
1a4d82fc 955 }
62682a34 956 }).collect()
223e47cc
LB
957}
958
d9579d0f
AL
959pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
960 cdata: Cmd,
b039eaaf 961 id: DefIndex,
d9579d0f
AL
962 tcx: &ty::ctxt<'tcx>)
963 -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
e9174d1e 964 let item = cdata.lookup_item(id);
d9579d0f 965
62682a34
SL
966 [tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| {
967 reader::tagged_docs(item, tag).filter_map(|ac_id| {
d9579d0f 968 let did = item_def_id(ac_id, cdata);
b039eaaf
SL
969 let ac_doc = cdata.lookup_item(did.index);
970
971 match item_sort(ac_doc) {
972 Some('C') | Some('c') => {
973 let trait_item = get_impl_or_trait_item(intr.clone(),
974 cdata,
975 did.index,
976 tcx);
977 if let ty::ConstTraitItem(ref ac) = trait_item {
978 Some((*ac).clone())
979 } else {
980 None
981 }
d9579d0f 982 }
b039eaaf 983 _ => None
d9579d0f 984 }
62682a34
SL
985 })
986 }).collect()
d9579d0f
AL
987}
988
1a4d82fc
JJ
989/// If node_id is the constructor of a tuple struct, retrieve the NodeId of
990/// the actual type definition, otherwise, return None
991pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
b039eaaf 992 node_id: DefIndex)
e9174d1e 993 -> Option<DefId>
1a4d82fc 994{
e9174d1e 995 let item = cdata.lookup_item(node_id);
62682a34
SL
996 reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor).next().map(|_| {
997 item_require_parent_item(cdata, item)
998 })
1a4d82fc
JJ
999}
1000
85aaf69f 1001pub fn get_item_attrs(cdata: Cmd,
b039eaaf
SL
1002 orig_node_id: DefIndex)
1003 -> Vec<ast::Attribute> {
1a4d82fc
JJ
1004 // The attributes for a tuple struct are attached to the definition, not the ctor;
1005 // we assume that someone passing in a tuple struct ctor is actually wanting to
1006 // look at the definition
1007 let node_id = get_tuple_struct_definition_if_ctor(cdata, orig_node_id);
b039eaaf 1008 let node_id = node_id.map(|x| x.index).unwrap_or(orig_node_id);
e9174d1e 1009 let item = cdata.lookup_item(node_id);
85aaf69f 1010 get_attributes(item)
1a4d82fc
JJ
1011}
1012
b039eaaf 1013pub fn get_struct_field_attrs(cdata: Cmd) -> FnvHashMap<DefId, Vec<ast::Attribute>> {
1a4d82fc
JJ
1014 let data = rbml::Doc::new(cdata.data());
1015 let fields = reader::get_doc(data, tag_struct_fields);
62682a34 1016 reader::tagged_docs(fields, tag_struct_field).map(|field| {
b039eaaf 1017 let def_id = translated_def_id(cdata, reader::get_doc(field, tag_def_id));
1a4d82fc 1018 let attrs = get_attributes(field);
b039eaaf 1019 (def_id, attrs)
62682a34 1020 }).collect()
1a4d82fc
JJ
1021}
1022
e9174d1e 1023fn struct_field_family_to_visibility(family: Family) -> hir::Visibility {
223e47cc 1024 match family {
e9174d1e
SL
1025 PublicField => hir::Public,
1026 InheritedField => hir::Inherited,
1a4d82fc 1027 _ => panic!()
223e47cc
LB
1028 }
1029}
1030
b039eaaf 1031pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: DefIndex)
e9174d1e
SL
1032 -> Vec<ast::Name> {
1033 let item = cdata.lookup_item(id);
1034 reader::tagged_docs(item, tag_item_field).map(|an_item| {
1035 item_name(intr, an_item)
1036 }).chain(reader::tagged_docs(item, tag_item_unnamed_field).map(|_| {
1037 special_idents::unnamed_field.name
62682a34 1038 })).collect()
223e47cc
LB
1039}
1040
b039eaaf 1041fn get_meta_items(md: rbml::Doc) -> Vec<P<ast::MetaItem>> {
62682a34 1042 reader::tagged_docs(md, tag_meta_item_word).map(|meta_item_doc| {
223e47cc 1043 let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
1a4d82fc 1044 let n = token::intern_and_get_ident(nd.as_str_slice());
62682a34
SL
1045 attr::mk_word_item(n)
1046 }).chain(reader::tagged_docs(md, tag_meta_item_name_value).map(|meta_item_doc| {
223e47cc
LB
1047 let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
1048 let vd = reader::get_doc(meta_item_doc, tag_meta_item_value);
1a4d82fc
JJ
1049 let n = token::intern_and_get_ident(nd.as_str_slice());
1050 let v = token::intern_and_get_ident(vd.as_str_slice());
1051 // FIXME (#623): Should be able to decode MetaNameValue variants,
223e47cc 1052 // but currently the encoder just drops them
62682a34
SL
1053 attr::mk_name_value_item_str(n, v)
1054 })).chain(reader::tagged_docs(md, tag_meta_item_list).map(|meta_item_doc| {
223e47cc 1055 let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
1a4d82fc 1056 let n = token::intern_and_get_ident(nd.as_str_slice());
223e47cc 1057 let subitems = get_meta_items(meta_item_doc);
62682a34
SL
1058 attr::mk_list_item(n, subitems)
1059 })).collect()
223e47cc
LB
1060}
1061
b039eaaf 1062fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
223e47cc 1063 match reader::maybe_get_doc(md, tag_attributes) {
62682a34
SL
1064 Some(attrs_d) => {
1065 reader::tagged_docs(attrs_d, tag_attribute).map(|attr_doc| {
1066 let is_sugared_doc = reader::doc_as_u8(
1067 reader::get_doc(attr_doc, tag_attribute_is_sugared_doc)
1068 ) == 1;
1069 let meta_items = get_meta_items(attr_doc);
1070 // Currently it's only possible to have a single meta item on
1071 // an attribute
1072 assert_eq!(meta_items.len(), 1);
1073 let meta_item = meta_items.into_iter().nth(0).unwrap();
1a4d82fc 1074 codemap::Spanned {
b039eaaf 1075 node: ast::Attribute_ {
1a4d82fc 1076 id: attr::mk_attr_id(),
b039eaaf 1077 style: ast::AttrStyle::Outer,
223e47cc 1078 value: meta_item,
1a4d82fc 1079 is_sugared_doc: is_sugared_doc,
223e47cc 1080 },
1a4d82fc 1081 span: codemap::DUMMY_SP
62682a34
SL
1082 }
1083 }).collect()
1084 },
1085 None => vec![],
223e47cc 1086 }
223e47cc
LB
1087}
1088
1a4d82fc 1089fn list_crate_attributes(md: rbml::Doc, hash: &Svh,
c34b1796 1090 out: &mut io::Write) -> io::Result<()> {
1a4d82fc 1091 try!(write!(out, "=Crate Attributes ({})=\n", *hash));
223e47cc 1092
970d7e83 1093 let r = get_attributes(md);
85aaf69f 1094 for attr in &r {
1a4d82fc 1095 try!(write!(out, "{}\n", pprust::attribute_to_string(attr)));
223e47cc
LB
1096 }
1097
1a4d82fc 1098 write!(out, "\n\n")
223e47cc
LB
1099}
1100
b039eaaf 1101pub fn get_crate_attributes(data: &[u8]) -> Vec<ast::Attribute> {
1a4d82fc 1102 get_attributes(rbml::Doc::new(data))
223e47cc
LB
1103}
1104
1a4d82fc
JJ
1105#[derive(Clone)]
1106pub struct CrateDep {
1107 pub cnum: ast::CrateNum,
1108 pub name: String,
1109 pub hash: Svh,
e9174d1e 1110 pub explicitly_linked: bool,
223e47cc
LB
1111}
1112
1a4d82fc 1113pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
1a4d82fc 1114 let cratedoc = rbml::Doc::new(data);
223e47cc 1115 let depsdoc = reader::get_doc(cratedoc, tag_crate_deps);
62682a34 1116
c34b1796 1117 fn docstr(doc: rbml::Doc, tag_: usize) -> String {
970d7e83 1118 let d = reader::get_doc(doc, tag_);
1a4d82fc 1119 d.as_str_slice().to_string()
223e47cc 1120 }
62682a34
SL
1121
1122 reader::tagged_docs(depsdoc, tag_crate_dep).enumerate().map(|(crate_num, depdoc)| {
1a4d82fc 1123 let name = docstr(depdoc, tag_crate_dep_crate_name);
c34b1796 1124 let hash = Svh::new(&docstr(depdoc, tag_crate_dep_hash));
e9174d1e
SL
1125 let doc = reader::get_doc(depdoc, tag_crate_dep_explicitly_linked);
1126 let explicitly_linked = reader::doc_as_u8(doc) != 0;
62682a34
SL
1127 CrateDep {
1128 cnum: crate_num as u32 + 1,
1a4d82fc
JJ
1129 name: name,
1130 hash: hash,
e9174d1e 1131 explicitly_linked: explicitly_linked,
62682a34
SL
1132 }
1133 }).collect()
223e47cc
LB
1134}
1135
c34b1796 1136fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> {
1a4d82fc 1137 try!(write!(out, "=External Dependencies=\n"));
85aaf69f 1138 for dep in &get_crate_deps(data) {
1a4d82fc 1139 try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash));
223e47cc 1140 }
1a4d82fc
JJ
1141 try!(write!(out, "\n"));
1142 Ok(())
1143}
223e47cc 1144
1a4d82fc
JJ
1145pub fn maybe_get_crate_hash(data: &[u8]) -> Option<Svh> {
1146 let cratedoc = rbml::Doc::new(data);
1147 reader::maybe_get_doc(cratedoc, tag_crate_hash).map(|doc| {
1148 Svh::new(doc.as_str_slice())
1149 })
223e47cc
LB
1150}
1151
1a4d82fc
JJ
1152pub fn get_crate_hash(data: &[u8]) -> Svh {
1153 let cratedoc = rbml::Doc::new(data);
223e47cc 1154 let hashdoc = reader::get_doc(cratedoc, tag_crate_hash);
1a4d82fc 1155 Svh::new(hashdoc.as_str_slice())
223e47cc
LB
1156}
1157
1a4d82fc
JJ
1158pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
1159 let cratedoc = rbml::Doc::new(data);
1160 reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| {
1161 doc.as_str_slice().to_string()
1162 })
1163}
223e47cc 1164
1a4d82fc
JJ
1165pub fn get_crate_triple(data: &[u8]) -> Option<String> {
1166 let cratedoc = rbml::Doc::new(data);
1167 let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);
1168 triple_doc.map(|s| s.as_str().to_string())
223e47cc
LB
1169}
1170
1a4d82fc
JJ
1171pub fn get_crate_name(data: &[u8]) -> String {
1172 maybe_get_crate_name(data).expect("no crate name in crate")
223e47cc
LB
1173}
1174
c34b1796 1175pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> {
223e47cc 1176 let hash = get_crate_hash(bytes);
1a4d82fc
JJ
1177 let md = rbml::Doc::new(bytes);
1178 try!(list_crate_attributes(md, &hash, out));
1179 list_crate_deps(bytes, out)
223e47cc
LB
1180}
1181
1182// Translates a def_id from an external crate to a def_id for the current
1183// compilation environment. We use this when trying to load types from
1184// external crates - if those types further refer to types in other crates
1185// then we must translate the crate number from that encoded in the external
1186// crate to the correct local crate number.
e9174d1e
SL
1187pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId {
1188 if did.is_local() {
b039eaaf 1189 return DefId { krate: cdata.cnum, index: did.index };
223e47cc
LB
1190 }
1191
e9174d1e 1192 match cdata.cnum_map.borrow().get(&did.krate) {
1a4d82fc 1193 Some(&n) => {
e9174d1e 1194 DefId {
1a4d82fc 1195 krate: n,
b039eaaf 1196 index: did.index,
1a4d82fc
JJ
1197 }
1198 }
1199 None => panic!("didn't find a crate in the cnum_map")
223e47cc
LB
1200 }
1201}
1202
d9579d0f
AL
1203// Translate a DefId from the current compilation environment to a DefId
1204// for an external crate.
e9174d1e 1205fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> {
d9579d0f 1206 if did.krate == cdata.cnum {
b039eaaf 1207 return Some(DefId { krate: LOCAL_CRATE, index: did.index });
d9579d0f
AL
1208 }
1209
e9174d1e 1210 for (&local, &global) in cdata.cnum_map.borrow().iter() {
d9579d0f 1211 if global == did.krate {
b039eaaf 1212 return Some(DefId { krate: local, index: did.index });
d9579d0f
AL
1213 }
1214 }
1215
1216 None
1a4d82fc
JJ
1217}
1218
d9579d0f 1219pub fn each_inherent_implementation_for_type<F>(cdata: Cmd,
b039eaaf 1220 id: DefIndex,
d9579d0f 1221 mut callback: F)
e9174d1e 1222 where F: FnMut(DefId),
1a4d82fc 1223{
e9174d1e 1224 let item_doc = cdata.lookup_item(id);
62682a34 1225 for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_inherent_impl) {
d9579d0f
AL
1226 if reader::maybe_get_doc(impl_doc, tag_item_trait_ref).is_none() {
1227 callback(item_def_id(impl_doc, cdata));
1228 }
62682a34 1229 }
1a4d82fc
JJ
1230}
1231
1232pub fn each_implementation_for_trait<F>(cdata: Cmd,
e9174d1e 1233 def_id: DefId,
1a4d82fc 1234 mut callback: F) where
e9174d1e 1235 F: FnMut(DefId),
1a4d82fc 1236{
d9579d0f
AL
1237 // Do a reverse lookup beforehand to avoid touching the crate_num
1238 // hash map in the loop below.
1239 if let Some(crate_local_did) = reverse_translate_def_id(cdata, def_id) {
1240 let def_id_u64 = def_to_u64(crate_local_did);
1241
1242 let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls);
b039eaaf
SL
1243 for trait_doc in reader::tagged_docs(impls_doc, tag_impls_trait) {
1244 let trait_def_id = reader::get_doc(trait_doc, tag_def_id);
1245 if reader::doc_as_u64(trait_def_id) != def_id_u64 {
1246 continue;
1247 }
1248 for impl_doc in reader::tagged_docs(trait_doc, tag_impls_trait_impl) {
1249 callback(translated_def_id(cdata, impl_doc));
d9579d0f 1250 }
62682a34 1251 }
d9579d0f 1252 }
1a4d82fc
JJ
1253}
1254
b039eaaf 1255pub fn get_trait_of_item(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt)
e9174d1e
SL
1256 -> Option<DefId> {
1257 let item_doc = cdata.lookup_item(id);
d9579d0f 1258 let parent_item_id = match item_parent_item(cdata, item_doc) {
1a4d82fc
JJ
1259 None => return None,
1260 Some(item_id) => item_id,
1261 };
b039eaaf 1262 let parent_item_doc = cdata.lookup_item(parent_item_id.index);
1a4d82fc
JJ
1263 match item_family(parent_item_doc) {
1264 Trait => Some(item_def_id(parent_item_doc, cdata)),
c34b1796 1265 Impl | DefaultImpl => {
1a4d82fc
JJ
1266 reader::maybe_get_doc(parent_item_doc, tag_item_trait_ref)
1267 .map(|_| item_trait_ref(parent_item_doc, tcx, cdata).def_id)
1268 }
1269 _ => None
1270 }
1271}
1272
1273
1274pub fn get_native_libraries(cdata: Cmd)
1275 -> Vec<(cstore::NativeLibraryKind, String)> {
1276 let libraries = reader::get_doc(rbml::Doc::new(cdata.data()),
1277 tag_native_libraries);
62682a34 1278 reader::tagged_docs(libraries, tag_native_libraries_lib).map(|lib_doc| {
1a4d82fc
JJ
1279 let kind_doc = reader::get_doc(lib_doc, tag_native_libraries_kind);
1280 let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name);
1281 let kind: cstore::NativeLibraryKind =
9346a6ac 1282 cstore::NativeLibraryKind::from_u32(reader::doc_as_u32(kind_doc)).unwrap();
1a4d82fc 1283 let name = name_doc.as_str().to_string();
62682a34
SL
1284 (kind, name)
1285 }).collect()
1a4d82fc
JJ
1286}
1287
b039eaaf 1288pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<DefIndex> {
1a4d82fc 1289 reader::maybe_get_doc(rbml::Doc::new(data), tag_plugin_registrar_fn)
b039eaaf 1290 .map(|doc| DefIndex::from_u32(reader::doc_as_u32(doc)))
1a4d82fc
JJ
1291}
1292
1293pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner, mut f: F) where
b039eaaf 1294 F: FnMut(ast::Name, Vec<ast::Attribute>, String) -> bool,
1a4d82fc
JJ
1295{
1296 let macros = reader::get_doc(rbml::Doc::new(data), tag_macro_defs);
62682a34 1297 for macro_doc in reader::tagged_docs(macros, tag_macro_def) {
1a4d82fc
JJ
1298 let name = item_name(intr, macro_doc);
1299 let attrs = get_attributes(macro_doc);
1300 let body = reader::get_doc(macro_doc, tag_macro_def_body);
62682a34
SL
1301 if !f(name, attrs, body.as_str().to_string()) {
1302 break;
1303 }
1304 }
1a4d82fc
JJ
1305}
1306
1307pub fn get_dylib_dependency_formats(cdata: Cmd)
92a42be0 1308 -> Vec<(ast::CrateNum, LinkagePreference)>
1a4d82fc
JJ
1309{
1310 let formats = reader::get_doc(rbml::Doc::new(cdata.data()),
1311 tag_dylib_dependency_formats);
1312 let mut result = Vec::new();
1313
1314 debug!("found dylib deps: {}", formats.as_str_slice());
1315 for spec in formats.as_str_slice().split(',') {
9346a6ac 1316 if spec.is_empty() { continue }
1a4d82fc
JJ
1317 let cnum = spec.split(':').nth(0).unwrap();
1318 let link = spec.split(':').nth(1).unwrap();
1319 let cnum: ast::CrateNum = cnum.parse().unwrap();
e9174d1e 1320 let cnum = match cdata.cnum_map.borrow().get(&cnum) {
1a4d82fc
JJ
1321 Some(&n) => n,
1322 None => panic!("didn't find a crate in the cnum_map")
1323 };
1324 result.push((cnum, if link == "d" {
92a42be0 1325 LinkagePreference::RequireDynamic
1a4d82fc 1326 } else {
92a42be0 1327 LinkagePreference::RequireStatic
1a4d82fc
JJ
1328 }));
1329 }
1330 return result;
1331}
1332
1333pub fn get_missing_lang_items(cdata: Cmd)
1334 -> Vec<lang_items::LangItem>
1335{
1336 let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_lang_items);
62682a34
SL
1337 reader::tagged_docs(items, tag_lang_items_missing).map(|missing_docs| {
1338 lang_items::LangItem::from_u32(reader::doc_as_u32(missing_docs)).unwrap()
1339 }).collect()
1a4d82fc
JJ
1340}
1341
b039eaaf 1342pub fn get_method_arg_names(cdata: Cmd, id: DefIndex) -> Vec<String> {
e9174d1e 1343 let method_doc = cdata.lookup_item(id);
1a4d82fc
JJ
1344 match reader::maybe_get_doc(method_doc, tag_method_argument_names) {
1345 Some(args_doc) => {
62682a34
SL
1346 reader::tagged_docs(args_doc, tag_method_argument_name).map(|name_doc| {
1347 name_doc.as_str_slice().to_string()
1348 }).collect()
1349 },
1350 None => vec![],
1a4d82fc 1351 }
1a4d82fc
JJ
1352}
1353
e9174d1e 1354pub fn get_reachable_ids(cdata: Cmd) -> Vec<DefId> {
1a4d82fc 1355 let items = reader::get_doc(rbml::Doc::new(cdata.data()),
e9174d1e
SL
1356 tag_reachable_ids);
1357 reader::tagged_docs(items, tag_reachable_id).map(|doc| {
1358 DefId {
1a4d82fc 1359 krate: cdata.cnum,
b039eaaf 1360 index: DefIndex::from_u32(reader::doc_as_u32(doc)),
62682a34
SL
1361 }
1362 }).collect()
1a4d82fc
JJ
1363}
1364
b039eaaf 1365pub fn is_typedef(cdata: Cmd, id: DefIndex) -> bool {
e9174d1e 1366 let item_doc = cdata.lookup_item(id);
1a4d82fc
JJ
1367 match item_family(item_doc) {
1368 Type => true,
1369 _ => false,
1370 }
1371}
1372
b039eaaf 1373pub fn is_const_fn(cdata: Cmd, id: DefIndex) -> bool {
e9174d1e 1374 let item_doc = cdata.lookup_item(id);
62682a34 1375 match fn_constness(item_doc) {
e9174d1e
SL
1376 hir::Constness::Const => true,
1377 hir::Constness::NotConst => false,
62682a34
SL
1378 }
1379}
1380
92a42be0
SL
1381pub fn is_static(cdata: Cmd, id: DefIndex) -> bool {
1382 let item_doc = cdata.lookup_item(id);
1383 match item_family(item_doc) {
1384 ImmStatic | MutStatic => true,
1385 _ => false,
1386 }
1387}
1388
b039eaaf 1389pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
e9174d1e 1390 let item_doc = cdata.lookup_item(id);
62682a34
SL
1391 match item_family(item_doc) {
1392 Impl => true,
1393 _ => false,
1394 }
1395}
1396
1a4d82fc
JJ
1397fn doc_generics<'tcx>(base_doc: rbml::Doc,
1398 tcx: &ty::ctxt<'tcx>,
1399 cdata: Cmd,
c34b1796 1400 tag: usize)
1a4d82fc
JJ
1401 -> ty::Generics<'tcx>
1402{
1403 let doc = reader::get_doc(base_doc, tag);
1404
1405 let mut types = subst::VecPerParamSpace::empty();
62682a34 1406 for p in reader::tagged_docs(doc, tag_type_param_def) {
e9174d1e
SL
1407 let bd =
1408 TyDecoder::with_doc(tcx, cdata.cnum, p,
b039eaaf 1409 &mut |did| translate_def_id(cdata, did))
e9174d1e 1410 .parse_type_param_def();
1a4d82fc 1411 types.push(bd.space, bd);
62682a34 1412 }
1a4d82fc
JJ
1413
1414 let mut regions = subst::VecPerParamSpace::empty();
62682a34 1415 for rp_doc in reader::tagged_docs(doc, tag_region_param_def) {
1a4d82fc
JJ
1416 let ident_str_doc = reader::get_doc(rp_doc,
1417 tag_region_param_def_ident);
1418 let name = item_name(&*token::get_ident_interner(), ident_str_doc);
1419 let def_id_doc = reader::get_doc(rp_doc,
1420 tag_region_param_def_def_id);
d9579d0f 1421 let def_id = translated_def_id(cdata, def_id_doc);
1a4d82fc
JJ
1422
1423 let doc = reader::get_doc(rp_doc, tag_region_param_def_space);
c34b1796 1424 let space = subst::ParamSpace::from_uint(reader::doc_as_u64(doc) as usize);
1a4d82fc
JJ
1425
1426 let doc = reader::get_doc(rp_doc, tag_region_param_def_index);
1427 let index = reader::doc_as_u64(doc) as u32;
1428
62682a34 1429 let bounds = reader::tagged_docs(rp_doc, tag_items_data_region).map(|p| {
e9174d1e 1430 TyDecoder::with_doc(tcx, cdata.cnum, p,
b039eaaf 1431 &mut |did| translate_def_id(cdata, did))
e9174d1e 1432 .parse_region()
62682a34 1433 }).collect();
1a4d82fc
JJ
1434
1435 regions.push(space, ty::RegionParameterDef { name: name,
1436 def_id: def_id,
1437 space: space,
1438 index: index,
1439 bounds: bounds });
62682a34 1440 }
1a4d82fc 1441
85aaf69f
SL
1442 ty::Generics { types: types, regions: regions }
1443}
1444
b039eaaf
SL
1445fn doc_predicate<'tcx>(cdata: Cmd,
1446 doc: rbml::Doc,
1447 tcx: &ty::ctxt<'tcx>)
1448 -> ty::Predicate<'tcx>
1449{
1450 let predicate_pos = cdata.xref_index.lookup(
1451 cdata.data(), reader::doc_as_u32(doc)).unwrap() as usize;
1452 TyDecoder::new(
1453 cdata.data(), cdata.cnum, predicate_pos, tcx,
1454 &mut |did| translate_def_id(cdata, did)
1455 ).parse_predicate()
1456}
1457
85aaf69f
SL
1458fn doc_predicates<'tcx>(base_doc: rbml::Doc,
1459 tcx: &ty::ctxt<'tcx>,
1460 cdata: Cmd,
c34b1796 1461 tag: usize)
85aaf69f
SL
1462 -> ty::GenericPredicates<'tcx>
1463{
1464 let doc = reader::get_doc(base_doc, tag);
1465
1a4d82fc 1466 let mut predicates = subst::VecPerParamSpace::empty();
b039eaaf
SL
1467 for predicate_doc in reader::tagged_docs(doc, tag_type_predicate) {
1468 predicates.push(subst::TypeSpace,
1469 doc_predicate(cdata, predicate_doc, tcx));
1470 }
1471 for predicate_doc in reader::tagged_docs(doc, tag_self_predicate) {
1472 predicates.push(subst::SelfSpace,
1473 doc_predicate(cdata, predicate_doc, tcx));
1474 }
1475 for predicate_doc in reader::tagged_docs(doc, tag_fn_predicate) {
1476 predicates.push(subst::FnSpace,
1477 doc_predicate(cdata, predicate_doc, tcx));
62682a34 1478 }
1a4d82fc 1479
85aaf69f 1480 ty::GenericPredicates { predicates: predicates }
1a4d82fc
JJ
1481}
1482
b039eaaf 1483pub fn is_defaulted_trait(cdata: Cmd, trait_id: DefIndex) -> bool {
e9174d1e 1484 let trait_doc = cdata.lookup_item(trait_id);
c34b1796
AL
1485 assert!(item_family(trait_doc) == Family::Trait);
1486 let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait);
1487 reader::doc_as_u8(defaulted_doc) != 0
1488}
1489
b039eaaf 1490pub fn is_default_impl(cdata: Cmd, impl_id: DefIndex) -> bool {
e9174d1e 1491 let impl_doc = cdata.lookup_item(impl_id);
c34b1796
AL
1492 item_family(impl_doc) == Family::DefaultImpl
1493}
1494
1495pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
1496 let crate_doc = rbml::Doc::new(metadata);
1497 let cm_doc = reader::get_doc(crate_doc, tag_codemap);
1498
62682a34 1499 reader::tagged_docs(cm_doc, tag_codemap_filemap).map(|filemap_doc| {
c34b1796 1500 let mut decoder = reader::Decoder::new(filemap_doc);
62682a34
SL
1501 Decodable::decode(&mut decoder).unwrap()
1502 }).collect()
c34b1796 1503}
e9174d1e 1504
b039eaaf 1505pub fn is_extern_fn(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt) -> bool {
e9174d1e
SL
1506 let item_doc = match cdata.get_item(id) {
1507 Some(doc) => doc,
1508 None => return false,
1509 };
1510 if let Fn = item_family(item_doc) {
1511 let ty::TypeScheme { generics, ty } = get_type(cdata, id, tcx);
1512 generics.types.is_empty() && match ty.sty {
1513 ty::TyBareFn(_, fn_ty) => fn_ty.abi != abi::Rust,
1514 _ => false,
1515 }
1516 } else {
1517 false
1518 }
1519}
b039eaaf
SL
1520
1521pub fn closure_kind(cdata: Cmd, closure_id: DefIndex) -> ty::ClosureKind {
1522 let closure_doc = cdata.lookup_item(closure_id);
1523 let closure_kind_doc = reader::get_doc(closure_doc, tag_items_closure_kind);
1524 let mut decoder = reader::Decoder::new(closure_kind_doc);
1525 ty::ClosureKind::decode(&mut decoder).unwrap()
1526}
1527
1528pub fn closure_ty<'tcx>(cdata: Cmd, closure_id: DefIndex, tcx: &ty::ctxt<'tcx>)
1529 -> ty::ClosureTy<'tcx> {
1530 let closure_doc = cdata.lookup_item(closure_id);
1531 let closure_ty_doc = reader::get_doc(closure_doc, tag_items_closure_ty);
1532 TyDecoder::with_doc(tcx, cdata.cnum, closure_ty_doc, &mut |did| translate_def_id(cdata, did))
1533 .parse_closure_ty()
1534}
1535
1536fn def_key(item_doc: rbml::Doc) -> hir_map::DefKey {
1537 match reader::maybe_get_doc(item_doc, tag_def_key) {
1538 Some(def_key_doc) => {
1539 let mut decoder = reader::Decoder::new(def_key_doc);
1540 hir_map::DefKey::decode(&mut decoder).unwrap()
1541 }
1542 None => {
1543 panic!("failed to find block with tag {:?} for item with family {:?}",
1544 tag_def_key,
1545 item_family(item_doc))
1546 }
1547 }
1548}
1549
1550pub fn def_path(cdata: Cmd, id: DefIndex) -> hir_map::DefPath {
1551 debug!("def_path(id={:?})", id);
1552 hir_map::definitions::make_def_path(id, |parent| {
1553 debug!("def_path: parent={:?}", parent);
1554 let parent_doc = cdata.lookup_item(parent);
1555 def_key(parent_doc)
1556 })
1557}