From 5c3aaf516531e06e5af21cd62220cb52ee78c75e Mon Sep 17 00:00:00 2001
From: Cody Tapscott <topolarity@tapscott.me>
Date: Sun, 24 Nov 2024 12:11:06 +0000
Subject: [PATCH] Prevent pre-compilation target package from triggering
 extensions

It is possible for an extension `ExtAB` to be loadable by one of its
triggers, e.g. if A loads B. However this loading is only supposed
to happen after loading for A is finished, so it shouldn't be
included as part of pre-compiling A.

Getting this wrong means disagreeing with the scheduled pre-compile
jobs (A is not scheduled to depend on or generate a cache file for
ExtAB but accidentally does both) and leads to confusing errors
about missing cache files.

To avoid trying to use / generate a cache file for ExtAB while still
pre-compiling A, this change tracks the package being currently pre-
compiled so that its extension triggers can be ignored.
---
 base/loading.jl | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/base/loading.jl b/base/loading.jl
index ae54ba19038e9..0a70564077692 100644
--- a/base/loading.jl
+++ b/base/loading.jl
@@ -1433,6 +1433,7 @@ function run_module_init(mod::Module, i::Int=1)
 end
 
 function run_package_callbacks(modkey::PkgId)
+    @assert modkey != precompilation_target
     run_extension_callbacks(modkey)
     assert_havelock(require_lock)
     unlock(require_lock)
@@ -1562,7 +1563,7 @@ function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}
             uuid_trigger = UUID(totaldeps[trigger]::String)
             trigger_id = PkgId(uuid_trigger, trigger)
             push!(trigger_ids, trigger_id)
-            if !haskey(Base.loaded_modules, trigger_id) || haskey(package_locks, trigger_id)
+            if !haskey(Base.loaded_modules, trigger_id) || haskey(package_locks, trigger_id) || (trigger_id == precompilation_target)
                 trigger1 = get!(Vector{ExtensionId}, EXT_DORMITORY, trigger_id)
                 push!(trigger1, gid)
             else
@@ -1575,6 +1576,7 @@ end
 loading_extension::Bool = false
 loadable_extensions::Union{Nothing,Vector{PkgId}} = nothing
 precompiling_extension::Bool = false
+precompilation_target::Union{Nothing,PkgId} = nothing
 function run_extension_callbacks(extid::ExtensionId)
     assert_havelock(require_lock)
     succeeded = try
@@ -3081,6 +3083,7 @@ function create_expr_cache(pkg::PkgId, input::String, output::String, output_o::
         Base.track_nested_precomp($(_pkg_str(vcat(Base.precompilation_stack, pkg))))
         Base.loadable_extensions = $(_pkg_str(loadable_exts))
         Base.precompiling_extension = $(loading_extension)
+        Base.precompilation_target = $(_pkg_str(pkg))
         Base.include_package_for_output($(_pkg_str(pkg)), $(repr(abspath(input))), $(repr(depot_path)), $(repr(dl_load_path)),
             $(repr(load_path)), $(_pkg_str(concrete_deps)), $(repr(source_path(nothing))))
         """)