use index::Index;
use schema::*;
-use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary};
+use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
+ EncodedMetadata, EncodedMetadataHash};
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId};
use rustc::hir::map::definitions::DefPathTable;
use rustc::middle::dependency_format::Linkage;
use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
use rustc::hir::intravisit;
-use super::index_builder::{FromId, IndexBuilder, Untracked};
+use super::index_builder::{FromId, IndexBuilder, Untracked, EntryBuilder};
pub struct EncodeContext<'a, 'tcx: 'a> {
opaque: opaque::Encoder<'a>,
lazy_state: LazyState,
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
+
+ pub metadata_hashes: Vec<EncodedMetadataHash>,
}
macro_rules! encoder_methods {
})
}
- fn lazy_seq<I, T>(&mut self, iter: I) -> LazySeq<T>
+ pub fn lazy_seq<I, T>(&mut self, iter: I) -> LazySeq<T>
where I: IntoIterator<Item = T>,
T: Encodable
{
})
}
- fn lazy_seq_ref<'b, I, T>(&mut self, iter: I) -> LazySeq<T>
+ pub fn lazy_seq_ref<'b, I, T>(&mut self, iter: I) -> LazySeq<T>
where I: IntoIterator<Item = &'b T>,
T: 'b + Encodable
{
Ok(())
}
+}
+impl<'a, 'b: 'a, 'tcx: 'b> EntryBuilder<'a, 'b, 'tcx> {
fn encode_item_variances(&mut self, def_id: DefId) -> LazySeq<ty::Variance> {
+ debug!("EntryBuilder::encode_item_variances({:?})", def_id);
let tcx = self.tcx;
- self.lazy_seq(tcx.item_variances(def_id).iter().cloned())
+ self.lazy_seq_from_slice(&tcx.item_variances(def_id))
}
fn encode_item_type(&mut self, def_id: DefId) -> Lazy<Ty<'tcx>> {
let tcx = self.tcx;
- self.lazy(&tcx.item_type(def_id))
+ let ty = tcx.item_type(def_id);
+ debug!("EntryBuilder::encode_item_type({:?}) => {:?}", def_id, ty);
+ self.lazy(&ty)
}
/// Encode data for the given variant of the given ADT. The
let def = tcx.lookup_adt_def(enum_did);
let variant = &def.variants[index];
let def_id = variant.did;
+ debug!("EntryBuilder::encode_enum_variant_info({:?})", def_id);
let data = VariantData {
ctor_kind: variant.ctor_kind,
-> Entry<'tcx> {
let tcx = self.tcx;
let def_id = tcx.hir.local_def_id(id);
+ debug!("EntryBuilder::encode_info_for_mod({:?})", def_id);
let data = ModData {
reexports: match tcx.export_map.get(&id) {
- Some(exports) if *vis == hir::Public => self.lazy_seq_ref(exports),
+ Some(exports) if *vis == hir::Public => {
+ self.lazy_seq_from_slice(exports.as_slice())
+ }
_ => LazySeq::empty(),
},
};
for (variant_index, variant) in def.variants.iter().enumerate() {
for (field_index, field) in variant.fields.iter().enumerate() {
self.record(field.did,
- EncodeContext::encode_field,
+ EntryBuilder::encode_field,
(adt_def_id, Untracked((variant_index, field_index))));
}
}
}
}
-impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
+impl<'a, 'b: 'a, 'tcx: 'b> EntryBuilder<'a, 'b, '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
let field = &variant.fields[field_index];
let def_id = field.did;
+ debug!("EntryBuilder::encode_field({:?})", def_id);
+
let variant_id = tcx.hir.as_local_node_id(variant.did).unwrap();
let variant_data = tcx.hir.expect_variant_data(variant_id);
}
fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<'tcx> {
+ debug!("EntryBuilder::encode_struct_ctor({:?})", def_id);
let tcx = self.tcx;
let variant = tcx.lookup_adt_def(adt_def_id).struct_variant();
}
fn encode_generics(&mut self, def_id: DefId) -> Lazy<ty::Generics> {
+ debug!("EntryBuilder::encode_generics({:?})", def_id);
let tcx = self.tcx;
self.lazy(tcx.item_generics(def_id))
}
fn encode_predicates(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> {
+ debug!("EntryBuilder::encode_predicates({:?})", def_id);
let tcx = self.tcx;
self.lazy(&tcx.item_predicates(def_id))
}
fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
+ debug!("EntryBuilder::encode_info_for_trait_item({:?})", def_id);
let tcx = self.tcx;
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
}
fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
+ debug!("EntryBuilder::encode_info_for_impl_item({:?})", def_id);
let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
let ast_item = self.tcx.hir.expect_impl_item(node_id);
let impl_item = self.tcx.associated_item(def_id);
}
fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Mir<'tcx>>> {
+ debug!("EntryBuilder::encode_mir({:?})", def_id);
self.tcx.maps.mir.borrow().get(&def_id).map(|mir| self.lazy(&*mir.borrow()))
}
// Encodes the inherent implementations of a structure, enumeration, or trait.
fn encode_inherent_implementations(&mut self, def_id: DefId) -> LazySeq<DefIndex> {
+ debug!("EntryBuilder::encode_inherent_implementations({:?})", def_id);
match self.tcx.maps.inherent_impls.borrow().get(&def_id) {
None => LazySeq::empty(),
Some(implementations) => {
}
fn encode_stability(&mut self, def_id: DefId) -> Option<Lazy<attr::Stability>> {
+ debug!("EntryBuilder::encode_stability({:?})", def_id);
self.tcx.lookup_stability(def_id).map(|stab| self.lazy(stab))
}
fn encode_deprecation(&mut self, def_id: DefId) -> Option<Lazy<attr::Deprecation>> {
+ debug!("EntryBuilder::encode_deprecation({:?})", def_id);
self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(&depr))
}
fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) -> Entry<'tcx> {
let tcx = self.tcx;
- debug!("encoding info for item at {}",
- tcx.sess.codemap().span_to_string(item.span));
+ debug!("EntryBuilder::encode_info_for_item({:?})", def_id);
let kind = match item.node {
hir::ItemStatic(_, hir::MutMutable, _) => EntryKind::MutStatic,
let def = self.tcx.lookup_adt_def(def_id);
for (i, variant) in def.variants.iter().enumerate() {
self.record(variant.did,
- EncodeContext::encode_enum_variant_info,
+ EntryBuilder::encode_enum_variant_info,
(def_id, Untracked(i)));
}
}
if !struct_def.is_struct() {
let ctor_def_id = self.tcx.hir.local_def_id(struct_def.id());
self.record(ctor_def_id,
- EncodeContext::encode_struct_ctor,
+ EntryBuilder::encode_struct_ctor,
(def_id, ctor_def_id));
}
}
hir::ItemImpl(..) => {
for &trait_item_def_id in self.tcx.associated_item_def_ids(def_id).iter() {
self.record(trait_item_def_id,
- EncodeContext::encode_info_for_impl_item,
+ EntryBuilder::encode_info_for_impl_item,
trait_item_def_id);
}
}
hir::ItemTrait(..) => {
for &item_def_id in self.tcx.associated_item_def_ids(def_id).iter() {
self.record(item_def_id,
- EncodeContext::encode_info_for_trait_item,
+ EntryBuilder::encode_info_for_trait_item,
item_def_id);
}
}
}
}
-impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
+impl<'a, 'b: 'a, 'tcx: 'b> EntryBuilder<'a, 'b, 'tcx> {
fn encode_info_for_foreign_item(&mut self,
(def_id, nitem): (DefId, &hir::ForeignItem))
-> Entry<'tcx> {
let tcx = self.tcx;
- debug!("writing foreign item {}", tcx.node_path_str(nitem.id));
+ debug!("EntryBuilder::encode_info_for_foreign_item({:?})", def_id);
let kind = match nitem.node {
hir::ForeignItemFn(_, ref names, _) => {
match item.node {
hir::ItemExternCrate(_) |
hir::ItemUse(..) => (), // ignore these
- _ => self.index.record(def_id, EncodeContext::encode_info_for_item, (def_id, item)),
+ _ => self.index.record(def_id, EntryBuilder::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.hir.local_def_id(ni.id);
self.index.record(def_id,
- EncodeContext::encode_info_for_foreign_item,
+ EntryBuilder::encode_info_for_foreign_item,
(def_id, ni));
}
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
}
fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef) {
let def_id = self.index.tcx.hir.local_def_id(macro_def.id);
- self.index.record(def_id, EncodeContext::encode_info_for_macro_def, macro_def);
+ self.index.record(def_id, EntryBuilder::encode_info_for_macro_def, macro_def);
}
}
for ty_param in &generics.ty_params {
let def_id = self.tcx.hir.local_def_id(ty_param.id);
let has_default = Untracked(ty_param.default.is_some());
- self.record(def_id, EncodeContext::encode_info_for_ty_param, (def_id, has_default));
+ self.record(def_id, EntryBuilder::encode_info_for_ty_param, (def_id, has_default));
}
}
fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
if let hir::TyImplTrait(_) = ty.node {
let def_id = self.tcx.hir.local_def_id(ty.id);
- self.record(def_id, EncodeContext::encode_info_for_anon_ty, def_id);
+ self.record(def_id, EntryBuilder::encode_info_for_anon_ty, def_id);
}
}
match expr.node {
hir::ExprClosure(..) => {
let def_id = self.tcx.hir.local_def_id(expr.id);
- self.record(def_id, EncodeContext::encode_info_for_closure, def_id);
+ self.record(def_id, EntryBuilder::encode_info_for_closure, def_id);
}
_ => {}
}
}
}
-impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
+impl<'a, 'b: 'a, 'tcx: 'b> EntryBuilder<'a, 'b, 'tcx> {
fn encode_info_for_ty_param(&mut self,
(def_id, Untracked(has_default)): (DefId, Untracked<bool>))
-> Entry<'tcx> {
+ debug!("EntryBuilder::encode_info_for_ty_param({:?})", def_id);
let tcx = self.tcx;
Entry {
kind: EntryKind::Type,
}
fn encode_info_for_anon_ty(&mut self, def_id: DefId) -> Entry<'tcx> {
+ debug!("EntryBuilder::encode_info_for_anon_ty({:?})", def_id);
let tcx = self.tcx;
Entry {
kind: EntryKind::Type,
}
fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
+ debug!("EntryBuilder::encode_info_for_closure({:?})", def_id);
let tcx = self.tcx;
let data = ClosureData {
}
}
+ fn encode_attributes(&mut self, attrs: &[ast::Attribute]) -> LazySeq<ast::Attribute> {
+ // NOTE: This must use lazy_seq_from_slice(), not lazy_seq() because
+ // we really on the HashStable specialization for [Attribute]
+ // to properly filter things out.
+ self.lazy_seq_from_slice(attrs)
+ }
+}
+
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_info_for_items(&mut self) -> Index {
let krate = self.tcx.hir.krate();
let mut index = IndexBuilder::new(self);
index.record(DefId::local(CRATE_DEF_INDEX),
- EncodeContext::encode_info_for_mod,
+ EntryBuilder::encode_info_for_mod,
FromId(CRATE_NODE_ID, (&krate.module, &krate.attrs, &hir::Public)));
let mut visitor = EncodeVisitor { index: index };
krate.visit_all_item_likes(&mut visitor.as_deep_visitor());
visitor.index.into_items()
}
- fn encode_attributes(&mut self, attrs: &[ast::Attribute]) -> LazySeq<ast::Attribute> {
- self.lazy_seq_ref(attrs)
- }
-
fn encode_crate_deps(&mut self) -> LazySeq<CrateDep> {
fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<(CrateNum, Rc<cstore::CrateMetadata>)> {
// Pull the cnums and name,vers,hash out of cstore
None => LazySeq::empty(),
}
}
+}
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
let mut i = self.position();
let crate_deps = self.encode_crate_deps();
cstore: &cstore::CStore,
link_meta: &LinkMeta,
exported_symbols: &NodeSet)
- -> Vec<u8> {
+ -> EncodedMetadata
+{
let mut cursor = Cursor::new(vec![]);
cursor.write_all(METADATA_HEADER).unwrap();
// Will be filed with the root position after encoding everything.
cursor.write_all(&[0, 0, 0, 0]).unwrap();
- let root = {
+ let (root, metadata_hashes) = {
let mut ecx = EncodeContext {
opaque: opaque::Encoder::new(&mut cursor),
tcx: tcx,
lazy_state: LazyState::NoNode,
type_shorthands: Default::default(),
predicate_shorthands: Default::default(),
+ metadata_hashes: Vec::new(),
};
// Encode the rustc version string in a predictable location.
// Encode all the entries and extra information in the crate,
// culminating in the `CrateRoot` which points to all of it.
- ecx.encode_crate_root()
+ let root = ecx.encode_crate_root();
+ (root, ecx.metadata_hashes)
};
let mut result = cursor.into_inner();
result[header + 2] = (pos >> 8) as u8;
result[header + 3] = (pos >> 0) as u8;
- result
+ EncodedMetadata {
+ raw_data: result,
+ hashes: metadata_hashes,
+ }
}
pub fn get_repr_options<'a, 'tcx, 'gcx>(tcx: &TyCtxt<'a, 'tcx, 'gcx>, did: DefId) -> ReprOptions {