Move ICH to rustc_query_system.
This commit is contained in:
parent
2d38c53767
commit
c355b2e5cd
11 changed files with 30 additions and 39 deletions
|
@ -10,12 +10,16 @@ doctest = false
|
|||
rustc_arena = { path = "../rustc_arena" }
|
||||
tracing = "0.1"
|
||||
rustc-rayon-core = "0.3.1"
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_feature = { path = "../rustc_feature" }
|
||||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_serialize = { path = "../rustc_serialize" }
|
||||
rustc_session = { path = "../rustc_session" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
parking_lot = "0.11"
|
||||
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
|
||||
|
|
209
compiler/rustc_query_system/src/ich/hcx.rs
Normal file
209
compiler/rustc_query_system/src/ich/hcx.rs
Normal file
|
@ -0,0 +1,209 @@
|
|||
use crate::ich;
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::definitions::{DefPathHash, Definitions};
|
||||
use rustc_session::cstore::CrateStore;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData};
|
||||
|
||||
fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
|
||||
debug_assert!(!ich::IGNORED_ATTRIBUTES.is_empty());
|
||||
ich::IGNORED_ATTRIBUTES.iter().copied().collect()
|
||||
}
|
||||
|
||||
/// This is the context state available during incr. comp. hashing. It contains
|
||||
/// enough information to transform `DefId`s and `HirId`s into stable `DefPath`s (i.e.,
|
||||
/// a reference to the `TyCtxt`) and it holds a few caches for speeding up various
|
||||
/// things (e.g., each `DefId`/`DefPath` is only hashed once).
|
||||
#[derive(Clone)]
|
||||
pub struct StableHashingContext<'a> {
|
||||
definitions: &'a Definitions,
|
||||
cstore: &'a dyn CrateStore,
|
||||
pub(super) body_resolver: BodyResolver<'a>,
|
||||
hash_spans: bool,
|
||||
hash_bodies: bool,
|
||||
pub(super) node_id_hashing_mode: NodeIdHashingMode,
|
||||
|
||||
// Very often, we are hashing something that does not need the
|
||||
// `CachingSourceMapView`, so we initialize it lazily.
|
||||
raw_source_map: &'a SourceMap,
|
||||
caching_source_map: Option<CachingSourceMapView<'a>>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum NodeIdHashingMode {
|
||||
Ignore,
|
||||
HashDefPath,
|
||||
}
|
||||
|
||||
/// The `BodyResolver` allows mapping 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)]
|
||||
pub(super) struct BodyResolver<'tcx>(&'tcx hir::Crate<'tcx>);
|
||||
|
||||
impl<'tcx> BodyResolver<'tcx> {
|
||||
/// Returns a reference to the `hir::Body` with the given `BodyId`.
|
||||
/// **Does not do any tracking**; use carefully.
|
||||
pub(super) fn body(self, id: hir::BodyId) -> &'tcx hir::Body<'tcx> {
|
||||
self.0.body(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> StableHashingContext<'a> {
|
||||
/// The `krate` here is only used for mapping `BodyId`s to `Body`s.
|
||||
/// Don't use it for anything else or you'll run the risk of
|
||||
/// leaking data out of the tracking system.
|
||||
#[inline]
|
||||
fn new_with_or_without_spans(
|
||||
sess: &'a Session,
|
||||
krate: &'a hir::Crate<'a>,
|
||||
definitions: &'a Definitions,
|
||||
cstore: &'a dyn CrateStore,
|
||||
always_ignore_spans: bool,
|
||||
) -> Self {
|
||||
let hash_spans_initial =
|
||||
!always_ignore_spans && !sess.opts.debugging_opts.incremental_ignore_spans;
|
||||
|
||||
StableHashingContext {
|
||||
body_resolver: BodyResolver(krate),
|
||||
definitions,
|
||||
cstore,
|
||||
caching_source_map: None,
|
||||
raw_source_map: sess.source_map(),
|
||||
hash_spans: hash_spans_initial,
|
||||
hash_bodies: true,
|
||||
node_id_hashing_mode: NodeIdHashingMode::HashDefPath,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new(
|
||||
sess: &'a Session,
|
||||
krate: &'a hir::Crate<'a>,
|
||||
definitions: &'a Definitions,
|
||||
cstore: &'a dyn CrateStore,
|
||||
) -> Self {
|
||||
Self::new_with_or_without_spans(
|
||||
sess,
|
||||
krate,
|
||||
definitions,
|
||||
cstore,
|
||||
/*always_ignore_spans=*/ false,
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn ignore_spans(
|
||||
sess: &'a Session,
|
||||
krate: &'a hir::Crate<'a>,
|
||||
definitions: &'a Definitions,
|
||||
cstore: &'a dyn CrateStore,
|
||||
) -> Self {
|
||||
let always_ignore_spans = true;
|
||||
Self::new_with_or_without_spans(sess, krate, definitions, cstore, always_ignore_spans)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn while_hashing_hir_bodies<F: FnOnce(&mut Self)>(&mut self, hash_bodies: bool, f: F) {
|
||||
let prev_hash_bodies = self.hash_bodies;
|
||||
self.hash_bodies = hash_bodies;
|
||||
f(self);
|
||||
self.hash_bodies = prev_hash_bodies;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn while_hashing_spans<F: FnOnce(&mut Self)>(&mut self, hash_spans: bool, f: F) {
|
||||
let prev_hash_spans = self.hash_spans;
|
||||
self.hash_spans = hash_spans;
|
||||
f(self);
|
||||
self.hash_spans = prev_hash_spans;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_node_id_hashing_mode<F: FnOnce(&mut Self)>(
|
||||
&mut self,
|
||||
mode: NodeIdHashingMode,
|
||||
f: F,
|
||||
) {
|
||||
let prev = self.node_id_hashing_mode;
|
||||
self.node_id_hashing_mode = mode;
|
||||
f(self);
|
||||
self.node_id_hashing_mode = prev;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
self.local_def_path_hash(def_id)
|
||||
} else {
|
||||
self.cstore.def_path_hash(def_id)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn local_def_path_hash(&self, def_id: LocalDefId) -> DefPathHash {
|
||||
self.definitions.def_path_hash(def_id)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hash_bodies(&self) -> bool {
|
||||
self.hash_bodies
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn source_map(&mut self) -> &mut CachingSourceMapView<'a> {
|
||||
match self.caching_source_map {
|
||||
Some(ref mut sm) => sm,
|
||||
ref mut none => {
|
||||
*none = Some(CachingSourceMapView::new(self.raw_source_map));
|
||||
none.as_mut().unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_ignored_attr(&self, name: Symbol) -> bool {
|
||||
thread_local! {
|
||||
static IGNORED_ATTRIBUTES: FxHashSet<Symbol> = compute_ignored_attr_names();
|
||||
}
|
||||
IGNORED_ATTRIBUTES.with(|attrs| attrs.contains(&name))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for ast::NodeId {
|
||||
fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) {
|
||||
panic!("Node IDs should not appear in incremental state");
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
|
||||
fn hash_spans(&self) -> bool {
|
||||
self.hash_spans
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
|
||||
self.def_path_hash(def_id)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn def_span(&self, def_id: LocalDefId) -> Span {
|
||||
self.definitions.def_span(def_id)
|
||||
}
|
||||
|
||||
fn span_data_to_lines_and_cols(
|
||||
&mut self,
|
||||
span: &SpanData,
|
||||
) -> Option<(Lrc<SourceFile>, usize, BytePos, usize, BytePos)> {
|
||||
self.source_map().span_data_to_lines_and_cols(span)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> rustc_session::HashStableContext for StableHashingContext<'a> {}
|
150
compiler/rustc_query_system/src/ich/impls_hir.rs
Normal file
150
compiler/rustc_query_system/src/ich/impls_hir.rs
Normal file
|
@ -0,0 +1,150 @@
|
|||
//! This module contains `HashStable` implementations for various HIR data
|
||||
//! types in no particular order.
|
||||
|
||||
use crate::ich::{NodeIdHashingMode, StableHashingContext};
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::definitions::DefPathHash;
|
||||
use smallvec::SmallVec;
|
||||
use std::mem;
|
||||
|
||||
impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
|
||||
#[inline]
|
||||
fn hash_hir_id(&mut self, hir_id: hir::HirId, hasher: &mut StableHasher) {
|
||||
let hcx = self;
|
||||
match hcx.node_id_hashing_mode {
|
||||
NodeIdHashingMode::Ignore => {
|
||||
// Don't do anything.
|
||||
}
|
||||
NodeIdHashingMode::HashDefPath => {
|
||||
let hir::HirId { owner, local_id } = hir_id;
|
||||
|
||||
hcx.local_def_path_hash(owner).hash_stable(hcx, hasher);
|
||||
local_id.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn hash_body_id(&mut self, id: hir::BodyId, hasher: &mut StableHasher) {
|
||||
let hcx = self;
|
||||
if hcx.hash_bodies() {
|
||||
hcx.body_resolver.body(id).hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
fn hash_reference_to_item(&mut self, id: hir::HirId, hasher: &mut StableHasher) {
|
||||
let hcx = self;
|
||||
|
||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
|
||||
id.hash_stable(hcx, hasher);
|
||||
})
|
||||
}
|
||||
|
||||
fn hash_hir_mod(&mut self, module: &hir::Mod<'_>, hasher: &mut StableHasher) {
|
||||
let hcx = self;
|
||||
let hir::Mod { inner: ref inner_span, ref item_ids } = *module;
|
||||
|
||||
inner_span.hash_stable(hcx, hasher);
|
||||
|
||||
// Combining the `DefPathHash`s directly is faster than feeding them
|
||||
// into the hasher. Because we use a commutative combine, we also don't
|
||||
// have to sort the array.
|
||||
let item_ids_hash = item_ids
|
||||
.iter()
|
||||
.map(|id| {
|
||||
let def_path_hash = id.to_stable_hash_key(hcx);
|
||||
def_path_hash.0
|
||||
})
|
||||
.fold(Fingerprint::ZERO, |a, b| a.combine_commutative(b));
|
||||
|
||||
item_ids.len().hash_stable(hcx, hasher);
|
||||
item_ids_hash.hash_stable(hcx, hasher);
|
||||
}
|
||||
|
||||
fn hash_hir_expr(&mut self, expr: &hir::Expr<'_>, hasher: &mut StableHasher) {
|
||||
self.while_hashing_hir_bodies(true, |hcx| {
|
||||
let hir::Expr { hir_id: _, ref span, ref kind } = *expr;
|
||||
|
||||
span.hash_stable(hcx, hasher);
|
||||
kind.hash_stable(hcx, hasher);
|
||||
})
|
||||
}
|
||||
|
||||
fn hash_hir_ty(&mut self, ty: &hir::Ty<'_>, hasher: &mut StableHasher) {
|
||||
self.while_hashing_hir_bodies(true, |hcx| {
|
||||
let hir::Ty { hir_id: _, ref kind, ref span } = *ty;
|
||||
|
||||
kind.hash_stable(hcx, hasher);
|
||||
span.hash_stable(hcx, hasher);
|
||||
})
|
||||
}
|
||||
|
||||
fn hash_hir_visibility_kind(
|
||||
&mut self,
|
||||
vis: &hir::VisibilityKind<'_>,
|
||||
hasher: &mut StableHasher,
|
||||
) {
|
||||
let hcx = self;
|
||||
mem::discriminant(vis).hash_stable(hcx, hasher);
|
||||
match *vis {
|
||||
hir::VisibilityKind::Public | hir::VisibilityKind::Inherited => {
|
||||
// No fields to hash.
|
||||
}
|
||||
hir::VisibilityKind::Crate(sugar) => {
|
||||
sugar.hash_stable(hcx, hasher);
|
||||
}
|
||||
hir::VisibilityKind::Restricted { ref path, hir_id } => {
|
||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
|
||||
hir_id.hash_stable(hcx, hasher);
|
||||
});
|
||||
path.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self, f: F) {
|
||||
let prev_hash_node_ids = self.node_id_hashing_mode;
|
||||
self.node_id_hashing_mode = NodeIdHashingMode::Ignore;
|
||||
|
||||
f(self);
|
||||
|
||||
self.node_id_hashing_mode = prev_hash_node_ids;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for hir::Body<'_> {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
let hir::Body { params, value, generator_kind } = self;
|
||||
|
||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
|
||||
params.hash_stable(hcx, hasher);
|
||||
value.hash_stable(hcx, hasher);
|
||||
generator_kind.hash_stable(hcx, hasher);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
|
||||
let hir::TraitCandidate { def_id, import_ids } = self;
|
||||
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
import_ids.hash_stable(hcx, hasher);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
|
||||
type KeyType = (DefPathHash, SmallVec<[DefPathHash; 1]>);
|
||||
|
||||
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Self::KeyType {
|
||||
let hir::TraitCandidate { def_id, import_ids } = self;
|
||||
|
||||
(
|
||||
hcx.def_path_hash(*def_id),
|
||||
import_ids.iter().map(|def_id| hcx.local_def_path_hash(*def_id)).collect(),
|
||||
)
|
||||
}
|
||||
}
|
146
compiler/rustc_query_system/src/ich/impls_syntax.rs
Normal file
146
compiler/rustc_query_system/src/ich/impls_syntax.rs
Normal file
|
@ -0,0 +1,146 @@
|
|||
//! This module contains `HashStable` implementations for various data types
|
||||
//! from `rustc_ast` in no particular order.
|
||||
|
||||
use crate::ich::StableHashingContext;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_span::{BytePos, NormalizedPos, SourceFile};
|
||||
use std::assert_matches::assert_matches;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
|
||||
impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {}
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
if self.is_empty() {
|
||||
self.len().hash_stable(hcx, hasher);
|
||||
return;
|
||||
}
|
||||
|
||||
// Some attributes are always ignored during hashing.
|
||||
let filtered: SmallVec<[&ast::Attribute; 8]> = self
|
||||
.iter()
|
||||
.filter(|attr| {
|
||||
!attr.is_doc_comment()
|
||||
&& !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
|
||||
})
|
||||
.collect();
|
||||
|
||||
filtered.len().hash_stable(hcx, hasher);
|
||||
for attr in filtered {
|
||||
attr.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {
|
||||
fn hash_attr(&mut self, attr: &ast::Attribute, hasher: &mut StableHasher) {
|
||||
// Make sure that these have been filtered out.
|
||||
debug_assert!(!attr.ident().map_or(false, |ident| self.is_ignored_attr(ident.name)));
|
||||
debug_assert!(!attr.is_doc_comment());
|
||||
|
||||
let ast::Attribute { kind, id: _, style, span } = attr;
|
||||
if let ast::AttrKind::Normal(item, tokens) = kind {
|
||||
item.hash_stable(self, hasher);
|
||||
style.hash_stable(self, hasher);
|
||||
span.hash_stable(self, hasher);
|
||||
assert_matches!(
|
||||
tokens.as_ref(),
|
||||
None,
|
||||
"Tokens should have been removed during lowering!"
|
||||
);
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
let SourceFile {
|
||||
name: _, // We hash the smaller name_hash instead of this
|
||||
name_hash,
|
||||
cnum,
|
||||
// Do not hash the source as it is not encoded
|
||||
src: _,
|
||||
ref src_hash,
|
||||
external_src: _,
|
||||
start_pos,
|
||||
end_pos: _,
|
||||
ref lines,
|
||||
ref multibyte_chars,
|
||||
ref non_narrow_chars,
|
||||
ref normalized_pos,
|
||||
} = *self;
|
||||
|
||||
(name_hash as u64).hash_stable(hcx, hasher);
|
||||
|
||||
src_hash.hash_stable(hcx, hasher);
|
||||
|
||||
// We only hash the relative position within this source_file
|
||||
lines.len().hash_stable(hcx, hasher);
|
||||
for &line in lines.iter() {
|
||||
stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
|
||||
}
|
||||
|
||||
// We only hash the relative position within this source_file
|
||||
multibyte_chars.len().hash_stable(hcx, hasher);
|
||||
for &char_pos in multibyte_chars.iter() {
|
||||
stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
|
||||
}
|
||||
|
||||
non_narrow_chars.len().hash_stable(hcx, hasher);
|
||||
for &char_pos in non_narrow_chars.iter() {
|
||||
stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
|
||||
}
|
||||
|
||||
normalized_pos.len().hash_stable(hcx, hasher);
|
||||
for &char_pos in normalized_pos.iter() {
|
||||
stable_normalized_pos(char_pos, start_pos).hash_stable(hcx, hasher);
|
||||
}
|
||||
|
||||
cnum.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
fn stable_byte_pos(pos: BytePos, source_file_start: BytePos) -> u32 {
|
||||
pos.0 - source_file_start.0
|
||||
}
|
||||
|
||||
fn stable_multibyte_char(mbc: rustc_span::MultiByteChar, source_file_start: BytePos) -> (u32, u32) {
|
||||
let rustc_span::MultiByteChar { pos, bytes } = mbc;
|
||||
|
||||
(pos.0 - source_file_start.0, bytes as u32)
|
||||
}
|
||||
|
||||
fn stable_non_narrow_char(
|
||||
swc: rustc_span::NonNarrowChar,
|
||||
source_file_start: BytePos,
|
||||
) -> (u32, u32) {
|
||||
let pos = swc.pos();
|
||||
let width = swc.width();
|
||||
|
||||
(pos.0 - source_file_start.0, width as u32)
|
||||
}
|
||||
|
||||
fn stable_normalized_pos(np: NormalizedPos, source_file_start: BytePos) -> (u32, u32) {
|
||||
let NormalizedPos { pos, diff } = np;
|
||||
|
||||
(pos.0 - source_file_start.0, diff)
|
||||
}
|
||||
|
||||
impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
|
||||
// Unfortunately we cannot exhaustively list fields here, since the
|
||||
// struct is macro generated.
|
||||
self.declared_lang_features.hash_stable(hcx, hasher);
|
||||
self.declared_lib_features.hash_stable(hcx, hasher);
|
||||
|
||||
self.walk_feature_fields(|feature_name, value| {
|
||||
feature_name.hash_stable(hcx, hasher);
|
||||
value.hash_stable(hcx, hasher);
|
||||
});
|
||||
}
|
||||
}
|
19
compiler/rustc_query_system/src/ich/mod.rs
Normal file
19
compiler/rustc_query_system/src/ich/mod.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
//! ICH - Incremental Compilation Hash
|
||||
|
||||
pub use self::hcx::{NodeIdHashingMode, StableHashingContext};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
|
||||
mod hcx;
|
||||
mod impls_hir;
|
||||
mod impls_syntax;
|
||||
|
||||
pub const IGNORED_ATTRIBUTES: &[Symbol] = &[
|
||||
sym::cfg,
|
||||
sym::rustc_if_this_changed,
|
||||
sym::rustc_then_this_would_need,
|
||||
sym::rustc_dirty,
|
||||
sym::rustc_clean,
|
||||
sym::rustc_partition_reused,
|
||||
sym::rustc_partition_codegened,
|
||||
sym::rustc_expected_cgu_reuse,
|
||||
];
|
|
@ -1,3 +1,4 @@
|
|||
#![feature(assert_matches)]
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(hash_raw_entry)]
|
||||
|
@ -14,4 +15,5 @@ extern crate rustc_macros;
|
|||
|
||||
pub mod cache;
|
||||
pub mod dep_graph;
|
||||
pub mod ich;
|
||||
pub mod query;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue