Auto merge of #152636 - nnethercote:big-cleanups, r=Zalathar
Big query system cleanups Recent PRs have moved a lot of code from `rustc_query_system` to `rustc_middle` and `rustc_query_impl`, where this code now has access to `TyCtxt`, e.g. rust-lang/rust#152419, rust-lang/rust#152516. As a result, a lot of abstraction and indirection that existed to work around this limitation is no longer necessary. This PR removes a lot of it. r? @Zalathar
This commit is contained in:
commit
fef627b1eb
19 changed files with 317 additions and 492 deletions
|
|
@ -4500,7 +4500,6 @@ dependencies = [
|
|||
"rustc_index",
|
||||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
"rustc_query_system",
|
||||
"rustc_serialize",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
|
|||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::dep_graph::{
|
||||
DepGraphQuery, DepKind, DepNode, DepNodeExt, DepNodeFilter, EdgeFilter, dep_kinds,
|
||||
DepGraphQuery, DepKind, DepNode, DepNodeFilter, EdgeFilter, dep_kinds,
|
||||
};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use rustc_hir::{
|
|||
Attribute, ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, find_attr,
|
||||
intravisit,
|
||||
};
|
||||
use rustc_middle::dep_graph::{DepNode, DepNodeExt, dep_kind_from_label, label_strs};
|
||||
use rustc_middle::dep_graph::{DepNode, dep_kind_from_label, label_strs};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use std::sync::Arc;
|
|||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_hashes::Hash64;
|
||||
use rustc_middle::dep_graph::{DepGraph, DepsType, SerializedDepGraph, WorkProductMap};
|
||||
use rustc_middle::dep_graph::{DepGraph, SerializedDepGraph, WorkProductMap};
|
||||
use rustc_middle::query::on_disk_cache::OnDiskCache;
|
||||
use rustc_serialize::Decodable;
|
||||
use rustc_serialize::opaque::MemDecoder;
|
||||
|
|
@ -171,7 +171,7 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkPr
|
|||
return LoadResult::DataOutOfDate;
|
||||
}
|
||||
|
||||
let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder);
|
||||
let dep_graph = SerializedDepGraph::decode(&mut decoder);
|
||||
|
||||
LoadResult::Ok { data: (dep_graph, prev_work_products) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,8 @@ use std::fmt;
|
|||
|
||||
use rustc_errors::{DiagInner, TRACK_DIAGNOSTIC};
|
||||
use rustc_middle::dep_graph::dep_node::default_dep_kind_debug;
|
||||
use rustc_middle::dep_graph::{DepContext, DepKind, DepNode, DepNodeExt, TaskDepsRef};
|
||||
use rustc_middle::dep_graph::{DepKind, DepNode, TaskDepsRef};
|
||||
use rustc_middle::ty::tls;
|
||||
use rustc_query_impl::QueryCtxt;
|
||||
|
||||
fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
|
||||
tls::with_context_opt(|icx| {
|
||||
|
|
@ -41,7 +40,7 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
|
|||
fn track_diagnostic<R>(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
|
||||
tls::with_context_opt(|icx| {
|
||||
if let Some(icx) = icx {
|
||||
icx.tcx.dep_graph.record_diagnostic(QueryCtxt::new(icx.tcx), &diagnostic);
|
||||
icx.tcx.dep_graph.record_diagnostic(icx.tcx, &diagnostic);
|
||||
|
||||
// Diagnostics are tracked, we can ignore the dependency.
|
||||
let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..icx.clone() };
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ use rustc_macros::{Decodable, Encodable};
|
|||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use super::{DepContext, FingerprintStyle, SerializedDepNodeIndex};
|
||||
use super::{FingerprintStyle, SerializedDepNodeIndex};
|
||||
use crate::mir::mono::MonoItem;
|
||||
use crate::ty::TyCtxt;
|
||||
|
||||
|
|
@ -92,6 +92,26 @@ impl DepKind {
|
|||
pub const fn as_usize(&self) -> usize {
|
||||
self.variant as usize
|
||||
}
|
||||
|
||||
pub(crate) fn name(self) -> &'static str {
|
||||
DEP_KIND_NAMES[self.as_usize()]
|
||||
}
|
||||
|
||||
/// We use this for most things when incr. comp. is turned off.
|
||||
pub(crate) const NULL: DepKind = dep_kinds::Null;
|
||||
|
||||
/// We use this to create a forever-red node.
|
||||
pub(crate) const RED: DepKind = dep_kinds::Red;
|
||||
|
||||
/// We use this to create a side effect node.
|
||||
pub(crate) const SIDE_EFFECT: DepKind = dep_kinds::SideEffect;
|
||||
|
||||
/// We use this to create the anon node with zero dependencies.
|
||||
pub(crate) const ANON_ZERO_DEPS: DepKind = dep_kinds::AnonZeroDeps;
|
||||
|
||||
/// This is the highest value a `DepKind` can have. It's used during encoding to
|
||||
/// pack information into the unused bits.
|
||||
pub(crate) const MAX: u16 = DEP_KIND_VARIANTS - 1;
|
||||
}
|
||||
|
||||
pub fn default_dep_kind_debug(kind: DepKind, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
|
@ -117,18 +137,14 @@ impl DepNode {
|
|||
/// Creates a new, parameterless DepNode. This method will assert
|
||||
/// that the DepNode corresponding to the given DepKind actually
|
||||
/// does not require any parameters.
|
||||
pub fn new_no_params<Tcx>(tcx: Tcx, kind: DepKind) -> DepNode
|
||||
where
|
||||
Tcx: super::DepContext,
|
||||
{
|
||||
pub fn new_no_params<'tcx>(tcx: TyCtxt<'tcx>, kind: DepKind) -> DepNode {
|
||||
debug_assert_eq!(tcx.fingerprint_style(kind), FingerprintStyle::Unit);
|
||||
DepNode { kind, hash: Fingerprint::ZERO.into() }
|
||||
}
|
||||
|
||||
pub fn construct<Tcx, Key>(tcx: Tcx, kind: DepKind, arg: &Key) -> DepNode
|
||||
pub fn construct<'tcx, Key>(tcx: TyCtxt<'tcx>, kind: DepKind, arg: &Key) -> DepNode
|
||||
where
|
||||
Tcx: super::DepContext,
|
||||
Key: DepNodeKey<Tcx>,
|
||||
Key: DepNodeKey<'tcx>,
|
||||
{
|
||||
let hash = arg.to_fingerprint(tcx);
|
||||
let dep_node = DepNode { kind, hash: hash.into() };
|
||||
|
|
@ -136,10 +152,10 @@ impl DepNode {
|
|||
#[cfg(debug_assertions)]
|
||||
{
|
||||
if !tcx.fingerprint_style(kind).reconstructible()
|
||||
&& (tcx.sess().opts.unstable_opts.incremental_info
|
||||
|| tcx.sess().opts.unstable_opts.query_dep_graph)
|
||||
&& (tcx.sess.opts.unstable_opts.incremental_info
|
||||
|| tcx.sess.opts.unstable_opts.query_dep_graph)
|
||||
{
|
||||
tcx.dep_graph().register_dep_node_debug_str(dep_node, || arg.to_debug_str(tcx));
|
||||
tcx.dep_graph.register_dep_node_debug_str(dep_node, || arg.to_debug_str(tcx));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -149,10 +165,11 @@ impl DepNode {
|
|||
/// Construct a DepNode from the given DepKind and DefPathHash. This
|
||||
/// method will assert that the given DepKind actually requires a
|
||||
/// single DefId/DefPathHash parameter.
|
||||
pub fn from_def_path_hash<Tcx>(tcx: Tcx, def_path_hash: DefPathHash, kind: DepKind) -> Self
|
||||
where
|
||||
Tcx: super::DepContext,
|
||||
{
|
||||
pub fn from_def_path_hash<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_path_hash: DefPathHash,
|
||||
kind: DepKind,
|
||||
) -> Self {
|
||||
debug_assert!(tcx.fingerprint_style(kind) == FingerprintStyle::DefPathHash);
|
||||
DepNode { kind, hash: def_path_hash.0.into() }
|
||||
}
|
||||
|
|
@ -172,14 +189,14 @@ impl fmt::Debug for DepNode {
|
|||
}
|
||||
|
||||
/// Trait for query keys as seen by dependency-node tracking.
|
||||
pub trait DepNodeKey<Tcx: DepContext>: fmt::Debug + Sized {
|
||||
pub trait DepNodeKey<'tcx>: fmt::Debug + Sized {
|
||||
fn fingerprint_style() -> FingerprintStyle;
|
||||
|
||||
/// This method turns a query key into an opaque `Fingerprint` to be used
|
||||
/// in `DepNode`.
|
||||
fn to_fingerprint(&self, _: Tcx) -> Fingerprint;
|
||||
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint;
|
||||
|
||||
fn to_debug_str(&self, tcx: Tcx) -> String;
|
||||
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String;
|
||||
|
||||
/// This method tries to recover the query key from the given `DepNode`,
|
||||
/// something which is needed when forcing `DepNode`s during red-green
|
||||
|
|
@ -187,11 +204,11 @@ pub trait DepNodeKey<Tcx: DepContext>: fmt::Debug + Sized {
|
|||
/// `fingerprint_style()` is not `FingerprintStyle::Opaque`.
|
||||
/// It is always valid to return `None` here, in which case incremental
|
||||
/// compilation will treat the query as having changed instead of forcing it.
|
||||
fn recover(tcx: Tcx, dep_node: &DepNode) -> Option<Self>;
|
||||
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
|
||||
}
|
||||
|
||||
// Blanket impl of `DepNodeKey`, which is specialized by other impls elsewhere.
|
||||
impl<Tcx: DepContext, T> DepNodeKey<Tcx> for T
|
||||
impl<'tcx, T> DepNodeKey<'tcx> for T
|
||||
where
|
||||
T: for<'a> HashStable<StableHashingContext<'a>> + fmt::Debug,
|
||||
{
|
||||
|
|
@ -201,7 +218,7 @@ where
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
default fn to_fingerprint(&self, tcx: Tcx) -> Fingerprint {
|
||||
default fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
|
||||
tcx.with_stable_hashing_context(|mut hcx| {
|
||||
let mut hasher = StableHasher::new();
|
||||
self.hash_stable(&mut hcx, &mut hasher);
|
||||
|
|
@ -210,7 +227,7 @@ where
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
default fn to_debug_str(&self, tcx: Tcx) -> String {
|
||||
default fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
|
||||
// Make sure to print dep node params with reduced queries since printing
|
||||
// may themselves call queries, which may lead to (possibly untracked!)
|
||||
// query cycles.
|
||||
|
|
@ -218,7 +235,7 @@ where
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
default fn recover(_: Tcx, _: &DepNode) -> Option<Self> {
|
||||
default fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -228,7 +245,7 @@ where
|
|||
/// Information is retrieved by indexing the `DEP_KINDS` array using the integer value
|
||||
/// of the `DepKind`. Overall, this allows to implement `DepContext` using this manual
|
||||
/// jump table instead of large matches.
|
||||
pub struct DepKindVTable<Tcx: DepContext> {
|
||||
pub struct DepKindVTable<'tcx> {
|
||||
/// Anonymous queries cannot be replayed from one compiler invocation to the next.
|
||||
/// When their result is needed, it is recomputed. They are useful for fine-grained
|
||||
/// dependency tracking, and caching within one compiler invocation.
|
||||
|
|
@ -279,11 +296,12 @@ pub struct DepKindVTable<Tcx: DepContext> {
|
|||
/// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode`
|
||||
/// is actually a `DefPathHash`, and can therefore just look up the corresponding
|
||||
/// `DefId` in `tcx.def_path_hash_to_def_id`.
|
||||
pub force_from_dep_node:
|
||||
Option<fn(tcx: Tcx, dep_node: DepNode, prev_index: SerializedDepNodeIndex) -> bool>,
|
||||
pub force_from_dep_node: Option<
|
||||
fn(tcx: TyCtxt<'tcx>, dep_node: DepNode, prev_index: SerializedDepNodeIndex) -> bool,
|
||||
>,
|
||||
|
||||
/// Invoke a query to put the on-disk cached value in memory.
|
||||
pub try_load_from_on_disk_cache: Option<fn(Tcx, DepNode)>,
|
||||
pub try_load_from_on_disk_cache: Option<fn(TyCtxt<'tcx>, DepNode)>,
|
||||
|
||||
/// The name of this dep kind.
|
||||
pub name: &'static &'static str,
|
||||
|
|
@ -434,19 +452,7 @@ pub(crate) fn make_metadata(tcx: TyCtxt<'_>) -> DepNode {
|
|||
DepNode::construct(tcx, dep_kinds::Metadata, &())
|
||||
}
|
||||
|
||||
pub trait DepNodeExt: Sized {
|
||||
fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId>;
|
||||
|
||||
fn from_label_string(
|
||||
tcx: TyCtxt<'_>,
|
||||
label: &str,
|
||||
def_path_hash: DefPathHash,
|
||||
) -> Result<Self, ()>;
|
||||
|
||||
fn has_label_string(label: &str) -> bool;
|
||||
}
|
||||
|
||||
impl DepNodeExt for DepNode {
|
||||
impl DepNode {
|
||||
/// Extracts the DefId corresponding to this DepNode. This will work
|
||||
/// if two conditions are met:
|
||||
///
|
||||
|
|
@ -457,7 +463,7 @@ impl DepNodeExt for DepNode {
|
|||
/// DepNode. Condition (2) might not be fulfilled if a DepNode
|
||||
/// refers to something from the previous compilation session that
|
||||
/// has been removed.
|
||||
fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
|
||||
pub fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
|
||||
if tcx.fingerprint_style(self.kind) == FingerprintStyle::DefPathHash {
|
||||
tcx.def_path_hash_to_def_id(DefPathHash(self.hash.into()))
|
||||
} else {
|
||||
|
|
@ -465,8 +471,7 @@ impl DepNodeExt for DepNode {
|
|||
}
|
||||
}
|
||||
|
||||
/// Used in testing
|
||||
fn from_label_string(
|
||||
pub fn from_label_string(
|
||||
tcx: TyCtxt<'_>,
|
||||
label: &str,
|
||||
def_path_hash: DefPathHash,
|
||||
|
|
@ -482,8 +487,7 @@ impl DepNodeExt for DepNode {
|
|||
}
|
||||
}
|
||||
|
||||
/// Used in testing
|
||||
fn has_label_string(label: &str) -> bool {
|
||||
pub fn has_label_string(label: &str) -> bool {
|
||||
dep_kind_from_label_string(label).is_ok()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId,
|
|||
use rustc_hir::definitions::DefPathHash;
|
||||
use rustc_hir::{HirId, ItemLocalId, OwnerId};
|
||||
|
||||
use crate::dep_graph::{DepContext, DepNode, DepNodeExt, DepNodeKey, FingerprintStyle};
|
||||
use crate::dep_graph::{DepNode, DepNodeKey, FingerprintStyle};
|
||||
use crate::ty::TyCtxt;
|
||||
|
||||
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for () {
|
||||
impl<'tcx> DepNodeKey<'tcx> for () {
|
||||
#[inline(always)]
|
||||
fn fingerprint_style() -> FingerprintStyle {
|
||||
FingerprintStyle::Unit
|
||||
|
|
@ -23,7 +23,7 @@ impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for () {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for DefId {
|
||||
impl<'tcx> DepNodeKey<'tcx> for DefId {
|
||||
#[inline(always)]
|
||||
fn fingerprint_style() -> FingerprintStyle {
|
||||
FingerprintStyle::DefPathHash
|
||||
|
|
@ -45,7 +45,7 @@ impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for DefId {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for LocalDefId {
|
||||
impl<'tcx> DepNodeKey<'tcx> for LocalDefId {
|
||||
#[inline(always)]
|
||||
fn fingerprint_style() -> FingerprintStyle {
|
||||
FingerprintStyle::DefPathHash
|
||||
|
|
@ -67,7 +67,7 @@ impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for LocalDefId {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for OwnerId {
|
||||
impl<'tcx> DepNodeKey<'tcx> for OwnerId {
|
||||
#[inline(always)]
|
||||
fn fingerprint_style() -> FingerprintStyle {
|
||||
FingerprintStyle::DefPathHash
|
||||
|
|
@ -89,7 +89,7 @@ impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for OwnerId {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for CrateNum {
|
||||
impl<'tcx> DepNodeKey<'tcx> for CrateNum {
|
||||
#[inline(always)]
|
||||
fn fingerprint_style() -> FingerprintStyle {
|
||||
FingerprintStyle::DefPathHash
|
||||
|
|
@ -112,7 +112,7 @@ impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for CrateNum {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for (DefId, DefId) {
|
||||
impl<'tcx> DepNodeKey<'tcx> for (DefId, DefId) {
|
||||
#[inline(always)]
|
||||
fn fingerprint_style() -> FingerprintStyle {
|
||||
FingerprintStyle::Opaque
|
||||
|
|
@ -139,7 +139,7 @@ impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for (DefId, DefId) {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for HirId {
|
||||
impl<'tcx> DepNodeKey<'tcx> for HirId {
|
||||
#[inline(always)]
|
||||
fn fingerprint_style() -> FingerprintStyle {
|
||||
FingerprintStyle::HirId
|
||||
|
|
@ -182,7 +182,7 @@ impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for HirId {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for ModDefId {
|
||||
impl<'tcx> DepNodeKey<'tcx> for ModDefId {
|
||||
#[inline(always)]
|
||||
fn fingerprint_style() -> FingerprintStyle {
|
||||
FingerprintStyle::DefPathHash
|
||||
|
|
@ -204,7 +204,7 @@ impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for ModDefId {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for LocalModDefId {
|
||||
impl<'tcx> DepNodeKey<'tcx> for LocalModDefId {
|
||||
#[inline(always)]
|
||||
fn fingerprint_style() -> FingerprintStyle {
|
||||
FingerprintStyle::DefPathHash
|
||||
|
|
|
|||
|
|
@ -25,13 +25,14 @@ use {super::debug::EdgeFilter, std::env};
|
|||
|
||||
use super::query::DepGraphQuery;
|
||||
use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex};
|
||||
use super::{DepContext, DepKind, DepNode, Deps, HasDepContext, WorkProductId};
|
||||
use super::{DepKind, DepNode, HasDepContext, WorkProductId, read_deps, with_deps};
|
||||
use crate::dep_graph::edges::EdgesVec;
|
||||
use crate::query::QueryContext;
|
||||
use crate::ty::TyCtxt;
|
||||
use crate::verify_ich::incremental_verify_ich;
|
||||
|
||||
pub struct DepGraph<D: Deps> {
|
||||
data: Option<Arc<DepGraphData<D>>>,
|
||||
#[derive(Clone)]
|
||||
pub struct DepGraph {
|
||||
data: Option<Arc<DepGraphData>>,
|
||||
|
||||
/// This field is used for assigning DepNodeIndices when running in
|
||||
/// non-incremental mode. Even in non-incremental mode we make sure that
|
||||
|
|
@ -40,17 +41,6 @@ pub struct DepGraph<D: Deps> {
|
|||
virtual_dep_node_index: Arc<AtomicU32>,
|
||||
}
|
||||
|
||||
/// Manual clone impl that does not require `D: Clone`.
|
||||
impl<D: Deps> Clone for DepGraph<D> {
|
||||
fn clone(&self) -> Self {
|
||||
let Self { data, virtual_dep_node_index } = self;
|
||||
Self {
|
||||
data: Option::<Arc<_>>::clone(data),
|
||||
virtual_dep_node_index: Arc::clone(virtual_dep_node_index),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
pub struct DepNodeIndex {}
|
||||
}
|
||||
|
|
@ -72,7 +62,7 @@ impl From<DepNodeIndex> for QueryInvocationId {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct MarkFrame<'a> {
|
||||
pub(crate) struct MarkFrame<'a> {
|
||||
index: SerializedDepNodeIndex,
|
||||
parent: Option<&'a MarkFrame<'a>>,
|
||||
}
|
||||
|
|
@ -84,12 +74,12 @@ pub(super) enum DepNodeColor {
|
|||
Unknown,
|
||||
}
|
||||
|
||||
pub struct DepGraphData<D: Deps> {
|
||||
pub struct DepGraphData {
|
||||
/// The new encoding of the dependency graph, optimized for red/green
|
||||
/// tracking. The `current` field is the dependency graph of only the
|
||||
/// current compilation session: We don't merge the previous dep-graph into
|
||||
/// current one anymore, but we do reference shared data to save space.
|
||||
current: CurrentDepGraph<D>,
|
||||
current: CurrentDepGraph,
|
||||
|
||||
/// The dep-graph from the previous compilation session. It contains all
|
||||
/// nodes and edges as well as all fingerprints of nodes that have them.
|
||||
|
|
@ -120,13 +110,13 @@ where
|
|||
stable_hasher.finish()
|
||||
}
|
||||
|
||||
impl<D: Deps> DepGraph<D> {
|
||||
impl DepGraph {
|
||||
pub fn new(
|
||||
session: &Session,
|
||||
prev_graph: Arc<SerializedDepGraph>,
|
||||
prev_work_products: WorkProductMap,
|
||||
encoder: FileEncoder,
|
||||
) -> DepGraph<D> {
|
||||
) -> DepGraph {
|
||||
let prev_graph_node_count = prev_graph.node_count();
|
||||
|
||||
let current =
|
||||
|
|
@ -136,7 +126,7 @@ impl<D: Deps> DepGraph<D> {
|
|||
|
||||
// Instantiate a node with zero dependencies only once for anonymous queries.
|
||||
let _green_node_index = current.alloc_new_node(
|
||||
DepNode { kind: D::DEP_KIND_ANON_ZERO_DEPS, hash: current.anon_id_seed.into() },
|
||||
DepNode { kind: DepKind::ANON_ZERO_DEPS, hash: current.anon_id_seed.into() },
|
||||
EdgesVec::new(),
|
||||
Fingerprint::ZERO,
|
||||
);
|
||||
|
|
@ -144,7 +134,7 @@ impl<D: Deps> DepGraph<D> {
|
|||
|
||||
// Instantiate a dependy-less red node only once for anonymous queries.
|
||||
let red_node_index = current.alloc_new_node(
|
||||
DepNode { kind: D::DEP_KIND_RED, hash: Fingerprint::ZERO.into() },
|
||||
DepNode { kind: DepKind::RED, hash: Fingerprint::ZERO.into() },
|
||||
EdgesVec::new(),
|
||||
Fingerprint::ZERO,
|
||||
);
|
||||
|
|
@ -168,12 +158,12 @@ impl<D: Deps> DepGraph<D> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_disabled() -> DepGraph<D> {
|
||||
pub fn new_disabled() -> DepGraph {
|
||||
DepGraph { data: None, virtual_dep_node_index: Arc::new(AtomicU32::new(0)) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn data(&self) -> Option<&DepGraphData<D>> {
|
||||
pub fn data(&self) -> Option<&DepGraphData> {
|
||||
self.data.as_deref()
|
||||
}
|
||||
|
||||
|
|
@ -191,7 +181,7 @@ impl<D: Deps> DepGraph<D> {
|
|||
|
||||
pub fn assert_ignored(&self) {
|
||||
if let Some(..) = self.data {
|
||||
D::read_deps(|task_deps| {
|
||||
read_deps(|task_deps| {
|
||||
assert_matches!(
|
||||
task_deps,
|
||||
TaskDepsRef::Ignore,
|
||||
|
|
@ -205,7 +195,7 @@ impl<D: Deps> DepGraph<D> {
|
|||
where
|
||||
OP: FnOnce() -> R,
|
||||
{
|
||||
D::with_deps(TaskDepsRef::Ignore, op)
|
||||
with_deps(TaskDepsRef::Ignore, op)
|
||||
}
|
||||
|
||||
/// Used to wrap the deserialization of a query result from disk,
|
||||
|
|
@ -258,11 +248,11 @@ impl<D: Deps> DepGraph<D> {
|
|||
where
|
||||
OP: FnOnce() -> R,
|
||||
{
|
||||
D::with_deps(TaskDepsRef::Forbid, op)
|
||||
with_deps(TaskDepsRef::Forbid, op)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn with_task<Ctxt: HasDepContext<Deps = D>, A: Debug, R>(
|
||||
pub fn with_task<'tcx, Ctxt: HasDepContext<'tcx>, A: Debug, R>(
|
||||
&self,
|
||||
key: DepNode,
|
||||
cx: Ctxt,
|
||||
|
|
@ -276,9 +266,9 @@ impl<D: Deps> DepGraph<D> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn with_anon_task<Tcx: DepContext<Deps = D>, OP, R>(
|
||||
pub fn with_anon_task<'tcx, OP, R>(
|
||||
&self,
|
||||
cx: Tcx,
|
||||
cx: TyCtxt<'tcx>,
|
||||
dep_kind: DepKind,
|
||||
op: OP,
|
||||
) -> (R, DepNodeIndex)
|
||||
|
|
@ -296,7 +286,7 @@ impl<D: Deps> DepGraph<D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: Deps> DepGraphData<D> {
|
||||
impl DepGraphData {
|
||||
/// Starts a new dep-graph task. Dep-graph tasks are specified
|
||||
/// using a free function (`task`) and **not** a closure -- this
|
||||
/// is intentional because we want to exercise tight control over
|
||||
|
|
@ -325,7 +315,7 @@ impl<D: Deps> DepGraphData<D> {
|
|||
///
|
||||
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/queries/incremental-compilation.html
|
||||
#[inline(always)]
|
||||
pub fn with_task<Ctxt: HasDepContext<Deps = D>, A: Debug, R>(
|
||||
pub fn with_task<'tcx, Ctxt: HasDepContext<'tcx>, A: Debug, R>(
|
||||
&self,
|
||||
key: DepNode,
|
||||
cx: Ctxt,
|
||||
|
|
@ -339,7 +329,7 @@ impl<D: Deps> DepGraphData<D> {
|
|||
// 2. Two distinct query keys get mapped to the same `DepNode`
|
||||
// (see for example #48923).
|
||||
self.assert_dep_node_not_yet_allocated_in_current_session(
|
||||
cx.dep_context().sess(),
|
||||
cx.dep_context().sess,
|
||||
&key,
|
||||
|| {
|
||||
format!(
|
||||
|
|
@ -350,7 +340,7 @@ impl<D: Deps> DepGraphData<D> {
|
|||
},
|
||||
);
|
||||
|
||||
let with_deps = |task_deps| D::with_deps(task_deps, || task(cx, arg));
|
||||
let with_deps = |task_deps| with_deps(task_deps, || task(cx, arg));
|
||||
let (result, edges) = if cx.dep_context().is_eval_always(key.kind) {
|
||||
(with_deps(TaskDepsRef::EvalAlways), EdgesVec::new())
|
||||
} else {
|
||||
|
|
@ -362,8 +352,8 @@ impl<D: Deps> DepGraphData<D> {
|
|||
(with_deps(TaskDepsRef::Allow(&task_deps)), task_deps.into_inner().reads)
|
||||
};
|
||||
|
||||
let dcx = cx.dep_context();
|
||||
let dep_node_index = self.hash_result_and_alloc_node(dcx, key, edges, &result, hash_result);
|
||||
let dep_node_index =
|
||||
self.hash_result_and_alloc_node(cx.dep_context(), key, edges, &result, hash_result);
|
||||
|
||||
(result, dep_node_index)
|
||||
}
|
||||
|
|
@ -379,9 +369,9 @@ impl<D: Deps> DepGraphData<D> {
|
|||
/// FIXME: This could perhaps return a `WithDepNode` to ensure that the
|
||||
/// user of this function actually performs the read; we'll have to see
|
||||
/// how to make that work with `anon` in `execute_job_incr`, though.
|
||||
pub fn with_anon_task_inner<Tcx: DepContext<Deps = D>, OP, R>(
|
||||
pub fn with_anon_task_inner<'tcx, OP, R>(
|
||||
&self,
|
||||
cx: Tcx,
|
||||
cx: TyCtxt<'tcx>,
|
||||
dep_kind: DepKind,
|
||||
op: OP,
|
||||
) -> (R, DepNodeIndex)
|
||||
|
|
@ -397,7 +387,7 @@ impl<D: Deps> DepGraphData<D> {
|
|||
None,
|
||||
128,
|
||||
));
|
||||
let result = D::with_deps(TaskDepsRef::Allow(&task_deps), op);
|
||||
let result = with_deps(TaskDepsRef::Allow(&task_deps), op);
|
||||
let task_deps = task_deps.into_inner();
|
||||
let reads = task_deps.reads;
|
||||
|
||||
|
|
@ -448,17 +438,17 @@ impl<D: Deps> DepGraphData<D> {
|
|||
}
|
||||
|
||||
/// Intern the new `DepNode` with the dependencies up-to-now.
|
||||
fn hash_result_and_alloc_node<Ctxt: DepContext<Deps = D>, R>(
|
||||
fn hash_result_and_alloc_node<'tcx, R>(
|
||||
&self,
|
||||
cx: &Ctxt,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
node: DepNode,
|
||||
edges: EdgesVec,
|
||||
result: &R,
|
||||
hash_result: Option<fn(&mut StableHashingContext<'_>, &R) -> Fingerprint>,
|
||||
) -> DepNodeIndex {
|
||||
let hashing_timer = cx.profiler().incr_result_hashing();
|
||||
let hashing_timer = tcx.prof.incr_result_hashing();
|
||||
let current_fingerprint = hash_result.map(|hash_result| {
|
||||
cx.with_stable_hashing_context(|mut hcx| hash_result(&mut hcx, result))
|
||||
tcx.with_stable_hashing_context(|mut hcx| hash_result(&mut hcx, result))
|
||||
});
|
||||
let dep_node_index = self.alloc_and_color_node(node, edges, current_fingerprint);
|
||||
hashing_timer.finish_with_query_invocation_id(dep_node_index.into());
|
||||
|
|
@ -466,11 +456,11 @@ impl<D: Deps> DepGraphData<D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: Deps> DepGraph<D> {
|
||||
impl DepGraph {
|
||||
#[inline]
|
||||
pub fn read_index(&self, dep_node_index: DepNodeIndex) {
|
||||
if let Some(ref data) = self.data {
|
||||
D::read_deps(|task_deps| {
|
||||
read_deps(|task_deps| {
|
||||
let mut task_deps = match task_deps {
|
||||
TaskDepsRef::Allow(deps) => deps.lock(),
|
||||
TaskDepsRef::EvalAlways => {
|
||||
|
|
@ -525,16 +515,12 @@ impl<D: Deps> DepGraph<D> {
|
|||
/// This encodes a diagnostic by creating a node with an unique index and associating
|
||||
/// `diagnostic` with it, for use in the next session.
|
||||
#[inline]
|
||||
pub fn record_diagnostic<'tcx, Qcx: QueryContext<'tcx>>(
|
||||
&self,
|
||||
qcx: Qcx,
|
||||
diagnostic: &DiagInner,
|
||||
) {
|
||||
pub fn record_diagnostic<'tcx>(&self, tcx: TyCtxt<'tcx>, diagnostic: &DiagInner) {
|
||||
if let Some(ref data) = self.data {
|
||||
D::read_deps(|task_deps| match task_deps {
|
||||
read_deps(|task_deps| match task_deps {
|
||||
TaskDepsRef::EvalAlways | TaskDepsRef::Ignore => return,
|
||||
TaskDepsRef::Forbid | TaskDepsRef::Allow(..) => {
|
||||
self.read_index(data.encode_diagnostic(qcx, diagnostic));
|
||||
self.read_index(data.encode_diagnostic(tcx, diagnostic));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -542,13 +528,13 @@ impl<D: Deps> DepGraph<D> {
|
|||
/// This forces a diagnostic node green by running its side effect. `prev_index` would
|
||||
/// refer to a node created used `encode_diagnostic` in the previous session.
|
||||
#[inline]
|
||||
pub fn force_diagnostic_node<'tcx, Qcx: QueryContext<'tcx>>(
|
||||
pub fn force_diagnostic_node<'tcx>(
|
||||
&self,
|
||||
qcx: Qcx,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
prev_index: SerializedDepNodeIndex,
|
||||
) {
|
||||
if let Some(ref data) = self.data {
|
||||
data.force_diagnostic_node(qcx, prev_index);
|
||||
data.force_diagnostic_node(tcx, prev_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -567,10 +553,10 @@ impl<D: Deps> DepGraph<D> {
|
|||
/// FIXME: If the code is changed enough for this node to be marked before requiring the
|
||||
/// caller's node, we suppose that those changes will be enough to mark this node red and
|
||||
/// force a recomputation using the "normal" way.
|
||||
pub fn with_feed_task<Ctxt: DepContext<Deps = D>, R>(
|
||||
pub fn with_feed_task<'tcx, R>(
|
||||
&self,
|
||||
node: DepNode,
|
||||
cx: Ctxt,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
result: &R,
|
||||
hash_result: Option<fn(&mut StableHashingContext<'_>, &R) -> Fingerprint>,
|
||||
format_value_fn: fn(&R) -> String,
|
||||
|
|
@ -586,7 +572,7 @@ impl<D: Deps> DepGraph<D> {
|
|||
let dep_node_index = data.colors.current(prev_index);
|
||||
if let Some(dep_node_index) = dep_node_index {
|
||||
incremental_verify_ich(
|
||||
cx,
|
||||
tcx,
|
||||
data,
|
||||
result,
|
||||
prev_index,
|
||||
|
|
@ -608,7 +594,7 @@ impl<D: Deps> DepGraph<D> {
|
|||
}
|
||||
|
||||
let mut edges = EdgesVec::new();
|
||||
D::read_deps(|task_deps| match task_deps {
|
||||
read_deps(|task_deps| match task_deps {
|
||||
TaskDepsRef::Allow(deps) => edges.extend(deps.lock().reads.iter().copied()),
|
||||
TaskDepsRef::EvalAlways => {
|
||||
edges.push(DepNodeIndex::FOREVER_RED_NODE);
|
||||
|
|
@ -619,7 +605,7 @@ impl<D: Deps> DepGraph<D> {
|
|||
}
|
||||
});
|
||||
|
||||
data.hash_result_and_alloc_node(&cx, node, edges, result, hash_result)
|
||||
data.hash_result_and_alloc_node(tcx, node, edges, result, hash_result)
|
||||
} else {
|
||||
// Incremental compilation is turned off. We just execute the task
|
||||
// without tracking. We still provide a dep-node index that uniquely
|
||||
|
|
@ -630,7 +616,7 @@ impl<D: Deps> DepGraph<D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: Deps> DepGraphData<D> {
|
||||
impl DepGraphData {
|
||||
fn assert_dep_node_not_yet_allocated_in_current_session<S: std::fmt::Display>(
|
||||
&self,
|
||||
sess: &Session,
|
||||
|
|
@ -688,15 +674,11 @@ impl<D: Deps> DepGraphData<D> {
|
|||
/// This encodes a diagnostic by creating a node with an unique index and associating
|
||||
/// `diagnostic` with it, for use in the next session.
|
||||
#[inline]
|
||||
fn encode_diagnostic<'tcx, Qcx: QueryContext<'tcx>>(
|
||||
&self,
|
||||
qcx: Qcx,
|
||||
diagnostic: &DiagInner,
|
||||
) -> DepNodeIndex {
|
||||
fn encode_diagnostic<'tcx>(&self, tcx: TyCtxt<'tcx>, diagnostic: &DiagInner) -> DepNodeIndex {
|
||||
// Use `send_new` so we get an unique index, even though the dep node is not.
|
||||
let dep_node_index = self.current.encoder.send_new(
|
||||
DepNode {
|
||||
kind: D::DEP_KIND_SIDE_EFFECT,
|
||||
kind: DepKind::SIDE_EFFECT,
|
||||
hash: PackedFingerprint::from(Fingerprint::ZERO),
|
||||
},
|
||||
Fingerprint::ZERO,
|
||||
|
|
@ -705,24 +687,20 @@ impl<D: Deps> DepGraphData<D> {
|
|||
std::iter::once(DepNodeIndex::FOREVER_RED_NODE).collect(),
|
||||
);
|
||||
let side_effect = QuerySideEffect::Diagnostic(diagnostic.clone());
|
||||
qcx.store_side_effect(dep_node_index, side_effect);
|
||||
tcx.store_side_effect(dep_node_index, side_effect);
|
||||
dep_node_index
|
||||
}
|
||||
|
||||
/// This forces a diagnostic node green by running its side effect. `prev_index` would
|
||||
/// refer to a node created used `encode_diagnostic` in the previous session.
|
||||
#[inline]
|
||||
fn force_diagnostic_node<'tcx, Qcx: QueryContext<'tcx>>(
|
||||
&self,
|
||||
qcx: Qcx,
|
||||
prev_index: SerializedDepNodeIndex,
|
||||
) {
|
||||
D::with_deps(TaskDepsRef::Ignore, || {
|
||||
let side_effect = qcx.load_side_effect(prev_index).unwrap();
|
||||
fn force_diagnostic_node<'tcx>(&self, tcx: TyCtxt<'tcx>, prev_index: SerializedDepNodeIndex) {
|
||||
with_deps(TaskDepsRef::Ignore, || {
|
||||
let side_effect = tcx.load_side_effect(prev_index).unwrap();
|
||||
|
||||
match &side_effect {
|
||||
QuerySideEffect::Diagnostic(diagnostic) => {
|
||||
qcx.dep_context().sess().dcx().emit_diagnostic(diagnostic.clone());
|
||||
tcx.dcx().emit_diagnostic(diagnostic.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -733,7 +711,7 @@ impl<D: Deps> DepGraphData<D> {
|
|||
prev_index,
|
||||
&self.colors,
|
||||
DepNode {
|
||||
kind: D::DEP_KIND_SIDE_EFFECT,
|
||||
kind: DepKind::SIDE_EFFECT,
|
||||
hash: PackedFingerprint::from(Fingerprint::ZERO),
|
||||
},
|
||||
Fingerprint::ZERO,
|
||||
|
|
@ -741,7 +719,7 @@ impl<D: Deps> DepGraphData<D> {
|
|||
true,
|
||||
);
|
||||
// This will just overwrite the same value for concurrent calls.
|
||||
qcx.store_side_effect(dep_node_index, side_effect);
|
||||
tcx.store_side_effect(dep_node_index, side_effect);
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -811,7 +789,7 @@ impl<D: Deps> DepGraphData<D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: Deps> DepGraph<D> {
|
||||
impl DepGraph {
|
||||
/// Checks whether a previous work product exists for `v` and, if
|
||||
/// so, return the path that leads to it. Used to skip doing work.
|
||||
pub fn previous_work_product(&self, v: &WorkProductId) -> Option<WorkProduct> {
|
||||
|
|
@ -867,27 +845,27 @@ impl<D: Deps> DepGraph<D> {
|
|||
DepNodeColor::Unknown
|
||||
}
|
||||
|
||||
pub fn try_mark_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
|
||||
pub fn try_mark_green<'tcx>(
|
||||
&self,
|
||||
qcx: Qcx,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
dep_node: &DepNode,
|
||||
) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> {
|
||||
self.data().and_then(|data| data.try_mark_green(qcx, dep_node))
|
||||
self.data().and_then(|data| data.try_mark_green(tcx, dep_node))
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Deps> DepGraphData<D> {
|
||||
impl DepGraphData {
|
||||
/// Try to mark a node index for the node dep_node.
|
||||
///
|
||||
/// A node will have an index, when it's already been marked green, or when we can mark it
|
||||
/// green. This function will mark the current task as a reader of the specified node, when
|
||||
/// a node index can be found for that node.
|
||||
pub fn try_mark_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
|
||||
pub fn try_mark_green<'tcx>(
|
||||
&self,
|
||||
qcx: Qcx,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
dep_node: &DepNode,
|
||||
) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> {
|
||||
debug_assert!(!qcx.dep_context().is_eval_always(dep_node.kind));
|
||||
debug_assert!(!tcx.is_eval_always(dep_node.kind));
|
||||
|
||||
// Return None if the dep node didn't exist in the previous session
|
||||
let prev_index = self.previous.node_to_index_opt(dep_node)?;
|
||||
|
|
@ -902,16 +880,16 @@ impl<D: Deps> DepGraphData<D> {
|
|||
// in the previous compilation session too, so we can try to
|
||||
// mark it as green by recursively marking all of its
|
||||
// dependencies green.
|
||||
self.try_mark_previous_green(qcx, prev_index, None)
|
||||
self.try_mark_previous_green(tcx, prev_index, None)
|
||||
.map(|dep_node_index| (prev_index, dep_node_index))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self, qcx, parent_dep_node_index, frame), level = "debug")]
|
||||
fn try_mark_parent_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
|
||||
#[instrument(skip(self, tcx, parent_dep_node_index, frame), level = "debug")]
|
||||
fn try_mark_parent_green<'tcx>(
|
||||
&self,
|
||||
qcx: Qcx,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
parent_dep_node_index: SerializedDepNodeIndex,
|
||||
frame: &MarkFrame<'_>,
|
||||
) -> Option<()> {
|
||||
|
|
@ -944,13 +922,13 @@ impl<D: Deps> DepGraphData<D> {
|
|||
|
||||
// We don't know the state of this dependency. If it isn't
|
||||
// an eval_always node, let's try to mark it green recursively.
|
||||
if !qcx.dep_context().is_eval_always(dep_dep_node.kind) {
|
||||
if !tcx.is_eval_always(dep_dep_node.kind) {
|
||||
debug!(
|
||||
"state of dependency {:?} ({}) is unknown, trying to mark it green",
|
||||
dep_dep_node, dep_dep_node.hash,
|
||||
);
|
||||
|
||||
let node_index = self.try_mark_previous_green(qcx, parent_dep_node_index, Some(frame));
|
||||
let node_index = self.try_mark_previous_green(tcx, parent_dep_node_index, Some(frame));
|
||||
|
||||
if node_index.is_some() {
|
||||
debug!("managed to MARK dependency {dep_dep_node:?} as green");
|
||||
|
|
@ -960,7 +938,7 @@ impl<D: Deps> DepGraphData<D> {
|
|||
|
||||
// We failed to mark it green, so we try to force the query.
|
||||
debug!("trying to force dependency {dep_dep_node:?}");
|
||||
if !qcx.dep_context().try_force_from_dep_node(*dep_dep_node, parent_dep_node_index, frame) {
|
||||
if !tcx.dep_context().try_force_from_dep_node(*dep_dep_node, parent_dep_node_index, frame) {
|
||||
// The DepNode could not be forced.
|
||||
debug!("dependency {dep_dep_node:?} could not be forced");
|
||||
return None;
|
||||
|
|
@ -978,7 +956,7 @@ impl<D: Deps> DepGraphData<D> {
|
|||
DepNodeColor::Unknown => {}
|
||||
}
|
||||
|
||||
if let None = qcx.dep_context().sess().dcx().has_errors_or_delayed_bugs() {
|
||||
if let None = tcx.dcx().has_errors_or_delayed_bugs() {
|
||||
panic!("try_mark_previous_green() - Forcing the DepNode should have set its color")
|
||||
}
|
||||
|
||||
|
|
@ -997,10 +975,10 @@ impl<D: Deps> DepGraphData<D> {
|
|||
}
|
||||
|
||||
/// Try to mark a dep-node which existed in the previous compilation session as green.
|
||||
#[instrument(skip(self, qcx, prev_dep_node_index, frame), level = "debug")]
|
||||
fn try_mark_previous_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
|
||||
#[instrument(skip(self, tcx, prev_dep_node_index, frame), level = "debug")]
|
||||
fn try_mark_previous_green<'tcx>(
|
||||
&self,
|
||||
qcx: Qcx,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
prev_dep_node_index: SerializedDepNodeIndex,
|
||||
frame: Option<&MarkFrame<'_>>,
|
||||
) -> Option<DepNodeIndex> {
|
||||
|
|
@ -1008,14 +986,14 @@ impl<D: Deps> DepGraphData<D> {
|
|||
|
||||
// We never try to mark eval_always nodes as green
|
||||
debug_assert!(
|
||||
!qcx.dep_context()
|
||||
!tcx.dep_context()
|
||||
.is_eval_always(self.previous.index_to_node(prev_dep_node_index).kind)
|
||||
);
|
||||
|
||||
let prev_deps = self.previous.edge_targets_from(prev_dep_node_index);
|
||||
|
||||
for dep_dep_node_index in prev_deps {
|
||||
self.try_mark_parent_green(qcx, dep_dep_node_index, &frame)?;
|
||||
self.try_mark_parent_green(tcx, dep_dep_node_index, &frame)?;
|
||||
}
|
||||
|
||||
// If we got here without hitting a `return` that means that all
|
||||
|
|
@ -1041,7 +1019,7 @@ impl<D: Deps> DepGraphData<D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: Deps> DepGraph<D> {
|
||||
impl DepGraph {
|
||||
/// Returns true if the given node has been marked as red during the
|
||||
/// current compilation session. Used in various assertions
|
||||
pub fn is_red(&self, dep_node: &DepNode) -> bool {
|
||||
|
|
@ -1073,8 +1051,8 @@ impl<D: Deps> DepGraph<D> {
|
|||
///
|
||||
/// This method will only load queries that will end up in the disk cache.
|
||||
/// Other queries will not be executed.
|
||||
pub fn exec_cache_promotions<Tcx: DepContext>(&self, tcx: Tcx) {
|
||||
let _prof_timer = tcx.profiler().generic_activity("incr_comp_query_cache_promotion");
|
||||
pub fn exec_cache_promotions<'tcx>(&self, tcx: TyCtxt<'tcx>) {
|
||||
let _prof_timer = tcx.prof.generic_activity("incr_comp_query_cache_promotion");
|
||||
|
||||
let data = self.data.as_ref().unwrap();
|
||||
for prev_index in data.colors.values.indices() {
|
||||
|
|
@ -1175,8 +1153,8 @@ rustc_index::newtype_index! {
|
|||
/// `anon_node_to_index` and `data`, or `prev_index_to_index` and `data`. When
|
||||
/// manipulating both, we acquire `anon_node_to_index` or `prev_index_to_index`
|
||||
/// first, and `data` second.
|
||||
pub(super) struct CurrentDepGraph<D: Deps> {
|
||||
encoder: GraphEncoder<D>,
|
||||
pub(super) struct CurrentDepGraph {
|
||||
encoder: GraphEncoder,
|
||||
anon_node_to_index: ShardedHashMap<DepNode, DepNodeIndex>,
|
||||
|
||||
/// This is used to verify that fingerprints do not change between the creation of a node
|
||||
|
|
@ -1214,7 +1192,7 @@ pub(super) struct CurrentDepGraph<D: Deps> {
|
|||
pub(super) total_duplicate_read_count: AtomicU64,
|
||||
}
|
||||
|
||||
impl<D: Deps> CurrentDepGraph<D> {
|
||||
impl CurrentDepGraph {
|
||||
fn new(
|
||||
session: &Session,
|
||||
prev_graph_node_count: usize,
|
||||
|
|
@ -1448,7 +1426,7 @@ impl DepNodeColorMap {
|
|||
|
||||
#[inline(never)]
|
||||
#[cold]
|
||||
pub(crate) fn print_markframe_trace<D: Deps>(graph: &DepGraph<D>, frame: &MarkFrame<'_>) {
|
||||
pub(crate) fn print_markframe_trace(graph: &DepGraph, frame: &MarkFrame<'_>) {
|
||||
let data = graph.data.as_ref().unwrap();
|
||||
|
||||
eprintln!("there was a panic while trying to force a dep node");
|
||||
|
|
@ -1468,7 +1446,7 @@ pub(crate) fn print_markframe_trace<D: Deps>(graph: &DepGraph<D>, frame: &MarkFr
|
|||
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
fn panic_on_forbidden_read<D: Deps>(data: &DepGraphData<D>, dep_node_index: DepNodeIndex) -> ! {
|
||||
fn panic_on_forbidden_read(data: &DepGraphData, dep_node_index: DepNodeIndex) -> ! {
|
||||
// We have to do an expensive reverse-lookup of the DepNode that
|
||||
// corresponds to `dep_node_index`, but that's OK since we are about
|
||||
// to ICE anyway.
|
||||
|
|
@ -1508,3 +1486,30 @@ fn panic_on_forbidden_read<D: Deps>(data: &DepGraphData<D>, dep_node_index: DepN
|
|||
See <https://github.com/rust-lang/rust/pull/91919>."
|
||||
)
|
||||
}
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
/// Return whether this kind always require evaluation.
|
||||
#[inline(always)]
|
||||
fn is_eval_always(self, kind: DepKind) -> bool {
|
||||
self.dep_kind_vtable(kind).is_eval_always
|
||||
}
|
||||
|
||||
// Interactions with on_disk_cache
|
||||
fn load_side_effect(
|
||||
self,
|
||||
prev_dep_node_index: SerializedDepNodeIndex,
|
||||
) -> Option<QuerySideEffect> {
|
||||
self.query_system
|
||||
.on_disk_cache
|
||||
.as_ref()
|
||||
.and_then(|c| c.load_side_effect(self, prev_dep_node_index))
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
#[cold]
|
||||
fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect) {
|
||||
if let Some(c) = self.query_system.on_disk_cache.as_ref() {
|
||||
c.store_side_effect(dep_node_index, side_effect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
use std::panic;
|
||||
|
||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||
use rustc_data_structures::sync::DynSync;
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_session::Session;
|
||||
use tracing::instrument;
|
||||
|
||||
pub use self::dep_node::{
|
||||
DepKind, DepNode, DepNodeExt, DepNodeKey, WorkProductId, dep_kind_from_label, dep_kinds,
|
||||
DepKind, DepKindVTable, DepNode, DepNodeKey, WorkProductId, dep_kind_from_label, dep_kinds,
|
||||
label_strs,
|
||||
};
|
||||
pub use self::graph::{
|
||||
DepGraphData, DepNodeIndex, TaskDepsRef, WorkProduct, WorkProductMap, hash_result,
|
||||
DepGraph, DepGraphData, DepNodeIndex, TaskDepsRef, WorkProduct, WorkProductMap, hash_result,
|
||||
};
|
||||
use self::graph::{MarkFrame, print_markframe_trace};
|
||||
pub use self::query::DepGraphQuery;
|
||||
|
|
@ -28,125 +24,18 @@ mod graph;
|
|||
mod query;
|
||||
mod serialized;
|
||||
|
||||
pub trait DepContext: Copy {
|
||||
type Deps: Deps;
|
||||
|
||||
/// Create a hashing context for hashing new results.
|
||||
fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R;
|
||||
|
||||
/// Access the DepGraph.
|
||||
fn dep_graph(&self) -> &graph::DepGraph<Self::Deps>;
|
||||
|
||||
/// Access the profiler.
|
||||
fn profiler(&self) -> &SelfProfilerRef;
|
||||
|
||||
/// Access the compiler session.
|
||||
fn sess(&self) -> &Session;
|
||||
|
||||
fn dep_kind_vtable(&self, dep_node: DepKind) -> &dep_node::DepKindVTable<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn fingerprint_style(self, kind: DepKind) -> FingerprintStyle {
|
||||
self.dep_kind_vtable(kind).fingerprint_style
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
/// Return whether this kind always require evaluation.
|
||||
fn is_eval_always(self, kind: DepKind) -> bool {
|
||||
self.dep_kind_vtable(kind).is_eval_always
|
||||
}
|
||||
|
||||
/// Try to force a dep node to execute and see if it's green.
|
||||
///
|
||||
/// Returns true if the query has actually been forced. It is valid that a query
|
||||
/// fails to be forced, e.g. when the query key cannot be reconstructed from the
|
||||
/// dep-node or when the query kind outright does not support it.
|
||||
#[inline]
|
||||
#[instrument(skip(self, frame), level = "debug")]
|
||||
fn try_force_from_dep_node(
|
||||
self,
|
||||
dep_node: DepNode,
|
||||
prev_index: SerializedDepNodeIndex,
|
||||
frame: &MarkFrame<'_>,
|
||||
) -> bool {
|
||||
if let Some(force_fn) = self.dep_kind_vtable(dep_node.kind).force_from_dep_node {
|
||||
match panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
||||
force_fn(self, dep_node, prev_index)
|
||||
})) {
|
||||
Err(value) => {
|
||||
if !value.is::<rustc_errors::FatalErrorMarker>() {
|
||||
print_markframe_trace(self.dep_graph(), frame);
|
||||
}
|
||||
panic::resume_unwind(value)
|
||||
}
|
||||
Ok(query_has_been_forced) => query_has_been_forced,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Load data from the on-disk cache.
|
||||
fn try_load_from_on_disk_cache(self, dep_node: &DepNode) {
|
||||
if let Some(try_load_fn) = self.dep_kind_vtable(dep_node.kind).try_load_from_on_disk_cache {
|
||||
try_load_fn(self, *dep_node)
|
||||
}
|
||||
}
|
||||
|
||||
fn with_reduced_queries<T>(self, _: impl FnOnce() -> T) -> T;
|
||||
pub trait HasDepContext<'tcx>: Copy {
|
||||
fn dep_context(&self) -> TyCtxt<'tcx>;
|
||||
}
|
||||
|
||||
pub trait Deps: DynSync {
|
||||
/// Execute the operation with provided dependencies.
|
||||
fn with_deps<OP, R>(deps: TaskDepsRef<'_>, op: OP) -> R
|
||||
where
|
||||
OP: FnOnce() -> R;
|
||||
|
||||
/// Access dependencies from current implicit context.
|
||||
fn read_deps<OP>(op: OP)
|
||||
where
|
||||
OP: for<'a> FnOnce(TaskDepsRef<'a>);
|
||||
|
||||
fn name(dep_kind: DepKind) -> &'static str;
|
||||
|
||||
/// We use this for most things when incr. comp. is turned off.
|
||||
const DEP_KIND_NULL: DepKind;
|
||||
|
||||
/// We use this to create a forever-red node.
|
||||
const DEP_KIND_RED: DepKind;
|
||||
|
||||
/// We use this to create a side effect node.
|
||||
const DEP_KIND_SIDE_EFFECT: DepKind;
|
||||
|
||||
/// We use this to create the anon node with zero dependencies.
|
||||
const DEP_KIND_ANON_ZERO_DEPS: DepKind;
|
||||
|
||||
/// This is the highest value a `DepKind` can have. It's used during encoding to
|
||||
/// pack information into the unused bits.
|
||||
const DEP_KIND_MAX: u16;
|
||||
}
|
||||
|
||||
pub trait HasDepContext: Copy {
|
||||
type Deps: self::Deps;
|
||||
type DepContext: self::DepContext<Deps = Self::Deps>;
|
||||
|
||||
fn dep_context(&self) -> &Self::DepContext;
|
||||
}
|
||||
|
||||
impl<T: DepContext> HasDepContext for T {
|
||||
type Deps = T::Deps;
|
||||
type DepContext = Self;
|
||||
|
||||
fn dep_context(&self) -> &Self::DepContext {
|
||||
self
|
||||
impl<'tcx> HasDepContext<'tcx> for TyCtxt<'tcx> {
|
||||
fn dep_context(&self) -> TyCtxt<'tcx> {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HasDepContext, Q: Copy> HasDepContext for (T, Q) {
|
||||
type Deps = T::Deps;
|
||||
type DepContext = T::DepContext;
|
||||
|
||||
fn dep_context(&self) -> &Self::DepContext {
|
||||
impl<'tcx, T: HasDepContext<'tcx>, Q: Copy> HasDepContext<'tcx> for (T, Q) {
|
||||
fn dep_context(&self) -> TyCtxt<'tcx> {
|
||||
self.0.dep_context()
|
||||
}
|
||||
}
|
||||
|
|
@ -179,74 +68,77 @@ impl FingerprintStyle {
|
|||
}
|
||||
}
|
||||
|
||||
pub type DepGraph = graph::DepGraph<DepsType>;
|
||||
|
||||
pub type DepKindVTable<'tcx> = dep_node::DepKindVTable<TyCtxt<'tcx>>;
|
||||
|
||||
pub struct DepsType;
|
||||
|
||||
impl Deps for DepsType {
|
||||
fn with_deps<OP, R>(task_deps: TaskDepsRef<'_>, op: OP) -> R
|
||||
where
|
||||
OP: FnOnce() -> R,
|
||||
{
|
||||
ty::tls::with_context(|icx| {
|
||||
let icx = ty::tls::ImplicitCtxt { task_deps, ..icx.clone() };
|
||||
|
||||
ty::tls::enter_context(&icx, op)
|
||||
})
|
||||
}
|
||||
|
||||
fn read_deps<OP>(op: OP)
|
||||
where
|
||||
OP: for<'a> FnOnce(TaskDepsRef<'a>),
|
||||
{
|
||||
ty::tls::with_context_opt(|icx| {
|
||||
let Some(icx) = icx else { return };
|
||||
op(icx.task_deps)
|
||||
})
|
||||
}
|
||||
|
||||
fn name(dep_kind: DepKind) -> &'static str {
|
||||
dep_node::DEP_KIND_NAMES[dep_kind.as_usize()]
|
||||
}
|
||||
|
||||
const DEP_KIND_NULL: DepKind = dep_kinds::Null;
|
||||
const DEP_KIND_RED: DepKind = dep_kinds::Red;
|
||||
const DEP_KIND_SIDE_EFFECT: DepKind = dep_kinds::SideEffect;
|
||||
const DEP_KIND_ANON_ZERO_DEPS: DepKind = dep_kinds::AnonZeroDeps;
|
||||
const DEP_KIND_MAX: u16 = dep_node::DEP_KIND_VARIANTS - 1;
|
||||
/// Execute the operation with provided dependencies.
|
||||
fn with_deps<OP, R>(task_deps: TaskDepsRef<'_>, op: OP) -> R
|
||||
where
|
||||
OP: FnOnce() -> R,
|
||||
{
|
||||
ty::tls::with_context(|icx| {
|
||||
let icx = ty::tls::ImplicitCtxt { task_deps, ..icx.clone() };
|
||||
ty::tls::enter_context(&icx, op)
|
||||
})
|
||||
}
|
||||
|
||||
impl<'tcx> DepContext for TyCtxt<'tcx> {
|
||||
type Deps = DepsType;
|
||||
/// Access dependencies from current implicit context.
|
||||
fn read_deps<OP>(op: OP)
|
||||
where
|
||||
OP: for<'a> FnOnce(TaskDepsRef<'a>),
|
||||
{
|
||||
ty::tls::with_context_opt(|icx| {
|
||||
let Some(icx) = icx else { return };
|
||||
op(icx.task_deps)
|
||||
})
|
||||
}
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
#[inline]
|
||||
fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R {
|
||||
TyCtxt::with_stable_hashing_context(self, f)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn dep_graph(&self) -> &DepGraph {
|
||||
&self.dep_graph
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn profiler(&self) -> &SelfProfilerRef {
|
||||
&self.prof
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn sess(&self) -> &Session {
|
||||
self.sess
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn dep_kind_vtable(&self, dk: DepKind) -> &DepKindVTable<'tcx> {
|
||||
pub fn dep_kind_vtable(self, dk: DepKind) -> &'tcx DepKindVTable<'tcx> {
|
||||
&self.dep_kind_vtables[dk.as_usize()]
|
||||
}
|
||||
|
||||
fn with_reduced_queries<T>(self, f: impl FnOnce() -> T) -> T {
|
||||
with_reduced_queries!(f())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fingerprint_style(self, kind: DepKind) -> FingerprintStyle {
|
||||
self.dep_kind_vtable(kind).fingerprint_style
|
||||
}
|
||||
|
||||
/// Try to force a dep node to execute and see if it's green.
|
||||
///
|
||||
/// Returns true if the query has actually been forced. It is valid that a query
|
||||
/// fails to be forced, e.g. when the query key cannot be reconstructed from the
|
||||
/// dep-node or when the query kind outright does not support it.
|
||||
#[inline]
|
||||
#[instrument(skip(self, frame), level = "debug")]
|
||||
fn try_force_from_dep_node(
|
||||
self,
|
||||
dep_node: DepNode,
|
||||
prev_index: SerializedDepNodeIndex,
|
||||
frame: &MarkFrame<'_>,
|
||||
) -> bool {
|
||||
if let Some(force_fn) = self.dep_kind_vtable(dep_node.kind).force_from_dep_node {
|
||||
match panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
||||
force_fn(self, dep_node, prev_index)
|
||||
})) {
|
||||
Err(value) => {
|
||||
if !value.is::<rustc_errors::FatalErrorMarker>() {
|
||||
print_markframe_trace(&self.dep_graph, frame);
|
||||
}
|
||||
panic::resume_unwind(value)
|
||||
}
|
||||
Ok(query_has_been_forced) => query_has_been_forced,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Load data from the on-disk cache.
|
||||
fn try_load_from_on_disk_cache(self, dep_node: &DepNode) {
|
||||
if let Some(try_load_fn) = self.dep_kind_vtable(dep_node.kind).try_load_from_on_disk_cache {
|
||||
try_load_fn(self, *dep_node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::max;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::{iter, mem, u64};
|
||||
|
|
@ -61,7 +60,7 @@ use tracing::{debug, instrument};
|
|||
|
||||
use super::graph::{CurrentDepGraph, DepNodeColorMap};
|
||||
use super::query::DepGraphQuery;
|
||||
use super::{DepKind, DepNode, DepNodeIndex, Deps};
|
||||
use super::{DepKind, DepNode, DepNodeIndex};
|
||||
use crate::dep_graph::edges::EdgesVec;
|
||||
|
||||
// The maximum value of `SerializedDepNodeIndex` leaves the upper two bits
|
||||
|
|
@ -192,7 +191,7 @@ fn mask(bits: usize) -> usize {
|
|||
|
||||
impl SerializedDepGraph {
|
||||
#[instrument(level = "debug", skip(d))]
|
||||
pub fn decode<D: Deps>(d: &mut MemDecoder<'_>) -> Arc<SerializedDepGraph> {
|
||||
pub fn decode(d: &mut MemDecoder<'_>) -> Arc<SerializedDepGraph> {
|
||||
// The last 16 bytes are the node count and edge count.
|
||||
debug!("position: {:?}", d.position());
|
||||
|
||||
|
|
@ -213,7 +212,7 @@ impl SerializedDepGraph {
|
|||
let graph_bytes = d.len() - (3 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position();
|
||||
|
||||
let mut nodes = IndexVec::from_elem_n(
|
||||
DepNode { kind: D::DEP_KIND_NULL, hash: PackedFingerprint::from(Fingerprint::ZERO) },
|
||||
DepNode { kind: DepKind::NULL, hash: PackedFingerprint::from(Fingerprint::ZERO) },
|
||||
node_max,
|
||||
);
|
||||
let mut fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_max);
|
||||
|
|
@ -230,19 +229,18 @@ impl SerializedDepGraph {
|
|||
// least (34 byte header + 1 byte len + 64 bytes edge data), which is ~1%. A 2-byte leb128
|
||||
// length is about the same fractional overhead and it amortizes for yet greater lengths.
|
||||
let mut edge_list_data =
|
||||
Vec::with_capacity(graph_bytes - node_count * size_of::<SerializedNodeHeader<D>>());
|
||||
Vec::with_capacity(graph_bytes - node_count * size_of::<SerializedNodeHeader>());
|
||||
|
||||
for _ in 0..node_count {
|
||||
// Decode the header for this edge; the header packs together as many of the fixed-size
|
||||
// fields as possible to limit the number of times we update decoder state.
|
||||
let node_header =
|
||||
SerializedNodeHeader::<D> { bytes: d.read_array(), _marker: PhantomData };
|
||||
let node_header = SerializedNodeHeader { bytes: d.read_array() };
|
||||
|
||||
let index = node_header.index();
|
||||
|
||||
let node = &mut nodes[index];
|
||||
// Make sure there's no duplicate indices in the dep graph.
|
||||
assert!(node_header.node().kind != D::DEP_KIND_NULL && node.kind == D::DEP_KIND_NULL);
|
||||
assert!(node_header.node().kind != DepKind::NULL && node.kind == DepKind::NULL);
|
||||
*node = node_header.node();
|
||||
|
||||
fingerprints[index] = node_header.fingerprint();
|
||||
|
|
@ -270,7 +268,7 @@ impl SerializedDepGraph {
|
|||
edge_list_data.extend(&[0u8; DEP_NODE_PAD]);
|
||||
|
||||
// Read the number of each dep kind and use it to create an hash map with a suitable size.
|
||||
let mut index: Vec<_> = (0..(D::DEP_KIND_MAX + 1))
|
||||
let mut index: Vec<_> = (0..(DepKind::MAX + 1))
|
||||
.map(|_| UnhashMap::with_capacity_and_hasher(d.read_u32() as usize, Default::default()))
|
||||
.collect();
|
||||
|
||||
|
|
@ -279,8 +277,8 @@ impl SerializedDepGraph {
|
|||
for (idx, node) in nodes.iter_enumerated() {
|
||||
if index[node.kind.as_usize()].insert(node.hash, idx).is_some() {
|
||||
// Empty nodes and side effect nodes can have duplicates
|
||||
if node.kind != D::DEP_KIND_NULL && node.kind != D::DEP_KIND_SIDE_EFFECT {
|
||||
let name = D::name(node.kind);
|
||||
if node.kind != DepKind::NULL && node.kind != DepKind::SIDE_EFFECT {
|
||||
let name = node.kind.name();
|
||||
panic!(
|
||||
"Error: A dep graph node ({name}) does not have an unique index. \
|
||||
Running a clean build on a nightly compiler with `-Z incremental-verify-ich` \
|
||||
|
|
@ -310,13 +308,12 @@ impl SerializedDepGraph {
|
|||
/// * The `DepKind`'s discriminant (a u16, but not all bits are used...)
|
||||
/// * The byte width of the encoded edges for this node
|
||||
/// * In whatever bits remain, the length of the edge list for this node, if it fits
|
||||
struct SerializedNodeHeader<D> {
|
||||
struct SerializedNodeHeader {
|
||||
// 2 bytes for the DepNode
|
||||
// 4 bytes for the index
|
||||
// 16 for Fingerprint in DepNode
|
||||
// 16 for Fingerprint in NodeInfo
|
||||
bytes: [u8; 38],
|
||||
_marker: PhantomData<D>,
|
||||
}
|
||||
|
||||
// The fields of a `SerializedNodeHeader`, this struct is an implementation detail and exists only
|
||||
|
|
@ -337,11 +334,11 @@ struct Unpacked {
|
|||
// 0..M length of the edge
|
||||
// M..M+N bytes per index
|
||||
// M+N..16 kind
|
||||
impl<D: Deps> SerializedNodeHeader<D> {
|
||||
impl SerializedNodeHeader {
|
||||
const TOTAL_BITS: usize = size_of::<DepKind>() * 8;
|
||||
const LEN_BITS: usize = Self::TOTAL_BITS - Self::KIND_BITS - Self::WIDTH_BITS;
|
||||
const WIDTH_BITS: usize = DEP_NODE_WIDTH_BITS;
|
||||
const KIND_BITS: usize = Self::TOTAL_BITS - D::DEP_KIND_MAX.leading_zeros() as usize;
|
||||
const KIND_BITS: usize = Self::TOTAL_BITS - DepKind::MAX.leading_zeros() as usize;
|
||||
const MAX_INLINE_LEN: usize = (u16::MAX as usize >> (Self::TOTAL_BITS - Self::LEN_BITS)) - 1;
|
||||
|
||||
#[inline]
|
||||
|
|
@ -377,14 +374,14 @@ impl<D: Deps> SerializedNodeHeader<D> {
|
|||
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
let res = Self { bytes, _marker: PhantomData };
|
||||
let res = Self { bytes };
|
||||
assert_eq!(fingerprint, res.fingerprint());
|
||||
assert_eq!(*node, res.node());
|
||||
if let Some(len) = res.len() {
|
||||
assert_eq!(edge_count, len as usize);
|
||||
}
|
||||
}
|
||||
Self { bytes, _marker: PhantomData }
|
||||
Self { bytes }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -451,15 +448,10 @@ struct NodeInfo {
|
|||
}
|
||||
|
||||
impl NodeInfo {
|
||||
fn encode<D: Deps>(&self, e: &mut MemEncoder, index: DepNodeIndex) {
|
||||
fn encode(&self, e: &mut MemEncoder, index: DepNodeIndex) {
|
||||
let NodeInfo { ref node, fingerprint, ref edges } = *self;
|
||||
let header = SerializedNodeHeader::<D>::new(
|
||||
node,
|
||||
index,
|
||||
fingerprint,
|
||||
edges.max_index(),
|
||||
edges.len(),
|
||||
);
|
||||
let header =
|
||||
SerializedNodeHeader::new(node, index, fingerprint, edges.max_index(), edges.len());
|
||||
e.write_array(header.bytes);
|
||||
|
||||
if header.len().is_none() {
|
||||
|
|
@ -480,7 +472,7 @@ impl NodeInfo {
|
|||
/// the previous dep graph and expects all edges to already have a new dep node index assigned.
|
||||
/// This avoids the overhead of constructing `EdgesVec`, which would be needed to call `encode`.
|
||||
#[inline]
|
||||
fn encode_promoted<D: Deps>(
|
||||
fn encode_promoted(
|
||||
e: &mut MemEncoder,
|
||||
node: &DepNode,
|
||||
index: DepNodeIndex,
|
||||
|
|
@ -496,7 +488,7 @@ impl NodeInfo {
|
|||
let edge_max =
|
||||
edges.clone().map(|i| colors.current(i).unwrap().as_u32()).max().unwrap_or(0);
|
||||
|
||||
let header = SerializedNodeHeader::<D>::new(node, index, fingerprint, edge_max, edge_count);
|
||||
let header = SerializedNodeHeader::new(node, index, fingerprint, edge_max, edge_count);
|
||||
e.write_array(header.bytes);
|
||||
|
||||
if header.len().is_none() {
|
||||
|
|
@ -543,16 +535,15 @@ struct LocalEncoderResult {
|
|||
kind_stats: Vec<u32>,
|
||||
}
|
||||
|
||||
struct EncoderState<D: Deps> {
|
||||
struct EncoderState {
|
||||
next_node_index: AtomicU64,
|
||||
previous: Arc<SerializedDepGraph>,
|
||||
file: Lock<Option<FileEncoder>>,
|
||||
local: WorkerLocal<RefCell<LocalEncoderState>>,
|
||||
stats: Option<Lock<FxHashMap<DepKind, Stat>>>,
|
||||
marker: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: Deps> EncoderState<D> {
|
||||
impl EncoderState {
|
||||
fn new(encoder: FileEncoder, record_stats: bool, previous: Arc<SerializedDepGraph>) -> Self {
|
||||
Self {
|
||||
previous,
|
||||
|
|
@ -566,10 +557,9 @@ impl<D: Deps> EncoderState<D> {
|
|||
edge_count: 0,
|
||||
node_count: 0,
|
||||
encoder: MemEncoder::new(),
|
||||
kind_stats: iter::repeat_n(0, D::DEP_KIND_MAX as usize + 1).collect(),
|
||||
kind_stats: iter::repeat_n(0, DepKind::MAX as usize + 1).collect(),
|
||||
})
|
||||
}),
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -658,7 +648,7 @@ impl<D: Deps> EncoderState<D> {
|
|||
record_graph: &Option<Lock<DepGraphQuery>>,
|
||||
local: &mut LocalEncoderState,
|
||||
) {
|
||||
node.encode::<D>(&mut local.encoder, index);
|
||||
node.encode(&mut local.encoder, index);
|
||||
self.flush_mem_encoder(&mut *local);
|
||||
self.record(
|
||||
&node.node,
|
||||
|
|
@ -687,7 +677,7 @@ impl<D: Deps> EncoderState<D> {
|
|||
) {
|
||||
let node = self.previous.index_to_node(prev_index);
|
||||
let fingerprint = self.previous.fingerprint_by_index(prev_index);
|
||||
let edge_count = NodeInfo::encode_promoted::<D>(
|
||||
let edge_count = NodeInfo::encode_promoted(
|
||||
&mut local.encoder,
|
||||
node,
|
||||
index,
|
||||
|
|
@ -712,7 +702,7 @@ impl<D: Deps> EncoderState<D> {
|
|||
);
|
||||
}
|
||||
|
||||
fn finish(&self, profiler: &SelfProfilerRef, current: &CurrentDepGraph<D>) -> FileEncodeResult {
|
||||
fn finish(&self, profiler: &SelfProfilerRef, current: &CurrentDepGraph) -> FileEncodeResult {
|
||||
// Prevent more indices from being allocated.
|
||||
self.next_node_index.store(u32::MAX as u64 + 1, Ordering::SeqCst);
|
||||
|
||||
|
|
@ -735,7 +725,7 @@ impl<D: Deps> EncoderState<D> {
|
|||
|
||||
let mut encoder = self.file.lock().take().unwrap();
|
||||
|
||||
let mut kind_stats: Vec<u32> = iter::repeat_n(0, D::DEP_KIND_MAX as usize + 1).collect();
|
||||
let mut kind_stats: Vec<u32> = iter::repeat_n(0, DepKind::MAX as usize + 1).collect();
|
||||
|
||||
let mut node_max = 0;
|
||||
let mut node_count = 0;
|
||||
|
|
@ -778,7 +768,7 @@ impl<D: Deps> EncoderState<D> {
|
|||
|
||||
fn print_incremental_info(
|
||||
&self,
|
||||
current: &CurrentDepGraph<D>,
|
||||
current: &CurrentDepGraph,
|
||||
total_node_count: usize,
|
||||
total_edge_count: usize,
|
||||
) {
|
||||
|
|
@ -835,13 +825,13 @@ impl<D: Deps> EncoderState<D> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct GraphEncoder<D: Deps> {
|
||||
pub(crate) struct GraphEncoder {
|
||||
profiler: SelfProfilerRef,
|
||||
status: EncoderState<D>,
|
||||
status: EncoderState,
|
||||
record_graph: Option<Lock<DepGraphQuery>>,
|
||||
}
|
||||
|
||||
impl<D: Deps> GraphEncoder<D> {
|
||||
impl GraphEncoder {
|
||||
pub(crate) fn new(
|
||||
sess: &Session,
|
||||
encoder: FileEncoder,
|
||||
|
|
@ -945,7 +935,7 @@ impl<D: Deps> GraphEncoder<D> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn finish(&self, current: &CurrentDepGraph<D>) -> FileEncodeResult {
|
||||
pub(crate) fn finish(&self, current: &CurrentDepGraph) -> FileEncodeResult {
|
||||
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph_finish");
|
||||
|
||||
self.status.finish(&self.profiler, current)
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ pub(crate) fn query_feed<'tcx, Cache>(
|
|||
value: Cache::Value,
|
||||
) where
|
||||
Cache: QueryCache,
|
||||
Cache::Key: DepNodeKey<TyCtxt<'tcx>>,
|
||||
Cache::Key: DepNodeKey<'tcx>,
|
||||
{
|
||||
let format_value = query_vtable.format_value;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
use rustc_data_structures::jobserver::Proxy;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_query_system::query::QuerySideEffect;
|
||||
|
||||
pub use self::caches::{
|
||||
DefIdCache, DefaultCache, QueryCache, QueryCacheKey, SingleCache, VecCache,
|
||||
|
|
@ -12,7 +10,6 @@ pub use self::plumbing::{
|
|||
TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk,
|
||||
};
|
||||
pub use self::stack::{QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra};
|
||||
use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
|
||||
pub use crate::queries::Providers;
|
||||
use crate::ty::TyCtxt;
|
||||
|
||||
|
|
@ -36,18 +33,3 @@ pub fn describe_as_module(def_id: impl Into<LocalDefId>, tcx: TyCtxt<'_>) -> Str
|
|||
format!("module `{}`", tcx.def_path_str(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait QueryContext<'tcx>: HasDepContext {
|
||||
/// Gets a jobserver reference which is used to release then acquire
|
||||
/// a token while waiting on a query.
|
||||
fn jobserver_proxy(&self) -> &Proxy;
|
||||
|
||||
/// Load a side effect associated to the node in the previous session.
|
||||
fn load_side_effect(
|
||||
self,
|
||||
prev_dep_node_index: SerializedDepNodeIndex,
|
||||
) -> Option<QuerySideEffect>;
|
||||
|
||||
/// Register a side effect for the given node, for use in next session.
|
||||
fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,20 +4,19 @@ use rustc_data_structures::fingerprint::Fingerprint;
|
|||
use rustc_query_system::ich::StableHashingContext;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::dep_graph::{DepContext, DepGraphData, SerializedDepNodeIndex};
|
||||
use crate::dep_graph::{DepGraphData, SerializedDepNodeIndex};
|
||||
use crate::ty::TyCtxt;
|
||||
|
||||
#[inline]
|
||||
#[instrument(skip(tcx, dep_graph_data, result, hash_result, format_value), level = "debug")]
|
||||
pub fn incremental_verify_ich<Tcx, V>(
|
||||
tcx: Tcx,
|
||||
dep_graph_data: &DepGraphData<Tcx::Deps>,
|
||||
pub fn incremental_verify_ich<'tcx, V>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
dep_graph_data: &DepGraphData,
|
||||
result: &V,
|
||||
prev_index: SerializedDepNodeIndex,
|
||||
hash_result: Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>,
|
||||
format_value: fn(&V) -> String,
|
||||
) where
|
||||
Tcx: DepContext,
|
||||
{
|
||||
) {
|
||||
if !dep_graph_data.is_index_green(prev_index) {
|
||||
incremental_verify_ich_not_green(tcx, prev_index)
|
||||
}
|
||||
|
|
@ -35,13 +34,10 @@ pub fn incremental_verify_ich<Tcx, V>(
|
|||
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
fn incremental_verify_ich_not_green<Tcx>(tcx: Tcx, prev_index: SerializedDepNodeIndex)
|
||||
where
|
||||
Tcx: DepContext,
|
||||
{
|
||||
fn incremental_verify_ich_not_green<'tcx>(tcx: TyCtxt<'tcx>, prev_index: SerializedDepNodeIndex) {
|
||||
panic!(
|
||||
"fingerprint for green query instance not loaded from cache: {:?}",
|
||||
tcx.dep_graph().data().unwrap().prev_node_of(prev_index)
|
||||
tcx.dep_graph.data().unwrap().prev_node_of(prev_index)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -50,13 +46,11 @@ where
|
|||
// chew on (and filling up the final binary, too).
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
fn incremental_verify_ich_failed<Tcx>(
|
||||
tcx: Tcx,
|
||||
fn incremental_verify_ich_failed<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
prev_index: SerializedDepNodeIndex,
|
||||
result: &dyn Fn() -> String,
|
||||
) where
|
||||
Tcx: DepContext,
|
||||
{
|
||||
) {
|
||||
// When we emit an error message and panic, we try to debug-print the `DepNode`
|
||||
// and query result. Unfortunately, this can cause us to run additional queries,
|
||||
// which may result in another fingerprint mismatch while we're in the middle
|
||||
|
|
@ -70,16 +64,16 @@ fn incremental_verify_ich_failed<Tcx>(
|
|||
let old_in_panic = INSIDE_VERIFY_PANIC.replace(true);
|
||||
|
||||
if old_in_panic {
|
||||
tcx.sess().dcx().emit_err(crate::error::Reentrant);
|
||||
tcx.dcx().emit_err(crate::error::Reentrant);
|
||||
} else {
|
||||
let run_cmd = if let Some(crate_name) = &tcx.sess().opts.crate_name {
|
||||
let run_cmd = if let Some(crate_name) = &tcx.sess.opts.crate_name {
|
||||
format!("`cargo clean -p {crate_name}` or `cargo clean`")
|
||||
} else {
|
||||
"`cargo clean`".to_string()
|
||||
};
|
||||
|
||||
let dep_node = tcx.dep_graph().data().unwrap().prev_node_of(prev_index);
|
||||
tcx.sess().dcx().emit_err(crate::error::IncrementCompilation {
|
||||
let dep_node = tcx.dep_graph.data().unwrap().prev_node_of(prev_index);
|
||||
tcx.dcx().emit_err(crate::error::IncrementCompilation {
|
||||
run_cmd,
|
||||
dep_node: format!("{dep_node:?}"),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ rustc_hir = { path = "../rustc_hir" }
|
|||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
rustc_query_system = { path = "../rustc_query_system" }
|
||||
rustc_serialize = { path = "../rustc_serialize" }
|
||||
rustc_session = { path = "../rustc_session" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::dep_graph::{DepKindVTable, DepNodeKey, FingerprintStyle};
|
||||
use rustc_middle::query::QueryCache;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
use crate::plumbing::{force_from_dep_node_inner, try_load_from_on_disk_cache_inner};
|
||||
use crate::{QueryCtxt, QueryDispatcherUnerased, QueryFlags};
|
||||
use crate::{QueryDispatcherUnerased, QueryFlags};
|
||||
|
||||
/// [`DepKindVTable`] constructors for special dep kinds that aren't queries.
|
||||
#[expect(non_snake_case, reason = "use non-snake case to avoid collision with query names")]
|
||||
|
|
@ -45,7 +44,7 @@ mod non_query {
|
|||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: Some(|tcx, _, prev_index| {
|
||||
tcx.dep_graph.force_diagnostic_node(QueryCtxt::new(tcx), prev_index);
|
||||
tcx.dep_graph.force_diagnostic_node(tcx, prev_index);
|
||||
true
|
||||
}),
|
||||
try_load_from_on_disk_cache: None,
|
||||
|
|
@ -122,7 +121,7 @@ where
|
|||
let fingerprint_style = if is_anon {
|
||||
FingerprintStyle::Opaque
|
||||
} else {
|
||||
<Cache::Key as DepNodeKey<TyCtxt<'tcx>>>::fingerprint_style()
|
||||
<Cache::Key as DepNodeKey<'tcx>>::fingerprint_style()
|
||||
};
|
||||
|
||||
if is_anon || !fingerprint_style.reconstructible() {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use rustc_data_structures::hash_table::{Entry, HashTable};
|
|||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_data_structures::{outline, sharded, sync};
|
||||
use rustc_errors::{Diag, FatalError, StashKey};
|
||||
use rustc_middle::dep_graph::{DepGraphData, DepNodeKey, DepsType, HasDepContext};
|
||||
use rustc_middle::dep_graph::{DepGraphData, DepNodeKey, HasDepContext};
|
||||
use rustc_middle::query::{
|
||||
ActiveKeyStatus, CycleError, CycleErrorHandling, QueryCache, QueryJob, QueryJobId, QueryLatch,
|
||||
QueryMode, QueryStackDeferred, QueryStackFrame, QueryState,
|
||||
|
|
@ -14,7 +14,7 @@ use rustc_middle::ty::TyCtxt;
|
|||
use rustc_middle::verify_ich::incremental_verify_ich;
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
|
||||
use crate::dep_graph::{DepContext, DepNode, DepNodeIndex};
|
||||
use crate::dep_graph::{DepNode, DepNodeIndex};
|
||||
use crate::job::{QueryJobInfo, QueryJobMap, find_cycle_in_stack, report_cycle};
|
||||
use crate::{QueryCtxt, QueryFlags, SemiDynamicQueryDispatcher};
|
||||
|
||||
|
|
@ -438,7 +438,7 @@ fn execute_job_non_incr<'tcx, C: QueryCache, const FLAGS: QueryFlags>(
|
|||
fn execute_job_incr<'tcx, C: QueryCache, const FLAGS: QueryFlags>(
|
||||
query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>,
|
||||
qcx: QueryCtxt<'tcx>,
|
||||
dep_graph_data: &DepGraphData<DepsType>,
|
||||
dep_graph_data: &DepGraphData,
|
||||
key: C::Key,
|
||||
mut dep_node_opt: Option<DepNode>,
|
||||
job_id: QueryJobId,
|
||||
|
|
@ -487,7 +487,7 @@ fn execute_job_incr<'tcx, C: QueryCache, const FLAGS: QueryFlags>(
|
|||
#[inline(always)]
|
||||
fn try_load_from_disk_and_cache_in_memory<'tcx, C: QueryCache, const FLAGS: QueryFlags>(
|
||||
query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>,
|
||||
dep_graph_data: &DepGraphData<DepsType>,
|
||||
dep_graph_data: &DepGraphData,
|
||||
qcx: QueryCtxt<'tcx>,
|
||||
key: &C::Key,
|
||||
dep_node: &DepNode,
|
||||
|
|
@ -495,7 +495,7 @@ fn try_load_from_disk_and_cache_in_memory<'tcx, C: QueryCache, const FLAGS: Quer
|
|||
// Note this function can be called concurrently from the same query
|
||||
// We must ensure that this is handled correctly.
|
||||
|
||||
let (prev_dep_node_index, dep_node_index) = dep_graph_data.try_mark_green(qcx, dep_node)?;
|
||||
let (prev_dep_node_index, dep_node_index) = dep_graph_data.try_mark_green(qcx.tcx, dep_node)?;
|
||||
|
||||
debug_assert!(dep_graph_data.is_index_green(prev_dep_node_index));
|
||||
|
||||
|
|
@ -535,7 +535,7 @@ fn try_load_from_disk_and_cache_in_memory<'tcx, C: QueryCache, const FLAGS: Quer
|
|||
// can be forced from `DepNode`.
|
||||
debug_assert!(
|
||||
!query.will_cache_on_disk_for_key(qcx.tcx, key)
|
||||
|| !qcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(),
|
||||
|| !qcx.tcx.fingerprint_style(dep_node.kind).reconstructible(),
|
||||
"missing on-disk cache entry for {dep_node:?}"
|
||||
);
|
||||
|
||||
|
|
@ -602,7 +602,7 @@ fn ensure_must_run<'tcx, C: QueryCache, const FLAGS: QueryFlags>(
|
|||
let dep_node = query.construct_dep_node(qcx.tcx, key);
|
||||
|
||||
let dep_graph = &qcx.tcx.dep_graph;
|
||||
let serialized_dep_node_index = match dep_graph.try_mark_green(qcx, &dep_node) {
|
||||
let serialized_dep_node_index = match dep_graph.try_mark_green(qcx.tcx, &dep_node) {
|
||||
None => {
|
||||
// A None return from `try_mark_green` means that this is either
|
||||
// a new dep node or that the dep node has already been marked red.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ use rustc_session::Session;
|
|||
use rustc_span::{DUMMY_SP, Span};
|
||||
|
||||
use crate::QueryCtxt;
|
||||
use crate::dep_graph::DepContext;
|
||||
|
||||
/// Map from query job IDs to job information collected by
|
||||
/// `collect_active_jobs_from_all_queries`.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
use std::num::NonZero;
|
||||
|
||||
use rustc_data_structures::jobserver::Proxy;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::sync::{DynSend, DynSync};
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
|
|
@ -16,22 +15,19 @@ use rustc_middle::bug;
|
|||
#[expect(unused_imports, reason = "used by doc comments")]
|
||||
use rustc_middle::dep_graph::DepKindVTable;
|
||||
use rustc_middle::dep_graph::{
|
||||
self, DepContext, DepNode, DepNodeIndex, DepNodeKey, DepsType, HasDepContext,
|
||||
SerializedDepNodeIndex, dep_kinds,
|
||||
self, DepNode, DepNodeIndex, DepNodeKey, HasDepContext, SerializedDepNodeIndex, dep_kinds,
|
||||
};
|
||||
use rustc_middle::query::on_disk_cache::{
|
||||
AbsoluteBytePos, CacheDecoder, CacheEncoder, EncodedDepNodeIndex,
|
||||
};
|
||||
use rustc_middle::query::plumbing::QueryVTable;
|
||||
use rustc_middle::query::{
|
||||
Key, QueryCache, QueryContext, QueryJobId, QueryStackDeferred, QueryStackFrame,
|
||||
QueryStackFrameExtra,
|
||||
Key, QueryCache, QueryJobId, QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra,
|
||||
};
|
||||
use rustc_middle::ty::codec::TyEncoder;
|
||||
use rustc_middle::ty::print::with_reduced_queries;
|
||||
use rustc_middle::ty::tls::{self, ImplicitCtxt};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_query_system::query::QuerySideEffect;
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
|
||||
|
|
@ -40,8 +36,6 @@ use crate::execution::{all_inactive, force_query};
|
|||
use crate::job::{QueryJobMap, find_dep_kind_root};
|
||||
use crate::{QueryDispatcherUnerased, QueryFlags, SemiDynamicQueryDispatcher};
|
||||
|
||||
/// Implements [`QueryContext`] for use by [`rustc_query_system`], since that
|
||||
/// crate does not have direct access to [`TyCtxt`].
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct QueryCtxt<'tcx> {
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
|
|
@ -146,45 +140,15 @@ impl<'tcx> QueryCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasDepContext for QueryCtxt<'tcx> {
|
||||
type Deps = DepsType;
|
||||
type DepContext = TyCtxt<'tcx>;
|
||||
|
||||
impl<'tcx> HasDepContext<'tcx> for QueryCtxt<'tcx> {
|
||||
#[inline]
|
||||
fn dep_context(&self) -> &Self::DepContext {
|
||||
&self.tcx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryContext<'tcx> for QueryCtxt<'tcx> {
|
||||
#[inline]
|
||||
fn jobserver_proxy(&self) -> &Proxy {
|
||||
&self.tcx.jobserver_proxy
|
||||
}
|
||||
|
||||
// Interactions with on_disk_cache
|
||||
fn load_side_effect(
|
||||
self,
|
||||
prev_dep_node_index: SerializedDepNodeIndex,
|
||||
) -> Option<QuerySideEffect> {
|
||||
fn dep_context(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
.query_system
|
||||
.on_disk_cache
|
||||
.as_ref()
|
||||
.and_then(|c| c.load_side_effect(self.tcx, prev_dep_node_index))
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
#[cold]
|
||||
fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect) {
|
||||
if let Some(c) = self.tcx.query_system.on_disk_cache.as_ref() {
|
||||
c.store_side_effect(dep_node_index, side_effect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn try_mark_green<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool {
|
||||
tcx.dep_graph.try_mark_green(QueryCtxt::new(tcx), dep_node).is_some()
|
||||
tcx.dep_graph.try_mark_green(tcx, dep_node).is_some()
|
||||
}
|
||||
|
||||
pub(super) fn encode_all_query_results<'tcx>(
|
||||
|
|
@ -198,7 +162,7 @@ pub(super) fn encode_all_query_results<'tcx>(
|
|||
}
|
||||
|
||||
pub fn query_key_hash_verify_all<'tcx>(tcx: TyCtxt<'tcx>) {
|
||||
if tcx.sess().opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions) {
|
||||
if tcx.sess.opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions) {
|
||||
tcx.sess.time("query_key_hash_verify_all", || {
|
||||
for verify in super::QUERY_KEY_HASH_VERIFY.iter() {
|
||||
verify(tcx);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ use rustc_hir::{self as hir};
|
|||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::dep_graph::DepContext;
|
||||
use rustc_middle::traits::PatternOriginExpr;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError, TypeErrorToStringExt};
|
||||
use rustc_middle::ty::print::{PrintTraitRefExt as _, WrapBinderMode, with_forced_trimmed_paths};
|
||||
|
|
@ -1837,7 +1836,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
// containing a single ASCII character, perhaps the user meant to write `b'c'` to
|
||||
// specify a byte literal
|
||||
(ty::Uint(ty::UintTy::U8), ty::Char) => {
|
||||
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
|
||||
if let Ok(code) = self.tcx.sess.source_map().span_to_snippet(span)
|
||||
&& let Some(code) = code.strip_circumfix('\'', '\'')
|
||||
// forbid all Unicode escapes
|
||||
&& !code.starts_with("\\u")
|
||||
|
|
@ -1854,7 +1853,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
// containing a single character, perhaps the user meant to write `'c'` to
|
||||
// specify a character literal (issue #92479)
|
||||
(ty::Char, ty::Ref(_, r, _)) if r.is_str() => {
|
||||
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
|
||||
if let Ok(code) = self.tcx.sess.source_map().span_to_snippet(span)
|
||||
&& let Some(code) = code.strip_circumfix('"', '"')
|
||||
&& code.chars().count() == 1
|
||||
{
|
||||
|
|
@ -1867,7 +1866,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
// If a string was expected and the found expression is a character literal,
|
||||
// perhaps the user meant to write `"s"` to specify a string literal.
|
||||
(ty::Ref(_, r, _), ty::Char) if r.is_str() => {
|
||||
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
|
||||
if let Ok(code) = self.tcx.sess.source_map().span_to_snippet(span)
|
||||
&& code.starts_with("'")
|
||||
&& code.ends_with("'")
|
||||
{
|
||||
|
|
@ -2008,7 +2007,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
return None;
|
||||
}
|
||||
|
||||
let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) else { return None };
|
||||
let Ok(code) = self.tcx.sess.source_map().span_to_snippet(span) else { return None };
|
||||
|
||||
let sugg = if code.starts_with('(') && code.ends_with(')') {
|
||||
let before_close = span.hi() - BytePos::from_u32(1);
|
||||
|
|
@ -2085,7 +2084,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
// Use the terminal width as the basis to determine when to compress the printed
|
||||
// out type, but give ourselves some leeway to avoid ending up creating a file for
|
||||
// a type that is somewhat shorter than the path we'd write to.
|
||||
let len = self.tcx.sess().diagnostic_width() + 40;
|
||||
let len = self.tcx.sess.diagnostic_width() + 40;
|
||||
let exp_s = exp.content();
|
||||
let fnd_s = fnd.content();
|
||||
if exp_s.len() > len {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue