2014-02-10 15:36:31 +01:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2012-12-04 01:48:01 +01:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2011-07-08 08:29:09 +02:00
|
|
|
// Decoding metadata from a single crate's metadata
|
2011-06-28 01:03:01 +02:00
|
|
|
|
2014-03-22 02:05:05 +01:00
|
|
|
#![allow(non_camel_case_types)]
|
2013-05-18 00:28:44 +02:00
|
|
|
|
2014-11-06 09:05:53 +01:00
|
|
|
pub use self::DefLike::*;
|
|
|
|
use self::Family::*;
|
|
|
|
|
2015-06-10 01:40:45 +02:00
|
|
|
use ast_map;
|
2014-02-25 04:45:20 +01:00
|
|
|
use back::svh::Svh;
|
2013-02-19 08:40:42 +01:00
|
|
|
use metadata::cstore::crate_metadata;
|
2012-12-13 22:05:22 +01:00
|
|
|
use metadata::common::*;
|
2014-10-20 03:30:31 +02:00
|
|
|
use metadata::csearch::MethodInfo;
|
2012-12-23 23:41:37 +01:00
|
|
|
use metadata::csearch;
|
|
|
|
use metadata::cstore;
|
2015-05-12 06:49:15 +02:00
|
|
|
use metadata::encoder::def_to_u64;
|
2015-08-13 16:57:34 +02:00
|
|
|
use metadata::inline::InlinedItem;
|
2015-08-16 03:35:49 +02:00
|
|
|
use metadata::tydecode::TyDecoder;
|
2014-05-14 21:31:30 +02:00
|
|
|
use middle::def;
|
2015-08-16 12:32:28 +02:00
|
|
|
use middle::def_id::{DefId, LOCAL_CRATE};
|
2014-08-04 22:56:56 +02:00
|
|
|
use middle::lang_items;
|
2014-06-01 00:53:13 +02:00
|
|
|
use middle::subst;
|
2013-08-23 23:34:00 +02:00
|
|
|
use middle::ty::{ImplContainer, TraitContainer};
|
2015-08-07 12:57:39 +02:00
|
|
|
use middle::ty::{self, RegionEscape, Ty};
|
2015-04-21 18:00:12 +02:00
|
|
|
use util::nodemap::FnvHashMap;
|
2013-07-23 01:40:31 +02:00
|
|
|
|
2015-04-21 18:00:12 +02:00
|
|
|
use std::cell::{Cell, RefCell};
|
2014-12-22 18:04:23 +01:00
|
|
|
use std::collections::HashMap;
|
2015-07-08 17:33:13 +02:00
|
|
|
use std::hash::{Hash, SipHasher, Hasher};
|
2015-02-27 06:00:43 +01:00
|
|
|
use std::io::prelude::*;
|
|
|
|
use std::io;
|
2014-02-01 05:57:59 +01:00
|
|
|
use std::rc::Rc;
|
2015-02-28 00:46:02 +01:00
|
|
|
use std::slice::bytes;
|
2014-11-02 07:27:11 +01:00
|
|
|
use std::str;
|
2014-12-22 18:04:23 +01:00
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
use rbml::reader;
|
|
|
|
use rbml;
|
2014-02-05 17:52:54 +01:00
|
|
|
use serialize::Decodable;
|
2015-07-29 02:19:08 +02:00
|
|
|
use syntax::abi;
|
2012-12-13 22:05:22 +01:00
|
|
|
use syntax::attr;
|
2014-01-09 14:05:33 +01:00
|
|
|
use syntax::parse::token::{IdentInterner, special_idents};
|
2014-02-14 06:07:09 +01:00
|
|
|
use syntax::parse::token;
|
2012-12-13 22:05:22 +01:00
|
|
|
use syntax::print::pprust;
|
2013-08-22 02:26:33 +02:00
|
|
|
use syntax::ast;
|
2013-01-30 18:56:33 +01:00
|
|
|
use syntax::codemap;
|
2014-09-07 19:09:06 +02:00
|
|
|
use syntax::ptr::P;
|
2011-06-28 00:53:27 +02:00
|
|
|
|
2014-04-17 14:06:25 +02:00
|
|
|
pub type Cmd<'a> = &'a crate_metadata;
|
2013-02-19 08:40:42 +01:00
|
|
|
|
2011-07-08 23:53:25 +02:00
|
|
|
// A function that takes a def_id relative to the crate being searched and
|
|
|
|
// returns a def_id relative to the compilation environment, i.e. if we hit a
|
|
|
|
// def_id for an item defined in another crate, somebody needs to figure out
|
|
|
|
// what crate that's in and give us a def_id that makes sense for the current
|
|
|
|
// build.
|
2011-07-27 14:19:39 +02:00
|
|
|
|
2015-02-28 00:46:02 +01:00
|
|
|
fn u32_from_be_bytes(bytes: &[u8]) -> u32 {
|
|
|
|
let mut b = [0; 4];
|
2015-03-27 19:12:28 +01:00
|
|
|
bytes::copy_memory(&bytes[..4], &mut b);
|
2015-02-28 00:46:02 +01:00
|
|
|
unsafe { (*(b.as_ptr() as *const u32)).to_be() }
|
|
|
|
}
|
|
|
|
|
2014-12-09 02:26:43 +01:00
|
|
|
fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option<rbml::Doc<'a>> where
|
|
|
|
F: FnMut(&[u8]) -> bool,
|
|
|
|
{
|
2012-12-07 01:13:54 +01:00
|
|
|
let index = reader::get_doc(d, tag_index);
|
|
|
|
let table = reader::get_doc(index, tag_index_table);
|
2015-03-26 01:06:52 +01:00
|
|
|
let hash_pos = table.start + (hash % 256 * 4) as usize;
|
|
|
|
let pos = u32_from_be_bytes(&d.data[hash_pos..]) as usize;
|
2014-03-29 01:05:46 +01:00
|
|
|
let tagged_doc = reader::doc_at(d.data, pos).unwrap();
|
2011-06-28 00:53:27 +02:00
|
|
|
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(tagged_doc.doc, tag_index_buckets_bucket_elt).find(|elt| {
|
|
|
|
eq_fn(&elt.data[elt.start + 4 .. elt.end])
|
|
|
|
}).map(|elt| {
|
2015-03-26 01:06:52 +01:00
|
|
|
let pos = u32_from_be_bytes(&elt.data[elt.start..]) as usize;
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::doc_at(d.data, pos).unwrap().doc
|
|
|
|
})
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2013-12-18 23:10:28 +01:00
|
|
|
pub fn maybe_find_item<'a>(item_id: ast::NodeId,
|
2014-07-30 02:06:37 +02:00
|
|
|
items: rbml::Doc<'a>) -> Option<rbml::Doc<'a>> {
|
2013-11-27 06:02:25 +01:00
|
|
|
fn eq_item(bytes: &[u8], item_id: ast::NodeId) -> bool {
|
2015-02-28 00:46:02 +01:00
|
|
|
u32_from_be_bytes(bytes) == item_id
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
2015-07-08 17:33:13 +02:00
|
|
|
let mut s = SipHasher::new_with_keys(0, 0);
|
|
|
|
(item_id as i64).hash(&mut s);
|
|
|
|
lookup_hash(items, |a| eq_item(a, item_id), s.finish())
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn find_item<'a>(item_id: ast::NodeId, items: rbml::Doc<'a>) -> rbml::Doc<'a> {
|
2013-06-11 11:40:10 +02:00
|
|
|
match maybe_find_item(item_id, items) {
|
2014-10-09 21:17:22 +02:00
|
|
|
None => panic!("lookup_item: id not found: {}", item_id),
|
2013-06-11 11:40:10 +02:00
|
|
|
Some(d) => d
|
|
|
|
}
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
// Looks up an item in the given metadata and returns an rbml doc pointing
|
2011-06-28 00:53:27 +02:00
|
|
|
// to the item data.
|
2014-07-30 02:06:37 +02:00
|
|
|
fn lookup_item<'a>(item_id: ast::NodeId, data: &'a [u8]) -> rbml::Doc<'a> {
|
|
|
|
let items = reader::get_doc(rbml::Doc::new(data), tag_items);
|
2013-06-11 11:40:10 +02:00
|
|
|
find_item(item_id, items)
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2015-07-22 20:53:52 +02:00
|
|
|
#[derive(Debug, PartialEq)]
|
2012-08-23 02:58:05 +02:00
|
|
|
enum Family {
|
2013-06-22 03:46:34 +02:00
|
|
|
ImmStatic, // c
|
|
|
|
MutStatic, // b
|
2012-08-23 02:58:05 +02:00
|
|
|
Fn, // f
|
2014-09-29 18:27:07 +02:00
|
|
|
CtorFn, // o
|
2012-08-23 02:58:05 +02:00
|
|
|
StaticMethod, // F
|
2014-10-16 06:40:01 +02:00
|
|
|
Method, // h
|
2012-08-23 02:58:05 +02:00
|
|
|
Type, // y
|
|
|
|
Mod, // m
|
|
|
|
ForeignMod, // n
|
|
|
|
Enum, // t
|
2013-09-09 02:36:01 +02:00
|
|
|
TupleVariant, // v
|
|
|
|
StructVariant, // V
|
2012-08-23 02:58:05 +02:00
|
|
|
Impl, // i
|
2015-02-07 14:24:34 +01:00
|
|
|
DefaultImpl, // d
|
2012-08-23 02:58:05 +02:00
|
|
|
Trait, // I
|
|
|
|
Struct, // S
|
|
|
|
PublicField, // g
|
rustc: Add `const` globals to the language
This change is an implementation of [RFC 69][rfc] which adds a third kind of
global to the language, `const`. This global is most similar to what the old
`static` was, and if you're unsure about what to use then you should use a
`const`.
The semantics of these three kinds of globals are:
* A `const` does not represent a memory location, but only a value. Constants
are translated as rvalues, which means that their values are directly inlined
at usage location (similar to a #define in C/C++). Constant values are, well,
constant, and can not be modified. Any "modification" is actually a
modification to a local value on the stack rather than the actual constant
itself.
Almost all values are allowed inside constants, whether they have interior
mutability or not. There are a few minor restrictions listed in the RFC, but
they should in general not come up too often.
* A `static` now always represents a memory location (unconditionally). Any
references to the same `static` are actually a reference to the same memory
location. Only values whose types ascribe to `Sync` are allowed in a `static`.
This restriction is in place because many threads may access a `static`
concurrently. Lifting this restriction (and allowing unsafe access) is a
future extension not implemented at this time.
* A `static mut` continues to always represent a memory location. All references
to a `static mut` continue to be `unsafe`.
This is a large breaking change, and many programs will need to be updated
accordingly. A summary of the breaking changes is:
* Statics may no longer be used in patterns. Statics now always represent a
memory location, which can sometimes be modified. To fix code, repurpose the
matched-on-`static` to a `const`.
static FOO: uint = 4;
match n {
FOO => { /* ... */ }
_ => { /* ... */ }
}
change this code to:
const FOO: uint = 4;
match n {
FOO => { /* ... */ }
_ => { /* ... */ }
}
* Statics may no longer refer to other statics by value. Due to statics being
able to change at runtime, allowing them to reference one another could
possibly lead to confusing semantics. If you are in this situation, use a
constant initializer instead. Note, however, that statics may reference other
statics by address, however.
* Statics may no longer be used in constant expressions, such as array lengths.
This is due to the same restrictions as listed above. Use a `const` instead.
[breaking-change]
[rfc]: https://github.com/rust-lang/rfcs/pull/246
2014-10-06 17:17:01 +02:00
|
|
|
InheritedField, // N
|
|
|
|
Constant, // C
|
2012-08-23 02:58:05 +02:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn item_family(item: rbml::Doc) -> Family {
|
2012-12-07 01:13:54 +01:00
|
|
|
let fam = reader::get_doc(item, tag_items_data_item_family);
|
|
|
|
match reader::doc_as_u8(fam) as char {
|
rustc: Add `const` globals to the language
This change is an implementation of [RFC 69][rfc] which adds a third kind of
global to the language, `const`. This global is most similar to what the old
`static` was, and if you're unsure about what to use then you should use a
`const`.
The semantics of these three kinds of globals are:
* A `const` does not represent a memory location, but only a value. Constants
are translated as rvalues, which means that their values are directly inlined
at usage location (similar to a #define in C/C++). Constant values are, well,
constant, and can not be modified. Any "modification" is actually a
modification to a local value on the stack rather than the actual constant
itself.
Almost all values are allowed inside constants, whether they have interior
mutability or not. There are a few minor restrictions listed in the RFC, but
they should in general not come up too often.
* A `static` now always represents a memory location (unconditionally). Any
references to the same `static` are actually a reference to the same memory
location. Only values whose types ascribe to `Sync` are allowed in a `static`.
This restriction is in place because many threads may access a `static`
concurrently. Lifting this restriction (and allowing unsafe access) is a
future extension not implemented at this time.
* A `static mut` continues to always represent a memory location. All references
to a `static mut` continue to be `unsafe`.
This is a large breaking change, and many programs will need to be updated
accordingly. A summary of the breaking changes is:
* Statics may no longer be used in patterns. Statics now always represent a
memory location, which can sometimes be modified. To fix code, repurpose the
matched-on-`static` to a `const`.
static FOO: uint = 4;
match n {
FOO => { /* ... */ }
_ => { /* ... */ }
}
change this code to:
const FOO: uint = 4;
match n {
FOO => { /* ... */ }
_ => { /* ... */ }
}
* Statics may no longer refer to other statics by value. Due to statics being
able to change at runtime, allowing them to reference one another could
possibly lead to confusing semantics. If you are in this situation, use a
constant initializer instead. Note, however, that statics may reference other
statics by address, however.
* Statics may no longer be used in constant expressions, such as array lengths.
This is due to the same restrictions as listed above. Use a `const` instead.
[breaking-change]
[rfc]: https://github.com/rust-lang/rfcs/pull/246
2014-10-06 17:17:01 +02:00
|
|
|
'C' => Constant,
|
2013-06-22 03:46:34 +02:00
|
|
|
'c' => ImmStatic,
|
|
|
|
'b' => MutStatic,
|
2012-08-23 02:58:05 +02:00
|
|
|
'f' => Fn,
|
2014-09-29 18:27:07 +02:00
|
|
|
'o' => CtorFn,
|
2012-08-23 02:58:05 +02:00
|
|
|
'F' => StaticMethod,
|
2014-10-16 06:40:01 +02:00
|
|
|
'h' => Method,
|
2012-08-23 02:58:05 +02:00
|
|
|
'y' => Type,
|
|
|
|
'm' => Mod,
|
|
|
|
'n' => ForeignMod,
|
|
|
|
't' => Enum,
|
2013-09-09 02:36:01 +02:00
|
|
|
'v' => TupleVariant,
|
|
|
|
'V' => StructVariant,
|
2012-08-23 02:58:05 +02:00
|
|
|
'i' => Impl,
|
2015-02-07 14:24:34 +01:00
|
|
|
'd' => DefaultImpl,
|
2012-08-23 02:58:05 +02:00
|
|
|
'I' => Trait,
|
|
|
|
'S' => Struct,
|
|
|
|
'g' => PublicField,
|
|
|
|
'N' => InheritedField,
|
2014-10-09 21:17:22 +02:00
|
|
|
c => panic!("unexpected family char: {}", c)
|
2012-08-23 02:58:05 +02:00
|
|
|
}
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn item_visibility(item: rbml::Doc) -> ast::Visibility {
|
2013-03-20 22:38:57 +01:00
|
|
|
match reader::maybe_get_doc(item, tag_items_data_item_visibility) {
|
2014-01-09 14:05:33 +01:00
|
|
|
None => ast::Public,
|
2013-03-20 22:38:57 +01:00
|
|
|
Some(visibility_doc) => {
|
|
|
|
match reader::doc_as_u8(visibility_doc) as char {
|
2014-01-09 14:05:33 +01:00
|
|
|
'y' => ast::Public,
|
|
|
|
'i' => ast::Inherited,
|
2014-10-09 21:17:22 +02:00
|
|
|
_ => panic!("unknown visibility character")
|
2013-03-20 22:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
2013-02-27 22:45:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-25 21:06:08 +01:00
|
|
|
fn fn_constness(item: rbml::Doc) -> ast::Constness {
|
|
|
|
match reader::maybe_get_doc(item, tag_items_data_item_constness) {
|
|
|
|
None => ast::Constness::NotConst,
|
|
|
|
Some(constness_doc) => {
|
|
|
|
match reader::doc_as_u8(constness_doc) as char {
|
|
|
|
'c' => ast::Constness::Const,
|
|
|
|
'n' => ast::Constness::NotConst,
|
|
|
|
_ => panic!("unknown constness character")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-30 11:16:59 +01:00
|
|
|
fn item_sort(item: rbml::Doc) -> Option<char> {
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(item, tag_item_trait_item_sort).nth(0).map(|doc| {
|
|
|
|
doc.as_str_slice().as_bytes()[0] as char
|
|
|
|
})
|
2012-10-08 21:39:30 +02:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn item_symbol(item: rbml::Doc) -> String {
|
2014-05-25 12:17:19 +02:00
|
|
|
reader::get_doc(item, tag_items_data_item_symbol).as_str().to_string()
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2015-08-16 12:32:28 +02:00
|
|
|
fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId {
|
2015-05-12 06:49:15 +02:00
|
|
|
let id = reader::doc_as_u64(d);
|
2015-08-16 12:32:28 +02:00
|
|
|
let def_id = DefId { krate: (id >> 32) as u32, node: id as u32 };
|
2015-05-12 06:49:15 +02:00
|
|
|
translate_def_id(cdata, def_id)
|
|
|
|
}
|
|
|
|
|
2015-08-16 12:32:28 +02:00
|
|
|
fn item_parent_item(cdata: Cmd, d: rbml::Doc) -> Option<DefId> {
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(d, tag_items_data_parent_item).nth(0).map(|did| {
|
|
|
|
translated_def_id(cdata, did)
|
|
|
|
})
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2015-08-16 12:32:28 +02:00
|
|
|
fn item_require_parent_item(cdata: Cmd, d: rbml::Doc) -> DefId {
|
2015-05-12 06:49:15 +02:00
|
|
|
translated_def_id(cdata, reader::get_doc(d, tag_items_data_parent_item))
|
2012-10-13 02:00:08 +02:00
|
|
|
}
|
|
|
|
|
2015-08-16 12:32:28 +02:00
|
|
|
fn item_def_id(d: rbml::Doc, cdata: Cmd) -> DefId {
|
2015-05-12 06:49:15 +02:00
|
|
|
translated_def_id(cdata, reader::get_doc(d, tag_def_id))
|
2012-03-06 17:02:13 +01:00
|
|
|
}
|
|
|
|
|
2015-08-16 12:32:28 +02:00
|
|
|
fn get_provided_source(d: rbml::Doc, cdata: Cmd) -> Option<DefId> {
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::maybe_get_doc(d, tag_item_method_provided_source).map(|doc| {
|
2015-05-12 06:49:15 +02:00
|
|
|
translated_def_id(cdata, doc)
|
2013-11-22 00:42:55 +01:00
|
|
|
})
|
2013-07-12 02:07:57 +02:00
|
|
|
}
|
|
|
|
|
2015-05-27 07:26:35 +02:00
|
|
|
fn reexports<'a>(d: rbml::Doc<'a>) -> reader::TaggedDocsIterator<'a> {
|
|
|
|
reader::tagged_docs(d, tag_items_data_item_reexport)
|
2013-05-03 19:08:08 +02:00
|
|
|
}
|
2012-08-17 21:41:34 +02:00
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn variant_disr_val(d: rbml::Doc) -> Option<ty::Disr> {
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::maybe_get_doc(d, tag_disr_val).and_then(|val_doc| {
|
2014-11-02 07:27:11 +01:00
|
|
|
reader::with_doc_data(val_doc, |data| {
|
2015-01-28 07:52:32 +01:00
|
|
|
str::from_utf8(data).ok().and_then(|s| s.parse().ok())
|
2014-11-02 07:27:11 +01:00
|
|
|
})
|
2013-11-22 00:42:55 +01:00
|
|
|
})
|
2012-01-10 22:50:40 +01:00
|
|
|
}
|
|
|
|
|
2014-09-29 21:11:30 +02:00
|
|
|
fn doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> {
|
2012-12-07 01:13:54 +01:00
|
|
|
let tp = reader::get_doc(doc, tag_items_data_item_type);
|
2015-08-16 03:35:49 +02:00
|
|
|
TyDecoder::with_doc(tcx, cdata.cnum, tp,
|
|
|
|
&mut |_, did| translate_def_id(cdata, did))
|
|
|
|
.parse_ty()
|
2012-01-05 13:57:27 +01:00
|
|
|
}
|
|
|
|
|
2015-05-26 16:12:39 +02:00
|
|
|
fn maybe_doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Option<Ty<'tcx>> {
|
|
|
|
reader::maybe_get_doc(doc, tag_items_data_item_type).map(|tp| {
|
2015-08-16 03:35:49 +02:00
|
|
|
TyDecoder::with_doc(tcx, cdata.cnum, tp,
|
|
|
|
&mut |_, did| translate_def_id(cdata, did))
|
|
|
|
.parse_ty()
|
2015-05-26 16:12:39 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2014-09-29 21:11:30 +02:00
|
|
|
fn doc_method_fty<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>,
|
|
|
|
cdata: Cmd) -> ty::BareFnTy<'tcx> {
|
2013-03-27 15:26:57 +01:00
|
|
|
let tp = reader::get_doc(doc, tag_item_method_fty);
|
2015-08-16 03:35:49 +02:00
|
|
|
TyDecoder::with_doc(tcx, cdata.cnum, tp,
|
|
|
|
&mut |_, did| translate_def_id(cdata, did))
|
|
|
|
.parse_bare_fn_ty()
|
2013-03-27 15:26:57 +01:00
|
|
|
}
|
|
|
|
|
2015-08-16 12:32:28 +02:00
|
|
|
pub fn item_type<'tcx>(_item_id: DefId, item: rbml::Doc,
|
2014-09-29 21:11:30 +02:00
|
|
|
tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> {
|
2013-04-02 22:41:18 +02:00
|
|
|
doc_type(item, tcx, cdata)
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2014-09-29 21:11:30 +02:00
|
|
|
fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
|
2015-04-21 17:59:58 +02:00
|
|
|
-> ty::TraitRef<'tcx> {
|
2015-08-16 03:35:49 +02:00
|
|
|
TyDecoder::with_doc(tcx, cdata.cnum, doc,
|
|
|
|
&mut |_, did| translate_def_id(cdata, did))
|
|
|
|
.parse_trait_ref()
|
2013-03-27 11:16:28 +01:00
|
|
|
}
|
|
|
|
|
2014-09-29 21:11:30 +02:00
|
|
|
fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
|
2015-04-21 17:59:58 +02:00
|
|
|
-> ty::TraitRef<'tcx> {
|
2013-03-27 11:16:28 +01:00
|
|
|
let tp = reader::get_doc(doc, tag_item_trait_ref);
|
|
|
|
doc_trait_ref(tp, tcx, cdata)
|
2012-01-05 10:57:19 +01:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn item_path(item_doc: rbml::Doc) -> Vec<ast_map::PathElem> {
|
2012-12-07 01:13:54 +01:00
|
|
|
let path_doc = reader::get_doc(item_doc, tag_path);
|
2015-05-17 18:14:40 +02:00
|
|
|
reader::docs(path_doc).filter_map(|(tag, elt_doc)| {
|
2014-01-09 14:05:33 +01:00
|
|
|
if tag == tag_path_elem_mod {
|
2014-02-14 06:07:09 +01:00
|
|
|
let s = elt_doc.as_str_slice();
|
2015-05-17 18:14:40 +02:00
|
|
|
Some(ast_map::PathMod(token::intern(s)))
|
2014-01-09 14:05:33 +01:00
|
|
|
} else if tag == tag_path_elem_name {
|
2014-02-14 06:07:09 +01:00
|
|
|
let s = elt_doc.as_str_slice();
|
2015-05-17 18:14:40 +02:00
|
|
|
Some(ast_map::PathName(token::intern(s)))
|
2012-02-10 15:01:32 +01:00
|
|
|
} else {
|
|
|
|
// ignore tag_path_len element
|
2015-05-17 18:14:40 +02:00
|
|
|
None
|
2012-02-10 15:01:32 +01:00
|
|
|
}
|
2015-05-17 18:14:40 +02:00
|
|
|
}).collect()
|
2012-02-10 15:01:32 +01:00
|
|
|
}
|
|
|
|
|
2014-10-01 02:11:34 +02:00
|
|
|
fn item_name(intr: &IdentInterner, item: rbml::Doc) -> ast::Name {
|
2012-12-07 01:13:54 +01:00
|
|
|
let name = reader::get_doc(item, tag_paths_data_name);
|
2013-06-08 02:37:17 +02:00
|
|
|
let string = name.as_str_slice();
|
2014-11-13 00:51:51 +01:00
|
|
|
match intr.find(string) {
|
2014-10-01 02:11:34 +02:00
|
|
|
None => token::intern(string),
|
|
|
|
Some(val) => val,
|
2013-04-03 01:20:02 +02:00
|
|
|
}
|
2011-12-16 14:41:12 +01:00
|
|
|
}
|
|
|
|
|
2015-08-16 12:32:28 +02:00
|
|
|
fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: DefId) -> DefLike {
|
2012-08-23 02:58:05 +02:00
|
|
|
let fam = item_family(item);
|
|
|
|
match fam {
|
2015-03-16 02:35:25 +01:00
|
|
|
Constant => {
|
|
|
|
// Check whether we have an associated const item.
|
|
|
|
if item_sort(item) == Some('C') {
|
2015-08-04 00:16:53 +02:00
|
|
|
DlDef(def::DefAssociatedConst(did))
|
2015-03-16 02:35:25 +01:00
|
|
|
} else {
|
|
|
|
// Regular const item.
|
|
|
|
DlDef(def::DefConst(did))
|
|
|
|
}
|
|
|
|
}
|
2014-05-14 21:31:30 +02:00
|
|
|
ImmStatic => DlDef(def::DefStatic(did, false)),
|
|
|
|
MutStatic => DlDef(def::DefStatic(did, true)),
|
|
|
|
Struct => DlDef(def::DefStruct(did)),
|
2014-10-16 06:44:24 +02:00
|
|
|
Fn => DlDef(def::DefFn(did, false)),
|
|
|
|
CtorFn => DlDef(def::DefFn(did, true)),
|
|
|
|
Method | StaticMethod => {
|
2015-08-04 00:16:53 +02:00
|
|
|
DlDef(def::DefMethod(did))
|
2012-10-13 02:00:08 +02:00
|
|
|
}
|
2015-01-30 11:16:59 +01:00
|
|
|
Type => {
|
|
|
|
if item_sort(item) == Some('t') {
|
2015-05-12 06:49:15 +02:00
|
|
|
let trait_did = item_require_parent_item(cdata, item);
|
2015-01-30 11:16:59 +01:00
|
|
|
DlDef(def::DefAssociatedTy(trait_did, did))
|
|
|
|
} else {
|
|
|
|
DlDef(def::DefTy(did, false))
|
|
|
|
}
|
|
|
|
}
|
2014-05-14 21:31:30 +02:00
|
|
|
Mod => DlDef(def::DefMod(did)),
|
|
|
|
ForeignMod => DlDef(def::DefForeignMod(did)),
|
2013-09-09 02:36:01 +02:00
|
|
|
StructVariant => {
|
2015-05-12 06:49:15 +02:00
|
|
|
let enum_did = item_require_parent_item(cdata, item);
|
2014-05-14 21:31:30 +02:00
|
|
|
DlDef(def::DefVariant(enum_did, did, true))
|
2013-09-09 02:36:01 +02:00
|
|
|
}
|
|
|
|
TupleVariant => {
|
2015-05-12 06:49:15 +02:00
|
|
|
let enum_did = item_require_parent_item(cdata, item);
|
2014-05-14 21:31:30 +02:00
|
|
|
DlDef(def::DefVariant(enum_did, did, false))
|
2012-10-13 02:00:08 +02:00
|
|
|
}
|
2015-02-24 06:45:34 +01:00
|
|
|
Trait => DlDef(def::DefTrait(did)),
|
2014-09-15 23:13:00 +02:00
|
|
|
Enum => DlDef(def::DefTy(did, true)),
|
2015-02-07 14:24:34 +01:00
|
|
|
Impl | DefaultImpl => DlImpl(did),
|
2014-04-16 03:02:58 +02:00
|
|
|
PublicField | InheritedField => DlField,
|
2012-02-13 20:55:23 +01:00
|
|
|
}
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2014-12-10 12:15:06 +01:00
|
|
|
fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety {
|
|
|
|
let unsafety_doc = reader::get_doc(item_doc, tag_unsafety);
|
|
|
|
if reader::doc_as_u8(unsafety_doc) != 0 {
|
|
|
|
ast::Unsafety::Unsafe
|
|
|
|
} else {
|
|
|
|
ast::Unsafety::Normal
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-26 20:39:58 +01:00
|
|
|
fn parse_paren_sugar(item_doc: rbml::Doc) -> bool {
|
|
|
|
let paren_sugar_doc = reader::get_doc(item_doc, tag_paren_sugar);
|
|
|
|
reader::doc_as_u8(paren_sugar_doc) != 0
|
|
|
|
}
|
|
|
|
|
2015-01-07 19:26:51 +01:00
|
|
|
fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity {
|
|
|
|
let polarity_doc = reader::get_doc(item_doc, tag_polarity);
|
|
|
|
if reader::doc_as_u8(polarity_doc) != 0 {
|
|
|
|
ast::ImplPolarity::Negative
|
|
|
|
} else {
|
|
|
|
ast::ImplPolarity::Positive
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-17 20:16:28 +01:00
|
|
|
fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
|
|
|
|
let names_doc = reader::get_doc(item_doc, tag_associated_type_names);
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(names_doc, tag_associated_type_name)
|
|
|
|
.map(|name_doc| token::intern(name_doc.as_str_slice()))
|
|
|
|
.collect()
|
2014-12-17 20:16:28 +01:00
|
|
|
}
|
|
|
|
|
2014-09-29 21:11:30 +02:00
|
|
|
pub fn get_trait_def<'tcx>(cdata: Cmd,
|
|
|
|
item_id: ast::NodeId,
|
|
|
|
tcx: &ty::ctxt<'tcx>) -> ty::TraitDef<'tcx>
|
2013-03-27 11:16:28 +01:00
|
|
|
{
|
2013-12-18 23:10:28 +01:00
|
|
|
let item_doc = lookup_item(item_id, cdata.data());
|
2014-08-28 03:46:52 +02:00
|
|
|
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
|
2014-12-10 12:15:06 +01:00
|
|
|
let unsafety = parse_unsafety(item_doc);
|
2014-12-17 20:16:28 +01:00
|
|
|
let associated_type_names = parse_associated_type_names(item_doc);
|
2015-01-26 20:39:58 +01:00
|
|
|
let paren_sugar = parse_paren_sugar(item_doc);
|
2014-04-03 02:38:45 +02:00
|
|
|
|
2013-03-27 11:16:28 +01:00
|
|
|
ty::TraitDef {
|
2015-01-26 20:39:58 +01:00
|
|
|
paren_sugar: paren_sugar,
|
2014-12-10 01:59:20 +01:00
|
|
|
unsafety: unsafety,
|
2014-08-28 03:46:52 +02:00
|
|
|
generics: generics,
|
2014-12-26 09:31:58 +01:00
|
|
|
trait_ref: item_trait_ref(item_doc, tcx, cdata),
|
2014-12-17 20:16:28 +01:00
|
|
|
associated_type_names: associated_type_names,
|
2015-04-21 18:00:12 +02:00
|
|
|
nonblanket_impls: RefCell::new(FnvHashMap()),
|
|
|
|
blanket_impls: RefCell::new(vec![]),
|
|
|
|
flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
|
2013-03-27 11:16:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-22 20:53:52 +02:00
|
|
|
pub fn get_adt_def<'tcx>(intr: &IdentInterner,
|
|
|
|
cdata: Cmd,
|
2015-07-20 21:13:36 +02:00
|
|
|
item_id: ast::NodeId,
|
2015-08-07 13:41:33 +02:00
|
|
|
tcx: &ty::ctxt<'tcx>) -> ty::AdtDefMaster<'tcx>
|
2015-07-20 21:13:36 +02:00
|
|
|
{
|
2015-07-22 20:53:52 +02:00
|
|
|
fn get_enum_variants<'tcx>(intr: &IdentInterner,
|
|
|
|
cdata: Cmd,
|
|
|
|
doc: rbml::Doc,
|
2015-08-07 13:41:33 +02:00
|
|
|
tcx: &ty::ctxt<'tcx>) -> Vec<ty::VariantDefData<'tcx, 'tcx>> {
|
2015-07-22 20:53:52 +02:00
|
|
|
let mut disr_val = 0;
|
|
|
|
reader::tagged_docs(doc, tag_items_data_item_variant).map(|p| {
|
|
|
|
let did = translated_def_id(cdata, p);
|
|
|
|
let item = lookup_item(did.node, cdata.data());
|
|
|
|
|
|
|
|
if let Some(disr) = variant_disr_val(item) {
|
|
|
|
disr_val = disr;
|
|
|
|
}
|
|
|
|
let disr = disr_val;
|
|
|
|
disr_val = disr_val.wrapping_add(1);
|
|
|
|
|
2015-08-07 13:41:33 +02:00
|
|
|
ty::VariantDefData {
|
2015-07-22 20:53:52 +02:00
|
|
|
did: did,
|
|
|
|
name: item_name(intr, item),
|
|
|
|
fields: get_variant_fields(intr, cdata, item, tcx),
|
|
|
|
disr_val: disr
|
|
|
|
}
|
|
|
|
}).collect()
|
|
|
|
}
|
|
|
|
fn get_variant_fields<'tcx>(intr: &IdentInterner,
|
|
|
|
cdata: Cmd,
|
|
|
|
doc: rbml::Doc,
|
2015-08-07 13:41:33 +02:00
|
|
|
tcx: &ty::ctxt<'tcx>) -> Vec<ty::FieldDefData<'tcx, 'tcx>> {
|
2015-07-22 20:53:52 +02:00
|
|
|
reader::tagged_docs(doc, tag_item_field).map(|f| {
|
|
|
|
let ff = item_family(f);
|
|
|
|
match ff {
|
|
|
|
PublicField | InheritedField => {},
|
|
|
|
_ => tcx.sess.bug(&format!("expected field, found {:?}", ff))
|
|
|
|
};
|
2015-08-07 13:41:33 +02:00
|
|
|
ty::FieldDefData::new(item_def_id(f, cdata),
|
|
|
|
item_name(intr, f),
|
|
|
|
struct_field_family_to_visibility(ff))
|
2015-07-22 20:53:52 +02:00
|
|
|
}).chain(reader::tagged_docs(doc, tag_item_unnamed_field).map(|f| {
|
|
|
|
let ff = item_family(f);
|
2015-08-07 13:41:33 +02:00
|
|
|
ty::FieldDefData::new(item_def_id(f, cdata),
|
|
|
|
special_idents::unnamed_field.name,
|
|
|
|
struct_field_family_to_visibility(ff))
|
2015-07-22 20:53:52 +02:00
|
|
|
})).collect()
|
|
|
|
}
|
|
|
|
fn get_struct_variant<'tcx>(intr: &IdentInterner,
|
|
|
|
cdata: Cmd,
|
|
|
|
doc: rbml::Doc,
|
2015-08-16 12:32:28 +02:00
|
|
|
did: DefId,
|
2015-08-07 13:41:33 +02:00
|
|
|
tcx: &ty::ctxt<'tcx>) -> ty::VariantDefData<'tcx, 'tcx> {
|
|
|
|
ty::VariantDefData {
|
2015-07-22 20:53:52 +02:00
|
|
|
did: did,
|
|
|
|
name: item_name(intr, doc),
|
|
|
|
fields: get_variant_fields(intr, cdata, doc, tcx),
|
|
|
|
disr_val: 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let doc = lookup_item(item_id, cdata.data());
|
2015-08-16 12:32:28 +02:00
|
|
|
let did = DefId { krate: cdata.cnum, node: item_id };
|
2015-07-22 20:53:52 +02:00
|
|
|
let (kind, variants) = match item_family(doc) {
|
2015-08-07 13:41:33 +02:00
|
|
|
Enum => (ty::AdtKind::Enum,
|
2015-07-22 20:53:52 +02:00
|
|
|
get_enum_variants(intr, cdata, doc, tcx)),
|
2015-08-07 13:41:33 +02:00
|
|
|
Struct => (ty::AdtKind::Struct,
|
2015-07-22 20:53:52 +02:00
|
|
|
vec![get_struct_variant(intr, cdata, doc, did, tcx)]),
|
|
|
|
_ => tcx.sess.bug("get_adt_def called on a non-ADT")
|
|
|
|
};
|
|
|
|
|
|
|
|
let adt = tcx.intern_adt_def(did, kind, variants);
|
|
|
|
|
|
|
|
// this needs to be done *after* the variant is interned,
|
|
|
|
// to support recursive structures
|
|
|
|
for variant in &adt.variants {
|
|
|
|
if variant.kind() == ty::VariantKind::Tuple &&
|
2015-08-07 13:41:33 +02:00
|
|
|
adt.adt_kind() == ty::AdtKind::Enum {
|
2015-07-22 20:53:52 +02:00
|
|
|
// tuple-like enum variant fields aren't real items - get the types
|
|
|
|
// from the ctor.
|
|
|
|
debug!("evaluating the ctor-type of {:?}",
|
|
|
|
variant.name);
|
|
|
|
let ctor_ty = get_type(cdata, variant.did.node, tcx).ty;
|
|
|
|
debug!("evaluating the ctor-type of {:?}.. {:?}",
|
|
|
|
variant.name,
|
|
|
|
ctor_ty);
|
|
|
|
let field_tys = match ctor_ty.sty {
|
2015-08-07 12:57:39 +02:00
|
|
|
ty::TyBareFn(_, &ty::BareFnTy { sig: ty::Binder(ty::FnSig {
|
|
|
|
ref inputs, ..
|
|
|
|
}), ..}) => {
|
|
|
|
// tuple-struct constructors don't have escaping regions
|
|
|
|
assert!(!inputs.has_escaping_regions());
|
|
|
|
inputs
|
|
|
|
},
|
2015-07-22 20:53:52 +02:00
|
|
|
_ => tcx.sess.bug("tuple-variant ctor is not an ADT")
|
|
|
|
};
|
|
|
|
for (field, &ty) in variant.fields.iter().zip(field_tys.iter()) {
|
|
|
|
field.fulfill_ty(ty);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for field in &variant.fields {
|
|
|
|
debug!("evaluating the type of {:?}::{:?}", variant.name, field.name);
|
|
|
|
let ty = get_type(cdata, field.did.node, tcx).ty;
|
|
|
|
field.fulfill_ty(ty);
|
|
|
|
debug!("evaluating the type of {:?}::{:?}: {:?}",
|
|
|
|
variant.name, field.name, ty);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
adt
|
2015-07-20 21:13:36 +02:00
|
|
|
}
|
|
|
|
|
2015-02-11 11:59:01 +01:00
|
|
|
pub fn get_predicates<'tcx>(cdata: Cmd,
|
2015-02-11 22:55:22 +01:00
|
|
|
item_id: ast::NodeId,
|
|
|
|
tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> ty::GenericPredicates<'tcx>
|
2015-02-11 11:59:01 +01:00
|
|
|
{
|
|
|
|
let item_doc = lookup_item(item_id, cdata.data());
|
|
|
|
doc_predicates(item_doc, tcx, cdata, tag_item_generics)
|
|
|
|
}
|
2013-10-29 11:03:32 +01:00
|
|
|
|
2015-02-24 15:24:42 +01:00
|
|
|
pub fn get_super_predicates<'tcx>(cdata: Cmd,
|
|
|
|
item_id: ast::NodeId,
|
|
|
|
tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> ty::GenericPredicates<'tcx>
|
|
|
|
{
|
|
|
|
let item_doc = lookup_item(item_id, cdata.data());
|
|
|
|
doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates)
|
|
|
|
}
|
|
|
|
|
2015-02-11 11:59:01 +01:00
|
|
|
pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> ty::TypeScheme<'tcx>
|
|
|
|
{
|
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2015-08-16 12:32:28 +02:00
|
|
|
let t = item_type(DefId { krate: cdata.cnum, node: id }, item_doc, tcx,
|
2013-01-13 20:05:40 +01:00
|
|
|
cdata);
|
2015-02-11 11:59:01 +01:00
|
|
|
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
|
2014-12-23 11:52:47 +01:00
|
|
|
ty::TypeScheme {
|
2014-08-28 03:46:52 +02:00
|
|
|
generics: generics,
|
2013-02-19 08:40:42 +01:00
|
|
|
ty: t
|
|
|
|
}
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
Add stability inheritance
This commit makes several changes to the stability index infrastructure:
* Stability levels are now inherited lexically, i.e., each item's
stability level becomes the default for any nested items.
* The computed stability level for an item is stored as part of the
metadata. When using an item from an external crate, this data is
looked up and cached.
* The stability lint works from the computed stability level, rather
than manual stability attribute annotations. However, the lint still
checks only a limited set of item uses (e.g., it does not check every
component of a path on import). This will be addressed in a later PR,
as part of issue #8962.
* The stability lint only applies to items originating from external
crates, since the stability index is intended as a promise to
downstream crates.
* The "experimental" lint is now _allow_ by default. This is because
almost all existing crates have been marked "experimental", pending
library stabilization. With inheritance in place, this would generate
a massive explosion of warnings for every Rust program.
The lint should be changed back to deny-by-default after library
stabilization is complete.
* The "deprecated" lint still warns by default.
The net result: we can begin tracking stability index for the standard
libraries as we stabilize, without impacting most clients.
Closes #13540.
2014-06-12 02:23:11 +02:00
|
|
|
pub fn get_stability(cdata: Cmd, id: ast::NodeId) -> Option<attr::Stability> {
|
|
|
|
let item = lookup_item(id, cdata.data());
|
|
|
|
reader::maybe_get_doc(item, tag_items_data_item_stability).map(|doc| {
|
|
|
|
let mut decoder = reader::Decoder::new(doc);
|
|
|
|
Decodable::decode(&mut decoder).unwrap()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2014-09-30 06:52:06 +02:00
|
|
|
pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> {
|
|
|
|
let item = lookup_item(id, cdata.data());
|
|
|
|
match reader::maybe_get_doc(item, tag_items_data_item_repr).map(|doc| {
|
|
|
|
let mut decoder = reader::Decoder::new(doc);
|
|
|
|
Decodable::decode(&mut decoder).unwrap()
|
|
|
|
}) {
|
|
|
|
Some(attrs) => attrs,
|
|
|
|
None => Vec::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-07 19:26:51 +01:00
|
|
|
pub fn get_impl_polarity<'tcx>(cdata: Cmd,
|
|
|
|
id: ast::NodeId)
|
|
|
|
-> Option<ast::ImplPolarity>
|
|
|
|
{
|
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
|
|
|
let fam = item_family(item_doc);
|
|
|
|
match fam {
|
|
|
|
Family::Impl => {
|
|
|
|
Some(parse_polarity(item_doc))
|
|
|
|
}
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-15 01:57:29 +02:00
|
|
|
pub fn get_custom_coerce_unsized_kind<'tcx>(cdata: Cmd,
|
|
|
|
id: ast::NodeId)
|
|
|
|
-> Option<ty::CustomCoerceUnsized> {
|
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
|
|
|
reader::maybe_get_doc(item_doc, tag_impl_coerce_unsized_kind).map(|kind_doc| {
|
|
|
|
let mut decoder = reader::Decoder::new(kind_doc);
|
|
|
|
Decodable::decode(&mut decoder).unwrap()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2014-09-29 21:11:30 +02:00
|
|
|
pub fn get_impl_trait<'tcx>(cdata: Cmd,
|
|
|
|
id: ast::NodeId,
|
|
|
|
tcx: &ty::ctxt<'tcx>)
|
2015-04-21 17:59:58 +02:00
|
|
|
-> Option<ty::TraitRef<'tcx>>
|
2013-03-27 11:16:28 +01:00
|
|
|
{
|
2013-12-18 23:10:28 +01:00
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2015-01-02 03:41:44 +01:00
|
|
|
let fam = item_family(item_doc);
|
|
|
|
match fam {
|
2015-02-07 14:24:34 +01:00
|
|
|
Family::Impl | Family::DefaultImpl => {
|
2015-01-02 03:41:44 +01:00
|
|
|
reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
|
|
|
|
doc_trait_ref(tp, tcx, cdata)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
_ => None
|
|
|
|
}
|
2012-01-05 10:57:19 +01:00
|
|
|
}
|
|
|
|
|
2014-05-23 01:57:53 +02:00
|
|
|
pub fn get_symbol(data: &[u8], id: ast::NodeId) -> String {
|
2012-08-02 02:30:05 +02:00
|
|
|
return item_symbol(lookup_item(id, data));
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2012-05-22 19:54:12 +02:00
|
|
|
// Something that a name can resolve to.
|
2015-01-28 14:34:18 +01:00
|
|
|
#[derive(Copy, Clone, Debug)]
|
2013-08-31 18:13:04 +02:00
|
|
|
pub enum DefLike {
|
2014-05-14 21:31:30 +02:00
|
|
|
DlDef(def::Def),
|
2015-08-16 12:32:28 +02:00
|
|
|
DlImpl(DefId),
|
2013-08-31 18:13:04 +02:00
|
|
|
DlField
|
2012-05-22 19:54:12 +02:00
|
|
|
}
|
|
|
|
|
2013-01-07 19:51:53 +01:00
|
|
|
/// Iterates over the language items in the given crate.
|
2014-12-09 02:26:43 +01:00
|
|
|
pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
|
2015-03-26 01:06:52 +01:00
|
|
|
F: FnMut(ast::NodeId, usize) -> bool,
|
2014-12-09 02:26:43 +01:00
|
|
|
{
|
2014-07-30 02:06:37 +02:00
|
|
|
let root = rbml::Doc::new(cdata.data());
|
2013-05-03 19:08:08 +02:00
|
|
|
let lang_items = reader::get_doc(root, tag_lang_items);
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(lang_items, tag_lang_items_item).all(|item_doc| {
|
2013-05-03 19:08:08 +02:00
|
|
|
let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
|
2015-03-26 01:06:52 +01:00
|
|
|
let id = reader::doc_as_u32(id_doc) as usize;
|
2013-05-03 19:08:08 +02:00
|
|
|
let node_id_doc = reader::get_doc(item_doc,
|
|
|
|
tag_lang_items_item_node_id);
|
2013-07-27 10:25:59 +02:00
|
|
|
let node_id = reader::doc_as_u32(node_id_doc) as ast::NodeId;
|
2013-05-03 19:08:08 +02:00
|
|
|
|
2013-08-02 08:17:20 +02:00
|
|
|
f(node_id, id)
|
2013-11-22 00:42:55 +01:00
|
|
|
})
|
2013-05-03 19:08:08 +02:00
|
|
|
}
|
2013-01-07 19:51:53 +01:00
|
|
|
|
2014-12-31 04:48:22 +01:00
|
|
|
fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
|
|
|
|
cdata: Cmd,
|
|
|
|
item_doc: rbml::Doc,
|
|
|
|
mut get_crate_data: G,
|
|
|
|
mut callback: F) where
|
2014-12-09 02:26:43 +01:00
|
|
|
F: FnMut(DefLike, ast::Name, ast::Visibility),
|
2014-12-31 04:48:22 +01:00
|
|
|
G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
|
2014-12-09 02:26:43 +01:00
|
|
|
{
|
2013-08-22 02:26:33 +02:00
|
|
|
// Iterate over all children.
|
2015-05-24 12:23:29 +02:00
|
|
|
for child_info_doc in reader::tagged_docs(item_doc, tag_mod_child) {
|
2015-05-12 06:49:15 +02:00
|
|
|
let child_def_id = translated_def_id(cdata, child_info_doc);
|
2013-08-22 02:26:33 +02:00
|
|
|
|
|
|
|
// This item may be in yet another crate if it was the child of a
|
|
|
|
// reexport.
|
2014-04-17 14:06:25 +02:00
|
|
|
let crate_data = if child_def_id.krate == cdata.cnum {
|
|
|
|
None
|
2013-08-22 02:26:33 +02:00
|
|
|
} else {
|
2014-04-17 14:06:25 +02:00
|
|
|
Some(get_crate_data(child_def_id.krate))
|
|
|
|
};
|
|
|
|
let crate_data = match crate_data {
|
|
|
|
Some(ref cdata) => &**cdata,
|
|
|
|
None => cdata
|
2013-08-22 02:26:33 +02:00
|
|
|
};
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
let other_crates_items = reader::get_doc(rbml::Doc::new(crate_data.data()), tag_items);
|
2014-04-17 14:06:25 +02:00
|
|
|
|
2013-08-22 02:26:33 +02:00
|
|
|
// Get the item.
|
|
|
|
match maybe_find_item(child_def_id.node, other_crates_items) {
|
|
|
|
None => {}
|
|
|
|
Some(child_item_doc) => {
|
|
|
|
// Hand off the item to the callback.
|
2014-03-27 18:28:38 +01:00
|
|
|
let child_name = item_name(&*intr, child_item_doc);
|
2015-05-12 06:49:15 +02:00
|
|
|
let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
|
2013-08-07 09:11:34 +02:00
|
|
|
let visibility = item_visibility(child_item_doc);
|
|
|
|
callback(def_like, child_name, visibility);
|
2013-08-24 03:31:43 +02:00
|
|
|
}
|
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
2013-08-24 03:31:43 +02:00
|
|
|
|
|
|
|
// As a special case, iterate over all static methods of
|
|
|
|
// associated implementations too. This is a bit of a botch.
|
|
|
|
// --pcwalton
|
2015-05-24 12:23:29 +02:00
|
|
|
for inherent_impl_def_id_doc in reader::tagged_docs(item_doc,
|
|
|
|
tag_items_data_item_inherent_impl) {
|
|
|
|
let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc, cdata);
|
2014-07-30 02:06:37 +02:00
|
|
|
let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
|
2014-11-29 22:41:21 +01:00
|
|
|
if let Some(inherent_impl_doc) = maybe_find_item(inherent_impl_def_id.node, items) {
|
2015-05-24 12:23:29 +02:00
|
|
|
for impl_item_def_id_doc in reader::tagged_docs(inherent_impl_doc,
|
|
|
|
tag_item_impl_item) {
|
2014-11-29 22:41:21 +01:00
|
|
|
let impl_item_def_id = item_def_id(impl_item_def_id_doc,
|
|
|
|
cdata);
|
|
|
|
if let Some(impl_method_doc) = maybe_find_item(impl_item_def_id.node, items) {
|
2014-12-01 00:11:40 +01:00
|
|
|
if let StaticMethod = item_family(impl_method_doc) {
|
|
|
|
// Hand off the static method to the callback.
|
|
|
|
let static_method_name = item_name(&*intr, impl_method_doc);
|
2015-05-12 06:49:15 +02:00
|
|
|
let static_method_def_like = item_to_def_like(cdata, impl_method_doc,
|
|
|
|
impl_item_def_id);
|
2014-12-01 00:11:40 +01:00
|
|
|
callback(static_method_def_like,
|
|
|
|
static_method_name,
|
|
|
|
item_visibility(impl_method_doc));
|
2013-08-24 03:31:43 +02:00
|
|
|
}
|
2014-11-29 22:41:21 +01:00
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
2013-08-22 02:26:33 +02:00
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
2013-08-22 02:26:33 +02:00
|
|
|
|
2015-05-27 07:26:35 +02:00
|
|
|
for reexport_doc in reexports(item_doc) {
|
2013-08-22 02:26:33 +02:00
|
|
|
let def_id_doc = reader::get_doc(reexport_doc,
|
|
|
|
tag_items_data_item_reexport_def_id);
|
2015-05-12 06:49:15 +02:00
|
|
|
let child_def_id = translated_def_id(cdata, def_id_doc);
|
2013-08-22 02:26:33 +02:00
|
|
|
|
|
|
|
let name_doc = reader::get_doc(reexport_doc,
|
|
|
|
tag_items_data_item_reexport_name);
|
|
|
|
let name = name_doc.as_str_slice();
|
|
|
|
|
|
|
|
// This reexport may be in yet another crate.
|
2014-04-17 14:06:25 +02:00
|
|
|
let crate_data = if child_def_id.krate == cdata.cnum {
|
|
|
|
None
|
2013-08-22 02:26:33 +02:00
|
|
|
} else {
|
2014-04-17 14:06:25 +02:00
|
|
|
Some(get_crate_data(child_def_id.krate))
|
|
|
|
};
|
|
|
|
let crate_data = match crate_data {
|
|
|
|
Some(ref cdata) => &**cdata,
|
|
|
|
None => cdata
|
2013-08-22 02:26:33 +02:00
|
|
|
};
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
let other_crates_items = reader::get_doc(rbml::Doc::new(crate_data.data()), tag_items);
|
2014-04-17 14:06:25 +02:00
|
|
|
|
2013-08-22 02:26:33 +02:00
|
|
|
// Get the item.
|
2014-11-29 22:41:21 +01:00
|
|
|
if let Some(child_item_doc) = maybe_find_item(child_def_id.node, other_crates_items) {
|
|
|
|
// Hand off the item to the callback.
|
2015-05-12 06:49:15 +02:00
|
|
|
let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
|
2014-11-29 22:41:21 +01:00
|
|
|
// These items have a public visibility because they're part of
|
|
|
|
// a public re-export.
|
|
|
|
callback(def_like, token::intern(name), ast::Public);
|
2013-08-22 02:26:33 +02:00
|
|
|
}
|
2015-05-27 07:26:35 +02:00
|
|
|
}
|
2013-08-22 02:26:33 +02:00
|
|
|
}
|
2013-06-18 18:39:16 +02:00
|
|
|
|
2013-08-22 02:26:33 +02:00
|
|
|
/// Iterates over each child of the given item.
|
2014-12-31 04:48:22 +01:00
|
|
|
pub fn each_child_of_item<F, G>(intr: Rc<IdentInterner>,
|
|
|
|
cdata: Cmd,
|
|
|
|
id: ast::NodeId,
|
|
|
|
get_crate_data: G,
|
|
|
|
callback: F) where
|
2014-12-09 02:26:43 +01:00
|
|
|
F: FnMut(DefLike, ast::Name, ast::Visibility),
|
2014-12-31 04:48:22 +01:00
|
|
|
G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
|
2014-12-09 02:26:43 +01:00
|
|
|
{
|
2013-08-22 02:26:33 +02:00
|
|
|
// Find the item.
|
2014-07-30 02:06:37 +02:00
|
|
|
let root_doc = rbml::Doc::new(cdata.data());
|
2013-08-22 02:26:33 +02:00
|
|
|
let items = reader::get_doc(root_doc, tag_items);
|
|
|
|
let item_doc = match maybe_find_item(id, items) {
|
|
|
|
None => return,
|
|
|
|
Some(item_doc) => item_doc,
|
|
|
|
};
|
|
|
|
|
|
|
|
each_child_of_item_or_crate(intr,
|
|
|
|
cdata,
|
|
|
|
item_doc,
|
|
|
|
get_crate_data,
|
|
|
|
callback)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Iterates over all the top-level crate items.
|
2014-12-31 04:48:22 +01:00
|
|
|
pub fn each_top_level_item_of_crate<F, G>(intr: Rc<IdentInterner>,
|
|
|
|
cdata: Cmd,
|
|
|
|
get_crate_data: G,
|
|
|
|
callback: F) where
|
2014-12-09 02:26:43 +01:00
|
|
|
F: FnMut(DefLike, ast::Name, ast::Visibility),
|
2014-12-31 04:48:22 +01:00
|
|
|
G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
|
2014-12-09 02:26:43 +01:00
|
|
|
{
|
2014-07-30 02:06:37 +02:00
|
|
|
let root_doc = rbml::Doc::new(cdata.data());
|
2013-06-18 18:39:16 +02:00
|
|
|
let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
|
|
|
|
let crate_items_doc = reader::get_doc(misc_info_doc,
|
|
|
|
tag_misc_info_crate_items);
|
|
|
|
|
2013-08-22 02:26:33 +02:00
|
|
|
each_child_of_item_or_crate(intr,
|
|
|
|
cdata,
|
|
|
|
crate_items_doc,
|
|
|
|
get_crate_data,
|
|
|
|
callback)
|
2012-05-22 19:54:12 +02:00
|
|
|
}
|
|
|
|
|
2014-03-04 19:02:49 +01:00
|
|
|
pub fn get_item_path(cdata: Cmd, id: ast::NodeId) -> Vec<ast_map::PathElem> {
|
2013-12-18 23:10:28 +01:00
|
|
|
item_path(lookup_item(id, cdata.data()))
|
2012-02-10 15:01:32 +01:00
|
|
|
}
|
|
|
|
|
2015-08-12 20:22:25 +02:00
|
|
|
pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: ast::NodeId) -> ast::Name {
|
|
|
|
item_name(intr, lookup_item(id, cdata.data()))
|
|
|
|
}
|
|
|
|
|
2015-01-04 15:07:13 +01:00
|
|
|
pub type DecodeInlinedItem<'a> =
|
|
|
|
Box<for<'tcx> FnMut(Cmd,
|
|
|
|
&ty::ctxt<'tcx>,
|
|
|
|
Vec<ast_map::PathElem>,
|
|
|
|
rbml::Doc)
|
2015-08-13 16:57:34 +02:00
|
|
|
-> Result<&'tcx InlinedItem, Vec<ast_map::PathElem>> + 'a>;
|
2012-05-15 02:46:45 +02:00
|
|
|
|
2014-09-07 19:09:06 +02:00
|
|
|
pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeId,
|
2015-01-04 15:07:13 +01:00
|
|
|
mut decode_inlined_item: DecodeInlinedItem)
|
2015-01-24 18:58:07 +01:00
|
|
|
-> csearch::FoundAst<'tcx> {
|
2013-10-21 22:08:31 +02:00
|
|
|
debug!("Looking up item: {}", id);
|
2013-12-18 23:10:28 +01:00
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2015-07-11 13:34:57 +02:00
|
|
|
let path = item_path(item_doc).split_last().unwrap().1.to_vec();
|
2015-01-06 18:24:46 +01:00
|
|
|
match decode_inlined_item(cdata, tcx, path, item_doc) {
|
2015-01-24 18:58:07 +01:00
|
|
|
Ok(ii) => csearch::FoundAst::Found(ii),
|
2014-02-14 06:07:09 +01:00
|
|
|
Err(path) => {
|
2015-05-12 06:49:15 +02:00
|
|
|
match item_parent_item(cdata, item_doc) {
|
2014-02-14 06:07:09 +01:00
|
|
|
Some(did) => {
|
|
|
|
let parent_item = lookup_item(did.node, cdata.data());
|
2015-01-06 18:24:46 +01:00
|
|
|
match decode_inlined_item(cdata, tcx, path, parent_item) {
|
2015-01-24 18:58:07 +01:00
|
|
|
Ok(ii) => csearch::FoundAst::FoundParent(did, ii),
|
|
|
|
Err(_) => csearch::FoundAst::NotFound
|
2014-02-14 06:07:09 +01:00
|
|
|
}
|
|
|
|
}
|
2015-01-24 18:58:07 +01:00
|
|
|
None => csearch::FoundAst::NotFound
|
2012-03-08 23:13:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-02-15 00:21:53 +01:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
|
2013-09-02 03:45:37 +02:00
|
|
|
fn get_mutability(ch: u8) -> ast::Mutability {
|
2012-08-06 21:34:08 +02:00
|
|
|
match ch as char {
|
2013-09-02 03:45:37 +02:00
|
|
|
'i' => ast::MutImmutable,
|
|
|
|
'm' => ast::MutMutable,
|
2014-10-09 21:17:22 +02:00
|
|
|
_ => panic!("unknown mutability character: `{}`", ch as char),
|
2012-08-01 01:32:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-30 17:49:48 +02:00
|
|
|
let explicit_self_doc = reader::get_doc(item, tag_item_trait_method_explicit_self);
|
2013-06-08 02:37:17 +02:00
|
|
|
let string = explicit_self_doc.as_str_slice();
|
2012-08-01 01:32:37 +02:00
|
|
|
|
2014-06-20 03:22:33 +02:00
|
|
|
let explicit_self_kind = string.as_bytes()[0];
|
2013-04-30 17:49:48 +02:00
|
|
|
match explicit_self_kind as char {
|
2014-05-07 01:37:32 +02:00
|
|
|
's' => ty::StaticExplicitSelfCategory,
|
|
|
|
'v' => ty::ByValueExplicitSelfCategory,
|
|
|
|
'~' => ty::ByBoxExplicitSelfCategory,
|
2014-01-09 14:05:33 +01:00
|
|
|
// FIXME(#4846) expl. region
|
2014-05-07 01:37:32 +02:00
|
|
|
'&' => {
|
|
|
|
ty::ByReferenceExplicitSelfCategory(
|
|
|
|
ty::ReEmpty,
|
|
|
|
get_mutability(string.as_bytes()[1]))
|
|
|
|
}
|
2014-10-09 21:17:22 +02:00
|
|
|
_ => panic!("unknown self type code: `{}`", explicit_self_kind as char)
|
2012-08-01 01:32:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-04 22:56:56 +02:00
|
|
|
/// Returns the def IDs of all the items in the given implementation.
|
|
|
|
pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
|
|
|
|
-> Vec<ty::ImplOrTraitItemId> {
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(lookup_item(impl_id, cdata.data()), tag_item_impl_item).map(|doc| {
|
2014-08-04 22:56:56 +02:00
|
|
|
let def_id = item_def_id(doc, cdata);
|
|
|
|
match item_sort(doc) {
|
2015-05-24 12:23:29 +02:00
|
|
|
Some('C') => ty::ConstTraitItemId(def_id),
|
|
|
|
Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
|
|
|
|
Some('t') => ty::TypeTraitItemId(def_id),
|
2014-10-09 21:17:22 +02:00
|
|
|
_ => panic!("unknown impl item sort"),
|
2014-08-04 22:56:56 +02:00
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
}).collect()
|
2012-01-05 13:57:27 +01:00
|
|
|
}
|
|
|
|
|
2014-11-23 10:29:41 +01:00
|
|
|
pub fn get_trait_name(intr: Rc<IdentInterner>,
|
|
|
|
cdata: Cmd,
|
|
|
|
id: ast::NodeId)
|
|
|
|
-> ast::Name {
|
|
|
|
let doc = lookup_item(id, cdata.data());
|
|
|
|
item_name(&*intr, doc)
|
|
|
|
}
|
|
|
|
|
2015-02-11 08:32:25 +01:00
|
|
|
pub fn is_static_method(cdata: Cmd, id: ast::NodeId) -> bool {
|
2014-08-04 22:56:56 +02:00
|
|
|
let doc = lookup_item(id, cdata.data());
|
|
|
|
match item_sort(doc) {
|
2015-01-30 11:16:59 +01:00
|
|
|
Some('r') | Some('p') => {
|
2015-02-11 08:32:25 +01:00
|
|
|
get_explicit_self(doc) == ty::StaticExplicitSelfCategory
|
2014-08-04 22:56:56 +02:00
|
|
|
}
|
2015-02-11 08:32:25 +01:00
|
|
|
_ => false
|
2014-08-04 22:56:56 +02:00
|
|
|
}
|
2013-03-27 15:26:57 +01:00
|
|
|
}
|
|
|
|
|
2014-09-29 21:11:30 +02:00
|
|
|
pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
|
|
|
|
cdata: Cmd,
|
|
|
|
id: ast::NodeId,
|
|
|
|
tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> ty::ImplOrTraitItem<'tcx> {
|
2015-05-26 16:12:39 +02:00
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2014-08-28 03:46:52 +02:00
|
|
|
|
2015-05-26 16:12:39 +02:00
|
|
|
let def_id = item_def_id(item_doc, cdata);
|
2013-08-23 23:34:00 +02:00
|
|
|
|
2015-05-26 16:12:39 +02:00
|
|
|
let container_id = item_require_parent_item(cdata, item_doc);
|
2013-12-18 23:10:28 +01:00
|
|
|
let container_doc = lookup_item(container_id.node, cdata.data());
|
2013-08-23 23:34:00 +02:00
|
|
|
let container = match item_family(container_doc) {
|
|
|
|
Trait => TraitContainer(container_id),
|
|
|
|
_ => ImplContainer(container_id),
|
|
|
|
};
|
|
|
|
|
2015-05-26 16:12:39 +02:00
|
|
|
let name = item_name(&*intr, item_doc);
|
|
|
|
let vis = item_visibility(item_doc);
|
2014-08-04 22:56:56 +02:00
|
|
|
|
2015-05-26 16:12:39 +02:00
|
|
|
match item_sort(item_doc) {
|
2015-03-16 02:35:25 +01:00
|
|
|
Some('C') => {
|
2015-05-26 16:12:39 +02:00
|
|
|
let ty = doc_type(item_doc, tcx, cdata);
|
|
|
|
let default = get_provided_source(item_doc, cdata);
|
2015-03-16 02:35:25 +01:00
|
|
|
ty::ConstTraitItem(Rc::new(ty::AssociatedConst {
|
|
|
|
name: name,
|
|
|
|
ty: ty,
|
|
|
|
vis: vis,
|
|
|
|
def_id: def_id,
|
|
|
|
container: container,
|
|
|
|
default: default,
|
|
|
|
}))
|
|
|
|
}
|
2015-01-30 11:16:59 +01:00
|
|
|
Some('r') | Some('p') => {
|
2015-05-26 16:12:39 +02:00
|
|
|
let generics = doc_generics(item_doc, tcx, cdata, tag_method_ty_generics);
|
|
|
|
let predicates = doc_predicates(item_doc, tcx, cdata, tag_method_ty_generics);
|
|
|
|
let fty = doc_method_fty(item_doc, tcx, cdata);
|
|
|
|
let explicit_self = get_explicit_self(item_doc);
|
|
|
|
let provided_source = get_provided_source(item_doc, cdata);
|
2014-08-04 22:56:56 +02:00
|
|
|
|
|
|
|
ty::MethodTraitItem(Rc::new(ty::Method::new(name,
|
|
|
|
generics,
|
2015-02-11 11:59:01 +01:00
|
|
|
predicates,
|
2014-08-04 22:56:56 +02:00
|
|
|
fty,
|
|
|
|
explicit_self,
|
|
|
|
vis,
|
|
|
|
def_id,
|
|
|
|
container,
|
|
|
|
provided_source)))
|
|
|
|
}
|
2015-01-30 11:16:59 +01:00
|
|
|
Some('t') => {
|
2015-05-26 16:12:39 +02:00
|
|
|
let ty = maybe_doc_type(item_doc, tcx, cdata);
|
2014-08-06 04:44:21 +02:00
|
|
|
ty::TypeTraitItem(Rc::new(ty::AssociatedType {
|
2014-10-01 02:11:34 +02:00
|
|
|
name: name,
|
2015-05-26 16:12:39 +02:00
|
|
|
ty: ty,
|
2014-08-06 04:44:21 +02:00
|
|
|
vis: vis,
|
|
|
|
def_id: def_id,
|
|
|
|
container: container,
|
|
|
|
}))
|
|
|
|
}
|
2014-10-09 21:17:22 +02:00
|
|
|
_ => panic!("unknown impl/trait item sort"),
|
2014-08-04 22:56:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
|
|
|
|
-> Vec<ty::ImplOrTraitItemId> {
|
2013-12-18 23:10:28 +01:00
|
|
|
let data = cdata.data();
|
2012-03-15 14:47:03 +01:00
|
|
|
let item = lookup_item(id, data);
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(item, tag_item_trait_item).map(|mth| {
|
2014-08-04 22:56:56 +02:00
|
|
|
let def_id = item_def_id(mth, cdata);
|
|
|
|
match item_sort(mth) {
|
2015-05-24 12:23:29 +02:00
|
|
|
Some('C') => ty::ConstTraitItemId(def_id),
|
|
|
|
Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
|
|
|
|
Some('t') => ty::TypeTraitItemId(def_id),
|
2014-10-09 21:17:22 +02:00
|
|
|
_ => panic!("unknown trait item sort"),
|
2014-08-04 22:56:56 +02:00
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
}).collect()
|
2012-01-05 13:57:27 +01:00
|
|
|
}
|
|
|
|
|
2013-10-29 11:08:34 +01:00
|
|
|
pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances {
|
2013-12-18 23:10:28 +01:00
|
|
|
let data = cdata.data();
|
2013-10-29 11:08:34 +01:00
|
|
|
let item_doc = lookup_item(id, data);
|
|
|
|
let variance_doc = reader::get_doc(item_doc, tag_item_variances);
|
2014-05-28 21:36:05 +02:00
|
|
|
let mut decoder = reader::Decoder::new(variance_doc);
|
2014-03-29 01:05:46 +01:00
|
|
|
Decodable::decode(&mut decoder).unwrap()
|
2013-10-29 11:08:34 +01:00
|
|
|
}
|
|
|
|
|
2014-09-29 21:11:30 +02:00
|
|
|
pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
|
|
|
|
cdata: Cmd,
|
|
|
|
id: ast::NodeId,
|
|
|
|
tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> Vec<Rc<ty::Method<'tcx>>> {
|
2013-12-18 23:10:28 +01:00
|
|
|
let data = cdata.data();
|
2012-10-08 21:39:30 +02:00
|
|
|
let item = lookup_item(id, data);
|
|
|
|
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(item, tag_item_trait_item).filter_map(|mth_id| {
|
2013-06-12 23:22:17 +02:00
|
|
|
let did = item_def_id(mth_id, cdata);
|
|
|
|
let mth = lookup_item(did.node, data);
|
2012-10-08 21:39:30 +02:00
|
|
|
|
2015-01-30 11:16:59 +01:00
|
|
|
if item_sort(mth) == Some('p') {
|
2014-08-04 22:56:56 +02:00
|
|
|
let trait_item = get_impl_or_trait_item(intr.clone(),
|
|
|
|
cdata,
|
|
|
|
did.node,
|
|
|
|
tcx);
|
2015-03-14 19:05:00 +01:00
|
|
|
if let ty::MethodTraitItem(ref method) = trait_item {
|
2015-05-24 12:23:29 +02:00
|
|
|
Some((*method).clone())
|
|
|
|
} else {
|
|
|
|
None
|
2014-08-04 22:56:56 +02:00
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
} else {
|
|
|
|
None
|
2013-08-02 08:17:20 +02:00
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
}).collect()
|
2012-10-08 21:39:30 +02:00
|
|
|
}
|
|
|
|
|
2015-03-16 02:35:25 +01:00
|
|
|
pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
|
|
|
|
cdata: Cmd,
|
|
|
|
id: ast::NodeId,
|
|
|
|
tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> Vec<Rc<ty::AssociatedConst<'tcx>>> {
|
|
|
|
let data = cdata.data();
|
|
|
|
let item = lookup_item(id, data);
|
|
|
|
|
2015-05-24 12:23:29 +02:00
|
|
|
[tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| {
|
|
|
|
reader::tagged_docs(item, tag).filter_map(|ac_id| {
|
2015-03-21 22:06:28 +01:00
|
|
|
let did = item_def_id(ac_id, cdata);
|
|
|
|
let ac_doc = lookup_item(did.node, data);
|
|
|
|
|
|
|
|
if item_sort(ac_doc) == Some('C') {
|
|
|
|
let trait_item = get_impl_or_trait_item(intr.clone(),
|
|
|
|
cdata,
|
|
|
|
did.node,
|
|
|
|
tcx);
|
|
|
|
if let ty::ConstTraitItem(ref ac) = trait_item {
|
2015-05-24 12:23:29 +02:00
|
|
|
Some((*ac).clone())
|
|
|
|
} else {
|
|
|
|
None
|
2015-03-21 22:06:28 +01:00
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
} else {
|
|
|
|
None
|
2015-03-16 02:35:25 +01:00
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
})
|
|
|
|
}).collect()
|
2015-03-16 02:35:25 +01:00
|
|
|
}
|
|
|
|
|
2013-08-31 18:13:04 +02:00
|
|
|
pub fn get_type_name_if_impl(cdata: Cmd,
|
2014-10-01 02:11:34 +02:00
|
|
|
node_id: ast::NodeId) -> Option<ast::Name> {
|
2013-12-18 23:10:28 +01:00
|
|
|
let item = lookup_item(node_id, cdata.data());
|
2012-10-18 22:29:34 +02:00
|
|
|
if item_family(item) != Impl {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(item, tag_item_impl_type_basename).nth(0).map(|doc| {
|
|
|
|
token::intern(doc.as_str_slice())
|
|
|
|
})
|
2012-10-18 22:29:34 +02:00
|
|
|
}
|
|
|
|
|
2014-10-20 03:30:31 +02:00
|
|
|
pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
|
2013-08-31 18:13:04 +02:00
|
|
|
cdata: Cmd,
|
2013-07-27 10:25:59 +02:00
|
|
|
node_id: ast::NodeId)
|
2014-10-20 03:30:31 +02:00
|
|
|
-> Option<Vec<MethodInfo> > {
|
2013-12-18 23:10:28 +01:00
|
|
|
let item = lookup_item(node_id, cdata.data());
|
2012-10-18 22:29:34 +02:00
|
|
|
if item_family(item) != Impl {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2013-03-27 11:16:28 +01:00
|
|
|
// If this impl implements a trait, don't consider it.
|
2015-05-24 12:23:29 +02:00
|
|
|
if reader::tagged_docs(item, tag_item_trait_ref).next().is_some() {
|
|
|
|
return None;
|
|
|
|
}
|
2012-10-18 22:29:34 +02:00
|
|
|
|
2015-05-24 12:23:29 +02:00
|
|
|
let impl_method_ids = reader::tagged_docs(item, tag_item_impl_item)
|
|
|
|
.map(|impl_method_doc| item_def_id(impl_method_doc, cdata));
|
2012-10-18 22:29:34 +02:00
|
|
|
|
2014-10-20 03:30:31 +02:00
|
|
|
let mut impl_methods = Vec::new();
|
2015-05-24 12:23:29 +02:00
|
|
|
for impl_method_id in impl_method_ids {
|
2013-12-18 23:10:28 +01:00
|
|
|
let impl_method_doc = lookup_item(impl_method_id.node, cdata.data());
|
2012-10-18 22:29:34 +02:00
|
|
|
let family = item_family(impl_method_doc);
|
|
|
|
match family {
|
2014-10-20 03:30:31 +02:00
|
|
|
StaticMethod | Method => {
|
|
|
|
impl_methods.push(MethodInfo {
|
2014-10-30 04:33:37 +01:00
|
|
|
name: item_name(&*intr, impl_method_doc),
|
2012-10-18 22:29:34 +02:00
|
|
|
def_id: item_def_id(impl_method_doc, cdata),
|
2013-08-07 09:11:34 +02:00
|
|
|
vis: item_visibility(impl_method_doc),
|
2012-10-18 22:29:34 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-20 03:30:31 +02:00
|
|
|
return Some(impl_methods);
|
2012-10-18 22:29:34 +02:00
|
|
|
}
|
|
|
|
|
2014-01-30 13:36:05 +01:00
|
|
|
/// If node_id is the constructor of a tuple struct, retrieve the NodeId of
|
|
|
|
/// the actual type definition, otherwise, return None
|
|
|
|
pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
|
2014-04-01 03:13:44 +02:00
|
|
|
node_id: ast::NodeId)
|
2015-08-16 12:32:28 +02:00
|
|
|
-> Option<DefId>
|
2014-04-01 03:13:44 +02:00
|
|
|
{
|
2014-01-30 13:36:05 +01:00
|
|
|
let item = lookup_item(node_id, cdata.data());
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor).next().map(|_| {
|
|
|
|
item_require_parent_item(cdata, item)
|
|
|
|
})
|
2014-01-30 13:36:05 +01:00
|
|
|
}
|
|
|
|
|
2015-01-11 17:33:02 +01:00
|
|
|
pub fn get_item_attrs(cdata: Cmd,
|
|
|
|
orig_node_id: ast::NodeId)
|
|
|
|
-> Vec<ast::Attribute> {
|
2014-01-30 13:36:05 +01:00
|
|
|
// The attributes for a tuple struct are attached to the definition, not the ctor;
|
|
|
|
// we assume that someone passing in a tuple struct ctor is actually wanting to
|
|
|
|
// look at the definition
|
2014-04-01 03:13:44 +02:00
|
|
|
let node_id = get_tuple_struct_definition_if_ctor(cdata, orig_node_id);
|
|
|
|
let node_id = node_id.map(|x| x.node).unwrap_or(orig_node_id);
|
2013-12-18 23:10:28 +01:00
|
|
|
let item = lookup_item(node_id, cdata.data());
|
2015-01-11 17:33:02 +01:00
|
|
|
get_attributes(item)
|
2012-07-26 03:36:18 +02:00
|
|
|
}
|
|
|
|
|
2014-07-26 22:21:36 +02:00
|
|
|
pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap<ast::NodeId, Vec<ast::Attribute>> {
|
2014-07-30 02:06:37 +02:00
|
|
|
let data = rbml::Doc::new(cdata.data());
|
2014-07-26 22:21:36 +02:00
|
|
|
let fields = reader::get_doc(data, tag_struct_fields);
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(fields, tag_struct_field).map(|field| {
|
2014-07-26 22:21:36 +02:00
|
|
|
let id = reader::doc_as_u32(reader::get_doc(field, tag_struct_field_id));
|
|
|
|
let attrs = get_attributes(field);
|
2015-05-24 12:23:29 +02:00
|
|
|
(id, attrs)
|
|
|
|
}).collect()
|
2014-07-26 22:21:36 +02:00
|
|
|
}
|
|
|
|
|
2014-01-09 14:05:33 +01:00
|
|
|
fn struct_field_family_to_visibility(family: Family) -> ast::Visibility {
|
2012-12-10 22:47:54 +01:00
|
|
|
match family {
|
2014-01-09 14:05:33 +01:00
|
|
|
PublicField => ast::Public,
|
|
|
|
InheritedField => ast::Inherited,
|
2014-10-09 21:17:22 +02:00
|
|
|
_ => panic!()
|
2012-12-10 22:47:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-06 00:55:13 +02:00
|
|
|
pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: ast::NodeId)
|
|
|
|
-> Vec<ast::Name> {
|
2013-12-18 23:10:28 +01:00
|
|
|
let data = cdata.data();
|
2012-03-15 14:47:03 +01:00
|
|
|
let item = lookup_item(id, data);
|
2015-08-06 00:55:13 +02:00
|
|
|
reader::tagged_docs(item, tag_item_field).map(|an_item| {
|
|
|
|
item_name(intr, an_item)
|
|
|
|
}).chain(reader::tagged_docs(item, tag_item_unnamed_field).map(|_| {
|
|
|
|
special_idents::unnamed_field.name
|
2015-05-24 12:23:29 +02:00
|
|
|
})).collect()
|
2012-03-06 17:02:13 +01:00
|
|
|
}
|
|
|
|
|
2014-09-07 19:09:06 +02:00
|
|
|
fn get_meta_items(md: rbml::Doc) -> Vec<P<ast::MetaItem>> {
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(md, tag_meta_item_word).map(|meta_item_doc| {
|
2012-12-07 01:13:54 +01:00
|
|
|
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
|
2014-01-08 19:35:15 +01:00
|
|
|
let n = token::intern_and_get_ident(nd.as_str_slice());
|
2015-05-24 12:23:29 +02:00
|
|
|
attr::mk_word_item(n)
|
|
|
|
}).chain(reader::tagged_docs(md, tag_meta_item_name_value).map(|meta_item_doc| {
|
2012-12-07 01:13:54 +01:00
|
|
|
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
|
|
|
|
let vd = reader::get_doc(meta_item_doc, tag_meta_item_value);
|
2014-01-08 19:35:15 +01:00
|
|
|
let n = token::intern_and_get_ident(nd.as_str_slice());
|
2014-01-10 23:02:36 +01:00
|
|
|
let v = token::intern_and_get_ident(vd.as_str_slice());
|
2013-07-19 13:51:37 +02:00
|
|
|
// FIXME (#623): Should be able to decode MetaNameValue variants,
|
2012-05-18 01:17:11 +02:00
|
|
|
// but currently the encoder just drops them
|
2015-05-24 12:23:29 +02:00
|
|
|
attr::mk_name_value_item_str(n, v)
|
|
|
|
})).chain(reader::tagged_docs(md, tag_meta_item_list).map(|meta_item_doc| {
|
2012-12-07 01:13:54 +01:00
|
|
|
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
|
2014-01-08 19:35:15 +01:00
|
|
|
let n = token::intern_and_get_ident(nd.as_str_slice());
|
2011-07-27 14:19:39 +02:00
|
|
|
let subitems = get_meta_items(meta_item_doc);
|
2015-05-24 12:23:29 +02:00
|
|
|
attr::mk_list_item(n, subitems)
|
|
|
|
})).collect()
|
2011-06-28 03:32:15 +02:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
|
2012-12-07 01:13:54 +01:00
|
|
|
match reader::maybe_get_doc(md, tag_attributes) {
|
2015-05-24 12:23:29 +02:00
|
|
|
Some(attrs_d) => {
|
|
|
|
reader::tagged_docs(attrs_d, tag_attribute).map(|attr_doc| {
|
|
|
|
let is_sugared_doc = reader::doc_as_u8(
|
|
|
|
reader::get_doc(attr_doc, tag_attribute_is_sugared_doc)
|
|
|
|
) == 1;
|
|
|
|
let meta_items = get_meta_items(attr_doc);
|
|
|
|
// Currently it's only possible to have a single meta item on
|
|
|
|
// an attribute
|
|
|
|
assert_eq!(meta_items.len(), 1);
|
|
|
|
let meta_item = meta_items.into_iter().nth(0).unwrap();
|
2013-08-31 18:13:04 +02:00
|
|
|
codemap::Spanned {
|
2013-07-19 13:51:37 +02:00
|
|
|
node: ast::Attribute_ {
|
2014-05-20 09:07:24 +02:00
|
|
|
id: attr::mk_attr_id(),
|
2013-07-19 13:51:37 +02:00
|
|
|
style: ast::AttrOuter,
|
2013-02-25 15:19:44 +01:00
|
|
|
value: meta_item,
|
2014-07-28 10:02:31 +02:00
|
|
|
is_sugared_doc: is_sugared_doc,
|
2013-01-14 01:51:48 +01:00
|
|
|
},
|
2014-01-01 07:53:22 +01:00
|
|
|
span: codemap::DUMMY_SP
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
|
|
|
}).collect()
|
|
|
|
},
|
|
|
|
None => vec![],
|
2011-06-28 04:41:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn list_crate_attributes(md: rbml::Doc, hash: &Svh,
|
2015-02-27 06:00:43 +01:00
|
|
|
out: &mut io::Write) -> io::Result<()> {
|
2014-02-25 04:45:20 +01:00
|
|
|
try!(write!(out, "=Crate Attributes ({})=\n", *hash));
|
2011-06-28 04:41:48 +02:00
|
|
|
|
2013-06-21 14:29:53 +02:00
|
|
|
let r = get_attributes(md);
|
2015-01-31 18:20:46 +01:00
|
|
|
for attr in &r {
|
2014-06-21 12:39:03 +02:00
|
|
|
try!(write!(out, "{}\n", pprust::attribute_to_string(attr)));
|
2011-06-28 04:41:48 +02:00
|
|
|
}
|
|
|
|
|
2014-01-30 03:42:19 +01:00
|
|
|
write!(out, "\n\n")
|
2011-06-28 03:32:15 +02:00
|
|
|
}
|
|
|
|
|
2014-03-04 19:02:49 +01:00
|
|
|
pub fn get_crate_attributes(data: &[u8]) -> Vec<ast::Attribute> {
|
2014-07-30 02:06:37 +02:00
|
|
|
get_attributes(rbml::Doc::new(data))
|
2011-06-28 20:24:24 +02:00
|
|
|
}
|
|
|
|
|
2015-01-04 04:54:18 +01:00
|
|
|
#[derive(Clone)]
|
2013-08-31 18:13:04 +02:00
|
|
|
pub struct CrateDep {
|
2014-03-28 18:05:27 +01:00
|
|
|
pub cnum: ast::CrateNum,
|
2014-06-06 22:21:18 +02:00
|
|
|
pub name: String,
|
2014-03-28 18:05:27 +01:00
|
|
|
pub hash: Svh,
|
2015-06-25 19:07:01 +02:00
|
|
|
pub explicitly_linked: bool,
|
2013-02-19 08:40:42 +01:00
|
|
|
}
|
2011-07-27 14:19:39 +02:00
|
|
|
|
2014-03-04 19:02:49 +01:00
|
|
|
pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
|
2014-07-30 02:06:37 +02:00
|
|
|
let cratedoc = rbml::Doc::new(data);
|
2012-12-07 01:13:54 +01:00
|
|
|
let depsdoc = reader::get_doc(cratedoc, tag_crate_deps);
|
2015-05-24 12:23:29 +02:00
|
|
|
|
2015-03-26 01:06:52 +01:00
|
|
|
fn docstr(doc: rbml::Doc, tag_: usize) -> String {
|
2013-06-12 19:02:55 +02:00
|
|
|
let d = reader::get_doc(doc, tag_);
|
2014-05-25 12:17:19 +02:00
|
|
|
d.as_str_slice().to_string()
|
2012-04-07 19:59:37 +02:00
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
|
|
|
|
reader::tagged_docs(depsdoc, tag_crate_dep).enumerate().map(|(crate_num, depdoc)| {
|
2014-06-06 22:21:18 +02:00
|
|
|
let name = docstr(depdoc, tag_crate_dep_crate_name);
|
2015-02-20 20:08:14 +01:00
|
|
|
let hash = Svh::new(&docstr(depdoc, tag_crate_dep_hash));
|
2015-06-25 19:07:01 +02:00
|
|
|
let doc = reader::get_doc(depdoc, tag_crate_dep_explicitly_linked);
|
|
|
|
let explicitly_linked = reader::doc_as_u8(doc) != 0;
|
2015-05-24 12:23:29 +02:00
|
|
|
CrateDep {
|
|
|
|
cnum: crate_num as u32 + 1,
|
2014-06-06 22:21:18 +02:00
|
|
|
name: name,
|
2014-02-25 03:13:51 +01:00
|
|
|
hash: hash,
|
2015-06-25 19:07:01 +02:00
|
|
|
explicitly_linked: explicitly_linked,
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
|
|
|
}).collect()
|
2011-07-08 20:29:56 +02:00
|
|
|
}
|
|
|
|
|
2015-02-27 06:00:43 +01:00
|
|
|
fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> {
|
2014-02-19 19:07:49 +01:00
|
|
|
try!(write!(out, "=External Dependencies=\n"));
|
2015-01-31 18:20:46 +01:00
|
|
|
for dep in &get_crate_deps(data) {
|
2014-06-06 22:21:18 +02:00
|
|
|
try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash));
|
2011-07-08 20:29:56 +02:00
|
|
|
}
|
2014-02-19 19:07:49 +01:00
|
|
|
try!(write!(out, "\n"));
|
2014-01-30 03:42:19 +01:00
|
|
|
Ok(())
|
2011-07-08 20:29:56 +02:00
|
|
|
}
|
|
|
|
|
2014-03-01 20:09:30 +01:00
|
|
|
pub fn maybe_get_crate_hash(data: &[u8]) -> Option<Svh> {
|
2014-07-30 02:06:37 +02:00
|
|
|
let cratedoc = rbml::Doc::new(data);
|
2014-03-01 20:09:30 +01:00
|
|
|
reader::maybe_get_doc(cratedoc, tag_crate_hash).map(|doc| {
|
|
|
|
Svh::new(doc.as_str_slice())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2014-02-25 04:45:20 +01:00
|
|
|
pub fn get_crate_hash(data: &[u8]) -> Svh {
|
2014-07-30 02:06:37 +02:00
|
|
|
let cratedoc = rbml::Doc::new(data);
|
2012-12-07 01:13:54 +01:00
|
|
|
let hashdoc = reader::get_doc(cratedoc, tag_crate_hash);
|
2014-02-25 04:45:20 +01:00
|
|
|
Svh::new(hashdoc.as_str_slice())
|
2011-12-11 16:23:38 +01:00
|
|
|
}
|
|
|
|
|
2014-06-06 22:21:18 +02:00
|
|
|
pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
|
2014-07-30 02:06:37 +02:00
|
|
|
let cratedoc = rbml::Doc::new(data);
|
2014-06-06 22:21:18 +02:00
|
|
|
reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| {
|
|
|
|
doc.as_str_slice().to_string()
|
2014-03-01 20:09:30 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2014-06-06 22:21:18 +02:00
|
|
|
pub fn get_crate_triple(data: &[u8]) -> Option<String> {
|
2014-07-30 02:06:37 +02:00
|
|
|
let cratedoc = rbml::Doc::new(data);
|
2014-04-17 17:52:25 +02:00
|
|
|
let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);
|
2014-06-06 22:21:18 +02:00
|
|
|
triple_doc.map(|s| s.as_str().to_string())
|
2014-04-17 17:52:25 +02:00
|
|
|
}
|
|
|
|
|
2014-06-06 22:21:18 +02:00
|
|
|
pub fn get_crate_name(data: &[u8]) -> String {
|
|
|
|
maybe_get_crate_name(data).expect("no crate name in crate")
|
2012-04-07 19:59:37 +02:00
|
|
|
}
|
|
|
|
|
2015-02-27 06:00:43 +01:00
|
|
|
pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> {
|
2011-12-11 16:23:38 +01:00
|
|
|
let hash = get_crate_hash(bytes);
|
2014-07-30 02:06:37 +02:00
|
|
|
let md = rbml::Doc::new(bytes);
|
2014-02-25 04:45:20 +01:00
|
|
|
try!(list_crate_attributes(md, &hash, out));
|
2014-01-30 03:42:19 +01:00
|
|
|
list_crate_deps(bytes, out)
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2012-01-05 16:04:59 +01:00
|
|
|
// Translates a def_id from an external crate to a def_id for the current
|
|
|
|
// compilation environment. We use this when trying to load types from
|
|
|
|
// external crates - if those types further refer to types in other crates
|
|
|
|
// then we must translate the crate number from that encoded in the external
|
|
|
|
// crate to the correct local crate number.
|
2015-08-16 12:32:28 +02:00
|
|
|
pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId {
|
|
|
|
if did.krate == LOCAL_CRATE {
|
|
|
|
return DefId { krate: cdata.cnum, node: did.node };
|
2012-01-05 16:04:59 +01:00
|
|
|
}
|
|
|
|
|
2015-06-25 19:07:01 +02:00
|
|
|
match cdata.cnum_map.borrow().get(&did.krate) {
|
2013-12-22 03:17:29 +01:00
|
|
|
Some(&n) => {
|
2015-08-16 12:32:28 +02:00
|
|
|
DefId {
|
2014-02-05 22:15:24 +01:00
|
|
|
krate: n,
|
2013-12-22 03:17:29 +01:00
|
|
|
node: did.node,
|
|
|
|
}
|
|
|
|
}
|
2014-10-09 21:17:22 +02:00
|
|
|
None => panic!("didn't find a crate in the cnum_map")
|
2012-01-05 16:04:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-12 06:56:37 +02:00
|
|
|
// Translate a DefId from the current compilation environment to a DefId
|
|
|
|
// for an external crate.
|
2015-08-16 12:32:28 +02:00
|
|
|
fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> {
|
2015-05-12 06:56:37 +02:00
|
|
|
if did.krate == cdata.cnum {
|
2015-08-16 12:32:28 +02:00
|
|
|
return Some(DefId { krate: LOCAL_CRATE, node: did.node });
|
2015-05-12 06:56:37 +02:00
|
|
|
}
|
|
|
|
|
2015-06-25 19:07:01 +02:00
|
|
|
for (&local, &global) in cdata.cnum_map.borrow().iter() {
|
2015-05-12 06:56:37 +02:00
|
|
|
if global == did.krate {
|
2015-08-16 12:32:28 +02:00
|
|
|
return Some(DefId { krate: local, node: did.node });
|
2015-05-12 06:56:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
2015-05-12 06:51:15 +02:00
|
|
|
pub fn each_inherent_implementation_for_type<F>(cdata: Cmd,
|
|
|
|
id: ast::NodeId,
|
|
|
|
mut callback: F)
|
2015-08-16 12:32:28 +02:00
|
|
|
where F: FnMut(DefId),
|
2014-12-09 02:26:43 +01:00
|
|
|
{
|
2013-12-18 23:10:28 +01:00
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2015-05-24 12:23:29 +02:00
|
|
|
for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_inherent_impl) {
|
2015-05-12 06:51:15 +02:00
|
|
|
if reader::maybe_get_doc(impl_doc, tag_item_trait_ref).is_none() {
|
|
|
|
callback(item_def_id(impl_doc, cdata));
|
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
2013-08-23 23:34:00 +02:00
|
|
|
}
|
|
|
|
|
2014-12-09 02:26:43 +01:00
|
|
|
pub fn each_implementation_for_trait<F>(cdata: Cmd,
|
2015-08-16 12:32:28 +02:00
|
|
|
def_id: DefId,
|
2014-12-09 02:26:43 +01:00
|
|
|
mut callback: F) where
|
2015-08-16 12:32:28 +02:00
|
|
|
F: FnMut(DefId),
|
2014-12-09 02:26:43 +01:00
|
|
|
{
|
2015-05-12 06:56:37 +02:00
|
|
|
if cdata.cnum == def_id.krate {
|
|
|
|
let item_doc = lookup_item(def_id.node, cdata.data());
|
2015-05-24 12:23:29 +02:00
|
|
|
for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_extension_impl) {
|
2015-05-12 06:56:37 +02:00
|
|
|
callback(item_def_id(impl_doc, cdata));
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
2015-05-12 06:56:37 +02:00
|
|
|
return;
|
|
|
|
}
|
2013-08-23 23:34:00 +02:00
|
|
|
|
2015-05-12 06:56:37 +02:00
|
|
|
// Do a reverse lookup beforehand to avoid touching the crate_num
|
|
|
|
// hash map in the loop below.
|
|
|
|
if let Some(crate_local_did) = reverse_translate_def_id(cdata, def_id) {
|
|
|
|
let def_id_u64 = def_to_u64(crate_local_did);
|
|
|
|
|
|
|
|
let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls);
|
2015-05-24 12:23:29 +02:00
|
|
|
for impl_doc in reader::tagged_docs(impls_doc, tag_impls_impl) {
|
2015-05-12 06:56:37 +02:00
|
|
|
let impl_trait = reader::get_doc(impl_doc, tag_impls_impl_trait_def_id);
|
|
|
|
if reader::doc_as_u64(impl_trait) == def_id_u64 {
|
|
|
|
callback(item_def_id(impl_doc, cdata));
|
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
2015-05-12 06:56:37 +02:00
|
|
|
}
|
2013-08-23 23:34:00 +02:00
|
|
|
}
|
|
|
|
|
2014-08-04 22:56:56 +02:00
|
|
|
pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
|
2015-08-16 12:32:28 +02:00
|
|
|
-> Option<DefId> {
|
2013-12-18 23:10:28 +01:00
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2015-05-12 06:49:15 +02:00
|
|
|
let parent_item_id = match item_parent_item(cdata, item_doc) {
|
2013-08-23 23:34:00 +02:00
|
|
|
None => return None,
|
|
|
|
Some(item_id) => item_id,
|
|
|
|
};
|
2013-12-18 23:10:28 +01:00
|
|
|
let parent_item_doc = lookup_item(parent_item_id.node, cdata.data());
|
2013-08-23 23:34:00 +02:00
|
|
|
match item_family(parent_item_doc) {
|
|
|
|
Trait => Some(item_def_id(parent_item_doc, cdata)),
|
2015-02-07 14:24:34 +01:00
|
|
|
Impl | DefaultImpl => {
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::maybe_get_doc(parent_item_doc, tag_item_trait_ref)
|
|
|
|
.map(|_| item_trait_ref(parent_item_doc, tcx, cdata).def_id)
|
2013-08-23 23:34:00 +02:00
|
|
|
}
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
2013-08-20 23:55:54 +02:00
|
|
|
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 23:03:29 +01:00
|
|
|
|
2014-05-10 03:45:36 +02:00
|
|
|
pub fn get_native_libraries(cdata: Cmd)
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-06 02:01:33 +01:00
|
|
|
-> Vec<(cstore::NativeLibraryKind, String)> {
|
2014-07-30 02:06:37 +02:00
|
|
|
let libraries = reader::get_doc(rbml::Doc::new(cdata.data()),
|
2013-12-18 23:10:28 +01:00
|
|
|
tag_native_libraries);
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(libraries, tag_native_libraries_lib).map(|lib_doc| {
|
2013-11-30 20:39:55 +01:00
|
|
|
let kind_doc = reader::get_doc(lib_doc, tag_native_libraries_kind);
|
|
|
|
let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name);
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-06 02:01:33 +01:00
|
|
|
let kind: cstore::NativeLibraryKind =
|
2015-04-18 00:32:42 +02:00
|
|
|
cstore::NativeLibraryKind::from_u32(reader::doc_as_u32(kind_doc)).unwrap();
|
2014-05-25 12:17:19 +02:00
|
|
|
let name = name_doc.as_str().to_string();
|
2015-05-24 12:23:29 +02:00
|
|
|
(kind, name)
|
|
|
|
}).collect()
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 23:03:29 +01:00
|
|
|
}
|
2013-12-25 19:10:33 +01:00
|
|
|
|
2014-05-25 01:16:10 +02:00
|
|
|
pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
|
2014-07-30 02:06:37 +02:00
|
|
|
reader::maybe_get_doc(rbml::Doc::new(data), tag_plugin_registrar_fn)
|
2015-04-18 00:32:42 +02:00
|
|
|
.map(|doc| reader::doc_as_u32(doc))
|
2013-12-25 19:10:33 +01:00
|
|
|
}
|
|
|
|
|
2014-12-31 04:10:46 +01:00
|
|
|
pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner, mut f: F) where
|
|
|
|
F: FnMut(ast::Name, Vec<ast::Attribute>, String) -> bool,
|
|
|
|
{
|
|
|
|
let macros = reader::get_doc(rbml::Doc::new(data), tag_macro_defs);
|
2015-05-24 12:23:29 +02:00
|
|
|
for macro_doc in reader::tagged_docs(macros, tag_macro_def) {
|
2014-12-31 04:10:46 +01:00
|
|
|
let name = item_name(intr, macro_doc);
|
|
|
|
let attrs = get_attributes(macro_doc);
|
|
|
|
let body = reader::get_doc(macro_doc, tag_macro_def_body);
|
2015-05-24 12:23:29 +02:00
|
|
|
if !f(name, attrs, body.as_str().to_string()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-12-25 19:10:33 +01:00
|
|
|
}
|
2014-05-02 09:59:27 +02:00
|
|
|
|
|
|
|
pub fn get_dylib_dependency_formats(cdata: Cmd)
|
|
|
|
-> Vec<(ast::CrateNum, cstore::LinkagePreference)>
|
|
|
|
{
|
2014-07-30 02:06:37 +02:00
|
|
|
let formats = reader::get_doc(rbml::Doc::new(cdata.data()),
|
2014-05-02 09:59:27 +02:00
|
|
|
tag_dylib_dependency_formats);
|
|
|
|
let mut result = Vec::new();
|
|
|
|
|
|
|
|
debug!("found dylib deps: {}", formats.as_str_slice());
|
|
|
|
for spec in formats.as_str_slice().split(',') {
|
2015-03-25 00:53:34 +01:00
|
|
|
if spec.is_empty() { continue }
|
2014-05-02 09:59:27 +02:00
|
|
|
let cnum = spec.split(':').nth(0).unwrap();
|
|
|
|
let link = spec.split(':').nth(1).unwrap();
|
2014-12-29 17:22:16 +01:00
|
|
|
let cnum: ast::CrateNum = cnum.parse().unwrap();
|
2015-06-25 19:07:01 +02:00
|
|
|
let cnum = match cdata.cnum_map.borrow().get(&cnum) {
|
2014-05-02 09:59:27 +02:00
|
|
|
Some(&n) => n,
|
2014-10-09 21:17:22 +02:00
|
|
|
None => panic!("didn't find a crate in the cnum_map")
|
2014-05-02 09:59:27 +02:00
|
|
|
};
|
|
|
|
result.push((cnum, if link == "d" {
|
|
|
|
cstore::RequireDynamic
|
|
|
|
} else {
|
|
|
|
cstore::RequireStatic
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2014-05-19 18:30:09 +02:00
|
|
|
|
|
|
|
pub fn get_missing_lang_items(cdata: Cmd)
|
|
|
|
-> Vec<lang_items::LangItem>
|
|
|
|
{
|
2014-07-30 02:06:37 +02:00
|
|
|
let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_lang_items);
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(items, tag_lang_items_missing).map(|missing_docs| {
|
|
|
|
lang_items::LangItem::from_u32(reader::doc_as_u32(missing_docs)).unwrap()
|
|
|
|
}).collect()
|
2014-05-19 18:30:09 +02:00
|
|
|
}
|
2014-05-24 02:13:44 +02:00
|
|
|
|
2014-05-24 20:56:38 +02:00
|
|
|
pub fn get_method_arg_names(cdata: Cmd, id: ast::NodeId) -> Vec<String> {
|
2014-05-24 02:13:44 +02:00
|
|
|
let method_doc = lookup_item(id, cdata.data());
|
|
|
|
match reader::maybe_get_doc(method_doc, tag_method_argument_names) {
|
|
|
|
Some(args_doc) => {
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(args_doc, tag_method_argument_name).map(|name_doc| {
|
|
|
|
name_doc.as_str_slice().to_string()
|
|
|
|
}).collect()
|
|
|
|
},
|
|
|
|
None => vec![],
|
2014-05-24 02:13:44 +02:00
|
|
|
}
|
|
|
|
}
|
2014-06-07 02:48:46 +02:00
|
|
|
|
2015-08-16 12:32:28 +02:00
|
|
|
pub fn get_reachable_ids(cdata: Cmd) -> Vec<DefId> {
|
2014-07-30 02:06:37 +02:00
|
|
|
let items = reader::get_doc(rbml::Doc::new(cdata.data()),
|
2015-07-29 02:19:08 +02:00
|
|
|
tag_reachable_ids);
|
|
|
|
reader::tagged_docs(items, tag_reachable_id).map(|doc| {
|
2015-08-16 12:32:28 +02:00
|
|
|
DefId {
|
2014-06-07 02:48:46 +02:00
|
|
|
krate: cdata.cnum,
|
|
|
|
node: reader::doc_as_u32(doc),
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
|
|
|
}).collect()
|
2014-06-07 02:48:46 +02:00
|
|
|
}
|
2014-06-09 21:56:37 +02:00
|
|
|
|
|
|
|
pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
|
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
|
|
|
match item_family(item_doc) {
|
|
|
|
Type => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
2014-08-28 03:46:52 +02:00
|
|
|
|
2015-02-25 21:06:08 +01:00
|
|
|
pub fn is_const_fn(cdata: Cmd, id: ast::NodeId) -> bool {
|
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
|
|
|
match fn_constness(item_doc) {
|
|
|
|
ast::Constness::Const => true,
|
|
|
|
ast::Constness::NotConst => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-25 23:41:27 +02:00
|
|
|
pub fn is_impl(cdata: Cmd, id: ast::NodeId) -> bool {
|
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
|
|
|
match item_family(item_doc) {
|
|
|
|
Impl => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-29 21:11:30 +02:00
|
|
|
fn doc_generics<'tcx>(base_doc: rbml::Doc,
|
|
|
|
tcx: &ty::ctxt<'tcx>,
|
|
|
|
cdata: Cmd,
|
2015-03-26 01:06:52 +01:00
|
|
|
tag: usize)
|
2014-09-29 21:11:30 +02:00
|
|
|
-> ty::Generics<'tcx>
|
2014-08-28 03:46:52 +02:00
|
|
|
{
|
|
|
|
let doc = reader::get_doc(base_doc, tag);
|
|
|
|
|
|
|
|
let mut types = subst::VecPerParamSpace::empty();
|
2015-05-24 12:23:29 +02:00
|
|
|
for p in reader::tagged_docs(doc, tag_type_param_def) {
|
2015-08-16 03:35:49 +02:00
|
|
|
let bd =
|
|
|
|
TyDecoder::with_doc(tcx, cdata.cnum, p,
|
|
|
|
&mut |_, did| translate_def_id(cdata, did))
|
|
|
|
.parse_type_param_def();
|
2014-08-28 03:46:52 +02:00
|
|
|
types.push(bd.space, bd);
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
2014-08-28 03:46:52 +02:00
|
|
|
|
|
|
|
let mut regions = subst::VecPerParamSpace::empty();
|
2015-05-24 12:23:29 +02:00
|
|
|
for rp_doc in reader::tagged_docs(doc, tag_region_param_def) {
|
2014-08-28 03:46:52 +02:00
|
|
|
let ident_str_doc = reader::get_doc(rp_doc,
|
|
|
|
tag_region_param_def_ident);
|
2014-10-01 02:11:34 +02:00
|
|
|
let name = item_name(&*token::get_ident_interner(), ident_str_doc);
|
2014-08-28 03:46:52 +02:00
|
|
|
let def_id_doc = reader::get_doc(rp_doc,
|
|
|
|
tag_region_param_def_def_id);
|
2015-05-12 06:49:15 +02:00
|
|
|
let def_id = translated_def_id(cdata, def_id_doc);
|
2014-08-28 03:46:52 +02:00
|
|
|
|
|
|
|
let doc = reader::get_doc(rp_doc, tag_region_param_def_space);
|
2015-03-26 01:06:52 +01:00
|
|
|
let space = subst::ParamSpace::from_uint(reader::doc_as_u64(doc) as usize);
|
2014-08-28 03:46:52 +02:00
|
|
|
|
|
|
|
let doc = reader::get_doc(rp_doc, tag_region_param_def_index);
|
2014-12-04 21:06:42 +01:00
|
|
|
let index = reader::doc_as_u64(doc) as u32;
|
2014-08-28 03:46:52 +02:00
|
|
|
|
2015-05-24 12:23:29 +02:00
|
|
|
let bounds = reader::tagged_docs(rp_doc, tag_items_data_region).map(|p| {
|
2015-08-16 03:35:49 +02:00
|
|
|
TyDecoder::with_doc(tcx, cdata.cnum, p,
|
|
|
|
&mut |_, did| translate_def_id(cdata, did))
|
|
|
|
.parse_region()
|
2015-05-24 12:23:29 +02:00
|
|
|
}).collect();
|
2014-08-28 03:46:52 +02:00
|
|
|
|
2014-10-01 02:11:34 +02:00
|
|
|
regions.push(space, ty::RegionParameterDef { name: name,
|
2014-08-28 03:46:52 +02:00
|
|
|
def_id: def_id,
|
|
|
|
space: space,
|
|
|
|
index: index,
|
|
|
|
bounds: bounds });
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
2014-08-28 03:46:52 +02:00
|
|
|
|
2015-02-11 11:59:01 +01:00
|
|
|
ty::Generics { types: types, regions: regions }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn doc_predicates<'tcx>(base_doc: rbml::Doc,
|
|
|
|
tcx: &ty::ctxt<'tcx>,
|
|
|
|
cdata: Cmd,
|
2015-03-26 01:06:52 +01:00
|
|
|
tag: usize)
|
2015-02-11 11:59:01 +01:00
|
|
|
-> ty::GenericPredicates<'tcx>
|
|
|
|
{
|
|
|
|
let doc = reader::get_doc(base_doc, tag);
|
|
|
|
|
2014-12-07 17:10:48 +01:00
|
|
|
let mut predicates = subst::VecPerParamSpace::empty();
|
2015-05-24 12:23:29 +02:00
|
|
|
for predicate_doc in reader::tagged_docs(doc, tag_predicate) {
|
2014-12-07 17:10:48 +01:00
|
|
|
let space_doc = reader::get_doc(predicate_doc, tag_predicate_space);
|
2015-03-26 01:06:52 +01:00
|
|
|
let space = subst::ParamSpace::from_uint(reader::doc_as_u8(space_doc) as usize);
|
2014-12-07 17:10:48 +01:00
|
|
|
|
|
|
|
let data_doc = reader::get_doc(predicate_doc, tag_predicate_data);
|
2015-08-16 03:35:49 +02:00
|
|
|
let data =
|
|
|
|
TyDecoder::with_doc(tcx, cdata.cnum, data_doc,
|
|
|
|
&mut |_, did| translate_def_id(cdata, did))
|
|
|
|
.parse_predicate();
|
2014-12-07 17:10:48 +01:00
|
|
|
|
|
|
|
predicates.push(space, data);
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
2014-12-05 17:04:49 +01:00
|
|
|
|
2015-02-11 11:59:01 +01:00
|
|
|
ty::GenericPredicates { predicates: predicates }
|
2014-08-28 03:46:52 +02:00
|
|
|
}
|
2014-08-06 04:44:21 +02:00
|
|
|
|
2015-03-13 03:15:52 +01:00
|
|
|
pub fn is_defaulted_trait(cdata: Cmd, trait_id: ast::NodeId) -> bool {
|
2015-03-04 21:19:27 +01:00
|
|
|
let trait_doc = lookup_item(trait_id, cdata.data());
|
|
|
|
assert!(item_family(trait_doc) == Family::Trait);
|
|
|
|
let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait);
|
|
|
|
reader::doc_as_u8(defaulted_doc) != 0
|
2015-01-24 14:17:24 +01:00
|
|
|
}
|
2015-02-11 18:29:49 +01:00
|
|
|
|
2015-03-13 03:15:52 +01:00
|
|
|
pub fn is_default_impl(cdata: Cmd, impl_id: ast::NodeId) -> bool {
|
|
|
|
let impl_doc = lookup_item(impl_id, cdata.data());
|
|
|
|
item_family(impl_doc) == Family::DefaultImpl
|
|
|
|
}
|
|
|
|
|
2015-02-11 18:29:49 +01:00
|
|
|
pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
|
|
|
|
let crate_doc = rbml::Doc::new(metadata);
|
|
|
|
let cm_doc = reader::get_doc(crate_doc, tag_codemap);
|
|
|
|
|
2015-05-24 12:23:29 +02:00
|
|
|
reader::tagged_docs(cm_doc, tag_codemap_filemap).map(|filemap_doc| {
|
2015-02-11 18:29:49 +01:00
|
|
|
let mut decoder = reader::Decoder::new(filemap_doc);
|
2015-05-24 12:23:29 +02:00
|
|
|
Decodable::decode(&mut decoder).unwrap()
|
|
|
|
}).collect()
|
2015-02-11 18:29:49 +01:00
|
|
|
}
|
2015-07-29 02:19:08 +02:00
|
|
|
|
|
|
|
pub fn is_extern_fn(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) -> bool {
|
|
|
|
let root_doc = rbml::Doc::new(cdata.data());
|
|
|
|
let items = reader::get_doc(root_doc, tag_items);
|
|
|
|
let item_doc = match maybe_find_item(id, items) {
|
|
|
|
Some(doc) => doc,
|
|
|
|
None => return false,
|
|
|
|
};
|
|
|
|
if let Fn = item_family(item_doc) {
|
|
|
|
let ty::TypeScheme { generics, ty } = get_type(cdata, id, tcx);
|
|
|
|
generics.types.is_empty() && match ty.sty {
|
|
|
|
ty::TyBareFn(_, fn_ty) => fn_ty.abi != abi::Rust,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|