rustc_metadata: rip out unused incremental infrastructure.

This commit is contained in:
Eduard-Mihai Burtescu 2019-05-22 12:16:48 +03:00
parent c99090761c
commit 7327768a75
6 changed files with 125 additions and 623 deletions

View File

@ -475,7 +475,7 @@ impl<'a, 'tcx> CrateMetadata {
fn maybe_entry(&self, item_id: DefIndex) -> Option<Lazy<Entry<'tcx>>> { fn maybe_entry(&self, item_id: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
assert!(!self.is_proc_macro(item_id)); assert!(!self.is_proc_macro(item_id));
self.root.index.lookup(self.blob.raw_bytes(), item_id) self.root.entries_index.lookup(self.blob.raw_bytes(), item_id)
} }
fn entry(&self, item_id: DefIndex) -> Entry<'tcx> { fn entry(&self, item_id: DefIndex) -> Entry<'tcx> {

View File

@ -1,6 +1,4 @@
use crate::index::Index; use crate::index::Index;
use crate::index_builder::{FromId, IndexBuilder, Untracked};
use crate::isolated_encoder::IsolatedEncoder;
use crate::schema::*; use crate::schema::*;
use rustc::middle::cstore::{LinkagePreference, NativeLibrary, use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
@ -46,6 +44,8 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
opaque: opaque::Encoder, opaque: opaque::Encoder,
pub tcx: TyCtxt<'a, 'tcx, 'tcx>, pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
entries_index: Index<'tcx>,
lazy_state: LazyState, lazy_state: LazyState,
type_shorthands: FxHashMap<Ty<'tcx>, usize>, type_shorthands: FxHashMap<Ty<'tcx>, usize>,
predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>, predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
@ -300,28 +300,34 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}) })
} }
// Encodes something that corresponds to a single DepNode::GlobalMetaData /// Emit the data for a `DefId` to the metadata. The function to
// and registers the Fingerprint in the `metadata_hashes` map. /// emit the data is `op`, and it will be given `data` as
pub fn tracked<'x, DATA, R>(&'x mut self, /// arguments. This `record` function will call `op` to generate
op: fn(&mut IsolatedEncoder<'x, 'a, 'tcx>, DATA) -> R, /// the `Entry` (which may point to other encoded information)
data: DATA) /// and will then record the `Lazy<Entry>` for use in the index.
-> R { // FIXME(eddyb) remove this.
op(&mut IsolatedEncoder::new(self), data) pub fn record<DATA>(&mut self,
id: DefId,
op: impl FnOnce(&mut Self, DATA) -> Entry<'tcx>,
data: DATA)
{
assert!(id.is_local());
let entry = op(self, data);
let entry = self.lazy(&entry);
self.entries_index.record(id, entry);
} }
fn encode_info_for_items(&mut self) -> Index<'tcx> { fn encode_info_for_items(&mut self) {
let krate = self.tcx.hir().krate(); let krate = self.tcx.hir().krate();
let mut index = IndexBuilder::new(self);
let vis = Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Public }; let vis = Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Public };
index.record(DefId::local(CRATE_DEF_INDEX), self.record(DefId::local(CRATE_DEF_INDEX),
IsolatedEncoder::encode_info_for_mod, EncodeContext::encode_info_for_mod,
FromId(hir::CRATE_HIR_ID, (&krate.module, &krate.attrs, &vis))); (hir::CRATE_HIR_ID, &krate.module, &krate.attrs, &vis));
let mut visitor = EncodeVisitor { index }; krate.visit_all_item_likes(&mut self.as_deep_visitor());
krate.visit_all_item_likes(&mut visitor.as_deep_visitor());
for macro_def in &krate.exported_macros { for macro_def in &krate.exported_macros {
visitor.visit_macro_def(macro_def); self.visit_macro_def(macro_def);
} }
visitor.index.into_items()
} }
fn encode_def_path_table(&mut self) -> Lazy<DefPathTable> { fn encode_def_path_table(&mut self) -> Lazy<DefPathTable> {
@ -374,35 +380,27 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> { fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
let mut i = self.position(); let mut i = self.position();
let crate_deps = self.tracked(IsolatedEncoder::encode_crate_deps, ()); let crate_deps = self.encode_crate_deps();
let dylib_dependency_formats = self.tracked( let dylib_dependency_formats = self.encode_dylib_dependency_formats();
IsolatedEncoder::encode_dylib_dependency_formats,
());
let dep_bytes = self.position() - i; let dep_bytes = self.position() - i;
// Encode the lib features. // Encode the lib features.
i = self.position(); i = self.position();
let lib_features = self.tracked(IsolatedEncoder::encode_lib_features, ()); let lib_features = self.encode_lib_features();
let lib_feature_bytes = self.position() - i; let lib_feature_bytes = self.position() - i;
// Encode the language items. // Encode the language items.
i = self.position(); i = self.position();
let lang_items = self.tracked(IsolatedEncoder::encode_lang_items, ()); let lang_items = self.encode_lang_items();
let lang_items_missing = self.tracked( let lang_items_missing = self.encode_lang_items_missing();
IsolatedEncoder::encode_lang_items_missing,
());
let lang_item_bytes = self.position() - i; let lang_item_bytes = self.position() - i;
// Encode the native libraries used // Encode the native libraries used
i = self.position(); i = self.position();
let native_libraries = self.tracked( let native_libraries = self.encode_native_libraries();
IsolatedEncoder::encode_native_libraries,
());
let native_lib_bytes = self.position() - i; let native_lib_bytes = self.position() - i;
let foreign_modules = self.tracked( let foreign_modules = self.encode_foreign_modules();
IsolatedEncoder::encode_foreign_modules,
());
// Encode source_map // Encode source_map
i = self.position(); i = self.position();
@ -416,22 +414,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Encode the def IDs of impls, for coherence checking. // Encode the def IDs of impls, for coherence checking.
i = self.position(); i = self.position();
let impls = self.tracked(IsolatedEncoder::encode_impls, ()); let impls = self.encode_impls();
let impl_bytes = self.position() - i; let impl_bytes = self.position() - i;
// Encode exported symbols info. // Encode exported symbols info.
i = self.position(); i = self.position();
let exported_symbols = self.tcx.exported_symbols(LOCAL_CRATE); let exported_symbols = self.tcx.exported_symbols(LOCAL_CRATE);
let exported_symbols = self.tracked( let exported_symbols = self.encode_exported_symbols(&exported_symbols);
IsolatedEncoder::encode_exported_symbols,
&exported_symbols);
let exported_symbols_bytes = self.position() - i; let exported_symbols_bytes = self.position() - i;
let tcx = self.tcx; let tcx = self.tcx;
// Encode the items. // Encode the items.
i = self.position(); i = self.position();
let items = self.encode_info_for_items(); self.encode_info_for_items();
let item_bytes = self.position() - i; let item_bytes = self.position() - i;
// Encode the allocation index // Encode the allocation index
@ -462,10 +458,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.lazy_seq(interpret_alloc_index) self.lazy_seq(interpret_alloc_index)
}; };
// Index the items
i = self.position(); i = self.position();
let index = items.write_index(&mut self.opaque); let entries_index = self.entries_index.write_index(&mut self.opaque);
let index_bytes = self.position() - i; let entries_index_bytes = self.position() - i;
let attrs = tcx.hir().krate_attrs(); let attrs = tcx.hir().krate_attrs();
let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro); let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
@ -516,7 +511,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
impls, impls,
exported_symbols, exported_symbols,
interpret_alloc_index, interpret_alloc_index,
index, entries_index,
}); });
let total_bytes = self.position(); let total_bytes = self.position();
@ -539,7 +534,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
println!(" exp. symbols bytes: {}", exported_symbols_bytes); println!(" exp. symbols bytes: {}", exported_symbols_bytes);
println!(" def-path table bytes: {}", def_path_table_bytes); println!(" def-path table bytes: {}", def_path_table_bytes);
println!(" item bytes: {}", item_bytes); println!(" item bytes: {}", item_bytes);
println!(" index bytes: {}", index_bytes); println!(" entries index bytes: {}", entries_index_bytes);
println!(" zero bytes: {}", zero_bytes); println!(" zero bytes: {}", zero_bytes);
println!(" total bytes: {}", total_bytes); println!(" total bytes: {}", total_bytes);
} }
@ -548,40 +543,29 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} }
} }
// These are methods for encoding various things. They are meant to be used with impl EncodeContext<'_, 'tcx> {
// IndexBuilder::record() and EncodeContext::tracked(). They actually
// would not have to be methods of IsolatedEncoder (free standing functions
// taking IsolatedEncoder as first argument would be just fine) but by making
// them methods we don't have to repeat the lengthy `<'a, 'b: 'a, 'tcx: 'b>`
// clause again and again.
impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
fn encode_variances_of(&mut self, def_id: DefId) -> LazySeq<ty::Variance> { fn encode_variances_of(&mut self, def_id: DefId) -> LazySeq<ty::Variance> {
debug!("IsolatedEncoder::encode_variances_of({:?})", def_id); debug!("EncodeContext::encode_variances_of({:?})", def_id);
let tcx = self.tcx; let tcx = self.tcx;
self.lazy_seq_from_slice(&tcx.variances_of(def_id)) self.lazy_seq_ref(&tcx.variances_of(def_id)[..])
} }
fn encode_item_type(&mut self, def_id: DefId) -> Lazy<Ty<'tcx>> { fn encode_item_type(&mut self, def_id: DefId) -> Lazy<Ty<'tcx>> {
let tcx = self.tcx; let tcx = self.tcx;
let ty = tcx.type_of(def_id); let ty = tcx.type_of(def_id);
debug!("IsolatedEncoder::encode_item_type({:?}) => {:?}", def_id, ty); debug!("EncodeContext::encode_item_type({:?}) => {:?}", def_id, ty);
self.lazy(&ty) self.lazy(&ty)
} }
/// 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
/// the right to access any information in the adt-def (including,
/// e.g., the length of the various vectors).
fn encode_enum_variant_info( fn encode_enum_variant_info(
&mut self, &mut self,
(enum_did, Untracked(index)): (DefId, Untracked<VariantIdx>), (enum_did, index): (DefId, VariantIdx),
) -> Entry<'tcx> { ) -> Entry<'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
let def = tcx.adt_def(enum_did); let def = tcx.adt_def(enum_did);
let variant = &def.variants[index]; let variant = &def.variants[index];
let def_id = variant.def_id; let def_id = variant.def_id;
debug!("IsolatedEncoder::encode_enum_variant_info({:?})", def_id); debug!("EncodeContext::encode_enum_variant_info({:?})", def_id);
let data = VariantData { let data = VariantData {
ctor_kind: variant.ctor_kind, ctor_kind: variant.ctor_kind,
@ -625,17 +609,15 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} }
} }
/// Encode the constructor for the given variant of the given ADT. See
/// `encode_enum_variant_info` for an explanation about why the index is untracked.
fn encode_enum_variant_ctor( fn encode_enum_variant_ctor(
&mut self, &mut self,
(enum_did, Untracked(index)): (DefId, Untracked<VariantIdx>), (enum_did, index): (DefId, VariantIdx),
) -> Entry<'tcx> { ) -> Entry<'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
let def = tcx.adt_def(enum_did); let def = tcx.adt_def(enum_did);
let variant = &def.variants[index]; let variant = &def.variants[index];
let def_id = variant.ctor_def_id.unwrap(); let def_id = variant.ctor_def_id.unwrap();
debug!("IsolatedEncoder::encode_enum_variant_ctor({:?})", def_id); debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
let data = VariantData { let data = VariantData {
ctor_kind: variant.ctor_kind, ctor_kind: variant.ctor_kind,
@ -681,18 +663,17 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} }
} }
fn encode_info_for_mod(&mut self, fn encode_info_for_mod(
FromId(id, (md, attrs, vis)): FromId<(&hir::Mod, &mut self,
&[ast::Attribute], (id, md, attrs, vis): (hir::HirId, &hir::Mod, &[ast::Attribute], &hir::Visibility),
&hir::Visibility)>) ) -> Entry<'tcx> {
-> Entry<'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
let def_id = tcx.hir().local_def_id_from_hir_id(id); let def_id = tcx.hir().local_def_id_from_hir_id(id);
debug!("IsolatedEncoder::encode_info_for_mod({:?})", def_id); debug!("EncodeContext::encode_info_for_mod({:?})", def_id);
let data = ModData { let data = ModData {
reexports: match tcx.module_exports(def_id) { reexports: match tcx.module_exports(def_id) {
Some(ref exports) => self.lazy_seq_from_slice(exports.as_slice()), Some(ref exports) => self.lazy_seq_ref(&exports[..]),
_ => LazySeq::empty(), _ => LazySeq::empty(),
}, },
}; };
@ -719,23 +700,16 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} }
} }
/// Encode data for the given field of the given variant of the fn encode_field(
/// given ADT. The indices of the variant/field are untracked: &mut self,
/// this is ok because we will have to lookup the adt-def by its (adt_def_id, variant_index, field_index): (DefId, VariantIdx, usize),
/// id, and that gives us the right to access any information in ) -> Entry<'tcx> {
/// the adt-def (including, e.g., the length of the various
/// vectors).
fn encode_field(&mut self,
(adt_def_id, Untracked((variant_index, field_index))): (DefId,
Untracked<(VariantIdx,
usize)>))
-> Entry<'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
let variant = &tcx.adt_def(adt_def_id).variants[variant_index]; let variant = &tcx.adt_def(adt_def_id).variants[variant_index];
let field = &variant.fields[field_index]; let field = &variant.fields[field_index];
let def_id = field.did; let def_id = field.did;
debug!("IsolatedEncoder::encode_field({:?})", def_id); debug!("EncodeContext::encode_field({:?})", def_id);
let variant_id = tcx.hir().as_local_hir_id(variant.def_id).unwrap(); let variant_id = tcx.hir().as_local_hir_id(variant.def_id).unwrap();
let variant_data = tcx.hir().expect_variant_data(variant_id); let variant_data = tcx.hir().expect_variant_data(variant_id);
@ -761,7 +735,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} }
fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<'tcx> { fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<'tcx> {
debug!("IsolatedEncoder::encode_struct_ctor({:?})", def_id); debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
let tcx = self.tcx; let tcx = self.tcx;
let adt_def = tcx.adt_def(adt_def_id); let adt_def = tcx.adt_def(adt_def_id);
let variant = adt_def.non_enum_variant(); let variant = adt_def.non_enum_variant();
@ -821,25 +795,25 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} }
fn encode_generics(&mut self, def_id: DefId) -> Lazy<ty::Generics> { fn encode_generics(&mut self, def_id: DefId) -> Lazy<ty::Generics> {
debug!("IsolatedEncoder::encode_generics({:?})", def_id); debug!("EncodeContext::encode_generics({:?})", def_id);
let tcx = self.tcx; let tcx = self.tcx;
self.lazy(tcx.generics_of(def_id)) self.lazy(tcx.generics_of(def_id))
} }
fn encode_predicates(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> { fn encode_predicates(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> {
debug!("IsolatedEncoder::encode_predicates({:?})", def_id); debug!("EncodeContext::encode_predicates({:?})", def_id);
let tcx = self.tcx; let tcx = self.tcx;
self.lazy(&tcx.predicates_of(def_id)) self.lazy(&tcx.predicates_of(def_id))
} }
fn encode_predicates_defined_on(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> { fn encode_predicates_defined_on(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> {
debug!("IsolatedEncoder::encode_predicates_defined_on({:?})", def_id); debug!("EncodeContext::encode_predicates_defined_on({:?})", def_id);
let tcx = self.tcx; let tcx = self.tcx;
self.lazy(&tcx.predicates_defined_on(def_id)) self.lazy(&tcx.predicates_defined_on(def_id))
} }
fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> { fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
debug!("IsolatedEncoder::encode_info_for_trait_item({:?})", def_id); debug!("EncodeContext::encode_info_for_trait_item({:?})", def_id);
let tcx = self.tcx; let tcx = self.tcx;
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
@ -949,7 +923,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} }
fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> { fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
debug!("IsolatedEncoder::encode_info_for_impl_item({:?})", def_id); debug!("EncodeContext::encode_info_for_impl_item({:?})", def_id);
let tcx = self.tcx; let tcx = self.tcx;
let hir_id = self.tcx.hir().as_local_hir_id(def_id).unwrap(); let hir_id = self.tcx.hir().as_local_hir_id(def_id).unwrap();
@ -1064,7 +1038,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
// Encodes the inherent implementations of a structure, enumeration, or trait. // Encodes the inherent implementations of a structure, enumeration, or trait.
fn encode_inherent_implementations(&mut self, def_id: DefId) -> LazySeq<DefIndex> { fn encode_inherent_implementations(&mut self, def_id: DefId) -> LazySeq<DefIndex> {
debug!("IsolatedEncoder::encode_inherent_implementations({:?})", def_id); debug!("EncodeContext::encode_inherent_implementations({:?})", def_id);
let implementations = self.tcx.inherent_impls(def_id); let implementations = self.tcx.inherent_impls(def_id);
if implementations.is_empty() { if implementations.is_empty() {
LazySeq::empty() LazySeq::empty()
@ -1077,12 +1051,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} }
fn encode_stability(&mut self, def_id: DefId) -> Option<Lazy<attr::Stability>> { fn encode_stability(&mut self, def_id: DefId) -> Option<Lazy<attr::Stability>> {
debug!("IsolatedEncoder::encode_stability({:?})", def_id); debug!("EncodeContext::encode_stability({:?})", def_id);
self.tcx.lookup_stability(def_id).map(|stab| self.lazy(stab)) self.tcx.lookup_stability(def_id).map(|stab| self.lazy(stab))
} }
fn encode_deprecation(&mut self, def_id: DefId) -> Option<Lazy<attr::Deprecation>> { fn encode_deprecation(&mut self, def_id: DefId) -> Option<Lazy<attr::Deprecation>> {
debug!("IsolatedEncoder::encode_deprecation({:?})", def_id); debug!("EncodeContext::encode_deprecation({:?})", def_id);
self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(&depr)) self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(&depr))
} }
@ -1096,7 +1070,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) -> Entry<'tcx> { fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) -> Entry<'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
debug!("IsolatedEncoder::encode_info_for_item({:?})", def_id); debug!("EncodeContext::encode_info_for_item({:?})", def_id);
let kind = match item.node { let kind = match item.node {
hir::ItemKind::Static(_, hir::MutMutable, _) => EntryKind::MutStatic, hir::ItemKind::Static(_, hir::MutMutable, _) => EntryKind::MutStatic,
@ -1118,7 +1092,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
EntryKind::Fn(self.lazy(&data)) EntryKind::Fn(self.lazy(&data))
} }
hir::ItemKind::Mod(ref m) => { hir::ItemKind::Mod(ref m) => {
return self.encode_info_for_mod(FromId(item.hir_id, (m, &item.attrs, &item.vis))); return self.encode_info_for_mod((item.hir_id, m, &item.attrs, &item.vis));
} }
hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod, hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod,
hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm, hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
@ -1391,9 +1365,9 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
fn encode_info_for_ty_param( fn encode_info_for_ty_param(
&mut self, &mut self,
(def_id, Untracked(encode_type)): (DefId, Untracked<bool>), (def_id, encode_type): (DefId, bool),
) -> Entry<'tcx> { ) -> Entry<'tcx> {
debug!("IsolatedEncoder::encode_info_for_ty_param({:?})", def_id); debug!("EncodeContext::encode_info_for_ty_param({:?})", def_id);
self.encode_info_for_generic_param(def_id, EntryKind::TypeParam, encode_type) self.encode_info_for_generic_param(def_id, EntryKind::TypeParam, encode_type)
} }
@ -1401,12 +1375,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
&mut self, &mut self,
def_id: DefId, def_id: DefId,
) -> Entry<'tcx> { ) -> Entry<'tcx> {
debug!("IsolatedEncoder::encode_info_for_const_param({:?})", def_id); debug!("EncodeContext::encode_info_for_const_param({:?})", def_id);
self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true) self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true)
} }
fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> { fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
debug!("IsolatedEncoder::encode_info_for_closure({:?})", def_id); debug!("EncodeContext::encode_info_for_closure({:?})", def_id);
let tcx = self.tcx; let tcx = self.tcx;
let tables = self.tcx.typeck_tables_of(def_id); let tables = self.tcx.typeck_tables_of(def_id);
@ -1450,7 +1424,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} }
fn encode_info_for_anon_const(&mut self, def_id: DefId) -> Entry<'tcx> { fn encode_info_for_anon_const(&mut self, def_id: DefId) -> Entry<'tcx> {
debug!("IsolatedEncoder::encode_info_for_anon_const({:?})", def_id); debug!("EncodeContext::encode_info_for_anon_const({:?})", def_id);
let tcx = self.tcx; let tcx = self.tcx;
let id = tcx.hir().as_local_hir_id(def_id).unwrap(); let id = tcx.hir().as_local_hir_id(def_id).unwrap();
let body_id = tcx.hir().body_owned_by(id); let body_id = tcx.hir().body_owned_by(id);
@ -1478,23 +1452,20 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} }
fn encode_attributes(&mut self, attrs: &[ast::Attribute]) -> LazySeq<ast::Attribute> { fn encode_attributes(&mut self, attrs: &[ast::Attribute]) -> LazySeq<ast::Attribute> {
// NOTE: This must use lazy_seq_from_slice(), not lazy_seq() because self.lazy_seq_ref(attrs)
// we rely on the HashStable specialization for [Attribute]
// to properly filter things out.
self.lazy_seq_from_slice(attrs)
} }
fn encode_native_libraries(&mut self, _: ()) -> LazySeq<NativeLibrary> { fn encode_native_libraries(&mut self) -> LazySeq<NativeLibrary> {
let used_libraries = self.tcx.native_libraries(LOCAL_CRATE); let used_libraries = self.tcx.native_libraries(LOCAL_CRATE);
self.lazy_seq(used_libraries.iter().cloned()) self.lazy_seq(used_libraries.iter().cloned())
} }
fn encode_foreign_modules(&mut self, _: ()) -> LazySeq<ForeignModule> { fn encode_foreign_modules(&mut self) -> LazySeq<ForeignModule> {
let foreign_modules = self.tcx.foreign_modules(LOCAL_CRATE); let foreign_modules = self.tcx.foreign_modules(LOCAL_CRATE);
self.lazy_seq(foreign_modules.iter().cloned()) self.lazy_seq(foreign_modules.iter().cloned())
} }
fn encode_crate_deps(&mut self, _: ()) -> LazySeq<CrateDep> { fn encode_crate_deps(&mut self) -> LazySeq<CrateDep> {
let crates = self.tcx.crates(); let crates = self.tcx.crates();
let mut deps = crates let mut deps = crates
@ -1528,13 +1499,13 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
self.lazy_seq_ref(deps.iter().map(|&(_, ref dep)| dep)) self.lazy_seq_ref(deps.iter().map(|&(_, ref dep)| dep))
} }
fn encode_lib_features(&mut self, _: ()) -> LazySeq<(ast::Name, Option<ast::Name>)> { fn encode_lib_features(&mut self) -> LazySeq<(ast::Name, Option<ast::Name>)> {
let tcx = self.tcx; let tcx = self.tcx;
let lib_features = tcx.lib_features(); let lib_features = tcx.lib_features();
self.lazy_seq(lib_features.to_vec()) self.lazy_seq(lib_features.to_vec())
} }
fn encode_lang_items(&mut self, _: ()) -> LazySeq<(DefIndex, usize)> { fn encode_lang_items(&mut self) -> LazySeq<(DefIndex, usize)> {
let tcx = self.tcx; let tcx = self.tcx;
let lang_items = tcx.lang_items(); let lang_items = tcx.lang_items();
let lang_items = lang_items.items().iter(); let lang_items = lang_items.items().iter();
@ -1548,14 +1519,14 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
})) }))
} }
fn encode_lang_items_missing(&mut self, _: ()) -> LazySeq<lang_items::LangItem> { fn encode_lang_items_missing(&mut self) -> LazySeq<lang_items::LangItem> {
let tcx = self.tcx; let tcx = self.tcx;
self.lazy_seq_ref(&tcx.lang_items().missing) self.lazy_seq_ref(&tcx.lang_items().missing)
} }
/// Encodes an index, mapping each trait to its (local) implementations. /// Encodes an index, mapping each trait to its (local) implementations.
fn encode_impls(&mut self, _: ()) -> LazySeq<TraitImpls> { fn encode_impls(&mut self) -> LazySeq<TraitImpls> {
debug!("IsolatedEncoder::encode_impls()"); debug!("EncodeContext::encode_impls()");
let tcx = self.tcx; let tcx = self.tcx;
let mut visitor = ImplVisitor { let mut visitor = ImplVisitor {
tcx, tcx,
@ -1580,12 +1551,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
TraitImpls { TraitImpls {
trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index),
impls: self.lazy_seq_from_slice(&impls[..]), impls: self.lazy_seq_ref(&impls),
} }
}) })
.collect(); .collect();
self.lazy_seq_from_slice(&all_impls[..]) self.lazy_seq_ref(&all_impls)
} }
// Encodes all symbols exported from this crate into the metadata. // Encodes all symbols exported from this crate into the metadata.
@ -1614,7 +1585,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
.cloned()) .cloned())
} }
fn encode_dylib_dependency_formats(&mut self, _: ()) -> LazySeq<Option<LinkagePreference>> { fn encode_dylib_dependency_formats(&mut self) -> LazySeq<Option<LinkagePreference>> {
match self.tcx.sess.dependency_formats.borrow().get(&config::CrateType::Dylib) { match self.tcx.sess.dependency_formats.borrow().get(&config::CrateType::Dylib) {
Some(arr) => { Some(arr) => {
self.lazy_seq(arr.iter().map(|slot| { self.lazy_seq(arr.iter().map(|slot| {
@ -1636,7 +1607,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
-> Entry<'tcx> { -> Entry<'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
debug!("IsolatedEncoder::encode_info_for_foreign_item({:?})", def_id); debug!("EncodeContext::encode_info_for_foreign_item({:?})", def_id);
let kind = match nitem.node { let kind = match nitem.node {
hir::ForeignItemKind::Fn(_, ref names, _) => { hir::ForeignItemKind::Fn(_, ref names, _) => {
@ -1676,33 +1647,29 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} }
} }
struct EncodeVisitor<'a, 'b: 'a, 'tcx: 'b> { impl Visitor<'tcx> for EncodeContext<'_, 'tcx> {
index: IndexBuilder<'a, 'b, 'tcx>,
}
impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.index.tcx.hir()) NestedVisitorMap::OnlyBodies(&self.tcx.hir())
} }
fn visit_expr(&mut self, ex: &'tcx hir::Expr) { fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
intravisit::walk_expr(self, ex); intravisit::walk_expr(self, ex);
self.index.encode_info_for_expr(ex); self.encode_info_for_expr(ex);
} }
fn visit_item(&mut self, item: &'tcx hir::Item) { fn visit_item(&mut self, item: &'tcx hir::Item) {
intravisit::walk_item(self, item); intravisit::walk_item(self, item);
let def_id = self.index.tcx.hir().local_def_id_from_hir_id(item.hir_id); let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
match item.node { match item.node {
hir::ItemKind::ExternCrate(_) | hir::ItemKind::ExternCrate(_) |
hir::ItemKind::Use(..) => (), // ignore these hir::ItemKind::Use(..) => {} // ignore these
_ => self.index.record(def_id, IsolatedEncoder::encode_info_for_item, (def_id, item)), _ => self.record(def_id, EncodeContext::encode_info_for_item, (def_id, item)),
} }
self.index.encode_addl_info_for_item(item); self.encode_addl_info_for_item(item);
} }
fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) {
intravisit::walk_foreign_item(self, ni); intravisit::walk_foreign_item(self, ni);
let def_id = self.index.tcx.hir().local_def_id_from_hir_id(ni.hir_id); let def_id = self.tcx.hir().local_def_id_from_hir_id(ni.hir_id);
self.index.record(def_id, self.record(def_id,
IsolatedEncoder::encode_info_for_foreign_item, EncodeContext::encode_info_for_foreign_item,
(def_id, ni)); (def_id, ni));
} }
fn visit_variant(&mut self, fn visit_variant(&mut self,
@ -1712,32 +1679,32 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> {
intravisit::walk_variant(self, v, g, id); intravisit::walk_variant(self, v, g, id);
if let Some(ref discr) = v.node.disr_expr { if let Some(ref discr) = v.node.disr_expr {
let def_id = self.index.tcx.hir().local_def_id_from_hir_id(discr.hir_id); let def_id = self.tcx.hir().local_def_id_from_hir_id(discr.hir_id);
self.index.record(def_id, IsolatedEncoder::encode_info_for_anon_const, def_id); self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id);
} }
} }
fn visit_generics(&mut self, generics: &'tcx hir::Generics) { fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
intravisit::walk_generics(self, generics); intravisit::walk_generics(self, generics);
self.index.encode_info_for_generics(generics); self.encode_info_for_generics(generics);
} }
fn visit_ty(&mut self, ty: &'tcx hir::Ty) { fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
intravisit::walk_ty(self, ty); intravisit::walk_ty(self, ty);
self.index.encode_info_for_ty(ty); self.encode_info_for_ty(ty);
} }
fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef) { fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef) {
let def_id = self.index.tcx.hir().local_def_id_from_hir_id(macro_def.hir_id); let def_id = self.tcx.hir().local_def_id_from_hir_id(macro_def.hir_id);
self.index.record(def_id, IsolatedEncoder::encode_info_for_macro_def, macro_def); self.record(def_id, EncodeContext::encode_info_for_macro_def, macro_def);
} }
} }
impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { impl EncodeContext<'_, 'tcx> {
fn encode_fields(&mut self, adt_def_id: DefId) { fn encode_fields(&mut self, adt_def_id: DefId) {
let def = self.tcx.adt_def(adt_def_id); let def = self.tcx.adt_def(adt_def_id);
for (variant_index, variant) in def.variants.iter_enumerated() { for (variant_index, variant) in def.variants.iter_enumerated() {
for (field_index, field) in variant.fields.iter().enumerate() { for (field_index, field) in variant.fields.iter().enumerate() {
self.record(field.did, self.record(field.did,
IsolatedEncoder::encode_field, EncodeContext::encode_field,
(adt_def_id, Untracked((variant_index, field_index)))); (adt_def_id, variant_index, field_index));
} }
} }
} }
@ -1750,12 +1717,12 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
GenericParamKind::Type { ref default, .. } => { GenericParamKind::Type { ref default, .. } => {
self.record( self.record(
def_id, def_id,
IsolatedEncoder::encode_info_for_ty_param, EncodeContext::encode_info_for_ty_param,
(def_id, Untracked(default.is_some())), (def_id, default.is_some()),
); );
} }
GenericParamKind::Const { .. } => { GenericParamKind::Const { .. } => {
self.record(def_id, IsolatedEncoder::encode_info_for_const_param, def_id); self.record(def_id, EncodeContext::encode_info_for_const_param, def_id);
} }
} }
} }
@ -1765,7 +1732,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
match ty.node { match ty.node {
hir::TyKind::Array(_, ref length) => { hir::TyKind::Array(_, ref length) => {
let def_id = self.tcx.hir().local_def_id_from_hir_id(length.hir_id); let def_id = self.tcx.hir().local_def_id_from_hir_id(length.hir_id);
self.record(def_id, IsolatedEncoder::encode_info_for_anon_const, def_id); self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id);
} }
_ => {} _ => {}
} }
@ -1775,7 +1742,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
match expr.node { match expr.node {
hir::ExprKind::Closure(..) => { hir::ExprKind::Closure(..) => {
let def_id = self.tcx.hir().local_def_id_from_hir_id(expr.hir_id); let def_id = self.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
self.record(def_id, IsolatedEncoder::encode_info_for_closure, def_id); self.record(def_id, EncodeContext::encode_info_for_closure, def_id);
} }
_ => {} _ => {}
} }
@ -1807,13 +1774,13 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
let def = self.tcx.adt_def(def_id); let def = self.tcx.adt_def(def_id);
for (i, variant) in def.variants.iter_enumerated() { for (i, variant) in def.variants.iter_enumerated() {
self.record(variant.def_id, self.record(variant.def_id,
IsolatedEncoder::encode_enum_variant_info, EncodeContext::encode_enum_variant_info,
(def_id, Untracked(i))); (def_id, i));
if let Some(ctor_def_id) = variant.ctor_def_id { if let Some(ctor_def_id) = variant.ctor_def_id {
self.record(ctor_def_id, self.record(ctor_def_id,
IsolatedEncoder::encode_enum_variant_ctor, EncodeContext::encode_enum_variant_ctor,
(def_id, Untracked(i))); (def_id, i));
} }
} }
} }
@ -1824,7 +1791,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() { if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
let ctor_def_id = self.tcx.hir().local_def_id_from_hir_id(ctor_hir_id); let ctor_def_id = self.tcx.hir().local_def_id_from_hir_id(ctor_hir_id);
self.record(ctor_def_id, self.record(ctor_def_id,
IsolatedEncoder::encode_struct_ctor, EncodeContext::encode_struct_ctor,
(def_id, ctor_def_id)); (def_id, ctor_def_id));
} }
} }
@ -1834,14 +1801,14 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
hir::ItemKind::Impl(..) => { hir::ItemKind::Impl(..) => {
for &trait_item_def_id in self.tcx.associated_item_def_ids(def_id).iter() { for &trait_item_def_id in self.tcx.associated_item_def_ids(def_id).iter() {
self.record(trait_item_def_id, self.record(trait_item_def_id,
IsolatedEncoder::encode_info_for_impl_item, EncodeContext::encode_info_for_impl_item,
trait_item_def_id); trait_item_def_id);
} }
} }
hir::ItemKind::Trait(..) => { hir::ItemKind::Trait(..) => {
for &item_def_id in self.tcx.associated_item_def_ids(def_id).iter() { for &item_def_id in self.tcx.associated_item_def_ids(def_id).iter() {
self.record(item_def_id, self.record(item_def_id,
IsolatedEncoder::encode_info_for_trait_item, EncodeContext::encode_info_for_trait_item,
item_def_id); item_def_id);
} }
} }
@ -1906,10 +1873,13 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
// Will be filled with the root position after encoding everything. // Will be filled with the root position after encoding everything.
encoder.emit_raw_bytes(&[0, 0, 0, 0]); encoder.emit_raw_bytes(&[0, 0, 0, 0]);
let (root, mut result) = { // Since encoding metadata is not in a query, and nothing is cached,
// there's no need to do dep-graph tracking for any of it.
let (root, mut result) = tcx.dep_graph.with_ignore(move || {
let mut ecx = EncodeContext { let mut ecx = EncodeContext {
opaque: encoder, opaque: encoder,
tcx, tcx,
entries_index: Index::new(tcx.hir().definitions().def_index_count()),
lazy_state: LazyState::NoNode, lazy_state: LazyState::NoNode,
type_shorthands: Default::default(), type_shorthands: Default::default(),
predicate_shorthands: Default::default(), predicate_shorthands: Default::default(),
@ -1925,7 +1895,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
// culminating in the `CrateRoot` which points to all of it. // culminating in the `CrateRoot` which points to all of it.
let root = ecx.encode_crate_root(); let root = ecx.encode_crate_root();
(root, ecx.opaque.into_inner()) (root, ecx.opaque.into_inner())
}; });
// Encode the root position. // Encode the root position.
let header = METADATA_HEADER.len(); let header = METADATA_HEADER.len();

View File

@ -1,224 +0,0 @@
//! Builder types for generating the "item data" section of the
//! metadata. This section winds up looking like this:
//!
//! ```
//! <common::data> // big list of item-like things...
//! <common::data_item> // ...for most `DefId`s, there is an entry.
//! </common::data_item>
//! </common::data>
//! ```
//!
//! As we generate this listing, we collect the offset of each
//! `data_item` entry and store it in an index. Then, when we load the
//! metadata, we can skip right to the metadata for a particular item.
//!
//! In addition to the offset, we need to track the data that was used
//! to generate the contents of each `data_item`. This is so that we
//! can figure out which HIR nodes contributed to that data for
//! incremental compilation purposes.
//!
//! The `IndexBuilder` facilitates both of these. It is created
//! with an `EncodingContext` (`ecx`), which it encapsulates.
//! It has one main method, `record()`. You invoke `record`
//! like so to create a new `data_item` element in the list:
//!
//! ```
//! index.record(some_def_id, callback_fn, data)
//! ```
//!
//! 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 the `EncodingContext`. Once `callback_fn`
//! returns, the `common::data_item` tag will be closed.
//!
//! `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
//! reads/writes that occur in the task. For this reason, the `data`
//! argument that is given to the `callback_fn` must implement the
//! trait `DepGraphRead`, which indicates how to register reads on the
//! data in this new task (note that many types of data, such as
//! `DefId`, do not currently require any reads to be registered,
//! since they are not derived from a HIR node). This is also why we
//! give a callback fn, rather than taking a closure: it allows us to
//! easily control precisely what data is given to that fn.
use crate::encoder::EncodeContext;
use crate::index::Index;
use crate::schema::*;
use crate::isolated_encoder::IsolatedEncoder;
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::ty::TyCtxt;
use syntax::ast;
use std::ops::{Deref, DerefMut};
/// Builder that can encode new items, adding them into the index.
/// Item encoding cannot be nested.
pub struct IndexBuilder<'a, 'b: 'a, 'tcx: 'b> {
items: Index<'tcx>,
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.ecx
}
}
impl<'a, 'b, 'tcx> DerefMut for IndexBuilder<'a, 'b, 'tcx> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.ecx
}
}
impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
pub fn new(ecx: &'a mut EncodeContext<'b, 'tcx>) -> Self {
IndexBuilder {
items: Index::new(ecx.tcx.hir().definitions().def_index_count()),
ecx,
}
}
/// Emit the data for a `DefId` to the metadata. The function to
/// emit the data is `op`, and it will be given `data` as
/// arguments. This `record` function will call `op` to generate
/// the `Entry` (which may point to other encoded information)
/// and will then record the `Lazy<Entry>` for use in the index.
///
/// In addition, it will setup a dep-graph task to track what data
/// `op` accesses to generate the metadata, which is later used by
/// incremental compilation to compute a hash for the metadata and
/// track changes.
///
/// The reason that `op` is a function pointer, and not a closure,
/// is that we want to be able to completely track all data it has
/// access to, so that we can be sure that `DATA: DepGraphRead`
/// holds, and that it is therefore not gaining "secret" access to
/// bits of HIR or other state that would not be trackd by the
/// content system.
pub fn record<'x, DATA>(&'x mut self,
id: DefId,
op: fn(&mut IsolatedEncoder<'x, 'b, 'tcx>, DATA) -> Entry<'tcx>,
data: DATA)
where DATA: DepGraphRead
{
assert!(id.is_local());
// We don't track this since we are explicitly computing the incr. comp.
// hashes anyway. In theory we could do some tracking here and use it to
// avoid rehashing things (and instead cache the hashes) but it's
// unclear whether that would be a win since hashing is cheap enough.
self.ecx.tcx.dep_graph.with_ignore(move || {
let mut entry_builder = IsolatedEncoder::new(self.ecx);
let entry = op(&mut entry_builder, data);
let entry = entry_builder.lazy(&entry);
self.items.record(id, entry);
})
}
pub fn into_items(self) -> Index<'tcx> {
self.items
}
}
/// Trait used for data that can be passed from outside a dep-graph
/// task. The data must either be of some safe type, such as a
/// `DefId` index, or implement the `read` method so that it can add
/// a read of whatever dep-graph nodes are appropriate.
pub trait DepGraphRead {
fn read(&self, tcx: TyCtxt<'_, '_, '_>);
}
impl DepGraphRead for DefId {
fn read(&self, _tcx: TyCtxt<'_, '_, '_>) {}
}
impl DepGraphRead for ast::NodeId {
fn read(&self, _tcx: TyCtxt<'_, '_, '_>) {}
}
impl<T> DepGraphRead for Option<T>
where T: DepGraphRead
{
fn read(&self, tcx: TyCtxt<'_, '_, '_>) {
match *self {
Some(ref v) => v.read(tcx),
None => (),
}
}
}
impl<T> DepGraphRead for [T]
where T: DepGraphRead
{
fn read(&self, tcx: TyCtxt<'_, '_, '_>) {
for i in self {
i.read(tcx);
}
}
}
macro_rules! read_tuple {
($($name:ident),*) => {
impl<$($name),*> DepGraphRead for ($($name),*)
where $($name: DepGraphRead),*
{
#[allow(non_snake_case)]
fn read(&self, tcx: TyCtxt<'_, '_, '_>) {
let &($(ref $name),*) = self;
$($name.read(tcx);)*
}
}
}
}
read_tuple!(A, B);
read_tuple!(A, B, C);
macro_rules! read_hir {
($t:ty) => {
impl<'tcx> DepGraphRead for &'tcx $t {
fn read(&self, tcx: TyCtxt<'_, '_, '_>) {
tcx.hir().read(self.hir_id);
}
}
}
}
read_hir!(hir::Item);
read_hir!(hir::ImplItem);
read_hir!(hir::TraitItem);
read_hir!(hir::ForeignItem);
read_hir!(hir::MacroDef);
/// Leaks access to a value of type T without any tracking. This is
/// suitable for ambiguous types like `usize`, which *could* represent
/// tracked data (e.g., if you read it out of a HIR node) or might not
/// (e.g., if it's an index). Adding in an `Untracked` is an
/// assertion, essentially, that the data does not need to be tracked
/// (or that read edges will be added by some other way).
///
/// A good idea is to add to each use of `Untracked` an explanation of
/// why this value is ok.
pub struct Untracked<T>(pub T);
impl<T> DepGraphRead for Untracked<T> {
fn read(&self, _tcx: TyCtxt<'_, '_, '_>) {}
}
/// Newtype that can be used to package up misc data extracted from a
/// HIR node that doesn't carry its own ID. This will allow an
/// arbitrary `T` to be passed in, but register a read on the given
/// `NodeId`.
pub struct FromId<T>(pub hir::HirId, pub T);
impl<T> DepGraphRead for FromId<T> {
fn read(&self, tcx: TyCtxt<'_, '_, '_>) {
tcx.hir().read(self.0);
}
}

View File

@ -1,48 +0,0 @@
use crate::encoder::EncodeContext;
use crate::schema::{Lazy, LazySeq};
use rustc::ty::TyCtxt;
use rustc_serialize::Encodable;
/// The IsolatedEncoder provides facilities to write to crate metadata while
/// making sure that anything going through it is also feed into an ICH hasher.
pub struct IsolatedEncoder<'a, 'b: 'a, 'tcx: 'b> {
pub tcx: TyCtxt<'b, 'tcx, 'tcx>,
ecx: &'a mut EncodeContext<'b, 'tcx>,
}
impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
pub fn new(ecx: &'a mut EncodeContext<'b, 'tcx>) -> Self {
let tcx = ecx.tcx;
IsolatedEncoder {
tcx,
ecx,
}
}
pub fn lazy<T>(&mut self, value: &T) -> Lazy<T>
where T: Encodable
{
self.ecx.lazy(value)
}
pub fn lazy_seq<I, T>(&mut self, iter: I) -> LazySeq<T>
where I: IntoIterator<Item = T>,
T: Encodable
{
self.ecx.lazy_seq(iter)
}
pub fn lazy_seq_ref<'x, I, T>(&mut self, iter: I) -> LazySeq<T>
where I: IntoIterator<Item = &'x T>,
T: 'x + Encodable
{
self.ecx.lazy_seq_ref(iter)
}
pub fn lazy_seq_from_slice<T>(&mut self, slice: &[T]) -> LazySeq<T>
where T: Encodable
{
self.ecx.lazy_seq_ref(slice.iter())
}
}

View File

@ -29,12 +29,10 @@ extern crate rustc_data_structures;
mod error_codes; mod error_codes;
mod index_builder;
mod index; mod index;
mod encoder; mod encoder;
mod decoder; mod decoder;
mod cstore_impl; mod cstore_impl;
mod isolated_encoder;
mod schema; mod schema;
mod native_libs; mod native_libs;
mod link_args; mod link_args;

View File

@ -2,8 +2,7 @@ use crate::index;
use rustc::hir; use rustc::hir;
use rustc::hir::def::{self, CtorKind}; use rustc::hir::def::{self, CtorKind};
use rustc::hir::def_id::{DefIndex, DefId, CrateNum}; use rustc::hir::def_id::{DefIndex, DefId};
use rustc::ich::StableHashingContext;
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary, ForeignModule}; use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary, ForeignModule};
use rustc::middle::lang_items; use rustc::middle::lang_items;
@ -20,10 +19,6 @@ use syntax::symbol::Symbol;
use syntax_pos::{self, Span}; use syntax_pos::{self, Span};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem;
use rustc_data_structures::stable_hasher::{StableHasher, HashStable,
StableHasherResult};
pub fn rustc_version() -> String { pub fn rustc_version() -> String {
format!("rustc {}", format!("rustc {}",
@ -92,15 +87,6 @@ impl<T> Clone for Lazy<T> {
impl<T> serialize::UseSpecializedEncodable for Lazy<T> {} impl<T> serialize::UseSpecializedEncodable for Lazy<T> {}
impl<T> serialize::UseSpecializedDecodable for Lazy<T> {} impl<T> serialize::UseSpecializedDecodable for Lazy<T> {}
impl<CTX, T> HashStable<CTX> for Lazy<T> {
fn hash_stable<W: StableHasherResult>(&self,
_: &mut CTX,
_: &mut StableHasher<W>) {
// There's nothing to do. Whatever got encoded within this Lazy<>
// wrapper has already been hashed.
}
}
/// A sequence of type T referred to by its absolute position /// A sequence of type T referred to by its absolute position
/// in the metadata and length, and which can be decoded lazily. /// in the metadata and length, and which can be decoded lazily.
/// The sequence is a single node for the purposes of `Lazy`. /// The sequence is a single node for the purposes of `Lazy`.
@ -149,15 +135,6 @@ impl<T> Clone for LazySeq<T> {
impl<T> serialize::UseSpecializedEncodable for LazySeq<T> {} impl<T> serialize::UseSpecializedEncodable for LazySeq<T> {}
impl<T> serialize::UseSpecializedDecodable for LazySeq<T> {} impl<T> serialize::UseSpecializedDecodable for LazySeq<T> {}
impl<CTX, T> HashStable<CTX> for LazySeq<T> {
fn hash_stable<W: StableHasherResult>(&self,
_: &mut CTX,
_: &mut StableHasher<W>) {
// There's nothing to do. Whatever got encoded within this Lazy<>
// wrapper has already been hashed.
}
}
/// Encoding / decoding state for `Lazy` and `LazySeq`. /// Encoding / decoding state for `Lazy` and `LazySeq`.
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum LazyState { pub enum LazyState {
@ -203,7 +180,7 @@ pub struct CrateRoot<'tcx> {
pub exported_symbols: LazySeq<(ExportedSymbol<'tcx>, SymbolExportLevel)>, pub exported_symbols: LazySeq<(ExportedSymbol<'tcx>, SymbolExportLevel)>,
pub interpret_alloc_index: LazySeq<u32>, pub interpret_alloc_index: LazySeq<u32>,
pub index: LazySeq<index::Index<'tcx>>, pub entries_index: LazySeq<index::Index<'tcx>>,
pub compiler_builtins: bool, pub compiler_builtins: bool,
pub needs_allocator: bool, pub needs_allocator: bool,
@ -222,36 +199,12 @@ pub struct CrateDep {
pub extra_filename: String, pub extra_filename: String,
} }
impl_stable_hash_for!(struct CrateDep {
name,
hash,
kind,
extra_filename
});
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct TraitImpls { pub struct TraitImpls {
pub trait_id: (u32, DefIndex), pub trait_id: (u32, DefIndex),
pub impls: LazySeq<DefIndex>, pub impls: LazySeq<DefIndex>,
} }
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TraitImpls {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let TraitImpls {
trait_id: (krate, def_index),
ref impls,
} = *self;
DefId {
krate: CrateNum::from_u32(krate),
index: def_index
}.hash_stable(hcx, hasher);
impls.hash_stable(hcx, hasher);
}
}
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct Entry<'tcx> { pub struct Entry<'tcx> {
pub kind: EntryKind<'tcx>, pub kind: EntryKind<'tcx>,
@ -272,23 +225,6 @@ pub struct Entry<'tcx> {
pub mir: Option<Lazy<mir::Mir<'tcx>>>, pub mir: Option<Lazy<mir::Mir<'tcx>>>,
} }
impl_stable_hash_for!(struct Entry<'tcx> {
kind,
visibility,
span,
attributes,
children,
stability,
deprecation,
ty,
inherent_impls,
variances,
generics,
predicates,
predicates_defined_on,
mir
});
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)] #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
pub enum EntryKind<'tcx> { pub enum EntryKind<'tcx> {
Const(ConstQualif, Lazy<RenderedConst>), Const(ConstQualif, Lazy<RenderedConst>),
@ -323,82 +259,6 @@ pub enum EntryKind<'tcx> {
TraitAlias(Lazy<TraitAliasData<'tcx>>), TraitAlias(Lazy<TraitAliasData<'tcx>>),
} }
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for EntryKind<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
EntryKind::ImmStatic |
EntryKind::MutStatic |
EntryKind::ForeignImmStatic |
EntryKind::ForeignMutStatic |
EntryKind::ForeignMod |
EntryKind::GlobalAsm |
EntryKind::ForeignType |
EntryKind::Field |
EntryKind::Existential |
EntryKind::Type |
EntryKind::TypeParam |
EntryKind::ConstParam => {
// Nothing else to hash here.
}
EntryKind::Const(qualif, ref const_data) => {
qualif.hash_stable(hcx, hasher);
const_data.hash_stable(hcx, hasher);
}
EntryKind::Enum(ref repr_options) => {
repr_options.hash_stable(hcx, hasher);
}
EntryKind::Variant(ref variant_data) => {
variant_data.hash_stable(hcx, hasher);
}
EntryKind::Struct(ref variant_data, ref repr_options) |
EntryKind::Union(ref variant_data, ref repr_options) => {
variant_data.hash_stable(hcx, hasher);
repr_options.hash_stable(hcx, hasher);
}
EntryKind::Fn(ref fn_data) |
EntryKind::ForeignFn(ref fn_data) => {
fn_data.hash_stable(hcx, hasher);
}
EntryKind::Mod(ref mod_data) => {
mod_data.hash_stable(hcx, hasher);
}
EntryKind::MacroDef(ref macro_def) => {
macro_def.hash_stable(hcx, hasher);
}
EntryKind::Generator(data) => {
data.hash_stable(hcx, hasher);
}
EntryKind::Closure(closure_data) => {
closure_data.hash_stable(hcx, hasher);
}
EntryKind::Trait(ref trait_data) => {
trait_data.hash_stable(hcx, hasher);
}
EntryKind::TraitAlias(ref trait_alias_data) => {
trait_alias_data.hash_stable(hcx, hasher);
}
EntryKind::Impl(ref impl_data) => {
impl_data.hash_stable(hcx, hasher);
}
EntryKind::Method(ref method_data) => {
method_data.hash_stable(hcx, hasher);
}
EntryKind::AssociatedExistential(associated_container) |
EntryKind::AssociatedType(associated_container) => {
associated_container.hash_stable(hcx, hasher);
}
EntryKind::AssociatedConst(associated_container, qualif, ref const_data) => {
associated_container.hash_stable(hcx, hasher);
qualif.hash_stable(hcx, hasher);
const_data.hash_stable(hcx, hasher);
}
}
}
}
/// Additional data for EntryKind::Const and EntryKind::AssociatedConst /// Additional data for EntryKind::Const and EntryKind::AssociatedConst
#[derive(Clone, Copy, RustcEncodable, RustcDecodable)] #[derive(Clone, Copy, RustcEncodable, RustcDecodable)]
pub struct ConstQualif { pub struct ConstQualif {
@ -406,37 +266,22 @@ pub struct ConstQualif {
pub ast_promotable: bool, pub ast_promotable: bool,
} }
impl_stable_hash_for!(struct ConstQualif { mir, ast_promotable });
/// Contains a constant which has been rendered to a String. /// Contains a constant which has been rendered to a String.
/// Used by rustdoc. /// Used by rustdoc.
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct RenderedConst(pub String); pub struct RenderedConst(pub String);
impl<'a> HashStable<StableHashingContext<'a>> for RenderedConst {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.0.hash_stable(hcx, hasher);
}
}
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct ModData { pub struct ModData {
pub reexports: LazySeq<def::Export<hir::HirId>>, pub reexports: LazySeq<def::Export<hir::HirId>>,
} }
impl_stable_hash_for!(struct ModData { reexports });
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct MacroDef { pub struct MacroDef {
pub body: String, pub body: String,
pub legacy: bool, pub legacy: bool,
} }
impl_stable_hash_for!(struct MacroDef { body, legacy });
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct FnData<'tcx> { pub struct FnData<'tcx> {
pub constness: hir::Constness, pub constness: hir::Constness,
@ -444,8 +289,6 @@ pub struct FnData<'tcx> {
pub sig: Lazy<ty::PolyFnSig<'tcx>>, pub sig: Lazy<ty::PolyFnSig<'tcx>>,
} }
impl_stable_hash_for!(struct FnData<'tcx> { constness, arg_names, sig });
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct VariantData<'tcx> { pub struct VariantData<'tcx> {
pub ctor_kind: CtorKind, pub ctor_kind: CtorKind,
@ -457,13 +300,6 @@ pub struct VariantData<'tcx> {
pub ctor_sig: Option<Lazy<ty::PolyFnSig<'tcx>>>, pub ctor_sig: Option<Lazy<ty::PolyFnSig<'tcx>>>,
} }
impl_stable_hash_for!(struct VariantData<'tcx> {
ctor_kind,
discr,
ctor,
ctor_sig
});
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct TraitData<'tcx> { pub struct TraitData<'tcx> {
pub unsafety: hir::Unsafety, pub unsafety: hir::Unsafety,
@ -473,23 +309,11 @@ pub struct TraitData<'tcx> {
pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>, pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
} }
impl_stable_hash_for!(struct TraitData<'tcx> {
unsafety,
paren_sugar,
has_auto_impl,
is_marker,
super_predicates
});
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct TraitAliasData<'tcx> { pub struct TraitAliasData<'tcx> {
pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>, pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
} }
impl_stable_hash_for!(struct TraitAliasData<'tcx> {
super_predicates
});
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct ImplData<'tcx> { pub struct ImplData<'tcx> {
pub polarity: hir::ImplPolarity, pub polarity: hir::ImplPolarity,
@ -501,14 +325,6 @@ pub struct ImplData<'tcx> {
pub trait_ref: Option<Lazy<ty::TraitRef<'tcx>>>, pub trait_ref: Option<Lazy<ty::TraitRef<'tcx>>>,
} }
impl_stable_hash_for!(struct ImplData<'tcx> {
polarity,
defaultness,
parent_impl,
coerce_unsized_info,
trait_ref
});
/// Describes whether the container of an associated item /// Describes whether the container of an associated item
/// is a trait or an impl and whether, in a trait, it has /// is a trait or an impl and whether, in a trait, it has
@ -521,13 +337,6 @@ pub enum AssociatedContainer {
ImplFinal, ImplFinal,
} }
impl_stable_hash_for!(enum crate::schema::AssociatedContainer {
TraitRequired,
TraitWithDefault,
ImplDefault,
ImplFinal
});
impl AssociatedContainer { impl AssociatedContainer {
pub fn with_def_id(&self, def_id: DefId) -> ty::AssociatedItemContainer { pub fn with_def_id(&self, def_id: DefId) -> ty::AssociatedItemContainer {
match *self { match *self {
@ -561,19 +370,16 @@ pub struct MethodData<'tcx> {
pub container: AssociatedContainer, pub container: AssociatedContainer,
pub has_self: bool, pub has_self: bool,
} }
impl_stable_hash_for!(struct MethodData<'tcx> { fn_data, container, has_self });
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct ClosureData<'tcx> { pub struct ClosureData<'tcx> {
pub sig: Lazy<ty::PolyFnSig<'tcx>>, pub sig: Lazy<ty::PolyFnSig<'tcx>>,
} }
impl_stable_hash_for!(struct ClosureData<'tcx> { sig });
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct GeneratorData<'tcx> { pub struct GeneratorData<'tcx> {
pub layout: mir::GeneratorLayout<'tcx>, pub layout: mir::GeneratorLayout<'tcx>,
} }
impl_stable_hash_for!(struct GeneratorData<'tcx> { layout });
// Tags used for encoding Spans: // Tags used for encoding Spans:
pub const TAG_VALID_SPAN: u8 = 0; pub const TAG_VALID_SPAN: u8 = 0;