diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 04f1129d87c1f..bd1ecf0ceb05f 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -19,7 +19,7 @@ pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { tcx, module, kind, - tcx.alloc_error_handler_kind(()).unwrap(), + tcx.alloc_error_handler_kind().unwrap(), tcx.sess.opts.unstable_opts.oom, ); true diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index e644a43f88340..c01dcb123c597 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1857,7 +1857,7 @@ fn exported_symbols_for_non_proc_macro( // Mark allocator shim symbols as exported only if they were generated. if export_threshold == SymbolExportLevel::Rust && needs_allocator_shim_for_linking(tcx.dependency_formats(()), crate_type) - && tcx.allocator_kind(()).is_some() + && tcx.allocator_kind().is_some() { symbols.extend(allocator_shim_symbols(tcx)); } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 422b06350e1fc..c2d6cf4437564 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -639,7 +639,7 @@ pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option { use rustc_middle::middle::dependency_format::Linkage; list.iter().any(|&linkage| linkage == Linkage::Dynamic) }); - if all_crate_types_any_dynamic_crate { None } else { tcx.allocator_kind(()) } + if all_crate_types_any_dynamic_crate { None } else { tcx.allocator_kind() } } /// Decide if this particular crate type needs an allocator shim linked in. @@ -705,7 +705,7 @@ pub fn codegen_crate( kind, // If allocator_kind is Some then alloc_error_handler_kind must // also be Some. - tcx.alloc_error_handler_kind(()).unwrap(), + tcx.alloc_error_handler_kind().unwrap(), ); Some(ModuleCodegen::new_allocator(llmod_id, module)) }) diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index df3add316ec23..ac33cfa394ab4 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -328,8 +328,8 @@ provide! { tcx, def_id, other, cdata, is_private_dep => { cdata.private_dep } is_panic_runtime => { cdata.root.panic_runtime } is_compiler_builtins => { cdata.root.compiler_builtins } - has_global_allocator => { cdata.root.has_global_allocator } - has_alloc_error_handler => { cdata.root.has_alloc_error_handler } + has_global_allocator_q => { cdata.root.has_global_allocator } + has_alloc_error_handler_q => { cdata.root.has_alloc_error_handler } has_panic_handler => { cdata.root.has_panic_handler } is_profiler_runtime => { cdata.root.profiler_runtime } required_panic_strategy => { cdata.root.required_panic_strategy } @@ -407,8 +407,8 @@ provide! { tcx, def_id, other, cdata, pub(in crate::rmeta) fn provide(providers: &mut Providers) { provide_cstore_hooks(providers); providers.queries = rustc_middle::query::Providers { - allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(), - alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(), + allocator_kind_q: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(), + alloc_error_handler_kind_q: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(), is_private_dep: |_tcx, LocalCrate| false, native_library: |tcx, id| { tcx.native_libraries(id.krate) @@ -519,8 +519,10 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { }, dependency_formats: |tcx, ()| Arc::new(crate::dependency_format::calculate(tcx)), - has_global_allocator: |tcx, LocalCrate| CStore::from_tcx(tcx).has_global_allocator(), - has_alloc_error_handler: |tcx, LocalCrate| CStore::from_tcx(tcx).has_alloc_error_handler(), + has_global_allocator_q: |tcx, LocalCrate| CStore::from_tcx(tcx).has_global_allocator(), + has_alloc_error_handler_q: |tcx, LocalCrate| { + CStore::from_tcx(tcx).has_alloc_error_handler() + }, postorder_cnums: |tcx, ()| { tcx.arena.alloc_from_iter( CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE).into_iter(), @@ -706,4 +708,44 @@ fn provide_cstore_hooks(providers: &mut Providers) { cdata.imported_source_file(file_index as u32, tcx.sess); } }; + providers.hooks.allocator_kind = |tcx| { + if tcx.dep_graph.is_fully_enabled() { + tcx.allocator_kind_q(()) + } else { + CStore::from_tcx(tcx).allocator_kind() + } + }; + providers.hooks.alloc_error_handler_kind = |tcx| { + if tcx.dep_graph.is_fully_enabled() { + tcx.alloc_error_handler_kind_q(()) + } else { + CStore::from_tcx(tcx).alloc_error_handler_kind() + } + }; + providers.hooks.has_global_allocator = |tcx, krate: CrateNum| { + if tcx.dep_graph.is_fully_enabled() { + tcx.has_global_allocator_q(krate) + } else { + if krate == LOCAL_CRATE { + CStore::from_tcx(tcx).has_global_allocator() + } else { + *rustc_data_structures::sync::FreezeReadGuard::map(CStore::from_tcx(tcx), |c| { + &c.get_crate_data(krate).cdata.root.has_global_allocator + }) + } + } + }; + providers.hooks.has_alloc_error_handler = |tcx, krate: CrateNum| { + if tcx.dep_graph.is_fully_enabled() { + tcx.has_alloc_error_handler_q(krate) + } else { + if krate == LOCAL_CRATE { + CStore::from_tcx(tcx).has_alloc_error_handler() + } else { + *rustc_data_structures::sync::FreezeReadGuard::map(CStore::from_tcx(tcx), |c| { + &c.get_crate_data(krate).cdata.root.has_alloc_error_handler + }) + } + } + }; } diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index dc6a3334a4c8b..c985e52eb91dc 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -3,6 +3,7 @@ //! similar to queries, but queries come with a lot of machinery for caching and incremental //! compilation, whereas hooks are just plain function pointers without any of the query magic. +use rustc_ast::expand::allocator::AllocatorKind; use rustc_hir::def_id::{DefId, DefPathHash}; use rustc_session::StableCrateId; use rustc_span::def_id::{CrateNum, LocalDefId}; @@ -102,6 +103,11 @@ declare_hooks! { /// Ensure the given scalar is valid for the given type. /// This checks non-recursive runtime validity. hook validate_scalar_in_layout(scalar: crate::ty::ScalarInt, ty: Ty<'tcx>) -> bool; + + hook allocator_kind() -> Option; + hook alloc_error_handler_kind() -> Option; + hook has_global_allocator(krate: CrateNum) -> bool; + hook has_alloc_error_handler(krate: CrateNum) -> bool; } #[cold] diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 895c8c0295a04..c9afdb99521bc 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1812,14 +1812,14 @@ rustc_queries! { desc { "checking if the crate is_compiler_builtins" } separate_provide_extern } - query has_global_allocator(_: CrateNum) -> bool { + query has_global_allocator_q(_: CrateNum) -> bool { // This query depends on untracked global state in CStore eval_always fatal_cycle desc { "checking if the crate has_global_allocator" } separate_provide_extern } - query has_alloc_error_handler(_: CrateNum) -> bool { + query has_alloc_error_handler_q(_: CrateNum) -> bool { // This query depends on untracked global state in CStore eval_always fatal_cycle @@ -2301,11 +2301,11 @@ rustc_queries! { desc { "checking whether crate `{}` is a private dependency", c } separate_provide_extern } - query allocator_kind(_: ()) -> Option { + query allocator_kind_q(_: ()) -> Option { eval_always desc { "getting the allocator kind for the current crate" } } - query alloc_error_handler_kind(_: ()) -> Option { + query alloc_error_handler_kind_q(_: ()) -> Option { eval_always desc { "alloc error handler kind for the current crate" } } diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index f05c5fbbe1d4f..04c4c44978bd3 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -61,7 +61,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, EmulateItemResult> { let this = self.eval_context_mut(); - let Some(allocator_kind) = this.tcx.allocator_kind(()) else { + let Some(allocator_kind) = this.tcx.allocator_kind() else { // in real code, this symbol does not exist without an allocator return interp_ok(EmulateItemResult::NotSupported); }; diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index eca8cccf5efc4..b9ef28fa173b7 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -53,7 +53,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { name if name == this.mangle_internal_symbol("__rust_alloc_error_handler") => { // Forward to the right symbol that implements this function. - let Some(handler_kind) = this.tcx.alloc_error_handler_kind(()) else { + let Some(handler_kind) = this.tcx.alloc_error_handler_kind() else { // in real code, this symbol does not exist without an allocator throw_unsup_format!( "`__rust_alloc_error_handler` cannot be called when no alloc error handler is set"