Create a forever red node and use it to force side effects.
This commit is contained in:
parent
682f57656e
commit
15530a1c84
@ -20,12 +20,6 @@
|
||||
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
|
||||
|
@ -123,9 +123,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
type PlaceholderRegion = ty::PlaceholderRegion;
|
||||
}
|
||||
|
||||
#[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)]
|
||||
@ -1477,23 +1474,15 @@ pub fn create_def(self, parent: LocalDefId, data: hir::definitions::DefPathData)
|
||||
let def_id = self.definitions.write().create_def(parent, data);
|
||||
|
||||
// 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 {
|
||||
@ -3033,5 +3022,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;
|
||||
}
|
||||
|
@ -72,8 +72,8 @@
|
||||
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;
|
||||
|
@ -39,17 +39,6 @@ fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -43,6 +43,7 @@ pub struct DepNodeIndex { .. }
|
||||
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 {
|
||||
@ -124,6 +125,8 @@ pub fn new(
|
||||
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,
|
||||
@ -133,6 +136,18 @@ pub fn new(
|
||||
);
|
||||
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,
|
||||
@ -140,7 +155,7 @@ pub fn new(
|
||||
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)),
|
||||
@ -965,6 +980,9 @@ fn new(
|
||||
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") {
|
||||
@ -1000,7 +1018,7 @@ fn new(
|
||||
)
|
||||
}),
|
||||
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),
|
||||
|
Loading…
Reference in New Issue
Block a user