diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5188fb8d6aada..bf45039328eb3 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -51,7 +51,6 @@ use rustc_data_structures::tagged_ptr::TaggedRef; use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle}; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId}; -use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::lints::{AttributeLint, DelayedLint, DynAttribute}; use rustc_hir::{ self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, @@ -94,7 +93,6 @@ pub mod stability; struct LoweringContext<'a, 'hir> { tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>, - current_disambiguator: PerParentDisambiguatorState, /// Used to allocate HIR nodes. arena: &'hir hir::Arena<'hir>, @@ -169,7 +167,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Self { tcx, resolver, - current_disambiguator: Default::default(), arena: tcx.hir_arena, // HirId handling. @@ -641,11 +638,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.tcx.hir_def_key(self.local_def_id(node_id)), ); - let def_id = self - .tcx - .at(span) - .create_def(parent, name, def_kind, None, &mut self.current_disambiguator) - .def_id(); + let def_id = self.tcx.at(span).create_def(parent, name, def_kind, None).def_id(); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); self.node_id_to_def_id.insert(node_id, def_id); @@ -697,16 +690,7 @@ impl<'hir> LoweringContext<'_, 'hir> { f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>, ) { let owner_id = self.owner_id(owner); - let def_id = owner_id.def_id; - let new_disambig = self - .resolver - .disambiguators - .get(&def_id) - .map(|s| s.steal()) - .unwrap_or_else(|| PerParentDisambiguatorState::new(def_id)); - - let disambiguator = std::mem::replace(&mut self.current_disambiguator, new_disambig); let current_attrs = std::mem::take(&mut self.attrs); let current_bodies = std::mem::take(&mut self.bodies); let current_define_opaque = std::mem::take(&mut self.define_opaque); @@ -741,7 +725,6 @@ impl<'hir> LoweringContext<'_, 'hir> { assert!(self.impl_trait_bounds.is_empty()); let info = self.make_owner_info(item); - self.current_disambiguator = disambiguator; self.attrs = current_attrs; self.bodies = current_bodies; self.define_opaque = current_define_opaque; diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 2f27b7e5082f2..2d14601ae5c33 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -16,7 +16,7 @@ use hir::def::DefKind; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; -use rustc_hir::definitions::{DefPathData, PerParentDisambiguatorState}; +use rustc_hir::definitions::DefPathData; use rustc_hir::{self as hir}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::interpret::{ @@ -105,7 +105,6 @@ fn intern_shallow<'tcx, M: CompileTimeMachine<'tcx>>( ecx: &mut InterpCx<'tcx, M>, alloc_id: AllocId, mutability: Mutability, - disambiguator: Option<&mut PerParentDisambiguatorState>, ) -> Result + 'tcx, InternError> { trace!("intern_shallow {:?}", alloc_id); // remove allocation @@ -124,13 +123,7 @@ fn intern_shallow<'tcx, M: CompileTimeMachine<'tcx>>( // link the alloc id to the actual allocation let alloc = ecx.tcx.mk_const_alloc(alloc); if let Some(static_id) = ecx.machine.static_def_id() { - intern_as_new_static( - ecx.tcx, - static_id, - alloc_id, - alloc, - disambiguator.expect("disambiguator needed"), - ); + intern_as_new_static(ecx.tcx, static_id, alloc_id, alloc); } else { ecx.tcx.set_alloc_id_memory(alloc_id, alloc); } @@ -144,18 +137,12 @@ fn intern_as_new_static<'tcx>( static_id: LocalDefId, alloc_id: AllocId, alloc: ConstAllocation<'tcx>, - disambiguator: &mut PerParentDisambiguatorState, ) { - // `intern_const_alloc_recursive` is called once per static and it contains the `PerParentDisambiguatorState`. - // The `::{{nested}}` path is thus unique to `intern_const_alloc_recursive` and the - // `PerParentDisambiguatorState` ensures the generated path is unique for this call as we generate - // `::{{nested#n}}` where `n` is the `n`th `intern_as_new_static` call. let feed = tcx.create_def( static_id, None, DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true }, Some(DefPathData::NestedStatic), - disambiguator, ); tcx.set_nested_alloc_id_static(alloc_id, feed.def_id()); @@ -205,10 +192,6 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx>>( intern_kind: InternKind, ret: &MPlaceTy<'tcx>, ) -> Result<(), InternError> { - let mut disambiguator = - ecx.machine.static_def_id().map(|id| PerParentDisambiguatorState::new(id)); - let mut disambiguator = disambiguator.as_mut(); - // We are interning recursively, and for mutability we are distinguishing the "root" allocation // that we are starting in, and all other allocations that we are encountering recursively. let (base_mutability, inner_mutability, is_static) = match intern_kind { @@ -246,15 +229,13 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx>>( // This gives us the initial set of nested allocations, which will then all be processed // recursively in the loop below. let mut todo: Vec<_> = if is_static { - assert!(disambiguator.is_some()); // Do not steal the root allocation, we need it later to create the return value of `eval_static_initializer`. // But still change its mutability to match the requested one. let (kind, alloc) = ecx.memory.alloc_map.get_mut(&base_alloc_id).unwrap(); prepare_alloc(*ecx.tcx, *kind, alloc, base_mutability)?; alloc.provenance().ptrs().iter().map(|&(_, prov)| prov).collect() } else { - assert!(disambiguator.is_none()); - intern_shallow(ecx, base_alloc_id, base_mutability, None)?.collect() + intern_shallow(ecx, base_alloc_id, base_mutability)?.collect() }; // We need to distinguish "has just been interned" from "was already in `tcx`", // so we track this in a separate set. @@ -336,7 +317,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx>>( // okay with losing some potential for immutability here. This can anyway only affect // `static mut`. just_interned.insert(alloc_id); - let next = intern_shallow(ecx, alloc_id, inner_mutability, disambiguator.as_deref_mut())?; + let next = intern_shallow(ecx, alloc_id, inner_mutability)?; todo.extend(next); } if found_bad_mutable_ptr { @@ -366,7 +347,7 @@ pub fn intern_const_alloc_for_constprop<'tcx, M: CompileTimeMachine<'tcx>>( return interp_ok(()); } // Move allocation to `tcx`. - if let Some(_) = intern_shallow(ecx, alloc_id, Mutability::Not, None).unwrap().next() { + if let Some(_) = intern_shallow(ecx, alloc_id, Mutability::Not).unwrap().next() { // We are not doing recursive interning, so we don't currently support provenance. // (If this assertion ever triggers, we should just implement a // proper recursive interning loop -- or just call `intern_const_alloc_recursive`. @@ -391,7 +372,7 @@ impl<'tcx> InterpCx<'tcx, DummyMachine> { let dest = self.allocate(layout, MemoryKind::Stack)?; f(self, &dest.clone().into())?; let alloc_id = dest.ptr().provenance.unwrap().alloc_id(); // this was just allocated, it must have provenance - for prov in intern_shallow(self, alloc_id, Mutability::Not, None).unwrap() { + for prov in intern_shallow(self, alloc_id, Mutability::Not).unwrap() { // We are not doing recursive interning, so we don't currently support provenance. // (If this assertion ever triggers, we should just implement a // proper recursive interning loop -- or just call `intern_const_alloc_recursive`. diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index e9801a8a5231b..d6e67e48d4708 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; use rustc_hashes::Hash64; use rustc_index::IndexVec; -use rustc_macros::{BlobDecodable, Decodable, Encodable, extension}; +use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic, extension}; use rustc_span::def_id::LocalDefIdMap; use rustc_span::{Symbol, kw, sym}; use tracing::{debug, instrument}; @@ -277,7 +277,7 @@ impl DefPath { } /// New variants should only be added in synchronization with `enum DefKind`. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, BlobDecodable)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, BlobDecodable, HashStable_Generic)] pub enum DefPathData { // Root: these should only be used for the root nodes, because // they are treated specially by the `def_path` function. diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 2aebe267dc4bc..55440ee0bbdc0 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -14,8 +14,7 @@ use rustc_ast::visit::walk_list; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::LocalDefIdMap; -use rustc_hir::definitions::{DefPathData, PerParentDisambiguatorsMap}; +use rustc_hir::definitions::DefPathData; use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt}; use rustc_hir::{ self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeKind, Node, @@ -31,7 +30,6 @@ use rustc_span::{Ident, Span, sym}; use tracing::{debug, debug_span, instrument}; use crate::errors; -use crate::hir::definitions::PerParentDisambiguatorState; #[extension(trait RegionExt)] impl ResolvedArg { @@ -66,7 +64,6 @@ impl ResolvedArg { struct BoundVarContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, rbv: &'a mut ResolveBoundVars<'tcx>, - disambiguators: &'a mut LocalDefIdMap, scope: ScopeRef<'a, 'tcx>, opaque_capture_errors: RefCell>, } @@ -261,7 +258,6 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou tcx, rbv: &mut rbv, scope: &Scope::Root { opt_parent_item: None }, - disambiguators: &mut Default::default(), opaque_capture_errors: RefCell::new(None), }; match tcx.hir_owner_node(local_def_id) { @@ -1106,12 +1102,11 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { where F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>), { - let BoundVarContext { tcx, rbv, disambiguators, .. } = self; + let BoundVarContext { tcx, rbv, .. } = self; let nested_errors = RefCell::new(self.opaque_capture_errors.borrow_mut().take()); let mut this = BoundVarContext { tcx: *tcx, rbv, - disambiguators, scope: &wrap_scope, opaque_capture_errors: nested_errors, }; @@ -1519,13 +1514,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // `opaque_def_id` is unique to the `BoundVarContext` pass which is executed once // per `resolve_bound_vars` query. This is the only location that creates // `OpaqueLifetime` paths. `::OpaqueLifetime(..)` is thus unique - // to this query and duplicates within the query are handled by `self.disambiguator`. + // to this query. let feed = self.tcx.create_def( opaque_def_id, None, DefKind::LifetimeParam, Some(DefPathData::OpaqueLifetime(ident.name)), - self.disambiguators.get_or_create(opaque_def_id), ); feed.def_span(ident.span); feed.def_ident_span(Some(ident.span)); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 9c020c35e1429..6c9e6fdd46462 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -11,7 +11,7 @@ use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo}; use rustc_data_structures::indexmap::IndexMap; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal, par_fns}; +use rustc_data_structures::sync::{WorkerLocal, par_fns}; use rustc_data_structures::thousands; use rustc_errors::DiagCallback; use rustc_errors::timings::TimingSection; @@ -19,8 +19,7 @@ use rustc_expand::base::{ExtCtxt, LintStoreExpand}; use rustc_feature::Features; use rustc_fs_util::try_canonicalize; use rustc_hir::attrs::AttributeKind; -use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap}; -use rustc_hir::definitions::Definitions; +use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId}; use rustc_hir::limit::Limit; use rustc_hir::lints::DelayedLint; use rustc_hir::{Attribute, MaybeOwner, Target, find_attr}; @@ -39,7 +38,6 @@ use rustc_passes::{abi_test, input_stats, layout_test}; use rustc_resolve::{Resolver, ResolverOutputs}; use rustc_session::Session; use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType}; -use rustc_session::cstore::Untracked; use rustc_session::output::{filename_for_input, invalid_output_for_target}; use rustc_session::parse::feature_err; use rustc_session::search_paths::PathKind; @@ -946,13 +944,7 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id); - let cstore = - FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _); - let definitions = FreezeLock::new(Definitions::new(stable_crate_id)); - - let stable_crate_ids = FreezeLock::new(StableCrateIdMap::default()); - let untracked = - Untracked { cstore, source_span: AppendOnlyIndexVec::new(), definitions, stable_crate_ids }; + let cstore = Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _; // We're constructing the HIR here; we don't care what we will // read, since we haven't even constructed the *input* to @@ -993,7 +985,7 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( stable_crate_id, &arena, &hir_arena, - untracked, + cstore, dep_graph, rustc_query_impl::make_dep_kind_vtables(&arena), rustc_query_impl::query_system( diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 16cb556c5a323..1e28427d3c4bb 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -51,7 +51,7 @@ use std::fmt; use std::hash::Hash; use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint}; -use rustc_data_structures::stable_hasher::{StableHasher, StableOrd, ToStableHashKey}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey}; use rustc_hir::def_id::DefId; use rustc_hir::definitions::DefPathHash; use rustc_macros::{Decodable, Encodable, HashStable}; @@ -59,6 +59,7 @@ use rustc_span::Symbol; use super::{KeyFingerprintStyle, SerializedDepNodeIndex}; use crate::dep_graph::DepNodeKey; +use crate::ich::StableHashingContext; use crate::mono::MonoItem; use crate::ty::{TyCtxt, tls}; @@ -152,6 +153,14 @@ impl fmt::Debug for DepNode { } } +impl HashStable> for DepNode { + fn hash_stable(&self, hcx: &mut StableHashingContext<'_>, hasher: &mut StableHasher) { + let DepNode { kind, key_fingerprint } = self; + kind.hash_stable(hcx, hasher); + Fingerprint::from(*key_fingerprint).hash_stable(hcx, hasher); + } +} + /// This struct stores function pointers and other metadata for a particular DepKind. /// /// Information is retrieved by indexing the `DEP_KINDS` array using the integer value @@ -269,7 +278,7 @@ macro_rules! define_dep_nodes { // encoding. The derived Encodable/Decodable uses leb128 encoding which is // dense when only considering this enum. But DepKind is encoded in a larger // struct, and there we can take advantage of the unused bits in the u16. - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, HashStable)] #[allow(non_camel_case_types)] #[repr(u16)] // Must be kept in sync with the rest of `DepKind`. pub enum DepKind { diff --git a/compiler/rustc_middle/src/dep_graph/graph.rs b/compiler/rustc_middle/src/dep_graph/graph.rs index 87d5ae5aaa783..a2e16940ce19f 100644 --- a/compiler/rustc_middle/src/dep_graph/graph.rs +++ b/compiler/rustc_middle/src/dep_graph/graph.rs @@ -335,11 +335,7 @@ impl DepGraphData { let (result, edges) = if tcx.is_eval_always(dep_node.kind) { (with_deps(TaskDepsRef::EvalAlways), EdgesVec::new()) } else { - let task_deps = Lock::new(TaskDeps::new( - #[cfg(debug_assertions)] - Some(dep_node), - 0, - )); + let task_deps = Lock::new(TaskDeps::new(Some(dep_node), 0)); (with_deps(TaskDepsRef::Allow(&task_deps)), task_deps.into_inner().reads) }; @@ -372,11 +368,7 @@ impl DepGraphData { // Large numbers of reads are common enough here that pre-sizing `read_set` // to 128 actually helps perf on some benchmarks. - let task_deps = Lock::new(TaskDeps::new( - #[cfg(debug_assertions)] - None, - 128, - )); + let task_deps = Lock::new(TaskDeps::new(None, 128)); let result = with_deps(TaskDepsRef::Allow(&task_deps), op); let task_deps = task_deps.into_inner(); let reads = task_deps.reads; @@ -486,7 +478,7 @@ impl DepGraph { #[cfg(debug_assertions)] { - if let Some(target) = task_deps.node + if let Some(target) = task_deps.current_dep_node && let Some(ref forbidden_edge) = data.current.forbidden_edge { let src = forbidden_edge.index_to_node.lock()[&dep_node_index]; @@ -1220,8 +1212,10 @@ pub enum TaskDepsRef<'a> { #[derive(Debug)] pub struct TaskDeps { - #[cfg(debug_assertions)] - node: Option, + current_dep_node: Option, + + /// Counter inside this query. + local_index: usize, /// A vector of `DepNodeIndex`, basically. reads: EdgesVec, @@ -1238,16 +1232,25 @@ impl TaskDeps { const LINEAR_SCAN_MAX: usize = 16; #[inline] - fn new(#[cfg(debug_assertions)] node: Option, read_set_capacity: usize) -> Self { + fn new(current_dep_node: Option, read_set_capacity: usize) -> Self { TaskDeps { - #[cfg(debug_assertions)] - node, + current_dep_node, + local_index: 0, reads: EdgesVec::new(), read_set: FxHashSet::with_capacity_and_hasher(read_set_capacity, Default::default()), } } } +impl TaskDeps { + pub fn next_query_local_index(&mut self) -> Option<(DepNode, usize)> { + let node = self.current_dep_node?; + let index = self.local_index; + self.local_index = index + 1; + Some((node, index)) + } +} + // A data structure that stores Option values as a contiguous // array, using one u32 per entry. pub(super) struct DepNodeColorMap { diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 7c6ab642b2736..34ca6f2b71c25 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -67,6 +67,7 @@ use rustc_hir::def::{DefKind, DocLinkResMap}; use rustc_hir::def_id::{ CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId, }; +use rustc_hir::definitions::DefPathData; use rustc_hir::lang_items::{LangItem, LanguageItems}; use rustc_hir::{ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, TraitCandidate}; use rustc_index::IndexVec; @@ -82,6 +83,7 @@ use rustc_span::def_id::LOCAL_CRATE; use rustc_span::{DUMMY_SP, LocalExpnId, Span, Spanned, Symbol}; use rustc_target::spec::PanicStrategy; +use crate::dep_graph::DepNode; use crate::hir::Crate; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintExpectation; @@ -198,6 +200,23 @@ rustc_queries! { desc { "getting the source span" } } + /// Create a new definition. + query create_def_raw(key: ( + LocalDefId, // parent + DefPathData, // def_path_data + DepNode, // caller query + usize, // counter of calls to `create_def_raw` by the caller query + )) -> LocalDefId { + // Accesses untracked data + eval_always + desc { + "create a new definition for `{}::{:?}`, {}th call", + tcx.def_path_str(key.0), + key.1, + key.3, + } + } + /// Represents crate as a whole (as distinct from the top-level crate module). /// /// If you call `tcx.hir_crate(())` we will have to assume that any change diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index a6ff238ad6f0b..2f54b8bcd9fa8 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -214,6 +214,7 @@ impl_erasable_for_types_with_no_type_params! { rustc_hir::OpaqueTyOrigin, rustc_hir::def::DefKind, rustc_hir::def_id::DefId, + rustc_hir::def_id::LocalDefId, rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs, rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault, rustc_middle::mir::ConstQualifs, diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index ad101cf34da3b..770cf55d9d1cc 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -7,10 +7,11 @@ use std::hash::Hash; use rustc_ast::tokenstream::TokenStream; use rustc_data_structures::stable_hasher::HashStable; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId}; +use rustc_hir::definitions::DefPathData; use rustc_hir::hir_id::OwnerId; use rustc_span::{DUMMY_SP, Ident, LocalExpnId, Span, Symbol}; -use crate::dep_graph::DepNodeIndex; +use crate::dep_graph::{DepNode, DepNodeIndex}; use crate::ich::StableHashingContext; use crate::infer::canonical::CanonicalQueryInput; use crate::mono::CollectionMode; @@ -361,3 +362,11 @@ impl<'tcx> QueryKey for (ty::Instance<'tcx>, CollectionMode) { self.0.default_span(tcx) } } + +impl QueryKey for (LocalDefId, DefPathData, DepNode, usize) { + type Cache = DefaultCache; + + fn default_span(&self, _: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index d1f82af3416b6..64044f7429b6f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -27,12 +27,17 @@ use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{ - self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal, + self, AppendOnlyIndexVec, DynSend, DynSync, FreezeLock, FreezeReadGuard, Lock, RwLock, + WorkerLocal, }; use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan}; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; -use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState}; +use rustc_hir::def_id::{ + CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap, StableCrateIdMap, +}; +use rustc_hir::definitions::{ + DefPathData, Definitions, PerParentDisambiguatorState, PerParentDisambiguatorsMap, +}; use rustc_hir::intravisit::VisitorExt; use rustc_hir::lang_items::LangItem; use rustc_hir::limit::Limit; @@ -54,7 +59,7 @@ use tracing::{debug, instrument}; use crate::arena::Arena; use crate::dep_graph::dep_node::make_metadata; -use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex}; +use crate::dep_graph::{DepGraph, DepKindVTable, DepNode, TaskDepsRef}; use crate::ich::StableHashingContext; use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind}; use crate::lint::emit_lint_base; @@ -856,6 +861,9 @@ pub struct GlobalCtxt<'tcx> { pub(crate) hooks: crate::hooks::Providers, untracked: Untracked, + /// This is shared untracked state for creating new definitions. + /// It should only be accessed by the `create_def_raw` query. + untracked_disambiguator_state: Lock>, pub query_system: QuerySystem<'tcx>, pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>], @@ -1075,7 +1083,7 @@ impl<'tcx> TyCtxt<'tcx> { stable_crate_id: StableCrateId, arena: &'tcx WorkerLocal>, hir_arena: &'tcx WorkerLocal>, - untracked: Untracked, + cstore: Box, dep_graph: DepGraph, dep_kind_vtables: &'tcx [DepKindVTable<'tcx>], query_system: QuerySystem<'tcx>, @@ -1084,6 +1092,17 @@ impl<'tcx> TyCtxt<'tcx> { jobserver_proxy: Arc, f: impl FnOnce(TyCtxt<'tcx>) -> T, ) -> T { + let cstore = FreezeLock::new(cstore); + let definitions = FreezeLock::new(Definitions::new(stable_crate_id)); + + let stable_crate_ids = FreezeLock::new(StableCrateIdMap::default()); + let untracked = Untracked { + cstore, + source_span: AppendOnlyIndexVec::new(), + definitions, + stable_crate_ids, + }; + let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| { s.dcx().emit_fatal(err); }); @@ -1106,6 +1125,7 @@ impl<'tcx> TyCtxt<'tcx> { lifetimes: common_lifetimes, consts: common_consts, untracked, + untracked_disambiguator_state: Lock::new(Default::default()), query_system, dep_kind_vtables, ty_rcache: Default::default(), @@ -1408,6 +1428,34 @@ impl<'tcx> TyCtxt<'tcx> { } } +#[instrument(level = "trace", skip(tcx), ret)] +fn create_def_raw_provider<'tcx>( + tcx: TyCtxt<'tcx>, + (parent, data, query, index): (LocalDefId, DefPathData, DepNode, usize), +) -> LocalDefId { + // `query` and `index` are guaranteed to change for each successive call to + // `create_def_raw`, but in a predictable manner. + let _ = (query, index); + + // This query is `eval_always`, so we can access untracked data. + let mut disambiguator_state = tcx.untracked_disambiguator_state.lock(); + + // The following call has the side effect of modifying the tables inside `definitions`. + // These very tables are relied on by the incr. comp. engine to decode DepNodes and to + // decode the on-disk cache. + // + // 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 `create_def`. + // As a consequence, this LocalDefId is always re-created before it is needed by the incr. + // comp. engine itself. + tcx.untracked.definitions.write().create_def( + parent, + data, + disambiguator_state.get_or_create(parent), + ) +} + impl<'tcx> TyCtxtAt<'tcx> { /// Create a new definition within the incr. comp. engine. pub fn create_def( @@ -1416,11 +1464,8 @@ impl<'tcx> TyCtxtAt<'tcx> { name: Option, def_kind: DefKind, override_def_path_data: Option, - disambiguator: &mut PerParentDisambiguatorState, ) -> TyCtxtFeed<'tcx, LocalDefId> { - let feed = - self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator); - + let feed = self.tcx.create_def(parent, name, def_kind, override_def_path_data); feed.def_span(self.span); feed } @@ -1434,28 +1479,37 @@ impl<'tcx> TyCtxt<'tcx> { name: Option, def_kind: DefKind, override_def_path_data: Option, - disambiguator: &mut PerParentDisambiguatorState, ) -> TyCtxtFeed<'tcx, LocalDefId> { let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name)); - // The following call has the side effect of modifying the tables inside `definitions`. - // These very tables are relied on by the incr. comp. engine to decode DepNodes and to - // decode the on-disk cache. - // - // 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 `create_def`. - // As a consequence, this LocalDefId is always re-created before it is needed by the incr. - // comp. engine itself. - let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator); - - // This function modifies `self.definitions` using a side-effect. - // We need to ensure that these side effects are re-run by the incr. comp. engine. - // Depending on the forever-red node will tell the graph that the calling query - // needs to be re-evaluated. - self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); + + let def_id = ty::tls::with_context(|icx| match icx.task_deps { + // `create_def_raw` is a query, so it can be replayed by the dep-graph engine. + // However, we may invoke it multiple times with the same `(parent, data)` pair, + // and we expect to create *different* definitions from them. + // + // In order to make this compatible with the general model of queries, we add + // additional information which must change at each call. + TaskDepsRef::Allow(deps) => { + let opt_dep_node_and_index = deps.lock().next_query_local_index(); + let Some((dep_node, index)) = opt_dep_node_and_index else { + // No idea how to support this for now... + bug!("trying to create a definition from an anonymous query") + }; + self.create_def_raw((parent, data, dep_node, index)) + } + + // If we are not tracking dependencies, we can use global mutable state. + TaskDepsRef::EvalAlways | TaskDepsRef::Forbid | TaskDepsRef::Ignore => { + // This query is `eval_always`, so we can access untracked data. + let mut disambiguator_state = self.untracked_disambiguator_state.lock(); + let disambiguator = disambiguator_state.get_or_create(parent); + self.untracked.definitions.write().create_def(parent, data, disambiguator) + } + }); let feed = TyCtxtFeed { tcx: self, key: def_id }; feed.def_kind(def_kind); + // Unique types created for closures participate in type privacy checking. // They have visibilities inherited from the module they are defined in. // Visibilities for opaque types are meaningless, but still provided @@ -2893,4 +2947,5 @@ pub fn provide(providers: &mut Providers) { tcx.lang_items().panic_impl().is_some_and(|did| did.is_local()) }; providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP); + providers.create_def_raw = create_def_raw_provider; } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 08356b643613a..1ef011bd0e8d4 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -40,7 +40,6 @@ use rustc_hir as hir; use rustc_hir::attrs::StrippedCfgItem; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; -use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::{LangItem, attrs as attr, find_attr}; use rustc_index::IndexVec; use rustc_index::bit_set::BitMatrix; @@ -226,8 +225,6 @@ pub struct ResolverAstLowering<'tcx> { // Information about delegations which is used when handling recursive delegations pub delegation_infos: LocalDefIdMap, - - pub disambiguators: LocalDefIdMap>, } #[derive(Debug)] diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index cfe07081ee219..a70af54446c59 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -72,7 +72,6 @@ use rustc_data_structures::steal::Steal; use rustc_data_structures::unord::UnordMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::{self as hir}; use rustc_middle::bug; use rustc_middle::hir::place::{Projection, ProjectionKind}; @@ -216,13 +215,7 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>( // This path is unique since we're in a query so we'll only be called once with `parent_def_id` // and this is the only location creating `SyntheticCoroutineBody`. - let body_def = tcx.create_def( - parent_def_id, - None, - DefKind::SyntheticCoroutineBody, - None, - &mut PerParentDisambiguatorState::new(parent_def_id), - ); + let body_def = tcx.create_def(parent_def_id, None, DefKind::SyntheticCoroutineBody, None); by_move_body.source = mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id())); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6e15f055c6aca..e76458f399022 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -57,7 +57,6 @@ use rustc_hir::def::{ PerNS, }; use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; -use rustc_hir::definitions::{PerParentDisambiguatorState, PerParentDisambiguatorsMap}; use rustc_hir::{PrimTy, TraitCandidate, find_attr}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::CStore; @@ -1424,8 +1423,6 @@ pub struct Resolver<'ra, 'tcx> { node_id_to_def_id: NodeMap, - disambiguators: LocalDefIdMap, - /// Indices of unnamed struct or variant fields with unresolved attributes. placeholder_field_indices: FxHashMap = default::fx_hash_map(), /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId` @@ -1619,10 +1616,8 @@ impl<'tcx> Resolver<'_, 'tcx> { self.tcx.definitions_untracked().def_key(self.node_id_to_def_id[&node_id]), ); - let disambiguator = self.disambiguators.get_or_create(parent); - // FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()` - let feed = self.tcx.create_def(parent, name, def_kind, None, disambiguator); + let feed = self.tcx.create_def(parent, name, def_kind, None); let def_id = feed.def_id(); // Create the definition. @@ -1805,7 +1800,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { doc_link_resolutions: Default::default(), doc_link_traits_in_scope: Default::default(), current_crate_outer_attr_insert_span, - disambiguators: Default::default(), .. }; @@ -1908,11 +1902,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Some(StrippedCfgItem { parent_scope, ident: item.ident, cfg: item.cfg }) }) .collect(); - let disambiguators = self - .disambiguators - .into_items() - .map(|(def_id, disamb)| (def_id, Steal::new(disamb))) - .collect(); let global_ctxt = ResolverGlobalCtxt { expn_that_defined, @@ -1944,7 +1933,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { lifetime_elision_allowed: self.lifetime_elision_allowed, lint_buffer: Steal::new(self.lint_buffer), delegation_infos: self.delegation_infos, - disambiguators, }; ResolverOutputs { global_ctxt, ast_lowering } } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 443f33aaa0b01..36e578e2eae34 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -1,6 +1,6 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; -use rustc_hir::definitions::{DefPathData, PerParentDisambiguatorState}; +use rustc_hir::definitions::DefPathData; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir, ConstItemRhs, ImplItemImplKind, ItemKind}; use rustc_middle::query::Providers; @@ -125,20 +125,18 @@ fn associated_item_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_> }; ty::AssocItem { kind, def_id: owner_id.to_def_id(), container } } -struct RPITVisitor<'a, 'tcx> { +struct RPITVisitor<'tcx> { tcx: TyCtxt<'tcx>, synthetics: Vec, data: DefPathData, - disambiguator: &'a mut PerParentDisambiguatorState, } -impl<'tcx> Visitor<'tcx> for RPITVisitor<'_, 'tcx> { +impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> { fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) -> Self::Result { self.synthetics.push(associated_type_for_impl_trait_in_trait( self.tcx, opaque.def_id, self.data, - &mut self.disambiguator, )); intravisit::walk_opaque_ty(self, opaque) } @@ -149,7 +147,6 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>( def_id: LocalDefId, ) -> DefIdMap> { let item = tcx.hir_expect_item(def_id); - let disambiguator = &mut PerParentDisambiguatorState::new(def_id); match item.kind { ItemKind::Trait(.., trait_item_refs) => trait_item_refs .iter() @@ -163,7 +160,7 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>( }; let def_name = tcx.item_name(fn_def_id.to_def_id()); let data = DefPathData::AnonAssocTy(def_name); - let mut visitor = RPITVisitor { tcx, synthetics: vec![], data, disambiguator }; + let mut visitor = RPITVisitor { tcx, synthetics: vec![], data }; visitor.visit_fn_ret_ty(output); let defs = visitor .synthetics @@ -197,8 +194,7 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>( return Some((did, vec![])); }; let iter = in_trait_def[&trait_item_def_id].iter().map(|&id| { - associated_type_for_impl_trait_in_impl(tcx, id, item, disambiguator) - .to_def_id() + associated_type_for_impl_trait_in_impl(tcx, id, item).to_def_id() }); Some((did, iter.collect())) }) @@ -221,7 +217,6 @@ fn associated_type_for_impl_trait_in_trait( tcx: TyCtxt<'_>, opaque_ty_def_id: LocalDefId, data: DefPathData, - disambiguator: &mut PerParentDisambiguatorState, ) -> LocalDefId { let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. }) = @@ -240,7 +235,6 @@ fn associated_type_for_impl_trait_in_trait( None, DefKind::AssocTy, Some(data), - disambiguator, ); let local_def_id = trait_assoc_ty.def_id(); @@ -283,7 +277,6 @@ fn associated_type_for_impl_trait_in_impl( tcx: TyCtxt<'_>, trait_assoc_def_id: DefId, impl_fn: &hir::ImplItem<'_>, - disambiguator: &mut PerParentDisambiguatorState, ) -> LocalDefId { let impl_local_def_id = tcx.local_parent(impl_fn.owner_id.def_id); @@ -293,12 +286,12 @@ fn associated_type_for_impl_trait_in_impl( hir::FnRetTy::Return(ty) => ty.span, }; - // Use the same disambiguator and method name as the anon associated type in the trait. + // Use the same method name as the anon associated type in the trait. let disambiguated_data = tcx.def_key(trait_assoc_def_id).disambiguated_data; - let DefPathData::AnonAssocTy(name) = disambiguated_data.data else { + let DefPathData::AnonAssocTy(method_name) = disambiguated_data.data else { bug!("expected anon associated type") }; - let data = DefPathData::AnonAssocTy(name); + let data = DefPathData::AnonAssocTy(method_name); let impl_assoc_ty = tcx.at(span).create_def( impl_local_def_id, @@ -306,7 +299,6 @@ fn associated_type_for_impl_trait_in_impl( None, DefKind::AssocTy, Some(data), - disambiguator, ); let local_def_id = impl_assoc_ty.def_id();