Fix issues uncovered by rebasing:
- Don't hash traits in scope as part of HIR hashing any more. - Some queries returned DefIndexes from other crates. - Provide a generic way of stably hashing maps (not used everywhere yet).
This commit is contained in:
parent
3cc3ae22bd
commit
e3f913167c
@ -633,6 +633,18 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId,) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefIndex,) {
|
||||
const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
|
||||
|
||||
fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
|
||||
tcx.hir.definitions().def_path_hash(self.0).0
|
||||
}
|
||||
|
||||
fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
|
||||
tcx.item_path_str(DefId::local(self.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId, DefId) {
|
||||
const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
|
||||
|
||||
|
@ -27,7 +27,8 @@ use syntax::symbol::Symbol;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHashingContextProvider,
|
||||
StableHasher, StableHasherResult};
|
||||
StableHasher, StableHasherResult,
|
||||
ToStableHashKey};
|
||||
use rustc_data_structures::accumulate_vec::AccumulateVec;
|
||||
|
||||
/// This is the context state available during incr. comp. hashing. It contains
|
||||
@ -48,9 +49,7 @@ pub struct StableHashingContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum NodeIdHashingMode {
|
||||
Ignore,
|
||||
CheckedIgnore,
|
||||
HashDefPath,
|
||||
HashTraitsInScope,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> {
|
||||
@ -150,7 +149,7 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> {
|
||||
self.overflow_checks_enabled = true;
|
||||
}
|
||||
let prev_hash_node_ids = self.node_id_hashing_mode;
|
||||
self.node_id_hashing_mode = NodeIdHashingMode::CheckedIgnore;
|
||||
self.node_id_hashing_mode = NodeIdHashingMode::Ignore;
|
||||
|
||||
f(self);
|
||||
|
||||
@ -207,41 +206,28 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::N
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
let hir_id = hcx.tcx.hir.node_to_hir_id(*self);
|
||||
match hcx.node_id_hashing_mode {
|
||||
NodeIdHashingMode::Ignore => {
|
||||
// Don't do anything.
|
||||
}
|
||||
NodeIdHashingMode::CheckedIgnore => {
|
||||
// Most NodeIds in the HIR can be ignored, but if there is a
|
||||
// corresponding entry in the `trait_map` we need to hash that.
|
||||
// Make sure we don't ignore too much by checking that there is
|
||||
// no entry in a debug_assert!().
|
||||
debug_assert!(hcx.tcx.in_scope_traits(hir_id).is_none());
|
||||
}
|
||||
NodeIdHashingMode::HashDefPath => {
|
||||
hir_id.hash_stable(hcx, hasher);
|
||||
}
|
||||
NodeIdHashingMode::HashTraitsInScope => {
|
||||
if let Some(traits) = hcx.tcx.in_scope_traits(hir_id) {
|
||||
// The ordering of the candidates is not fixed. So we hash
|
||||
// the def-ids and then sort them and hash the collection.
|
||||
let mut candidates: AccumulateVec<[_; 8]> =
|
||||
traits.iter()
|
||||
.map(|&hir::TraitCandidate { def_id, import_id: _ }| {
|
||||
hcx.def_path_hash(def_id)
|
||||
})
|
||||
.collect();
|
||||
if traits.len() > 1 {
|
||||
candidates.sort();
|
||||
}
|
||||
candidates.hash_stable(hcx, hasher);
|
||||
}
|
||||
hcx.tcx.hir.node_to_hir_id(*self).hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for ast::NodeId {
|
||||
type KeyType = (DefPathHash, hir::ItemLocalId);
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self,
|
||||
hcx: &StableHashingContext<'a, 'gcx, 'tcx>)
|
||||
-> (DefPathHash, hir::ItemLocalId) {
|
||||
hcx.tcx.hir.node_to_hir_id(*self).to_stable_hash_key(hcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Span {
|
||||
|
||||
// Hash a span in a stable way. We can't directly hash the span's BytePos
|
||||
|
@ -45,3 +45,9 @@ impl_stable_hash_for!(struct middle::cstore::ExternCrate {
|
||||
direct,
|
||||
path_len
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct middle::cstore::CrateSource {
|
||||
dylib,
|
||||
rlib,
|
||||
rmeta
|
||||
});
|
||||
|
@ -12,13 +12,13 @@
|
||||
//! types in no particular order.
|
||||
|
||||
use hir;
|
||||
use hir::map::DefPathHash;
|
||||
use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
|
||||
use ich::{self, StableHashingContext, NodeIdHashingMode};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
|
||||
StableHasherResult};
|
||||
use ich::{StableHashingContext, NodeIdHashingMode};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
|
||||
StableHasher, StableHasherResult};
|
||||
use std::mem;
|
||||
use syntax::ast;
|
||||
use util::nodemap::DefIdSet;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for DefId {
|
||||
#[inline]
|
||||
@ -29,14 +29,12 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for DefId
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for DefIdSet
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
ich::hash_stable_hashset(hcx, hasher, self, |hcx, def_id| {
|
||||
hcx.def_path_hash(*def_id)
|
||||
});
|
||||
impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for DefId {
|
||||
type KeyType = DefPathHash;
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash {
|
||||
hcx.tcx().def_path_hash(*self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,11 +48,22 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::H
|
||||
local_id,
|
||||
} = *self;
|
||||
|
||||
hcx.def_path_hash(DefId::local(owner)).hash_stable(hcx, hasher);
|
||||
hcx.tcx().hir.definitions().def_path_hash(owner).hash_stable(hcx, hasher);
|
||||
local_id.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId {
|
||||
type KeyType = (DefPathHash, hir::ItemLocalId);
|
||||
|
||||
#[inline]
|
||||
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);
|
||||
(def_path_hash, self.local_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for CrateNum {
|
||||
#[inline]
|
||||
@ -68,8 +77,30 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for CrateN
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for CrateNum {
|
||||
type KeyType = DefPathHash;
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash {
|
||||
let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
|
||||
def_id.to_stable_hash_key(hcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(tuple_struct hir::ItemLocalId { index });
|
||||
|
||||
impl<'a, 'gcx, 'lcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'lcx>>
|
||||
for hir::ItemLocalId {
|
||||
type KeyType = hir::ItemLocalId;
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self,
|
||||
_: &StableHashingContext<'a, 'gcx, 'lcx>)
|
||||
-> hir::ItemLocalId {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
// The following implementations of HashStable for ItemId, TraitItemId, and
|
||||
// ImplItemId deserve special attention. Normally we do not hash NodeIds within
|
||||
// the HIR, since they just signify a HIR nodes own path. But ItemId et al
|
||||
@ -231,36 +262,13 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::T
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
let node_id_hashing_mode = match self.node {
|
||||
hir::TySlice(..) |
|
||||
hir::TyArray(..) |
|
||||
hir::TyPtr(..) |
|
||||
hir::TyRptr(..) |
|
||||
hir::TyBareFn(..) |
|
||||
hir::TyNever |
|
||||
hir::TyTup(..) |
|
||||
hir::TyTraitObject(..) |
|
||||
hir::TyImplTrait(..) |
|
||||
hir::TyTypeof(..) |
|
||||
hir::TyErr |
|
||||
hir::TyInfer => {
|
||||
NodeIdHashingMode::CheckedIgnore
|
||||
}
|
||||
hir::TyPath(..) => {
|
||||
NodeIdHashingMode::HashTraitsInScope
|
||||
}
|
||||
};
|
||||
|
||||
hcx.while_hashing_hir_bodies(true, |hcx| {
|
||||
let hir::Ty {
|
||||
id,
|
||||
id: _,
|
||||
ref node,
|
||||
ref span,
|
||||
} = *self;
|
||||
|
||||
hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
|
||||
id.hash_stable(hcx, hasher);
|
||||
});
|
||||
node.hash_stable(hcx, hasher);
|
||||
span.hash_stable(hcx, hasher);
|
||||
})
|
||||
@ -317,13 +325,11 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::T
|
||||
hasher: &mut StableHasher<W>) {
|
||||
let hir::TraitRef {
|
||||
ref path,
|
||||
ref_id,
|
||||
// Don't hash the ref_id. It is tracked via the thing it is used to access
|
||||
ref_id: _,
|
||||
} = *self;
|
||||
|
||||
path.hash_stable(hcx, hasher);
|
||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashTraitsInScope, |hcx| {
|
||||
ref_id.hash_stable(hcx, hasher);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -357,7 +363,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B
|
||||
let hir::Block {
|
||||
ref stmts,
|
||||
ref expr,
|
||||
id,
|
||||
id: _,
|
||||
hir_id: _,
|
||||
rules,
|
||||
span,
|
||||
@ -392,7 +398,6 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B
|
||||
}
|
||||
|
||||
expr.hash_stable(hcx, hasher);
|
||||
id.hash_stable(hcx, hasher);
|
||||
rules.hash_stable(hcx, hasher);
|
||||
span.hash_stable(hcx, hasher);
|
||||
targeted_by_break.hash_stable(hcx, hasher);
|
||||
@ -403,34 +408,13 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::P
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
let node_id_hashing_mode = match self.node {
|
||||
hir::PatKind::Wild |
|
||||
hir::PatKind::Binding(..) |
|
||||
hir::PatKind::Tuple(..) |
|
||||
hir::PatKind::Box(..) |
|
||||
hir::PatKind::Ref(..) |
|
||||
hir::PatKind::Lit(..) |
|
||||
hir::PatKind::Range(..) |
|
||||
hir::PatKind::Slice(..) => {
|
||||
NodeIdHashingMode::CheckedIgnore
|
||||
}
|
||||
hir::PatKind::Path(..) |
|
||||
hir::PatKind::Struct(..) |
|
||||
hir::PatKind::TupleStruct(..) => {
|
||||
NodeIdHashingMode::HashTraitsInScope
|
||||
}
|
||||
};
|
||||
|
||||
let hir::Pat {
|
||||
id,
|
||||
id: _,
|
||||
hir_id: _,
|
||||
ref node,
|
||||
ref span
|
||||
} = *self;
|
||||
|
||||
hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
|
||||
id.hash_stable(hcx, hasher);
|
||||
});
|
||||
node.hash_stable(hcx, hasher);
|
||||
span.hash_stable(hcx, hasher);
|
||||
}
|
||||
@ -552,14 +536,14 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::E
|
||||
hasher: &mut StableHasher<W>) {
|
||||
hcx.while_hashing_hir_bodies(true, |hcx| {
|
||||
let hir::Expr {
|
||||
id,
|
||||
id: _,
|
||||
hir_id: _,
|
||||
ref span,
|
||||
ref node,
|
||||
ref attrs
|
||||
} = *self;
|
||||
|
||||
let (spans_always_on, node_id_hashing_mode) = match *node {
|
||||
let spans_always_on = match *node {
|
||||
hir::ExprBox(..) |
|
||||
hir::ExprArray(..) |
|
||||
hir::ExprCall(..) |
|
||||
@ -578,41 +562,33 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::E
|
||||
hir::ExprBreak(..) |
|
||||
hir::ExprAgain(..) |
|
||||
hir::ExprRet(..) |
|
||||
hir::ExprYield(..) |
|
||||
hir::ExprYield(..) |
|
||||
hir::ExprInlineAsm(..) |
|
||||
hir::ExprRepeat(..) |
|
||||
hir::ExprTup(..) => {
|
||||
// For these we only hash the span when debuginfo is on.
|
||||
(false, NodeIdHashingMode::CheckedIgnore)
|
||||
}
|
||||
// For the following, spans might be significant because of
|
||||
// panic messages indicating the source location.
|
||||
hir::ExprBinary(op, ..) => {
|
||||
(hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::CheckedIgnore)
|
||||
}
|
||||
hir::ExprUnary(op, _) => {
|
||||
(hcx.unop_can_panic_at_runtime(op), NodeIdHashingMode::CheckedIgnore)
|
||||
}
|
||||
hir::ExprAssignOp(op, ..) => {
|
||||
(hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::CheckedIgnore)
|
||||
}
|
||||
hir::ExprIndex(..) => {
|
||||
(true, NodeIdHashingMode::CheckedIgnore)
|
||||
}
|
||||
// For these we don't care about the span, but want to hash the
|
||||
// trait in scope
|
||||
hir::ExprTup(..) |
|
||||
hir::ExprMethodCall(..) |
|
||||
hir::ExprPath(..) |
|
||||
hir::ExprStruct(..) |
|
||||
hir::ExprField(..) => {
|
||||
(false, NodeIdHashingMode::HashTraitsInScope)
|
||||
// For these we only hash the span when debuginfo is on.
|
||||
false
|
||||
}
|
||||
// For the following, spans might be significant because of
|
||||
// panic messages indicating the source location.
|
||||
hir::ExprBinary(op, ..) => {
|
||||
hcx.binop_can_panic_at_runtime(op.node)
|
||||
}
|
||||
hir::ExprUnary(op, _) => {
|
||||
hcx.unop_can_panic_at_runtime(op)
|
||||
}
|
||||
hir::ExprAssignOp(op, ..) => {
|
||||
hcx.binop_can_panic_at_runtime(op.node)
|
||||
}
|
||||
hir::ExprIndex(..) => {
|
||||
true
|
||||
}
|
||||
};
|
||||
|
||||
hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
|
||||
id.hash_stable(hcx, hasher);
|
||||
});
|
||||
|
||||
if spans_always_on {
|
||||
hcx.while_hashing_spans(true, |hcx| {
|
||||
span.hash_stable(hcx, hasher);
|
||||
@ -815,7 +791,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::V
|
||||
// No fields to hash.
|
||||
}
|
||||
hir::Visibility::Restricted { ref path, id } => {
|
||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashTraitsInScope, |hcx| {
|
||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
|
||||
id.hash_stable(hcx, hasher);
|
||||
});
|
||||
path.hash_stable(hcx, hasher);
|
||||
@ -904,16 +880,13 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::I
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
let (node_id_hashing_mode, hash_spans) = match self.node {
|
||||
let hash_spans = match self.node {
|
||||
hir::ItemStatic(..) |
|
||||
hir::ItemConst(..) |
|
||||
hir::ItemFn(..) => {
|
||||
(NodeIdHashingMode::CheckedIgnore, hcx.hash_spans())
|
||||
hcx.hash_spans()
|
||||
}
|
||||
hir::ItemUse(..) => {
|
||||
(NodeIdHashingMode::HashTraitsInScope, false)
|
||||
}
|
||||
|
||||
hir::ItemUse(..) |
|
||||
hir::ItemExternCrate(..) |
|
||||
hir::ItemForeignMod(..) |
|
||||
hir::ItemGlobalAsm(..) |
|
||||
@ -925,14 +898,14 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::I
|
||||
hir::ItemEnum(..) |
|
||||
hir::ItemStruct(..) |
|
||||
hir::ItemUnion(..) => {
|
||||
(NodeIdHashingMode::CheckedIgnore, false)
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
let hir::Item {
|
||||
name,
|
||||
ref attrs,
|
||||
id,
|
||||
id: _,
|
||||
hir_id: _,
|
||||
ref node,
|
||||
ref vis,
|
||||
@ -941,9 +914,6 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::I
|
||||
|
||||
hcx.hash_hir_item_like(attrs, |hcx| {
|
||||
hcx.while_hashing_spans(hash_spans, |hcx| {
|
||||
hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
|
||||
id.hash_stable(hcx, hasher);
|
||||
});
|
||||
name.hash_stable(hcx, hasher);
|
||||
attrs.hash_stable(hcx, hasher);
|
||||
node.hash_stable(hcx, hasher);
|
||||
@ -1049,6 +1019,18 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId {
|
||||
type KeyType = (DefPathHash, hir::ItemLocalId);
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self,
|
||||
hcx: &StableHashingContext<'a, 'gcx, 'tcx>)
|
||||
-> (DefPathHash, hir::ItemLocalId) {
|
||||
let hir::BodyId { node_id } = *self;
|
||||
node_id.to_stable_hash_key(hcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct hir::InlineAsmOutput {
|
||||
constraint,
|
||||
is_rw,
|
||||
@ -1151,7 +1133,17 @@ for hir::def_id::DefIndex {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
DefId::local(*self).hash_stable(hcx, hasher);
|
||||
hcx.tcx().hir.definitions().def_path_hash(*self).hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for hir::def_id::DefIndex {
|
||||
type KeyType = DefPathHash;
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash {
|
||||
hcx.tcx().hir.definitions().def_path_hash(*self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1170,6 +1162,11 @@ for ::middle::lang_items::LangItem {
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
|
||||
items,
|
||||
missing
|
||||
});
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for hir::TraitCandidate {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
@ -1186,3 +1183,8 @@ for hir::TraitCandidate {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct hir::Freevar {
|
||||
def,
|
||||
span
|
||||
});
|
||||
|
26
src/librustc/ich/impls_misc.rs
Normal file
26
src/librustc/ich/impls_misc.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! This module contains `HashStable` implementations for various data types
|
||||
//! that don't fit into any of the other impls_xxx modules.
|
||||
|
||||
impl_stable_hash_for!(enum ::session::search_paths::PathKind {
|
||||
Native,
|
||||
Crate,
|
||||
Dependency,
|
||||
Framework,
|
||||
ExternFlag,
|
||||
All
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(enum ::rustc_back::PanicStrategy {
|
||||
Abort,
|
||||
Unwind
|
||||
});
|
@ -18,17 +18,17 @@ use std::mem;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::parse::token;
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax::tokenstream;
|
||||
use syntax_pos::{Span, FileMap};
|
||||
|
||||
use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
|
||||
StableHasherResult};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
|
||||
StableHasher, StableHasherResult};
|
||||
use rustc_data_structures::accumulate_vec::AccumulateVec;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for ::syntax::symbol::InternedString {
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for InternedString {
|
||||
#[inline]
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
@ -38,6 +38,17 @@ for ::syntax::symbol::InternedString {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for InternedString {
|
||||
type KeyType = InternedString;
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self,
|
||||
_: &StableHashingContext<'a, 'gcx, 'tcx>)
|
||||
-> InternedString {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::Name {
|
||||
#[inline]
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
@ -47,6 +58,17 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::N
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for ast::Name {
|
||||
type KeyType = InternedString;
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self,
|
||||
_: &StableHashingContext<'a, 'gcx, 'tcx>)
|
||||
-> InternedString {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(enum ::syntax::ast::AsmDialect {
|
||||
Att,
|
||||
Intel
|
||||
|
@ -24,6 +24,7 @@ mod impls_const_math;
|
||||
mod impls_cstore;
|
||||
mod impls_hir;
|
||||
mod impls_mir;
|
||||
mod impls_misc;
|
||||
mod impls_ty;
|
||||
mod impls_syntax;
|
||||
|
||||
|
@ -132,7 +132,7 @@ pub struct NativeLibrary {
|
||||
pub kind: NativeLibraryKind,
|
||||
pub name: Symbol,
|
||||
pub cfg: Option<ast::MetaItem>,
|
||||
pub foreign_items: Vec<DefIndex>,
|
||||
pub foreign_items: Vec<DefId>,
|
||||
}
|
||||
|
||||
pub enum LoadedMacro {
|
||||
|
@ -192,8 +192,7 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
|
||||
pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems {
|
||||
let mut collector = LanguageItemCollector::new(tcx);
|
||||
for &cnum in tcx.crates().iter() {
|
||||
for &(index, item_index) in tcx.defined_lang_items(cnum).iter() {
|
||||
let def_id = DefId { krate: cnum, index: index };
|
||||
for &(def_id, item_index) in tcx.defined_lang_items(cnum).iter() {
|
||||
collector.collect_item(item_index, def_id);
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,11 @@ pub struct DeprecationEntry {
|
||||
origin: Option<HirId>,
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct self::DeprecationEntry {
|
||||
attr,
|
||||
origin
|
||||
});
|
||||
|
||||
impl DeprecationEntry {
|
||||
fn local(attr: Deprecation, id: HirId) -> DeprecationEntry {
|
||||
DeprecationEntry {
|
||||
@ -102,6 +107,13 @@ pub struct Index<'tcx> {
|
||||
active_features: FxHashSet<Symbol>,
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct self::Index<'tcx> {
|
||||
stab_map,
|
||||
depr_map,
|
||||
staged_api,
|
||||
active_features
|
||||
});
|
||||
|
||||
// A private tree-walker for producing an Index.
|
||||
struct Annotator<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
@ -1083,6 +1083,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
None
|
||||
};
|
||||
|
||||
// FIXME(mw): Each of the Vecs in the trait_map should be brought into
|
||||
// a deterministic order here. Otherwise we might end up with
|
||||
// unnecessarily unstable incr. comp. hashes.
|
||||
let mut trait_map = FxHashMap();
|
||||
for (k, v) in resolutions.trait_map {
|
||||
let hir_id = hir.node_to_hir_id(k);
|
||||
@ -1171,17 +1174,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn lang_items(self) -> Rc<middle::lang_items::LanguageItems> {
|
||||
// FIXME(#42293) Right now we insert a `with_ignore` node in the dep
|
||||
// graph here to ignore the fact that `get_lang_items` below depends on
|
||||
// the entire crate. For now this'll prevent false positives of
|
||||
// recompiling too much when anything changes.
|
||||
//
|
||||
// Once red/green incremental compilation lands we should be able to
|
||||
// remove this because while the crate changes often the lint level map
|
||||
// will change rarely.
|
||||
self.dep_graph.with_ignore(|| {
|
||||
self.get_lang_items(LOCAL_CRATE)
|
||||
})
|
||||
self.get_lang_items(LOCAL_CRATE)
|
||||
}
|
||||
|
||||
pub fn stability(self) -> Rc<stability::Index<'tcx>> {
|
||||
@ -2198,7 +2191,15 @@ pub fn provide(providers: &mut ty::maps::Providers) {
|
||||
};
|
||||
providers.get_lang_items = |tcx, id| {
|
||||
assert_eq!(id, LOCAL_CRATE);
|
||||
Rc::new(middle::lang_items::collect(tcx))
|
||||
// FIXME(#42293) Right now we insert a `with_ignore` node in the dep
|
||||
// graph here to ignore the fact that `get_lang_items` below depends on
|
||||
// the entire crate. For now this'll prevent false positives of
|
||||
// recompiling too much when anything changes.
|
||||
//
|
||||
// Once red/green incremental compilation lands we should be able to
|
||||
// remove this because while the crate changes often the lint level map
|
||||
// will change rarely.
|
||||
tcx.dep_graph.with_ignore(|| Rc::new(middle::lang_items::collect(tcx)))
|
||||
};
|
||||
providers.freevars = |tcx, id| tcx.gcx.freevars.get(&id).cloned();
|
||||
providers.maybe_unused_trait_import = |tcx, id| {
|
||||
|
@ -1400,7 +1400,7 @@ define_maps! { <'tcx>
|
||||
[] fn extern_mod_stmt_cnum: ExternModStmtCnum(DefId) -> Option<CrateNum>,
|
||||
|
||||
[] fn get_lang_items: get_lang_items_node(CrateNum) -> Rc<LanguageItems>,
|
||||
[] fn defined_lang_items: DefinedLangItems(CrateNum) -> Rc<Vec<(DefIndex, usize)>>,
|
||||
[] fn defined_lang_items: DefinedLangItems(CrateNum) -> Rc<Vec<(DefId, usize)>>,
|
||||
[] fn missing_lang_items: MissingLangItems(CrateNum) -> Rc<Vec<LangItem>>,
|
||||
[] fn extern_const_body: ExternConstBody(DefId) -> &'tcx hir::Body,
|
||||
[] fn visible_parent_map: visible_parent_map_node(CrateNum)
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::hash::{Hash, Hasher, BuildHasher};
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use blake2b::Blake2bHasher;
|
||||
@ -222,6 +222,14 @@ pub trait HashStable<CTX> {
|
||||
hasher: &mut StableHasher<W>);
|
||||
}
|
||||
|
||||
/// Implement this for types that can be turned into stable keys like, for
|
||||
/// example, for DefId that can be converted to a DefPathHash. This is used for
|
||||
/// bringing maps into a predictable order before hashing them.
|
||||
pub trait ToStableHashKey<HCX> {
|
||||
type KeyType: Ord + Clone + Sized + HashStable<HCX>;
|
||||
fn to_stable_hash_key(&self, hcx: &HCX) -> Self::KeyType;
|
||||
}
|
||||
|
||||
// Implement HashStable by just calling `Hash::hash()`. This works fine for
|
||||
// self-contained values that don't depend on the hashing context `CTX`.
|
||||
macro_rules! impl_stable_hash_via_hash {
|
||||
@ -423,34 +431,6 @@ impl<T, CTX> HashStable<CTX> for ::std::mem::Discriminant<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, CTX> HashStable<CTX> for ::std::collections::BTreeMap<K, V>
|
||||
where K: Ord + HashStable<CTX>,
|
||||
V: HashStable<CTX>,
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
ctx: &mut CTX,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
self.len().hash_stable(ctx, hasher);
|
||||
for (k, v) in self {
|
||||
k.hash_stable(ctx, hasher);
|
||||
v.hash_stable(ctx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, CTX> HashStable<CTX> for ::std::collections::BTreeSet<T>
|
||||
where T: Ord + HashStable<CTX>,
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
ctx: &mut CTX,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
self.len().hash_stable(ctx, hasher);
|
||||
for v in self {
|
||||
v.hash_stable(ctx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: ::indexed_vec::Idx, T, CTX> HashStable<CTX> for ::indexed_vec::IndexVec<I, T>
|
||||
where T: HashStable<CTX>,
|
||||
{
|
||||
@ -473,3 +453,66 @@ impl<I: ::indexed_vec::Idx, CTX> HashStable<CTX> for ::indexed_set::IdxSetBuf<I>
|
||||
self.words().hash_stable(ctx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_via_hash!(::std::path::Path);
|
||||
impl_stable_hash_via_hash!(::std::path::PathBuf);
|
||||
|
||||
impl<K, V, R, HCX> HashStable<HCX> for ::std::collections::HashMap<K, V, R>
|
||||
where K: ToStableHashKey<HCX> + Eq + Hash,
|
||||
V: HashStable<HCX>,
|
||||
R: BuildHasher,
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut HCX,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
let mut entries: Vec<_> = self.iter()
|
||||
.map(|(k, v)| (k.to_stable_hash_key(hcx), v))
|
||||
.collect();
|
||||
entries.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2));
|
||||
entries.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, R, HCX> HashStable<HCX> for ::std::collections::HashSet<K, R>
|
||||
where K: ToStableHashKey<HCX> + Eq + Hash,
|
||||
R: BuildHasher,
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut HCX,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
let mut keys: Vec<_> = self.iter()
|
||||
.map(|k| k.to_stable_hash_key(hcx))
|
||||
.collect();
|
||||
keys.sort_unstable();
|
||||
keys.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, HCX> HashStable<HCX> for ::std::collections::BTreeMap<K, V>
|
||||
where K: ToStableHashKey<HCX>,
|
||||
V: HashStable<HCX>,
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut HCX,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
let mut entries: Vec<_> = self.iter()
|
||||
.map(|(k, v)| (k.to_stable_hash_key(hcx), v))
|
||||
.collect();
|
||||
entries.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2));
|
||||
entries.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, HCX> HashStable<HCX> for ::std::collections::BTreeSet<K>
|
||||
where K: ToStableHashKey<HCX>,
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut HCX,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
let mut keys: Vec<_> = self.iter()
|
||||
.map(|k| k.to_stable_hash_key(hcx))
|
||||
.collect();
|
||||
keys.sort_unstable();
|
||||
keys.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ use std::cell::RefCell;
|
||||
use std::hash::Hash;
|
||||
use rustc::dep_graph::{DepNode, DepKind};
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
|
||||
use rustc::hir::map::DefPathHash;
|
||||
use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc::ich::{Fingerprint, StableHashingContext};
|
||||
@ -96,7 +96,7 @@ struct ComputeItemHashesVisitor<'a, 'tcx: 'a> {
|
||||
|
||||
impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
|
||||
fn compute_and_store_ich_for_item_like<T>(&mut self,
|
||||
dep_node: DepNode,
|
||||
def_index: DefIndex,
|
||||
hash_bodies: bool,
|
||||
item_like: T)
|
||||
where T: HashStable<StableHashingContext<'a, 'tcx, 'tcx>>
|
||||
@ -108,6 +108,8 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
|
||||
return
|
||||
}
|
||||
|
||||
let def_path_hash = self.hcx.tcx().hir.definitions().def_path_hash(def_index);
|
||||
|
||||
let mut hasher = IchHasher::new();
|
||||
self.hcx.while_hashing_hir_bodies(hash_bodies, |hcx| {
|
||||
item_like.hash_stable(hcx, &mut hasher);
|
||||
@ -115,6 +117,11 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
|
||||
|
||||
let bytes_hashed = hasher.bytes_hashed();
|
||||
let item_hash = hasher.finish();
|
||||
let dep_node = if hash_bodies {
|
||||
def_path_hash.to_dep_node(DepKind::HirBody)
|
||||
} else {
|
||||
def_path_hash.to_dep_node(DepKind::Hir)
|
||||
};
|
||||
debug!("calculate_def_hash: dep_node={:?} hash={:?}", dep_node, item_hash);
|
||||
self.hashes.insert(dep_node, item_hash);
|
||||
|
||||
@ -123,6 +130,14 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
|
||||
tcx.sess.perf_stats.incr_comp_bytes_hashed.get() +
|
||||
bytes_hashed;
|
||||
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 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);
|
||||
self.hashes.insert(dep_node, hasher.finish());
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_crate_hash(&mut self) {
|
||||
@ -145,6 +160,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
|
||||
// This `match` determines what kinds of nodes
|
||||
// go into the SVH:
|
||||
match item_dep_node.kind {
|
||||
DepKind::InScopeTraits |
|
||||
DepKind::Hir |
|
||||
DepKind::HirBody => {
|
||||
// We want to incoporate these into the
|
||||
@ -195,11 +211,10 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
|
||||
body_ids: _,
|
||||
} = *krate;
|
||||
|
||||
let def_path_hash = self.hcx.tcx().hir.definitions().def_path_hash(CRATE_DEF_INDEX);
|
||||
self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::Hir),
|
||||
self.compute_and_store_ich_for_item_like(CRATE_DEF_INDEX,
|
||||
false,
|
||||
(module, (span, attrs)));
|
||||
self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::HirBody),
|
||||
self.compute_and_store_ich_for_item_like(CRATE_DEF_INDEX,
|
||||
true,
|
||||
(module, (span, attrs)));
|
||||
}
|
||||
@ -251,34 +266,31 @@ 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_id = self.hcx.tcx().hir.local_def_id(item.id);
|
||||
let def_path_hash = self.hcx.tcx().def_path_hash(def_id);
|
||||
self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::Hir),
|
||||
let def_index = self.hcx.tcx().hir.local_def_id(item.id).index;
|
||||
self.compute_and_store_ich_for_item_like(def_index,
|
||||
false,
|
||||
item);
|
||||
self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::HirBody),
|
||||
self.compute_and_store_ich_for_item_like(def_index,
|
||||
true,
|
||||
item);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
|
||||
let def_id = self.hcx.tcx().hir.local_def_id(item.id);
|
||||
let def_path_hash = self.hcx.tcx().def_path_hash(def_id);
|
||||
self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::Hir),
|
||||
let def_index = self.hcx.tcx().hir.local_def_id(item.id).index;
|
||||
self.compute_and_store_ich_for_item_like(def_index,
|
||||
false,
|
||||
item);
|
||||
self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::HirBody),
|
||||
self.compute_and_store_ich_for_item_like(def_index,
|
||||
true,
|
||||
item);
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) {
|
||||
let def_id = self.hcx.tcx().hir.local_def_id(item.id);
|
||||
let def_path_hash = self.hcx.tcx().def_path_hash(def_id);
|
||||
self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::Hir),
|
||||
let def_index = self.hcx.tcx().hir.local_def_id(item.id).index;
|
||||
self.compute_and_store_ich_for_item_like(def_index,
|
||||
false,
|
||||
item);
|
||||
self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::HirBody),
|
||||
self.compute_and_store_ich_for_item_like(def_index,
|
||||
true,
|
||||
item);
|
||||
}
|
||||
@ -301,12 +313,11 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
krate.visit_all_item_likes(&mut visitor);
|
||||
|
||||
for macro_def in krate.exported_macros.iter() {
|
||||
let def_id = tcx.hir.local_def_id(macro_def.id);
|
||||
let def_path_hash = tcx.def_path_hash(def_id);
|
||||
visitor.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::Hir),
|
||||
let def_index = tcx.hir.local_def_id(macro_def.id).index;
|
||||
visitor.compute_and_store_ich_for_item_like(def_index,
|
||||
false,
|
||||
macro_def);
|
||||
visitor.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::HirBody),
|
||||
visitor.compute_and_store_ich_for_item_like(def_index,
|
||||
true,
|
||||
macro_def);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
|
||||
match dep_node.kind {
|
||||
DepKind::Krate |
|
||||
DepKind::Hir |
|
||||
DepKind::InScopeTraits |
|
||||
DepKind::HirBody =>
|
||||
true,
|
||||
DepKind::MetaData => {
|
||||
@ -66,6 +67,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// HIR nodes (which always come from our crate) are an input:
|
||||
DepKind::InScopeTraits |
|
||||
DepKind::Hir |
|
||||
DepKind::HirBody => {
|
||||
Some(self.incremental_hashes_map[dep_node])
|
||||
|
@ -104,6 +104,7 @@ fn does_still_exist(tcx: TyCtxt, dep_node: &DepNode) -> bool {
|
||||
match dep_node.kind {
|
||||
DepKind::Hir |
|
||||
DepKind::HirBody |
|
||||
DepKind::InScopeTraits |
|
||||
DepKind::MetaData => {
|
||||
dep_node.extract_def_id(tcx).is_some()
|
||||
}
|
||||
|
@ -301,7 +301,10 @@ impl<'a> CrateLoader<'a> {
|
||||
.decode(&cmeta)
|
||||
.filter(|lib| relevant_lib(self.sess, lib) &&
|
||||
lib.kind == cstore::NativeLibraryKind::NativeUnknown)
|
||||
.flat_map(|lib| lib.foreign_items.into_iter())
|
||||
.flat_map(|lib| {
|
||||
assert!(lib.foreign_items.iter().all(|def_id| def_id.krate == cnum));
|
||||
lib.foreign_items.into_iter().map(|def_id| def_id.index)
|
||||
})
|
||||
.collect();
|
||||
|
||||
cmeta.dllimport_foreign_items = dllimports;
|
||||
|
@ -264,7 +264,7 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
|
||||
tcx.native_libraries(id.krate)
|
||||
.iter()
|
||||
.filter(|lib| native_libs::relevant_lib(&tcx.sess, lib))
|
||||
.find(|l| l.foreign_items.contains(&id.index))
|
||||
.find(|l| l.foreign_items.contains(&id))
|
||||
.map(|l| l.kind)
|
||||
},
|
||||
native_libraries: |tcx, cnum| {
|
||||
|
@ -659,10 +659,11 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
}
|
||||
|
||||
/// Iterates over the language items in the given crate.
|
||||
pub fn get_lang_items(&self) -> Vec<(DefIndex, usize)> {
|
||||
pub fn get_lang_items(&self) -> Vec<(DefId, usize)> {
|
||||
self.root
|
||||
.lang_items
|
||||
.decode(self)
|
||||
.map(|(def_index, index)| (self.local_def_id(def_index), index))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> {
|
||||
list[0].meta_item().unwrap().clone()
|
||||
});
|
||||
let foreign_items = fm.items.iter()
|
||||
.map(|it| self.tcx.hir.local_def_id(it.id).index)
|
||||
.map(|it| self.tcx.hir.local_def_id(it.id))
|
||||
.collect();
|
||||
let lib = NativeLibrary {
|
||||
name: n,
|
||||
|
@ -15,8 +15,7 @@
|
||||
//! "types-as-contracts"-validation, namely, AcquireValid, ReleaseValid, and EndRegion.
|
||||
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, Ty, TyCtxt, ClosureSubsts};
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::{MutVisitor, Lookup};
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
@ -80,45 +79,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
|
||||
self.super_statement(block, statement, location);
|
||||
self.in_validation_statement = false;
|
||||
}
|
||||
|
||||
fn visit_const_val(&mut self,
|
||||
const_val: &mut ConstVal<'tcx>,
|
||||
_: Location) {
|
||||
erase_const_val(self.tcx, const_val);
|
||||
self.super_const_val(const_val);
|
||||
|
||||
fn erase_const_val<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
const_val: &mut ConstVal<'tcx>) {
|
||||
match *const_val {
|
||||
ConstVal::Float(_) |
|
||||
ConstVal::Integral(_) |
|
||||
ConstVal::Str(_) |
|
||||
ConstVal::ByteStr(_) |
|
||||
ConstVal::Bool(_) |
|
||||
ConstVal::Char(_) |
|
||||
ConstVal::Variant(_) => {
|
||||
// nothing to do
|
||||
}
|
||||
ConstVal::Function(_, ref mut substs) => {
|
||||
*substs = tcx.erase_regions(&{*substs});
|
||||
}
|
||||
ConstVal::Struct(ref mut field_map) => {
|
||||
for (_, field_val) in field_map {
|
||||
erase_const_val(tcx, field_val);
|
||||
}
|
||||
}
|
||||
ConstVal::Tuple(ref mut fields) |
|
||||
ConstVal::Array(ref mut fields) => {
|
||||
for field_val in fields {
|
||||
erase_const_val(tcx, field_val);
|
||||
}
|
||||
}
|
||||
ConstVal::Repeat(ref mut expr, _) => {
|
||||
erase_const_val(tcx, &mut **expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EraseRegions;
|
||||
|
@ -12,6 +12,7 @@
|
||||
// scope.
|
||||
|
||||
// revisions: rpass1 rpass2
|
||||
// compile-flags: -Z query-dep-graph
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
@ -47,13 +48,15 @@ mod mod3 {
|
||||
use Trait2;
|
||||
|
||||
#[rustc_clean(label="Hir", cfg="rpass2")]
|
||||
#[rustc_dirty(label="HirBody", cfg="rpass2")]
|
||||
#[rustc_clean(label="HirBody", cfg="rpass2")]
|
||||
#[rustc_dirty(label="TypeckTables", cfg="rpass2")]
|
||||
fn bar() {
|
||||
().method();
|
||||
}
|
||||
|
||||
#[rustc_clean(label="Hir", cfg="rpass2")]
|
||||
#[rustc_clean(label="HirBody", cfg="rpass2")]
|
||||
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
|
||||
fn baz() {
|
||||
22; // no method call, traits in scope don't matter
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user