Skip to content

Commit

Permalink
Create a forever red node and use it to force side effects.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Apr 30, 2022
1 parent 9d6214f commit 50c56c5
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 37 deletions.
6 changes: 0 additions & 6 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ rustc_queries! {
desc { "trigger a delay span bug" }
}

/// Create a new definition within the incr. comp. engine.
query register_def(_: ty::RawLocalDefId) -> LocalDefId {
eval_always
desc { "register a DefId with the incr. comp. engine" }
}

query resolutions(_: ()) -> &'tcx ty::ResolverOutputs {
eval_always
no_hash
Expand Down
20 changes: 4 additions & 16 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync {
fn serialize(&self, tcx: TyCtxt<'tcx>, encoder: &mut FileEncoder) -> FileEncodeResult;
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
pub struct RawLocalDefId(LocalDefId);

/// A type that is not publicly constructable. This prevents people from making [`TyKind::Error`]s
/// except through the error-reporting functions on a [`tcx`][TyCtxt].
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
Expand Down Expand Up @@ -1405,23 +1402,15 @@ impl<'tcx> TyCtxt<'tcx> {
let def_id = self.definitions.write().create_def(parent, data, expn_id, span);

// We need to ensure that these side effects are re-run by the incr. comp. engine.
// When the incr. comp. engine considers marking this query as green, eval_always requires
// we run the function to run. To invoke it, the parameter cannot be reconstructed from
// the DepNode, so the caller query is run. Luckily, we are inside the caller query,
// therefore the definition is properly created.
debug_assert!({
use rustc_query_system::dep_graph::{DepContext, DepNodeParams};
self.is_eval_always(crate::dep_graph::DepKind::register_def)
&& !<RawLocalDefId as DepNodeParams<TyCtxt<'_>>>::fingerprint_style()
.reconstructible()
});
use rustc_query_system::dep_graph::DepNodeIndex;
self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);

// Any LocalDefId which is used within queries, either as key or result, either:
// - has been created before the construction of the TyCtxt;
// - has been created by this call to `register_def`.
// - has been created by this call to `create_def`.
// As a consequence, this LocalDefId is always re-created before it is needed by the incr.
// comp. engine itself.
self.register_def(RawLocalDefId(def_id))
def_id
}

pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> + 'tcx {
Expand Down Expand Up @@ -3021,5 +3010,4 @@ pub fn provide(providers: &mut ty::query::Providers) {
// We want to check if the panic handler was defined in this crate
tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
};
providers.register_def = |_, raw_id| raw_id.0;
}
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ pub use self::consts::{
pub use self::context::{
tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorDiagnosticData,
GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, RawLocalDefId, TyCtxt,
TypeckResults, UserType, UserTypeAnnotationIndex,
GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType,
UserTypeAnnotationIndex,
};
pub use self::instance::{Instance, InstanceDef};
pub use self::list::List;
Expand Down
11 changes: 0 additions & 11 deletions compiler/rustc_query_impl/src/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,6 @@ impl Key for () {
}
}

impl Key for ty::RawLocalDefId {
#[inline(always)]
fn query_crate_is_local(&self) -> bool {
true
}

fn default_span(&self, _: TyCtxt<'_>) -> Span {
DUMMY_SP
}
}

impl<'tcx> Key for ty::InstanceDef<'tcx> {
#[inline(always)]
fn query_crate_is_local(&self) -> bool {
Expand Down
22 changes: 20 additions & 2 deletions compiler/rustc_query_system/src/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ rustc_index::newtype_index! {
impl DepNodeIndex {
pub const INVALID: DepNodeIndex = DepNodeIndex::MAX;
pub const SINGLETON_DEPENDENCYLESS_ANON_NODE: DepNodeIndex = DepNodeIndex::from_u32(0);
pub const FOREVER_RED_NODE: DepNodeIndex = DepNodeIndex::from_u32(1);
}

impl std::convert::From<DepNodeIndex> for QueryInvocationId {
Expand Down Expand Up @@ -124,6 +125,8 @@ impl<K: DepKind> DepGraph<K> {
record_stats,
);

let colors = DepNodeColorMap::new(prev_graph_node_count);

// Instantiate a dependy-less node only once for anonymous queries.
let _green_node_index = current.intern_new_node(
profiler,
Expand All @@ -133,14 +136,26 @@ impl<K: DepKind> DepGraph<K> {
);
debug_assert_eq!(_green_node_index, DepNodeIndex::SINGLETON_DEPENDENCYLESS_ANON_NODE);

// Instantiate a dependy-less red node only once for anonymous queries.
let (_red_node_index, _prev_and_index) = current.intern_node(
profiler,
&prev_graph,
DepNode { kind: DepKind::NULL, hash: Fingerprint::ZERO.into() },
smallvec![],
None,
false,
);
debug_assert_eq!(_red_node_index, DepNodeIndex::FOREVER_RED_NODE);
debug_assert!(matches!(_prev_and_index, None | Some((_, DepNodeColor::Red))));

DepGraph {
data: Some(Lrc::new(DepGraphData {
previous_work_products: prev_work_products,
dep_node_debug: Default::default(),
current,
processed_side_effects: Default::default(),
previous: prev_graph,
colors: DepNodeColorMap::new(prev_graph_node_count),
colors,
debug_loaded_from_disk: Default::default(),
})),
virtual_dep_node_index: Lrc::new(AtomicU32::new(0)),
Expand Down Expand Up @@ -965,6 +980,9 @@ impl<K: DepKind> CurrentDepGraph<K> {
let nanos = duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64;
let mut stable_hasher = StableHasher::new();
nanos.hash(&mut stable_hasher);
let anon_id_seed = stable_hasher.finish();
// We rely on the fact that `anon_id_seed` is not zero when creating static nodes.
debug_assert_ne!(anon_id_seed, Fingerprint::ZERO);

#[cfg(debug_assertions)]
let forbidden_edge = match env::var("RUST_FORBID_DEP_GRAPH_EDGE") {
Expand Down Expand Up @@ -1000,7 +1018,7 @@ impl<K: DepKind> CurrentDepGraph<K> {
)
}),
prev_index_to_index: Lock::new(IndexVec::from_elem_n(None, prev_graph_node_count)),
anon_id_seed: stable_hasher.finish(),
anon_id_seed,
#[cfg(debug_assertions)]
forbidden_edge,
total_read_count: AtomicU64::new(0),
Expand Down

0 comments on commit 50c56c5

Please sign in to comment.