// table in the tcx (or elsewhere) maps to one of these
// nodes. Often we map multiple tables to the same node if there
// is no point in distinguishing them (e.g., both the type and
- // predicates for an item wind up in `ItemSignature`). Other
- // times, such as `ImplItems` vs `TraitItemDefIds`, tables which
- // might be mergable are kept distinct because the sets of def-ids
- // to which they apply are disjoint, and hence we might as well
- // have distinct labels for easier debugging.
+ // predicates for an item wind up in `ItemSignature`).
ImplOrTraitItems(D),
ItemSignature(D),
FieldTy(D),
SizedConstraint(D),
- TraitItemDefIds(D),
+ ImplOrTraitItemIds(D),
InherentImpls(D),
- ImplItems(D),
// The set of impls for a given trait. Ultimately, it would be
// nice to get more fine-grained here (e.g., to include a
ImplOrTraitItems,
ItemSignature,
FieldTy,
- TraitItemDefIds,
+ ImplOrTraitItemIds,
InherentImpls,
- ImplItems,
TraitImpls,
ReprHints,
}
ItemSignature(ref d) => op(d).map(ItemSignature),
FieldTy(ref d) => op(d).map(FieldTy),
SizedConstraint(ref d) => op(d).map(SizedConstraint),
- TraitItemDefIds(ref d) => op(d).map(TraitItemDefIds),
+ ImplOrTraitItemIds(ref d) => op(d).map(ImplOrTraitItemIds),
InherentImpls(ref d) => op(d).map(InherentImpls),
- ImplItems(ref d) => op(d).map(ImplItems),
TraitImpls(ref d) => op(d).map(TraitImpls),
TraitItems(ref d) => op(d).map(TraitItems),
ReprHints(ref d) => op(d).map(ReprHints),
// within.
pub type ExportMap = NodeMap<Vec<Export>>;
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct Export {
pub name: ast::Name, // The name of the target.
pub def_id: DefId, // The definition of the target.
}
}
- pub fn expect_struct(&self, id: NodeId) -> &'ast VariantData {
+ pub fn expect_variant_data(&self, id: NodeId) -> &'ast VariantData {
match self.find(id) {
Some(NodeItem(i)) => {
match i.node {
- ItemStruct(ref struct_def, _) => struct_def,
- _ => bug!("struct ID bound to non-struct")
+ ItemStruct(ref struct_def, _) |
+ ItemUnion(ref struct_def, _) => struct_def,
+ _ => {
+ bug!("struct ID bound to non-struct {}",
+ self.node_to_string(id));
+ }
}
}
- Some(NodeVariant(variant)) => {
- if variant.node.data.is_struct() {
- &variant.node.data
- } else {
- bug!("struct ID bound to enum variant that isn't struct-like")
- }
+ Some(NodeStructCtor(data)) => data,
+ Some(NodeVariant(variant)) => &variant.node.data,
+ _ => {
+ bug!("expected struct or variant, found {}",
+ self.node_to_string(id));
}
- _ => bug!("expected struct, found {}", self.node_to_string(id)),
}
}
use hir::map::definitions::DefKey;
use hir::svh::Svh;
use middle::lang_items;
-use ty::{self, Ty, TyCtxt, VariantKind};
+use ty::{self, Ty, TyCtxt};
use mir::repr::Mir;
use mir::mir_map::MirMap;
use session::Session;
use session::config::PanicStrategy;
use session::search_paths::PathKind;
-use util::nodemap::{FnvHashMap, NodeSet, DefIdMap};
-use std::rc::Rc;
+use util::nodemap::{NodeSet, DefIdMap};
use std::path::PathBuf;
use syntax::ast;
use syntax::attr;
use hir;
use hir::intravisit::Visitor;
-pub use self::DefLike::{DlDef, DlField, DlImpl};
pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown};
// lonely orphan structs and enums looking for a better home
pub cnum: CrateNum,
}
-#[derive(Copy, Debug, PartialEq, Clone)]
+#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable)]
pub enum LinkagePreference {
RequireDynamic,
RequireStatic,
}
-enum_from_u32! {
- #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
- pub enum NativeLibraryKind {
- NativeStatic, // native static library (.a archive)
- NativeFramework, // OSX-specific
- NativeUnknown, // default way to specify a dynamic library
- }
-}
-
-// Something that a name can resolve to.
-#[derive(Copy, Clone, Debug)]
-pub enum DefLike {
- DlDef(Def),
- DlImpl(DefId),
- DlField
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+pub enum NativeLibraryKind {
+ NativeStatic, // native static library (.a archive)
+ NativeFramework, // OSX-specific
+ NativeUnknown, // default way to specify a dynamic library
}
/// The data we save and restore about an inlined item or method. This is not
#[derive(Copy, Clone)]
pub struct ChildItem {
- pub def: DefLike,
+ pub def: Def,
pub name: ast::Name,
pub vis: ty::Visibility,
}
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
// trait info
- fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId>;
- fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
- -> Vec<Rc<ty::Method<'tcx>>>;
- fn trait_item_def_ids(&self, def: DefId)
- -> Vec<ty::ImplOrTraitItemId>;
+ fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
// impl info
- fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>;
+ fn impl_or_trait_items(&self, def_id: DefId) -> Vec<ty::ImplOrTraitItemId>;
fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> Option<ty::TraitRef<'tcx>>;
- fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity>;
+ fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity;
fn custom_coerce_unsized_kind(&self, def: DefId)
-> Option<ty::adjustment::CustomCoerceUnsized>;
- fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
- -> Vec<Rc<ty::AssociatedConst<'tcx>>>;
fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
// trait/impl-item info
// flags
fn is_const_fn(&self, did: DefId) -> bool;
fn is_defaulted_trait(&self, did: DefId) -> bool;
- fn is_impl(&self, did: DefId) -> bool;
fn is_default_impl(&self, impl_did: DefId) -> bool;
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool;
fn is_foreign_item(&self, did: DefId) -> bool;
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
- fn is_typedef(&self, did: DefId) -> bool;
// crate metadata
fn dylib_dependency_formats(&self, cnum: CrateNum)
fn original_crate_name(&self, cnum: CrateNum) -> InternedString;
fn crate_hash(&self, cnum: CrateNum) -> Svh;
fn crate_disambiguator(&self, cnum: CrateNum) -> InternedString;
- fn crate_struct_field_attrs(&self, cnum: CrateNum)
- -> FnvHashMap<DefId, Vec<ast::Attribute>>;
fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>;
fn native_libraries(&self, cnum: CrateNum) -> Vec<(NativeLibraryKind, String)>;
fn reachable_ids(&self, cnum: CrateNum) -> Vec<DefId>;
-> Option<DefIndex>;
fn def_key(&self, def: DefId) -> hir_map::DefKey;
fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath>;
- fn variant_kind(&self, def_id: DefId) -> Option<VariantKind>;
fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>;
fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>;
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
fn item_children(&self, did: DefId) -> Vec<ChildItem>;
- fn crate_top_level_items(&self, cnum: CrateNum) -> Vec<ChildItem>;
// misc. metadata
fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
// trait info
- fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId> { vec![] }
- fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
- -> Vec<Rc<ty::Method<'tcx>>> { bug!("provided_trait_methods") }
- fn trait_item_def_ids(&self, def: DefId)
- -> Vec<ty::ImplOrTraitItemId> { bug!("trait_item_def_ids") }
+ fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }
fn def_index_for_def_key(&self,
cnum: CrateNum,
def: DefKey)
}
// impl info
- fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
- { bug!("impl_items") }
+ fn impl_or_trait_items(&self, def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
+ { bug!("impl_or_trait_items") }
fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> Option<ty::TraitRef<'tcx>> { bug!("impl_trait_ref") }
- fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity> { bug!("impl_polarity") }
+ fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity { bug!("impl_polarity") }
fn custom_coerce_unsized_kind(&self, def: DefId)
-> Option<ty::adjustment::CustomCoerceUnsized>
{ bug!("custom_coerce_unsized_kind") }
- fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
- -> Vec<Rc<ty::AssociatedConst<'tcx>>> { bug!("associated_consts") }
fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
// trait/impl-item info
// flags
fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") }
fn is_defaulted_trait(&self, did: DefId) -> bool { bug!("is_defaulted_trait") }
- fn is_impl(&self, did: DefId) -> bool { bug!("is_impl") }
fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool
{ bug!("is_extern_item") }
fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
- fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") }
// crate metadata
fn dylib_dependency_formats(&self, cnum: CrateNum)
fn crate_hash(&self, cnum: CrateNum) -> Svh { bug!("crate_hash") }
fn crate_disambiguator(&self, cnum: CrateNum)
-> InternedString { bug!("crate_disambiguator") }
- fn crate_struct_field_attrs(&self, cnum: CrateNum)
- -> FnvHashMap<DefId, Vec<ast::Attribute>>
- { bug!("crate_struct_field_attrs") }
fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
{ bug!("plugin_registrar_fn") }
fn native_libraries(&self, cnum: CrateNum) -> Vec<(NativeLibraryKind, String)>
fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath> {
bug!("relative_def_path")
}
- fn variant_kind(&self, def_id: DefId) -> Option<VariantKind> { bug!("variant_kind") }
fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
{ bug!("struct_ctor_def_id") }
fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>
{ bug!("tuple_struct_definition_if_ctor") }
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
fn item_children(&self, did: DefId) -> Vec<ChildItem> { bug!("item_children") }
- fn crate_top_level_items(&self, cnum: CrateNum) -> Vec<ChildItem>
- { bug!("crate_top_level_items") }
// misc. metadata
fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
// This is done to handle the case where, for example, the static
// method of a private type is used, but the type itself is never
// called directly.
- let impl_items = self.tcx.impl_items.borrow();
+ let impl_items = self.tcx.impl_or_trait_item_ids.borrow();
if let Some(impl_list) =
self.tcx.inherent_impls.borrow().get(&self.tcx.map.local_def_id(id)) {
for impl_did in impl_list.iter() {
enum_from_u32! {
- #[derive(Copy, Clone, PartialEq, Eq, Hash)]
+ #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum LangItem {
$($variant,)*
}
}
}
-#[derive(Clone, PartialEq, Hash)]
+#[derive(Clone, PartialEq, Hash, RustcEncodable, RustcDecodable)]
pub enum PanicStrategy {
Unwind,
Abort,
fn filter_negative_impls(&self, candidate: SelectionCandidate<'tcx>)
-> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
if let ImplCandidate(def_id) = candidate {
- if self.tcx().trait_impl_polarity(def_id) == Some(hir::ImplPolarity::Negative) {
+ if self.tcx().trait_impl_polarity(def_id) == hir::ImplPolarity::Negative {
return Err(Unimplemented)
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::cell;
use std::rc::Rc;
use super::{OverlapError, specializes};
/// Iterate over the items defined directly by the given (impl or trait) node.
pub fn items(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> NodeItems<'a, 'gcx> {
- match *self {
- Node::Impl(impl_def_id) => {
- NodeItems::Impl {
- tcx: tcx.global_tcx(),
- items: cell::Ref::map(tcx.impl_items.borrow(),
- |impl_items| &impl_items[&impl_def_id]),
- idx: 0,
- }
- }
- Node::Trait(trait_def_id) => {
- NodeItems::Trait {
- items: tcx.trait_items(trait_def_id).clone(),
- idx: 0,
- }
- }
+ NodeItems {
+ tcx: tcx.global_tcx(),
+ items: tcx.impl_or_trait_items(self.def_id()),
+ idx: 0,
}
}
}
/// An iterator over the items defined within a trait or impl.
-pub enum NodeItems<'a, 'tcx: 'a> {
- Impl {
- tcx: TyCtxt<'a, 'tcx, 'tcx>,
- items: cell::Ref<'a, Vec<ty::ImplOrTraitItemId>>,
- idx: usize,
- },
- Trait {
- items: Rc<Vec<ImplOrTraitItem<'tcx>>>,
- idx: usize,
- },
+pub struct NodeItems<'a, 'tcx: 'a> {
+ tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ items: Rc<Vec<ty::ImplOrTraitItemId>>,
+ idx: usize
}
impl<'a, 'tcx> Iterator for NodeItems<'a, 'tcx> {
type Item = ImplOrTraitItem<'tcx>;
fn next(&mut self) -> Option<ImplOrTraitItem<'tcx>> {
- match *self {
- NodeItems::Impl { tcx, ref items, ref mut idx } => {
- let items_table = tcx.impl_or_trait_items.borrow();
- if *idx < items.len() {
- let item_def_id = items[*idx].def_id();
- let item = items_table[&item_def_id].clone();
- *idx += 1;
- Some(item)
- } else {
- None
- }
- }
- NodeItems::Trait { ref items, ref mut idx } => {
- if *idx < items.len() {
- let item = items[*idx].clone();
- *idx += 1;
- Some(item)
- } else {
- None
- }
- }
+ if self.idx < self.items.len() {
+ let item_def_id = self.items[self.idx].def_id();
+ let items_table = self.tcx.impl_or_trait_items.borrow();
+ let item = items_table[&item_def_id].clone();
+ self.idx += 1;
+ Some(item)
+ } else {
+ None
}
}
}
/// Maps from a trait item to the trait item "descriptor"
pub impl_or_trait_items: RefCell<DepTrackingMap<maps::ImplOrTraitItems<'tcx>>>,
- /// Maps from a trait def-id to a list of the def-ids of its trait items
- pub trait_item_def_ids: RefCell<DepTrackingMap<maps::TraitItemDefIds<'tcx>>>,
+ /// Maps from an impl/trait def-id to a list of the def-ids of its items
+ pub impl_or_trait_item_ids: RefCell<DepTrackingMap<maps::ImplOrTraitItemIds<'tcx>>>,
/// A cache for the trait_items() routine; note that the routine
/// itself pushes the `TraitItems` dependency node.
/// Methods in these implementations don't need to be exported.
pub inherent_impls: RefCell<DepTrackingMap<maps::InherentImpls<'tcx>>>,
- /// Maps a DefId of an impl to a list of its items.
- /// Note that this contains all of the impls that we know about,
- /// including ones in other crates. It's not clear that this is the best
- /// way to do it.
- pub impl_items: RefCell<DepTrackingMap<maps::ImplItems<'tcx>>>,
-
/// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
/// present in this set can be warned about.
pub used_unsafe: RefCell<NodeSet>,
rcache: RefCell::new(FnvHashMap()),
tc_cache: RefCell::new(FnvHashMap()),
impl_or_trait_items: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
- trait_item_def_ids: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
+ impl_or_trait_item_ids: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
trait_items_cache: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
ty_param_defs: RefCell::new(NodeMap()),
normalized_cache: RefCell::new(FnvHashMap()),
lang_items: lang_items,
inherent_impls: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
- impl_items: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
used_unsafe: RefCell::new(NodeSet()),
used_mut_nodes: RefCell::new(NodeSet()),
used_trait_imports: RefCell::new(NodeSet()),
pub fn trait_items(self, trait_did: DefId) -> Rc<Vec<ty::ImplOrTraitItem<'gcx>>> {
self.trait_items_cache.memoize(trait_did, || {
- let def_ids = self.trait_item_def_ids(trait_did);
+ let def_ids = self.impl_or_trait_items(trait_did);
Rc::new(def_ids.iter()
.map(|d| self.impl_or_trait_item(d.def_id()))
.collect())
dep_map_ty! { Generics: ItemSignature(DefId) -> &'tcx ty::Generics<'tcx> }
dep_map_ty! { Predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
dep_map_ty! { SuperPredicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
-dep_map_ty! { TraitItemDefIds: TraitItemDefIds(DefId) -> Rc<Vec<ty::ImplOrTraitItemId>> }
+dep_map_ty! { ImplOrTraitItemIds: ImplOrTraitItemIds(DefId)
+ -> Rc<Vec<ty::ImplOrTraitItemId>> }
dep_map_ty! { ImplTraitRefs: ItemSignature(DefId) -> Option<ty::TraitRef<'tcx>> }
dep_map_ty! { TraitDefs: ItemSignature(DefId) -> &'tcx ty::TraitDef<'tcx> }
dep_map_ty! { AdtDefs: ItemSignature(DefId) -> ty::AdtDefMaster<'tcx> }
dep_map_ty! { ItemVariances: ItemSignature(DefId) -> Rc<Vec<ty::Variance>> }
dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Vec<DefId> }
-dep_map_ty! { ImplItems: ImplItems(DefId) -> Vec<ty::ImplOrTraitItemId> }
dep_map_ty! { TraitItems: TraitItems(DefId) -> Rc<Vec<ty::ImplOrTraitItem<'tcx>>> }
dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc<Vec<attr::ReprAttr>> }
dep_map_ty! { InlinedClosures: Hir(DefId) -> ast::NodeId }
use rustc_const_math::ConstInt;
use hir;
-use hir::{ItemImpl, ItemTrait, PatKind};
use hir::intravisit::Visitor;
pub use self::sty::{Binder, DebruijnIndex};
}
}
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Copy, Debug, RustcEncodable, RustcDecodable)]
pub enum ImplOrTraitItemId {
ConstTraitItemId(DefId),
MethodTraitItemId(DefId),
}
}
-#[derive(Clone, Debug, PartialEq, Eq, Copy)]
+#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)]
pub enum Visibility {
/// Visible everywhere (including in other crates).
Public,
pub explicit_self: ExplicitSelfCategory<'tcx>,
pub vis: Visibility,
pub defaultness: hir::Defaultness,
+ pub has_body: bool,
pub def_id: DefId,
pub container: ImplOrTraitItemContainer,
}
impl<'tcx> Method<'tcx> {
- pub fn new(name: Name,
- generics: &'tcx ty::Generics<'tcx>,
- predicates: GenericPredicates<'tcx>,
- fty: &'tcx BareFnTy<'tcx>,
- explicit_self: ExplicitSelfCategory<'tcx>,
- vis: Visibility,
- defaultness: hir::Defaultness,
- def_id: DefId,
- container: ImplOrTraitItemContainer)
- -> Method<'tcx> {
- Method {
- name: name,
- generics: generics,
- predicates: predicates,
- fty: fty,
- explicit_self: explicit_self,
- vis: vis,
- defaultness: defaultness,
- def_id: def_id,
- container: container,
- }
- }
-
pub fn container_id(&self) -> DefId {
match self.container {
TraitContainer(id) => id,
match self.map.find(id) {
Some(ast_map::NodeLocal(pat)) => {
match pat.node {
- PatKind::Binding(_, ref path1, _) => path1.node.as_str(),
+ hir::PatKind::Binding(_, ref path1, _) => path1.node.as_str(),
_ => {
bug!("Variable id {} maps to {:?}, not local", id, pat);
},
}
pub fn provided_trait_methods(self, id: DefId) -> Vec<Rc<Method<'gcx>>> {
- if let Some(id) = self.map.as_local_node_id(id) {
- if let ItemTrait(.., ref ms) = self.map.expect_item(id).node {
- ms.iter().filter_map(|ti| {
- if let hir::MethodTraitItem(_, Some(_)) = ti.node {
- match self.impl_or_trait_item(self.map.local_def_id(ti.id)) {
- MethodTraitItem(m) => Some(m),
- _ => {
- bug!("provided_trait_methods(): \
- non-method item found from \
- looking up provided method?!")
- }
- }
- } else {
- None
- }
- }).collect()
- } else {
- bug!("provided_trait_methods: `{:?}` is not a trait", id)
+ self.impl_or_trait_items(id).iter().filter_map(|id| {
+ match self.impl_or_trait_item(id.def_id()) {
+ MethodTraitItem(ref m) if m.has_body => Some(m.clone()),
+ _ => None
}
- } else {
- self.sess.cstore.provided_trait_methods(self.global_tcx(), id)
- }
+ }).collect()
}
- pub fn associated_consts(self, id: DefId) -> Vec<Rc<AssociatedConst<'gcx>>> {
+ pub fn trait_impl_polarity(self, id: DefId) -> hir::ImplPolarity {
if let Some(id) = self.map.as_local_node_id(id) {
match self.map.expect_item(id).node {
- ItemTrait(.., ref tis) => {
- tis.iter().filter_map(|ti| {
- if let hir::ConstTraitItem(..) = ti.node {
- match self.impl_or_trait_item(self.map.local_def_id(ti.id)) {
- ConstTraitItem(ac) => Some(ac),
- _ => {
- bug!("associated_consts(): \
- non-const item found from \
- looking up a constant?!")
- }
- }
- } else {
- None
- }
- }).collect()
- }
- ItemImpl(.., ref iis) => {
- iis.iter().filter_map(|ii| {
- if let hir::ImplItemKind::Const(..) = ii.node {
- match self.impl_or_trait_item(self.map.local_def_id(ii.id)) {
- ConstTraitItem(ac) => Some(ac),
- _ => {
- bug!("associated_consts(): \
- non-const item found from \
- looking up a constant?!")
- }
- }
- } else {
- None
- }
- }).collect()
- }
- _ => {
- bug!("associated_consts: `{:?}` is not a trait or impl", id)
- }
- }
- } else {
- self.sess.cstore.associated_consts(self.global_tcx(), id)
- }
- }
-
- pub fn trait_impl_polarity(self, id: DefId) -> Option<hir::ImplPolarity> {
- if let Some(id) = self.map.as_local_node_id(id) {
- match self.map.find(id) {
- Some(ast_map::NodeItem(item)) => {
- match item.node {
- hir::ItemImpl(_, polarity, ..) => Some(polarity),
- _ => None
- }
- }
- _ => None
+ hir::ItemImpl(_, polarity, ..) => polarity,
+ ref item => bug!("trait_impl_polarity: {:?} not an impl", item)
}
} else {
self.sess.cstore.impl_polarity(id)
.expect("missing ImplOrTraitItem in metadata"))
}
- pub fn trait_item_def_ids(self, id: DefId) -> Rc<Vec<ImplOrTraitItemId>> {
+ pub fn impl_or_trait_items(self, id: DefId) -> Rc<Vec<ImplOrTraitItemId>> {
lookup_locally_or_in_crate_store(
- "trait_item_def_ids", id, &self.trait_item_def_ids,
- || Rc::new(self.sess.cstore.trait_item_def_ids(id)))
+ "impl_or_trait_items", id, &self.impl_or_trait_item_ids,
+ || Rc::new(self.sess.cstore.impl_or_trait_items(id)))
}
/// Returns the trait-ref corresponding to a given impl, or None if it is
|| self.sess.cstore.impl_trait_ref(self.global_tcx(), id))
}
- /// Returns whether this DefId refers to an impl
- pub fn is_impl(self, id: DefId) -> bool {
- if let Some(id) = self.map.as_local_node_id(id) {
- if let Some(ast_map::NodeItem(
- &hir::Item { node: hir::ItemImpl(..), .. })) = self.map.find(id) {
- true
- } else {
- false
- }
- } else {
- self.sess.cstore.is_impl(id)
- }
- }
-
/// Returns a path resolution for node id if it exists, panics otherwise.
pub fn expect_resolution(self, id: NodeId) -> PathResolution {
*self.def_map.borrow().get(&id).expect("no def-map entry for node id")
debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
primitive_def_id);
- let impl_items = self.sess.cstore.impl_items(primitive_def_id);
+ let impl_items = self.sess.cstore.impl_or_trait_items(primitive_def_id);
// Store the implementation info.
- self.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
+ self.impl_or_trait_item_ids.borrow_mut().insert(primitive_def_id, Rc::new(impl_items));
self.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
}
let inherent_impls = self.sess.cstore.inherent_implementations_for_type(type_id);
for &impl_def_id in &inherent_impls {
// Store the implementation info.
- let impl_items = self.sess.cstore.impl_items(impl_def_id);
- self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
+ let impl_items = self.sess.cstore.impl_or_trait_items(impl_def_id);
+ self.impl_or_trait_item_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items));
}
self.inherent_impls.borrow_mut().insert(type_id, inherent_impls);
self.record_trait_has_default_impl(trait_id);
}
- for impl_def_id in self.sess.cstore.implementations_of_trait(trait_id) {
- let impl_items = self.sess.cstore.impl_items(impl_def_id);
+ for impl_def_id in self.sess.cstore.implementations_of_trait(Some(trait_id)) {
+ let impl_items = self.sess.cstore.impl_or_trait_items(impl_def_id);
let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
// Record the trait->implementation mapping.
}
// Store the implementation info.
- self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
+ self.impl_or_trait_item_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items));
}
def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
}
/// The category of explicit self.
-#[derive(Clone, Copy, Eq, PartialEq, Debug)]
+#[derive(Clone, Copy, Eq, PartialEq, Debug, RustcEncodable, RustcDecodable)]
pub enum ExplicitSelfCategory<'tcx> {
Static,
ByValue,
// when constructing the inference context above.
match selection {
traits::VtableImpl(ref impl_data) => {
- match tcx.associated_consts(impl_data.impl_def_id)
- .iter().find(|ic| ic.name == ti.name) {
- Some(ic) => lookup_const_by_id(tcx, ic.def_id, None),
+ let ac = tcx.impl_or_trait_items(impl_data.impl_def_id)
+ .iter().filter_map(|id| {
+ match *id {
+ ty::ConstTraitItemId(def_id) => {
+ Some(tcx.impl_or_trait_item(def_id))
+ }
+ _ => None
+ }
+ }).find(|ic| ic.name() == ti.name);
+ match ac {
+ Some(ic) => lookup_const_by_id(tcx, ic.def_id(), None),
None => match ti.node {
hir::ConstTraitItem(ref ty, Some(ref expr)) => {
Some((&*expr, tcx.ast_ty_to_prim_ty(ty)))
#![allow(non_camel_case_types, non_upper_case_globals)]
+use rustc::ty;
+
+#[derive(Clone, Copy, Debug, PartialEq, RustcEncodable, RustcDecodable)]
+pub enum Family {
+ ImmStatic,
+ MutStatic,
+ Fn,
+ Method,
+ AssociatedType,
+ Type,
+ Mod,
+ ForeignMod,
+ Enum,
+ Variant(ty::VariantKind),
+ Impl,
+ DefaultImpl,
+ Trait,
+ Struct(ty::VariantKind),
+ Union,
+ PublicField,
+ InheritedField,
+ Const,
+ AssociatedConst,
+}
+
// GAP 0x00...0x19
pub const tag_items: usize = 0x100; // top-level only
pub const tag_paths_data_name: usize = 0x20;
-pub const tag_def_id: usize = 0x21;
+pub const tag_def_index: usize = 0x21;
pub const tag_items_data: usize = 0x22;
pub const tag_items_data_item_type: usize = 0x25;
-// GAP 0x26
-
-pub const tag_items_data_item_variant: usize = 0x27;
+// GAP 0x26, 0x27
pub const tag_items_data_parent_item: usize = 0x28;
// The list of crates that this crate depends on
pub const tag_crate_deps: usize = 0x102; // top-level only
-
-// A single crate dependency
-pub const tag_crate_dep: usize = 0x35;
-
pub const tag_crate_hash: usize = 0x103; // top-level only
pub const tag_crate_crate_name: usize = 0x104; // top-level only
pub const tag_crate_disambiguator: usize = 0x113; // top-level only
-pub const tag_crate_dep_crate_name: usize = 0x36;
-pub const tag_crate_dep_hash: usize = 0x37;
-pub const tag_crate_dep_explicitly_linked: usize = 0x38; // top-level only
-
-pub const tag_item_trait_item: usize = 0x3a;
+// GAP 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a
pub const tag_item_trait_ref: usize = 0x3b;
// GAP 0x3d, 0x3e, 0x3f, 0x40
-pub const tag_item_field: usize = 0x41;
+pub const tag_item_fields: usize = 0x41;
// GAP 0x42
pub const tag_item_variances: usize = 0x43;
-/*
- trait items contain tag_item_trait_item elements,
- impl items contain tag_item_impl_item elements, and classes
- have both. That's because some code treats classes like traits,
- and other code treats them like impls. Because classes can contain
- both, tag_item_trait_item and tag_item_impl_item have to be two
- different tags.
- */
-pub const tag_item_impl_item: usize = 0x44;
+// GAP 0x44
pub const tag_item_trait_method_explicit_self: usize = 0x45;
-
-// Reexports are found within module tags. Each reexport contains def_ids
-// and names.
-pub const tag_items_data_item_reexport: usize = 0x46;
-pub const tag_items_data_item_reexport_def_id: usize = 0x47;
-pub const tag_items_data_item_reexport_name: usize = 0x48;
+// GAP 0x46, 0x47, 0x48
// used to encode crate_ctxt side tables
pub const tag_ast: usize = 0x50;
// GAP 0x53...0x6a
-pub const tag_item_trait_item_sort: usize = 0x70;
+pub const tag_item_trait_item_has_body: usize = 0x70;
pub const tag_crate_triple: usize = 0x105; // top-level only
pub const tag_dylib_dependency_formats: usize = 0x106; // top-level only
-// Language items are a top-level directory (for speed). Hierarchy:
-//
-// tag_lang_items
-// - tag_lang_items_item
-// - tag_lang_items_item_id: u32
-// - tag_lang_items_item_index: u32
-
pub const tag_lang_items: usize = 0x107; // top-level only
-pub const tag_lang_items_item: usize = 0x73;
-pub const tag_lang_items_item_id: usize = 0x74;
-pub const tag_lang_items_item_index: usize = 0x75;
-pub const tag_lang_items_missing: usize = 0x76;
-pub const tag_item_unnamed_field: usize = 0x77;
+// GAP 0x73, 0x74, 0x75
+
+pub const tag_lang_items_missing: usize = 0x76; // top-level only
+
+// GAP 0x77
+
pub const tag_items_data_item_visibility: usize = 0x78;
-pub const tag_items_data_item_inherent_impl: usize = 0x79;
+pub const tag_items_data_item_inherent_impls: usize = 0x79;
+
// GAP 0x7a
-pub const tag_mod_child: usize = 0x7b;
+
+// GAP 0x7c
+pub const tag_mod_children: usize = 0x7b;
+
+// GAP 0x108 // top-level only
+
// GAP 0x7c
// GAP 0x108
pub const tag_impls: usize = 0x109; // top-level only
-pub const tag_impls_trait: usize = 0x7d;
-pub const tag_impls_trait_impl: usize = 0x7e;
-// GAP 0x7f, 0x80, 0x81
+// GAP 0x7d, 0x7e, 0x7f, 0x80, 0x81
pub const tag_native_libraries: usize = 0x10a; // top-level only
-pub const tag_native_libraries_lib: usize = 0x82;
-pub const tag_native_libraries_name: usize = 0x83;
-pub const tag_native_libraries_kind: usize = 0x84;
+
+// GAP 0x82, 0x83, 0x84
pub const tag_plugin_registrar_fn: usize = 0x10b; // top-level only
pub const tag_method_argument_names: usize = 0x85;
-pub const tag_method_argument_name: usize = 0x86;
+
+// GAP 0x86
pub const tag_reachable_ids: usize = 0x10c; // top-level only
-pub const tag_reachable_id: usize = 0x87;
+
+// GAP 0x87
pub const tag_items_data_item_stability: usize = 0x88;
pub const tag_items_data_item_repr: usize = 0x89;
-pub const tag_struct_fields: usize = 0x10d; // top-level only
-pub const tag_struct_field: usize = 0x8a;
+// GAP 0x10d // top-level only
+
+// GAP 0x8a
pub const tag_items_data_item_struct_ctor: usize = 0x8b;
pub const tag_attribute_is_sugared_doc: usize = 0x8c;
// GAP 0x90, 0x91, 0x92, 0x93, 0x94
pub const tag_item_predicates: usize = 0x95;
-// GAP 0x96
-
-pub const tag_predicate: usize = 0x97;
-// GAP 0x98, 0x99
+// GAP 0x96, 0x97, 0x98, 0x99
pub const tag_unsafety: usize = 0x9a;
pub const tag_polarity: usize = 0x9d;
pub const tag_macro_defs: usize = 0x10e; // top-level only
-pub const tag_macro_def: usize = 0x9e;
-pub const tag_macro_def_body: usize = 0x9f;
-pub const tag_macro_def_span_lo: usize = 0xa8;
-pub const tag_macro_def_span_hi: usize = 0xa9;
+
+// GAP 0x9e, 0x9f
pub const tag_paren_sugar: usize = 0xa0;
pub const tag_codemap: usize = 0xa1;
-pub const tag_codemap_filemap: usize = 0xa2;
+
+// GAP 0xa2
pub const tag_item_super_predicates: usize = 0xa3;
// Check for (potential) conflicts with the local crate
if self.local_crate_name == crate_name &&
- self.sess.local_crate_disambiguator() == disambiguator {
+ self.sess.local_crate_disambiguator() == &disambiguator[..] {
span_fatal!(self.sess, span, E0519,
"the current crate is indistinguishable from one of its \
dependencies: it has the same crate-name `{}` and was \
let loader::Library { dylib, rlib, metadata } = lib;
let cnum_map = self.resolve_crate_deps(root, metadata.as_slice(), cnum, span);
- let staged_api = self.is_staged_api(metadata.as_slice());
let cmeta = Rc::new(cstore::CrateMetadata {
name: name.to_string(),
cnum_map: RefCell::new(cnum_map),
cnum: cnum,
codemap_import_info: RefCell::new(vec![]),
- staged_api: staged_api,
explicitly_linked: Cell::new(explicitly_linked),
});
(cnum, cmeta, source)
}
- fn is_staged_api(&self, data: &[u8]) -> bool {
- let attrs = decoder::get_crate_attributes(data);
- for attr in &attrs {
- if attr.name() == "stable" || attr.name() == "unstable" {
- return true
- }
- }
- false
- }
-
fn resolve_crate(&mut self,
root: &Option<CratePaths>,
ident: &str,
use encoder;
use loader;
-use middle::cstore::{InlinedItem, CrateStore, CrateSource, ChildItem, ExternCrate, DefLike};
+use middle::cstore::{InlinedItem, CrateStore, CrateSource, ChildItem, ExternCrate};
use middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference};
use rustc::hir::def;
use middle::lang_items;
-use rustc::ty::{self, Ty, TyCtxt, VariantKind};
+use rustc::ty::{self, Ty, TyCtxt};
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
use rustc::dep_graph::DepNode;
use rustc::hir::map::DefKey;
use rustc::mir::repr::Mir;
use rustc::mir::mir_map::MirMap;
-use rustc::util::nodemap::{FnvHashMap, NodeSet, DefIdMap};
+use rustc::util::nodemap::{NodeSet, DefIdMap};
use rustc::session::config::PanicStrategy;
-use std::rc::Rc;
use std::path::PathBuf;
use syntax::ast;
use syntax::attr;
result
}
- fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId>
+ fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>
{
- self.dep_graph.read(DepNode::MetaData(def_id));
+ if let Some(def_id) = filter {
+ self.dep_graph.read(DepNode::MetaData(def_id));
+ }
let mut result = vec![];
self.iter_crate_data(|_, cdata| {
- decoder::each_implementation_for_trait(cdata, def_id, &mut |iid| {
+ decoder::each_implementation_for_trait(cdata, filter, &mut |iid| {
result.push(iid)
})
});
result
}
- fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
- -> Vec<Rc<ty::Method<'tcx>>>
- {
- self.dep_graph.read(DepNode::MetaData(def));
- let cdata = self.get_crate_data(def.krate);
- decoder::get_provided_trait_methods(&cdata, def.index, tcx)
- }
-
- fn trait_item_def_ids(&self, def: DefId)
- -> Vec<ty::ImplOrTraitItemId>
- {
- self.dep_graph.read(DepNode::MetaData(def));
- let cdata = self.get_crate_data(def.krate);
- decoder::get_trait_item_def_ids(&cdata, def.index)
- }
-
- fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
- {
- self.dep_graph.read(DepNode::MetaData(impl_def_id));
- let cdata = self.get_crate_data(impl_def_id.krate);
- decoder::get_impl_items(&cdata, impl_def_id.index)
+ fn impl_or_trait_items(&self, def_id: DefId) -> Vec<ty::ImplOrTraitItemId> {
+ self.dep_graph.read(DepNode::MetaData(def_id));
+ let cdata = self.get_crate_data(def_id.krate);
+ decoder::get_impl_or_trait_items(&cdata, def_id.index)
}
- fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity>
+ fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity
{
self.dep_graph.read(DepNode::MetaData(def));
let cdata = self.get_crate_data(def.krate);
decoder::get_custom_coerce_unsized_kind(&cdata, def.index)
}
- // FIXME: killme
- fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
- -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
- self.dep_graph.read(DepNode::MetaData(def));
- let cdata = self.get_crate_data(def.krate);
- decoder::get_associated_consts(&cdata, def.index, tcx)
- }
-
fn impl_parent(&self, impl_def: DefId) -> Option<DefId> {
self.dep_graph.read(DepNode::MetaData(impl_def));
let cdata = self.get_crate_data(impl_def.krate);
decoder::is_defaulted_trait(&cdata, trait_def_id.index)
}
- fn is_impl(&self, did: DefId) -> bool
- {
- self.dep_graph.read(DepNode::MetaData(did));
- let cdata = self.get_crate_data(did.krate);
- decoder::is_impl(&cdata, did.index)
- }
-
fn is_default_impl(&self, impl_did: DefId) -> bool {
self.dep_graph.read(DepNode::MetaData(impl_did));
let cdata = self.get_crate_data(impl_did.krate);
self.do_is_statically_included_foreign_item(id)
}
- fn is_typedef(&self, did: DefId) -> bool {
- self.dep_graph.read(DepNode::MetaData(did));
- let cdata = self.get_crate_data(did.krate);
- decoder::is_typedef(&cdata, did.index)
- }
-
fn dylib_dependency_formats(&self, cnum: CrateNum)
-> Vec<(CrateNum, LinkagePreference)>
{
fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>
{
- let mut result = vec![];
let crate_data = self.get_crate_data(cnum);
- decoder::each_lang_item(&crate_data, |did, lid| {
- result.push((did, lid)); true
- });
- result
+ decoder::get_lang_items(&crate_data)
}
fn missing_lang_items(&self, cnum: CrateNum)
fn is_staged_api(&self, cnum: CrateNum) -> bool
{
- self.get_crate_data(cnum).staged_api
+ self.get_crate_data(cnum).is_staged_api()
}
fn is_explicitly_linked(&self, cnum: CrateNum) -> bool
fn crate_attrs(&self, cnum: CrateNum) -> Vec<ast::Attribute>
{
- decoder::get_crate_attributes(self.get_crate_data(cnum).data())
+ decoder::get_item_attrs(&self.get_crate_data(cnum), CRATE_DEF_INDEX)
}
fn crate_name(&self, cnum: CrateNum) -> token::InternedString
fn crate_disambiguator(&self, cnum: CrateNum) -> token::InternedString
{
let cdata = self.get_crate_data(cnum);
- token::intern_and_get_ident(decoder::get_crate_disambiguator(cdata.data()))
- }
-
- fn crate_struct_field_attrs(&self, cnum: CrateNum)
- -> FnvHashMap<DefId, Vec<ast::Attribute>>
- {
- decoder::get_struct_field_attrs(&self.get_crate_data(cnum))
+ token::intern_and_get_ident(&decoder::get_crate_disambiguator(cdata.data()))
}
fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
decoder::def_path(&cdata, def.index)
}
- fn variant_kind(&self, def_id: DefId) -> Option<VariantKind> {
- self.dep_graph.read(DepNode::MetaData(def_id));
- let cdata = self.get_crate_data(def_id.krate);
- decoder::get_variant_kind(&cdata, def_id.index)
- }
-
fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
{
self.dep_graph.read(DepNode::MetaData(struct_def_id));
result
}
- fn crate_top_level_items(&self, cnum: CrateNum) -> Vec<ChildItem>
- {
- let mut result = vec![];
- let crate_data = self.get_crate_data(cnum);
- let get_crate_data = |cnum| self.get_crate_data(cnum);
- decoder::each_top_level_item_of_crate(&crate_data, get_crate_data, |def, name, vis| {
- result.push(ChildItem { def: def, name: name, vis: vis });
- });
- result
- }
-
fn maybe_get_item_ast<'a>(&'tcx self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
let mut bfs_queue = &mut VecDeque::new();
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: ChildItem, parent: DefId| {
- let child = match child.def {
- DefLike::DlDef(def) if child.vis == ty::Visibility::Public => def.def_id(),
- _ => return,
+ let child = if child.vis == ty::Visibility::Public {
+ child.def.def_id()
+ } else {
+ return;
};
match visible_parent_map.entry(child) {
}
};
- let croot = DefId { krate: cnum, index: CRATE_DEF_INDEX };
- for child in self.crate_top_level_items(cnum) {
- add_child(bfs_queue, child, croot);
- }
+ bfs_queue.push_back(DefId {
+ krate: cnum,
+ index: CRATE_DEF_INDEX
+ });
while let Some(def) = bfs_queue.pop_front() {
for child in self.item_children(def) {
add_child(bfs_queue, child, def);
visible_parent_map
}
}
-
use loader;
use rustc::dep_graph::DepGraph;
-use rustc::hir::def_id::{CrateNum, DefIndex, DefId};
+use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex, DefId};
use rustc::hir::map::DefKey;
use rustc::hir::svh::Svh;
use rustc::middle::cstore::ExternCrate;
pub cnum_map: RefCell<CrateNumMap>,
pub cnum: CrateNum,
pub codemap_import_info: RefCell<Vec<ImportedFileMap>>,
- pub staged_api: bool,
pub index: index::Index,
pub xref_index: index::DenseIndex,
impl CrateMetadata {
pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
- pub fn name(&self) -> &str { decoder::get_crate_name(self.data()) }
+ pub fn name(&self) -> String { decoder::get_crate_name(self.data()) }
pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
- pub fn disambiguator(&self) -> &str {
+ pub fn disambiguator(&self) -> String {
decoder::get_crate_disambiguator(self.data())
}
pub fn imported_filemaps<'a>(&'a self, codemap: &codemap::CodeMap)
}
}
+ pub fn is_staged_api(&self) -> bool {
+ let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX);
+ attrs.iter().any(|attr| {
+ attr.name() == "stable" || attr.name() == "unstable"
+ })
+ }
+
pub fn is_allocator(&self) -> bool {
- let attrs = decoder::get_crate_attributes(self.data());
+ let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX);
attr::contains_name(&attrs, "allocator")
}
pub fn needs_allocator(&self) -> bool {
- let attrs = decoder::get_crate_attributes(self.data());
+ let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX);
attr::contains_name(&attrs, "needs_allocator")
}
pub fn is_panic_runtime(&self) -> bool {
- let attrs = decoder::get_crate_attributes(self.data());
+ let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX);
attr::contains_name(&attrs, "panic_runtime")
}
pub fn needs_panic_runtime(&self) -> bool {
- let attrs = decoder::get_crate_attributes(self.data());
+ let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX);
attr::contains_name(&attrs, "needs_panic_runtime")
}
#![allow(non_camel_case_types)]
-use self::Family::*;
-
use astencode::decode_inlined_item;
use cstore::{self, CrateMetadata};
use common::*;
+use common::Family::*;
use def_key;
-use encoder::def_to_u64;
use index;
use rustc::hir::def_id::CRATE_DEF_INDEX;
use rustc::session::config::PanicStrategy;
use middle::cstore::{InlinedItem, LinkagePreference};
-use middle::cstore::{DefLike, DlDef, DlField, DlImpl};
-use rustc::hir::def::Def;
+use rustc::hir::def::{self, Def};
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
use middle::lang_items;
use rustc::ty::{ImplContainer, TraitContainer};
-use rustc::ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable, VariantKind};
+use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::ty::subst::Substs;
use rustc_const_math::ConstInt;
use rbml::reader;
use rbml;
use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
-use rustc_serialize as serialize;
use syntax::attr;
-use syntax::parse::token;
use syntax::ast::{self, NodeId};
-use syntax::print::pprust;
-use syntax_pos::{self, Span, BytePos, NO_EXPANSION};
+use syntax_pos::{self, Span, BytePos};
pub struct DecodeContext<'a, 'tcx: 'a> {
pub opaque: opaque::Decoder<'a>,
pub fn cdata(&self) -> &'a cstore::CrateMetadata {
self.cdata.expect("missing CrateMetadata in DecodeContext")
}
+
+ pub fn decode<T: Decodable>(&mut self) -> T {
+ T::decode(self).unwrap()
+ }
+
+ /// Iterate over the indices of a sequence.
+ /// This will work solely because of `serialize::opaque`'s
+ /// simple encoding of `n: usize` followed by `n` elements.
+ pub fn seq<T: Decodable>(mut self) -> impl Iterator<Item=T> {
+ (0..self.read_usize().unwrap()).map(move |_| {
+ self.decode()
+ })
+ }
+
+ pub fn seq_mut<'b, T: Decodable>(&'b mut self) -> impl Iterator<Item=T> + 'b {
+ (0..self.read_usize().unwrap()).map(move |_| {
+ self.decode()
+ })
+ }
}
macro_rules! decoder_methods {
}
}
-impl<'doc, 'tcx> serialize::Decoder for ::decoder::DecodeContext<'doc, 'tcx> {
- type Error = <opaque::Decoder<'doc> as serialize::Decoder>::Error;
+impl<'doc, 'tcx> Decoder for DecodeContext<'doc, 'tcx> {
+ type Error = <opaque::Decoder<'doc> as Decoder>::Error;
decoder_methods! {
read_nil -> ();
}
pub fn load_index(data: &[u8]) -> index::Index {
- let index = reader::get_doc(rbml::Doc::new(data), tag_index);
- index::Index::from_rbml(index)
+ index::Index::from_rbml(rbml::Doc::new(data).get(tag_index))
}
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.to_string())
+ reader::maybe_get_doc(doc, tag_rustc_version).map(|s| {
+ str::from_utf8(&s.data[s.start..s.end]).unwrap().to_string()
+ })
}
pub fn load_xrefs(data: &[u8]) -> index::DenseIndex {
- let index = reader::get_doc(rbml::Doc::new(data), tag_xref_index);
+ let index = rbml::Doc::new(data).get(tag_xref_index);
index::DenseIndex::from_buf(index.data, index.start, index.end)
}
// Go through each item in the metadata and create a map from that
// item's def-key to the item's DefIndex.
pub fn load_key_map(data: &[u8]) -> FnvHashMap<DefKey, DefIndex> {
- let root_doc = rbml::Doc::new(data);
- let items_doc = reader::get_doc(root_doc, tag_items);
- let items_data_doc = reader::get_doc(items_doc, tag_items_data);
- reader::docs(items_data_doc)
- .filter(|&(tag, _)| tag == tag_items_data_item)
- .map(|(_, item_doc)| {
- // load def-key from item
- let key = item_def_key(item_doc);
-
- // load def-index from item; we only encode the full def-id,
- // so just pull out the index
- let def_id_doc = reader::get_doc(item_doc, tag_def_id);
- let def_id = untranslated_def_id(def_id_doc);
- assert!(def_id.is_local()); // local to the crate we are decoding, that is
-
- (key, def_id.index)
- })
- .collect()
-}
-
-#[derive(Clone, Copy, Debug, PartialEq)]
-enum Family {
- ImmStatic, // c
- MutStatic, // b
- Fn, // f
- StaticMethod, // F
- Method, // h
- Type, // y
- Mod, // m
- ForeignMod, // n
- Enum, // t
- Variant(VariantKind), // V, v, w
- Impl, // i
- DefaultImpl, // d
- Trait, // I
- Struct(VariantKind), // S, s, u
- Union, // U
- PublicField, // g
- InheritedField, // N
- Constant, // C
+ rbml::Doc::new(data).get(tag_items).get(tag_items_data).children().map(|item_doc| {
+ // load def-key from item
+ let key = item_def_key(item_doc);
+
+ // load def-index from item
+ (key, item_doc.get(tag_def_index).decoder().decode())
+ }).collect()
}
fn item_family(item: rbml::Doc) -> Family {
- let fam = reader::get_doc(item, tag_items_data_item_family);
- match reader::doc_as_u8(fam) as char {
- 'C' => Constant,
- 'c' => ImmStatic,
- 'b' => MutStatic,
- 'f' => Fn,
- 'F' => StaticMethod,
- 'h' => Method,
- 'y' => Type,
- 'm' => Mod,
- 'n' => ForeignMod,
- 't' => Enum,
- 'V' => Variant(VariantKind::Struct),
- 'v' => Variant(VariantKind::Tuple),
- 'w' => Variant(VariantKind::Unit),
- 'i' => Impl,
- 'd' => DefaultImpl,
- 'I' => Trait,
- 'S' => Struct(VariantKind::Struct),
- 's' => Struct(VariantKind::Tuple),
- 'u' => Struct(VariantKind::Unit),
- 'U' => Union,
- 'g' => PublicField,
- 'N' => InheritedField,
- c => bug!("unexpected family char: {}", c)
- }
+ item.get(tag_items_data_item_family).decoder().decode()
}
fn item_visibility(item: rbml::Doc) -> ty::Visibility {
match reader::maybe_get_doc(item, tag_items_data_item_visibility) {
None => ty::Visibility::Public,
- Some(visibility_doc) => {
- match reader::doc_as_u8(visibility_doc) as char {
- 'y' => ty::Visibility::Public,
- 'i' => ty::Visibility::PrivateExternal,
- _ => bug!("unknown visibility character")
- }
- }
- }
-}
-
-fn fn_constness(item: rbml::Doc) -> hir::Constness {
- match reader::maybe_get_doc(item, tag_items_data_item_constness) {
- None => hir::Constness::NotConst,
- Some(constness_doc) => {
- match reader::doc_as_u8(constness_doc) as char {
- 'c' => hir::Constness::Const,
- 'n' => hir::Constness::NotConst,
- _ => bug!("unknown constness character")
- }
- }
+ Some(visibility_doc) => visibility_doc.decoder().decode()
}
}
fn item_defaultness(item: rbml::Doc) -> hir::Defaultness {
match reader::maybe_get_doc(item, tag_items_data_item_defaultness) {
None => hir::Defaultness::Default, // should occur only for default impls on traits
- Some(defaultness_doc) => {
- match reader::doc_as_u8(defaultness_doc) as char {
- 'd' => hir::Defaultness::Default,
- 'f' => hir::Defaultness::Final,
- _ => bug!("unknown defaultness character")
- }
- }
- }
-}
-
-fn item_sort(item: rbml::Doc) -> Option<char> {
- reader::tagged_docs(item, tag_item_trait_item_sort).nth(0).map(|doc| {
- doc.as_str().as_bytes()[0] as char
- })
-}
-
-fn untranslated_def_id(d: rbml::Doc) -> DefId {
- let id = reader::doc_as_u64(d);
- DefId {
- krate: CrateNum::from_u32((id >> 32) as u32),
- index: DefIndex::from_u32((id & 0xFFFF_FFFF) as u32)
+ Some(defaultness_doc) => defaultness_doc.decoder().decode()
}
}
-fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId {
- let def_id = untranslated_def_id(d);
- translate_def_id(cdata, def_id)
-}
-
fn item_parent_item(cdata: Cmd, d: rbml::Doc) -> Option<DefId> {
- reader::tagged_docs(d, tag_items_data_parent_item).nth(0).map(|did| {
- translated_def_id(cdata, did)
+ reader::maybe_get_doc(d, tag_items_data_parent_item).map(|did| {
+ let mut dcx = did.decoder();
+ dcx.cdata = Some(cdata);
+ dcx.decode()
})
}
fn item_require_parent_item(cdata: Cmd, d: rbml::Doc) -> DefId {
- translated_def_id(cdata, reader::get_doc(d, tag_items_data_parent_item))
+ let mut dcx = d.get(tag_items_data_parent_item).decoder();
+ dcx.cdata = Some(cdata);
+ dcx.decode()
}
fn item_def_id(d: rbml::Doc, cdata: Cmd) -> DefId {
- translated_def_id(cdata, reader::get_doc(d, tag_def_id))
-}
-
-fn reexports<'a>(d: rbml::Doc<'a>) -> reader::TaggedDocsIterator<'a> {
- reader::tagged_docs(d, tag_items_data_item_reexport)
-}
-
-fn variant_disr_val(d: rbml::Doc) -> u64 {
- let val_doc = reader::get_doc(d, tag_disr_val);
- reader::with_doc_data(val_doc, |data| {
- str::from_utf8(data).unwrap().parse().unwrap()
- })
+ DefId {
+ krate: cdata.cnum,
+ index: d.get(tag_def_index).decoder().decode()
+ }
}
fn doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd) -> Ty<'tcx> {
let mut dcx = tp.decoder();
dcx.tcx = Some(tcx);
dcx.cdata = Some(cdata);
- Decodable::decode(&mut dcx).unwrap()
+ dcx.decode()
})
}
let mut dcx = doc.decoder();
dcx.tcx = Some(tcx);
dcx.cdata = Some(cdata);
- Decodable::decode(&mut dcx).unwrap()
-}
-
-fn item_trait_ref<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd)
- -> ty::TraitRef<'tcx> {
- let tp = reader::get_doc(doc, tag_item_trait_ref);
- doc_trait_ref(tp, tcx, cdata)
+ dcx.decode()
}
fn item_name(item: rbml::Doc) -> ast::Name {
fn maybe_item_name(item: rbml::Doc) -> Option<ast::Name> {
reader::maybe_get_doc(item, tag_paths_data_name).map(|name| {
- let string = name.as_str();
- token::intern(string)
+ name.decoder().decode()
})
}
-fn family_to_variant_kind<'tcx>(family: Family) -> Option<ty::VariantKind> {
- match family {
- Struct(VariantKind::Struct) | Variant(VariantKind::Struct) | Union =>
- 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,
- }
-}
-
-fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: DefId) -> DefLike {
- let fam = item_family(item);
- match fam {
- Constant => {
- // Check whether we have an associated const item.
- match item_sort(item) {
- Some('C') | Some('c') => {
- DlDef(Def::AssociatedConst(did))
- }
- _ => {
- // Regular const item.
- DlDef(Def::Const(did))
- }
- }
- }
- ImmStatic => DlDef(Def::Static(did, false)),
- MutStatic => DlDef(Def::Static(did, true)),
- Struct(..) => DlDef(Def::Struct(did)),
- Union => DlDef(Def::Union(did)),
- Fn => DlDef(Def::Fn(did)),
- Method | StaticMethod => {
- DlDef(Def::Method(did))
+fn item_to_def(cdata: Cmd, item: rbml::Doc, did: DefId) -> Option<Def> {
+ Some(match item_family(item) {
+ Family::Const => Def::Const(did),
+ Family::AssociatedConst => Def::AssociatedConst(did),
+ Family::ImmStatic => Def::Static(did, false),
+ Family::MutStatic => Def::Static(did, true),
+ Family::Struct(..) => Def::Struct(did),
+ Family::Union => Def::Union(did),
+ Family::Fn => Def::Fn(did),
+ Family::Method => Def::Method(did),
+ Family::Type => Def::TyAlias(did),
+ Family::AssociatedType => {
+ Def::AssociatedTy(item_require_parent_item(cdata, item), did)
}
- Type => {
- if item_sort(item) == Some('t') {
- let trait_did = item_require_parent_item(cdata, item);
- DlDef(Def::AssociatedTy(trait_did, did))
- } else {
- DlDef(Def::TyAlias(did))
- }
+ Family::Mod => Def::Mod(did),
+ Family::ForeignMod => Def::ForeignMod(did),
+ Family::Variant(..) => {
+ Def::Variant(item_require_parent_item(cdata, item), did)
}
- Mod => DlDef(Def::Mod(did)),
- ForeignMod => DlDef(Def::ForeignMod(did)),
- Variant(..) => {
- let enum_did = item_require_parent_item(cdata, item);
- DlDef(Def::Variant(enum_did, did))
+ Family::Trait => Def::Trait(did),
+ Family::Enum => Def::Enum(did),
+
+ Family::Impl |
+ Family::DefaultImpl |
+ Family::PublicField |
+ Family::InheritedField => {
+ return None
}
- Trait => DlDef(Def::Trait(did)),
- Enum => DlDef(Def::Enum(did)),
- Impl | DefaultImpl => DlImpl(did),
- PublicField | InheritedField => DlField,
- }
-}
-
-fn parse_unsafety(item_doc: rbml::Doc) -> hir::Unsafety {
- let unsafety_doc = reader::get_doc(item_doc, tag_unsafety);
- if reader::doc_as_u8(unsafety_doc) != 0 {
- hir::Unsafety::Unsafe
- } else {
- hir::Unsafety::Normal
- }
-}
-
-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
-}
-
-fn parse_polarity(item_doc: rbml::Doc) -> hir::ImplPolarity {
- let polarity_doc = reader::get_doc(item_doc, tag_polarity);
- if reader::doc_as_u8(polarity_doc) != 0 {
- hir::ImplPolarity::Negative
- } else {
- hir::ImplPolarity::Positive
- }
+ })
}
fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
- let names_doc = reader::get_doc(item_doc, tag_associated_type_names);
- reader::tagged_docs(names_doc, tag_associated_type_name)
- .map(|name_doc| token::intern(name_doc.as_str()))
- .collect()
+ item_doc.get(tag_associated_type_names).decoder().decode()
}
pub fn get_trait_def<'a, 'tcx>(cdata: Cmd,
{
let item_doc = cdata.lookup_item(item_id);
let generics = doc_generics(item_doc, tcx, cdata);
- let unsafety = parse_unsafety(item_doc);
+ let unsafety = item_doc.get(tag_unsafety).decoder().decode();
let associated_type_names = parse_associated_type_names(item_doc);
- let paren_sugar = parse_paren_sugar(item_doc);
+ let paren_sugar = item_doc.get(tag_paren_sugar).decoder().decode();
+ let trait_ref = doc_trait_ref(item_doc.get(tag_item_trait_ref), tcx, cdata);
let def_path = def_path(cdata, item_id).unwrap();
ty::TraitDef::new(unsafety,
paren_sugar,
generics,
- item_trait_ref(item_doc, tcx, cdata),
+ trait_ref,
associated_type_names,
def_path.deterministic_hash(tcx))
}
-> ty::AdtDefMaster<'tcx>
{
fn expect_variant_kind(family: Family) -> ty::VariantKind {
- match family_to_variant_kind(family) {
- Some(kind) => kind,
+ match family {
+ Struct(kind) | Variant(kind) => kind,
+ Union => ty::VariantKind::Struct,
_ => bug!("unexpected family: {:?}", family),
}
}
fn get_enum_variants<'tcx>(cdata: Cmd, doc: rbml::Doc) -> Vec<ty::VariantDefData<'tcx, 'tcx>> {
- reader::tagged_docs(doc, tag_items_data_item_variant).map(|p| {
- let did = translated_def_id(cdata, p);
+ let mut dcx = doc.get(tag_mod_children).decoder();
+ dcx.cdata = Some(cdata);
+
+ dcx.seq().map(|did: DefId| {
let item = cdata.lookup_item(did.index);
- let disr = variant_disr_val(item);
+ let disr = item.get(tag_disr_val).decoder().decode();
ty::VariantDefData {
did: did,
name: item_name(item),
}).collect()
}
fn get_variant_fields<'tcx>(cdata: Cmd, doc: rbml::Doc) -> Vec<ty::FieldDefData<'tcx, 'tcx>> {
- let mut index = 0;
- reader::tagged_docs(doc, tag_item_field).map(|f| {
- let ff = item_family(f);
- match ff {
- PublicField | InheritedField => {},
- _ => bug!("expected field, found {:?}", ff)
+ let mut dcx = doc.get(tag_item_fields).decoder();
+ dcx.cdata = Some(cdata);
+
+ dcx.seq().map(|did: DefId| {
+ let f = cdata.lookup_item(did.index);
+ let vis = match item_family(f) {
+ PublicField => ty::Visibility::Public,
+ InheritedField => ty::Visibility::PrivateExternal,
+ _ => bug!()
};
- ty::FieldDefData::new(item_def_id(f, cdata),
- item_name(f),
- struct_field_family_to_visibility(ff))
- }).chain(reader::tagged_docs(doc, tag_item_unnamed_field).map(|f| {
- let ff = item_family(f);
- let name = token::with_ident_interner(|interner| interner.intern(index.to_string()));
- index += 1;
- ty::FieldDefData::new(item_def_id(f, cdata), name,
- struct_field_family_to_visibility(ff))
- })).collect()
+ ty::FieldDefData::new(did, item_name(f), vis)
+ }).collect()
}
fn get_struct_variant<'tcx>(cdata: Cmd,
doc: rbml::Doc,
Struct(..) => {
// Use separate constructor id for unit/tuple structs and reuse did for braced structs.
ctor_did = reader::maybe_get_doc(doc, tag_items_data_item_struct_ctor).map(|ctor_doc| {
- translated_def_id(cdata, ctor_doc)
+ let mut dcx = ctor_doc.decoder();
+ dcx.cdata = Some(cdata);
+ dcx.decode()
});
(AdtKind::Struct, vec![get_struct_variant(cdata, doc, ctor_did.unwrap_or(did))])
}
pub fn get_stability(cdata: Cmd, id: DefIndex) -> Option<attr::Stability> {
let item = cdata.lookup_item(id);
reader::maybe_get_doc(item, tag_items_data_item_stability).map(|doc| {
- Decodable::decode(&mut doc.decoder()).unwrap()
+ doc.decoder().decode()
})
}
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| {
- Decodable::decode(&mut doc.decoder()).unwrap()
+ doc.decoder().decode()
})
}
pub fn get_parent_impl(cdata: Cmd, id: DefIndex) -> Option<DefId> {
let item = cdata.lookup_item(id);
reader::maybe_get_doc(item, tag_items_data_parent_impl).map(|doc| {
- translated_def_id(cdata, doc)
+ let mut dcx = doc.decoder();
+ dcx.cdata = Some(cdata);
+ dcx.decode()
})
}
pub fn get_repr_attrs(cdata: Cmd, id: DefIndex) -> Vec<attr::ReprAttr> {
let item = cdata.lookup_item(id);
reader::maybe_get_doc(item, tag_items_data_item_repr).map_or(vec![], |doc| {
- Decodable::decode(&mut doc.decoder()).unwrap()
+ doc.decoder().decode()
})
}
-pub fn get_impl_polarity(cdata: Cmd, id: DefIndex) -> Option<hir::ImplPolarity> {
- let item_doc = cdata.lookup_item(id);
- let fam = item_family(item_doc);
- match fam {
- Family::Impl => {
- Some(parse_polarity(item_doc))
- }
- _ => None
- }
+pub fn get_impl_polarity(cdata: Cmd, id: DefIndex) -> hir::ImplPolarity {
+ cdata.lookup_item(id).get(tag_polarity).decoder().decode()
}
pub fn get_custom_coerce_unsized_kind(
{
let item_doc = cdata.lookup_item(id);
reader::maybe_get_doc(item_doc, tag_impl_coerce_unsized_kind).map(|kind_doc| {
- Decodable::decode(&mut kind_doc.decoder()).unwrap()
+ kind_doc.decoder().decode()
})
}
-> Option<ty::TraitRef<'tcx>>
{
let item_doc = cdata.lookup_item(id);
- let fam = item_family(item_doc);
- match fam {
- Family::Impl | Family::DefaultImpl => {
- reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
- doc_trait_ref(tp, tcx, cdata)
- })
- }
- _ => None
- }
+ reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
+ doc_trait_ref(tp, tcx, cdata)
+ })
}
/// Iterates over the language items in the given crate.
-pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
- F: FnMut(DefIndex, usize) -> bool,
-{
- let root = rbml::Doc::new(cdata.data());
- let lang_items = reader::get_doc(root, tag_lang_items);
- reader::tagged_docs(lang_items, tag_lang_items_item).all(|item_doc| {
- let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
- let id = reader::doc_as_u32(id_doc) as usize;
- let index_doc = reader::get_doc(item_doc, tag_lang_items_item_index);
- let index = DefIndex::from_u32(reader::doc_as_u32(index_doc));
-
- f(index, id)
- })
+pub fn get_lang_items(cdata: Cmd) -> Vec<(DefIndex, usize)> {
+ rbml::Doc::new(cdata.data()).get(tag_lang_items).decoder().decode()
}
-fn each_child_of_item_or_crate<F, G>(cdata: Cmd,
- item_doc: rbml::Doc,
- mut get_crate_data: G,
- mut callback: F) where
- F: FnMut(DefLike, ast::Name, ty::Visibility),
- G: FnMut(CrateNum) -> Rc<CrateMetadata>,
+
+/// Iterates over each child of the given item.
+pub fn each_child_of_item<F, G>(cdata: Cmd, id: DefIndex,
+ mut get_crate_data: G,
+ mut callback: F)
+ where F: FnMut(Def, ast::Name, ty::Visibility),
+ G: FnMut(CrateNum) -> Rc<CrateMetadata>,
{
- // Iterate over all children.
- for child_info_doc in reader::tagged_docs(item_doc, tag_mod_child) {
- let child_def_id = translated_def_id(cdata, child_info_doc);
+ // Find the item.
+ let item_doc = match cdata.get_item(id) {
+ None => return,
+ Some(item_doc) => item_doc,
+ };
+
+ let mut dcx = match reader::maybe_get_doc(item_doc, tag_mod_children) {
+ Some(doc) => doc.decoder(),
+ None => return
+ };
+ dcx.cdata = Some(cdata);
+ // Iterate over all children.
+ for child_def_id in dcx.seq_mut::<DefId>() {
// This item may be in yet another crate if it was the child of a
// reexport.
let crate_data = if child_def_id.krate == cdata.cnum {
// Get the item.
if let Some(child_item_doc) = crate_data.get_item(child_def_id.index) {
// Hand off the item to the callback.
- let child_name = item_name(child_item_doc);
- let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
- let visibility = item_visibility(child_item_doc);
- callback(def_like, child_name, visibility);
+ if let Some(def) = item_to_def(crate_data, child_item_doc, child_def_id) {
+ let child_name = item_name(child_item_doc);
+ let visibility = item_visibility(child_item_doc);
+ callback(def, child_name, visibility);
+ }
}
}
- for reexport_doc in reexports(item_doc) {
- let def_id_doc = reader::get_doc(reexport_doc,
- tag_items_data_item_reexport_def_id);
- let child_def_id = translated_def_id(cdata, def_id_doc);
-
- let name_doc = reader::get_doc(reexport_doc,
- tag_items_data_item_reexport_name);
- let name = name_doc.as_str();
-
+ for exp in dcx.seq_mut::<def::Export>() {
// This reexport may be in yet another crate.
- let crate_data = if child_def_id.krate == cdata.cnum {
+ let crate_data = if exp.def_id.krate == cdata.cnum {
None
} else {
- Some(get_crate_data(child_def_id.krate))
+ Some(get_crate_data(exp.def_id.krate))
};
let crate_data = match crate_data {
Some(ref cdata) => &**cdata,
};
// Get the item.
- if let Some(child_item_doc) = crate_data.get_item(child_def_id.index) {
+ if let Some(child_item_doc) = crate_data.get_item(exp.def_id.index) {
// Hand off the item to the callback.
- let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
- // These items have a public visibility because they're part of
- // a public re-export.
- callback(def_like, token::intern(name), ty::Visibility::Public);
+ if let Some(def) = item_to_def(crate_data, child_item_doc, exp.def_id) {
+ // These items have a public visibility because they're part of
+ // a public re-export.
+ callback(def, exp.name, ty::Visibility::Public);
+ }
}
}
}
-/// Iterates over each child of the given item.
-pub fn each_child_of_item<F, G>(cdata: Cmd, id: DefIndex, get_crate_data: G, callback: F)
- where F: FnMut(DefLike, ast::Name, ty::Visibility),
- G: FnMut(CrateNum) -> Rc<CrateMetadata>,
-{
- // Find the item.
- let item_doc = match cdata.get_item(id) {
- None => return,
- Some(item_doc) => item_doc,
- };
-
- each_child_of_item_or_crate(cdata, item_doc, get_crate_data, callback)
-}
-
-/// Iterates over all the top-level crate items.
-pub fn each_top_level_item_of_crate<F, G>(cdata: Cmd, get_crate_data: G, callback: F)
- where F: FnMut(DefLike, ast::Name, ty::Visibility),
- G: FnMut(CrateNum) -> Rc<CrateMetadata>,
-{
- each_child_of_item(cdata, CRATE_DEF_INDEX, get_crate_data, callback)
-}
-
pub fn get_item_name(cdata: Cmd, id: DefIndex) -> ast::Name {
item_name(cdata.lookup_item(id))
}
let mut dcx = mir_doc.decoder();
dcx.tcx = Some(tcx);
dcx.cdata = Some(cdata);
- Decodable::decode(&mut dcx).unwrap()
+ dcx.decode()
})
}
-fn get_explicit_self<'a, 'tcx>(item: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>)
+fn get_explicit_self<'a, 'tcx>(cdata: Cmd, item: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> ty::ExplicitSelfCategory<'tcx> {
- fn get_mutability(ch: u8) -> hir::Mutability {
- match ch as char {
- 'i' => hir::MutImmutable,
- 'm' => hir::MutMutable,
- _ => bug!("unknown mutability character: `{}`", ch as char),
- }
- }
+ let mut dcx = item.get(tag_item_trait_method_explicit_self).decoder();
+ dcx.cdata = Some(cdata);
+ dcx.tcx = Some(tcx);
- let explicit_self_doc = reader::get_doc(item, tag_item_trait_method_explicit_self);
- let string = explicit_self_doc.as_str();
-
- let explicit_self_kind = string.as_bytes()[0];
- match explicit_self_kind as char {
- 's' => ty::ExplicitSelfCategory::Static,
- 'v' => ty::ExplicitSelfCategory::ByValue,
- '~' => ty::ExplicitSelfCategory::ByBox,
- // FIXME(#4846) expl. region
- '&' => {
- ty::ExplicitSelfCategory::ByReference(
- tcx.mk_region(ty::ReEmpty),
- get_mutability(string.as_bytes()[1]))
- }
- _ => bug!("unknown self type code: `{}`", explicit_self_kind as char)
- }
+ dcx.decode()
}
/// Returns the def IDs of all the items in the given implementation.
-pub fn get_impl_items(cdata: Cmd, impl_id: DefIndex)
- -> Vec<ty::ImplOrTraitItemId> {
- reader::tagged_docs(cdata.lookup_item(impl_id), tag_item_impl_item).map(|doc| {
- let def_id = item_def_id(doc, cdata);
- match item_sort(doc) {
- Some('C') | Some('c') => ty::ConstTraitItemId(def_id),
- Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
- Some('t') => ty::TypeTraitItemId(def_id),
- _ => bug!("unknown impl item sort"),
+pub fn get_impl_or_trait_items(cdata: Cmd, impl_id: DefIndex)
+ -> Vec<ty::ImplOrTraitItemId> {
+ let item = cdata.lookup_item(impl_id);
+ let mut dcx = item.get(tag_mod_children).decoder();
+ dcx.cdata = Some(cdata);
+ dcx.seq().map(|def_id: DefId| {
+ match item_to_def(cdata, cdata.lookup_item(def_id.index), def_id) {
+ Some(Def::AssociatedConst(def_id)) => ty::ConstTraitItemId(def_id),
+ Some(Def::Method(def_id)) => ty::MethodTraitItemId(def_id),
+ Some(Def::AssociatedTy(_, def_id)) => ty::TypeTraitItemId(def_id),
+ def => bug!("get_impl_or_trait_items: invalid def {:?}", def)
}
}).collect()
}
} else {
return None;
};
- let container_doc = cdata.lookup_item(container_id.index);
- let container = match item_family(container_doc) {
+ let container = match item_family(cdata.lookup_item(container_id.index)) {
Trait => TraitContainer(container_id),
_ => ImplContainer(container_id),
};
let vis = item_visibility(item_doc);
let defaultness = item_defaultness(item_doc);
- Some(match item_sort(item_doc) {
- sort @ Some('C') | sort @ Some('c') => {
+ Some(match item_family(item_doc) {
+ Family::AssociatedConst => {
let ty = doc_type(item_doc, tcx, cdata);
ty::ConstTraitItem(Rc::new(ty::AssociatedConst {
name: name,
defaultness: defaultness,
def_id: def_id,
container: container,
- has_value: sort == Some('C')
+ has_value: item_doc.get(tag_item_trait_item_has_body).decoder().decode(),
}))
}
- Some('r') | Some('p') => {
+ Family::Method => {
let generics = doc_generics(item_doc, tcx, cdata);
let predicates = doc_predicates(item_doc, tcx, cdata, tag_item_predicates);
let ity = tcx.lookup_item_type(def_id).ty;
"the type {:?} of the method {:?} is not a function?",
ity, name)
};
- let explicit_self = get_explicit_self(item_doc, tcx);
-
- ty::MethodTraitItem(Rc::new(ty::Method::new(name,
- generics,
- predicates,
- fty,
- explicit_self,
- vis,
- defaultness,
- def_id,
- container)))
+ let explicit_self = get_explicit_self(cdata, item_doc, tcx);
+
+ ty::MethodTraitItem(Rc::new(ty::Method {
+ name: name,
+ generics: generics,
+ predicates: predicates,
+ fty: fty,
+ explicit_self: explicit_self,
+ vis: vis,
+ defaultness: defaultness,
+ has_body: item_doc.get(tag_item_trait_item_has_body).decoder().decode(),
+ def_id: def_id,
+ container: container,
+ }))
}
- Some('t') => {
+ Family::AssociatedType => {
let ty = maybe_doc_type(item_doc, tcx, cdata);
ty::TypeTraitItem(Rc::new(ty::AssociatedType {
name: name,
})
}
-pub fn get_trait_item_def_ids(cdata: Cmd, id: DefIndex)
- -> Vec<ty::ImplOrTraitItemId> {
- let item = cdata.lookup_item(id);
- reader::tagged_docs(item, tag_item_trait_item).map(|mth| {
- let def_id = item_def_id(mth, cdata);
- match item_sort(mth) {
- Some('C') | Some('c') => ty::ConstTraitItemId(def_id),
- Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
- Some('t') => ty::TypeTraitItemId(def_id),
- _ => bug!("unknown trait item sort"),
- }
- }).collect()
-}
-
pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> Vec<ty::Variance> {
let item_doc = cdata.lookup_item(id);
- let variance_doc = reader::get_doc(item_doc, tag_item_variances);
- Decodable::decode(&mut variance_doc.decoder()).unwrap()
-}
-
-pub fn get_provided_trait_methods<'a, 'tcx>(cdata: Cmd,
- id: DefIndex,
- tcx: TyCtxt<'a, 'tcx, 'tcx>)
- -> Vec<Rc<ty::Method<'tcx>>> {
- let item = cdata.lookup_item(id);
-
- reader::tagged_docs(item, tag_item_trait_item).filter_map(|mth_id| {
- let did = item_def_id(mth_id, cdata);
- let mth = cdata.lookup_item(did.index);
-
- if item_sort(mth) == Some('p') {
- let trait_item = get_impl_or_trait_item(cdata, did.index, tcx);
- if let Some(ty::MethodTraitItem(ref method)) = trait_item {
- Some((*method).clone())
- } else {
- None
- }
- } else {
- None
- }
- }).collect()
-}
-
-pub fn get_associated_consts<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
- -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
- let item = cdata.lookup_item(id);
-
- [tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| {
- reader::tagged_docs(item, tag).filter_map(|ac_id| {
- let did = item_def_id(ac_id, cdata);
- let ac_doc = cdata.lookup_item(did.index);
-
- match item_sort(ac_doc) {
- Some('C') | Some('c') => {
- let trait_item = get_impl_or_trait_item(cdata, did.index, tcx);
- if let Some(ty::ConstTraitItem(ref ac)) = trait_item {
- Some((*ac).clone())
- } else {
- None
- }
- }
- _ => None
- }
- })
- }).collect()
-}
-
-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))
+ item_doc.get(tag_item_variances).decoder().decode()
}
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))
+ reader::maybe_get_doc(item, tag_items_data_item_struct_ctor).map(|ctor_doc| {
+ let mut dcx = ctor_doc.decoder();
+ dcx.cdata = Some(cdata);
+ dcx.decode()
+ })
}
/// If node_id is the constructor of a tuple struct, retrieve the NodeId of
-> Option<DefId>
{
let item = cdata.lookup_item(node_id);
- reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor).next().map(|_| {
- item_require_parent_item(cdata, item)
+ reader::maybe_get_doc(item, tag_items_data_item_is_tuple_struct_ctor).and_then(|doc| {
+ if doc.decoder().decode() {
+ Some(item_require_parent_item(cdata, item))
+ } else {
+ None
+ }
})
}
get_attributes(item)
}
-pub fn get_struct_field_attrs(cdata: Cmd) -> FnvHashMap<DefId, Vec<ast::Attribute>> {
- let data = rbml::Doc::new(cdata.data());
- let fields = reader::get_doc(data, tag_struct_fields);
- reader::tagged_docs(fields, tag_struct_field).map(|field| {
- let def_id = translated_def_id(cdata, reader::get_doc(field, tag_def_id));
- let attrs = get_attributes(field);
- (def_id, attrs)
- }).collect()
-}
-
-fn struct_field_family_to_visibility(family: Family) -> ty::Visibility {
- match family {
- PublicField => ty::Visibility::Public,
- InheritedField => ty::Visibility::PrivateExternal,
- _ => bug!()
- }
-}
-
pub fn get_struct_field_names(cdata: Cmd, id: DefIndex) -> Vec<ast::Name> {
- let item = cdata.lookup_item(id);
- let mut index = 0;
- reader::tagged_docs(item, tag_item_field).map(|an_item| {
- item_name(an_item)
- }).chain(reader::tagged_docs(item, tag_item_unnamed_field).map(|_| {
- let name = token::with_ident_interner(|interner| interner.intern(index.to_string()));
- index += 1;
- name
- })).collect()
+ let mut dcx = cdata.lookup_item(id).get(tag_item_fields).decoder();
+ dcx.cdata = Some(cdata);
+
+ dcx.seq().map(|did: DefId| {
+ item_name(cdata.lookup_item(did.index))
+ }).collect()
}
fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
reader::maybe_get_doc(md, tag_attributes).map_or(vec![], |attrs_doc| {
- let mut attrs = Vec::<ast::Attribute>::decode(&mut attrs_doc.decoder()).unwrap();
+ let mut attrs = attrs_doc.decoder().decode::<Vec<ast::Attribute>>();
// Need new unique IDs: old thread-local IDs won't map to new threads.
for attr in attrs.iter_mut() {
})
}
-fn list_crate_attributes(md: rbml::Doc, hash: &Svh,
- out: &mut io::Write) -> io::Result<()> {
- write!(out, "=Crate Attributes ({})=\n", *hash)?;
-
- let r = get_attributes(md);
- for attr in &r {
- write!(out, "{}\n", pprust::attribute_to_string(attr))?;
- }
-
- write!(out, "\n\n")
-}
-
-pub fn get_crate_attributes(data: &[u8]) -> Vec<ast::Attribute> {
- get_attributes(rbml::Doc::new(data))
-}
-
#[derive(Clone)]
pub struct CrateDep {
pub cnum: CrateNum,
}
pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
- let cratedoc = rbml::Doc::new(data);
- let depsdoc = reader::get_doc(cratedoc, tag_crate_deps);
+ let dcx = rbml::Doc::new(data).get(tag_crate_deps).decoder();
- fn docstr(doc: rbml::Doc, tag_: usize) -> String {
- let d = reader::get_doc(doc, tag_);
- d.as_str().to_string()
- }
-
- reader::tagged_docs(depsdoc, tag_crate_dep).enumerate().map(|(crate_num, depdoc)| {
- let name = docstr(depdoc, tag_crate_dep_crate_name);
- let hash = Svh::new(reader::doc_as_u64(reader::get_doc(depdoc, tag_crate_dep_hash)));
- let doc = reader::get_doc(depdoc, tag_crate_dep_explicitly_linked);
- let explicitly_linked = reader::doc_as_u8(doc) != 0;
+ dcx.seq().enumerate().map(|(crate_num, (name, hash, explicitly_linked))| {
CrateDep {
cnum: CrateNum::new(crate_num + 1),
name: name,
pub fn maybe_get_crate_hash(data: &[u8]) -> Option<Svh> {
let cratedoc = rbml::Doc::new(data);
reader::maybe_get_doc(cratedoc, tag_crate_hash).map(|doc| {
- Svh::new(reader::doc_as_u64(doc))
+ doc.decoder().decode()
})
}
pub fn get_crate_hash(data: &[u8]) -> Svh {
- let cratedoc = rbml::Doc::new(data);
- let hashdoc = reader::get_doc(cratedoc, tag_crate_hash);
- Svh::new(reader::doc_as_u64(hashdoc))
+ rbml::Doc::new(data).get(tag_crate_hash).decoder().decode()
}
-pub fn maybe_get_crate_name(data: &[u8]) -> Option<&str> {
+pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
let cratedoc = rbml::Doc::new(data);
reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| {
- doc.as_str()
+ doc.decoder().decode()
})
}
-pub fn get_crate_disambiguator<'a>(data: &'a [u8]) -> &'a str {
- let crate_doc = rbml::Doc::new(data);
- let disambiguator_doc = reader::get_doc(crate_doc, tag_crate_disambiguator);
- let slice: &'a str = disambiguator_doc.as_str();
- slice
+pub fn get_crate_disambiguator(data: &[u8]) -> String {
+ rbml::Doc::new(data).get(tag_crate_disambiguator).decoder().decode()
}
pub fn get_crate_triple(data: &[u8]) -> Option<String> {
let cratedoc = rbml::Doc::new(data);
let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);
- triple_doc.map(|s| s.as_str().to_string())
+ triple_doc.map(|s| s.decoder().decode())
}
-pub fn get_crate_name(data: &[u8]) -> &str {
+pub fn get_crate_name(data: &[u8]) -> String {
maybe_get_crate_name(data).expect("no crate name in crate")
}
pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> {
- let hash = get_crate_hash(bytes);
- let md = rbml::Doc::new(bytes);
- list_crate_attributes(md, &hash, out)?;
list_crate_deps(bytes, out)
}
-// 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.
-pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId {
- if did.is_local() {
- return DefId { krate: cdata.cnum, index: did.index };
- }
-
- DefId {
- krate: cdata.cnum_map.borrow()[did.krate],
- index: did.index
- }
-}
-
// Translate a DefId from the current compilation environment to a DefId
// for an external crate.
fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> {
where F: FnMut(DefId),
{
let item_doc = cdata.lookup_item(id);
- for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_inherent_impl) {
- if reader::maybe_get_doc(impl_doc, tag_item_trait_ref).is_none() {
- callback(item_def_id(impl_doc, cdata));
- }
+ let mut dcx = item_doc.get(tag_items_data_item_inherent_impls).decoder();
+ dcx.cdata = Some(cdata);
+
+ for impl_def_id in dcx.seq() {
+ callback(impl_def_id);
}
}
pub fn each_implementation_for_trait<F>(cdata: Cmd,
- def_id: DefId,
+ filter: Option<DefId>,
mut callback: F) where
F: FnMut(DefId),
{
// 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 filter = match filter.map(|def_id| reverse_translate_def_id(cdata, def_id)) {
+ Some(Some(def_id)) => Some(def_id),
+ Some(None) => return,
+ None => None
+ };
+
+ // FIXME(eddyb) Make this O(1) instead of O(n).
+ for trait_doc in rbml::Doc::new(cdata.data()).get(tag_impls).children() {
+ let mut dcx = trait_doc.decoder();
+ dcx.cdata = Some(cdata);
- let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls);
- 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 {
+ let (krate, index) = dcx.decode();
+ if let Some(local_did) = filter {
+ if (local_did.krate.as_u32(), local_did.index) != (krate, index) {
continue;
}
- for impl_doc in reader::tagged_docs(trait_doc, tag_impls_trait_impl) {
- callback(translated_def_id(cdata, impl_doc));
- }
+ }
+
+ for impl_def_id in dcx.seq() {
+ callback(impl_def_id);
}
}
}
pub fn get_native_libraries(cdata: Cmd)
-> Vec<(cstore::NativeLibraryKind, String)> {
- let libraries = reader::get_doc(rbml::Doc::new(cdata.data()),
- tag_native_libraries);
- reader::tagged_docs(libraries, tag_native_libraries_lib).map(|lib_doc| {
- let kind_doc = reader::get_doc(lib_doc, tag_native_libraries_kind);
- let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name);
- let kind: cstore::NativeLibraryKind =
- cstore::NativeLibraryKind::from_u32(reader::doc_as_u32(kind_doc)).unwrap();
- let name = name_doc.as_str().to_string();
- (kind, name)
- }).collect()
+ rbml::Doc::new(cdata.data()).get(tag_native_libraries).decoder().decode()
}
pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<DefIndex> {
reader::maybe_get_doc(rbml::Doc::new(data), tag_plugin_registrar_fn)
- .map(|doc| DefIndex::from_u32(reader::doc_as_u32(doc)))
+ .map(|doc| doc.decoder().decode())
}
pub fn each_exported_macro<F>(data: &[u8], mut f: F) where
F: FnMut(ast::Name, Vec<ast::Attribute>, Span, String) -> bool,
{
- let macros = reader::get_doc(rbml::Doc::new(data), tag_macro_defs);
- for macro_doc in reader::tagged_docs(macros, tag_macro_def) {
- let name = item_name(macro_doc);
- let attrs = get_attributes(macro_doc);
- let span = get_macro_span(macro_doc);
- let body = reader::get_doc(macro_doc, tag_macro_def_body);
- if !f(name, attrs, span, body.as_str().to_string()) {
+ let dcx = rbml::Doc::new(data).get(tag_macro_defs).decoder();
+ for (name, attrs, span, body) in dcx.seq() {
+ if !f(name, attrs, span, body) {
break;
}
}
pub fn get_derive_registrar_fn(data: &[u8]) -> Option<DefIndex> {
reader::maybe_get_doc(rbml::Doc::new(data), tag_macro_derive_registrar)
- .map(|doc| DefIndex::from_u32(reader::doc_as_u32(doc)))
-}
-
-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 };
+ .map(|doc| doc.decoder().decode())
}
pub fn get_dylib_dependency_formats(cdata: Cmd)
-> Vec<(CrateNum, LinkagePreference)>
{
- let formats = reader::get_doc(rbml::Doc::new(cdata.data()),
- tag_dylib_dependency_formats);
- let mut result = Vec::new();
-
- debug!("found dylib deps: {}", formats.as_str());
- for spec in formats.as_str().split(',') {
- if spec.is_empty() { continue }
- let mut split = spec.split(':');
- let cnum = split.next().unwrap();
- let link = split.next().unwrap();
- let cnum = CrateNum::new(cnum.parse().unwrap());
- let cnum = cdata.cnum_map.borrow()[cnum];
- result.push((cnum, if link == "d" {
- LinkagePreference::RequireDynamic
- } else {
- LinkagePreference::RequireStatic
- }));
- }
- return result;
-}
+ let dcx = rbml::Doc::new(cdata.data()).get(tag_dylib_dependency_formats).decoder();
-pub fn get_missing_lang_items(cdata: Cmd)
- -> Vec<lang_items::LangItem>
-{
- let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_lang_items);
- reader::tagged_docs(items, tag_lang_items_missing).map(|missing_docs| {
- lang_items::LangItem::from_u32(reader::doc_as_u32(missing_docs)).unwrap()
+ dcx.seq::<Option<_>>().enumerate().flat_map(|(i, link)| {
+ let cnum = CrateNum::new(i + 1);
+ link.map(|link| (cdata.cnum_map.borrow()[cnum], link))
}).collect()
}
+pub fn get_missing_lang_items(cdata: Cmd) -> Vec<lang_items::LangItem> {
+ rbml::Doc::new(cdata.data()).get(tag_lang_items_missing).decoder().decode()
+}
+
pub fn get_method_arg_names(cdata: Cmd, id: DefIndex) -> Vec<String> {
let method_doc = cdata.lookup_item(id);
match reader::maybe_get_doc(method_doc, tag_method_argument_names) {
- Some(args_doc) => {
- reader::tagged_docs(args_doc, tag_method_argument_name).map(|name_doc| {
- name_doc.as_str().to_string()
- }).collect()
- },
+ Some(args_doc) => args_doc.decoder().decode(),
None => vec![],
}
}
pub fn get_reachable_ids(cdata: Cmd) -> Vec<DefId> {
- let items = reader::get_doc(rbml::Doc::new(cdata.data()),
- tag_reachable_ids);
- reader::tagged_docs(items, tag_reachable_id).map(|doc| {
+ let dcx = rbml::Doc::new(cdata.data()).get(tag_reachable_ids).decoder();
+
+ dcx.seq().map(|index| {
DefId {
krate: cdata.cnum,
- index: DefIndex::from_u32(reader::doc_as_u32(doc)),
+ index: index,
}
}).collect()
}
-pub fn is_typedef(cdata: Cmd, id: DefIndex) -> bool {
- let item_doc = cdata.lookup_item(id);
- match item_family(item_doc) {
- Type => true,
- _ => false,
- }
-}
-
pub fn is_const_fn(cdata: Cmd, id: DefIndex) -> bool {
- let item_doc = cdata.lookup_item(id);
- match fn_constness(item_doc) {
- hir::Constness::Const => true,
- hir::Constness::NotConst => false,
+ match reader::maybe_get_doc(cdata.lookup_item(id), tag_items_data_item_constness) {
+ None => false,
+ Some(doc) => {
+ match doc.decoder().decode() {
+ hir::Constness::Const => true,
+ hir::Constness::NotConst => false,
+ }
+ }
}
}
item_family(parent_item_doc) == ForeignMod
}
-pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
- let item_doc = cdata.lookup_item(id);
- match item_family(item_doc) {
- Impl => true,
- _ => false,
- }
-}
-
fn doc_generics<'a, 'tcx>(base_doc: rbml::Doc,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
cdata: Cmd)
-> &'tcx ty::Generics<'tcx>
{
- let mut dcx = reader::get_doc(base_doc, tag_item_generics).decoder();
- dcx.tcx = Some(tcx);
- dcx.cdata = Some(cdata);
- tcx.alloc_generics(Decodable::decode(&mut dcx).unwrap())
-}
-
-fn doc_predicate<'a, 'tcx>(cdata: Cmd,
- doc: rbml::Doc,
- tcx: TyCtxt<'a, 'tcx, 'tcx>)
- -> ty::Predicate<'tcx>
-{
- let predicate_pos = cdata.xref_index.lookup(
- cdata.data(), reader::doc_as_u32(doc)).unwrap() as usize;
- let mut dcx = rbml::Doc {
- data: cdata.data(),
- start: predicate_pos,
- end: cdata.data().len(),
- }.decoder();
+ let mut dcx = base_doc.get(tag_item_generics).decoder();
dcx.tcx = Some(tcx);
dcx.cdata = Some(cdata);
- Decodable::decode(&mut dcx).unwrap()
+ tcx.alloc_generics(dcx.decode())
}
fn doc_predicates<'a, 'tcx>(base_doc: rbml::Doc,
tag: usize)
-> ty::GenericPredicates<'tcx>
{
- let doc = reader::get_doc(base_doc, tag);
+ let mut dcx = base_doc.get(tag).decoder();
+ dcx.cdata = Some(cdata);
ty::GenericPredicates {
- parent: item_parent_item(cdata, doc),
- predicates: reader::tagged_docs(doc, tag_predicate).map(|predicate_doc| {
- doc_predicate(cdata, predicate_doc, tcx)
+ parent: dcx.decode(),
+ predicates: dcx.seq().map(|offset| {
+ let predicate_pos = cdata.xref_index.lookup(
+ cdata.data(), offset).unwrap() as usize;
+ let mut dcx = rbml::Doc {
+ data: cdata.data(),
+ start: predicate_pos,
+ end: cdata.data().len(),
+ }.decoder();
+ dcx.tcx = Some(tcx);
+ dcx.cdata = Some(cdata);
+ dcx.decode()
}).collect()
}
}
pub fn is_defaulted_trait(cdata: Cmd, trait_id: DefIndex) -> bool {
- let trait_doc = cdata.lookup_item(trait_id);
- 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
+ cdata.lookup_item(trait_id).get(tag_defaulted_trait).decoder().decode()
}
pub fn is_default_impl(cdata: Cmd, impl_id: DefIndex) -> bool {
- let impl_doc = cdata.lookup_item(impl_id);
- item_family(impl_doc) == Family::DefaultImpl
+ item_family(cdata.lookup_item(impl_id)) == Family::DefaultImpl
}
pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<syntax_pos::FileMap> {
- let crate_doc = rbml::Doc::new(metadata);
- let cm_doc = reader::get_doc(crate_doc, tag_codemap);
-
- reader::tagged_docs(cm_doc, tag_codemap_filemap).map(|filemap_doc| {
- Decodable::decode(&mut filemap_doc.decoder()).unwrap()
- }).collect()
+ rbml::Doc::new(metadata).get(tag_codemap).decoder().decode()
}
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);
- ty::ClosureKind::decode(&mut closure_kind_doc.decoder()).unwrap()
+ cdata.lookup_item(closure_id).get(tag_items_closure_kind).decoder().decode()
}
pub fn closure_ty<'a, 'tcx>(cdata: Cmd, closure_id: DefIndex, tcx: TyCtxt<'a, 'tcx, '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);
+ let closure_ty_doc = closure_doc.get(tag_items_closure_ty);
let mut dcx = closure_ty_doc.decoder();
dcx.tcx = Some(tcx);
dcx.cdata = Some(cdata);
- Decodable::decode(&mut dcx).unwrap()
+ dcx.decode()
}
pub fn def_key(cdata: Cmd, id: DefIndex) -> hir_map::DefKey {
fn item_def_key(item_doc: rbml::Doc) -> hir_map::DefKey {
match reader::maybe_get_doc(item_doc, tag_def_key) {
Some(def_key_doc) => {
- let simple_key = def_key::DefKey::decode(&mut def_key_doc.decoder()).unwrap();
- let name = reader::maybe_get_doc(item_doc, tag_paths_data_name).map(|name| {
- token::intern(name.as_str()).as_str()
- });
+ let simple_key = def_key_doc.decoder().decode();
+ let name = maybe_item_name(item_doc).map(|name| name.as_str());
def_key::recover_def_key(simple_key, name)
}
None => {
}
pub fn get_panic_strategy(data: &[u8]) -> PanicStrategy {
- let crate_doc = rbml::Doc::new(data);
- let strat_doc = reader::get_doc(crate_doc, tag_panic_strategy);
- match reader::doc_as_u8(strat_doc) {
- b'U' => PanicStrategy::Unwind,
- b'A' => PanicStrategy::Abort,
- b => panic!("unknown panic strategy in metadata: {}", b),
- }
+ rbml::Doc::new(data).get(tag_panic_strategy).decoder().decode()
}
use def_key;
use index::{self, IndexData};
-use middle::cstore::{InlinedItemRef, LinkMeta};
+use middle::cstore::{InlinedItemRef, LinkMeta, LinkagePreference};
use rustc::hir::def;
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
use middle::dependency_format::Linkage;
use rustc::traits::specialization_graph;
use rustc::ty::{self, Ty, TyCtxt};
-use rustc::hir::svh::Svh;
use rustc::mir::mir_map::MirMap;
-use rustc::session::config::{self, PanicStrategy, CrateTypeRustcMacro};
+use rustc::session::config::{self, CrateTypeRustcMacro};
use rustc::util::nodemap::{FnvHashMap, NodeSet};
use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
-use rustc_serialize as serialize;
use std::cell::RefCell;
use std::intrinsics;
use std::io::prelude::*;
use std::io::Cursor;
+use std::mem;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use std::u32;
use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID};
use syntax::attr;
use syntax;
-use syntax_pos::BytePos;
use rbml;
use rustc::hir::{self, PatKind};
use rustc::hir::intravisit;
use rustc::hir::map::DefKey;
-use super::index_builder::{FromId, IndexBuilder, ItemContentBuilder, Untracked, XRef};
+use super::index_builder::{FromId, IndexBuilder, Untracked};
pub struct EncodeContext<'a, 'tcx: 'a> {
rbml_w: rbml::writer::Encoder<'a>,
reexports: &'a def::ExportMap,
link_meta: &'a LinkMeta,
cstore: &'a cstore::CStore,
- type_shorthands: RefCell<FnvHashMap<Ty<'tcx>, usize>>,
reachable: &'a NodeSet,
mir_map: &'a MirMap<'tcx>,
+
+ type_shorthands: RefCell<FnvHashMap<Ty<'tcx>, usize>>,
+ xrefs: FnvHashMap<XRef<'tcx>, u32>, // sequentially-assigned
}
+/// "interned" entries referenced by id
+#[derive(PartialEq, Eq, Hash)]
+enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) }
+
impl<'a, 'tcx> Deref for EncodeContext<'a, 'tcx> {
type Target = rbml::writer::Encoder<'a>;
fn deref(&self) -> &Self::Target {
}
}
-impl<'a, 'tcx> serialize::Encoder for ::encoder::EncodeContext<'a, 'tcx> {
- type Error = <opaque::Encoder<'a> as serialize::Encoder>::Error;
+impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
+ type Error = <opaque::Encoder<'a> as Encoder>::Error;
fn emit_nil(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
+ fn seq<I, F, T>(&mut self, iter: I, mut f: F)
+ where I: IntoIterator,
+ I::IntoIter: ExactSizeIterator,
+ F: FnMut(&mut Self, I::Item) -> T,
+ T: Encodable {
+ let iter = iter.into_iter();
+ self.emit_seq(iter.len(), move |ecx| {
+ for (i, elem) in iter.enumerate() {
+ ecx.emit_seq_elt(i, |ecx| {
+ f(ecx, elem).encode(ecx)
+ })?;
+ }
+ Ok(())
+ }).unwrap();
+ }
+}
+
fn encode_name(ecx: &mut EncodeContext, name: Name) {
- ecx.wr_tagged_str(tag_paths_data_name, &name.as_str());
+ ecx.start_tag(tag_paths_data_name);
+ name.encode(ecx).unwrap();
+ ecx.end_tag();
}
-fn encode_def_id(ecx: &mut EncodeContext, id: DefId) {
- ecx.wr_tagged_u64(tag_def_id, def_to_u64(id));
+fn encode_def_id(ecx: &mut EncodeContext, def_id: DefId) {
+ assert!(def_id.is_local());
+ ecx.start_tag(tag_def_index);
+ def_id.index.encode(ecx).unwrap();
+ ecx.end_tag();
}
fn encode_def_key(ecx: &mut EncodeContext, key: DefKey) {
}
// Item info table encoding
-fn encode_family(ecx: &mut EncodeContext, c: char) {
- ecx.wr_tagged_u8(tag_items_data_item_family, c as u8);
-}
-
-pub fn def_to_u64(did: DefId) -> u64 {
- (did.krate.as_u32() as u64) << 32 | (did.index.as_u32() as u64)
-}
-
-pub fn def_to_string(_tcx: TyCtxt, did: DefId) -> String {
- format!("{}:{}", did.krate, did.index.as_usize())
+fn encode_family(ecx: &mut EncodeContext, f: Family) {
+ ecx.start_tag(tag_items_data_item_family);
+ f.encode(ecx).unwrap();
+ ecx.end_tag();
}
fn encode_item_variances(ecx: &mut EncodeContext, id: NodeId) {
ecx.end_tag();
}
-impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_bounds_and_type_for_item(&mut self, def_id: DefId) {
let tcx = self.tcx;
self.encode_bounds_and_type(&tcx.lookup_item_type(def_id),
self.encode_generics(&scheme.generics, &predicates);
self.encode_type(scheme.ty);
}
-}
-
-fn encode_variant_id(ecx: &mut EncodeContext, vid: DefId) {
- let id = def_to_u64(vid);
- ecx.wr_tagged_u64(tag_items_data_item_variant, id);
- ecx.wr_tagged_u64(tag_mod_child, id);
-}
-impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
fn encode_type(&mut self, typ: Ty<'tcx>) {
self.start_tag(tag_items_data_item_type);
- typ.encode(self.ecx).unwrap();
+ typ.encode(self).unwrap();
self.end_tag();
}
fn encode_disr_val(&mut self,
disr_val: ty::Disr) {
- // convert to u64 so just the number is printed, without any type info
- self.wr_tagged_str(tag_disr_val, &disr_val.to_u64_unchecked().to_string());
+ self.start_tag(tag_disr_val);
+ disr_val.to_u64_unchecked().encode(self).unwrap();
+ self.end_tag();
}
fn encode_parent_item(&mut self, id: DefId) {
- self.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(id));
+ self.start_tag(tag_items_data_parent_item);
+ id.encode(self).unwrap();
+ self.end_tag();
}
- fn encode_struct_fields(&mut self,
- variant: ty::VariantDef) {
- for f in &variant.fields {
- if variant.kind == ty::VariantKind::Tuple {
- self.start_tag(tag_item_unnamed_field);
- } else {
- self.start_tag(tag_item_field);
- encode_name(self, f.name);
- }
- self.encode_struct_field_family(f.vis);
- encode_def_id(self, f.did);
- self.end_tag();
- }
+ fn encode_variant_fields(&mut self,
+ variant: ty::VariantDef) {
+ self.start_tag(tag_item_fields);
+ self.seq(&variant.fields, |_, f| f.did);
+ self.end_tag();
}
}
self.encode_fields(enum_did);
for (i, variant) in def.variants.iter().enumerate() {
self.record(variant.did,
- ItemContentBuilder::encode_enum_variant_info,
+ EncodeContext::encode_enum_variant_info,
(enum_did, Untracked(i)));
}
}
}
-impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
/// Encode data for the given variant of the given ADT. The
/// index of the variant is untracked: this is ok because we
/// will have to lookup the adt-def by its id, and that gives us
let variant = &def.variants[index];
let vid = variant.did;
encode_def_id_and_key(self, vid);
- encode_family(self, match variant.kind {
- ty::VariantKind::Struct => 'V',
- ty::VariantKind::Tuple => 'v',
- ty::VariantKind::Unit => 'w',
- });
+ encode_family(self, Family::Variant(variant.kind));
encode_name(self, variant.name);
self.encode_parent_item(enum_did);
encode_stability(self, stab);
encode_deprecation(self, depr);
- self.encode_struct_fields(variant);
+ self.encode_variant_fields(variant);
self.encode_disr_val(variant.disr_val);
self.encode_bounds_and_type_for_item(vid);
}
}
-fn encode_reexports(ecx: &mut EncodeContext, id: NodeId) {
- debug!("(encoding info for module) encoding reexports for {}", id);
- match ecx.reexports.get(&id) {
- Some(exports) => {
- debug!("(encoding info for module) found reexports for {}", id);
- for exp in exports {
- debug!("(encoding info for module) reexport '{}' ({:?}) for \
- {}",
- exp.name,
- exp.def_id,
- id);
- ecx.start_tag(tag_items_data_item_reexport);
- ecx.wr_tagged_u64(tag_items_data_item_reexport_def_id,
- def_to_u64(exp.def_id));
- ecx.wr_tagged_str(tag_items_data_item_reexport_name,
- &exp.name.as_str());
- ecx.end_tag();
- }
- },
- None => debug!("(encoding info for module) found no reexports for {}", id),
- }
-}
-
-impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_info_for_mod(&mut self,
FromId(id, (md, attrs, name, vis)):
FromId<(&hir::Mod, &[ast::Attribute], Name, &hir::Visibility)>) {
let tcx = self.tcx;
encode_def_id_and_key(self, tcx.map.local_def_id(id));
- encode_family(self, 'm');
+ encode_family(self, Family::Mod);
encode_name(self, name);
debug!("(encoding info for module) encoding info for module ID {}", id);
// Encode info about all the module children.
- for item_id in &md.item_ids {
- self.wr_tagged_u64(tag_mod_child,
- def_to_u64(tcx.map.local_def_id(item_id.id)));
+ self.start_tag(tag_mod_children);
+ self.seq(&md.item_ids, |_, item_id| {
+ tcx.map.local_def_id(item_id.id)
+ });
+
+ // Encode the reexports of this module, if this module is public.
+ match self.reexports.get(&id) {
+ Some(exports) if *vis == hir::Public => exports.encode(self).unwrap(),
+ _ => <[def::Export]>::encode(&[], self).unwrap()
}
+ self.end_tag();
self.encode_visibility(vis);
encode_stability(self, stab);
encode_deprecation(self, depr);
- // Encode the reexports of this module, if this module is public.
- if *vis == hir::Public {
- debug!("(encoding info for module) encoding reexports for {}", id);
- encode_reexports(self, id);
- }
encode_attributes(self, attrs);
}
fn encode_struct_field_family(&mut self,
visibility: ty::Visibility) {
- encode_family(self, if visibility.is_public() { 'g' } else { 'N' });
+ encode_family(self, if visibility.is_public() {
+ Family::PublicField
+ } else {
+ Family::InheritedField
+ });
}
fn encode_visibility<T: HasVisibility>(&mut self, visibility: T) {
- let ch = if visibility.is_public() { 'y' } else { 'i' };
- self.wr_tagged_u8(tag_items_data_item_visibility, ch as u8);
+ let vis = if visibility.is_public() {
+ ty::Visibility::Public
+ } else {
+ ty::Visibility::PrivateExternal
+ };
+ self.start_tag(tag_items_data_item_visibility);
+ vis.encode(self).unwrap();
+ self.end_tag();
}
}
fn encode_constness(ecx: &mut EncodeContext, constness: hir::Constness) {
ecx.start_tag(tag_items_data_item_constness);
- let ch = match constness {
- hir::Constness::Const => 'c',
- hir::Constness::NotConst => 'n',
- };
- ecx.wr_str(&ch.to_string());
+ constness.encode(ecx).unwrap();
ecx.end_tag();
}
fn encode_defaultness(ecx: &mut EncodeContext, defaultness: hir::Defaultness) {
- let ch = match defaultness {
- hir::Defaultness::Default => 'd',
- hir::Defaultness::Final => 'f',
- };
- ecx.wr_tagged_u8(tag_items_data_item_defaultness, ch as u8);
-}
-
-fn encode_explicit_self(ecx: &mut EncodeContext,
- explicit_self: &ty::ExplicitSelfCategory) {
- let tag = tag_item_trait_method_explicit_self;
-
- // Encode the base self type.
- match *explicit_self {
- ty::ExplicitSelfCategory::Static => {
- ecx.wr_tagged_bytes(tag, &['s' as u8]);
- }
- ty::ExplicitSelfCategory::ByValue => {
- ecx.wr_tagged_bytes(tag, &['v' as u8]);
- }
- ty::ExplicitSelfCategory::ByBox => {
- ecx.wr_tagged_bytes(tag, &['~' as u8]);
- }
- ty::ExplicitSelfCategory::ByReference(_, m) => {
- // FIXME(#4846) encode custom lifetime
- let ch = encode_mutability(m);
- ecx.wr_tagged_bytes(tag, &['&' as u8, ch]);
- }
- }
-
- fn encode_mutability(m: hir::Mutability) -> u8 {
- match m {
- hir::MutImmutable => 'i' as u8,
- hir::MutMutable => 'm' as u8,
- }
- }
-}
-
-fn encode_item_sort(ecx: &mut EncodeContext, sort: char) {
- ecx.wr_tagged_u8(tag_item_trait_item_sort, sort as u8);
+ ecx.start_tag(tag_items_data_item_defaultness);
+ defaultness.encode(ecx).unwrap();
+ ecx.end_tag();
}
impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
for (variant_index, variant) in def.variants.iter().enumerate() {
for (field_index, field) in variant.fields.iter().enumerate() {
self.record(field.did,
- ItemContentBuilder::encode_field,
+ EncodeContext::encode_field,
(adt_def_id, Untracked((variant_index, field_index))));
}
}
}
}
-impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
/// Encode data for the given field of the given variant of the
/// given ADT. The indices of the variant/field are untracked:
/// this is ok because we will have to lookup the adt-def by its
self.encode_bounds_and_type_for_item(field.did);
encode_def_id_and_key(self, field.did);
+ let variant_id = tcx.map.as_local_node_id(variant.did).unwrap();
+ let variant_data = tcx.map.expect_variant_data(variant_id);
+ encode_attributes(self, &variant_data.fields()[field_index].attrs);
+
let stab = tcx.lookup_stability(field.did);
let depr = tcx.lookup_deprecation(field.did);
encode_stability(self, stab);
let item = tcx.map.expect_item(struct_node_id);
let ctor_def_id = tcx.map.local_def_id(ctor_node_id);
encode_def_id_and_key(self, ctor_def_id);
- encode_family(self, match variant.kind {
- ty::VariantKind::Struct => 'S',
- ty::VariantKind::Tuple => 's',
- ty::VariantKind::Unit => 'u',
- });
+ encode_family(self, Family::Struct(variant.kind));
self.encode_bounds_and_type_for_item(ctor_def_id);
encode_name(self, item.name);
self.encode_parent_item(struct_def_id);
// definition, but without this there is no way for them
// to tell that they actually have a ctor rather than a
// normal function
- self.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]);
+ self.start_tag(tag_items_data_item_is_tuple_struct_ctor);
+ true.encode(self).unwrap();
+ self.end_tag();
}
fn encode_generics(&mut self,
predicates: &ty::GenericPredicates<'tcx>)
{
self.start_tag(tag_item_generics);
- generics.encode(self.ecx).unwrap();
+ generics.encode(self).unwrap();
self.end_tag();
self.encode_predicates(predicates, tag_item_predicates);
}
predicates: &ty::GenericPredicates<'tcx>,
tag: usize) {
self.start_tag(tag);
- if let Some(def_id) = predicates.parent {
- self.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(def_id));
- }
- for predicate in &predicates.predicates {
- let xref = self.add_xref(XRef::Predicate(predicate.clone()));
- self.wr_tagged_u32(tag_predicate, xref);
- }
+ predicates.parent.encode(self).unwrap();
+ self.seq(&predicates.predicates, |ecx, predicate| {
+ ecx.add_xref(XRef::Predicate(predicate.clone()))
+ });
self.end_tag();
}
encode_name(self, method_ty.name);
self.encode_generics(&method_ty.generics, &method_ty.predicates);
self.encode_visibility(method_ty.vis);
- encode_explicit_self(self, &method_ty.explicit_self);
- match method_ty.explicit_self {
- ty::ExplicitSelfCategory::Static => {
- encode_family(self, STATIC_METHOD_FAMILY);
- }
- _ => encode_family(self, METHOD_FAMILY)
- }
+
+ self.start_tag(tag_item_trait_method_explicit_self);
+ method_ty.explicit_self.encode(self).unwrap();
+ self.end_tag();
+
+ encode_family(self, Family::Method);
}
fn encode_info_for_trait_item(&mut self,
encode_stability(self, stab);
encode_deprecation(self, depr);
- let trait_item_type =
- tcx.impl_or_trait_item(item_def_id);
- let is_nonstatic_method;
- match trait_item_type {
+ match tcx.impl_or_trait_item(item_def_id) {
ty::ConstTraitItem(associated_const) => {
encode_name(self, associated_const.name);
- encode_def_id_and_key(self, associated_const.def_id);
+ encode_def_id_and_key(self, item_def_id);
self.encode_visibility(associated_const.vis);
- encode_family(self, 'C');
-
- self.encode_bounds_and_type_for_item(associated_const.def_id);
-
- is_nonstatic_method = false;
+ encode_family(self, Family::AssociatedConst);
+ self.encode_bounds_and_type_for_item(item_def_id);
}
ty::MethodTraitItem(method_ty) => {
- let method_def_id = item_def_id;
-
self.encode_method_ty_fields(&method_ty);
-
- match method_ty.explicit_self {
- ty::ExplicitSelfCategory::Static => {
- encode_family(self, STATIC_METHOD_FAMILY);
- }
- _ => {
- encode_family(self, METHOD_FAMILY);
- }
- }
- self.encode_bounds_and_type_for_item(method_def_id);
-
- is_nonstatic_method = method_ty.explicit_self !=
- ty::ExplicitSelfCategory::Static;
+ self.encode_bounds_and_type_for_item(item_def_id);
}
ty::TypeTraitItem(associated_type) => {
encode_name(self, associated_type.name);
- encode_def_id_and_key(self, associated_type.def_id);
- encode_item_sort(self, 't');
- encode_family(self, 'y');
+ encode_def_id_and_key(self, item_def_id);
+ encode_family(self, Family::AssociatedType);
if let Some(ty) = associated_type.ty {
self.encode_type(ty);
}
-
- is_nonstatic_method = false;
}
}
encode_attributes(self, &trait_item.attrs);
match trait_item.node {
hir::ConstTraitItem(_, ref default) => {
- if default.is_some() {
- encode_item_sort(self, 'C');
- } else {
- encode_item_sort(self, 'c');
- }
+ self.start_tag(tag_item_trait_item_has_body);
+ default.is_some().encode(self).unwrap();
+ self.end_tag();
encode_inlined_item(self,
InlinedItemRef::TraitItem(trait_def_id, trait_item));
self.encode_mir(item_def_id);
}
hir::MethodTraitItem(ref sig, ref body) => {
- // If this is a static method, we've already
- // encoded self.
- if is_nonstatic_method {
- self.encode_bounds_and_type_for_item(item_def_id);
- }
+ self.start_tag(tag_item_trait_item_has_body);
+ body.is_some().encode(self).unwrap();
+ self.end_tag();
- if body.is_some() {
- encode_item_sort(self, 'p');
- self.encode_mir(item_def_id);
- } else {
- encode_item_sort(self, 'r');
- }
+ self.encode_mir(item_def_id);
self.encode_method_argument_names(&sig.decl);
}
}
ty::MethodTraitItem(ref method_type) => {
self.encode_info_for_method(&method_type,
- false,
impl_id,
ast_item)
}
encode_def_id_and_key(self, associated_const.def_id);
encode_name(self, associated_const.name);
self.encode_visibility(associated_const.vis);
- encode_family(self, 'C');
+ encode_family(self, Family::AssociatedConst);
self.encode_parent_item(tcx.map.local_def_id(parent_id));
- encode_item_sort(self, 'C');
+
+ self.start_tag(tag_item_trait_item_has_body);
+ true.encode(self).unwrap();
+ self.end_tag();
self.encode_bounds_and_type_for_item(associated_const.def_id);
fn encode_info_for_method(&mut self,
m: &ty::Method<'tcx>,
- is_default_impl: bool,
parent_id: NodeId,
impl_item_opt: Option<&hir::ImplItem>) {
let tcx = self.tcx;
m.name);
self.encode_method_ty_fields(m);
self.encode_parent_item(tcx.map.local_def_id(parent_id));
- encode_item_sort(self, 'r');
+
+ self.start_tag(tag_item_trait_item_has_body);
+ true.encode(self).unwrap();
+ self.end_tag();
let stab = tcx.lookup_stability(m.def_id);
let depr = tcx.lookup_deprecation(m.def_id);
encode_attributes(self, &impl_item.attrs);
let generics = tcx.lookup_generics(m.def_id);
let types = generics.parent_types as usize + generics.types.len();
- let needs_inline = types > 0 || is_default_impl ||
- attr::requests_inline(&impl_item.attrs);
+ let needs_inline = types > 0 || attr::requests_inline(&impl_item.attrs);
if sig.constness == hir::Constness::Const {
encode_inlined_item(
self,
encode_def_id_and_key(self, associated_type.def_id);
encode_name(self, associated_type.name);
self.encode_visibility(associated_type.vis);
- encode_family(self, 'y');
+ encode_family(self, Family::AssociatedType);
self.encode_parent_item(tcx.map.local_def_id(parent_id));
- encode_item_sort(self, 't');
let stab = tcx.lookup_stability(associated_type.def_id);
let depr = tcx.lookup_deprecation(associated_type.def_id);
fn encode_method_argument_names(&mut self,
decl: &hir::FnDecl) {
self.start_tag(tag_method_argument_names);
- for arg in &decl.inputs {
- let tag = tag_method_argument_name;
+
+ self.seq(&decl.inputs, |_, arg| {
if let PatKind::Binding(_, ref path1, _) = arg.pat.node {
- let name = path1.node.as_str();
- self.wr_tagged_bytes(tag, name.as_bytes());
+ path1.node
} else {
- self.wr_tagged_bytes(tag, &[]);
+ syntax::parse::token::intern("")
}
- }
+ });
+
self.end_tag();
}
attr));
}
self.start_tag(tag_items_data_item_repr);
- repr_attrs.encode(self.ecx);
+ repr_attrs.encode(self);
self.end_tag();
}
fn encode_mir(&mut self, def_id: DefId) {
if let Some(mir) = self.mir_map.map.get(&def_id) {
self.start_tag(tag_mir as usize);
- mir.encode(self.ecx);
+ mir.encode(self);
self.end_tag();
}
}
}
-const FN_FAMILY: char = 'f';
-const STATIC_METHOD_FAMILY: char = 'F';
-const METHOD_FAMILY: char = 'h';
-
// Encodes the inherent implementations of a structure, enumeration, or trait.
fn encode_inherent_implementations(ecx: &mut EncodeContext,
def_id: DefId) {
+ ecx.start_tag(tag_items_data_item_inherent_impls);
match ecx.tcx.inherent_impls.borrow().get(&def_id) {
- None => {}
- Some(implementations) => {
- for &impl_def_id in implementations.iter() {
- ecx.start_tag(tag_items_data_item_inherent_impl);
- encode_def_id(ecx, impl_def_id);
- ecx.end_tag();
- }
- }
+ None => <[DefId]>::encode(&[], ecx).unwrap(),
+ Some(implementations) => implementations.encode(ecx).unwrap()
}
+ ecx.end_tag();
}
fn encode_stability(ecx: &mut EncodeContext, stab_opt: Option<&attr::Stability>) {
});
}
-fn encode_parent_impl(ecx: &mut EncodeContext, parent_opt: Option<DefId>) {
- parent_opt.map(|parent| {
- ecx.wr_tagged_u64(tag_items_data_parent_impl, def_to_u64(parent));
- });
-}
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
+ fn add_xref(&mut self, xref: XRef<'tcx>) -> u32 {
+ let old_len = self.xrefs.len() as u32;
+ *self.xrefs.entry(xref).or_insert(old_len)
+ }
-fn encode_xrefs<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>,
- xrefs: FnvHashMap<XRef<'tcx>, u32>)
-{
- let mut xref_positions = vec![0; xrefs.len()];
+ fn encode_xrefs(&mut self) {
+ let xrefs = mem::replace(&mut self.xrefs, Default::default());
+ let mut xref_positions = vec![0; xrefs.len()];
- // Encode XRefs sorted by their ID
- let mut sorted_xrefs: Vec<_> = xrefs.into_iter().collect();
- sorted_xrefs.sort_by_key(|&(_, id)| id);
+ // Encode XRefs sorted by their ID
+ let mut sorted_xrefs: Vec<_> = xrefs.into_iter().collect();
+ sorted_xrefs.sort_by_key(|&(_, id)| id);
- ecx.start_tag(tag_xref_data);
- for (xref, id) in sorted_xrefs.into_iter() {
- xref_positions[id as usize] = ecx.mark_stable_position() as u32;
- match xref {
- XRef::Predicate(p) => p.encode(ecx).unwrap()
+ self.start_tag(tag_xref_data);
+ for (xref, id) in sorted_xrefs.into_iter() {
+ xref_positions[id as usize] = self.mark_stable_position() as u32;
+ match xref {
+ XRef::Predicate(p) => p.encode(self).unwrap()
+ }
}
- }
- ecx.mark_stable_position();
- ecx.end_tag();
+ self.mark_stable_position();
+ self.end_tag();
- ecx.start_tag(tag_xref_index);
- index::write_dense_index(xref_positions, &mut ecx.opaque.cursor);
- ecx.end_tag();
-}
+ self.start_tag(tag_xref_index);
+ index::write_dense_index(xref_positions, &mut self.opaque.cursor);
+ self.end_tag();
+ }
-impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
fn encode_info_for_item(&mut self,
(def_id, item): (DefId, &hir::Item)) {
let tcx = self.tcx;
match item.node {
hir::ItemStatic(_, m, _) => {
encode_def_id_and_key(self, def_id);
- if m == hir::MutMutable {
- encode_family(self, 'b');
+ encode_family(self, if m == hir::MutMutable {
+ Family::MutStatic
} else {
- encode_family(self, 'c');
- }
+ Family::ImmStatic
+ });
self.encode_bounds_and_type_for_item(def_id);
encode_name(self, item.name);
self.encode_visibility(vis);
}
hir::ItemConst(..) => {
encode_def_id_and_key(self, def_id);
- encode_family(self, 'C');
+ encode_family(self, Family::Const);
self.encode_bounds_and_type_for_item(def_id);
encode_name(self, item.name);
encode_attributes(self, &item.attrs);
}
hir::ItemFn(ref decl, _, constness, _, ref generics, _) => {
encode_def_id_and_key(self, def_id);
- encode_family(self, FN_FAMILY);
+ encode_family(self, Family::Fn);
let tps_len = generics.ty_params.len();
self.encode_bounds_and_type_for_item(def_id);
encode_name(self, item.name);
}
hir::ItemForeignMod(ref fm) => {
encode_def_id_and_key(self, def_id);
- encode_family(self, 'n');
+ encode_family(self, Family::ForeignMod);
encode_name(self, item.name);
// Encode all the items in self module.
- for foreign_item in &fm.items {
- self.wr_tagged_u64(
- tag_mod_child,
- def_to_u64(tcx.map.local_def_id(foreign_item.id)));
- }
+ self.start_tag(tag_mod_children);
+ self.seq(&fm.items, |_, foreign_item| {
+ tcx.map.local_def_id(foreign_item.id)
+ });
+ <[def::Export]>::encode(&[], self).unwrap();
+ self.end_tag();
+
self.encode_visibility(vis);
encode_stability(self, stab);
encode_deprecation(self, depr);
}
hir::ItemTy(..) => {
encode_def_id_and_key(self, def_id);
- encode_family(self, 'y');
+ encode_family(self, Family::Type);
self.encode_bounds_and_type_for_item(def_id);
encode_name(self, item.name);
self.encode_visibility(vis);
}
hir::ItemEnum(ref enum_definition, _) => {
encode_def_id_and_key(self, def_id);
- encode_family(self, 't');
+ encode_family(self, Family::Enum);
encode_item_variances(self, item.id);
self.encode_bounds_and_type_for_item(def_id);
encode_name(self, item.name);
encode_attributes(self, &item.attrs);
self.encode_repr_attrs(&item.attrs);
- for v in &enum_definition.variants {
- encode_variant_id(self, tcx.map.local_def_id(v.node.data.id()));
- }
+
+ self.start_tag(tag_mod_children);
+ self.seq(&enum_definition.variants, |_, v| {
+ tcx.map.local_def_id(v.node.data.id())
+ });
+ <[def::Export]>::encode(&[], self).unwrap();
+ self.end_tag();
// Encode inherent implementations for self enumeration.
encode_inherent_implementations(self, def_id);
/* Now, make an item for the class itself */
encode_def_id_and_key(self, def_id);
- encode_family(self, match *struct_def {
- hir::VariantData::Struct(..) => 'S',
- hir::VariantData::Tuple(..) => 's',
- hir::VariantData::Unit(..) => 'u',
- });
+ encode_family(self, Family::Struct(variant.kind));
self.encode_bounds_and_type_for_item(def_id);
encode_item_variances(self, item.id);
/* Encode def_ids for each field and method
for methods, write all the stuff get_trait_method
needs to know*/
- self.encode_struct_fields(variant);
+ self.encode_variant_fields(variant);
// Encode inherent implementations for self structure.
encode_inherent_implementations(self, def_id);
if !struct_def.is_struct() {
let ctor_did = tcx.map.local_def_id(struct_def.id());
- self.wr_tagged_u64(tag_items_data_item_struct_ctor,
- def_to_u64(ctor_did));
+ self.start_tag(tag_items_data_item_struct_ctor);
+ ctor_did.encode(self).unwrap();
+ self.end_tag();
}
}
hir::ItemUnion(..) => {
let variant = def.struct_variant();
encode_def_id_and_key(self, def_id);
- encode_family(self, 'U');
+ encode_family(self, Family::Union);
self.encode_bounds_and_type_for_item(def_id);
encode_item_variances(self, item.id);
/* Encode def_ids for each field and method
for methods, write all the stuff get_trait_method
needs to know*/
- self.encode_struct_fields(variant);
+ self.encode_variant_fields(variant);
encode_inlined_item(self, InlinedItemRef::Item(def_id, item));
self.encode_mir(def_id);
// Encode inherent implementations for self union.
encode_inherent_implementations(self, def_id);
}
- hir::ItemDefaultImpl(unsafety, _) => {
+ hir::ItemDefaultImpl(..) => {
encode_def_id_and_key(self, def_id);
- encode_family(self, 'd');
+ encode_family(self, Family::DefaultImpl);
encode_name(self, item.name);
- encode_unsafety(self, unsafety);
let trait_ref = tcx.impl_trait_ref(tcx.map.local_def_id(item.id)).unwrap();
encode_trait_ref(self, trait_ref, tag_item_trait_ref);
}
- hir::ItemImpl(unsafety, polarity, ..) => {
- // We need to encode information about the default methods we
- // have inherited, so we drive self based on the impl structure.
- let impl_items = tcx.impl_items.borrow();
- let items = &impl_items[&def_id];
-
+ hir::ItemImpl(_, polarity, ..) => {
encode_def_id_and_key(self, def_id);
- encode_family(self, 'i');
+ encode_family(self, Family::Impl);
self.encode_bounds_and_type_for_item(def_id);
encode_name(self, item.name);
encode_attributes(self, &item.attrs);
- encode_unsafety(self, unsafety);
- encode_polarity(self, polarity);
+
+ self.start_tag(tag_polarity);
+ polarity.encode(self).unwrap();
+ self.end_tag();
match
tcx.custom_coerce_unsized_kinds
{
Some(&kind) => {
self.start_tag(tag_impl_coerce_unsized_kind);
- kind.encode(self.ecx);
+ kind.encode(self);
self.end_tag();
}
None => {}
}
- for &item_def_id in items {
- self.start_tag(tag_item_impl_item);
- match item_def_id {
- ty::ConstTraitItemId(item_def_id) => {
- encode_def_id(self, item_def_id);
- encode_item_sort(self, 'C');
- }
- ty::MethodTraitItemId(item_def_id) => {
- encode_def_id(self, item_def_id);
- encode_item_sort(self, 'r');
- }
- ty::TypeTraitItemId(item_def_id) => {
- encode_def_id(self, item_def_id);
- encode_item_sort(self, 't');
- }
- }
- self.end_tag();
- }
+ self.start_tag(tag_mod_children);
+ let items = tcx.impl_or_trait_items(def_id);
+ self.seq(&items[..], |_, id| id.def_id());
+ <[def::Export]>::encode(&[], self).unwrap();
+ self.end_tag();
let did = tcx.map.local_def_id(item.id);
if let Some(trait_ref) = tcx.impl_trait_ref(did) {
Some(parent),
_ => None,
});
- encode_parent_impl(self, parent);
+ parent.map(|parent| {
+ self.start_tag(tag_items_data_parent_impl);
+ parent.encode(self).unwrap();
+ self.end_tag();
+ });
}
encode_stability(self, stab);
encode_deprecation(self, depr);
}
hir::ItemTrait(..) => {
encode_def_id_and_key(self, def_id);
- encode_family(self, 'I');
+ encode_family(self, Family::Trait);
encode_item_variances(self, item.id);
let trait_def = tcx.lookup_trait_def(def_id);
let trait_predicates = tcx.lookup_predicates(def_id);
- encode_unsafety(self, trait_def.unsafety);
- encode_paren_sugar(self, trait_def.paren_sugar);
- encode_defaulted(self, tcx.trait_has_default_impl(def_id));
+
+ self.start_tag(tag_unsafety);
+ trait_def.unsafety.encode(self).unwrap();
+ self.end_tag();
+
+ self.start_tag(tag_paren_sugar);
+ trait_def.paren_sugar.encode(self).unwrap();
+ self.end_tag();
+
+ self.start_tag(tag_defaulted_trait);
+ tcx.trait_has_default_impl(def_id).encode(self).unwrap();
+ self.end_tag();
+
encode_associated_type_names(self, &trait_def.associated_type_names);
self.encode_generics(&trait_def.generics, &trait_predicates);
self.encode_predicates(&tcx.lookup_super_predicates(def_id),
self.encode_visibility(vis);
encode_stability(self, stab);
encode_deprecation(self, depr);
- for &method_def_id in tcx.trait_item_def_ids(def_id).iter() {
- self.start_tag(tag_item_trait_item);
- match method_def_id {
- ty::ConstTraitItemId(const_def_id) => {
- encode_def_id(self, const_def_id);
- encode_item_sort(self, 'C');
- }
- ty::MethodTraitItemId(method_def_id) => {
- encode_def_id(self, method_def_id);
- encode_item_sort(self, 'r');
- }
- ty::TypeTraitItemId(type_def_id) => {
- encode_def_id(self, type_def_id);
- encode_item_sort(self, 't');
- }
- }
- self.end_tag();
- self.wr_tagged_u64(tag_mod_child,
- def_to_u64(method_def_id.def_id()));
- }
+ self.start_tag(tag_mod_children);
+ let items = tcx.impl_or_trait_items(def_id);
+ self.seq(&items[..], |_, id| id.def_id());
+ <[def::Export]>::encode(&[], self).unwrap();
+ self.end_tag();
// Encode inherent implementations for self trait.
encode_inherent_implementations(self, def_id);
// Foo()` and `struct Foo`
let ctor_def_id = self.tcx.map.local_def_id(struct_node_id);
self.record(ctor_def_id,
- ItemContentBuilder::encode_struct_ctor,
+ EncodeContext::encode_struct_ctor,
(def_id, item.id, struct_node_id));
}
}
def_id: DefId,
impl_id: ast::NodeId,
ast_items: &[hir::ImplItem]) {
- let impl_items = self.tcx.impl_items.borrow();
- let items = &impl_items[&def_id];
+ let items = self.tcx.impl_or_trait_items(def_id);
// Iterate down the trait items, emitting them. We rely on the
// assumption that all of the actually implemented trait items
let trait_item_def_id = trait_item_def_id.def_id();
self.record(trait_item_def_id,
- ItemContentBuilder::encode_info_for_impl_item,
+ EncodeContext::encode_info_for_impl_item,
(impl_id, trait_item_def_id, ast_item));
}
}
def_id: DefId,
trait_items: &[hir::TraitItem]) {
// Now output the trait item info for each trait item.
- let tcx = self.tcx;
- let r = tcx.trait_item_def_ids(def_id);
+ let r = self.tcx.impl_or_trait_items(def_id);
for (item_def_id, trait_item) in r.iter().zip(trait_items) {
let item_def_id = item_def_id.def_id();
assert!(item_def_id.is_local());
self.record(item_def_id,
- ItemContentBuilder::encode_info_for_trait_item,
+ EncodeContext::encode_info_for_trait_item,
(def_id, item_def_id, trait_item));
}
}
}
-impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_info_for_foreign_item(&mut self,
(def_id, nitem): (DefId, &hir::ForeignItem)) {
let tcx = self.tcx;
self.encode_visibility(&nitem.vis);
match nitem.node {
hir::ForeignItemFn(ref fndecl, _) => {
- encode_family(self, FN_FAMILY);
+ encode_family(self, Family::Fn);
self.encode_bounds_and_type_for_item(def_id);
encode_name(self, nitem.name);
encode_attributes(self, &nitem.attrs);
self.encode_method_argument_names(&fndecl);
}
hir::ForeignItemStatic(_, mutbl) => {
- if mutbl {
- encode_family(self, 'b');
+ encode_family(self, if mutbl {
+ Family::MutStatic
} else {
- encode_family(self, 'c');
- }
+ Family::ImmStatic
+ });
self.encode_bounds_and_type_for_item(def_id);
encode_attributes(self, &nitem.attrs);
let stab = tcx.lookup_stability(tcx.map.local_def_id(nitem.id));
match item.node {
hir::ItemExternCrate(_) | hir::ItemUse(_) => (), // ignore these
_ => self.index.record(def_id,
- ItemContentBuilder::encode_info_for_item,
+ EncodeContext::encode_info_for_item,
(def_id, item)),
}
self.index.encode_addl_info_for_item(item);
intravisit::walk_foreign_item(self, ni);
let def_id = self.index.tcx.map.local_def_id(ni.id);
self.index.record(def_id,
- ItemContentBuilder::encode_info_for_foreign_item,
+ EncodeContext::encode_info_for_foreign_item,
(def_id, ni));
}
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
if let hir::TyImplTrait(_) = ty.node {
let def_id = self.tcx.map.local_def_id(ty.id);
self.record(def_id,
- ItemContentBuilder::encode_info_for_anon_ty,
+ EncodeContext::encode_info_for_anon_ty,
def_id);
}
}
hir::ExprClosure(..) => {
let def_id = self.tcx.map.local_def_id(expr.id);
self.record(def_id,
- ItemContentBuilder::encode_info_for_closure,
+ EncodeContext::encode_info_for_closure,
def_id);
}
_ => { }
}
}
-impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_info_for_anon_ty(&mut self, def_id: DefId) {
encode_def_id_and_key(self, def_id);
- encode_family(self, 'y');
self.encode_bounds_and_type_for_item(def_id);
}
encode_name(self, syntax::parse::token::intern("<closure>"));
self.start_tag(tag_items_closure_ty);
- tcx.tables.borrow().closure_tys[&def_id].encode(self.ecx).unwrap();
+ tcx.tables.borrow().closure_tys[&def_id].encode(self).unwrap();
self.end_tag();
self.start_tag(tag_items_closure_kind);
- tcx.closure_kind(def_id).encode(self.ecx).unwrap();
+ tcx.closure_kind(def_id).encode(self).unwrap();
self.end_tag();
assert!(self.mir_map.map.contains_key(&def_id));
}
}
-fn encode_info_for_items<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>)
- -> (IndexData, FnvHashMap<XRef<'tcx>, u32>) {
+fn encode_info_for_items(ecx: &mut EncodeContext) -> IndexData {
let krate = ecx.tcx.map.krate();
ecx.start_tag(tag_items_data);
- let fields = {
+ let items = {
let mut index = IndexBuilder::new(ecx);
index.record(DefId::local(CRATE_DEF_INDEX),
- ItemContentBuilder::encode_info_for_mod,
+ EncodeContext::encode_info_for_mod,
FromId(CRATE_NODE_ID, (&krate.module,
- &[],
+ &krate.attrs,
syntax::parse::token::intern(&ecx.link_meta.crate_name),
&hir::Public)));
let mut visitor = EncodeVisitor {
index: index,
};
krate.visit_all_items(&mut visitor);
- visitor.index.into_fields()
+ visitor.index.into_items()
};
ecx.end_tag();
- fields
+ items
}
fn encode_item_index(ecx: &mut EncodeContext, index: IndexData) {
ecx.end_tag();
}
-fn encode_unsafety(ecx: &mut EncodeContext, unsafety: hir::Unsafety) {
- let byte: u8 = match unsafety {
- hir::Unsafety::Normal => 0,
- hir::Unsafety::Unsafe => 1,
- };
- ecx.wr_tagged_u8(tag_unsafety, byte);
-}
-
-fn encode_paren_sugar(ecx: &mut EncodeContext, paren_sugar: bool) {
- let byte: u8 = if paren_sugar {1} else {0};
- ecx.wr_tagged_u8(tag_paren_sugar, byte);
-}
-
-fn encode_defaulted(ecx: &mut EncodeContext, is_defaulted: bool) {
- let byte: u8 = if is_defaulted {1} else {0};
- ecx.wr_tagged_u8(tag_defaulted_trait, byte);
-}
-
fn encode_associated_type_names(ecx: &mut EncodeContext, names: &[Name]) {
ecx.start_tag(tag_associated_type_names);
- for &name in names {
- ecx.wr_tagged_str(tag_associated_type_name, &name.as_str());
- }
+ names.encode(ecx).unwrap();
ecx.end_tag();
}
-fn encode_polarity(ecx: &mut EncodeContext, polarity: hir::ImplPolarity) {
- let byte: u8 = match polarity {
- hir::ImplPolarity::Positive => 0,
- hir::ImplPolarity::Negative => 1,
- };
- ecx.wr_tagged_u8(tag_polarity, byte);
-}
-
fn encode_crate_deps(ecx: &mut EncodeContext, cstore: &cstore::CStore) {
fn get_ordered_deps(cstore: &cstore::CStore)
-> Vec<(CrateNum, Rc<cstore::CrateMetadata>)> {
// FIXME (#2166): This is not nearly enough to support correct versioning
// but is enough to get transitive crate dependencies working.
ecx.start_tag(tag_crate_deps);
- for (_cnum, dep) in get_ordered_deps(cstore) {
- encode_crate_dep(ecx, &dep);
- }
+ ecx.seq(&get_ordered_deps(cstore), |_, &(_, ref dep)| {
+ (dep.name(), decoder::get_crate_hash(dep.data()),
+ dep.explicitly_linked.get())
+ });
ecx.end_tag();
}
fn encode_lang_items(ecx: &mut EncodeContext) {
- ecx.start_tag(tag_lang_items);
-
- for (i, &opt_def_id) in ecx.tcx.lang_items.items().iter().enumerate() {
- if let Some(def_id) = opt_def_id {
- if def_id.is_local() {
- ecx.start_tag(tag_lang_items_item);
- ecx.wr_tagged_u32(tag_lang_items_item_id, i as u32);
- ecx.wr_tagged_u32(tag_lang_items_item_index, def_id.index.as_u32());
- ecx.end_tag();
+ let tcx = ecx.tcx;
+ let lang_items = || {
+ tcx.lang_items.items().iter().enumerate().filter_map(|(i, &opt_def_id)| {
+ if let Some(def_id) = opt_def_id {
+ if def_id.is_local() {
+ return Some((def_id.index, i));
+ }
}
- }
- }
+ None
+ })
+ };
- for i in &ecx.tcx.lang_items.missing {
- ecx.wr_tagged_u32(tag_lang_items_missing, *i as u32);
- }
+ let count = lang_items().count();
+ let mut lang_items = lang_items();
- ecx.end_tag(); // tag_lang_items
+ ecx.start_tag(tag_lang_items);
+ ecx.seq(0..count, |_, _| lang_items.next().unwrap());
+ ecx.end_tag();
+
+ ecx.start_tag(tag_lang_items_missing);
+ tcx.lang_items.missing.encode(ecx).unwrap();
+ ecx.end_tag();
}
fn encode_native_libraries(ecx: &mut EncodeContext) {
- ecx.start_tag(tag_native_libraries);
-
- for &(ref lib, kind) in ecx.tcx.sess.cstore.used_libraries().iter() {
- match kind {
- cstore::NativeStatic => {} // these libraries are not propagated
- cstore::NativeFramework | cstore::NativeUnknown => {
- ecx.start_tag(tag_native_libraries_lib);
- ecx.wr_tagged_u32(tag_native_libraries_kind, kind as u32);
- ecx.wr_tagged_str(tag_native_libraries_name, lib);
- ecx.end_tag();
+ let used_libraries = ecx.tcx.sess.cstore.used_libraries();
+ let libs = || {
+ used_libraries.iter().filter_map(|&(ref lib, kind)| {
+ match kind {
+ cstore::NativeStatic => None, // these libraries are not propagated
+ cstore::NativeFramework | cstore::NativeUnknown => {
+ Some((kind, lib))
+ }
}
- }
- }
+ })
+ };
+
+ let count = libs().count();
+ let mut libs = libs();
+ ecx.start_tag(tag_native_libraries);
+ ecx.seq(0..count, |_, _| libs.next().unwrap());
ecx.end_tag();
}
match ecx.tcx.sess.plugin_registrar_fn.get() {
Some(id) => {
let def_id = ecx.tcx.map.local_def_id(id);
- ecx.wr_tagged_u32(tag_plugin_registrar_fn, def_id.index.as_u32());
+ ecx.start_tag(tag_plugin_registrar_fn);
+ def_id.index.encode(ecx).unwrap();
+ ecx.end_tag();
}
None => {}
}
}
fn encode_codemap(ecx: &mut EncodeContext) {
- ecx.start_tag(tag_codemap);
let codemap = ecx.tcx.sess.codemap();
+ let all_filemaps = codemap.files.borrow();
+ let filemaps = || {
+ // No need to export empty filemaps, as they can't contain spans
+ // that need translation.
+ // Also no need to re-export imported filemaps, as any downstream
+ // crate will import them from their original source.
+ all_filemaps.iter().filter(|filemap| {
+ !filemap.lines.borrow().is_empty() && !filemap.is_imported()
+ })
+ };
- for filemap in &codemap.files.borrow()[..] {
-
- if filemap.lines.borrow().is_empty() || filemap.is_imported() {
- // No need to export empty filemaps, as they can't contain spans
- // that need translation.
- // Also no need to re-export imported filemaps, as any downstream
- // crate will import them from their original source.
- continue;
- }
-
- ecx.start_tag(tag_codemap_filemap);
- filemap.encode(ecx).unwrap();
- ecx.end_tag();
- }
+ let count = filemaps().count();
+ let mut filemaps = filemaps();
+ ecx.start_tag(tag_codemap);
+ ecx.seq(0..count, |_, _| filemaps.next().unwrap());
ecx.end_tag();
}
/// Serialize the text of the exported macros
-fn encode_macro_defs(ecx: &mut EncodeContext,
- krate: &hir::Crate) {
+fn encode_macro_defs(ecx: &mut EncodeContext) {
+ let tcx = ecx.tcx;
ecx.start_tag(tag_macro_defs);
- for def in &krate.exported_macros {
- ecx.start_tag(tag_macro_def);
-
- encode_name(ecx, def.name);
- encode_attributes(ecx, &def.attrs);
- let &BytePos(lo) = &def.span.lo;
- let &BytePos(hi) = &def.span.hi;
- ecx.wr_tagged_u32(tag_macro_def_span_lo, lo);
- ecx.wr_tagged_u32(tag_macro_def_span_hi, hi);
-
- ecx.wr_tagged_str(tag_macro_def_body,
- &::syntax::print::pprust::tts_to_string(&def.body));
-
- ecx.end_tag();
- }
+ ecx.seq(&tcx.map.krate().exported_macros, |_, def| {
+ let body = ::syntax::print::pprust::tts_to_string(&def.body);
+ (def.name, &def.attrs, def.span, body)
+ });
ecx.end_tag();
if ecx.tcx.sess.crate_types.borrow().contains(&CrateTypeRustcMacro) {
let id = ecx.tcx.sess.derive_registrar_fn.get().unwrap();
let did = ecx.tcx.map.local_def_id(id);
- ecx.wr_tagged_u32(tag_macro_derive_registrar, did.index.as_u32());
- }
-}
-fn encode_struct_field_attrs(ecx: &mut EncodeContext, krate: &hir::Crate) {
- struct StructFieldVisitor<'a, 'b:'a, 'tcx:'b> {
- ecx: &'a mut EncodeContext<'b, 'tcx>
- }
-
- impl<'a, 'b, 'tcx, 'v> Visitor<'v> for StructFieldVisitor<'a, 'b, 'tcx> {
- fn visit_struct_field(&mut self, field: &hir::StructField) {
- self.ecx.start_tag(tag_struct_field);
- let def_id = self.ecx.tcx.map.local_def_id(field.id);
- encode_def_id(self.ecx, def_id);
- encode_attributes(self.ecx, &field.attrs);
- self.ecx.end_tag();
- }
+ ecx.start_tag(tag_macro_derive_registrar);
+ did.index.encode(ecx).unwrap();
+ ecx.end_tag();
}
-
- ecx.start_tag(tag_struct_fields);
- krate.visit_all_items(&mut StructFieldVisitor { ecx: ecx });
- ecx.end_tag();
}
-
-
struct ImplVisitor<'a, 'tcx:'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
impls: FnvHashMap<DefId, Vec<DefId>>
}
/// Encodes an index, mapping each trait to its (local) implementations.
-fn encode_impls(ecx: &mut EncodeContext, krate: &hir::Crate) {
+fn encode_impls(ecx: &mut EncodeContext) {
let mut visitor = ImplVisitor {
tcx: ecx.tcx,
impls: FnvHashMap()
};
- krate.visit_all_items(&mut visitor);
+ ecx.tcx.map.krate().visit_all_items(&mut visitor);
ecx.start_tag(tag_impls);
- for (trait_, trait_impls) in visitor.impls {
- ecx.start_tag(tag_impls_trait);
- encode_def_id(ecx, trait_);
- for impl_ in trait_impls {
- ecx.wr_tagged_u64(tag_impls_trait_impl, def_to_u64(impl_));
- }
+ for (trait_def_id, trait_impls) in visitor.impls {
+ // FIXME(eddyb) Avoid wrapping the entries in docs.
+ ecx.start_tag(0);
+ (trait_def_id.krate.as_u32(), trait_def_id.index).encode(ecx).unwrap();
+ trait_impls.encode(ecx).unwrap();
ecx.end_tag();
}
ecx.end_tag();
// definition (as that's not defined in this crate).
fn encode_reachable(ecx: &mut EncodeContext) {
ecx.start_tag(tag_reachable_ids);
- for &id in ecx.reachable {
- let def_id = ecx.tcx.map.local_def_id(id);
- ecx.wr_tagged_u32(tag_reachable_id, def_id.index.as_u32());
- }
- ecx.end_tag();
-}
-
-fn encode_crate_dep(ecx: &mut EncodeContext,
- dep: &cstore::CrateMetadata) {
- ecx.start_tag(tag_crate_dep);
- ecx.wr_tagged_str(tag_crate_dep_crate_name, &dep.name());
- let hash = decoder::get_crate_hash(dep.data());
- ecx.wr_tagged_u64(tag_crate_dep_hash, hash.as_u64());
- ecx.wr_tagged_u8(tag_crate_dep_explicitly_linked,
- dep.explicitly_linked.get() as u8);
- ecx.end_tag();
-}
-
-fn encode_hash(ecx: &mut EncodeContext, hash: &Svh) {
- ecx.wr_tagged_u64(tag_crate_hash, hash.as_u64());
-}
-
-fn encode_rustc_version(ecx: &mut EncodeContext) {
- ecx.wr_tagged_str(tag_rustc_version, &rustc_version());
-}
-fn encode_crate_name(ecx: &mut EncodeContext, crate_name: &str) {
- ecx.wr_tagged_str(tag_crate_crate_name, crate_name);
-}
+ let reachable = ecx.reachable;
+ ecx.seq(reachable, |ecx, &id| ecx.tcx.map.local_def_id(id).index);
-fn encode_crate_disambiguator(ecx: &mut EncodeContext, crate_disambiguator: &str) {
- ecx.wr_tagged_str(tag_crate_disambiguator, crate_disambiguator);
-}
-
-fn encode_crate_triple(ecx: &mut EncodeContext, triple: &str) {
- ecx.wr_tagged_str(tag_crate_triple, triple);
+ ecx.end_tag();
}
fn encode_dylib_dependency_formats(ecx: &mut EncodeContext) {
- let tag = tag_dylib_dependency_formats;
+ ecx.start_tag(tag_dylib_dependency_formats);
match ecx.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) {
Some(arr) => {
- let s = arr.iter().enumerate().filter_map(|(i, slot)| {
- let kind = match *slot {
+ ecx.seq(arr, |_, slot| {
+ match *slot {
Linkage::NotLinked |
- Linkage::IncludedFromDylib => return None,
- Linkage::Dynamic => "d",
- Linkage::Static => "s",
- };
- Some(format!("{}:{}", i + 1, kind))
- }).collect::<Vec<String>>();
- ecx.wr_tagged_str(tag, &s.join(","));
- }
- None => {
- ecx.wr_tagged_str(tag, "");
- }
- }
-}
+ Linkage::IncludedFromDylib => None,
-fn encode_panic_strategy(ecx: &mut EncodeContext) {
- match ecx.tcx.sess.opts.cg.panic {
- PanicStrategy::Unwind => {
- ecx.wr_tagged_u8(tag_panic_strategy, b'U');
+ Linkage::Dynamic => Some(LinkagePreference::RequireDynamic),
+ Linkage::Static => Some(LinkagePreference::RequireStatic),
+ }
+ });
}
- PanicStrategy::Abort => {
- ecx.wr_tagged_u8(tag_panic_strategy, b'A');
+ None => {
+ <[Option<LinkagePreference>]>::encode(&[], ecx).unwrap();
}
}
+ ecx.end_tag();
}
pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
reachable: reachable,
mir_map: mir_map,
type_shorthands: Default::default(),
+ xrefs: Default::default()
});
// RBML compacts the encoded bytes whenever appropriate,
}
fn encode_metadata_inner(ecx: &mut EncodeContext) {
- encode_rustc_version(ecx);
+ ecx.wr_tagged_str(tag_rustc_version, &rustc_version());
let tcx = ecx.tcx;
let link_meta = ecx.link_meta;
- encode_crate_name(ecx, &link_meta.crate_name);
- encode_crate_triple(ecx, &tcx.sess.opts.target_triple);
- encode_hash(ecx, &link_meta.crate_hash);
- encode_crate_disambiguator(ecx, &tcx.sess.local_crate_disambiguator());
+
+ ecx.start_tag(tag_crate_crate_name);
+ link_meta.crate_name.encode(ecx).unwrap();
+ ecx.end_tag();
+
+ ecx.start_tag(tag_crate_triple);
+ tcx.sess.opts.target_triple.encode(ecx).unwrap();
+ ecx.end_tag();
+
+ ecx.start_tag(tag_crate_hash);
+ link_meta.crate_hash.encode(ecx).unwrap();
+ ecx.end_tag();
+
+ ecx.start_tag(tag_crate_disambiguator);
+ tcx.sess.local_crate_disambiguator().encode(ecx).unwrap();
+ ecx.end_tag();
+
encode_dylib_dependency_formats(ecx);
- encode_panic_strategy(ecx);
- let krate = tcx.map.krate();
+ ecx.start_tag(tag_panic_strategy);
+ ecx.tcx.sess.opts.cg.panic.encode(ecx);
+ ecx.end_tag();
let mut i = ecx.position();
- encode_attributes(ecx, &krate.attrs);
- let attr_bytes = ecx.position() - i;
-
- i = ecx.position();
encode_crate_deps(ecx, ecx.cstore);
let dep_bytes = ecx.position() - i;
// Encode macro definitions
i = ecx.position();
- encode_macro_defs(ecx, krate);
+ encode_macro_defs(ecx);
let macro_defs_bytes = ecx.position() - i;
// Encode the def IDs of impls, for coherence checking.
i = ecx.position();
- encode_impls(ecx, krate);
+ encode_impls(ecx);
let impl_bytes = ecx.position() - i;
// Encode reachability info.
// Encode and index the items.
ecx.start_tag(tag_items);
i = ecx.position();
- let (items, xrefs) = encode_info_for_items(ecx);
+ let items = encode_info_for_items(ecx);
let item_bytes = ecx.position() - i;
ecx.end_tag();
let index_bytes = ecx.position() - i;
i = ecx.position();
- encode_xrefs(ecx, xrefs);
+ ecx.encode_xrefs();
let xref_bytes = ecx.position() - i;
- encode_struct_field_attrs(ecx, krate);
-
let total_bytes = ecx.position();
if ecx.tcx.sess.meta_stats() {
}
println!("metadata stats:");
- println!(" attribute bytes: {}", attr_bytes);
println!(" dep bytes: {}", dep_bytes);
println!(" lang item bytes: {}", lang_item_bytes);
println!(" native bytes: {}", native_lib_bytes);
//!
//! What record will do is to (a) record the current offset, (b) emit
//! the `common::data_item` tag, and then call `callback_fn` with the
-//! given data as well as an `ItemContentBuilder`. Once `callback_fn`
+//! given data as well as the `EncodingContext`. Once `callback_fn`
//! returns, the `common::data_item` tag will be closed.
//!
-//! The `ItemContentBuilder` is another type that just offers access
-//! to the `ecx` that was given in, as well as maintaining a list of
-//! `xref` instances, which are used to extract common data so it is
-//! not re-serialized.
-//!
-//! `ItemContentBuilder` is a distinct type which does not offer the
-//! `record` method, so that we can ensure that `common::data_item` elements
-//! are never nested.
+//! `EncodingContext` does not offer the `record` method, so that we
+//! can ensure that `common::data_item` elements are never nested.
//!
//! In addition, while the `callback_fn` is executing, we will push a
//! task `MetaData(some_def_id)`, which can then observe the
use rustc::dep_graph::DepNode;
use rustc::hir;
use rustc::hir::def_id::DefId;
-use rustc::ty::{self, TyCtxt};
-use rustc_data_structures::fnv::FnvHashMap;
+use rustc::ty::TyCtxt;
use syntax::ast;
use std::ops::{Deref, DerefMut};
/// Item encoding cannot be nested.
pub struct IndexBuilder<'a, 'b: 'a, 'tcx: 'b> {
items: IndexData,
- builder: ItemContentBuilder<'a, 'b, 'tcx>,
-}
-
-/// Builder that can encode the content of items, but can't start a
-/// new item itself. Most code is attached to here.
-pub struct ItemContentBuilder<'a, 'b: 'a, 'tcx: 'b> {
- xrefs: FnvHashMap<XRef<'tcx>, u32>, // sequentially-assigned
pub ecx: &'a mut EncodeContext<'b, 'tcx>,
}
impl<'a, 'b, 'tcx> Deref for IndexBuilder<'a, 'b, 'tcx> {
- type Target = EncodeContext<'b, 'tcx>;
- fn deref(&self) -> &Self::Target {
- self.builder.ecx
- }
-}
-
-impl<'a, 'b, 'tcx> DerefMut for IndexBuilder<'a, 'b, 'tcx> {
- fn deref_mut(&mut self) -> &mut Self::Target {
- self.builder.ecx
- }
-}
-
-impl<'a, 'b, 'tcx> Deref for ItemContentBuilder<'a, 'b, 'tcx> {
type Target = EncodeContext<'b, 'tcx>;
fn deref(&self) -> &Self::Target {
self.ecx
}
}
-impl<'a, 'b, 'tcx> DerefMut for ItemContentBuilder<'a, 'b, 'tcx> {
+impl<'a, 'b, 'tcx> DerefMut for IndexBuilder<'a, 'b, 'tcx> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.ecx
}
}
-/// "interned" entries referenced by id
-#[derive(PartialEq, Eq, Hash)]
-pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) }
-
impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
pub fn new(ecx: &'a mut EncodeContext<'b, 'tcx>) -> Self {
IndexBuilder {
items: IndexData::new(ecx.tcx.map.num_local_def_ids()),
- builder: ItemContentBuilder {
- ecx: ecx,
- xrefs: FnvHashMap(),
- },
+ ecx: ecx,
}
}
/// content system.
pub fn record<DATA>(&mut self,
id: DefId,
- op: fn(&mut ItemContentBuilder<'a, 'b, 'tcx>, DATA),
+ op: fn(&mut EncodeContext<'b, 'tcx>, DATA),
data: DATA)
where DATA: DepGraphRead
{
- let position = self.builder.ecx.mark_stable_position();
+ let position = self.ecx.mark_stable_position();
self.items.record(id, position);
let _task = self.tcx.dep_graph.in_task(DepNode::MetaData(id));
- self.builder.ecx.start_tag(tag_items_data_item).unwrap();
+ self.ecx.start_tag(tag_items_data_item).unwrap();
data.read(self.tcx);
- op(&mut self.builder, data);
- self.builder.ecx.end_tag().unwrap();
- }
-
- pub fn into_fields(self) -> (IndexData, FnvHashMap<XRef<'tcx>, u32>) {
- (self.items, self.builder.xrefs)
+ op(&mut self.ecx, data);
+ self.ecx.end_tag().unwrap();
}
-}
-impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
- pub fn add_xref(&mut self, xref: XRef<'tcx>) -> u32 {
- let old_len = self.xrefs.len() as u32;
- *self.xrefs.entry(xref).or_insert(old_len)
+ pub fn into_items(self) -> IndexData {
+ self.items
}
}
html_root_url = "https://doc.rust-lang.org/nightly/")]
#![cfg_attr(not(stage0), deny(warnings))]
+#![feature(conservative_impl_trait)]
#![feature(core_intrinsics)]
#![feature(box_patterns)]
#![feature(dotdot_in_tuple_patterns)]
}
pub fn get(&self, tag: usize) -> Doc<'doc> {
- get_doc(*self, tag)
- }
-
- pub fn is_empty(&self) -> bool {
- self.start == self.end
- }
-
- pub fn as_str(&self) -> &'doc str {
- str::from_utf8(&self.data[self.start..self.end]).unwrap()
+ match maybe_get_doc(*self, tag) {
+ Some(d) => d,
+ None => {
+ bug!("failed to find block with tag {:?}", tag);
+ }
+ }
}
- pub fn to_string(&self) -> String {
- self.as_str().to_string()
+ pub fn children(self) -> DocsIterator<'doc> {
+ DocsIterator { d: self }
}
}
pub next: usize,
}
-pub fn tag_at(data: &[u8], start: usize) -> Result<Res, Error> {
+fn tag_at(data: &[u8], start: usize) -> Result<Res, Error> {
let v = data[start] as usize;
if v < 0xf0 {
Ok(Res {
Err(Error::IntTooBig(a as usize))
}
-pub fn vuint_at(data: &[u8], start: usize) -> Result<Res, Error> {
+fn vuint_at(data: &[u8], start: usize) -> Result<Res, Error> {
if data.len() - start < 4 {
return vuint_at_slow(data, start);
}
}
}
-pub fn tag_len_at(data: &[u8], next: usize) -> Result<Res, Error> {
+fn tag_len_at(data: &[u8], next: usize) -> Result<Res, Error> {
vuint_at(data, next)
}
None
}
-pub fn get_doc<'a>(d: Doc<'a>, tg: usize) -> Doc<'a> {
- match maybe_get_doc(d, tg) {
- Some(d) => d,
- None => {
- bug!("failed to find block with tag {:?}", tg);
- }
- }
-}
-
-pub fn docs<'a>(d: Doc<'a>) -> DocsIterator<'a> {
- DocsIterator { d: d }
-}
-
pub struct DocsIterator<'a> {
d: Doc<'a>,
}
impl<'a> Iterator for DocsIterator<'a> {
- type Item = (usize, Doc<'a>);
+ type Item = Doc<'a>;
- fn next(&mut self) -> Option<(usize, Doc<'a>)> {
+ fn next(&mut self) -> Option<Doc<'a>> {
if self.d.start >= self.d.end {
return None;
}
};
self.d.start = end;
- return Some((elt_tag.val, doc));
- }
-}
-
-pub fn tagged_docs<'a>(d: Doc<'a>, tag: usize) -> TaggedDocsIterator<'a> {
- TaggedDocsIterator {
- iter: docs(d),
- tag: tag,
+ return Some(doc);
}
}
-pub struct TaggedDocsIterator<'a> {
- iter: DocsIterator<'a>,
- tag: usize,
-}
-
-impl<'a> Iterator for TaggedDocsIterator<'a> {
- type Item = Doc<'a>;
-
- fn next(&mut self) -> Option<Doc<'a>> {
- while let Some((tag, doc)) = self.iter.next() {
- if tag == self.tag {
- return Some(doc);
- }
- }
- None
- }
-}
-
-pub fn with_doc_data<T, F>(d: Doc, f: F) -> T
- where F: FnOnce(&[u8]) -> T
-{
- f(&d.data[d.start..d.end])
-}
-
-pub fn doc_as_u8(d: Doc) -> u8 {
- assert_eq!(d.end, d.start + 1);
- d.data[d.start]
-}
-
-pub fn doc_as_u64(d: Doc) -> u64 {
- if d.end >= 8 {
- // For performance, we read 8 big-endian bytes,
- // and mask off the junk if there is any. This
- // obviously won't work on the first 8 bytes
- // of a file - we will fall of the start
- // of the page and segfault.
-
- let mut b = [0; 8];
- b.copy_from_slice(&d.data[d.end - 8..d.end]);
- let data = unsafe { (*(b.as_ptr() as *const u64)).to_be() };
- let len = d.end - d.start;
- if len < 8 {
- data & ((1 << (len * 8)) - 1)
- } else {
- data
- }
- } else {
- let mut result = 0;
- for b in &d.data[d.start..d.end] {
- result = (result << 8) + (*b as u64);
- }
- result
- }
-}
-
-#[inline]
-pub fn doc_as_u16(d: Doc) -> u16 {
- doc_as_u64(d) as u16
-}
-#[inline]
-pub fn doc_as_u32(d: Doc) -> u32 {
- doc_as_u64(d) as u32
-}
-
-#[inline]
-pub fn doc_as_i8(d: Doc) -> i8 {
- doc_as_u8(d) as i8
-}
-#[inline]
-pub fn doc_as_i16(d: Doc) -> i16 {
- doc_as_u16(d) as i16
-}
-#[inline]
-pub fn doc_as_i32(d: Doc) -> i32 {
- doc_as_u32(d) as i32
-}
-#[inline]
-pub fn doc_as_i64(d: Doc) -> i64 {
- doc_as_u64(d) as i64
-}
-
#[test]
fn test_vuint_at() {
let data = &[
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::mem;
use std::io::prelude::*;
use std::io::{self, SeekFrom, Cursor};
Ok(())
}
- pub fn wr_tag<F>(&mut self, tag_id: usize, blk: F) -> EncodeResult
- where F: FnOnce() -> EncodeResult
- {
- self.start_tag(tag_id)?;
- blk()?;
- self.end_tag()
- }
-
- pub fn wr_tagged_bytes(&mut self, tag_id: usize, b: &[u8]) -> EncodeResult {
- write_tag(&mut self.opaque.cursor, tag_id)?;
- write_vuint(&mut self.opaque.cursor, b.len())?;
- self.opaque.cursor.write_all(b)
- }
-
- pub fn wr_tagged_u64(&mut self, tag_id: usize, v: u64) -> EncodeResult {
- let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) };
- // tagged integers are emitted in big-endian, with no
- // leading zeros.
- let leading_zero_bytes = v.leading_zeros() / 8;
- self.wr_tagged_bytes(tag_id, &bytes[leading_zero_bytes as usize..])
- }
-
- #[inline]
- pub fn wr_tagged_u32(&mut self, tag_id: usize, v: u32) -> EncodeResult {
- self.wr_tagged_u64(tag_id, v as u64)
- }
-
- #[inline]
- pub fn wr_tagged_u8(&mut self, tag_id: usize, v: u8) -> EncodeResult {
- self.wr_tagged_bytes(tag_id, &[v])
- }
-
pub fn wr_tagged_str(&mut self, tag_id: usize, v: &str) -> EncodeResult {
- self.wr_tagged_bytes(tag_id, v.as_bytes())
- }
-
- pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
- debug!("Write {:?} bytes", b.len());
- self.opaque.cursor.write_all(b)
- }
-
- pub fn wr_str(&mut self, s: &str) -> EncodeResult {
- debug!("Write str: {:?}", s);
- self.opaque.cursor.write_all(s.as_bytes())
+ write_tag(&mut self.opaque.cursor, tag_id)?;
+ write_vuint(&mut self.opaque.cursor, v.len())?;
+ self.opaque.cursor.write_all(v.as_bytes())
}
pub fn position(&mut self) -> usize {
use Resolver;
use {resolve_error, resolve_struct_error, ResolutionError};
-use rustc::middle::cstore::{ChildItem, DlDef};
+use rustc::middle::cstore::ChildItem;
use rustc::hir::def::*;
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
-use rustc::ty::{self, VariantKind};
+use rustc::ty;
use std::cell::Cell;
let module = self.new_extern_crate_module(parent_link, def, item.id);
self.define(parent, name, TypeNS, (module, sp, vis));
- self.build_reduced_graph_for_external_crate(module);
+ self.populate_module_if_necessary(module);
}
}
}
/// Builds the reduced graph for a single item in an external crate.
- fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, xcdef: ChildItem) {
- let def = match xcdef.def {
- DlDef(def) => def,
- _ => return,
- };
-
- if let Def::ForeignMod(def_id) = def {
+ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, child: ChildItem) {
+ if let Def::ForeignMod(def_id) = child.def {
// Foreign modules have no names. Recur and populate eagerly.
for child in self.session.cstore.item_children(def_id) {
self.build_reduced_graph_for_external_crate_def(parent, child);
return;
}
- let name = xcdef.name;
- let vis = if parent.is_trait() { ty::Visibility::Public } else { xcdef.vis };
+ let def = child.def;
+ let name = child.name;
+ let vis = if parent.is_trait() { ty::Visibility::Public } else { child.vis };
match def {
Def::Mod(_) | Def::ForeignMod(_) | Def::Enum(..) => {
let module = self.new_module(parent_link, Some(def), None);
let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
}
- Def::Variant(_, variant_id) => {
+ Def::Variant(..) => {
debug!("(building reduced graph for external crate) building variant {}", name);
// Variants are always treated as importable to allow them to be glob used.
// All variants are defined in both type and value namespaces as future-proofing.
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
- if self.session.cstore.variant_kind(variant_id) == Some(VariantKind::Struct) {
- // Not adding fields for variants as they are not accessed with a self receiver
- self.structs.insert(variant_id, Vec::new());
- }
}
Def::Fn(..) |
Def::Static(..) |
// If this is a trait, add all the trait item names to the trait
// info.
- let trait_item_def_ids = self.session.cstore.trait_item_def_ids(def_id);
+ let trait_item_def_ids = self.session.cstore.impl_or_trait_items(def_id);
for trait_item_def in &trait_item_def_ids {
let trait_item_name =
self.session.cstore.item_name(trait_item_def.def_id());
}
}
- /// Builds the reduced graph rooted at the 'use' directive for an external
- /// crate.
- fn build_reduced_graph_for_external_crate(&mut self, root: Module<'b>) {
- let root_cnum = root.def_id().unwrap().krate;
- for child in self.session.cstore.crate_top_level_items(root_cnum) {
- self.build_reduced_graph_for_external_crate_def(root, child);
- }
- }
-
/// Ensures that the reduced graph rooted at the given external module
/// is built, building it if it is not.
pub fn populate_module_if_necessary(&mut self, module: Module<'b>) {
-> Module<'a> {
let mut module = ModuleS::new(parent_link, Some(def), Some(local_node_id));
module.extern_crate_id = Some(local_node_id);
+ module.populated.set(false);
self.arenas.modules.alloc(module)
}
.map(|mr| mr.def_id())
}
ty::ImplContainer(def_id) => {
- let impl_items = self.tcx.impl_items.borrow();
- Some(impl_items.get(&def_id)
- .unwrap()
- .iter()
+ let impl_items = self.tcx.impl_or_trait_items(def_id);
+ Some(impl_items.iter()
.find(|mr| {
self.tcx.impl_or_trait_item(mr.def_id()).name() ==
ti.name()
fn can_result_in_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> bool {
- if !match tcx.lookup_item_type(def_id).ty.sty {
- ty::TyFnDef(def_id, ..) => {
+ match tcx.lookup_item_type(def_id).ty.sty {
+ ty::TyFnDef(def_id, _, f) => {
// Some constructors also have type TyFnDef but they are
// always instantiated inline and don't result in
// translation item. Same for FFI functions.
- match tcx.map.get_if_local(def_id) {
- Some(hir_map::NodeVariant(_)) |
- Some(hir_map::NodeStructCtor(_)) |
- Some(hir_map::NodeForeignItem(_)) => false,
- Some(_) => true,
- None => {
- tcx.sess.cstore.variant_kind(def_id).is_none()
+ if let Some(hir_map::NodeForeignItem(_)) = tcx.map.get_if_local(def_id) {
+ return false;
+ }
+
+ if let Some(adt_def) = f.sig.output().skip_binder().ty_adt_def() {
+ if adt_def.variants.iter().any(|v| def_id == v.did) {
+ return false;
}
}
}
- ty::TyClosure(..) => true,
- _ => false
- } {
- return false;
+ ty::TyClosure(..) => {}
+ _ => return false
}
can_have_local_instance(tcx, def_id)
tcx.populate_implementations_for_trait_if_necessary(trait_id);
- let trait_item_def_ids = tcx.trait_item_def_ids(trait_id);
+ let trait_item_def_ids = tcx.impl_or_trait_items(trait_id);
trait_item_def_ids
.iter()
let vtable = common::fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref);
if let traits::VtableImpl(vtable_impl) = vtable {
let name = ccx.tcx().item_name(instance.def);
- for ac in ccx.tcx().associated_consts(vtable_impl.impl_def_id) {
- if ac.name == name {
- instance = Instance::new(ac.def_id, vtable_impl.substs);
- break;
- }
+ let ac = ccx.tcx().impl_or_trait_items(vtable_impl.impl_def_id)
+ .iter().filter_map(|id| {
+ match *id {
+ ty::ConstTraitItemId(def_id) => {
+ Some(ccx.tcx().impl_or_trait_item(def_id))
+ }
+ _ => None
+ }
+ }).find(|ic| ic.name() == name);
+ if let Some(ac) = ac {
+ instance = Instance::new(ac.def_id(), vtable_impl.substs);
}
}
}
// Trait must have a method named `m_name` and it should not have
// type parameters or early-bound regions.
let tcx = self.tcx;
- let method_item = self.trait_item(trait_def_id, m_name).unwrap();
+ let method_item = self.impl_or_trait_item(trait_def_id, m_name).unwrap();
let method_ty = method_item.as_opt_method().unwrap();
assert_eq!(method_ty.generics.types.len(), 0);
assert_eq!(method_ty.generics.regions.len(), 0);
Ok(def)
}
- /// Find item with name `item_name` defined in `trait_def_id`
- /// and return it, or `None`, if no such item.
- pub fn trait_item(&self,
- trait_def_id: DefId,
- item_name: ast::Name)
- -> Option<ty::ImplOrTraitItem<'tcx>>
+ /// Find item with name `item_name` defined in impl/trait `def_id`
+ /// and return it, or `None`, if no such item was defined there.
+ pub fn impl_or_trait_item(&self,
+ def_id: DefId,
+ item_name: ast::Name)
+ -> Option<ty::ImplOrTraitItem<'tcx>>
{
- let trait_items = self.tcx.trait_items(trait_def_id);
- trait_items.iter()
- .find(|item| item.name() == item_name)
- .cloned()
- }
-
- pub fn impl_item(&self,
- impl_def_id: DefId,
- item_name: ast::Name)
- -> Option<ty::ImplOrTraitItem<'tcx>>
- {
- let impl_items = self.tcx.impl_items.borrow();
- let impl_items = impl_items.get(&impl_def_id).unwrap();
- impl_items
+ self.tcx.impl_or_trait_items(def_id)
.iter()
.map(|&did| self.tcx.impl_or_trait_item(did.def_id()))
.find(|m| m.name() == item_name)
debug!("assemble_inherent_impl_probe {:?}", impl_def_id);
- let item = match self.impl_item(impl_def_id) {
+ let item = match self.impl_or_trait_item(impl_def_id) {
Some(m) => m,
None => { return; } // No method with correct name on this impl
};
let tcx = self.tcx;
for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
- let item = match self.trait_item(bound_trait_ref.def_id()) {
+ let item = match self.impl_or_trait_item(bound_trait_ref.def_id()) {
Some(v) => v,
None => { continue; }
};
self.tcx.erase_late_bound_regions(value)
}
- fn impl_item(&self, impl_def_id: DefId)
- -> Option<ty::ImplOrTraitItem<'tcx>>
+ /// Find item with name `item_name` defined in impl/trait `def_id`
+ /// and return it, or `None`, if no such item was defined there.
+ fn impl_or_trait_item(&self, def_id: DefId)
+ -> Option<ty::ImplOrTraitItem<'tcx>>
{
- self.fcx.impl_item(impl_def_id, self.item_name)
- }
-
- /// Find item with name `item_name` defined in `trait_def_id`
- /// and return it, or `None`, if no such item.
- fn trait_item(&self, trait_def_id: DefId)
- -> Option<ty::ImplOrTraitItem<'tcx>>
- {
- self.fcx.trait_item(trait_def_id, self.item_name)
+ self.fcx.impl_or_trait_item(def_id, self.item_name)
}
}
use check::{FnCtxt};
use rustc::hir::map as hir_map;
use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable};
-use middle::cstore;
use hir::def::Def;
-use hir::def_id::DefId;
+use hir::def_id::{CRATE_DEF_INDEX, DefId};
use middle::lang_items::FnOnceTraitLangItem;
use rustc::ty::subst::Substs;
use rustc::traits::{Obligation, SelectionContext};
CandidateSource::ImplSource(impl_did) => {
// Provide the best span we can. Use the item, if local to crate, else
// the impl, if local to crate (item may be defaulted), else nothing.
- let item = self.impl_item(impl_did, item_name)
+ let item = self.impl_or_trait_item(impl_did, item_name)
.or_else(|| {
- self.trait_item(
+ self.impl_or_trait_item(
self.tcx.impl_trait_ref(impl_did).unwrap().def_id,
item_name
}
}
CandidateSource::TraitSource(trait_did) => {
- let item = self.trait_item(trait_did, item_name).unwrap();
+ let item = self.impl_or_trait_item(trait_did, item_name).unwrap();
let item_span = self.tcx.map.def_id_span(item.def_id(), span);
span_note!(err, item_span,
"candidate #{} is defined in the trait `{}`",
// implementing a trait would be legal but is rejected
// here).
(type_is_local || info.def_id.is_local())
- && self.trait_item(info.def_id, item_name).is_some()
+ && self.impl_or_trait_item(info.def_id, item_name).is_some()
})
.collect::<Vec<_>>();
// Cross-crate:
let mut external_mods = FnvHashSet();
- fn handle_external_def(traits: &mut AllTraitsVec,
+ fn handle_external_def(ccx: &CrateCtxt,
+ traits: &mut AllTraitsVec,
external_mods: &mut FnvHashSet<DefId>,
- ccx: &CrateCtxt,
- cstore: &for<'a> cstore::CrateStore<'a>,
- dl: cstore::DefLike) {
- match dl {
- cstore::DlDef(Def::Trait(did)) => {
+ def: Def) {
+ match def {
+ Def::Trait(did) => {
traits.push(TraitInfo::new(did));
}
- cstore::DlDef(Def::Mod(did)) => {
+ Def::Mod(did) => {
if !external_mods.insert(did) {
return;
}
- for child in cstore.item_children(did) {
- handle_external_def(traits, external_mods,
- ccx, cstore, child.def)
+ for child in ccx.tcx.sess.cstore.item_children(did) {
+ handle_external_def(ccx, traits, external_mods, child.def)
}
}
_ => {}
}
}
- let cstore = &*ccx.tcx.sess.cstore;
-
for cnum in ccx.tcx.sess.cstore.crates() {
- for child in cstore.crate_top_level_items(cnum) {
- handle_external_def(&mut traits, &mut external_mods,
- ccx, cstore, child.def)
- }
+ handle_external_def(ccx, &mut traits, &mut external_mods, Def::Mod(DefId {
+ krate: cnum,
+ index: CRATE_DEF_INDEX
+ }));
}
*ccx.all_traits.borrow_mut() = Some(traits);
use rustc::hir::{Item, ItemImpl};
use rustc::hir;
+use std::rc::Rc;
+
mod orphan;
mod overlap;
mod unsafety;
}
}
- tcx.impl_items.borrow_mut().insert(impl_did, impl_items);
+ tcx.impl_or_trait_item_ids.borrow_mut().insert(impl_did, Rc::new(impl_items));
}
fn add_inherent_impl(&self, base_def_id: DefId, impl_def_id: DefId) {
tcx.populate_implementations_for_trait_if_necessary(drop_trait);
let drop_trait = tcx.lookup_trait_def(drop_trait);
- let impl_items = tcx.impl_items.borrow();
+ let impl_items = tcx.impl_or_trait_item_ids.borrow();
drop_trait.for_each_impl(tcx, |impl_did| {
let items = impl_items.get(&impl_did).unwrap();
})
}
- let impl_items = self.tcx.impl_items.borrow();
+ let impl_items = self.tcx.impl_or_trait_item_ids.borrow();
- for item1 in &impl_items[&impl1] {
+ for item1 in &impl_items[&impl1][..] {
let (name, namespace) = name_and_namespace(self.tcx, item1);
- for item2 in &impl_items[&impl2] {
+ for item2 in &impl_items[&impl2][..] {
if (name, namespace) == name_and_namespace(self.tcx, item2) {
let msg = format!("duplicate definitions with name `{}`", name);
let node_id = self.tcx.map.as_local_node_id(item1.def_id()).unwrap();
vis: &hir::Visibility,
sig: &hir::MethodSig,
defaultness: hir::Defaultness,
+ has_body: bool,
untransformed_rcvr_ty: Ty<'tcx>,
rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
let def_id = ccx.tcx.map.local_def_id(id);
sig, untransformed_rcvr_ty, anon_scope)
};
- let ty_method = ty::Method::new(name,
- ty_generics,
- ty_generic_predicates,
- fty,
- explicit_self_category,
- ty::Visibility::from_hir(vis, id, ccx.tcx),
- defaultness,
- def_id,
- container);
+ let ty_method = ty::Method {
+ name: name,
+ generics: ty_generics,
+ predicates: ty_generic_predicates,
+ fty: fty,
+ explicit_self: explicit_self_category,
+ vis: ty::Visibility::from_hir(vis, id, ccx.tcx),
+ defaultness: defaultness,
+ has_body: has_body,
+ def_id: def_id,
+ container: container,
+ };
let substs = mk_item_substs(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
ccx.tcx.map.span(id), def_id);
convert_method(ccx, ImplContainer(def_id),
impl_item.name, impl_item.id, method_vis,
- sig, impl_item.defaultness, selfty,
+ sig, impl_item.defaultness, true, selfty,
&ty_predicates);
}
}
// Convert all the methods
for trait_item in trait_items {
- if let hir::MethodTraitItem(ref sig, _) = trait_item.node {
+ if let hir::MethodTraitItem(ref sig, ref body) = trait_item.node {
convert_method(ccx,
container,
trait_item.name,
&hir::Inherited,
sig,
hir::Defaultness::Default,
+ body.is_some(),
tcx.mk_self_type(),
&trait_predicates);
hir::TypeTraitItem(..) => ty::TypeTraitItemId(def_id)
}
}).collect());
- tcx.trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
- trait_item_def_ids);
+ tcx.impl_or_trait_item_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
+ trait_item_def_ids);
},
hir::ItemStruct(ref struct_def, _) |
hir::ItemUnion(ref struct_def, _) => {
use syntax::ast;
use rustc::hir;
-use rustc::middle::cstore;
use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
use rustc::hir::print as pprust;
Def::TyAlias(did) => {
record_extern_fqn(cx, did, clean::TypeTypedef);
ret.extend(build_impls(cx, tcx, did));
- build_type(cx, tcx, did)
+ clean::TypedefItem(build_type_alias(cx, tcx, did), false)
}
Def::Enum(did) => {
record_extern_fqn(cx, did, clean::TypeEnum);
ret.extend(build_impls(cx, tcx, did));
- build_type(cx, tcx, did)
+ clean::EnumItem(build_enum(cx, tcx, did))
}
// Assume that the enum type is reexported next to the variant, and
// variants don't show up in documentation specially.
}
}
+fn build_enum<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ did: DefId) -> clean::Enum {
+ let t = tcx.lookup_item_type(did);
+ let predicates = tcx.lookup_predicates(did);
+
+ clean::Enum {
+ generics: (t.generics, &predicates).clean(cx),
+ variants_stripped: false,
+ variants: tcx.lookup_adt_def(did).variants.clean(cx),
+ }
+}
+
fn build_struct<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
did: DefId) -> clean::Struct {
let t = tcx.lookup_item_type(did);
}
}
-fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
- did: DefId) -> clean::ItemEnum {
+fn build_type_alias<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ did: DefId) -> clean::Typedef {
let t = tcx.lookup_item_type(did);
let predicates = tcx.lookup_predicates(did);
- match t.ty.sty {
- ty::TyAdt(edef, _) if edef.is_enum() && !tcx.sess.cstore.is_typedef(did) => {
- return clean::EnumItem(clean::Enum {
- generics: (t.generics, &predicates).clean(cx),
- variants_stripped: false,
- variants: edef.variants.clean(cx),
- })
- }
- _ => {}
- }
- clean::TypedefItem(clean::Typedef {
+ clean::Typedef {
type_: t.ty.clean(cx),
generics: (t.generics, &predicates).clean(cx),
- }, false)
+ }
}
pub fn build_impls<'a, 'tcx>(cx: &DocContext,
build_impl(cx, tcx, did, &mut impls);
}
}
-
- // If this is the first time we've inlined something from this crate, then
- // we inline *all* impls from the crate into this crate. Note that there's
+ // If this is the first time we've inlined something from another crate, then
+ // we inline *all* impls from all the crates into this crate. Note that there's
// currently no way for us to filter this based on type, and we likely need
// many impls for a variety of reasons.
//
// Primarily, the impls will be used to populate the documentation for this
// type being inlined, but impls can also be used when generating
// documentation for primitives (no way to find those specifically).
- if cx.populated_crate_impls.borrow_mut().insert(did.krate) {
- for item in tcx.sess.cstore.crate_top_level_items(did.krate) {
- populate_impls(cx, tcx, item.def, &mut impls);
- }
+ if cx.populated_all_crate_impls.get() {
+ return impls;
+ }
- fn populate_impls<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
- def: cstore::DefLike,
- impls: &mut Vec<clean::Item>) {
- match def {
- cstore::DlImpl(did) => build_impl(cx, tcx, did, impls),
- cstore::DlDef(Def::Mod(did)) => {
- for item in tcx.sess.cstore.item_children(did) {
- populate_impls(cx, tcx, item.def, impls)
- }
- }
- _ => {}
- }
+ cx.populated_all_crate_impls.set(true);
+
+ for did in tcx.sess.cstore.implementations_of_trait(None) {
+ build_impl(cx, tcx, did, &mut impls);
+ }
+
+ // Also try to inline primitive impls from other crates.
+ let primitive_impls = [
+ tcx.lang_items.isize_impl(),
+ tcx.lang_items.i8_impl(),
+ tcx.lang_items.i16_impl(),
+ tcx.lang_items.i32_impl(),
+ tcx.lang_items.i64_impl(),
+ tcx.lang_items.usize_impl(),
+ tcx.lang_items.u8_impl(),
+ tcx.lang_items.u16_impl(),
+ tcx.lang_items.u32_impl(),
+ tcx.lang_items.u64_impl(),
+ tcx.lang_items.f32_impl(),
+ tcx.lang_items.f64_impl(),
+ tcx.lang_items.char_impl(),
+ tcx.lang_items.str_impl(),
+ tcx.lang_items.slice_impl(),
+ tcx.lang_items.slice_impl(),
+ tcx.lang_items.const_ptr_impl()
+ ];
+
+ for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) {
+ if !def_id.is_local() {
+ tcx.populate_implementations_for_primitive_if_necessary(def_id);
+ build_impl(cx, tcx, def_id, &mut impls);
}
}
}
let predicates = tcx.lookup_predicates(did);
- let trait_items = tcx.sess.cstore.impl_items(did)
+ let trait_items = tcx.sess.cstore.impl_or_trait_items(did)
.iter()
.filter_map(|did| {
let did = did.def_id();
for_: for_,
generics: (ty.generics, &predicates).clean(cx),
items: trait_items,
- polarity: polarity.map(|p| { p.clean(cx) }),
+ polarity: Some(polarity.clean(cx)),
}),
source: clean::Span::empty(),
name: None,
let mut visited = FnvHashSet();
for item in tcx.sess.cstore.item_children(did) {
match item.def {
- cstore::DlDef(Def::ForeignMod(did)) => {
+ Def::ForeignMod(did) => {
fill_in(cx, tcx, did, items);
}
- cstore::DlDef(def) if item.vis == ty::Visibility::Public => {
- if !visited.insert(def) { continue }
- if let Some(i) = try_inline_def(cx, tcx, def) {
- items.extend(i)
+ def => {
+ if item.vis == ty::Visibility::Public {
+ if !visited.insert(def) { continue }
+ if let Some(i) = try_inline_def(cx, tcx, def) {
+ items.extend(i)
+ }
}
}
- cstore::DlDef(..) => {}
- // All impls were inlined above
- cstore::DlImpl(..) => {}
- cstore::DlField => panic!("unimplemented field"),
}
}
}
use syntax_pos::{self, DUMMY_SP, Pos};
use rustc_trans::back::link;
-use rustc::middle::cstore;
use rustc::middle::privacy::AccessLevels;
use rustc::middle::resolve_lifetime::DefRegion::*;
use rustc::hir::def::Def;
fn clean(&self, cx: &DocContext) -> ExternalCrate {
let mut primitives = Vec::new();
cx.tcx_opt().map(|tcx| {
- for item in tcx.sess.cstore.crate_top_level_items(self.0) {
+ let root = DefId { krate: self.0, index: CRATE_DEF_INDEX };
+ for item in tcx.sess.cstore.item_children(root) {
let did = match item.def {
- cstore::DlDef(Def::Mod(did)) => did,
+ Def::Mod(did) => did,
_ => continue
};
let attrs = inline::load_attrs(cx, tcx, did);
impl<'tcx> Clean<Item> for ty::FieldDefData<'tcx, 'static> {
fn clean(&self, cx: &DocContext) -> Item {
- // FIXME: possible O(n^2)-ness! Not my fault.
- let attr_map = cx.tcx().sess.cstore.crate_struct_field_attrs(self.did.krate);
Item {
name: Some(self.name).clean(cx),
- attrs: attr_map.get(&self.did).unwrap_or(&Vec::new()).clean(cx),
+ attrs: cx.tcx().get_attrs(self.did).clean(cx),
source: Span::empty(),
visibility: self.vis.clean(cx),
stability: get_stability(cx, self.did),
use rustc_driver::{driver, target_features, abort_on_err};
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config};
-use rustc::hir::def_id::{CrateNum, DefId};
+use rustc::hir::def_id::DefId;
use rustc::hir::def::Def;
use rustc::middle::privacy::AccessLevels;
use rustc::ty::{self, TyCtxt};
use rustc::hir::map as hir_map;
use rustc::lint;
-use rustc::util::nodemap::{FnvHashMap, FnvHashSet};
+use rustc::util::nodemap::FnvHashMap;
use rustc_trans::back::link;
use rustc_resolve as resolve;
use rustc_metadata::cstore::CStore;
pub map: &'a hir_map::Map<'tcx>,
pub maybe_typed: MaybeTyped<'a, 'tcx>,
pub input: Input,
- pub populated_crate_impls: RefCell<FnvHashSet<CrateNum>>,
+ pub populated_all_crate_impls: Cell<bool>,
pub deref_trait_did: Cell<Option<DefId>>,
pub deref_mut_trait_did: Cell<Option<DefId>>,
// Note that external items for which `doc(hidden)` applies to are shown as
map: &tcx.map,
maybe_typed: Typed(tcx),
input: input,
- populated_crate_impls: Default::default(),
+ populated_all_crate_impls: Cell::new(false),
deref_trait_did: Cell::new(None),
deref_mut_trait_did: Cell::new(None),
access_levels: RefCell::new(access_levels),
map: &map,
maybe_typed: core::NotTyped(&sess),
input: input,
+ populated_all_crate_impls: Cell::new(false),
external_traits: Default::default(),
- populated_crate_impls: Default::default(),
deref_trait_did: Cell::new(None),
deref_mut_trait_did: Cell::new(None),
access_levels: Default::default(),
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use rustc::middle::cstore::{CrateStore, ChildItem, DefLike};
+use rustc::middle::cstore::{CrateStore, ChildItem};
use rustc::middle::privacy::{AccessLevels, AccessLevel};
use rustc::hir::def::Def;
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
pub fn visit_mod(&mut self, did: DefId) {
for item in self.cstore.item_children(did) {
- if let DefLike::DlDef(def) = item.def {
- match def {
- Def::Mod(did) |
- Def::ForeignMod(did) |
- Def::Trait(did) |
- Def::Struct(did) |
- Def::Union(did) |
- Def::Enum(did) |
- Def::TyAlias(did) |
- Def::Fn(did) |
- Def::Method(did) |
- Def::Static(did, _) |
- Def::Const(did) => self.visit_item(did, item),
- _ => {}
- }
+ match item.def {
+ Def::Mod(did) |
+ Def::ForeignMod(did) |
+ Def::Trait(did) |
+ Def::Struct(did) |
+ Def::Union(did) |
+ Def::Enum(did) |
+ Def::TyAlias(did) |
+ Def::Fn(did) |
+ Def::Method(did) |
+ Def::Static(did, _) |
+ Def::Const(did) => self.visit_item(did, item),
+ _ => {}
}
}
}
fn visit_item(&mut self, did: DefId, item: ChildItem) {
let inherited_item_level = match item.def {
- DefLike::DlImpl(..) | DefLike::DlField => unreachable!(),
- DefLike::DlDef(def) => {
- match def {
- Def::ForeignMod(..) => self.prev_level,
- _ => if item.vis == Visibility::Public { self.prev_level } else { None }
- }
- }
+ Def::ForeignMod(..) => self.prev_level,
+ _ => if item.vis == Visibility::Public { self.prev_level } else { None }
};
let item_level = self.update(did, inherited_item_level);
- if let DefLike::DlDef(Def::Mod(did)) = item.def {
+ if let Def::Mod(did) = item.def {
let orig_level = self.prev_level;
self.prev_level = item_level;