incr.comp.: Make the StableHashingContext mostly independent of the tcx.

This commit is contained in:
Michael Woerister 2017-09-14 14:01:40 +02:00
parent e567afbc58
commit ba6f93ca76
5 changed files with 61 additions and 39 deletions

View File

@ -9,11 +9,12 @@
// except according to those terms.
use hir;
use hir::def_id::DefId;
use hir::def_id::{DefId, DefIndex};
use hir::map::DefPathHash;
use ich::{self, CachingCodemapView};
use session::config::DebugInfoLevel::NoDebugInfo;
use ty::{self, TyCtxt, fast_reject};
use session::Session;
use std::cmp::Ord;
use std::hash as std_hash;
@ -42,6 +43,7 @@ thread_local!(static IGNORED_ATTR_NAMES: RefCell<FxHashSet<Symbol>> =
/// things (e.g. each DefId/DefPath is only hashed once).
pub struct StableHashingContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
body_resolver: BodyResolver<'gcx>,
hash_spans: bool,
hash_bodies: bool,
overflow_checks_enabled: bool,
@ -59,6 +61,20 @@ pub enum NodeIdHashingMode {
HashDefPath,
}
/// The BodyResolver allows to map a BodyId to the corresponding hir::Body.
/// We could also just store a plain reference to the hir::Crate but we want
/// to avoid that the crate is used to get untracked access to all of the HIR.
#[derive(Clone, Copy)]
struct BodyResolver<'hir>(&'hir hir::Crate);
impl<'hir> BodyResolver<'hir> {
// Return a reference to the hir::Body with the given BodyId.
// DOES NOT DO ANY TRACKING, use carefully.
fn body(self, id: hir::BodyId) -> &'hir hir::Body {
self.0.body(id)
}
}
impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self {
@ -74,8 +90,11 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> {
}
});
let body_resolver = BodyResolver(tcx.dep_graph.with_ignore(|| tcx.hir.krate()));
StableHashingContext {
tcx,
body_resolver,
caching_codemap: None,
raw_codemap: tcx.sess.codemap(),
hash_spans: hash_spans_initial,
@ -85,6 +104,11 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> {
}
}
#[inline]
pub fn sess(&self) -> &'gcx Session {
self.tcx.sess
}
pub fn force_span_hashing(mut self) -> Self {
self.hash_spans = true;
self
@ -121,13 +145,13 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> {
}
#[inline]
pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
self.tcx
pub fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
self.tcx.def_path_hash(def_id)
}
#[inline]
pub fn def_path_hash(&mut self, def_id: DefId) -> DefPathHash {
self.tcx.def_path_hash(def_id)
pub fn local_def_path_hash(&self, def_index: DefIndex) -> DefPathHash {
self.tcx.hir.definitions().def_path_hash(def_index)
}
#[inline]
@ -221,6 +245,16 @@ impl<'a, 'gcx, 'lcx> StableHashingContextProvider for ty::TyCtxt<'a, 'gcx, 'lcx>
}
}
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>) {
if hcx.hash_bodies() {
hcx.body_resolver.body(*self).hash_stable(hcx, hasher);
}
}
}
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
@ -250,7 +284,7 @@ impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for h
fn to_stable_hash_key(&self,
hcx: &StableHashingContext<'a, 'gcx, 'tcx>)
-> (DefPathHash, hir::ItemLocalId) {
let def_path_hash = hcx.tcx().hir.definitions().def_path_hash(self.owner);
let def_path_hash = hcx.local_def_path_hash(self.owner);
(def_path_hash, self.local_id)
}
}
@ -378,10 +412,9 @@ pub fn hash_stable_trait_impls<'a, 'tcx, 'gcx, W, R>(
}
{
let tcx = hcx.tcx();
let mut keys: AccumulateVec<[_; 8]> =
non_blanket_impls.keys()
.map(|k| (k, k.map_def(|d| tcx.def_path_hash(d))))
.map(|k| (k, k.map_def(|d| hcx.def_path_hash(d))))
.collect();
keys.sort_unstable_by(|&(_, ref k1), &(_, ref k2)| k1.cmp(k2));
keys.len().hash_stable(hcx, hasher);

View File

@ -34,7 +34,7 @@ impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for D
#[inline]
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash {
hcx.tcx().def_path_hash(*self)
hcx.def_path_hash(*self)
}
}
@ -995,16 +995,6 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B
}
}
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>) {
if hcx.hash_bodies() {
hcx.tcx().hir.body(*self).hash_stable(hcx, hasher);
}
}
}
impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId {
type KeyType = (DefPathHash, hir::ItemLocalId);
@ -1119,7 +1109,7 @@ for hir::def_id::DefIndex {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>) {
hcx.tcx().hir.definitions().def_path_hash(*self).hash_stable(hcx, hasher);
hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
}
}
@ -1129,7 +1119,7 @@ for hir::def_id::DefIndex {
#[inline]
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash {
hcx.tcx().hir.definitions().def_path_hash(*self)
hcx.local_def_path_hash(*self)
}
}

View File

@ -324,11 +324,11 @@ fn hash_token<'a, 'gcx, 'tcx, W: StableHasherResult>(token: &token::Token,
// in a stable way, in addition to the HIR.
// Since this is hardly used anywhere, just emit a
// warning for now.
if hcx.tcx().sess.opts.debugging_opts.incremental.is_some() {
if hcx.sess().opts.debugging_opts.incremental.is_some() {
let msg = format!("Quasi-quoting might make incremental \
compilation very inefficient: {:?}",
non_terminal);
hcx.tcx().sess.span_warn(error_reporting_span, &msg[..]);
hcx.sess().span_warn(error_reporting_span, &msg[..]);
}
std_hash::Hash::hash(non_terminal, hasher);

View File

@ -736,9 +736,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Typeck
krate: local_id_root.krate,
index: closure_expr_id,
};
(hcx.tcx().def_path_hash(var_owner_def_id),
(hcx.def_path_hash(var_owner_def_id),
var_id.local_id,
hcx.tcx().def_path_hash(closure_def_id))
hcx.def_path_hash(closure_def_id))
});
closure_tys.hash_stable(hcx, hasher);

View File

@ -90,6 +90,7 @@ impl<'a> ::std::ops::Index<&'a DepNode> for IncrementalHashesMap {
}
struct ComputeItemHashesVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
hcx: StableHashingContext<'a, 'tcx, 'tcx>,
hashes: IncrementalHashesMap,
}
@ -101,14 +102,14 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
item_like: T)
where T: HashStable<StableHashingContext<'a, 'tcx, 'tcx>>
{
if !hash_bodies && !self.hcx.tcx().sess.opts.build_dep_graph() {
if !hash_bodies && !self.tcx.sess.opts.build_dep_graph() {
// If we just need the hashes in order to compute the SVH, we don't
// need have two hashes per item. Just the one containing also the
// item's body is sufficient.
return
}
let def_path_hash = self.hcx.tcx().hir.definitions().def_path_hash(def_index);
let def_path_hash = self.hcx.local_def_path_hash(def_index);
let mut hasher = IchHasher::new();
self.hcx.while_hashing_hir_bodies(hash_bodies, |hcx| {
@ -125,14 +126,12 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
debug!("calculate_def_hash: dep_node={:?} hash={:?}", dep_node, item_hash);
self.hashes.insert(dep_node, item_hash);
let tcx = self.hcx.tcx();
let bytes_hashed =
tcx.sess.perf_stats.incr_comp_bytes_hashed.get() +
bytes_hashed;
tcx.sess.perf_stats.incr_comp_bytes_hashed.set(bytes_hashed);
self.tcx.sess.perf_stats.incr_comp_bytes_hashed.get() + bytes_hashed;
self.tcx.sess.perf_stats.incr_comp_bytes_hashed.set(bytes_hashed);
if hash_bodies {
let in_scope_traits_map = tcx.in_scope_traits_map(def_index);
let in_scope_traits_map = self.tcx.in_scope_traits_map(def_index);
let mut hasher = IchHasher::new();
in_scope_traits_map.hash_stable(&mut self.hcx, &mut hasher);
let dep_node = def_path_hash.to_dep_node(DepKind::InScopeTraits);
@ -141,12 +140,11 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
}
fn compute_crate_hash(&mut self) {
let tcx = self.hcx.tcx();
let krate = tcx.hir.krate();
let krate = self.tcx.hir.krate();
let mut crate_state = IchHasher::new();
let crate_disambiguator = tcx.sess.local_crate_disambiguator();
let crate_disambiguator = self.tcx.sess.local_crate_disambiguator();
"crate_disambiguator".hash(&mut crate_state);
crate_disambiguator.as_str().len().hash(&mut crate_state);
crate_disambiguator.as_str().hash(&mut crate_state);
@ -221,7 +219,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
fn compute_and_store_ich_for_trait_impls(&mut self, krate: &'tcx hir::Crate)
{
let tcx = self.hcx.tcx();
let tcx = self.tcx;
let mut impls: Vec<(DefPathHash, Fingerprint)> = krate
.trait_impls
@ -266,7 +264,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item) {
let def_index = self.hcx.tcx().hir.local_def_id(item.id).index;
let def_index = self.tcx.hir.local_def_id(item.id).index;
self.compute_and_store_ich_for_item_like(def_index,
false,
item);
@ -276,7 +274,7 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx>
}
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
let def_index = self.hcx.tcx().hir.local_def_id(item.id).index;
let def_index = self.tcx.hir.local_def_id(item.id).index;
self.compute_and_store_ich_for_item_like(def_index,
false,
item);
@ -286,7 +284,7 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx>
}
fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) {
let def_index = self.hcx.tcx().hir.local_def_id(item.id).index;
let def_index = self.tcx.hir.local_def_id(item.id).index;
self.compute_and_store_ich_for_item_like(def_index,
false,
item);
@ -304,6 +302,7 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
let krate = tcx.hir.krate();
let mut visitor = ComputeItemHashesVisitor {
tcx,
hcx: StableHashingContext::new(tcx),
hashes: IncrementalHashesMap::new(),
};