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-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;
|
2014-08-28 03:46:52 +02:00
|
|
|
use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
|
|
|
|
parse_type_param_def_data, parse_bounds_data,
|
|
|
|
parse_bare_fn_ty_data, parse_trait_ref_data};
|
2014-05-14 21:31:30 +02:00
|
|
|
use middle::def;
|
2014-08-04 22:56:56 +02:00
|
|
|
use middle::lang_items;
|
2014-08-06 04:44:21 +02:00
|
|
|
use middle::resolve::{TraitItemKind, TypeTraitItemKind};
|
2014-06-01 00:53:13 +02:00
|
|
|
use middle::subst;
|
2013-08-23 23:34:00 +02:00
|
|
|
use middle::ty::{ImplContainer, TraitContainer};
|
2013-07-16 00:24:16 +02:00
|
|
|
use middle::ty;
|
2013-07-23 01:40:31 +02:00
|
|
|
use middle::typeck;
|
|
|
|
use middle::astencode::vtable_decoder_helpers;
|
|
|
|
|
2014-02-23 11:29:35 +01:00
|
|
|
use std::hash::Hash;
|
2014-05-16 19:15:33 +02:00
|
|
|
use std::hash;
|
2013-11-11 07:46:32 +01:00
|
|
|
use std::io::extensions::u64_from_be_bytes;
|
2014-05-16 19:15:33 +02:00
|
|
|
use std::io;
|
2014-07-26 22:21:36 +02:00
|
|
|
use std::collections::hashmap::HashMap;
|
2014-02-01 05:57:59 +01:00
|
|
|
use std::rc::Rc;
|
2014-05-16 19:15:33 +02:00
|
|
|
use std::u64;
|
2014-07-30 02:06:37 +02:00
|
|
|
use rbml::reader;
|
|
|
|
use rbml;
|
2014-02-05 17:52:54 +01:00
|
|
|
use serialize::Decodable;
|
2012-09-04 20:54:36 +02:00
|
|
|
use syntax::ast_map;
|
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
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn lookup_hash<'a>(d: rbml::Doc<'a>, eq_fn: |&[u8]| -> bool,
|
|
|
|
hash: u64) -> Option<rbml::Doc<'a>> {
|
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);
|
2013-08-07 04:35:09 +02:00
|
|
|
let hash_pos = table.start + (hash % 256 * 4) as uint;
|
2013-12-18 23:10:28 +01:00
|
|
|
let pos = u64_from_be_bytes(d.data, hash_pos, 4) as uint;
|
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
|
|
|
|
2011-07-27 14:19:39 +02:00
|
|
|
let belt = tag_index_buckets_bucket_elt;
|
2013-08-02 08:17:20 +02:00
|
|
|
|
|
|
|
let mut ret = None;
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::tagged_docs(tagged_doc.doc, belt, |elt| {
|
2013-12-18 23:10:28 +01:00
|
|
|
let pos = u64_from_be_bytes(elt.data, elt.start, 4) as uint;
|
2014-09-24 13:41:09 +02:00
|
|
|
if eq_fn(elt.data[elt.start + 4 .. elt.end]) {
|
2014-03-29 01:05:46 +01:00
|
|
|
ret = Some(reader::doc_at(d.data, pos).unwrap().doc);
|
2013-08-02 08:17:20 +02:00
|
|
|
false
|
|
|
|
} else {
|
|
|
|
true
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2013-08-02 08:17:20 +02:00
|
|
|
ret
|
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 {
|
2013-10-22 08:06:12 +02:00
|
|
|
return u64_from_be_bytes(
|
2014-09-24 13:41:09 +02:00
|
|
|
bytes[0u..4u], 0u, 4u) as ast::NodeId
|
2012-07-04 01:37:38 +02:00
|
|
|
== item_id;
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
2012-07-26 22:43:27 +02:00
|
|
|
lookup_hash(items,
|
|
|
|
|a| eq_item(a, item_id),
|
2014-02-23 11:29:35 +01:00
|
|
|
hash::hash(&(item_id as i64)))
|
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
|
|
|
}
|
|
|
|
|
2014-05-30 02:45:07 +02:00
|
|
|
#[deriving(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
|
|
|
|
ForeignType, // T
|
|
|
|
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
|
|
|
|
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,
|
|
|
|
'T' => ForeignType,
|
|
|
|
'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,
|
|
|
|
'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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-04 22:56:56 +02:00
|
|
|
fn item_sort(item: rbml::Doc) -> char {
|
2014-08-06 04:44:21 +02:00
|
|
|
// NB(pcwalton): The default of 'r' here is relied upon in
|
|
|
|
// `is_associated_type` below.
|
2013-08-02 08:17:20 +02:00
|
|
|
let mut ret = 'r';
|
2014-08-04 22:56:56 +02:00
|
|
|
reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
|
2014-06-20 03:22:33 +02:00
|
|
|
ret = doc.as_str_slice().as_bytes()[0] as char;
|
2013-08-02 08:17:20 +02:00
|
|
|
false
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2013-08-02 08:17:20 +02:00
|
|
|
ret
|
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
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn item_parent_item(d: rbml::Doc) -> Option<ast::DefId> {
|
2013-08-02 08:17:20 +02:00
|
|
|
let mut ret = None;
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::tagged_docs(d, tag_items_data_parent_item, |did| {
|
2013-08-02 08:17:20 +02:00
|
|
|
ret = Some(reader::with_doc_data(did, parse_def_id));
|
|
|
|
false
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2013-08-02 08:17:20 +02:00
|
|
|
ret
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2013-07-19 07:38:55 +02:00
|
|
|
fn item_reqd_and_translated_parent_item(cnum: ast::CrateNum,
|
2014-07-30 02:06:37 +02:00
|
|
|
d: rbml::Doc) -> ast::DefId {
|
2013-05-19 07:07:44 +02:00
|
|
|
let trait_did = item_parent_item(d).expect("item without parent");
|
2014-02-05 22:15:24 +01:00
|
|
|
ast::DefId { krate: cnum, node: trait_did.node }
|
2012-10-13 02:00:08 +02:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn item_def_id(d: rbml::Doc, cdata: Cmd) -> ast::DefId {
|
2012-12-07 01:13:54 +01:00
|
|
|
let tagdoc = reader::get_doc(d, tag_def_id);
|
2013-06-08 02:32:25 +02:00
|
|
|
return translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id));
|
2012-03-06 17:02:13 +01:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn get_provided_source(d: rbml::Doc, cdata: Cmd) -> Option<ast::DefId> {
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::maybe_get_doc(d, tag_item_method_provided_source).map(|doc| {
|
2013-08-04 23:59:36 +02:00
|
|
|
translate_def_id(cdata, reader::with_doc_data(doc, parse_def_id))
|
2013-11-22 00:42:55 +01:00
|
|
|
})
|
2013-07-12 02:07:57 +02:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn each_reexport(d: rbml::Doc, f: |rbml::Doc| -> bool) -> bool {
|
2013-08-02 08:17:20 +02:00
|
|
|
reader::tagged_docs(d, tag_items_data_item_reexport, f)
|
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| {
|
|
|
|
reader::with_doc_data(val_doc, |data| u64::parse_bytes(data, 10u))
|
|
|
|
})
|
2012-01-10 22:50:40 +01:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn doc_type(doc: rbml::Doc, tcx: &ty::ctxt, cdata: Cmd) -> ty::t {
|
2012-12-07 01:13:54 +01:00
|
|
|
let tp = reader::get_doc(doc, tag_items_data_item_type);
|
2013-12-18 23:10:28 +01:00
|
|
|
parse_ty_data(tp.data, cdata.cnum, tp.start, tcx,
|
2013-01-17 15:13:26 +01:00
|
|
|
|_, did| translate_def_id(cdata, did))
|
2012-01-05 13:57:27 +01:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn doc_method_fty(doc: rbml::Doc, tcx: &ty::ctxt, cdata: Cmd) -> ty::BareFnTy {
|
2013-03-27 15:26:57 +01:00
|
|
|
let tp = reader::get_doc(doc, tag_item_method_fty);
|
2013-12-18 23:10:28 +01:00
|
|
|
parse_bare_fn_ty_data(tp.data, cdata.cnum, tp.start, tcx,
|
2013-03-27 15:26:57 +01:00
|
|
|
|_, did| translate_def_id(cdata, did))
|
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
pub fn item_type(_item_id: ast::DefId, item: rbml::Doc,
|
2014-03-06 04:07:47 +01:00
|
|
|
tcx: &ty::ctxt, cdata: Cmd) -> ty::t {
|
2013-04-02 22:41:18 +02:00
|
|
|
doc_type(item, tcx, cdata)
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn doc_trait_ref(doc: rbml::Doc, tcx: &ty::ctxt, cdata: Cmd) -> ty::TraitRef {
|
2013-12-18 23:10:28 +01:00
|
|
|
parse_trait_ref_data(doc.data, cdata.cnum, doc.start, tcx,
|
2013-03-27 11:16:28 +01:00
|
|
|
|_, did| translate_def_id(cdata, did))
|
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn item_trait_ref(doc: rbml::Doc, tcx: &ty::ctxt, cdata: Cmd) -> ty::TraitRef {
|
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-08-28 03:46:52 +02:00
|
|
|
fn doc_bounds(doc: rbml::Doc, tcx: &ty::ctxt, cdata: Cmd) -> ty::ParamBounds {
|
|
|
|
parse_bounds_data(doc.data, cdata.cnum, doc.start, tcx,
|
|
|
|
|_, did| translate_def_id(cdata, did))
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2014-08-28 03:46:52 +02:00
|
|
|
fn trait_def_bounds(doc: rbml::Doc, tcx: &ty::ctxt, cdata: Cmd) -> ty::ParamBounds {
|
|
|
|
let d = reader::get_doc(doc, tag_trait_def_bounds);
|
|
|
|
doc_bounds(d, tcx, cdata)
|
2012-04-19 06:26:25 +02:00
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn enum_variant_ids(item: rbml::Doc, cdata: Cmd) -> Vec<ast::DefId> {
|
2014-03-04 19:02:49 +01:00
|
|
|
let mut ids: Vec<ast::DefId> = Vec::new();
|
2011-07-27 14:19:39 +02:00
|
|
|
let v = tag_items_data_item_variant;
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::tagged_docs(item, v, |p| {
|
2013-06-08 02:32:25 +02:00
|
|
|
let ext = reader::with_doc_data(p, parse_def_id);
|
2014-02-05 22:15:24 +01:00
|
|
|
ids.push(ast::DefId { krate: cdata.cnum, node: ext.node });
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2012-08-02 02:30:05 +02:00
|
|
|
return ids;
|
2011-06-28 00:53:27 +02: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);
|
2012-02-10 15:01:32 +01:00
|
|
|
|
2012-12-07 01:13:54 +01:00
|
|
|
let len_doc = reader::get_doc(path_doc, tag_path_len);
|
|
|
|
let len = reader::doc_as_u32(len_doc) as uint;
|
2012-02-10 15:01:32 +01:00
|
|
|
|
2014-03-08 21:36:22 +01:00
|
|
|
let mut result = Vec::with_capacity(len);
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::docs(path_doc, |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();
|
|
|
|
result.push(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();
|
|
|
|
result.push(ast_map::PathName(token::intern(s)));
|
2012-02-10 15:01:32 +01:00
|
|
|
} else {
|
|
|
|
// ignore tag_path_len element
|
|
|
|
}
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2012-02-10 15:01:32 +01:00
|
|
|
|
2014-02-14 06:07:09 +01:00
|
|
|
result
|
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-10-24 19:25:50 +02:00
|
|
|
match intr.find_equiv(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
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
|
2013-08-31 18:13:04 +02:00
|
|
|
-> DefLike {
|
2012-08-23 02:58:05 +02:00
|
|
|
let fam = item_family(item);
|
|
|
|
match fam {
|
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
|
|
|
Constant => 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 => {
|
2013-07-16 02:26:56 +02:00
|
|
|
// def_static_method carries an optional field of its enclosing
|
2013-08-08 20:38:10 +02:00
|
|
|
// trait or enclosing impl (if this is an inherent static method).
|
|
|
|
// So we need to detect whether this is in a trait or not, which
|
|
|
|
// we do through the mildly hacky way of checking whether there is
|
2014-08-04 22:56:56 +02:00
|
|
|
// a trait_parent_sort.
|
2013-08-08 20:38:10 +02:00
|
|
|
let provenance = if reader::maybe_get_doc(
|
2014-08-04 22:56:56 +02:00
|
|
|
item, tag_item_trait_parent_sort).is_some() {
|
2014-05-14 21:31:30 +02:00
|
|
|
def::FromTrait(item_reqd_and_translated_parent_item(cnum,
|
2013-08-08 20:38:10 +02:00
|
|
|
item))
|
|
|
|
} else {
|
2014-05-14 21:31:30 +02:00
|
|
|
def::FromImpl(item_reqd_and_translated_parent_item(cnum,
|
2013-08-08 20:38:10 +02:00
|
|
|
item))
|
|
|
|
};
|
2014-10-16 06:44:24 +02:00
|
|
|
match fam {
|
|
|
|
// We don't bother to get encode/decode the trait id, we don't need it.
|
|
|
|
Method => DlDef(def::DefMethod(did, None, provenance)),
|
|
|
|
StaticMethod => DlDef(def::DefStaticMethod(did, provenance)),
|
2014-10-30 04:33:37 +01:00
|
|
|
_ => panic!()
|
2014-10-16 06:44:24 +02:00
|
|
|
}
|
2012-10-13 02:00:08 +02:00
|
|
|
}
|
2014-09-15 23:13:00 +02:00
|
|
|
Type | ForeignType => 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 => {
|
2012-10-13 02:00:08 +02:00
|
|
|
let enum_did = item_reqd_and_translated_parent_item(cnum, 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 => {
|
|
|
|
let enum_did = item_reqd_and_translated_parent_item(cnum, item);
|
2014-05-14 21:31:30 +02:00
|
|
|
DlDef(def::DefVariant(enum_did, did, false))
|
2012-10-13 02:00:08 +02:00
|
|
|
}
|
2014-05-14 21:31:30 +02:00
|
|
|
Trait => DlDef(def::DefTrait(did)),
|
2014-09-15 23:13:00 +02:00
|
|
|
Enum => DlDef(def::DefTy(did, true)),
|
2013-08-31 18:13:04 +02:00
|
|
|
Impl => 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
|
|
|
}
|
|
|
|
|
2013-08-31 18:13:04 +02:00
|
|
|
pub fn get_trait_def(cdata: Cmd,
|
2013-07-27 10:25:59 +02:00
|
|
|
item_id: ast::NodeId,
|
2014-03-06 04:07:47 +01:00
|
|
|
tcx: &ty::ctxt) -> ty::TraitDef
|
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);
|
|
|
|
let bounds = trait_def_bounds(item_doc, tcx, cdata);
|
2014-04-03 02:38:45 +02:00
|
|
|
|
2013-03-27 11:16:28 +01:00
|
|
|
ty::TraitDef {
|
2014-08-28 03:46:52 +02:00
|
|
|
generics: generics,
|
2013-08-16 22:57:42 +02:00
|
|
|
bounds: bounds,
|
2014-04-22 01:21:52 +02:00
|
|
|
trait_ref: Rc::new(item_trait_ref(item_doc, tcx, cdata))
|
2013-03-27 11:16:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-06 04:07:47 +01:00
|
|
|
pub fn get_type(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
|
2014-05-06 21:59:45 +02:00
|
|
|
-> ty::Polytype {
|
2012-04-19 06:26:25 +02:00
|
|
|
|
2013-12-18 23:10:28 +01:00
|
|
|
let item = lookup_item(id, cdata.data());
|
2013-10-29 11:03:32 +01:00
|
|
|
|
2014-02-05 22:15:24 +01:00
|
|
|
let t = item_type(ast::DefId { krate: cdata.cnum, node: id }, item, tcx,
|
2013-01-13 20:05:40 +01:00
|
|
|
cdata);
|
2013-10-29 11:03:32 +01:00
|
|
|
|
2014-08-28 03:46:52 +02:00
|
|
|
let generics = doc_generics(item, tcx, cdata, tag_item_generics);
|
2013-10-29 11:03:32 +01:00
|
|
|
|
2014-05-06 21:59:45 +02:00
|
|
|
ty::Polytype {
|
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(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-31 18:13:04 +02:00
|
|
|
pub fn get_impl_trait(cdata: Cmd,
|
2013-10-29 11:03:32 +01:00
|
|
|
id: ast::NodeId,
|
2014-04-22 01:21:52 +02:00
|
|
|
tcx: &ty::ctxt) -> Option<Rc<ty::TraitRef>>
|
2013-03-27 11:16:28 +01:00
|
|
|
{
|
2013-12-18 23:10:28 +01:00
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
|
2014-04-22 01:21:52 +02:00
|
|
|
Rc::new(doc_trait_ref(tp, tcx, cdata))
|
2013-11-22 00:42:55 +01:00
|
|
|
})
|
2012-01-05 10:57:19 +01:00
|
|
|
}
|
|
|
|
|
2013-08-31 18:13:04 +02:00
|
|
|
pub fn get_impl_vtables(cdata: Cmd,
|
2013-07-27 10:25:59 +02:00
|
|
|
id: ast::NodeId,
|
2014-06-01 00:53:13 +02:00
|
|
|
tcx: &ty::ctxt)
|
|
|
|
-> typeck::vtable_res
|
2013-07-23 01:40:31 +02:00
|
|
|
{
|
2013-12-18 23:10:28 +01:00
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2013-07-23 01:40:31 +02:00
|
|
|
let vtables_doc = reader::get_doc(item_doc, tag_item_impl_vtables);
|
2014-05-28 21:36:05 +02:00
|
|
|
let mut decoder = reader::Decoder::new(vtables_doc);
|
2014-06-01 00:53:13 +02:00
|
|
|
decoder.read_vtable_res(tcx, cdata)
|
2013-07-23 01:40:31 +02: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.
|
2013-12-21 22:58:11 +01:00
|
|
|
#[deriving(Clone)]
|
2013-08-31 18:13:04 +02:00
|
|
|
pub enum DefLike {
|
2014-05-14 21:31:30 +02:00
|
|
|
DlDef(def::Def),
|
2013-09-02 03:45:37 +02:00
|
|
|
DlImpl(ast::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.
|
2013-11-19 22:22:03 +01:00
|
|
|
pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool {
|
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);
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::tagged_docs(lang_items, tag_lang_items_item, |item_doc| {
|
2013-05-03 19:08:08 +02:00
|
|
|
let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
|
|
|
|
let id = reader::doc_as_u32(id_doc) as uint;
|
|
|
|
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-04-17 14:06:25 +02:00
|
|
|
pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Rc<crate_metadata>;
|
|
|
|
|
2014-03-27 18:28:38 +01:00
|
|
|
fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
|
2013-08-31 18:13:04 +02:00
|
|
|
cdata: Cmd,
|
2014-07-30 02:06:37 +02:00
|
|
|
item_doc: rbml::Doc,
|
2013-08-22 02:26:33 +02:00
|
|
|
get_crate_data: GetCrateDataCb,
|
2013-11-19 22:22:03 +01:00
|
|
|
callback: |DefLike,
|
2014-10-01 02:11:34 +02:00
|
|
|
ast::Name,
|
2014-01-09 14:05:33 +01:00
|
|
|
ast::Visibility|) {
|
2013-08-22 02:26:33 +02:00
|
|
|
// Iterate over all children.
|
2013-11-22 00:42:55 +01:00
|
|
|
let _ = reader::tagged_docs(item_doc, tag_mod_child, |child_info_doc| {
|
2013-08-22 02:26:33 +02:00
|
|
|
let child_def_id = reader::with_doc_data(child_info_doc,
|
|
|
|
parse_def_id);
|
|
|
|
let child_def_id = translate_def_id(cdata, child_def_id);
|
|
|
|
|
|
|
|
// 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);
|
2013-08-22 02:26:33 +02:00
|
|
|
let def_like = item_to_def_like(child_item_doc,
|
|
|
|
child_def_id,
|
|
|
|
cdata.cnum);
|
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
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
true
|
2013-11-22 00:42:55 +01: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
|
2013-11-22 00:42:55 +01:00
|
|
|
let _ = reader::tagged_docs(item_doc,
|
|
|
|
tag_items_data_item_inherent_impl,
|
|
|
|
|inherent_impl_def_id_doc| {
|
2013-08-24 03:31:43 +02:00
|
|
|
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);
|
2013-08-24 03:31:43 +02:00
|
|
|
match maybe_find_item(inherent_impl_def_id.node, items) {
|
|
|
|
None => {}
|
|
|
|
Some(inherent_impl_doc) => {
|
2013-11-22 00:42:55 +01:00
|
|
|
let _ = reader::tagged_docs(inherent_impl_doc,
|
2014-08-04 22:56:56 +02:00
|
|
|
tag_item_impl_item,
|
|
|
|
|impl_item_def_id_doc| {
|
|
|
|
let impl_item_def_id = item_def_id(impl_item_def_id_doc,
|
|
|
|
cdata);
|
|
|
|
match maybe_find_item(impl_item_def_id.node, items) {
|
2013-08-24 03:31:43 +02:00
|
|
|
None => {}
|
|
|
|
Some(impl_method_doc) => {
|
|
|
|
match item_family(impl_method_doc) {
|
2014-10-16 06:44:24 +02:00
|
|
|
StaticMethod => {
|
2013-08-24 03:31:43 +02:00
|
|
|
// Hand off the static method
|
|
|
|
// to the callback.
|
|
|
|
let static_method_name =
|
2014-03-27 18:28:38 +01:00
|
|
|
item_name(&*intr, impl_method_doc);
|
2013-08-24 03:31:43 +02:00
|
|
|
let static_method_def_like =
|
|
|
|
item_to_def_like(impl_method_doc,
|
2014-08-04 22:56:56 +02:00
|
|
|
impl_item_def_id,
|
2013-08-24 03:31:43 +02:00
|
|
|
cdata.cnum);
|
|
|
|
callback(static_method_def_like,
|
2013-08-07 09:11:34 +02:00
|
|
|
static_method_name,
|
|
|
|
item_visibility(impl_method_doc));
|
2013-08-24 03:31:43 +02:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2013-08-22 02:26:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2013-08-22 02:26:33 +02:00
|
|
|
|
|
|
|
// Iterate over all reexports.
|
2013-11-22 00:42:55 +01:00
|
|
|
let _ = each_reexport(item_doc, |reexport_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);
|
|
|
|
let child_def_id = reader::with_doc_data(def_id_doc,
|
|
|
|
parse_def_id);
|
|
|
|
let child_def_id = translate_def_id(cdata, child_def_id);
|
|
|
|
|
|
|
|
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.
|
|
|
|
match maybe_find_item(child_def_id.node, other_crates_items) {
|
|
|
|
None => {}
|
|
|
|
Some(child_item_doc) => {
|
|
|
|
// Hand off the item to the callback.
|
|
|
|
let def_like = item_to_def_like(child_item_doc,
|
|
|
|
child_def_id,
|
2014-05-01 04:24:21 +02:00
|
|
|
child_def_id.krate);
|
Extract privacy checking from name resolution
This commit is the culmination of my recent effort to refine Rust's notion of
privacy and visibility among crates. The major goals of this commit were to
remove privacy checking from resolve for the sake of sane error messages, and to
attempt a much more rigid and well-tested implementation of visibility
throughout rust. The implemented rules for name visibility are:
1. Everything pub from the root namespace is visible to anyone
2. You may access any private item of your ancestors.
"Accessing a private item" depends on what the item is, so for a function this
means that you can call it, but for a module it means that you can look inside
of it. Once you look inside a private module, any accessed item must be "pub
from the root" where the new root is the private module that you looked into.
These rules required some more analysis results to get propagated from trans to
privacy in the form of a few hash tables.
I added a new test in which my goal was to showcase all of the privacy nuances
of the language, and I hope to place any new bugs into this file to prevent
regressions.
Overall, I was unable to completely remove the notion of privacy from resolve.
One use of privacy is for dealing with glob imports. Essentially a glob import
can only import *public* items from the destination, and because this must be
done at namespace resolution time, resolve must maintain the notion of "what
items are public in a module". There are some sad approximations of privacy, but
I unfortunately can't see clear methods to extract them outside.
The other use case of privacy in resolve now is one that must stick around
regardless of glob imports. When dealing with privacy, checking a private path
needs to know "what the last private thing was" when looking at a path. Resolve
is the only compiler pass which knows the answer to this question, so it
maintains the answer on a per-path resolution basis (works similarly to the
def_map generated).
Closes #8215
2013-10-05 23:37:39 +02:00
|
|
|
// These items have a public visibility because they're part of
|
|
|
|
// a public re-export.
|
2014-10-01 02:11:34 +02:00
|
|
|
callback(def_like, token::intern(name), ast::Public);
|
2013-08-22 02:26:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
true
|
2013-11-22 00:42:55 +01: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-03-27 18:28:38 +01:00
|
|
|
pub fn each_child_of_item(intr: Rc<IdentInterner>,
|
2013-08-31 18:13:04 +02:00
|
|
|
cdata: Cmd,
|
2013-08-22 02:26:33 +02:00
|
|
|
id: ast::NodeId,
|
|
|
|
get_crate_data: GetCrateDataCb,
|
2014-10-01 02:11:34 +02:00
|
|
|
callback: |DefLike, ast::Name, ast::Visibility|) {
|
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-03-27 18:28:38 +01:00
|
|
|
pub fn each_top_level_item_of_crate(intr: Rc<IdentInterner>,
|
2013-08-31 18:13:04 +02:00
|
|
|
cdata: Cmd,
|
2013-08-22 02:26:33 +02:00
|
|
|
get_crate_data: GetCrateDataCb,
|
2013-11-19 22:22:03 +01:00
|
|
|
callback: |DefLike,
|
2014-10-01 02:11:34 +02:00
|
|
|
ast::Name,
|
2014-01-09 14:05:33 +01:00
|
|
|
ast::Visibility|) {
|
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
|
|
|
}
|
|
|
|
|
2014-09-07 19:09:06 +02:00
|
|
|
pub type DecodeInlinedItem<'a> = <'tcx> |cdata: Cmd,
|
|
|
|
tcx: &ty::ctxt<'tcx>,
|
|
|
|
path: Vec<ast_map::PathElem>,
|
|
|
|
par_doc: rbml::Doc|: 'a
|
|
|
|
-> Result<&'tcx ast::InlinedItem,
|
|
|
|
Vec<ast_map::PathElem>>;
|
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,
|
|
|
|
decode_inlined_item: DecodeInlinedItem)
|
|
|
|
-> csearch::found_ast<'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());
|
2014-10-15 08:05:01 +02:00
|
|
|
let path = item_path(item_doc).init().to_vec();
|
2014-02-14 06:07:09 +01:00
|
|
|
match decode_inlined_item(cdata, tcx, path, item_doc) {
|
2014-09-07 19:09:06 +02:00
|
|
|
Ok(ii) => csearch::found(ii),
|
2014-02-14 06:07:09 +01:00
|
|
|
Err(path) => {
|
|
|
|
match item_parent_item(item_doc) {
|
|
|
|
Some(did) => {
|
|
|
|
let did = translate_def_id(cdata, did);
|
|
|
|
let parent_item = lookup_item(did.node, cdata.data());
|
|
|
|
match decode_inlined_item(cdata, tcx, path, parent_item) {
|
2014-09-07 19:09:06 +02:00
|
|
|
Ok(ii) => csearch::found_parent(did, ii),
|
2014-02-14 06:07:09 +01:00
|
|
|
Err(_) => csearch::not_found
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => csearch::not_found
|
2012-03-08 23:13:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-02-15 00:21:53 +01:00
|
|
|
}
|
|
|
|
|
2014-03-27 18:28:38 +01:00
|
|
|
pub fn get_enum_variants(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
|
2014-04-22 01:21:52 +02:00
|
|
|
tcx: &ty::ctxt) -> Vec<Rc<ty::VariantInfo>> {
|
2013-12-18 23:10:28 +01:00
|
|
|
let data = cdata.data();
|
2014-07-30 02:06:37 +02:00
|
|
|
let items = reader::get_doc(rbml::Doc::new(data), tag_items);
|
2012-01-05 16:04:59 +01:00
|
|
|
let item = find_item(id, items);
|
2012-03-15 14:47:03 +01:00
|
|
|
let mut disr_val = 0;
|
2014-04-22 01:21:52 +02:00
|
|
|
enum_variant_ids(item, cdata).iter().map(|did| {
|
2011-07-27 14:19:39 +02:00
|
|
|
let item = find_item(did.node, items);
|
2014-02-05 22:15:24 +01:00
|
|
|
let ctor_ty = item_type(ast::DefId { krate: cdata.cnum, node: id},
|
2013-01-13 20:05:40 +01:00
|
|
|
item, tcx, cdata);
|
2014-03-27 18:28:38 +01:00
|
|
|
let name = item_name(&*intr, item);
|
2014-10-21 03:40:10 +02:00
|
|
|
let (ctor_ty, arg_tys) = match ty::get(ctor_ty).sty {
|
|
|
|
ty::ty_bare_fn(ref f) =>
|
|
|
|
(Some(ctor_ty), f.sig.inputs.clone()),
|
|
|
|
_ => // Nullary or struct enum variant.
|
|
|
|
(None, get_struct_fields(intr.clone(), cdata, did.node)
|
|
|
|
.iter()
|
|
|
|
.map(|field_ty| get_type(cdata, field_ty.id.node, tcx).ty)
|
|
|
|
.collect())
|
2012-10-18 18:14:11 +02:00
|
|
|
};
|
2012-08-06 21:34:08 +02:00
|
|
|
match variant_disr_val(item) {
|
2014-04-22 01:21:52 +02:00
|
|
|
Some(val) => { disr_val = val; }
|
|
|
|
_ => { /* empty */ }
|
2012-01-10 22:50:40 +01:00
|
|
|
}
|
2014-04-22 01:21:52 +02:00
|
|
|
let old_disr_val = disr_val;
|
|
|
|
disr_val += 1;
|
|
|
|
Rc::new(ty::VariantInfo {
|
2013-07-08 17:27:07 +02:00
|
|
|
args: arg_tys,
|
|
|
|
arg_names: None,
|
|
|
|
ctor_ty: ctor_ty,
|
|
|
|
name: name,
|
|
|
|
// I'm not even sure if we encode visibility
|
|
|
|
// for variants -- TEST -- tjc
|
|
|
|
id: *did,
|
2014-04-22 01:21:52 +02:00
|
|
|
disr_val: old_disr_val,
|
|
|
|
vis: ast::Inherited
|
|
|
|
})
|
|
|
|
}).collect()
|
2011-06-28 00:53:27 +02: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> {
|
|
|
|
let mut impl_items = Vec::new();
|
2014-04-21 11:04:35 +02:00
|
|
|
reader::tagged_docs(lookup_item(impl_id, cdata.data()),
|
2014-08-04 22:56:56 +02:00
|
|
|
tag_item_impl_item, |doc| {
|
|
|
|
let def_id = item_def_id(doc, cdata);
|
|
|
|
match item_sort(doc) {
|
|
|
|
'r' | 'p' => impl_items.push(ty::MethodTraitItemId(def_id)),
|
2014-08-06 04:44:21 +02:00
|
|
|
't' => impl_items.push(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
|
|
|
}
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2013-07-16 00:24:16 +02:00
|
|
|
|
2014-08-04 22:56:56 +02:00
|
|
|
impl_items
|
2012-01-05 13:57:27 +01:00
|
|
|
}
|
|
|
|
|
2014-08-04 22:56:56 +02:00
|
|
|
pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
|
|
|
|
cdata: Cmd,
|
|
|
|
id: ast::NodeId)
|
2014-10-01 02:11:34 +02:00
|
|
|
-> (ast::Name, TraitItemKind) {
|
2014-08-04 22:56:56 +02:00
|
|
|
let doc = lookup_item(id, cdata.data());
|
|
|
|
let name = item_name(&*intr, doc);
|
|
|
|
match item_sort(doc) {
|
|
|
|
'r' | 'p' => {
|
|
|
|
let explicit_self = get_explicit_self(doc);
|
|
|
|
(name, TraitItemKind::from_explicit_self_category(explicit_self))
|
|
|
|
}
|
2014-08-06 04:44:21 +02:00
|
|
|
't' => (name, TypeTraitItemKind),
|
2014-08-04 22:56:56 +02:00
|
|
|
c => {
|
2014-10-09 21:17:22 +02:00
|
|
|
panic!("get_trait_item_name_and_kind(): unknown trait item kind \
|
2014-08-04 22:56:56 +02:00
|
|
|
in metadata: `{}`", c)
|
|
|
|
}
|
|
|
|
}
|
2013-03-27 15:26:57 +01:00
|
|
|
}
|
|
|
|
|
2014-08-04 22:56:56 +02:00
|
|
|
pub fn get_impl_or_trait_item(intr: Rc<IdentInterner>,
|
|
|
|
cdata: Cmd,
|
|
|
|
id: ast::NodeId,
|
|
|
|
tcx: &ty::ctxt)
|
|
|
|
-> ty::ImplOrTraitItem {
|
2013-12-18 23:10:28 +01:00
|
|
|
let method_doc = lookup_item(id, cdata.data());
|
2014-08-28 03:46:52 +02:00
|
|
|
|
2013-03-28 19:27:54 +01:00
|
|
|
let def_id = item_def_id(method_doc, cdata);
|
2013-08-23 23:34:00 +02:00
|
|
|
|
2013-07-16 02:26:56 +02:00
|
|
|
let container_id = item_reqd_and_translated_parent_item(cdata.cnum,
|
|
|
|
method_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),
|
|
|
|
};
|
|
|
|
|
2014-03-27 18:28:38 +01:00
|
|
|
let name = item_name(&*intr, method_doc);
|
2014-08-06 04:44:21 +02:00
|
|
|
let vis = item_visibility(method_doc);
|
2014-08-04 22:56:56 +02:00
|
|
|
|
|
|
|
match item_sort(method_doc) {
|
|
|
|
'r' | 'p' => {
|
2014-08-28 03:46:52 +02:00
|
|
|
let generics = doc_generics(method_doc, tcx, cdata,
|
|
|
|
tag_method_ty_generics);
|
2014-08-04 22:56:56 +02:00
|
|
|
let fty = doc_method_fty(method_doc, tcx, cdata);
|
|
|
|
let explicit_self = get_explicit_self(method_doc);
|
|
|
|
let provided_source = get_provided_source(method_doc, cdata);
|
|
|
|
|
|
|
|
ty::MethodTraitItem(Rc::new(ty::Method::new(name,
|
|
|
|
generics,
|
|
|
|
fty,
|
|
|
|
explicit_self,
|
|
|
|
vis,
|
|
|
|
def_id,
|
|
|
|
container,
|
|
|
|
provided_source)))
|
|
|
|
}
|
2014-08-06 04:44:21 +02:00
|
|
|
't' => {
|
|
|
|
ty::TypeTraitItem(Rc::new(ty::AssociatedType {
|
2014-10-01 02:11:34 +02:00
|
|
|
name: name,
|
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);
|
2014-03-04 19:02:49 +01:00
|
|
|
let mut result = Vec::new();
|
2014-08-04 22:56:56 +02:00
|
|
|
reader::tagged_docs(item, tag_item_trait_item, |mth| {
|
|
|
|
let def_id = item_def_id(mth, cdata);
|
|
|
|
match item_sort(mth) {
|
|
|
|
'r' | 'p' => result.push(ty::MethodTraitItemId(def_id)),
|
2014-08-06 04:44:21 +02:00
|
|
|
't' => result.push(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
|
|
|
}
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2013-03-27 15:26:57 +01:00
|
|
|
result
|
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-08-04 22:56:56 +02:00
|
|
|
pub fn get_provided_trait_methods(intr: Rc<IdentInterner>,
|
|
|
|
cdata: Cmd,
|
|
|
|
id: ast::NodeId,
|
|
|
|
tcx: &ty::ctxt)
|
2014-04-22 01:21:52 +02:00
|
|
|
-> Vec<Rc<ty::Method>> {
|
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);
|
2014-03-04 19:02:49 +01:00
|
|
|
let mut result = Vec::new();
|
2012-10-08 21:39:30 +02:00
|
|
|
|
2014-08-04 22:56:56 +02:00
|
|
|
reader::tagged_docs(item, tag_item_trait_item, |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
|
|
|
|
2014-08-04 22:56:56 +02:00
|
|
|
if item_sort(mth) == 'p' {
|
|
|
|
let trait_item = get_impl_or_trait_item(intr.clone(),
|
|
|
|
cdata,
|
|
|
|
did.node,
|
|
|
|
tcx);
|
|
|
|
match trait_item {
|
|
|
|
ty::MethodTraitItem(ref method) => {
|
|
|
|
result.push((*method).clone())
|
|
|
|
}
|
2014-08-06 04:44:21 +02:00
|
|
|
ty::TypeTraitItem(_) => {}
|
2014-08-04 22:56:56 +02:00
|
|
|
}
|
2013-08-02 08:17:20 +02:00
|
|
|
}
|
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2012-10-08 21:39:30 +02:00
|
|
|
|
2013-02-15 10:14:34 +01:00
|
|
|
return result;
|
2012-10-08 21:39:30 +02:00
|
|
|
}
|
|
|
|
|
2012-10-20 06:27:01 +02:00
|
|
|
/// Returns the supertraits of the given trait.
|
2014-03-06 04:07:47 +01:00
|
|
|
pub fn get_supertraits(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
|
2014-04-22 01:21:52 +02:00
|
|
|
-> Vec<Rc<ty::TraitRef>> {
|
2014-03-04 19:02:49 +01:00
|
|
|
let mut results = Vec::new();
|
2013-12-18 23:10:28 +01:00
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::tagged_docs(item_doc, tag_item_super_trait_ref, |trait_doc| {
|
2013-08-16 22:57:42 +02:00
|
|
|
// NB. Only reads the ones that *aren't* builtin-bounds. See also
|
|
|
|
// get_trait_def() for collecting the builtin bounds.
|
|
|
|
// FIXME(#8559): The builtin bounds shouldn't be encoded in the first place.
|
|
|
|
let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
|
|
|
|
if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() {
|
2014-04-22 01:21:52 +02:00
|
|
|
results.push(Rc::new(trait_ref));
|
2013-08-16 22:57:42 +02:00
|
|
|
}
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2013-03-08 00:37:14 +01:00
|
|
|
return results;
|
2012-10-20 06:27:01 +02: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;
|
|
|
|
}
|
|
|
|
|
2013-08-02 08:17:20 +02:00
|
|
|
let mut ret = None;
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::tagged_docs(item, tag_item_impl_type_basename, |doc| {
|
2014-10-01 02:11:34 +02:00
|
|
|
ret = Some(token::intern(doc.as_str_slice()));
|
2013-08-02 08:17:20 +02:00
|
|
|
false
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2012-10-18 22:29:34 +02:00
|
|
|
|
2013-08-02 08:17:20 +02:00
|
|
|
ret
|
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.
|
2013-11-22 00:42:55 +01:00
|
|
|
let ret = reader::tagged_docs(item, tag_item_trait_ref, |_doc| {
|
2013-08-02 08:17:20 +02:00
|
|
|
false
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2013-08-02 08:17:20 +02:00
|
|
|
|
|
|
|
if !ret { return None }
|
2012-10-18 22:29:34 +02:00
|
|
|
|
2014-03-04 19:02:49 +01:00
|
|
|
let mut impl_method_ids = Vec::new();
|
2014-08-04 22:56:56 +02:00
|
|
|
reader::tagged_docs(item, tag_item_impl_item, |impl_method_doc| {
|
|
|
|
impl_method_ids.push(item_def_id(impl_method_doc, cdata));
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2012-10-18 22:29:34 +02:00
|
|
|
|
2014-10-20 03:30:31 +02:00
|
|
|
let mut impl_methods = Vec::new();
|
2013-08-03 18:45:23 +02:00
|
|
|
for impl_method_id in impl_method_ids.iter() {
|
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)
|
|
|
|
-> Option<ast::DefId>
|
|
|
|
{
|
2014-01-30 13:36:05 +01:00
|
|
|
let item = lookup_item(node_id, cdata.data());
|
|
|
|
let mut ret = None;
|
|
|
|
reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor, |_| {
|
|
|
|
ret = Some(item_reqd_and_translated_parent_item(cdata.cnum, item));
|
|
|
|
false
|
|
|
|
});
|
2014-04-01 03:13:44 +02:00
|
|
|
ret
|
2014-01-30 13:36:05 +01:00
|
|
|
}
|
|
|
|
|
2013-08-31 18:13:04 +02:00
|
|
|
pub fn get_item_attrs(cdata: Cmd,
|
2014-04-01 03:13:44 +02:00
|
|
|
orig_node_id: ast::NodeId,
|
2014-05-21 09:05:45 +02:00
|
|
|
f: |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());
|
2014-05-21 09:05:45 +02:00
|
|
|
f(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);
|
|
|
|
let mut map = HashMap::new();
|
|
|
|
reader::tagged_docs(fields, tag_struct_field, |field| {
|
|
|
|
let id = reader::doc_as_u32(reader::get_doc(field, tag_struct_field_id));
|
|
|
|
let attrs = get_attributes(field);
|
|
|
|
map.insert(id, attrs);
|
|
|
|
true
|
|
|
|
});
|
|
|
|
map
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-27 18:28:38 +01:00
|
|
|
pub fn get_struct_fields(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId)
|
2014-03-04 19:02:49 +01:00
|
|
|
-> Vec<ty::field_ty> {
|
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);
|
2014-03-04 19:02:49 +01:00
|
|
|
let mut result = Vec::new();
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::tagged_docs(item, tag_item_field, |an_item| {
|
2013-01-17 04:24:10 +01:00
|
|
|
let f = item_family(an_item);
|
2014-04-16 03:02:58 +02:00
|
|
|
if f == PublicField || f == InheritedField {
|
2014-03-27 18:28:38 +01:00
|
|
|
let name = item_name(&*intr, an_item);
|
2013-01-17 04:24:10 +01:00
|
|
|
let did = item_def_id(an_item, cdata);
|
2014-02-24 08:17:02 +01:00
|
|
|
let tagdoc = reader::get_doc(an_item, tag_item_field_origin);
|
|
|
|
let origin_id = translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id));
|
2013-01-17 04:24:10 +01:00
|
|
|
result.push(ty::field_ty {
|
2014-10-01 02:11:34 +02:00
|
|
|
name: name,
|
2014-02-24 08:17:02 +01:00
|
|
|
id: did,
|
|
|
|
vis: struct_field_family_to_visibility(f),
|
|
|
|
origin: origin_id,
|
2013-01-17 04:24:10 +01:00
|
|
|
});
|
|
|
|
}
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
|
|
|
reader::tagged_docs(item, tag_item_unnamed_field, |an_item| {
|
2013-02-12 01:28:39 +01:00
|
|
|
let did = item_def_id(an_item, cdata);
|
2014-02-24 08:17:02 +01:00
|
|
|
let tagdoc = reader::get_doc(an_item, tag_item_field_origin);
|
2014-03-26 00:53:52 +01:00
|
|
|
let f = item_family(an_item);
|
2014-02-24 08:17:02 +01:00
|
|
|
let origin_id = translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id));
|
2013-02-12 01:28:39 +01:00
|
|
|
result.push(ty::field_ty {
|
2013-09-12 01:21:03 +02:00
|
|
|
name: special_idents::unnamed_field.name,
|
2013-02-12 01:28:39 +01:00
|
|
|
id: did,
|
2014-03-26 00:53:52 +01:00
|
|
|
vis: struct_field_family_to_visibility(f),
|
2014-02-24 08:17:02 +01:00
|
|
|
origin: origin_id,
|
2013-02-12 01:28:39 +01:00
|
|
|
});
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2012-03-06 17:02:13 +01:00
|
|
|
result
|
|
|
|
}
|
|
|
|
|
2014-09-07 19:09:06 +02:00
|
|
|
fn get_meta_items(md: rbml::Doc) -> Vec<P<ast::MetaItem>> {
|
|
|
|
let mut items: Vec<P<ast::MetaItem>> = Vec::new();
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::tagged_docs(md, tag_meta_item_word, |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());
|
2013-06-12 19:02:55 +02:00
|
|
|
items.push(attr::mk_word_item(n));
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
|
|
|
reader::tagged_docs(md, tag_meta_item_name_value, |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
|
2013-06-12 19:02:55 +02:00
|
|
|
items.push(attr::mk_name_value_item_str(n, v));
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
|
|
|
reader::tagged_docs(md, tag_meta_item_list, |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);
|
2014-09-15 05:27:36 +02:00
|
|
|
items.push(attr::mk_list_item(n, subitems.into_iter().collect()));
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2012-08-02 02:30:05 +02:00
|
|
|
return items;
|
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> {
|
2014-03-04 19:02:49 +01:00
|
|
|
let mut attrs: Vec<ast::Attribute> = Vec::new();
|
2012-12-07 01:13:54 +01:00
|
|
|
match reader::maybe_get_doc(md, tag_attributes) {
|
2014-05-16 19:15:33 +02:00
|
|
|
Some(attrs_d) => {
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::tagged_docs(attrs_d, tag_attribute, |attr_doc| {
|
2014-07-28 10:02:31 +02:00
|
|
|
let is_sugared_doc = reader::doc_as_u8(
|
|
|
|
reader::get_doc(attr_doc, tag_attribute_is_sugared_doc)
|
|
|
|
) == 1;
|
2011-07-27 14:19:39 +02:00
|
|
|
let meta_items = get_meta_items(attr_doc);
|
|
|
|
// Currently it's only possible to have a single meta item on
|
|
|
|
// an attribute
|
2013-05-19 04:02:45 +02:00
|
|
|
assert_eq!(meta_items.len(), 1u);
|
2014-09-15 05:27:36 +02:00
|
|
|
let meta_item = meta_items.into_iter().nth(0).unwrap();
|
2012-09-27 02:33:34 +02:00
|
|
|
attrs.push(
|
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
|
2013-01-14 01:51:48 +01:00
|
|
|
});
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2014-05-16 19:15:33 +02:00
|
|
|
None => ()
|
2011-06-28 04:41:48 +02:00
|
|
|
}
|
2012-08-02 02:30:05 +02:00
|
|
|
return attrs;
|
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,
|
2014-01-30 03:42:19 +01:00
|
|
|
out: &mut io::Writer) -> io::IoResult<()> {
|
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);
|
2013-08-03 18:45:23 +02:00
|
|
|
for attr in r.iter() {
|
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
|
|
|
}
|
|
|
|
|
2013-07-02 21:47:32 +02:00
|
|
|
#[deriving(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,
|
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> {
|
|
|
|
let mut deps: Vec<CrateDep> = Vec::new();
|
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);
|
2012-03-15 14:47:03 +01:00
|
|
|
let mut crate_num = 1;
|
2014-07-30 02:06:37 +02:00
|
|
|
fn docstr(doc: rbml::Doc, tag_: uint) -> 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
|
|
|
}
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| {
|
2014-06-06 22:21:18 +02:00
|
|
|
let name = docstr(depdoc, tag_crate_dep_crate_name);
|
2014-05-10 03:45:36 +02:00
|
|
|
let hash = Svh::new(docstr(depdoc, tag_crate_dep_hash).as_slice());
|
2014-02-25 03:13:51 +01:00
|
|
|
deps.push(CrateDep {
|
|
|
|
cnum: crate_num,
|
2014-06-06 22:21:18 +02:00
|
|
|
name: name,
|
2014-02-25 03:13:51 +01:00
|
|
|
hash: hash,
|
|
|
|
});
|
2011-07-08 20:29:56 +02:00
|
|
|
crate_num += 1;
|
2013-08-02 08:17:20 +02:00
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2012-08-02 02:30:05 +02:00
|
|
|
return deps;
|
2011-07-08 20:29:56 +02:00
|
|
|
}
|
|
|
|
|
2014-01-30 03:42:19 +01:00
|
|
|
fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
|
2014-02-19 19:07:49 +01:00
|
|
|
try!(write!(out, "=External Dependencies=\n"));
|
2014-02-25 03:13:51 +01:00
|
|
|
for dep in get_crate_deps(data).iter() {
|
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
|
|
|
}
|
|
|
|
|
2014-02-14 06:07:09 +01:00
|
|
|
pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
|
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.
|
2013-09-02 03:45:37 +02:00
|
|
|
pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId {
|
2014-02-05 22:15:24 +01:00
|
|
|
if did.krate == ast::LOCAL_CRATE {
|
|
|
|
return ast::DefId { krate: cdata.cnum, node: did.node };
|
2012-01-05 16:04:59 +01:00
|
|
|
}
|
|
|
|
|
2014-04-22 18:06:43 +02:00
|
|
|
match cdata.cnum_map.find(&did.krate) {
|
2013-12-22 03:17:29 +01:00
|
|
|
Some(&n) => {
|
|
|
|
ast::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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-19 22:22:03 +01:00
|
|
|
pub fn each_impl(cdata: Cmd, callback: |ast::DefId|) {
|
2014-07-30 02:06:37 +02:00
|
|
|
let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls);
|
2013-11-22 00:42:55 +01:00
|
|
|
let _ = reader::tagged_docs(impls_doc, tag_impls_impl, |impl_doc| {
|
2013-08-20 23:55:54 +02:00
|
|
|
callback(item_def_id(impl_doc, cdata));
|
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2013-08-20 23:55:54 +02:00
|
|
|
}
|
|
|
|
|
2013-08-31 18:13:04 +02:00
|
|
|
pub fn each_implementation_for_type(cdata: Cmd,
|
2013-08-23 23:34:00 +02:00
|
|
|
id: ast::NodeId,
|
2013-11-19 22:22:03 +01:00
|
|
|
callback: |ast::DefId|) {
|
2013-12-18 23:10:28 +01:00
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2013-11-22 00:42:55 +01:00
|
|
|
reader::tagged_docs(item_doc,
|
|
|
|
tag_items_data_item_inherent_impl,
|
|
|
|
|impl_doc| {
|
2013-08-23 23:34:00 +02:00
|
|
|
let implementation_def_id = item_def_id(impl_doc, cdata);
|
|
|
|
callback(implementation_def_id);
|
|
|
|
true
|
2013-11-22 00:42:55 +01:00
|
|
|
});
|
2013-08-23 23:34:00 +02:00
|
|
|
}
|
|
|
|
|
2013-08-31 18:13:04 +02:00
|
|
|
pub fn each_implementation_for_trait(cdata: Cmd,
|
2013-08-23 23:34:00 +02:00
|
|
|
id: ast::NodeId,
|
2013-11-19 22:22:03 +01:00
|
|
|
callback: |ast::DefId|) {
|
2013-12-18 23:10:28 +01:00
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2013-08-23 23:34:00 +02:00
|
|
|
|
2013-11-22 00:42:55 +01:00
|
|
|
let _ = reader::tagged_docs(item_doc,
|
|
|
|
tag_items_data_item_extension_impl,
|
|
|
|
|impl_doc| {
|
2013-08-23 23:34:00 +02:00
|
|
|
let implementation_def_id = item_def_id(impl_doc, cdata);
|
|
|
|
callback(implementation_def_id);
|
|
|
|
true
|
2013-11-22 00:42:55 +01: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)
|
|
|
|
-> Option<ast::DefId> {
|
2013-12-18 23:10:28 +01:00
|
|
|
let item_doc = lookup_item(id, cdata.data());
|
2013-08-23 23:34:00 +02:00
|
|
|
let parent_item_id = match item_parent_item(item_doc) {
|
|
|
|
None => return None,
|
|
|
|
Some(item_id) => item_id,
|
|
|
|
};
|
|
|
|
let parent_item_id = translate_def_id(cdata, parent_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)),
|
|
|
|
Impl => {
|
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)
|
2014-05-23 01:57:53 +02:00
|
|
|
-> Vec<(cstore::NativeLibaryKind, 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);
|
2014-03-04 19:02:49 +01:00
|
|
|
let mut result = Vec::new();
|
2013-11-29 03:03:38 +01:00
|
|
|
reader::tagged_docs(libraries, tag_native_libraries_lib, |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);
|
|
|
|
let kind: cstore::NativeLibaryKind =
|
|
|
|
FromPrimitive::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();
|
2013-11-30 20:39:55 +01:00
|
|
|
result.push((kind, name));
|
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
|
|
|
true
|
2013-11-29 03:03:38 +01: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
|
|
|
return result;
|
|
|
|
}
|
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)
|
2014-04-13 20:26:43 +02:00
|
|
|
.map(|doc| FromPrimitive::from_u32(reader::doc_as_u32(doc)).unwrap())
|
2013-12-25 19:10:33 +01:00
|
|
|
}
|
|
|
|
|
2014-05-23 01:57:53 +02:00
|
|
|
pub fn get_exported_macros(data: &[u8]) -> Vec<String> {
|
2014-07-30 02:06:37 +02:00
|
|
|
let macros = reader::get_doc(rbml::Doc::new(data),
|
2013-12-25 19:10:33 +01:00
|
|
|
tag_exported_macros);
|
2014-03-04 19:02:49 +01:00
|
|
|
let mut result = Vec::new();
|
2013-12-25 19:10:33 +01:00
|
|
|
reader::tagged_docs(macros, tag_macro_def, |macro_doc| {
|
2014-05-25 12:17:19 +02:00
|
|
|
result.push(macro_doc.as_str().to_string());
|
2013-12-25 19:10:33 +01:00
|
|
|
true
|
|
|
|
});
|
|
|
|
result
|
|
|
|
}
|
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(',') {
|
|
|
|
if spec.len() == 0 { continue }
|
|
|
|
let cnum = spec.split(':').nth(0).unwrap();
|
|
|
|
let link = spec.split(':').nth(1).unwrap();
|
|
|
|
let cnum = from_str(cnum).unwrap();
|
|
|
|
let cnum = match cdata.cnum_map.find(&cnum) {
|
|
|
|
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);
|
2014-05-19 18:30:09 +02:00
|
|
|
let mut result = Vec::new();
|
2014-10-27 23:37:07 +01:00
|
|
|
reader::tagged_docs(items, tag_lang_items_missing, |missing_docs| {
|
2014-05-19 18:30:09 +02:00
|
|
|
let item: lang_items::LangItem =
|
2014-10-27 23:37:07 +01:00
|
|
|
FromPrimitive::from_u32(reader::doc_as_u32(missing_docs)).unwrap();
|
2014-05-19 18:30:09 +02:00
|
|
|
result.push(item);
|
|
|
|
true
|
|
|
|
});
|
|
|
|
return result;
|
|
|
|
}
|
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 mut ret = Vec::new();
|
|
|
|
let method_doc = lookup_item(id, cdata.data());
|
|
|
|
match reader::maybe_get_doc(method_doc, tag_method_argument_names) {
|
|
|
|
Some(args_doc) => {
|
|
|
|
reader::tagged_docs(args_doc, tag_method_argument_name, |name_doc| {
|
2014-05-25 12:17:19 +02:00
|
|
|
ret.push(name_doc.as_str_slice().to_string());
|
2014-05-24 02:13:44 +02:00
|
|
|
true
|
|
|
|
});
|
|
|
|
}
|
|
|
|
None => {}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
2014-06-07 02:48:46 +02:00
|
|
|
|
|
|
|
pub fn get_reachable_extern_fns(cdata: Cmd) -> Vec<ast::DefId> {
|
|
|
|
let mut ret = Vec::new();
|
2014-07-30 02:06:37 +02:00
|
|
|
let items = reader::get_doc(rbml::Doc::new(cdata.data()),
|
2014-06-07 02:48:46 +02:00
|
|
|
tag_reachable_extern_fns);
|
|
|
|
reader::tagged_docs(items, tag_reachable_extern_fn_id, |doc| {
|
|
|
|
ret.push(ast::DefId {
|
|
|
|
krate: cdata.cnum,
|
|
|
|
node: reader::doc_as_u32(doc),
|
|
|
|
});
|
|
|
|
true
|
|
|
|
});
|
|
|
|
return ret;
|
|
|
|
}
|
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
|
|
|
|
|
|
|
fn doc_generics(base_doc: rbml::Doc,
|
|
|
|
tcx: &ty::ctxt,
|
|
|
|
cdata: Cmd,
|
|
|
|
tag: uint)
|
|
|
|
-> ty::Generics
|
|
|
|
{
|
|
|
|
let doc = reader::get_doc(base_doc, tag);
|
|
|
|
|
|
|
|
let mut types = subst::VecPerParamSpace::empty();
|
|
|
|
reader::tagged_docs(doc, tag_type_param_def, |p| {
|
|
|
|
let bd = parse_type_param_def_data(
|
|
|
|
p.data, p.start, cdata.cnum, tcx,
|
|
|
|
|_, did| translate_def_id(cdata, did));
|
|
|
|
types.push(bd.space, bd);
|
|
|
|
true
|
|
|
|
});
|
|
|
|
|
|
|
|
let mut regions = subst::VecPerParamSpace::empty();
|
|
|
|
reader::tagged_docs(doc, tag_region_param_def, |rp_doc| {
|
|
|
|
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);
|
|
|
|
let def_id = reader::with_doc_data(def_id_doc, parse_def_id);
|
|
|
|
let def_id = translate_def_id(cdata, def_id);
|
|
|
|
|
|
|
|
let doc = reader::get_doc(rp_doc, tag_region_param_def_space);
|
|
|
|
let space = subst::ParamSpace::from_uint(reader::doc_as_u64(doc) as uint);
|
|
|
|
|
|
|
|
let doc = reader::get_doc(rp_doc, tag_region_param_def_index);
|
|
|
|
let index = reader::doc_as_u64(doc) as uint;
|
|
|
|
|
|
|
|
let mut bounds = Vec::new();
|
|
|
|
reader::tagged_docs(rp_doc, tag_items_data_region, |p| {
|
|
|
|
bounds.push(
|
|
|
|
parse_region_data(
|
|
|
|
p.data, cdata.cnum, p.start, tcx,
|
|
|
|
|_, did| translate_def_id(cdata, did)));
|
|
|
|
true
|
|
|
|
});
|
|
|
|
|
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 });
|
|
|
|
|
|
|
|
true
|
|
|
|
});
|
|
|
|
|
|
|
|
ty::Generics { types: types, regions: regions }
|
|
|
|
}
|
2014-08-06 04:44:21 +02:00
|
|
|
|
|
|
|
pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
|
|
|
|
let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
|
|
|
|
match maybe_find_item(id, items) {
|
|
|
|
None => false,
|
|
|
|
Some(item) => item_sort(item) == 't',
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|