Split crate_hash from index_hir.
This commit is contained in:
parent
553004539e
commit
323f5b2ac9
@ -91,7 +91,7 @@ macro_rules! arena_types {
|
||||
[] predicates: rustc_middle::ty::PredicateInner<$tcx>,
|
||||
|
||||
// HIR query types
|
||||
[few] indexed_hir: rustc_middle::hir::map::IndexedHir<$tcx>,
|
||||
[few] indexed_hir: rustc_middle::hir::IndexedHir<$tcx>,
|
||||
[few] hir_definitions: rustc_hir::definitions::Definitions,
|
||||
[] hir_owner: rustc_middle::hir::Owner<$tcx>,
|
||||
[] hir_owner_nodes: rustc_middle::hir::OwnerNodes<$tcx>,
|
||||
|
@ -2,21 +2,19 @@ use crate::arena::Arena;
|
||||
use crate::hir::map::{Entry, HirOwnerData, Map};
|
||||
use crate::hir::{Owner, OwnerNodes, ParentedNode};
|
||||
use crate::ich::StableHashingContext;
|
||||
use crate::middle::cstore::CrateStore;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::def_id::CRATE_DEF_INDEX;
|
||||
use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::{self, DefPathHash};
|
||||
use rustc_hir::definitions;
|
||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::*;
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_session::{CrateDisambiguator, Session};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::{Span, Symbol, DUMMY_SP};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use std::iter::repeat;
|
||||
|
||||
@ -40,10 +38,6 @@ pub(super) struct NodeCollector<'a, 'hir> {
|
||||
definitions: &'a definitions::Definitions,
|
||||
|
||||
hcx: StableHashingContext<'a>,
|
||||
|
||||
// We are collecting HIR hashes here so we can compute the
|
||||
// crate hash from them later on.
|
||||
hir_body_nodes: Vec<(DefPathHash, Fingerprint)>,
|
||||
}
|
||||
|
||||
fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V) {
|
||||
@ -58,34 +52,13 @@ fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V
|
||||
|
||||
fn hash_body(
|
||||
hcx: &mut StableHashingContext<'_>,
|
||||
def_path_hash: DefPathHash,
|
||||
item_like: impl for<'a> HashStable<StableHashingContext<'a>>,
|
||||
hir_body_nodes: &mut Vec<(DefPathHash, Fingerprint)>,
|
||||
) -> Fingerprint {
|
||||
let hash = {
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
hcx.while_hashing_hir_bodies(true, |hcx| {
|
||||
item_like.hash_stable(hcx, &mut stable_hasher);
|
||||
});
|
||||
stable_hasher.finish()
|
||||
};
|
||||
hir_body_nodes.push((def_path_hash, hash));
|
||||
hash
|
||||
}
|
||||
|
||||
fn upstream_crates(cstore: &dyn CrateStore) -> Vec<(Symbol, Fingerprint, Svh)> {
|
||||
let mut upstream_crates: Vec<_> = cstore
|
||||
.crates_untracked()
|
||||
.iter()
|
||||
.map(|&cnum| {
|
||||
let name = cstore.crate_name_untracked(cnum);
|
||||
let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
|
||||
let hash = cstore.crate_hash_untracked(cnum);
|
||||
(name, disambiguator, hash)
|
||||
})
|
||||
.collect();
|
||||
upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name.as_str(), dis));
|
||||
upstream_crates
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
hcx.while_hashing_hir_bodies(true, |hcx| {
|
||||
item_like.hash_stable(hcx, &mut stable_hasher);
|
||||
});
|
||||
stable_hasher.finish()
|
||||
}
|
||||
|
||||
impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
@ -96,11 +69,6 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
definitions: &'a definitions::Definitions,
|
||||
mut hcx: StableHashingContext<'a>,
|
||||
) -> NodeCollector<'a, 'hir> {
|
||||
let root_mod_def_path_hash =
|
||||
definitions.def_path_hash(LocalDefId { local_def_index: CRATE_DEF_INDEX });
|
||||
|
||||
let mut hir_body_nodes = Vec::new();
|
||||
|
||||
let hash = {
|
||||
let Crate {
|
||||
ref item,
|
||||
@ -120,7 +88,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
attrs: _,
|
||||
} = *krate;
|
||||
|
||||
hash_body(&mut hcx, root_mod_def_path_hash, item, &mut hir_body_nodes)
|
||||
hash_body(&mut hcx, item)
|
||||
};
|
||||
|
||||
let mut collector = NodeCollector {
|
||||
@ -131,7 +99,6 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
current_dep_node_owner: LocalDefId { local_def_index: CRATE_DEF_INDEX },
|
||||
definitions,
|
||||
hcx,
|
||||
hir_body_nodes,
|
||||
map: (0..definitions.def_index_count())
|
||||
.map(|_| HirOwnerData { signature: None, with_bodies: None })
|
||||
.collect(),
|
||||
@ -147,53 +114,13 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
|
||||
pub(super) fn finalize_and_compute_crate_hash(
|
||||
mut self,
|
||||
crate_disambiguator: CrateDisambiguator,
|
||||
cstore: &dyn CrateStore,
|
||||
commandline_args_hash: u64,
|
||||
) -> (IndexVec<LocalDefId, HirOwnerData<'hir>>, Svh) {
|
||||
) -> IndexVec<LocalDefId, HirOwnerData<'hir>> {
|
||||
// Insert bodies into the map
|
||||
for (id, body) in self.krate.bodies.iter() {
|
||||
let bodies = &mut self.map[id.hir_id.owner].with_bodies.as_mut().unwrap().bodies;
|
||||
assert!(bodies.insert(id.hir_id.local_id, body).is_none());
|
||||
}
|
||||
|
||||
self.hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
|
||||
|
||||
let node_hashes = self.hir_body_nodes.iter().fold(
|
||||
Fingerprint::ZERO,
|
||||
|combined_fingerprint, &(def_path_hash, fingerprint)| {
|
||||
combined_fingerprint.combine(def_path_hash.0.combine(fingerprint))
|
||||
},
|
||||
);
|
||||
|
||||
let upstream_crates = upstream_crates(cstore);
|
||||
|
||||
// We hash the final, remapped names of all local source files so we
|
||||
// don't have to include the path prefix remapping commandline args.
|
||||
// If we included the full mapping in the SVH, we could only have
|
||||
// reproducible builds by compiling from the same directory. So we just
|
||||
// hash the result of the mapping instead of the mapping itself.
|
||||
let mut source_file_names: Vec<_> = self
|
||||
.source_map
|
||||
.files()
|
||||
.iter()
|
||||
.filter(|source_file| source_file.cnum == LOCAL_CRATE)
|
||||
.map(|source_file| source_file.name_hash)
|
||||
.collect();
|
||||
|
||||
source_file_names.sort_unstable();
|
||||
|
||||
let crate_hash_input = (
|
||||
((node_hashes, upstream_crates), source_file_names),
|
||||
(commandline_args_hash, crate_disambiguator.to_fingerprint()),
|
||||
);
|
||||
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
crate_hash_input.hash_stable(&mut self.hcx, &mut stable_hasher);
|
||||
let crate_hash: Fingerprint = stable_hasher.finish();
|
||||
|
||||
let svh = Svh::new(crate_hash.to_smaller_hash());
|
||||
(self.map, svh)
|
||||
self.map
|
||||
}
|
||||
|
||||
fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>, hash: Fingerprint) {
|
||||
@ -294,10 +221,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
f: F,
|
||||
) {
|
||||
let prev_owner = self.current_dep_node_owner;
|
||||
|
||||
let def_path_hash = self.definitions.def_path_hash(dep_node_owner);
|
||||
|
||||
let hash = hash_body(&mut self.hcx, def_path_hash, item_like, &mut self.hir_body_nodes);
|
||||
let hash = hash_body(&mut self.hcx, item_like);
|
||||
|
||||
self.current_dep_node_owner = dep_node_owner;
|
||||
f(self, hash);
|
||||
|
@ -1,8 +1,11 @@
|
||||
use self::collector::NodeCollector;
|
||||
|
||||
use crate::hir::{Owner, OwnerNodes};
|
||||
use crate::hir::{HirOwnerData, IndexedHir};
|
||||
use crate::middle::cstore::CrateStore;
|
||||
use crate::ty::TyCtxt;
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
@ -11,7 +14,6 @@ use rustc_hir::intravisit;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc_hir::*;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||
@ -86,20 +88,6 @@ fn is_body_owner<'hir>(node: Node<'hir>, hir_id: HirId) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct HirOwnerData<'hir> {
|
||||
pub(super) signature: Option<&'hir Owner<'hir>>,
|
||||
pub(super) with_bodies: Option<&'hir mut OwnerNodes<'hir>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IndexedHir<'hir> {
|
||||
/// The SVH of the local crate.
|
||||
pub crate_hash: Svh,
|
||||
|
||||
pub(super) map: IndexVec<LocalDefId, HirOwnerData<'hir>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Map<'hir> {
|
||||
pub(super) tcx: TyCtxt<'hir>,
|
||||
@ -935,19 +923,82 @@ pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> &'tcx Indexe
|
||||
|
||||
let _prof_timer = tcx.sess.prof.generic_activity("build_hir_map");
|
||||
|
||||
let (map, crate_hash) = {
|
||||
let map = {
|
||||
let hcx = tcx.create_stable_hashing_context();
|
||||
|
||||
let mut collector =
|
||||
NodeCollector::root(tcx.sess, &**tcx.arena, tcx.untracked_crate, &tcx.definitions, hcx);
|
||||
intravisit::walk_crate(&mut collector, tcx.untracked_crate);
|
||||
|
||||
let crate_disambiguator = tcx.sess.local_crate_disambiguator();
|
||||
let cmdline_args = tcx.sess.opts.dep_tracking_hash(true);
|
||||
collector.finalize_and_compute_crate_hash(crate_disambiguator, &*tcx.cstore, cmdline_args)
|
||||
collector.finalize_and_compute_crate_hash()
|
||||
};
|
||||
|
||||
tcx.arena.alloc(IndexedHir { crate_hash, map })
|
||||
tcx.arena.alloc(IndexedHir { map })
|
||||
}
|
||||
|
||||
pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
||||
let mut hir_body_nodes: Vec<_> = tcx
|
||||
.index_hir(crate_num)
|
||||
.map
|
||||
.iter_enumerated()
|
||||
.filter_map(|(def_id, hod)| {
|
||||
let def_path_hash = tcx.definitions.def_path_hash(def_id);
|
||||
let hash = hod.with_bodies.as_ref()?.hash;
|
||||
Some((def_path_hash, hash))
|
||||
})
|
||||
.collect();
|
||||
hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
|
||||
|
||||
let node_hashes = hir_body_nodes.iter().fold(
|
||||
Fingerprint::ZERO,
|
||||
|combined_fingerprint, &(def_path_hash, fingerprint)| {
|
||||
combined_fingerprint.combine(def_path_hash.0.combine(fingerprint))
|
||||
},
|
||||
);
|
||||
|
||||
let upstream_crates = upstream_crates(&*tcx.cstore);
|
||||
|
||||
// We hash the final, remapped names of all local source files so we
|
||||
// don't have to include the path prefix remapping commandline args.
|
||||
// If we included the full mapping in the SVH, we could only have
|
||||
// reproducible builds by compiling from the same directory. So we just
|
||||
// hash the result of the mapping instead of the mapping itself.
|
||||
let mut source_file_names: Vec<_> = tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.files()
|
||||
.iter()
|
||||
.filter(|source_file| source_file.cnum == LOCAL_CRATE)
|
||||
.map(|source_file| source_file.name_hash)
|
||||
.collect();
|
||||
|
||||
source_file_names.sort_unstable();
|
||||
|
||||
let mut hcx = tcx.create_stable_hashing_context();
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
node_hashes.hash_stable(&mut hcx, &mut stable_hasher);
|
||||
upstream_crates.hash_stable(&mut hcx, &mut stable_hasher);
|
||||
source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
|
||||
tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
|
||||
tcx.sess.local_crate_disambiguator().to_fingerprint().hash_stable(&mut hcx, &mut stable_hasher);
|
||||
|
||||
let crate_hash: Fingerprint = stable_hasher.finish();
|
||||
Svh::new(crate_hash.to_smaller_hash())
|
||||
}
|
||||
|
||||
fn upstream_crates(cstore: &dyn CrateStore) -> Vec<(Symbol, Fingerprint, Svh)> {
|
||||
let mut upstream_crates: Vec<_> = cstore
|
||||
.crates_untracked()
|
||||
.iter()
|
||||
.map(|&cnum| {
|
||||
let name = cstore.crate_name_untracked(cnum);
|
||||
let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
|
||||
let hash = cstore.crate_hash_untracked(cnum);
|
||||
(name, disambiguator, hash)
|
||||
})
|
||||
.collect();
|
||||
upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name.as_str(), dis));
|
||||
upstream_crates
|
||||
}
|
||||
|
||||
fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String {
|
||||
|
@ -19,6 +19,17 @@ use rustc_index::vec::IndexVec;
|
||||
use rustc_span::DUMMY_SP;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct HirOwnerData<'hir> {
|
||||
signature: Option<&'hir Owner<'hir>>,
|
||||
with_bodies: Option<&'hir mut OwnerNodes<'hir>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IndexedHir<'hir> {
|
||||
map: IndexVec<LocalDefId, HirOwnerData<'hir>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Owner<'tcx> {
|
||||
parent: HirId,
|
||||
@ -117,6 +128,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
};
|
||||
providers.hir_crate = |tcx, _| tcx.untracked_crate;
|
||||
providers.index_hir = map::index_hir;
|
||||
providers.crate_hash = map::crate_hash;
|
||||
providers.hir_module_items = |tcx, id| &tcx.untracked_crate.modules[&id];
|
||||
providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature;
|
||||
providers.hir_owner_nodes = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_deref();
|
||||
|
@ -28,7 +28,7 @@ rustc_queries! {
|
||||
|
||||
/// The indexed HIR. This can be conveniently accessed by `tcx.hir()`.
|
||||
/// Avoid calling this query directly.
|
||||
query index_hir(_: CrateNum) -> &'tcx map::IndexedHir<'tcx> {
|
||||
query index_hir(_: CrateNum) -> &'tcx crate::hir::IndexedHir<'tcx> {
|
||||
eval_always
|
||||
no_hash
|
||||
desc { "index HIR" }
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::dep_graph;
|
||||
use crate::hir::exports::Export;
|
||||
use crate::hir::map;
|
||||
use crate::infer::canonical::{self, Canonical};
|
||||
use crate::lint::LintLevelMap;
|
||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
|
@ -1,5 +1,4 @@
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_middle::hir::map as hir_map;
|
||||
@ -400,10 +399,6 @@ fn original_crate_name(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Symbol {
|
||||
tcx.crate_name
|
||||
}
|
||||
|
||||
fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
||||
tcx.index_hir(crate_num).crate_hash
|
||||
}
|
||||
|
||||
fn instance_def_size_estimate<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
instance_def: ty::InstanceDef<'tcx>,
|
||||
@ -551,7 +546,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
|
||||
trait_of_item,
|
||||
crate_disambiguator,
|
||||
original_crate_name,
|
||||
crate_hash,
|
||||
instance_def_size_estimate,
|
||||
issue33140_self_ty,
|
||||
impl_defaultness,
|
||||
|
Loading…
x
Reference in New Issue
Block a user