diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e74fd1db15b96..0a3646f6609c0 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -532,11 +532,7 @@ impl<'a, 'hir> LoweringContext<'a, '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.resolver.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.resolver.node_id_to_def_id.insert(node_id, def_id); diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index f0f958d069ee8..68e253515ef74 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -17,7 +17,7 @@ use hir::def::DefKind; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; -use rustc_hir::definitions::{DefPathData, DisambiguatorState}; +use rustc_hir::definitions::DefPathData; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::interpret::{ConstAllocation, CtfeProvenance, InterpResult}; use rustc_middle::query::TyCtxtAt; @@ -66,7 +66,6 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>( ecx: &mut InterpCx<'tcx, M>, alloc_id: AllocId, mutability: Mutability, - disambiguator: Option<&mut DisambiguatorState>, ) -> Result + 'tcx, ()> { trace!("intern_shallow {:?}", alloc_id); // remove allocation @@ -89,13 +88,7 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>( // 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); } @@ -109,18 +102,16 @@ fn intern_as_new_static<'tcx>( static_id: LocalDefId, alloc_id: AllocId, alloc: ConstAllocation<'tcx>, - disambiguator: &mut DisambiguatorState, ) { - // `intern_const_alloc_recursive` is called once per static and it contains the `DisambiguatorState`. - // The `::{{nested}}` path is thus unique to `intern_const_alloc_recursive` and the - // `DisambiguatorState` 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. + // `intern_const_alloc_recursive` is called once per static. The `::{{nested}}` path + // is thus unique to `intern_const_alloc_recursive`. If there are several calls to + // `intern_as_new_static`, `create_def` generates a path that is unique for this call as + // 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()); @@ -168,8 +159,6 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval intern_kind: InternKind, ret: &MPlaceTy<'tcx>, ) -> Result<(), InternResult> { - let mut disambiguator = DisambiguatorState::new(); - // 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 { @@ -213,9 +202,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval alloc.1.mutability = base_mutability; alloc.1.provenance().ptrs().iter().map(|&(_, prov)| prov).collect() } else { - intern_shallow(ecx, base_alloc_id, base_mutability, Some(&mut disambiguator)) - .unwrap() - .collect() + intern_shallow(ecx, base_alloc_id, base_mutability).unwrap().collect() }; // We need to distinguish "has just been interned" from "was already in `tcx`", // so we track this in a separate set. @@ -308,7 +295,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval // okay with losing some potential for immutability here. This can anyway only affect // `static mut`. just_interned.insert(alloc_id); - match intern_shallow(ecx, alloc_id, inner_mutability, Some(&mut disambiguator)) { + match intern_shallow(ecx, alloc_id, inner_mutability) { Ok(nested) => todo.extend(nested), Err(()) => { ecx.tcx.dcx().delayed_bug("found dangling pointer during const interning"); @@ -330,9 +317,8 @@ pub fn intern_const_alloc_for_constprop<'tcx, T, M: CompileTimeMachine<'tcx, T>> return interp_ok(()); } // Move allocation to `tcx`. - if let Some(_) = intern_shallow(ecx, alloc_id, Mutability::Not, None) - .map_err(|()| err_ub!(DeadLocal))? - .next() + if let Some(_) = + intern_shallow(ecx, alloc_id, Mutability::Not).map_err(|()| err_ub!(DeadLocal))?.next() { // We are not doing recursive interning, so we don't currently support provenance. // (If this assertion ever triggers, we should just implement a @@ -358,7 +344,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 f93b9e5af5345..8a496c1b367bc 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -11,7 +11,7 @@ use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::unord::UnordMap; use rustc_hashes::Hash64; use rustc_index::IndexVec; -use rustc_macros::{Decodable, Encodable}; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::{Symbol, kw, sym}; use tracing::{debug, instrument}; @@ -274,7 +274,7 @@ impl DefPath { } /// New variants should only be added in synchronization with `enum DefKind`. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable, 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 d45f0475e9910..938ab66555fe4 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -14,7 +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::definitions::{DefPathData, DisambiguatorState}; +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, @@ -64,7 +64,6 @@ impl ResolvedArg { struct BoundVarContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, rbv: &'a mut ResolveBoundVars, - disambiguator: &'a mut DisambiguatorState, scope: ScopeRef<'a>, } @@ -247,12 +246,8 @@ pub(crate) fn provide(providers: &mut Providers) { #[instrument(level = "debug", skip(tcx))] fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBoundVars { let mut rbv = ResolveBoundVars::default(); - let mut visitor = BoundVarContext { - tcx, - rbv: &mut rbv, - scope: &Scope::Root { opt_parent_item: None }, - disambiguator: &mut DisambiguatorState::new(), - }; + let mut visitor = + BoundVarContext { tcx, rbv: &mut rbv, scope: &Scope::Root { opt_parent_item: None } }; match tcx.hir_owner_node(local_def_id) { hir::OwnerNode::Item(item) => visitor.visit_item(item), hir::OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item), @@ -1098,8 +1093,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { where F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>), { - let BoundVarContext { tcx, rbv, disambiguator, .. } = self; - let mut this = BoundVarContext { tcx: *tcx, rbv, disambiguator, scope: &wrap_scope }; + let BoundVarContext { tcx, rbv, .. } = self; + let mut this = BoundVarContext { tcx: *tcx, rbv, scope: &wrap_scope }; let span = debug_span!("scope", scope = ?this.scope.debug_truncated()); { let _enter = span.enter(); @@ -1472,13 +1467,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)), - &mut self.disambiguator, ); 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 02d1ebdb31a9a..06377e82c8d16 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -9,13 +9,12 @@ use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::jobserver::Proxy; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal}; +use rustc_data_structures::sync::WorkerLocal; use rustc_data_structures::{parallel, thousands}; use rustc_expand::base::{ExtCtxt, LintStoreExpand}; use rustc_feature::Features; use rustc_fs_util::try_canonicalize; -use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap}; -use rustc_hir::definitions::Definitions; +use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId}; use rustc_incremental::setup_dep_graph; use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store}; use rustc_metadata::EncodedMetadata; @@ -30,7 +29,6 @@ use rustc_parse::{ use rustc_passes::{abi_test, input_stats, layout_test}; use rustc_resolve::Resolver; use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType}; -use rustc_session::cstore::Untracked; use rustc_session::output::{collect_crate_types, filename_for_input}; use rustc_session::parse::feature_err; use rustc_session::search_paths::PathKind; @@ -904,13 +902,7 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( let dep_type = DepsType { dep_names: rustc_query_impl::dep_kind_names() }; let dep_graph = setup_dep_graph(sess, crate_name, &dep_type); - 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 @@ -953,7 +945,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::query_callbacks(arena), rustc_query_impl::query_system( diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 4d914c42cfc62..5b248dff9dbf1 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -3,11 +3,13 @@ use std::ffi::OsStr; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId}; +use rustc_hir::definitions::DefPathData; use rustc_hir::hir_id::{HirId, OwnerId}; use rustc_query_system::dep_graph::DepNodeIndex; use rustc_query_system::query::{DefIdCache, DefaultCache, SingleCache, VecCache}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol}; +use crate::dep_graph::DepNode; use crate::infer::canonical::CanonicalQueryInput; use crate::mir::mono::CollectionMode; use crate::ty::fast_reject::SimplifiedType; @@ -640,3 +642,11 @@ impl<'tcx> Key for (ty::Instance<'tcx>, CollectionMode) { self.0.default_span(tcx) } } + +impl Key for (LocalDefId, DefPathData, Option, usize) { + type Cache = DefaultCache; + + fn default_span(&self, _: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3668f4e12f5d9..4c83444bd61fd 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -81,6 +81,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::{Crate, ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, TraitCandidate}; use rustc_index::IndexVec; @@ -102,6 +103,7 @@ use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_target::spec::PanicStrategy; use {rustc_abi as abi, rustc_ast as ast, rustc_attr_data_structures as attr, rustc_hir as hir}; +use crate::dep_graph::DepNode; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintExpectation; use crate::metadata::ModChild; @@ -215,6 +217,23 @@ rustc_queries! { desc { "getting the source span" } } + /// Create a new definition. + query create_def_raw(key: ( + LocalDefId, // parent + DefPathData, // def_path_data + Option, // caller query + usize, // counter of calls to `create_def_raw` by the caller query + )) -> LocalDefId { + // Accesses untracked data + eval_always + desc { |tcx| + "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/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f1395c242f271..8145ab69705e8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -27,7 +27,8 @@ 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, ErrorGuaranteed, LintDiagnostic, LintEmitter, MultiSpan, @@ -49,7 +50,7 @@ use rustc_session::config::CrateType; use rustc_session::cstore::{CrateStoreDyn, Untracked}; use rustc_session::lint::Lint; use rustc_session::{Limit, Session}; -use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId}; +use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId, StableCrateIdMap}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use rustc_type_ir::TyKind::*; use rustc_type_ir::lang_items::TraitSolverLangItem; @@ -60,7 +61,7 @@ use rustc_type_ir::{ use tracing::{debug, instrument}; use crate::arena::Arena; -use crate::dep_graph::{DepGraph, DepKindStruct}; +use crate::dep_graph::{DepGraph, DepKindStruct, DepNode, TaskDepsRef}; use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind, CanonicalVarKinds}; use crate::lint::lint_level; use crate::metadata::ModChild; @@ -1456,6 +1457,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) query_kinds: &'tcx [DepKindStruct<'tcx>], @@ -1688,7 +1692,7 @@ impl<'tcx> TyCtxt<'tcx> { stable_crate_id: StableCrateId, arena: &'tcx WorkerLocal>, hir_arena: &'tcx WorkerLocal>, - untracked: Untracked, + cstore: Box, dep_graph: DepGraph, query_kinds: &'tcx [DepKindStruct<'tcx>], query_system: QuerySystem<'tcx>, @@ -1697,6 +1701,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); }); @@ -1719,6 +1734,7 @@ impl<'tcx> TyCtxt<'tcx> { lifetimes: common_lifetimes, consts: common_consts, untracked, + untracked_disambiguator_state: Lock::new(DisambiguatorState::new()), query_system, query_kinds, ty_rcache: Default::default(), @@ -2000,6 +2016,30 @@ 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, Option, 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, &mut disambiguator_state) +} + impl<'tcx> TyCtxtAt<'tcx> { /// Create a new definition within the incr. comp. engine. pub fn create_def( @@ -2008,11 +2048,8 @@ impl<'tcx> TyCtxtAt<'tcx> { name: Option, def_kind: DefKind, override_def_path_data: Option, - disambiguator: &mut DisambiguatorState, ) -> 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 } @@ -2026,28 +2063,39 @@ impl<'tcx> TyCtxt<'tcx> { name: Option, def_kind: DefKind, override_def_path_data: Option, - disambiguator: &mut DisambiguatorState, ) -> 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); + + // `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* defintions from them. In order to make this compatible with the + // general model of queries, we add additional information which must change at each call. + let (dep_node, query_local_index) = + ty::tls::with_related_context(self, |icx| match icx.task_deps { + // If we are inside a query, we can only use local information, and no global + // mutable state. The current query's name and the number of calls to `create_def` + // are local to the current query, so are ok to use. + TaskDepsRef::Allow(deps) => { + let opt_dep_node_and_index = deps.lock().next_query_local_index(); + if let Some((dep_node, index)) = opt_dep_node_and_index { + (Some(dep_node), index) + } else { + // No idea how to support this for now... + bug!("trying to create a definition from an anonymous query") + } + } + // If we are not tracking dependencies, we can use global mutable state, + // so we use the total number of definitions as a proxy. + TaskDepsRef::EvalAlways | TaskDepsRef::Forbid | TaskDepsRef::Ignore => { + let global_count = self.untracked.definitions.read().def_index_count(); + (None, global_count) + } + }); + let def_id = self.create_def_raw((parent, data, dep_node, query_local_index)); 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 @@ -3458,6 +3506,7 @@ 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; } pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 97408e31854ae..bd9495b5f5b6b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -38,7 +38,6 @@ use rustc_errors::{Diag, ErrorGuaranteed}; use rustc_hir::LangItem; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; -use rustc_hir::definitions::DisambiguatorState; use rustc_index::IndexVec; use rustc_index::bit_set::BitMatrix; use rustc_macros::{ @@ -221,8 +220,6 @@ pub struct ResolverAstLowering { pub node_id_to_def_id: NodeMap, - pub disambiguator: DisambiguatorState, - pub trait_map: NodeMap>, /// List functions and methods for which lifetime elision was successful. pub lifetime_elision_allowed: FxHashSet, 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 0a839d91404ec..74860947de9d2 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -73,7 +73,6 @@ use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::definitions::DisambiguatorState; use rustc_middle::bug; use rustc_middle::hir::place::{Projection, ProjectionKind}; use rustc_middle::mir::visit::MutVisitor; @@ -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 DisambiguatorState::new(), - ); + 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())); dump_mir(tcx, false, "built", &"after", &by_move_body, |_, _| Ok(())); diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index bdd1d5f3e88a9..a515b4c3f33cd 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -73,6 +73,14 @@ pub struct DepKind { variant: u16, } +impl HashStable for DepKind { + #[inline] + fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + let DepKind { variant } = self; + variant.hash_stable(hcx, hasher) + } +} + impl DepKind { #[inline] pub const fn new(variant: u16) -> Self { @@ -109,6 +117,15 @@ pub struct DepNode { pub hash: PackedFingerprint, } +impl HashStable for DepNode { + #[inline] + fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + let DepNode { kind, hash } = *self; + kind.hash_stable(hcx, hasher); + Fingerprint::from(hash).hash_stable(hcx, hasher); + } +} + impl DepNode { /// Creates a new, parameterless DepNode. This method will assert /// that the DepNode corresponding to the given DepKind actually diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index d4217e0aa5499..450ee7d78562d 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -350,8 +350,8 @@ impl DepGraphData { (with_deps(TaskDepsRef::EvalAlways), EdgesVec::new()) } else { let task_deps = Lock::new(TaskDeps { - #[cfg(debug_assertions)] - node: Some(key), + current_dep_node: Some(key), + local_index: 0, reads: EdgesVec::new(), read_set: Default::default(), phantom_data: PhantomData, @@ -498,7 +498,7 @@ impl DepGraph { #[cfg(debug_assertions)] { - if let Some(target) = task_deps.node { + if let Some(target) = task_deps.current_dep_node { if let Some(ref forbidden_edge) = data.current.forbidden_edge { let src = forbidden_edge.index_to_node.lock()[&dep_node_index]; if forbidden_edge.test(&src, &target) { @@ -1297,8 +1297,9 @@ 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, reads: EdgesVec, read_set: FxHashSet, phantom_data: PhantomData, @@ -1307,14 +1308,24 @@ pub struct TaskDeps { impl Default for TaskDeps { fn default() -> Self { Self { - #[cfg(debug_assertions)] - node: None, + current_dep_node: None, + local_index: 0, reads: EdgesVec::new(), read_set: FxHashSet::with_capacity_and_hasher(128, Default::default()), phantom_data: PhantomData, } } } + +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_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f0540725416cb..c0fc243c950fc 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -55,7 +55,6 @@ use rustc_hir::def::{ self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS, }; use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; -use rustc_hir::definitions::DisambiguatorState; use rustc_hir::{PrimTy, TraitCandidate}; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::metadata::ModChild; @@ -1179,8 +1178,6 @@ pub struct Resolver<'ra, 'tcx> { node_id_to_def_id: NodeMap>, - disambiguator: DisambiguatorState, - /// Indices of unnamed struct or variant fields with unresolved attributes. placeholder_field_indices: FxHashMap, /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId` @@ -1344,7 +1341,7 @@ impl<'tcx> Resolver<'_, 'tcx> { ); // 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, &mut self.disambiguator); + let feed = self.tcx.create_def(parent, name, def_kind, None); let def_id = feed.def_id(); // Create the definition. @@ -1558,7 +1555,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { lint_buffer: LintBuffer::default(), next_node_id: CRATE_NODE_ID, node_id_to_def_id, - disambiguator: DisambiguatorState::new(), placeholder_field_indices: Default::default(), invocation_parents, legacy_const_generic_args: Default::default(), @@ -1688,7 +1684,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .into_items() .map(|(k, f)| (k, f.key())) .collect(), - disambiguator: self.disambiguator, trait_map: self.trait_map, lifetime_elision_allowed: self.lifetime_elision_allowed, lint_buffer: Steal::new(self.lint_buffer), diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index f14a45aa1e3b9..2dfaad64ac58a 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -1,7 +1,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; -use rustc_hir::definitions::{DefPathData, DisambiguatorState}; +use rustc_hir::definitions::DefPathData; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir, AmbigArg}; use rustc_middle::query::Providers; @@ -246,13 +246,8 @@ fn associated_type_for_impl_trait_in_trait( let trait_def_id = tcx.local_parent(fn_def_id); assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait); - // Collect all opaque types in return position for the method and use - // the index as the disambiguator to make an unique def path. - let mut visitor = RPITVisitor { rpits: FxIndexSet::default() }; - visitor.visit_fn_ret_ty(tcx.hir_get_fn_output(fn_def_id).unwrap()); - let disambiguator = visitor.rpits.get_index_of(&opaque_ty_def_id).unwrap().try_into().unwrap(); - let span = tcx.def_span(opaque_ty_def_id); + // Also use the method name to create an unique def path. let data = DefPathData::AnonAssocTy(tcx.item_name(fn_def_id.to_def_id())); let trait_assoc_ty = tcx.at(span).create_def( @@ -261,7 +256,6 @@ fn associated_type_for_impl_trait_in_trait( None, DefKind::AssocTy, Some(data), - &mut DisambiguatorState::with(trait_def_id, data, disambiguator), ); let local_def_id = trait_assoc_ty.def_id(); @@ -314,12 +308,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, @@ -327,7 +321,6 @@ fn associated_type_for_impl_trait_in_impl( None, DefKind::AssocTy, Some(data), - &mut DisambiguatorState::with(impl_local_def_id, data, disambiguated_data.disambiguator), ); let local_def_id = impl_assoc_ty.def_id();