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
|
|
|
use self::Family::*;
|
|
|
|
|
2015-11-24 23:00:26 +01:00
|
|
|
use cstore::{self, crate_metadata};
|
|
|
|
use common::*;
|
|
|
|
use encoder::def_to_u64;
|
|
|
|
use index;
|
2015-12-08 21:53:19 +01:00
|
|
|
use tls_context;
|
2015-11-24 23:00:26 +01:00
|
|
|
use tydecode::TyDecoder;
|
|
|
|
|
|
|
|
use rustc::back::svh::Svh;
|
|
|
|
use rustc::front::map as hir_map;
|
|
|
|
use rustc::util::nodemap::FnvHashMap;
|
2015-07-31 09:04:06 +02:00
|
|
|
use rustc_front::hir;
|
|
|
|
|
2015-11-24 23:00:26 +01:00
|
|
|
use middle::cstore::{LOCAL_CRATE, FoundAst, InlinedItem, LinkagePreference};
|
2015-12-08 21:53:19 +01:00
|
|
|
use middle::cstore::{DefLike, DlDef, DlField, DlImpl, tls};
|
2016-01-20 20:31:10 +01:00
|
|
|
use middle::def::Def;
|
2015-09-17 20:29:59 +02:00
|
|
|
use middle::def_id::{DefId, DefIndex};
|
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};
|
2016-01-17 20:57:54 +01:00
|
|
|
use middle::ty::{self, Ty, TypeFoldable, VariantKind};
|
2013-07-23 01:40:31 +02:00
|
|
|
|
2015-12-08 21:53:19 +01:00
|
|
|
use rustc::mir;
|
|
|
|
use rustc::mir::visit::MutVisitor;
|
|
|
|
|
2015-12-22 22:39:33 +01:00
|
|
|
use std::cell::Cell;
|
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;
|
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-09-14 11:58:20 +02: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;
|
2013-08-22 02:26:33 +02:00
|
|
|
use syntax::ast;
|
2016-02-05 13:13:36 +01:00
|
|
|
use syntax::abi::Abi;
|
2016-01-29 08:22:55 +01:00
|
|
|
use syntax::codemap::{self, Span, BytePos, NO_EXPANSION};
|
2015-09-14 11:58:20 +02:00
|
|
|
use syntax::print::pprust;
|
2014-09-07 19:09:06 +02:00
|
|
|
use syntax::ptr::P;
|
2011-06-28 00:53:27 +02:00
|
|
|
|
2015-07-31 09:04:06 +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
|
|
|
|
2015-09-03 00:22:31 +02:00
|
|
|
impl crate_metadata {
|
2015-09-17 20:29:59 +02:00
|
|
|
fn get_item(&self, item_id: DefIndex) -> Option<rbml::Doc> {
|
2015-09-03 00:22:31 +02:00
|
|
|
self.index.lookup_item(self.data(), item_id).map(|pos| {
|
|
|
|
reader::doc_at(self.data(), pos as usize).unwrap().doc
|
|
|
|
})
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
fn lookup_item(&self, item_id: DefIndex) -> rbml::Doc {
|
2015-09-03 00:22:31 +02:00
|
|
|
match self.get_item(item_id) {
|
2015-09-17 20:29:59 +02:00
|
|
|
None => panic!("lookup_item: id not found: {:?}", item_id),
|
2015-09-03 00:22:31 +02:00
|
|
|
Some(d) => d
|
|
|
|
}
|
2013-06-11 11:40:10 +02:00
|
|
|
}
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2015-09-03 00:22:31 +02:00
|
|
|
pub fn load_index(data: &[u8]) -> index::Index {
|
|
|
|
let index = reader::get_doc(rbml::Doc::new(data), tag_index);
|
2015-09-17 20:29:59 +02:00
|
|
|
index::Index::from_rbml(index)
|
2011-06-28 00:53:27 +02:00
|
|
|
}
|
|
|
|
|
2015-09-28 06:31:45 +02:00
|
|
|
pub fn crate_rustc_version(data: &[u8]) -> Option<String> {
|
|
|
|
let doc = rbml::Doc::new(data);
|
|
|
|
reader::maybe_get_doc(doc, tag_rustc_version).map(|s| s.as_str())
|
|
|
|
}
|
|
|
|
|
2015-09-17 15:04:18 +02:00
|
|
|
pub fn load_xrefs(data: &[u8]) -> index::DenseIndex {
|
|
|
|
let index = reader::get_doc(rbml::Doc::new(data), tag_xref_index);
|
|
|
|
index::DenseIndex::from_buf(index.data, index.start, index.end)
|
|
|
|
}
|
|
|
|
|
2016-01-17 20:57:54 +01:00
|
|
|
#[derive(Clone, Copy, 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
|
|
|
|
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
|
2016-01-17 20:57:54 +01:00
|
|
|
Variant(VariantKind), // V, v, w
|
2012-08-23 02:58:05 +02:00
|
|
|
Impl, // i
|
2016-01-14 12:26:50 +01:00
|
|
|
DefaultImpl, // d
|
2012-08-23 02:58:05 +02:00
|
|
|
Trait, // I
|
2016-01-17 20:57:54 +01:00
|
|
|
Struct(VariantKind), // S, s, u
|
2012-08-23 02:58:05 +02:00
|
|
|
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,
|
|
|
|
'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,
|
2016-01-17 20:57:54 +01:00
|
|
|
'V' => Variant(VariantKind::Struct),
|
|
|
|
'v' => Variant(VariantKind::Tuple),
|
|
|
|
'w' => Variant(VariantKind::Unit),
|
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,
|
2016-01-17 20:57:54 +01:00
|
|
|
'S' => Struct(VariantKind::Struct),
|
|
|
|
's' => Struct(VariantKind::Tuple),
|
|
|
|
'u' => Struct(VariantKind::Unit),
|
2012-08-23 02:58:05 +02:00
|
|
|
'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
|
|
|
}
|
|
|
|
|
2015-07-31 09:04:06 +02:00
|
|
|
fn item_visibility(item: rbml::Doc) -> hir::Visibility {
|
2013-03-20 22:38:57 +01:00
|
|
|
match reader::maybe_get_doc(item, tag_items_data_item_visibility) {
|
2015-07-31 09:04:06 +02:00
|
|
|
None => hir::Public,
|
2013-03-20 22:38:57 +01:00
|
|
|
Some(visibility_doc) => {
|
|
|
|
match reader::doc_as_u8(visibility_doc) as char {
|
2015-07-31 09:04:06 +02:00
|
|
|
'y' => hir::Public,
|
|
|
|
'i' => hir::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-07-31 09:04:06 +02:00
|
|
|
fn fn_constness(item: rbml::Doc) -> hir::Constness {
|
2015-02-25 21:06:08 +01:00
|
|
|
match reader::maybe_get_doc(item, tag_items_data_item_constness) {
|
2015-07-31 09:04:06 +02:00
|
|
|
None => hir::Constness::NotConst,
|
2015-02-25 21:06:08 +01:00
|
|
|
Some(constness_doc) => {
|
|
|
|
match reader::doc_as_u8(constness_doc) as char {
|
2015-07-31 09:04:06 +02:00
|
|
|
'c' => hir::Constness::Const,
|
|
|
|
'n' => hir::Constness::NotConst,
|
2015-02-25 21:06:08 +01:00
|
|
|
_ => 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-09-17 20:29:59 +02:00
|
|
|
let index = DefIndex::new((id & 0xFFFF_FFFF) as usize);
|
|
|
|
let def_id = DefId { krate: (id >> 32) as u32, index: index };
|
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-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,
|
2015-09-17 20:29:59 +02:00
|
|
|
&mut |did| translate_def_id(cdata, did))
|
2015-08-16 03:35:49 +02:00
|
|
|
.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,
|
2015-09-17 20:29:59 +02:00
|
|
|
&mut |did| translate_def_id(cdata, did))
|
2015-08-16 03:35:49 +02:00
|
|
|
.parse_ty()
|
2015-05-26 16:12:39 +02: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,
|
2015-09-17 20:29:59 +02:00
|
|
|
&mut |did| translate_def_id(cdata, did))
|
2015-08-16 03:35:49 +02:00
|
|
|
.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
|
|
|
}
|
|
|
|
|
2015-09-11 17:29:17 +02:00
|
|
|
fn item_path(item_doc: rbml::Doc) -> Vec<hir_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-09-11 17:29:17 +02:00
|
|
|
Some(hir_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-09-11 17:29:17 +02:00
|
|
|
Some(hir_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
|
|
|
}
|
|
|
|
|
2016-01-17 20:57:54 +01:00
|
|
|
fn family_to_variant_kind<'tcx>(family: Family) -> Option<ty::VariantKind> {
|
|
|
|
match family {
|
|
|
|
Struct(VariantKind::Struct) | Variant(VariantKind::Struct) =>
|
|
|
|
Some(ty::VariantKind::Struct),
|
|
|
|
Struct(VariantKind::Tuple) | Variant(VariantKind::Tuple) =>
|
|
|
|
Some(ty::VariantKind::Tuple),
|
|
|
|
Struct(VariantKind::Unit) | Variant(VariantKind::Unit) =>
|
|
|
|
Some(ty::VariantKind::Unit),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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.
|
2015-09-30 21:28:27 +02:00
|
|
|
match item_sort(item) {
|
|
|
|
Some('C') | Some('c') => {
|
2016-01-20 20:31:10 +01:00
|
|
|
DlDef(Def::AssociatedConst(did))
|
2015-09-30 21:28:27 +02:00
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
// Regular const item.
|
2016-01-20 20:31:10 +01:00
|
|
|
DlDef(Def::Const(did))
|
2015-09-30 21:28:27 +02:00
|
|
|
}
|
2015-03-16 02:35:25 +01:00
|
|
|
}
|
|
|
|
}
|
2016-01-20 20:31:10 +01:00
|
|
|
ImmStatic => DlDef(Def::Static(did, false)),
|
|
|
|
MutStatic => DlDef(Def::Static(did, true)),
|
|
|
|
Struct(..) => DlDef(Def::Struct(did)),
|
|
|
|
Fn => DlDef(Def::Fn(did)),
|
2014-10-16 06:44:24 +02:00
|
|
|
Method | StaticMethod => {
|
2016-01-20 20:31:10 +01:00
|
|
|
DlDef(Def::Method(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);
|
2016-01-20 20:31:10 +01:00
|
|
|
DlDef(Def::AssociatedTy(trait_did, did))
|
2015-01-30 11:16:59 +01:00
|
|
|
} else {
|
2016-01-20 20:31:10 +01:00
|
|
|
DlDef(Def::TyAlias(did))
|
2015-01-30 11:16:59 +01:00
|
|
|
}
|
|
|
|
}
|
2016-01-20 20:31:10 +01:00
|
|
|
Mod => DlDef(Def::Mod(did)),
|
|
|
|
ForeignMod => DlDef(Def::ForeignMod(did)),
|
2016-01-17 20:57:54 +01:00
|
|
|
Variant(..) => {
|
2015-05-12 06:49:15 +02:00
|
|
|
let enum_did = item_require_parent_item(cdata, item);
|
2016-01-20 20:31:10 +01:00
|
|
|
DlDef(Def::Variant(enum_did, did))
|
2012-10-13 02:00:08 +02:00
|
|
|
}
|
2016-01-20 20:31:10 +01:00
|
|
|
Trait => DlDef(Def::Trait(did)),
|
|
|
|
Enum => DlDef(Def::Enum(did)),
|
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
|
|
|
}
|
|
|
|
|
2015-07-31 09:04:06 +02:00
|
|
|
fn parse_unsafety(item_doc: rbml::Doc) -> hir::Unsafety {
|
2014-12-10 12:15:06 +01:00
|
|
|
let unsafety_doc = reader::get_doc(item_doc, tag_unsafety);
|
|
|
|
if reader::doc_as_u8(unsafety_doc) != 0 {
|
2015-07-31 09:04:06 +02:00
|
|
|
hir::Unsafety::Unsafe
|
2014-12-10 12:15:06 +01:00
|
|
|
} else {
|
2015-07-31 09:04:06 +02:00
|
|
|
hir::Unsafety::Normal
|
2014-12-10 12:15:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-07-31 09:04:06 +02:00
|
|
|
fn parse_polarity(item_doc: rbml::Doc) -> hir::ImplPolarity {
|
2015-01-07 19:26:51 +01:00
|
|
|
let polarity_doc = reader::get_doc(item_doc, tag_polarity);
|
|
|
|
if reader::doc_as_u8(polarity_doc) != 0 {
|
2015-07-31 09:04:06 +02:00
|
|
|
hir::ImplPolarity::Negative
|
2015-01-07 19:26:51 +01:00
|
|
|
} else {
|
2015-07-31 09:04:06 +02:00
|
|
|
hir::ImplPolarity::Positive
|
2015-01-07 19:26:51 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
item_id: DefIndex,
|
2014-09-29 21:11:30 +02:00
|
|
|
tcx: &ty::ctxt<'tcx>) -> ty::TraitDef<'tcx>
|
2013-03-27 11:16:28 +01:00
|
|
|
{
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(item_id);
|
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
|
|
|
|
2015-12-22 22:39:33 +01:00
|
|
|
ty::TraitDef::new(unsafety,
|
|
|
|
paren_sugar,
|
|
|
|
generics,
|
|
|
|
item_trait_ref(item_doc, tcx, cdata),
|
|
|
|
associated_type_names)
|
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-09-17 20:29:59 +02:00
|
|
|
item_id: DefIndex,
|
2015-08-07 13:41:33 +02:00
|
|
|
tcx: &ty::ctxt<'tcx>) -> ty::AdtDefMaster<'tcx>
|
2015-07-20 21:13:36 +02:00
|
|
|
{
|
2016-01-17 20:57:54 +01:00
|
|
|
fn expect_variant_kind<'tcx>(family: Family, tcx: &ty::ctxt<'tcx>) -> ty::VariantKind {
|
|
|
|
match family_to_variant_kind(family) {
|
|
|
|
Some(kind) => kind,
|
2016-01-14 12:26:50 +01:00
|
|
|
_ => tcx.sess.bug(&format!("unexpected family: {:?}", family)),
|
|
|
|
}
|
|
|
|
}
|
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);
|
2015-09-17 20:29:59 +02:00
|
|
|
let item = cdata.lookup_item(did.index);
|
2015-07-22 20:53:52 +02:00
|
|
|
|
|
|
|
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),
|
2016-01-14 12:26:50 +01:00
|
|
|
disr_val: disr,
|
2016-01-17 20:57:54 +01:00
|
|
|
kind: expect_variant_kind(item_family(item), tcx),
|
2015-07-22 20:53:52 +02:00
|
|
|
}
|
|
|
|
}).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),
|
2016-01-14 12:26:50 +01:00
|
|
|
disr_val: 0,
|
2016-01-17 20:57:54 +01:00
|
|
|
kind: expect_variant_kind(item_family(doc), tcx),
|
2015-07-22 20:53:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-03 00:22:31 +02:00
|
|
|
let doc = cdata.lookup_item(item_id);
|
2015-09-17 20:29:59 +02:00
|
|
|
let did = DefId { krate: cdata.cnum, index: item_id };
|
2015-07-22 20:53:52 +02:00
|
|
|
let (kind, variants) = match item_family(doc) {
|
2015-10-02 15:12:20 +02:00
|
|
|
Enum => {
|
|
|
|
(ty::AdtKind::Enum,
|
|
|
|
get_enum_variants(intr, cdata, doc, tcx))
|
|
|
|
}
|
2016-01-17 20:57:54 +01:00
|
|
|
Struct(..) => {
|
2015-10-02 15:12:20 +02:00
|
|
|
let ctor_did =
|
|
|
|
reader::maybe_get_doc(doc, tag_items_data_item_struct_ctor).
|
|
|
|
map_or(did, |ctor_doc| translated_def_id(cdata, ctor_doc));
|
|
|
|
(ty::AdtKind::Struct,
|
2015-10-07 19:30:48 +02:00
|
|
|
vec![get_struct_variant(intr, cdata, doc, ctor_did, tcx)])
|
2015-10-02 15:12:20 +02:00
|
|
|
}
|
|
|
|
_ => tcx.sess.bug(
|
|
|
|
&format!("get_adt_def called on a non-ADT {:?} - {:?}",
|
|
|
|
item_family(doc), did))
|
2015-07-22 20:53:52 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
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);
|
2015-09-17 20:29:59 +02:00
|
|
|
let ctor_ty = get_type(cdata, variant.did.index, tcx).ty;
|
2015-07-22 20:53:52 +02:00
|
|
|
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);
|
2015-09-17 20:29:59 +02:00
|
|
|
let ty = get_type(cdata, field.did.index, tcx).ty;
|
2015-07-22 20:53:52 +02:00
|
|
|
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-09-17 20:29:59 +02:00
|
|
|
item_id: DefIndex,
|
2015-02-11 22:55:22 +01:00
|
|
|
tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> ty::GenericPredicates<'tcx>
|
2015-02-11 11:59:01 +01:00
|
|
|
{
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(item_id);
|
2015-02-11 11:59:01 +01:00
|
|
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
item_id: DefIndex,
|
2015-02-24 15:24:42 +01:00
|
|
|
tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> ty::GenericPredicates<'tcx>
|
|
|
|
{
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(item_id);
|
2015-02-24 15:24:42 +01:00
|
|
|
doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates)
|
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_type<'tcx>(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt<'tcx>)
|
2015-02-11 11:59:01 +01:00
|
|
|
-> ty::TypeScheme<'tcx>
|
|
|
|
{
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
2015-09-17 20:29:59 +02:00
|
|
|
let t = item_type(DefId { krate: cdata.cnum, index: 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
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_stability(cdata: Cmd, id: DefIndex) -> Option<attr::Stability> {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item = cdata.lookup_item(id);
|
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
|
|
|
reader::maybe_get_doc(item, tag_items_data_item_stability).map(|doc| {
|
|
|
|
let mut decoder = reader::Decoder::new(doc);
|
|
|
|
Decodable::decode(&mut decoder).unwrap()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-12-04 17:34:28 +01:00
|
|
|
pub fn get_deprecation(cdata: Cmd, id: DefIndex) -> Option<attr::Deprecation> {
|
|
|
|
let item = cdata.lookup_item(id);
|
|
|
|
reader::maybe_get_doc(item, tag_items_data_item_deprecation).map(|doc| {
|
|
|
|
let mut decoder = reader::Decoder::new(doc);
|
|
|
|
Decodable::decode(&mut decoder).unwrap()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_repr_attrs(cdata: Cmd, id: DefIndex) -> Vec<attr::ReprAttr> {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item = cdata.lookup_item(id);
|
2014-09-30 06:52:06 +02:00
|
|
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
id: DefIndex)
|
2015-07-31 09:04:06 +02:00
|
|
|
-> Option<hir::ImplPolarity>
|
2015-01-07 19:26:51 +01:00
|
|
|
{
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
2015-01-07 19:26:51 +01:00
|
|
|
let fam = item_family(item_doc);
|
|
|
|
match fam {
|
|
|
|
Family::Impl => {
|
|
|
|
Some(parse_polarity(item_doc))
|
|
|
|
}
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-14 13:55:56 +02:00
|
|
|
pub fn get_custom_coerce_unsized_kind<'tcx>(
|
|
|
|
cdata: Cmd,
|
2015-09-17 20:29:59 +02:00
|
|
|
id: DefIndex)
|
2015-09-14 13:55:56 +02:00
|
|
|
-> Option<ty::adjustment::CustomCoerceUnsized>
|
|
|
|
{
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
2015-04-15 01:57:29 +02:00
|
|
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
id: DefIndex,
|
2014-09-29 21:11:30 +02:00
|
|
|
tcx: &ty::ctxt<'tcx>)
|
2015-04-21 17:59:58 +02:00
|
|
|
-> Option<ty::TraitRef<'tcx>>
|
2013-03-27 11:16:28 +01:00
|
|
|
{
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
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
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_symbol(cdata: Cmd, id: DefIndex) -> String {
|
2015-09-03 00:22:31 +02:00
|
|
|
return item_symbol(cdata.lookup_item(id));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// If you have a crate_metadata, call get_symbol instead
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_symbol_from_buf(data: &[u8], id: DefIndex) -> String {
|
2015-09-03 00:22:31 +02:00
|
|
|
let index = load_index(data);
|
|
|
|
let pos = index.lookup_item(data, id).unwrap();
|
|
|
|
let doc = reader::doc_at(data, pos as usize).unwrap().doc;
|
|
|
|
item_symbol(doc)
|
2011-06-28 00:53:27 +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-09-17 20:29:59 +02:00
|
|
|
F: FnMut(DefIndex, 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;
|
2015-09-17 20:29:59 +02:00
|
|
|
let index_doc = reader::get_doc(item_doc, tag_lang_items_item_index);
|
|
|
|
let index = DefIndex::from_u32(reader::doc_as_u32(index_doc));
|
2013-05-03 19:08:08 +02:00
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
f(index, 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
|
2015-07-31 09:04:06 +02:00
|
|
|
F: FnMut(DefLike, ast::Name, hir::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
|
|
|
};
|
|
|
|
|
|
|
|
// Get the item.
|
2015-09-17 20:29:59 +02:00
|
|
|
match crate_data.get_item(child_def_id.index) {
|
2013-08-22 02:26:33 +02:00
|
|
|
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);
|
2015-09-17 20:29:59 +02:00
|
|
|
if let Some(inherent_impl_doc) = cdata.get_item(inherent_impl_def_id.index) {
|
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);
|
2015-09-17 20:29:59 +02:00
|
|
|
if let Some(impl_method_doc) = cdata.get_item(impl_item_def_id.index) {
|
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
|
|
|
};
|
|
|
|
|
|
|
|
// Get the item.
|
2015-09-17 20:29:59 +02:00
|
|
|
if let Some(child_item_doc) = crate_data.get_item(child_def_id.index) {
|
2014-11-29 22:41:21 +01:00
|
|
|
// 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.
|
2015-07-31 09:04:06 +02:00
|
|
|
callback(def_like, token::intern(name), hir::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,
|
2015-09-17 20:29:59 +02:00
|
|
|
id: DefIndex,
|
2014-12-31 04:48:22 +01:00
|
|
|
get_crate_data: G,
|
|
|
|
callback: F) where
|
2015-07-31 09:04:06 +02:00
|
|
|
F: FnMut(DefLike, ast::Name, hir::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.
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = match cdata.get_item(id) {
|
2013-08-22 02:26:33 +02:00
|
|
|
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
|
2015-07-31 09:04:06 +02:00
|
|
|
F: FnMut(DefLike, ast::Name, hir::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
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_item_path(cdata: Cmd, id: DefIndex) -> Vec<hir_map::PathElem> {
|
2015-09-03 00:22:31 +02:00
|
|
|
item_path(cdata.lookup_item(id))
|
2012-02-10 15:01:32 +01:00
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: DefIndex) -> ast::Name {
|
2015-09-03 00:22:31 +02:00
|
|
|
item_name(intr, cdata.lookup_item(id))
|
2015-08-12 20:22:25 +02:00
|
|
|
}
|
|
|
|
|
2015-01-04 15:07:13 +01:00
|
|
|
pub type DecodeInlinedItem<'a> =
|
|
|
|
Box<for<'tcx> FnMut(Cmd,
|
|
|
|
&ty::ctxt<'tcx>,
|
2015-12-22 16:27:20 +01:00
|
|
|
Vec<hir_map::PathElem>, // parent_path
|
|
|
|
hir_map::DefPath, // parent_def_path
|
2015-10-02 15:12:20 +02:00
|
|
|
rbml::Doc,
|
|
|
|
DefId)
|
2015-09-17 20:29:59 +02:00
|
|
|
-> Result<&'tcx InlinedItem, (Vec<hir_map::PathElem>,
|
|
|
|
hir_map::DefPath)> + 'a>;
|
2012-05-15 02:46:45 +02:00
|
|
|
|
2015-12-22 16:27:20 +01:00
|
|
|
pub fn maybe_get_item_ast<'tcx>(cdata: Cmd,
|
|
|
|
tcx: &ty::ctxt<'tcx>,
|
|
|
|
id: DefIndex,
|
2015-01-04 15:07:13 +01:00
|
|
|
mut decode_inlined_item: DecodeInlinedItem)
|
2015-11-21 20:39:05 +01:00
|
|
|
-> FoundAst<'tcx> {
|
2015-09-17 20:29:59 +02:00
|
|
|
debug!("Looking up item: {:?}", id);
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
2015-10-02 15:12:20 +02:00
|
|
|
let item_did = item_def_id(item_doc, cdata);
|
2015-12-22 16:27:20 +01:00
|
|
|
let parent_path = {
|
|
|
|
let mut path = item_path(item_doc);
|
|
|
|
path.pop();
|
|
|
|
path
|
|
|
|
};
|
|
|
|
let parent_def_path = {
|
|
|
|
let mut def_path = def_path(cdata, id);
|
|
|
|
def_path.pop();
|
|
|
|
def_path
|
|
|
|
};
|
|
|
|
match decode_inlined_item(cdata,
|
|
|
|
tcx,
|
|
|
|
parent_path,
|
|
|
|
parent_def_path,
|
|
|
|
item_doc,
|
|
|
|
item_did) {
|
2015-11-21 20:39:05 +01:00
|
|
|
Ok(ii) => FoundAst::Found(ii),
|
2015-12-22 16:27:20 +01:00
|
|
|
Err((mut parent_path, mut parent_def_path)) => {
|
2015-05-12 06:49:15 +02:00
|
|
|
match item_parent_item(cdata, item_doc) {
|
2015-12-22 16:27:20 +01:00
|
|
|
Some(parent_did) => {
|
|
|
|
// Remove the last element from the paths, since we are now
|
|
|
|
// trying to inline the parent.
|
|
|
|
parent_path.pop();
|
|
|
|
parent_def_path.pop();
|
|
|
|
|
|
|
|
let parent_item = cdata.lookup_item(parent_did.index);
|
|
|
|
match decode_inlined_item(cdata,
|
|
|
|
tcx,
|
|
|
|
parent_path,
|
|
|
|
parent_def_path,
|
|
|
|
parent_item,
|
|
|
|
parent_did) {
|
|
|
|
Ok(ii) => FoundAst::FoundParent(parent_did, ii),
|
2015-11-21 20:39:05 +01:00
|
|
|
Err(_) => FoundAst::NotFound
|
2014-02-14 06:07:09 +01:00
|
|
|
}
|
|
|
|
}
|
2015-11-21 20:39:05 +01:00
|
|
|
None => FoundAst::NotFound
|
2012-03-08 23:13:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-02-15 00:21:53 +01:00
|
|
|
}
|
|
|
|
|
2015-11-02 14:46:39 +01:00
|
|
|
pub fn is_item_mir_available<'tcx>(cdata: Cmd, id: DefIndex) -> bool {
|
|
|
|
if let Some(item_doc) = cdata.get_item(id) {
|
|
|
|
return reader::maybe_get_doc(item_doc, tag_mir as usize).is_some();
|
|
|
|
}
|
|
|
|
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
2015-12-08 21:53:19 +01:00
|
|
|
pub fn maybe_get_item_mir<'tcx>(cdata: Cmd,
|
|
|
|
tcx: &ty::ctxt<'tcx>,
|
|
|
|
id: DefIndex)
|
|
|
|
-> Option<mir::repr::Mir<'tcx>> {
|
|
|
|
let item_doc = cdata.lookup_item(id);
|
|
|
|
|
|
|
|
return reader::maybe_get_doc(item_doc, tag_mir as usize).map(|mir_doc| {
|
|
|
|
let dcx = tls_context::DecodingContext {
|
|
|
|
crate_metadata: cdata,
|
|
|
|
tcx: tcx,
|
|
|
|
};
|
|
|
|
let mut decoder = reader::Decoder::new(mir_doc);
|
|
|
|
|
2015-12-25 19:59:02 +01:00
|
|
|
let mut mir = decoder.read_opaque(|opaque_decoder, _| {
|
|
|
|
tls::enter_decoding_context(&dcx, opaque_decoder, |_, opaque_decoder| {
|
|
|
|
Decodable::decode(opaque_decoder)
|
|
|
|
})
|
|
|
|
}).unwrap();
|
2015-12-08 21:53:19 +01:00
|
|
|
|
2015-11-02 14:46:39 +01:00
|
|
|
assert!(decoder.position() == mir_doc.end);
|
|
|
|
|
2015-12-08 21:53:19 +01:00
|
|
|
let mut def_id_and_span_translator = MirDefIdAndSpanTranslator {
|
|
|
|
crate_metadata: cdata,
|
|
|
|
codemap: tcx.sess.codemap(),
|
|
|
|
last_filemap_index_hint: Cell::new(0),
|
|
|
|
};
|
|
|
|
|
|
|
|
def_id_and_span_translator.visit_mir(&mut mir);
|
|
|
|
|
|
|
|
mir
|
|
|
|
});
|
|
|
|
|
|
|
|
struct MirDefIdAndSpanTranslator<'cdata, 'codemap> {
|
|
|
|
crate_metadata: Cmd<'cdata>,
|
|
|
|
codemap: &'codemap codemap::CodeMap,
|
|
|
|
last_filemap_index_hint: Cell<usize>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'v, 'cdata, 'codemap> mir::visit::MutVisitor<'v>
|
|
|
|
for MirDefIdAndSpanTranslator<'cdata, 'codemap>
|
|
|
|
{
|
|
|
|
fn visit_def_id(&mut self, def_id: &mut DefId) {
|
|
|
|
*def_id = translate_def_id(self.crate_metadata, *def_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_span(&mut self, span: &mut Span) {
|
|
|
|
*span = translate_span(self.crate_metadata,
|
|
|
|
self.codemap,
|
|
|
|
&self.last_filemap_index_hint,
|
|
|
|
*span);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-30 02:06:37 +02:00
|
|
|
fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
|
2015-07-31 09:04:06 +02:00
|
|
|
fn get_mutability(ch: u8) -> hir::Mutability {
|
2012-08-06 21:34:08 +02:00
|
|
|
match ch as char {
|
2015-07-31 09:04:06 +02:00
|
|
|
'i' => hir::MutImmutable,
|
|
|
|
'm' => hir::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 {
|
2015-12-28 12:52:43 +01:00
|
|
|
's' => ty::ExplicitSelfCategory::Static,
|
|
|
|
'v' => ty::ExplicitSelfCategory::ByValue,
|
|
|
|
'~' => ty::ExplicitSelfCategory::ByBox,
|
2014-01-09 14:05:33 +01:00
|
|
|
// FIXME(#4846) expl. region
|
2014-05-07 01:37:32 +02:00
|
|
|
'&' => {
|
2015-12-28 12:52:43 +01:00
|
|
|
ty::ExplicitSelfCategory::ByReference(
|
2014-05-07 01:37:32 +02:00
|
|
|
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.
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_impl_items(cdata: Cmd, impl_id: DefIndex)
|
2014-08-04 22:56:56 +02:00
|
|
|
-> Vec<ty::ImplOrTraitItemId> {
|
2015-09-03 00:22:31 +02:00
|
|
|
reader::tagged_docs(cdata.lookup_item(impl_id), 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-09-30 21:28:27 +02:00
|
|
|
Some('C') | Some('c') => ty::ConstTraitItemId(def_id),
|
2015-05-24 12:23:29 +02:00
|
|
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
id: DefIndex)
|
2014-11-23 10:29:41 +01:00
|
|
|
-> ast::Name {
|
2015-09-03 00:22:31 +02:00
|
|
|
let doc = cdata.lookup_item(id);
|
2014-11-23 10:29:41 +01:00
|
|
|
item_name(&*intr, doc)
|
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn is_static_method(cdata: Cmd, id: DefIndex) -> bool {
|
2015-09-03 00:22:31 +02:00
|
|
|
let doc = cdata.lookup_item(id);
|
2014-08-04 22:56:56 +02:00
|
|
|
match item_sort(doc) {
|
2015-01-30 11:16:59 +01:00
|
|
|
Some('r') | Some('p') => {
|
2015-12-28 12:52:43 +01:00
|
|
|
get_explicit_self(doc) == ty::ExplicitSelfCategory::Static
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
id: DefIndex,
|
2014-09-29 21:11:30 +02:00
|
|
|
tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> ty::ImplOrTraitItem<'tcx> {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
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);
|
2015-09-17 20:29:59 +02:00
|
|
|
let container_doc = cdata.lookup_item(container_id.index);
|
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-09-30 21:28:27 +02:00
|
|
|
sort @ Some('C') | sort @ Some('c') => {
|
2015-05-26 16:12:39 +02:00
|
|
|
let ty = doc_type(item_doc, tcx, 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,
|
2015-09-30 21:28:27 +02:00
|
|
|
has_value: sort == Some('C')
|
2015-03-16 02:35:25 +01:00
|
|
|
}))
|
|
|
|
}
|
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);
|
2015-09-20 13:15:21 +02:00
|
|
|
let ity = tcx.lookup_item_type(def_id).ty;
|
|
|
|
let fty = match ity.sty {
|
|
|
|
ty::TyBareFn(_, fty) => fty.clone(),
|
|
|
|
_ => tcx.sess.bug(&format!(
|
|
|
|
"the type {:?} of the method {:?} is not a function?",
|
|
|
|
ity, name))
|
|
|
|
};
|
2015-05-26 16:12:39 +02:00
|
|
|
let explicit_self = get_explicit_self(item_doc);
|
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,
|
2015-09-30 21:28:27 +02:00
|
|
|
container)))
|
2014-08-04 22:56:56 +02:00
|
|
|
}
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_trait_item_def_ids(cdata: Cmd, id: DefIndex)
|
2014-08-04 22:56:56 +02:00
|
|
|
-> Vec<ty::ImplOrTraitItemId> {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item = cdata.lookup_item(id);
|
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-09-30 21:28:27 +02:00
|
|
|
Some('C') | Some('c') => ty::ConstTraitItemId(def_id),
|
2015-05-24 12:23:29 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> ty::ItemVariances {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
2013-10-29 11:08:34 +01:00
|
|
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
id: DefIndex,
|
2014-09-29 21:11:30 +02:00
|
|
|
tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> Vec<Rc<ty::Method<'tcx>>> {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item = cdata.lookup_item(id);
|
2012-10-08 21:39:30 +02:00
|
|
|
|
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);
|
2015-09-17 20:29:59 +02:00
|
|
|
let mth = cdata.lookup_item(did.index);
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
did.index,
|
2014-08-04 22:56:56 +02:00
|
|
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
id: DefIndex,
|
2015-03-16 02:35:25 +01:00
|
|
|
tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> Vec<Rc<ty::AssociatedConst<'tcx>>> {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item = cdata.lookup_item(id);
|
2015-03-16 02:35:25 +01:00
|
|
|
|
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);
|
2015-09-17 20:29:59 +02:00
|
|
|
let ac_doc = cdata.lookup_item(did.index);
|
2015-03-21 22:06:28 +01:00
|
|
|
|
2015-09-30 21:28:27 +02:00
|
|
|
match item_sort(ac_doc) {
|
|
|
|
Some('C') | Some('c') => {
|
|
|
|
let trait_item = get_impl_or_trait_item(intr.clone(),
|
|
|
|
cdata,
|
2015-09-17 20:29:59 +02:00
|
|
|
did.index,
|
2015-09-30 21:28:27 +02:00
|
|
|
tcx);
|
|
|
|
if let ty::ConstTraitItem(ref ac) = trait_item {
|
|
|
|
Some((*ac).clone())
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2015-03-21 22:06:28 +01:00
|
|
|
}
|
2015-09-30 21:28:27 +02:00
|
|
|
_ => 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
|
|
|
}
|
|
|
|
|
2016-01-17 20:57:54 +01:00
|
|
|
pub fn get_variant_kind(cdata: Cmd, node_id: DefIndex) -> Option<VariantKind>
|
|
|
|
{
|
|
|
|
let item = cdata.lookup_item(node_id);
|
|
|
|
family_to_variant_kind(item_family(item))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_struct_ctor_def_id(cdata: Cmd, node_id: DefIndex) -> Option<DefId>
|
|
|
|
{
|
|
|
|
let item = cdata.lookup_item(node_id);
|
|
|
|
reader::maybe_get_doc(item, tag_items_data_item_struct_ctor).
|
|
|
|
map(|ctor_doc| translated_def_id(cdata, ctor_doc))
|
|
|
|
}
|
|
|
|
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
node_id: DefIndex)
|
2015-08-16 12:32:28 +02:00
|
|
|
-> Option<DefId>
|
2014-04-01 03:13:44 +02:00
|
|
|
{
|
2015-09-03 00:22:31 +02:00
|
|
|
let item = cdata.lookup_item(node_id);
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
orig_node_id: DefIndex)
|
2015-09-14 11:58:20 +02:00
|
|
|
-> 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);
|
2015-09-17 20:29:59 +02:00
|
|
|
let node_id = node_id.map(|x| x.index).unwrap_or(orig_node_id);
|
2015-09-03 00:22:31 +02:00
|
|
|
let item = cdata.lookup_item(node_id);
|
2015-01-11 17:33:02 +01:00
|
|
|
get_attributes(item)
|
2012-07-26 03:36:18 +02:00
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_struct_field_attrs(cdata: Cmd) -> FnvHashMap<DefId, 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| {
|
2015-09-17 20:29:59 +02:00
|
|
|
let def_id = translated_def_id(cdata, reader::get_doc(field, tag_def_id));
|
2014-07-26 22:21:36 +02:00
|
|
|
let attrs = get_attributes(field);
|
2015-09-17 20:29:59 +02:00
|
|
|
(def_id, attrs)
|
2015-05-24 12:23:29 +02:00
|
|
|
}).collect()
|
2014-07-26 22:21:36 +02:00
|
|
|
}
|
|
|
|
|
2015-07-31 09:04:06 +02:00
|
|
|
fn struct_field_family_to_visibility(family: Family) -> hir::Visibility {
|
2012-12-10 22:47:54 +01:00
|
|
|
match family {
|
2015-07-31 09:04:06 +02:00
|
|
|
PublicField => hir::Public,
|
|
|
|
InheritedField => hir::Inherited,
|
2014-10-09 21:17:22 +02:00
|
|
|
_ => panic!()
|
2012-12-10 22:47:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: DefIndex)
|
2015-08-06 00:55:13 +02:00
|
|
|
-> Vec<ast::Name> {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item = cdata.lookup_item(id);
|
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
|
|
|
}
|
|
|
|
|
2015-09-14 11:58:20 +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());
|
2016-02-09 12:05:20 +01:00
|
|
|
// FIXME (#623): Should be able to decode MetaItemKind::NameValue 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
|
|
|
}
|
|
|
|
|
2015-09-14 11:58:20 +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 {
|
2015-09-14 11:58:20 +02:00
|
|
|
node: ast::Attribute_ {
|
2014-05-20 09:07:24 +02:00
|
|
|
id: attr::mk_attr_id(),
|
2015-10-01 18:03:34 +02:00
|
|
|
style: ast::AttrStyle::Outer,
|
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
|
|
|
}
|
|
|
|
|
2015-09-14 11:58:20 +02: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 {
|
2015-08-16 15:06:23 +02:00
|
|
|
if did.is_local() {
|
2015-09-17 20:29:59 +02:00
|
|
|
return DefId { krate: cdata.cnum, index: did.index };
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
index: did.index,
|
2013-12-22 03:17:29 +01:00
|
|
|
}
|
|
|
|
}
|
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-09-17 20:29:59 +02:00
|
|
|
return Some(DefId { krate: LOCAL_CRATE, index: did.index });
|
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-09-17 20:29:59 +02:00
|
|
|
return Some(DefId { krate: local, index: did.index });
|
2015-05-12 06:56:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
2015-12-01 16:07:15 +01:00
|
|
|
/// Translates a `Span` from an extern crate to the corresponding `Span`
|
|
|
|
/// within the local crate's codemap.
|
|
|
|
pub fn translate_span(cdata: Cmd,
|
|
|
|
codemap: &codemap::CodeMap,
|
|
|
|
last_filemap_index_hint: &Cell<usize>,
|
|
|
|
span: codemap::Span)
|
|
|
|
-> codemap::Span {
|
|
|
|
let span = if span.lo > span.hi {
|
|
|
|
// Currently macro expansion sometimes produces invalid Span values
|
|
|
|
// where lo > hi. In order not to crash the compiler when trying to
|
|
|
|
// translate these values, let's transform them into something we
|
|
|
|
// can handle (and which will produce useful debug locations at
|
|
|
|
// least some of the time).
|
|
|
|
// This workaround is only necessary as long as macro expansion is
|
|
|
|
// not fixed. FIXME(#23480)
|
|
|
|
codemap::mk_sp(span.lo, span.lo)
|
|
|
|
} else {
|
|
|
|
span
|
|
|
|
};
|
|
|
|
|
|
|
|
let imported_filemaps = cdata.imported_filemaps(&codemap);
|
|
|
|
let filemap = {
|
|
|
|
// Optimize for the case that most spans within a translated item
|
|
|
|
// originate from the same filemap.
|
|
|
|
let last_filemap_index = last_filemap_index_hint.get();
|
|
|
|
let last_filemap = &imported_filemaps[last_filemap_index];
|
|
|
|
|
|
|
|
if span.lo >= last_filemap.original_start_pos &&
|
|
|
|
span.lo <= last_filemap.original_end_pos &&
|
|
|
|
span.hi >= last_filemap.original_start_pos &&
|
|
|
|
span.hi <= last_filemap.original_end_pos {
|
|
|
|
last_filemap
|
|
|
|
} else {
|
|
|
|
let mut a = 0;
|
|
|
|
let mut b = imported_filemaps.len();
|
|
|
|
|
|
|
|
while b - a > 1 {
|
|
|
|
let m = (a + b) / 2;
|
|
|
|
if imported_filemaps[m].original_start_pos > span.lo {
|
|
|
|
b = m;
|
|
|
|
} else {
|
|
|
|
a = m;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
last_filemap_index_hint.set(a);
|
|
|
|
&imported_filemaps[a]
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let lo = (span.lo - filemap.original_start_pos) +
|
|
|
|
filemap.translated_filemap.start_pos;
|
|
|
|
let hi = (span.hi - filemap.original_start_pos) +
|
|
|
|
filemap.translated_filemap.start_pos;
|
|
|
|
|
|
|
|
codemap::mk_sp(lo, hi)
|
|
|
|
}
|
|
|
|
|
2015-05-12 06:51:15 +02:00
|
|
|
pub fn each_inherent_implementation_for_type<F>(cdata: Cmd,
|
2015-09-17 20:29:59 +02:00
|
|
|
id: DefIndex,
|
2015-05-12 06:51:15 +02:00
|
|
|
mut callback: F)
|
2015-08-16 12:32:28 +02:00
|
|
|
where F: FnMut(DefId),
|
2014-12-09 02:26:43 +01:00
|
|
|
{
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
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
|
|
|
// 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-10-02 15:44:26 +02:00
|
|
|
for trait_doc in reader::tagged_docs(impls_doc, tag_impls_trait) {
|
|
|
|
let trait_def_id = reader::get_doc(trait_doc, tag_def_id);
|
|
|
|
if reader::doc_as_u64(trait_def_id) != def_id_u64 {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for impl_doc in reader::tagged_docs(trait_doc, tag_impls_trait_impl) {
|
|
|
|
callback(translated_def_id(cdata, impl_doc));
|
2015-05-12 06:56:37 +02:00
|
|
|
}
|
2015-05-24 12:23:29 +02:00
|
|
|
}
|
2015-05-12 06:56:37 +02:00
|
|
|
}
|
2013-08-23 23:34:00 +02:00
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_trait_of_item(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt)
|
2015-08-16 12:32:28 +02:00
|
|
|
-> Option<DefId> {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
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,
|
|
|
|
};
|
2015-09-17 20:29:59 +02:00
|
|
|
let parent_item_doc = cdata.lookup_item(parent_item_id.index);
|
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
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<DefIndex> {
|
2014-07-30 02:06:37 +02:00
|
|
|
reader::maybe_get_doc(rbml::Doc::new(data), tag_plugin_registrar_fn)
|
2015-09-17 20:29:59 +02:00
|
|
|
.map(|doc| DefIndex::from_u32(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
|
2016-01-29 08:22:55 +01:00
|
|
|
F: FnMut(ast::Name, Vec<ast::Attribute>, Span, String) -> bool,
|
2014-12-31 04:10:46 +01:00
|
|
|
{
|
|
|
|
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);
|
2016-01-29 08:22:55 +01:00
|
|
|
let span = get_macro_span(macro_doc);
|
2014-12-31 04:10:46 +01:00
|
|
|
let body = reader::get_doc(macro_doc, tag_macro_def_body);
|
2016-01-29 08:22:55 +01:00
|
|
|
if !f(name, attrs, span, body.as_str().to_string()) {
|
2015-05-24 12:23:29 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-12-25 19:10:33 +01:00
|
|
|
}
|
2014-05-02 09:59:27 +02:00
|
|
|
|
2016-01-29 08:22:55 +01:00
|
|
|
pub fn get_macro_span(doc: rbml::Doc) -> Span {
|
|
|
|
let lo_doc = reader::get_doc(doc, tag_macro_def_span_lo);
|
|
|
|
let lo = BytePos(reader::doc_as_u32(lo_doc));
|
|
|
|
let hi_doc = reader::get_doc(doc, tag_macro_def_span_hi);
|
|
|
|
let hi = BytePos(reader::doc_as_u32(hi_doc));
|
|
|
|
return Span { lo: lo, hi: hi, expn_id: NO_EXPANSION };
|
|
|
|
}
|
|
|
|
|
2014-05-02 09:59:27 +02:00
|
|
|
pub fn get_dylib_dependency_formats(cdata: Cmd)
|
2015-11-24 23:00:26 +01:00
|
|
|
-> Vec<(ast::CrateNum, LinkagePreference)>
|
2014-05-02 09:59:27 +02:00
|
|
|
{
|
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" {
|
2015-11-24 23:00:26 +01:00
|
|
|
LinkagePreference::RequireDynamic
|
2014-05-02 09:59:27 +02:00
|
|
|
} else {
|
2015-11-24 23:00:26 +01:00
|
|
|
LinkagePreference::RequireStatic
|
2014-05-02 09:59:27 +02:00
|
|
|
}));
|
|
|
|
}
|
|
|
|
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
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn get_method_arg_names(cdata: Cmd, id: DefIndex) -> Vec<String> {
|
2015-09-03 00:22:31 +02:00
|
|
|
let method_doc = cdata.lookup_item(id);
|
2014-05-24 02:13:44 +02:00
|
|
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
index: DefIndex::from_u32(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
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn is_typedef(cdata: Cmd, id: DefIndex) -> bool {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
2014-06-09 21:56:37 +02:00
|
|
|
match item_family(item_doc) {
|
|
|
|
Type => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
2014-08-28 03:46:52 +02:00
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn is_const_fn(cdata: Cmd, id: DefIndex) -> bool {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
2015-02-25 21:06:08 +01:00
|
|
|
match fn_constness(item_doc) {
|
2015-07-31 09:04:06 +02:00
|
|
|
hir::Constness::Const => true,
|
|
|
|
hir::Constness::NotConst => false,
|
2015-02-25 21:06:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-07 18:22:04 +01:00
|
|
|
pub fn is_extern_item(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt) -> bool {
|
|
|
|
let item_doc = match cdata.get_item(id) {
|
|
|
|
Some(doc) => doc,
|
|
|
|
None => return false,
|
|
|
|
};
|
|
|
|
let applicable = match item_family(item_doc) {
|
2015-11-06 10:51:03 +01:00
|
|
|
ImmStatic | MutStatic => true,
|
2015-11-07 18:22:04 +01:00
|
|
|
Fn => {
|
|
|
|
let ty::TypeScheme { generics, ty } = get_type(cdata, id, tcx);
|
|
|
|
let no_generics = generics.types.is_empty();
|
|
|
|
match ty.sty {
|
|
|
|
ty::TyBareFn(_, fn_ty) if fn_ty.abi != Abi::Rust => return no_generics,
|
|
|
|
_ => no_generics,
|
|
|
|
}
|
|
|
|
},
|
2015-11-06 10:51:03 +01:00
|
|
|
_ => false,
|
2015-11-07 18:22:04 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
if applicable {
|
2016-01-15 20:43:14 +01:00
|
|
|
attr::contains_extern_indicator(tcx.sess.diagnostic(),
|
|
|
|
&get_attributes(item_doc))
|
2015-11-07 18:22:04 +01:00
|
|
|
} else {
|
|
|
|
false
|
2015-11-06 10:51:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
|
2015-09-03 00:22:31 +02:00
|
|
|
let item_doc = cdata.lookup_item(id);
|
2015-05-25 23:41:27 +02:00
|
|
|
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,
|
2015-09-17 20:29:59 +02:00
|
|
|
&mut |did| translate_def_id(cdata, did))
|
2015-08-16 03:35:49 +02:00
|
|
|
.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,
|
2015-09-17 20:29:59 +02:00
|
|
|
&mut |did| translate_def_id(cdata, did))
|
2015-08-16 03:35:49 +02:00
|
|
|
.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 }
|
|
|
|
}
|
|
|
|
|
2015-09-17 17:05:30 +02:00
|
|
|
fn doc_predicate<'tcx>(cdata: Cmd,
|
|
|
|
doc: rbml::Doc,
|
|
|
|
tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> ty::Predicate<'tcx>
|
|
|
|
{
|
|
|
|
let predicate_pos = cdata.xref_index.lookup(
|
|
|
|
cdata.data(), reader::doc_as_u32(doc)).unwrap() as usize;
|
|
|
|
TyDecoder::new(
|
|
|
|
cdata.data(), cdata.cnum, predicate_pos, tcx,
|
2015-10-02 15:12:20 +02:00
|
|
|
&mut |did| translate_def_id(cdata, did)
|
2015-09-17 17:05:30 +02:00
|
|
|
).parse_predicate()
|
|
|
|
}
|
|
|
|
|
2015-02-11 11:59:01 +01:00
|
|
|
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-09-17 17:05:30 +02:00
|
|
|
for predicate_doc in reader::tagged_docs(doc, tag_type_predicate) {
|
|
|
|
predicates.push(subst::TypeSpace,
|
|
|
|
doc_predicate(cdata, predicate_doc, tcx));
|
|
|
|
}
|
|
|
|
for predicate_doc in reader::tagged_docs(doc, tag_self_predicate) {
|
|
|
|
predicates.push(subst::SelfSpace,
|
|
|
|
doc_predicate(cdata, predicate_doc, tcx));
|
|
|
|
}
|
|
|
|
for predicate_doc in reader::tagged_docs(doc, tag_fn_predicate) {
|
|
|
|
predicates.push(subst::FnSpace,
|
|
|
|
doc_predicate(cdata, predicate_doc, tcx));
|
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-09-17 20:29:59 +02:00
|
|
|
pub fn is_defaulted_trait(cdata: Cmd, trait_id: DefIndex) -> bool {
|
2015-09-03 00:22:31 +02:00
|
|
|
let trait_doc = cdata.lookup_item(trait_id);
|
2015-03-04 21:19:27 +01:00
|
|
|
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-09-17 20:29:59 +02:00
|
|
|
pub fn is_default_impl(cdata: Cmd, impl_id: DefIndex) -> bool {
|
2015-09-03 00:22:31 +02:00
|
|
|
let impl_doc = cdata.lookup_item(impl_id);
|
2015-03-13 03:15:52 +01:00
|
|
|
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-12-25 19:59:02 +01:00
|
|
|
decoder.read_opaque(|opaque_decoder, _| {
|
|
|
|
Decodable::decode(opaque_decoder)
|
|
|
|
}).unwrap()
|
2015-05-24 12:23:29 +02:00
|
|
|
}).collect()
|
2015-02-11 18:29:49 +01:00
|
|
|
}
|
2015-07-29 02:19:08 +02:00
|
|
|
|
2015-09-17 20:29:59 +02:00
|
|
|
pub fn closure_kind(cdata: Cmd, closure_id: DefIndex) -> ty::ClosureKind {
|
|
|
|
let closure_doc = cdata.lookup_item(closure_id);
|
|
|
|
let closure_kind_doc = reader::get_doc(closure_doc, tag_items_closure_kind);
|
|
|
|
let mut decoder = reader::Decoder::new(closure_kind_doc);
|
|
|
|
ty::ClosureKind::decode(&mut decoder).unwrap()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn closure_ty<'tcx>(cdata: Cmd, closure_id: DefIndex, tcx: &ty::ctxt<'tcx>)
|
|
|
|
-> ty::ClosureTy<'tcx> {
|
|
|
|
let closure_doc = cdata.lookup_item(closure_id);
|
|
|
|
let closure_ty_doc = reader::get_doc(closure_doc, tag_items_closure_ty);
|
|
|
|
TyDecoder::with_doc(tcx, cdata.cnum, closure_ty_doc, &mut |did| translate_def_id(cdata, did))
|
|
|
|
.parse_closure_ty()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn def_key(item_doc: rbml::Doc) -> hir_map::DefKey {
|
|
|
|
match reader::maybe_get_doc(item_doc, tag_def_key) {
|
|
|
|
Some(def_key_doc) => {
|
|
|
|
let mut decoder = reader::Decoder::new(def_key_doc);
|
|
|
|
hir_map::DefKey::decode(&mut decoder).unwrap()
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
panic!("failed to find block with tag {:?} for item with family {:?}",
|
|
|
|
tag_def_key,
|
|
|
|
item_family(item_doc))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn def_path(cdata: Cmd, id: DefIndex) -> hir_map::DefPath {
|
|
|
|
debug!("def_path(id={:?})", id);
|
|
|
|
hir_map::definitions::make_def_path(id, |parent| {
|
|
|
|
debug!("def_path: parent={:?}", parent);
|
|
|
|
let parent_doc = cdata.lookup_item(parent);
|
|
|
|
def_key(parent_doc)
|
|
|
|
})
|
|
|
|
}
|