1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // Decoding metadata from a single crate's metadata
13 #![allow(non_camel_case_types)]
15 pub use self::DefLike
::*;
18 use front
::map
as ast_map
;
19 use rustc_front
::print
::pprust
;
23 use metadata
::cstore
::crate_metadata
;
24 use metadata
::common
::*;
25 use metadata
::csearch
::MethodInfo
;
26 use metadata
::csearch
;
28 use metadata
::encoder
::def_to_u64
;
30 use metadata
::inline
::InlinedItem
;
31 use metadata
::tydecode
::TyDecoder
;
33 use middle
::def_id
::{DefId, LOCAL_CRATE}
;
34 use middle
::lang_items
;
36 use middle
::ty
::{ImplContainer, TraitContainer}
;
37 use middle
::ty
::{self, RegionEscape, Ty}
;
38 use util
::nodemap
::FnvHashMap
;
40 use std
::cell
::{Cell, RefCell}
;
41 use std
::io
::prelude
::*;
48 use serialize
::Decodable
;
49 use rustc_front
::attr
;
50 use syntax
::parse
::token
::{IdentInterner, special_idents}
;
51 use syntax
::parse
::token
;
58 pub type Cmd
<'a
> = &'a crate_metadata
;
61 fn get_item(&self, item_id
: ast
::NodeId
) -> Option
<rbml
::Doc
> {
62 self.index
.lookup_item(self.data(), item_id
).map(|pos
| {
63 reader
::doc_at(self.data(), pos
as usize).unwrap().doc
67 fn lookup_item(&self, item_id
: ast
::NodeId
) -> rbml
::Doc
{
68 match self.get_item(item_id
) {
69 None
=> panic
!("lookup_item: id not found: {}", item_id
),
75 pub fn load_index(data
: &[u8]) -> index
::Index
{
76 let index
= reader
::get_doc(rbml
::Doc
::new(data
), tag_index
);
77 index
::Index
::from_buf(index
.data
, index
.start
, index
.end
)
80 #[derive(Debug, PartialEq)]
103 fn item_family(item
: rbml
::Doc
) -> Family
{
104 let fam
= reader
::get_doc(item
, tag_items_data_item_family
);
105 match reader
::doc_as_u8(fam
) as char {
118 'V'
=> StructVariant
,
124 'N'
=> InheritedField
,
125 c
=> panic
!("unexpected family char: {}", c
)
129 fn item_visibility(item
: rbml
::Doc
) -> hir
::Visibility
{
130 match reader
::maybe_get_doc(item
, tag_items_data_item_visibility
) {
132 Some(visibility_doc
) => {
133 match reader
::doc_as_u8(visibility_doc
) as char {
135 'i'
=> hir
::Inherited
,
136 _
=> panic
!("unknown visibility character")
142 fn fn_constness(item
: rbml
::Doc
) -> hir
::Constness
{
143 match reader
::maybe_get_doc(item
, tag_items_data_item_constness
) {
144 None
=> hir
::Constness
::NotConst
,
145 Some(constness_doc
) => {
146 match reader
::doc_as_u8(constness_doc
) as char {
147 'c'
=> hir
::Constness
::Const
,
148 'n'
=> hir
::Constness
::NotConst
,
149 _
=> panic
!("unknown constness character")
155 fn item_sort(item
: rbml
::Doc
) -> Option
<char> {
156 reader
::tagged_docs(item
, tag_item_trait_item_sort
).nth(0).map(|doc
| {
157 doc
.as_str_slice().as_bytes()[0] as char
161 fn item_symbol(item
: rbml
::Doc
) -> String
{
162 reader
::get_doc(item
, tag_items_data_item_symbol
).as_str().to_string()
165 fn translated_def_id(cdata
: Cmd
, d
: rbml
::Doc
) -> DefId
{
166 let id
= reader
::doc_as_u64(d
);
167 let def_id
= DefId { krate: (id >> 32) as u32, node: id as u32 }
;
168 translate_def_id(cdata
, def_id
)
171 fn item_parent_item(cdata
: Cmd
, d
: rbml
::Doc
) -> Option
<DefId
> {
172 reader
::tagged_docs(d
, tag_items_data_parent_item
).nth(0).map(|did
| {
173 translated_def_id(cdata
, did
)
177 fn item_require_parent_item(cdata
: Cmd
, d
: rbml
::Doc
) -> DefId
{
178 translated_def_id(cdata
, reader
::get_doc(d
, tag_items_data_parent_item
))
181 fn item_def_id(d
: rbml
::Doc
, cdata
: Cmd
) -> DefId
{
182 translated_def_id(cdata
, reader
::get_doc(d
, tag_def_id
))
185 fn get_provided_source(d
: rbml
::Doc
, cdata
: Cmd
) -> Option
<DefId
> {
186 reader
::maybe_get_doc(d
, tag_item_method_provided_source
).map(|doc
| {
187 translated_def_id(cdata
, doc
)
191 fn reexports
<'a
>(d
: rbml
::Doc
<'a
>) -> reader
::TaggedDocsIterator
<'a
> {
192 reader
::tagged_docs(d
, tag_items_data_item_reexport
)
195 fn variant_disr_val(d
: rbml
::Doc
) -> Option
<ty
::Disr
> {
196 reader
::maybe_get_doc(d
, tag_disr_val
).and_then(|val_doc
| {
197 reader
::with_doc_data(val_doc
, |data
| {
198 str::from_utf8(data
).ok().and_then(|s
| s
.parse().ok())
203 fn doc_type
<'tcx
>(doc
: rbml
::Doc
, tcx
: &ty
::ctxt
<'tcx
>, cdata
: Cmd
) -> Ty
<'tcx
> {
204 let tp
= reader
::get_doc(doc
, tag_items_data_item_type
);
205 TyDecoder
::with_doc(tcx
, cdata
.cnum
, tp
,
206 &mut |_
, did
| translate_def_id(cdata
, did
))
210 fn maybe_doc_type
<'tcx
>(doc
: rbml
::Doc
, tcx
: &ty
::ctxt
<'tcx
>, cdata
: Cmd
) -> Option
<Ty
<'tcx
>> {
211 reader
::maybe_get_doc(doc
, tag_items_data_item_type
).map(|tp
| {
212 TyDecoder
::with_doc(tcx
, cdata
.cnum
, tp
,
213 &mut |_
, did
| translate_def_id(cdata
, did
))
218 fn doc_method_fty
<'tcx
>(doc
: rbml
::Doc
, tcx
: &ty
::ctxt
<'tcx
>,
219 cdata
: Cmd
) -> ty
::BareFnTy
<'tcx
> {
220 let tp
= reader
::get_doc(doc
, tag_item_method_fty
);
221 TyDecoder
::with_doc(tcx
, cdata
.cnum
, tp
,
222 &mut |_
, did
| translate_def_id(cdata
, did
))
226 pub fn item_type
<'tcx
>(_item_id
: DefId
, item
: rbml
::Doc
,
227 tcx
: &ty
::ctxt
<'tcx
>, cdata
: Cmd
) -> Ty
<'tcx
> {
228 doc_type(item
, tcx
, cdata
)
231 fn doc_trait_ref
<'tcx
>(doc
: rbml
::Doc
, tcx
: &ty
::ctxt
<'tcx
>, cdata
: Cmd
)
232 -> ty
::TraitRef
<'tcx
> {
233 TyDecoder
::with_doc(tcx
, cdata
.cnum
, doc
,
234 &mut |_
, did
| translate_def_id(cdata
, did
))
238 fn item_trait_ref
<'tcx
>(doc
: rbml
::Doc
, tcx
: &ty
::ctxt
<'tcx
>, cdata
: Cmd
)
239 -> ty
::TraitRef
<'tcx
> {
240 let tp
= reader
::get_doc(doc
, tag_item_trait_ref
);
241 doc_trait_ref(tp
, tcx
, cdata
)
244 fn item_path(item_doc
: rbml
::Doc
) -> Vec
<ast_map
::PathElem
> {
245 let path_doc
= reader
::get_doc(item_doc
, tag_path
);
246 reader
::docs(path_doc
).filter_map(|(tag
, elt_doc
)| {
247 if tag
== tag_path_elem_mod
{
248 let s
= elt_doc
.as_str_slice();
249 Some(ast_map
::PathMod(token
::intern(s
)))
250 } else if tag
== tag_path_elem_name
{
251 let s
= elt_doc
.as_str_slice();
252 Some(ast_map
::PathName(token
::intern(s
)))
254 // ignore tag_path_len element
260 fn item_name(intr
: &IdentInterner
, item
: rbml
::Doc
) -> ast
::Name
{
261 let name
= reader
::get_doc(item
, tag_paths_data_name
);
262 let string
= name
.as_str_slice();
263 match intr
.find(string
) {
264 None
=> token
::intern(string
),
269 fn item_to_def_like(cdata
: Cmd
, item
: rbml
::Doc
, did
: DefId
) -> DefLike
{
270 let fam
= item_family(item
);
273 // Check whether we have an associated const item.
274 if item_sort(item
) == Some('C'
) {
275 DlDef(def
::DefAssociatedConst(did
))
277 // Regular const item.
278 DlDef(def
::DefConst(did
))
281 ImmStatic
=> DlDef(def
::DefStatic(did
, false)),
282 MutStatic
=> DlDef(def
::DefStatic(did
, true)),
283 Struct
=> DlDef(def
::DefStruct(did
)),
284 Fn
=> DlDef(def
::DefFn(did
, false)),
285 CtorFn
=> DlDef(def
::DefFn(did
, true)),
286 Method
| StaticMethod
=> {
287 DlDef(def
::DefMethod(did
))
290 if item_sort(item
) == Some('t'
) {
291 let trait_did
= item_require_parent_item(cdata
, item
);
292 DlDef(def
::DefAssociatedTy(trait_did
, did
))
294 DlDef(def
::DefTy(did
, false))
297 Mod
=> DlDef(def
::DefMod(did
)),
298 ForeignMod
=> DlDef(def
::DefForeignMod(did
)),
300 let enum_did
= item_require_parent_item(cdata
, item
);
301 DlDef(def
::DefVariant(enum_did
, did
, true))
304 let enum_did
= item_require_parent_item(cdata
, item
);
305 DlDef(def
::DefVariant(enum_did
, did
, false))
307 Trait
=> DlDef(def
::DefTrait(did
)),
308 Enum
=> DlDef(def
::DefTy(did
, true)),
309 Impl
| DefaultImpl
=> DlImpl(did
),
310 PublicField
| InheritedField
=> DlField
,
314 fn parse_unsafety(item_doc
: rbml
::Doc
) -> hir
::Unsafety
{
315 let unsafety_doc
= reader
::get_doc(item_doc
, tag_unsafety
);
316 if reader
::doc_as_u8(unsafety_doc
) != 0 {
317 hir
::Unsafety
::Unsafe
319 hir
::Unsafety
::Normal
323 fn parse_paren_sugar(item_doc
: rbml
::Doc
) -> bool
{
324 let paren_sugar_doc
= reader
::get_doc(item_doc
, tag_paren_sugar
);
325 reader
::doc_as_u8(paren_sugar_doc
) != 0
328 fn parse_polarity(item_doc
: rbml
::Doc
) -> hir
::ImplPolarity
{
329 let polarity_doc
= reader
::get_doc(item_doc
, tag_polarity
);
330 if reader
::doc_as_u8(polarity_doc
) != 0 {
331 hir
::ImplPolarity
::Negative
333 hir
::ImplPolarity
::Positive
337 fn parse_associated_type_names(item_doc
: rbml
::Doc
) -> Vec
<ast
::Name
> {
338 let names_doc
= reader
::get_doc(item_doc
, tag_associated_type_names
);
339 reader
::tagged_docs(names_doc
, tag_associated_type_name
)
340 .map(|name_doc
| token
::intern(name_doc
.as_str_slice()))
344 pub fn get_trait_def
<'tcx
>(cdata
: Cmd
,
345 item_id
: ast
::NodeId
,
346 tcx
: &ty
::ctxt
<'tcx
>) -> ty
::TraitDef
<'tcx
>
348 let item_doc
= cdata
.lookup_item(item_id
);
349 let generics
= doc_generics(item_doc
, tcx
, cdata
, tag_item_generics
);
350 let unsafety
= parse_unsafety(item_doc
);
351 let associated_type_names
= parse_associated_type_names(item_doc
);
352 let paren_sugar
= parse_paren_sugar(item_doc
);
355 paren_sugar
: paren_sugar
,
358 trait_ref
: item_trait_ref(item_doc
, tcx
, cdata
),
359 associated_type_names
: associated_type_names
,
360 nonblanket_impls
: RefCell
::new(FnvHashMap()),
361 blanket_impls
: RefCell
::new(vec
![]),
362 flags
: Cell
::new(ty
::TraitFlags
::NO_TRAIT_FLAGS
)
366 pub fn get_adt_def
<'tcx
>(intr
: &IdentInterner
,
368 item_id
: ast
::NodeId
,
369 tcx
: &ty
::ctxt
<'tcx
>) -> ty
::AdtDefMaster
<'tcx
>
371 fn get_enum_variants
<'tcx
>(intr
: &IdentInterner
,
374 tcx
: &ty
::ctxt
<'tcx
>) -> Vec
<ty
::VariantDefData
<'tcx
, 'tcx
>> {
375 let mut disr_val
= 0;
376 reader
::tagged_docs(doc
, tag_items_data_item_variant
).map(|p
| {
377 let did
= translated_def_id(cdata
, p
);
378 let item
= cdata
.lookup_item(did
.node
);
380 if let Some(disr
) = variant_disr_val(item
) {
384 disr_val
= disr_val
.wrapping_add(1);
388 name
: item_name(intr
, item
),
389 fields
: get_variant_fields(intr
, cdata
, item
, tcx
),
394 fn get_variant_fields
<'tcx
>(intr
: &IdentInterner
,
397 tcx
: &ty
::ctxt
<'tcx
>) -> Vec
<ty
::FieldDefData
<'tcx
, 'tcx
>> {
398 reader
::tagged_docs(doc
, tag_item_field
).map(|f
| {
399 let ff
= item_family(f
);
401 PublicField
| InheritedField
=> {}
,
402 _
=> tcx
.sess
.bug(&format
!("expected field, found {:?}", ff
))
404 ty
::FieldDefData
::new(item_def_id(f
, cdata
),
406 struct_field_family_to_visibility(ff
))
407 }).chain(reader
::tagged_docs(doc
, tag_item_unnamed_field
).map(|f
| {
408 let ff
= item_family(f
);
409 ty
::FieldDefData
::new(item_def_id(f
, cdata
),
410 special_idents
::unnamed_field
.name
,
411 struct_field_family_to_visibility(ff
))
414 fn get_struct_variant
<'tcx
>(intr
: &IdentInterner
,
418 tcx
: &ty
::ctxt
<'tcx
>) -> ty
::VariantDefData
<'tcx
, 'tcx
> {
421 name
: item_name(intr
, doc
),
422 fields
: get_variant_fields(intr
, cdata
, doc
, tcx
),
427 let doc
= cdata
.lookup_item(item_id
);
428 let did
= DefId { krate: cdata.cnum, node: item_id }
;
429 let (kind
, variants
) = match item_family(doc
) {
430 Enum
=> (ty
::AdtKind
::Enum
,
431 get_enum_variants(intr
, cdata
, doc
, tcx
)),
432 Struct
=> (ty
::AdtKind
::Struct
,
433 vec
![get_struct_variant(intr
, cdata
, doc
, did
, tcx
)]),
434 _
=> tcx
.sess
.bug("get_adt_def called on a non-ADT")
437 let adt
= tcx
.intern_adt_def(did
, kind
, variants
);
439 // this needs to be done *after* the variant is interned,
440 // to support recursive structures
441 for variant
in &adt
.variants
{
442 if variant
.kind() == ty
::VariantKind
::Tuple
&&
443 adt
.adt_kind() == ty
::AdtKind
::Enum
{
444 // tuple-like enum variant fields aren't real items - get the types
446 debug
!("evaluating the ctor-type of {:?}",
448 let ctor_ty
= get_type(cdata
, variant
.did
.node
, tcx
).ty
;
449 debug
!("evaluating the ctor-type of {:?}.. {:?}",
452 let field_tys
= match ctor_ty
.sty
{
453 ty
::TyBareFn(_
, &ty
::BareFnTy
{ sig
: ty
::Binder(ty
::FnSig
{
456 // tuple-struct constructors don't have escaping regions
457 assert
!(!inputs
.has_escaping_regions());
460 _
=> tcx
.sess
.bug("tuple-variant ctor is not an ADT")
462 for (field
, &ty
) in variant
.fields
.iter().zip(field_tys
.iter()) {
463 field
.fulfill_ty(ty
);
466 for field
in &variant
.fields
{
467 debug
!("evaluating the type of {:?}::{:?}", variant
.name
, field
.name
);
468 let ty
= get_type(cdata
, field
.did
.node
, tcx
).ty
;
469 field
.fulfill_ty(ty
);
470 debug
!("evaluating the type of {:?}::{:?}: {:?}",
471 variant
.name
, field
.name
, ty
);
479 pub fn get_predicates
<'tcx
>(cdata
: Cmd
,
480 item_id
: ast
::NodeId
,
481 tcx
: &ty
::ctxt
<'tcx
>)
482 -> ty
::GenericPredicates
<'tcx
>
484 let item_doc
= cdata
.lookup_item(item_id
);
485 doc_predicates(item_doc
, tcx
, cdata
, tag_item_generics
)
488 pub fn get_super_predicates
<'tcx
>(cdata
: Cmd
,
489 item_id
: ast
::NodeId
,
490 tcx
: &ty
::ctxt
<'tcx
>)
491 -> ty
::GenericPredicates
<'tcx
>
493 let item_doc
= cdata
.lookup_item(item_id
);
494 doc_predicates(item_doc
, tcx
, cdata
, tag_item_super_predicates
)
497 pub fn get_type
<'tcx
>(cdata
: Cmd
, id
: ast
::NodeId
, tcx
: &ty
::ctxt
<'tcx
>)
498 -> ty
::TypeScheme
<'tcx
>
500 let item_doc
= cdata
.lookup_item(id
);
501 let t
= item_type(DefId { krate: cdata.cnum, node: id }
, item_doc
, tcx
,
503 let generics
= doc_generics(item_doc
, tcx
, cdata
, tag_item_generics
);
510 pub fn get_stability(cdata
: Cmd
, id
: ast
::NodeId
) -> Option
<attr
::Stability
> {
511 let item
= cdata
.lookup_item(id
);
512 reader
::maybe_get_doc(item
, tag_items_data_item_stability
).map(|doc
| {
513 let mut decoder
= reader
::Decoder
::new(doc
);
514 Decodable
::decode(&mut decoder
).unwrap()
518 pub fn get_repr_attrs(cdata
: Cmd
, id
: ast
::NodeId
) -> Vec
<attr
::ReprAttr
> {
519 let item
= cdata
.lookup_item(id
);
520 match reader
::maybe_get_doc(item
, tag_items_data_item_repr
).map(|doc
| {
521 let mut decoder
= reader
::Decoder
::new(doc
);
522 Decodable
::decode(&mut decoder
).unwrap()
524 Some(attrs
) => attrs
,
529 pub fn get_impl_polarity
<'tcx
>(cdata
: Cmd
,
531 -> Option
<hir
::ImplPolarity
>
533 let item_doc
= cdata
.lookup_item(id
);
534 let fam
= item_family(item_doc
);
537 Some(parse_polarity(item_doc
))
543 pub fn get_custom_coerce_unsized_kind
<'tcx
>(
546 -> Option
<ty
::adjustment
::CustomCoerceUnsized
>
548 let item_doc
= cdata
.lookup_item(id
);
549 reader
::maybe_get_doc(item_doc
, tag_impl_coerce_unsized_kind
).map(|kind_doc
| {
550 let mut decoder
= reader
::Decoder
::new(kind_doc
);
551 Decodable
::decode(&mut decoder
).unwrap()
555 pub fn get_impl_trait
<'tcx
>(cdata
: Cmd
,
557 tcx
: &ty
::ctxt
<'tcx
>)
558 -> Option
<ty
::TraitRef
<'tcx
>>
560 let item_doc
= cdata
.lookup_item(id
);
561 let fam
= item_family(item_doc
);
563 Family
::Impl
| Family
::DefaultImpl
=> {
564 reader
::maybe_get_doc(item_doc
, tag_item_trait_ref
).map(|tp
| {
565 doc_trait_ref(tp
, tcx
, cdata
)
572 pub fn get_symbol(cdata
: Cmd
, id
: ast
::NodeId
) -> String
{
573 return item_symbol(cdata
.lookup_item(id
));
576 /// If you have a crate_metadata, call get_symbol instead
577 pub fn get_symbol_from_buf(data
: &[u8], id
: ast
::NodeId
) -> String
{
578 let index
= load_index(data
);
579 let pos
= index
.lookup_item(data
, id
).unwrap();
580 let doc
= reader
::doc_at(data
, pos
as usize).unwrap().doc
;
584 // Something that a name can resolve to.
585 #[derive(Copy, Clone, Debug)]
592 /// Iterates over the language items in the given crate.
593 pub fn each_lang_item
<F
>(cdata
: Cmd
, mut f
: F
) -> bool
where
594 F
: FnMut(ast
::NodeId
, usize) -> bool
,
596 let root
= rbml
::Doc
::new(cdata
.data());
597 let lang_items
= reader
::get_doc(root
, tag_lang_items
);
598 reader
::tagged_docs(lang_items
, tag_lang_items_item
).all(|item_doc
| {
599 let id_doc
= reader
::get_doc(item_doc
, tag_lang_items_item_id
);
600 let id
= reader
::doc_as_u32(id_doc
) as usize;
601 let node_id_doc
= reader
::get_doc(item_doc
,
602 tag_lang_items_item_node_id
);
603 let node_id
= reader
::doc_as_u32(node_id_doc
) as ast
::NodeId
;
609 fn each_child_of_item_or_crate
<F
, G
>(intr
: Rc
<IdentInterner
>,
612 mut get_crate_data
: G
,
613 mut callback
: F
) where
614 F
: FnMut(DefLike
, ast
::Name
, hir
::Visibility
),
615 G
: FnMut(ast
::CrateNum
) -> Rc
<crate_metadata
>,
617 // Iterate over all children.
618 for child_info_doc
in reader
::tagged_docs(item_doc
, tag_mod_child
) {
619 let child_def_id
= translated_def_id(cdata
, child_info_doc
);
621 // This item may be in yet another crate if it was the child of a
623 let crate_data
= if child_def_id
.krate
== cdata
.cnum
{
626 Some(get_crate_data(child_def_id
.krate
))
628 let crate_data
= match crate_data
{
629 Some(ref cdata
) => &**cdata
,
634 match crate_data
.get_item(child_def_id
.node
) {
636 Some(child_item_doc
) => {
637 // Hand off the item to the callback.
638 let child_name
= item_name(&*intr
, child_item_doc
);
639 let def_like
= item_to_def_like(crate_data
, child_item_doc
, child_def_id
);
640 let visibility
= item_visibility(child_item_doc
);
641 callback(def_like
, child_name
, visibility
);
646 // As a special case, iterate over all static methods of
647 // associated implementations too. This is a bit of a botch.
649 for inherent_impl_def_id_doc
in reader
::tagged_docs(item_doc
,
650 tag_items_data_item_inherent_impl
) {
651 let inherent_impl_def_id
= item_def_id(inherent_impl_def_id_doc
, cdata
);
652 if let Some(inherent_impl_doc
) = cdata
.get_item(inherent_impl_def_id
.node
) {
653 for impl_item_def_id_doc
in reader
::tagged_docs(inherent_impl_doc
,
654 tag_item_impl_item
) {
655 let impl_item_def_id
= item_def_id(impl_item_def_id_doc
,
657 if let Some(impl_method_doc
) = cdata
.get_item(impl_item_def_id
.node
) {
658 if let StaticMethod
= item_family(impl_method_doc
) {
659 // Hand off the static method to the callback.
660 let static_method_name
= item_name(&*intr
, impl_method_doc
);
661 let static_method_def_like
= item_to_def_like(cdata
, impl_method_doc
,
663 callback(static_method_def_like
,
665 item_visibility(impl_method_doc
));
672 for reexport_doc
in reexports(item_doc
) {
673 let def_id_doc
= reader
::get_doc(reexport_doc
,
674 tag_items_data_item_reexport_def_id
);
675 let child_def_id
= translated_def_id(cdata
, def_id_doc
);
677 let name_doc
= reader
::get_doc(reexport_doc
,
678 tag_items_data_item_reexport_name
);
679 let name
= name_doc
.as_str_slice();
681 // This reexport may be in yet another crate.
682 let crate_data
= if child_def_id
.krate
== cdata
.cnum
{
685 Some(get_crate_data(child_def_id
.krate
))
687 let crate_data
= match crate_data
{
688 Some(ref cdata
) => &**cdata
,
693 if let Some(child_item_doc
) = crate_data
.get_item(child_def_id
.node
) {
694 // Hand off the item to the callback.
695 let def_like
= item_to_def_like(crate_data
, child_item_doc
, child_def_id
);
696 // These items have a public visibility because they're part of
697 // a public re-export.
698 callback(def_like
, token
::intern(name
), hir
::Public
);
703 /// Iterates over each child of the given item.
704 pub fn each_child_of_item
<F
, G
>(intr
: Rc
<IdentInterner
>,
709 F
: FnMut(DefLike
, ast
::Name
, hir
::Visibility
),
710 G
: FnMut(ast
::CrateNum
) -> Rc
<crate_metadata
>,
713 let item_doc
= match cdata
.get_item(id
) {
715 Some(item_doc
) => item_doc
,
718 each_child_of_item_or_crate(intr
,
725 /// Iterates over all the top-level crate items.
726 pub fn each_top_level_item_of_crate
<F
, G
>(intr
: Rc
<IdentInterner
>,
730 F
: FnMut(DefLike
, ast
::Name
, hir
::Visibility
),
731 G
: FnMut(ast
::CrateNum
) -> Rc
<crate_metadata
>,
733 let root_doc
= rbml
::Doc
::new(cdata
.data());
734 let misc_info_doc
= reader
::get_doc(root_doc
, tag_misc_info
);
735 let crate_items_doc
= reader
::get_doc(misc_info_doc
,
736 tag_misc_info_crate_items
);
738 each_child_of_item_or_crate(intr
,
745 pub fn get_item_path(cdata
: Cmd
, id
: ast
::NodeId
) -> Vec
<ast_map
::PathElem
> {
746 item_path(cdata
.lookup_item(id
))
749 pub fn get_item_name(intr
: &IdentInterner
, cdata
: Cmd
, id
: ast
::NodeId
) -> ast
::Name
{
750 item_name(intr
, cdata
.lookup_item(id
))
753 pub type DecodeInlinedItem
<'a
> =
754 Box
<for<'tcx
> FnMut(Cmd
,
756 Vec
<ast_map
::PathElem
>,
758 -> Result
<&'tcx InlinedItem
, Vec
<ast_map
::PathElem
>> + 'a
>;
760 pub fn maybe_get_item_ast
<'tcx
>(cdata
: Cmd
, tcx
: &ty
::ctxt
<'tcx
>, id
: ast
::NodeId
,
761 mut decode_inlined_item
: DecodeInlinedItem
)
762 -> csearch
::FoundAst
<'tcx
> {
763 debug
!("Looking up item: {}", id
);
764 let item_doc
= cdata
.lookup_item(id
);
765 let path
= item_path(item_doc
).split_last().unwrap().1.to_vec();
766 match decode_inlined_item(cdata
, tcx
, path
, item_doc
) {
767 Ok(ii
) => csearch
::FoundAst
::Found(ii
),
769 match item_parent_item(cdata
, item_doc
) {
771 let parent_item
= cdata
.lookup_item(did
.node
);
772 match decode_inlined_item(cdata
, tcx
, path
, parent_item
) {
773 Ok(ii
) => csearch
::FoundAst
::FoundParent(did
, ii
),
774 Err(_
) => csearch
::FoundAst
::NotFound
777 None
=> csearch
::FoundAst
::NotFound
783 fn get_explicit_self(item
: rbml
::Doc
) -> ty
::ExplicitSelfCategory
{
784 fn get_mutability(ch
: u8) -> hir
::Mutability
{
786 'i'
=> hir
::MutImmutable
,
787 'm'
=> hir
::MutMutable
,
788 _
=> panic
!("unknown mutability character: `{}`", ch
as char),
792 let explicit_self_doc
= reader
::get_doc(item
, tag_item_trait_method_explicit_self
);
793 let string
= explicit_self_doc
.as_str_slice();
795 let explicit_self_kind
= string
.as_bytes()[0];
796 match explicit_self_kind
as char {
797 's'
=> ty
::StaticExplicitSelfCategory
,
798 'v'
=> ty
::ByValueExplicitSelfCategory
,
799 '
~'
=> ty
::ByBoxExplicitSelfCategory
,
800 // FIXME(#4846) expl. region
802 ty
::ByReferenceExplicitSelfCategory(
804 get_mutability(string
.as_bytes()[1]))
806 _
=> panic
!("unknown self type code: `{}`", explicit_self_kind
as char)
810 /// Returns the def IDs of all the items in the given implementation.
811 pub fn get_impl_items(cdata
: Cmd
, impl_id
: ast
::NodeId
)
812 -> Vec
<ty
::ImplOrTraitItemId
> {
813 reader
::tagged_docs(cdata
.lookup_item(impl_id
), tag_item_impl_item
).map(|doc
| {
814 let def_id
= item_def_id(doc
, cdata
);
815 match item_sort(doc
) {
816 Some('C'
) => ty
::ConstTraitItemId(def_id
),
817 Some('r'
) | Some('p'
) => ty
::MethodTraitItemId(def_id
),
818 Some('t'
) => ty
::TypeTraitItemId(def_id
),
819 _
=> panic
!("unknown impl item sort"),
824 pub fn get_trait_name(intr
: Rc
<IdentInterner
>,
828 let doc
= cdata
.lookup_item(id
);
829 item_name(&*intr
, doc
)
832 pub fn is_static_method(cdata
: Cmd
, id
: ast
::NodeId
) -> bool
{
833 let doc
= cdata
.lookup_item(id
);
834 match item_sort(doc
) {
835 Some('r'
) | Some('p'
) => {
836 get_explicit_self(doc
) == ty
::StaticExplicitSelfCategory
842 pub fn get_impl_or_trait_item
<'tcx
>(intr
: Rc
<IdentInterner
>,
845 tcx
: &ty
::ctxt
<'tcx
>)
846 -> ty
::ImplOrTraitItem
<'tcx
> {
847 let item_doc
= cdata
.lookup_item(id
);
849 let def_id
= item_def_id(item_doc
, cdata
);
851 let container_id
= item_require_parent_item(cdata
, item_doc
);
852 let container_doc
= cdata
.lookup_item(container_id
.node
);
853 let container
= match item_family(container_doc
) {
854 Trait
=> TraitContainer(container_id
),
855 _
=> ImplContainer(container_id
),
858 let name
= item_name(&*intr
, item_doc
);
859 let vis
= item_visibility(item_doc
);
861 match item_sort(item_doc
) {
863 let ty
= doc_type(item_doc
, tcx
, cdata
);
864 let default = get_provided_source(item_doc
, cdata
);
865 ty
::ConstTraitItem(Rc
::new(ty
::AssociatedConst
{
870 container
: container
,
874 Some('r'
) | Some('p'
) => {
875 let generics
= doc_generics(item_doc
, tcx
, cdata
, tag_method_ty_generics
);
876 let predicates
= doc_predicates(item_doc
, tcx
, cdata
, tag_method_ty_generics
);
877 let fty
= doc_method_fty(item_doc
, tcx
, cdata
);
878 let explicit_self
= get_explicit_self(item_doc
);
879 let provided_source
= get_provided_source(item_doc
, cdata
);
881 ty
::MethodTraitItem(Rc
::new(ty
::Method
::new(name
,
892 let ty
= maybe_doc_type(item_doc
, tcx
, cdata
);
893 ty
::TypeTraitItem(Rc
::new(ty
::AssociatedType
{
898 container
: container
,
901 _
=> panic
!("unknown impl/trait item sort"),
905 pub fn get_trait_item_def_ids(cdata
: Cmd
, id
: ast
::NodeId
)
906 -> Vec
<ty
::ImplOrTraitItemId
> {
907 let item
= cdata
.lookup_item(id
);
908 reader
::tagged_docs(item
, tag_item_trait_item
).map(|mth
| {
909 let def_id
= item_def_id(mth
, cdata
);
910 match item_sort(mth
) {
911 Some('C'
) => ty
::ConstTraitItemId(def_id
),
912 Some('r'
) | Some('p'
) => ty
::MethodTraitItemId(def_id
),
913 Some('t'
) => ty
::TypeTraitItemId(def_id
),
914 _
=> panic
!("unknown trait item sort"),
919 pub fn get_item_variances(cdata
: Cmd
, id
: ast
::NodeId
) -> ty
::ItemVariances
{
920 let item_doc
= cdata
.lookup_item(id
);
921 let variance_doc
= reader
::get_doc(item_doc
, tag_item_variances
);
922 let mut decoder
= reader
::Decoder
::new(variance_doc
);
923 Decodable
::decode(&mut decoder
).unwrap()
926 pub fn get_provided_trait_methods
<'tcx
>(intr
: Rc
<IdentInterner
>,
929 tcx
: &ty
::ctxt
<'tcx
>)
930 -> Vec
<Rc
<ty
::Method
<'tcx
>>> {
931 let item
= cdata
.lookup_item(id
);
933 reader
::tagged_docs(item
, tag_item_trait_item
).filter_map(|mth_id
| {
934 let did
= item_def_id(mth_id
, cdata
);
935 let mth
= cdata
.lookup_item(did
.node
);
937 if item_sort(mth
) == Some('p'
) {
938 let trait_item
= get_impl_or_trait_item(intr
.clone(),
942 if let ty
::MethodTraitItem(ref method
) = trait_item
{
943 Some((*method
).clone())
953 pub fn get_associated_consts
<'tcx
>(intr
: Rc
<IdentInterner
>,
956 tcx
: &ty
::ctxt
<'tcx
>)
957 -> Vec
<Rc
<ty
::AssociatedConst
<'tcx
>>> {
958 let item
= cdata
.lookup_item(id
);
960 [tag_item_trait_item
, tag_item_impl_item
].iter().flat_map(|&tag
| {
961 reader
::tagged_docs(item
, tag
).filter_map(|ac_id
| {
962 let did
= item_def_id(ac_id
, cdata
);
963 let ac_doc
= cdata
.lookup_item(did
.node
);
965 if item_sort(ac_doc
) == Some('C'
) {
966 let trait_item
= get_impl_or_trait_item(intr
.clone(),
970 if let ty
::ConstTraitItem(ref ac
) = trait_item
{
982 pub fn get_type_name_if_impl(cdata
: Cmd
,
983 node_id
: ast
::NodeId
) -> Option
<ast
::Name
> {
984 let item
= cdata
.lookup_item(node_id
);
985 if item_family(item
) != Impl
{
989 reader
::tagged_docs(item
, tag_item_impl_type_basename
).nth(0).map(|doc
| {
990 token
::intern(doc
.as_str_slice())
994 pub fn get_methods_if_impl(intr
: Rc
<IdentInterner
>,
996 node_id
: ast
::NodeId
)
997 -> Option
<Vec
<MethodInfo
> > {
998 let item
= cdata
.lookup_item(node_id
);
999 if item_family(item
) != Impl
{
1003 // If this impl implements a trait, don't consider it.
1004 if reader
::tagged_docs(item
, tag_item_trait_ref
).next().is_some() {
1008 let impl_method_ids
= reader
::tagged_docs(item
, tag_item_impl_item
)
1009 .map(|impl_method_doc
| item_def_id(impl_method_doc
, cdata
));
1011 let mut impl_methods
= Vec
::new();
1012 for impl_method_id
in impl_method_ids
{
1013 let impl_method_doc
= cdata
.lookup_item(impl_method_id
.node
);
1014 let family
= item_family(impl_method_doc
);
1016 StaticMethod
| Method
=> {
1017 impl_methods
.push(MethodInfo
{
1018 name
: item_name(&*intr
, impl_method_doc
),
1019 def_id
: item_def_id(impl_method_doc
, cdata
),
1020 vis
: item_visibility(impl_method_doc
),
1027 return Some(impl_methods
);
1030 /// If node_id is the constructor of a tuple struct, retrieve the NodeId of
1031 /// the actual type definition, otherwise, return None
1032 pub fn get_tuple_struct_definition_if_ctor(cdata
: Cmd
,
1033 node_id
: ast
::NodeId
)
1036 let item
= cdata
.lookup_item(node_id
);
1037 reader
::tagged_docs(item
, tag_items_data_item_is_tuple_struct_ctor
).next().map(|_
| {
1038 item_require_parent_item(cdata
, item
)
1042 pub fn get_item_attrs(cdata
: Cmd
,
1043 orig_node_id
: ast
::NodeId
)
1044 -> Vec
<hir
::Attribute
> {
1045 // The attributes for a tuple struct are attached to the definition, not the ctor;
1046 // we assume that someone passing in a tuple struct ctor is actually wanting to
1047 // look at the definition
1048 let node_id
= get_tuple_struct_definition_if_ctor(cdata
, orig_node_id
);
1049 let node_id
= node_id
.map(|x
| x
.node
).unwrap_or(orig_node_id
);
1050 let item
= cdata
.lookup_item(node_id
);
1051 get_attributes(item
)
1054 pub fn get_struct_field_attrs(cdata
: Cmd
) -> FnvHashMap
<ast
::NodeId
, Vec
<hir
::Attribute
>> {
1055 let data
= rbml
::Doc
::new(cdata
.data());
1056 let fields
= reader
::get_doc(data
, tag_struct_fields
);
1057 reader
::tagged_docs(fields
, tag_struct_field
).map(|field
| {
1058 let id
= reader
::doc_as_u32(reader
::get_doc(field
, tag_struct_field_id
));
1059 let attrs
= get_attributes(field
);
1064 fn struct_field_family_to_visibility(family
: Family
) -> hir
::Visibility
{
1066 PublicField
=> hir
::Public
,
1067 InheritedField
=> hir
::Inherited
,
1072 pub fn get_struct_field_names(intr
: &IdentInterner
, cdata
: Cmd
, id
: ast
::NodeId
)
1074 let item
= cdata
.lookup_item(id
);
1075 reader
::tagged_docs(item
, tag_item_field
).map(|an_item
| {
1076 item_name(intr
, an_item
)
1077 }).chain(reader
::tagged_docs(item
, tag_item_unnamed_field
).map(|_
| {
1078 special_idents
::unnamed_field
.name
1082 fn get_meta_items(md
: rbml
::Doc
) -> Vec
<P
<hir
::MetaItem
>> {
1083 reader
::tagged_docs(md
, tag_meta_item_word
).map(|meta_item_doc
| {
1084 let nd
= reader
::get_doc(meta_item_doc
, tag_meta_item_name
);
1085 let n
= token
::intern_and_get_ident(nd
.as_str_slice());
1086 attr
::mk_word_item(n
)
1087 }).chain(reader
::tagged_docs(md
, tag_meta_item_name_value
).map(|meta_item_doc
| {
1088 let nd
= reader
::get_doc(meta_item_doc
, tag_meta_item_name
);
1089 let vd
= reader
::get_doc(meta_item_doc
, tag_meta_item_value
);
1090 let n
= token
::intern_and_get_ident(nd
.as_str_slice());
1091 let v
= token
::intern_and_get_ident(vd
.as_str_slice());
1092 // FIXME (#623): Should be able to decode MetaNameValue variants,
1093 // but currently the encoder just drops them
1094 attr
::mk_name_value_item_str(n
, v
)
1095 })).chain(reader
::tagged_docs(md
, tag_meta_item_list
).map(|meta_item_doc
| {
1096 let nd
= reader
::get_doc(meta_item_doc
, tag_meta_item_name
);
1097 let n
= token
::intern_and_get_ident(nd
.as_str_slice());
1098 let subitems
= get_meta_items(meta_item_doc
);
1099 attr
::mk_list_item(n
, subitems
)
1103 fn get_attributes(md
: rbml
::Doc
) -> Vec
<hir
::Attribute
> {
1104 match reader
::maybe_get_doc(md
, tag_attributes
) {
1106 reader
::tagged_docs(attrs_d
, tag_attribute
).map(|attr_doc
| {
1107 let is_sugared_doc
= reader
::doc_as_u8(
1108 reader
::get_doc(attr_doc
, tag_attribute_is_sugared_doc
)
1110 let meta_items
= get_meta_items(attr_doc
);
1111 // Currently it's only possible to have a single meta item on
1113 assert_eq
!(meta_items
.len(), 1);
1114 let meta_item
= meta_items
.into_iter().nth(0).unwrap();
1116 node
: hir
::Attribute_
{
1117 id
: attr
::mk_attr_id(),
1118 style
: hir
::AttrOuter
,
1120 is_sugared_doc
: is_sugared_doc
,
1122 span
: codemap
::DUMMY_SP
1130 fn list_crate_attributes(md
: rbml
::Doc
, hash
: &Svh
,
1131 out
: &mut io
::Write
) -> io
::Result
<()> {
1132 try
!(write
!(out
, "=Crate Attributes ({})=\n", *hash
));
1134 let r
= get_attributes(md
);
1136 try
!(write
!(out
, "{}\n", pprust
::attribute_to_string(attr
)));
1142 pub fn get_crate_attributes(data
: &[u8]) -> Vec
<hir
::Attribute
> {
1143 get_attributes(rbml
::Doc
::new(data
))
1147 pub struct CrateDep
{
1148 pub cnum
: ast
::CrateNum
,
1151 pub explicitly_linked
: bool
,
1154 pub fn get_crate_deps(data
: &[u8]) -> Vec
<CrateDep
> {
1155 let cratedoc
= rbml
::Doc
::new(data
);
1156 let depsdoc
= reader
::get_doc(cratedoc
, tag_crate_deps
);
1158 fn docstr(doc
: rbml
::Doc
, tag_
: usize) -> String
{
1159 let d
= reader
::get_doc(doc
, tag_
);
1160 d
.as_str_slice().to_string()
1163 reader
::tagged_docs(depsdoc
, tag_crate_dep
).enumerate().map(|(crate_num
, depdoc
)| {
1164 let name
= docstr(depdoc
, tag_crate_dep_crate_name
);
1165 let hash
= Svh
::new(&docstr(depdoc
, tag_crate_dep_hash
));
1166 let doc
= reader
::get_doc(depdoc
, tag_crate_dep_explicitly_linked
);
1167 let explicitly_linked
= reader
::doc_as_u8(doc
) != 0;
1169 cnum
: crate_num
as u32 + 1,
1172 explicitly_linked
: explicitly_linked
,
1177 fn list_crate_deps(data
: &[u8], out
: &mut io
::Write
) -> io
::Result
<()> {
1178 try
!(write
!(out
, "=External Dependencies=\n"));
1179 for dep
in &get_crate_deps(data
) {
1180 try
!(write
!(out
, "{} {}-{}\n", dep
.cnum
, dep
.name
, dep
.hash
));
1182 try
!(write
!(out
, "\n"));
1186 pub fn maybe_get_crate_hash(data
: &[u8]) -> Option
<Svh
> {
1187 let cratedoc
= rbml
::Doc
::new(data
);
1188 reader
::maybe_get_doc(cratedoc
, tag_crate_hash
).map(|doc
| {
1189 Svh
::new(doc
.as_str_slice())
1193 pub fn get_crate_hash(data
: &[u8]) -> Svh
{
1194 let cratedoc
= rbml
::Doc
::new(data
);
1195 let hashdoc
= reader
::get_doc(cratedoc
, tag_crate_hash
);
1196 Svh
::new(hashdoc
.as_str_slice())
1199 pub fn maybe_get_crate_name(data
: &[u8]) -> Option
<String
> {
1200 let cratedoc
= rbml
::Doc
::new(data
);
1201 reader
::maybe_get_doc(cratedoc
, tag_crate_crate_name
).map(|doc
| {
1202 doc
.as_str_slice().to_string()
1206 pub fn get_crate_triple(data
: &[u8]) -> Option
<String
> {
1207 let cratedoc
= rbml
::Doc
::new(data
);
1208 let triple_doc
= reader
::maybe_get_doc(cratedoc
, tag_crate_triple
);
1209 triple_doc
.map(|s
| s
.as_str().to_string())
1212 pub fn get_crate_name(data
: &[u8]) -> String
{
1213 maybe_get_crate_name(data
).expect("no crate name in crate")
1216 pub fn list_crate_metadata(bytes
: &[u8], out
: &mut io
::Write
) -> io
::Result
<()> {
1217 let hash
= get_crate_hash(bytes
);
1218 let md
= rbml
::Doc
::new(bytes
);
1219 try
!(list_crate_attributes(md
, &hash
, out
));
1220 list_crate_deps(bytes
, out
)
1223 // Translates a def_id from an external crate to a def_id for the current
1224 // compilation environment. We use this when trying to load types from
1225 // external crates - if those types further refer to types in other crates
1226 // then we must translate the crate number from that encoded in the external
1227 // crate to the correct local crate number.
1228 pub fn translate_def_id(cdata
: Cmd
, did
: DefId
) -> DefId
{
1230 return DefId { krate: cdata.cnum, node: did.node }
;
1233 match cdata
.cnum_map
.borrow().get(&did
.krate
) {
1240 None
=> panic
!("didn't find a crate in the cnum_map")
1244 // Translate a DefId from the current compilation environment to a DefId
1245 // for an external crate.
1246 fn reverse_translate_def_id(cdata
: Cmd
, did
: DefId
) -> Option
<DefId
> {
1247 if did
.krate
== cdata
.cnum
{
1248 return Some(DefId { krate: LOCAL_CRATE, node: did.node }
);
1251 for (&local
, &global
) in cdata
.cnum_map
.borrow().iter() {
1252 if global
== did
.krate
{
1253 return Some(DefId { krate: local, node: did.node }
);
1260 pub fn each_inherent_implementation_for_type
<F
>(cdata
: Cmd
,
1263 where F
: FnMut(DefId
),
1265 let item_doc
= cdata
.lookup_item(id
);
1266 for impl_doc
in reader
::tagged_docs(item_doc
, tag_items_data_item_inherent_impl
) {
1267 if reader
::maybe_get_doc(impl_doc
, tag_item_trait_ref
).is_none() {
1268 callback(item_def_id(impl_doc
, cdata
));
1273 pub fn each_implementation_for_trait
<F
>(cdata
: Cmd
,
1275 mut callback
: F
) where
1278 if cdata
.cnum
== def_id
.krate
{
1279 let item_doc
= cdata
.lookup_item(def_id
.node
);
1280 for impl_doc
in reader
::tagged_docs(item_doc
, tag_items_data_item_extension_impl
) {
1281 callback(item_def_id(impl_doc
, cdata
));
1286 // Do a reverse lookup beforehand to avoid touching the crate_num
1287 // hash map in the loop below.
1288 if let Some(crate_local_did
) = reverse_translate_def_id(cdata
, def_id
) {
1289 let def_id_u64
= def_to_u64(crate_local_did
);
1291 let impls_doc
= reader
::get_doc(rbml
::Doc
::new(cdata
.data()), tag_impls
);
1292 for impl_doc
in reader
::tagged_docs(impls_doc
, tag_impls_impl
) {
1293 let impl_trait
= reader
::get_doc(impl_doc
, tag_impls_impl_trait_def_id
);
1294 if reader
::doc_as_u64(impl_trait
) == def_id_u64
{
1295 callback(item_def_id(impl_doc
, cdata
));
1301 pub fn get_trait_of_item(cdata
: Cmd
, id
: ast
::NodeId
, tcx
: &ty
::ctxt
)
1303 let item_doc
= cdata
.lookup_item(id
);
1304 let parent_item_id
= match item_parent_item(cdata
, item_doc
) {
1305 None
=> return None
,
1306 Some(item_id
) => item_id
,
1308 let parent_item_doc
= cdata
.lookup_item(parent_item_id
.node
);
1309 match item_family(parent_item_doc
) {
1310 Trait
=> Some(item_def_id(parent_item_doc
, cdata
)),
1311 Impl
| DefaultImpl
=> {
1312 reader
::maybe_get_doc(parent_item_doc
, tag_item_trait_ref
)
1313 .map(|_
| item_trait_ref(parent_item_doc
, tcx
, cdata
).def_id
)
1320 pub fn get_native_libraries(cdata
: Cmd
)
1321 -> Vec
<(cstore
::NativeLibraryKind
, String
)> {
1322 let libraries
= reader
::get_doc(rbml
::Doc
::new(cdata
.data()),
1323 tag_native_libraries
);
1324 reader
::tagged_docs(libraries
, tag_native_libraries_lib
).map(|lib_doc
| {
1325 let kind_doc
= reader
::get_doc(lib_doc
, tag_native_libraries_kind
);
1326 let name_doc
= reader
::get_doc(lib_doc
, tag_native_libraries_name
);
1327 let kind
: cstore
::NativeLibraryKind
=
1328 cstore
::NativeLibraryKind
::from_u32(reader
::doc_as_u32(kind_doc
)).unwrap();
1329 let name
= name_doc
.as_str().to_string();
1334 pub fn get_plugin_registrar_fn(data
: &[u8]) -> Option
<ast
::NodeId
> {
1335 reader
::maybe_get_doc(rbml
::Doc
::new(data
), tag_plugin_registrar_fn
)
1336 .map(|doc
| reader
::doc_as_u32(doc
))
1339 pub fn each_exported_macro
<F
>(data
: &[u8], intr
: &IdentInterner
, mut f
: F
) where
1340 F
: FnMut(ast
::Name
, Vec
<hir
::Attribute
>, String
) -> bool
,
1342 let macros
= reader
::get_doc(rbml
::Doc
::new(data
), tag_macro_defs
);
1343 for macro_doc
in reader
::tagged_docs(macros
, tag_macro_def
) {
1344 let name
= item_name(intr
, macro_doc
);
1345 let attrs
= get_attributes(macro_doc
);
1346 let body
= reader
::get_doc(macro_doc
, tag_macro_def_body
);
1347 if !f(name
, attrs
, body
.as_str().to_string()) {
1353 pub fn get_dylib_dependency_formats(cdata
: Cmd
)
1354 -> Vec
<(ast
::CrateNum
, cstore
::LinkagePreference
)>
1356 let formats
= reader
::get_doc(rbml
::Doc
::new(cdata
.data()),
1357 tag_dylib_dependency_formats
);
1358 let mut result
= Vec
::new();
1360 debug
!("found dylib deps: {}", formats
.as_str_slice());
1361 for spec
in formats
.as_str_slice().split('
,'
) {
1362 if spec
.is_empty() { continue }
1363 let cnum
= spec
.split('
:'
).nth(0).unwrap();
1364 let link
= spec
.split('
:'
).nth(1).unwrap();
1365 let cnum
: ast
::CrateNum
= cnum
.parse().unwrap();
1366 let cnum
= match cdata
.cnum_map
.borrow().get(&cnum
) {
1368 None
=> panic
!("didn't find a crate in the cnum_map")
1370 result
.push((cnum
, if link
== "d" {
1371 cstore
::RequireDynamic
1373 cstore
::RequireStatic
1379 pub fn get_missing_lang_items(cdata
: Cmd
)
1380 -> Vec
<lang_items
::LangItem
>
1382 let items
= reader
::get_doc(rbml
::Doc
::new(cdata
.data()), tag_lang_items
);
1383 reader
::tagged_docs(items
, tag_lang_items_missing
).map(|missing_docs
| {
1384 lang_items
::LangItem
::from_u32(reader
::doc_as_u32(missing_docs
)).unwrap()
1388 pub fn get_method_arg_names(cdata
: Cmd
, id
: ast
::NodeId
) -> Vec
<String
> {
1389 let method_doc
= cdata
.lookup_item(id
);
1390 match reader
::maybe_get_doc(method_doc
, tag_method_argument_names
) {
1392 reader
::tagged_docs(args_doc
, tag_method_argument_name
).map(|name_doc
| {
1393 name_doc
.as_str_slice().to_string()
1400 pub fn get_reachable_ids(cdata
: Cmd
) -> Vec
<DefId
> {
1401 let items
= reader
::get_doc(rbml
::Doc
::new(cdata
.data()),
1403 reader
::tagged_docs(items
, tag_reachable_id
).map(|doc
| {
1406 node
: reader
::doc_as_u32(doc
),
1411 pub fn is_typedef(cdata
: Cmd
, id
: ast
::NodeId
) -> bool
{
1412 let item_doc
= cdata
.lookup_item(id
);
1413 match item_family(item_doc
) {
1419 pub fn is_const_fn(cdata
: Cmd
, id
: ast
::NodeId
) -> bool
{
1420 let item_doc
= cdata
.lookup_item(id
);
1421 match fn_constness(item_doc
) {
1422 hir
::Constness
::Const
=> true,
1423 hir
::Constness
::NotConst
=> false,
1427 pub fn is_impl(cdata
: Cmd
, id
: ast
::NodeId
) -> bool
{
1428 let item_doc
= cdata
.lookup_item(id
);
1429 match item_family(item_doc
) {
1435 fn doc_generics
<'tcx
>(base_doc
: rbml
::Doc
,
1436 tcx
: &ty
::ctxt
<'tcx
>,
1439 -> ty
::Generics
<'tcx
>
1441 let doc
= reader
::get_doc(base_doc
, tag
);
1443 let mut types
= subst
::VecPerParamSpace
::empty();
1444 for p
in reader
::tagged_docs(doc
, tag_type_param_def
) {
1446 TyDecoder
::with_doc(tcx
, cdata
.cnum
, p
,
1447 &mut |_
, did
| translate_def_id(cdata
, did
))
1448 .parse_type_param_def();
1449 types
.push(bd
.space
, bd
);
1452 let mut regions
= subst
::VecPerParamSpace
::empty();
1453 for rp_doc
in reader
::tagged_docs(doc
, tag_region_param_def
) {
1454 let ident_str_doc
= reader
::get_doc(rp_doc
,
1455 tag_region_param_def_ident
);
1456 let name
= item_name(&*token
::get_ident_interner(), ident_str_doc
);
1457 let def_id_doc
= reader
::get_doc(rp_doc
,
1458 tag_region_param_def_def_id
);
1459 let def_id
= translated_def_id(cdata
, def_id_doc
);
1461 let doc
= reader
::get_doc(rp_doc
, tag_region_param_def_space
);
1462 let space
= subst
::ParamSpace
::from_uint(reader
::doc_as_u64(doc
) as usize);
1464 let doc
= reader
::get_doc(rp_doc
, tag_region_param_def_index
);
1465 let index
= reader
::doc_as_u64(doc
) as u32;
1467 let bounds
= reader
::tagged_docs(rp_doc
, tag_items_data_region
).map(|p
| {
1468 TyDecoder
::with_doc(tcx
, cdata
.cnum
, p
,
1469 &mut |_
, did
| translate_def_id(cdata
, did
))
1473 regions
.push(space
, ty
::RegionParameterDef
{ name
: name
,
1480 ty
::Generics { types: types, regions: regions }
1483 fn doc_predicates
<'tcx
>(base_doc
: rbml
::Doc
,
1484 tcx
: &ty
::ctxt
<'tcx
>,
1487 -> ty
::GenericPredicates
<'tcx
>
1489 let doc
= reader
::get_doc(base_doc
, tag
);
1491 let mut predicates
= subst
::VecPerParamSpace
::empty();
1492 for predicate_doc
in reader
::tagged_docs(doc
, tag_predicate
) {
1493 let space_doc
= reader
::get_doc(predicate_doc
, tag_predicate_space
);
1494 let space
= subst
::ParamSpace
::from_uint(reader
::doc_as_u8(space_doc
) as usize);
1496 let data_doc
= reader
::get_doc(predicate_doc
, tag_predicate_data
);
1498 TyDecoder
::with_doc(tcx
, cdata
.cnum
, data_doc
,
1499 &mut |_
, did
| translate_def_id(cdata
, did
))
1502 predicates
.push(space
, data
);
1505 ty
::GenericPredicates { predicates: predicates }
1508 pub fn is_defaulted_trait(cdata
: Cmd
, trait_id
: ast
::NodeId
) -> bool
{
1509 let trait_doc
= cdata
.lookup_item(trait_id
);
1510 assert
!(item_family(trait_doc
) == Family
::Trait
);
1511 let defaulted_doc
= reader
::get_doc(trait_doc
, tag_defaulted_trait
);
1512 reader
::doc_as_u8(defaulted_doc
) != 0
1515 pub fn is_default_impl(cdata
: Cmd
, impl_id
: ast
::NodeId
) -> bool
{
1516 let impl_doc
= cdata
.lookup_item(impl_id
);
1517 item_family(impl_doc
) == Family
::DefaultImpl
1520 pub fn get_imported_filemaps(metadata
: &[u8]) -> Vec
<codemap
::FileMap
> {
1521 let crate_doc
= rbml
::Doc
::new(metadata
);
1522 let cm_doc
= reader
::get_doc(crate_doc
, tag_codemap
);
1524 reader
::tagged_docs(cm_doc
, tag_codemap_filemap
).map(|filemap_doc
| {
1525 let mut decoder
= reader
::Decoder
::new(filemap_doc
);
1526 Decodable
::decode(&mut decoder
).unwrap()
1530 pub fn is_extern_fn(cdata
: Cmd
, id
: ast
::NodeId
, tcx
: &ty
::ctxt
) -> bool
{
1531 let item_doc
= match cdata
.get_item(id
) {
1533 None
=> return false,
1535 if let Fn
= item_family(item_doc
) {
1536 let ty
::TypeScheme { generics, ty }
= get_type(cdata
, id
, tcx
);
1537 generics
.types
.is_empty() && match ty
.sty
{
1538 ty
::TyBareFn(_
, fn_ty
) => fn_ty
.abi
!= abi
::Rust
,