Skip to content

Commit f9e4d07

Browse files
authored
Backports for 1.11.1 (#56025)
Backported PRs: - [x] #55945 <!-- Fix logic in `?` docstring example --> - [x] #55932 <!-- REPL: make UndefVarError aware of imported modules --> - [x] #55968 <!-- [build] avoid libedit linkage and align libccalllazy* SONAMEs --> - [x] #55977 <!-- fix comma logic in time_print --> - [x] #55982 <!-- `@time` actually fix time report commas & add tests --> - [x] #55743 <!-- doc: heap snapshot viewing --> - [x] #55851 <!-- [REPL] Fix #55850 by using `safe_realpath` instead of `abspath` in `projname` --> - [x] #55992 <!-- Avoid `stat`-ing stdlib path if it's unreadable --> - [x] #55589 <!-- prevent loading other extensions when precompiling an extension --> - [x] #54009 <!-- allow extensions to trigger from packages in [deps] --> - [x] #56019 <!-- Fix no-arg `ScopedValues.@with` within a scope --> - [x] #56023 <!-- Sockets: Warn when local network access not granted. --> - [x] #55569 <!-- Add a docs section about loading/precomp/ttfx time tuning --> - [x] #55824 <!-- Replace regex package module checks with actual code checks --> - [x] #56041 <!-- Don't show keymap `@error` for hints --> - [x] #53469 - [x] #56029 <!-- fix `_growbeg!` unncessary resizing --> - [x] #56103 - [x] #55941 <!-- Fix zero elements for block-matrix kron involving Diagonal -->
2 parents 501a4f2 + 4e03986 commit f9e4d07

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+625
-334
lines changed

base/Enums.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Base.print(io::IO, x::Enum) = print(io, _symbol(x))
4444
function Base.show(io::IO, x::Enum)
4545
sym = _symbol(x)
4646
if !(get(io, :compact, false)::Bool)
47-
from = get(io, :module, Base.active_module())
47+
from = get(io, :module, Main)
4848
def = parentmodule(typeof(x))
4949
if from === nothing || !Base.isvisible(sym, def, from)
5050
show(io, def)

base/array.jl

+7-2
Original file line numberDiff line numberDiff line change
@@ -1062,10 +1062,11 @@ function _growbeg!(a::Vector, delta::Integer)
10621062
setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
10631063
else
10641064
@noinline (function()
1065+
@_terminates_locally_meta
10651066
memlen = length(mem)
10661067
# since we will allocate the array in the middle of the memory we need at least 2*delta extra space
10671068
# the +1 is because I didn't want to have an off by 1 error.
1068-
newmemlen = max(overallocation(memlen), len + 2 * delta + 1)
1069+
newmemlen = max(overallocation(len), len + 2 * delta + 1)
10691070
newoffset = div(newmemlen - newlen, 2) + 1
10701071
# If there is extra data after the end of the array we can use that space so long as there is enough
10711072
# space at the end that there won't be quadratic behavior with a mix of growth from both ends.
@@ -1074,10 +1075,14 @@ function _growbeg!(a::Vector, delta::Integer)
10741075
if newoffset + newlen < memlen
10751076
newoffset = div(memlen - newlen, 2) + 1
10761077
newmem = mem
1078+
unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
1079+
for j in offset:newoffset+delta-1
1080+
@inbounds _unsetindex!(mem, j)
1081+
end
10771082
else
10781083
newmem = array_new_memory(mem, newmemlen)
1084+
unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
10791085
end
1080-
unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
10811086
setfield!(a, :ref, @inbounds memoryref(newmem, newoffset))
10821087
end)()
10831088
end

base/docs/basedocs.jl

+6-3
Original file line numberDiff line numberDiff line change
@@ -931,11 +931,14 @@ expression, rather than the side effects that evaluating `b` or `c` may have.
931931
See the manual section on [control flow](@ref man-conditional-evaluation) for more details.
932932
933933
# Examples
934-
```
934+
```jldoctest
935935
julia> x = 1; y = 2;
936936
937-
julia> x > y ? println("x is larger") : println("y is larger")
938-
y is larger
937+
julia> x > y ? println("x is larger") : println("x is not larger")
938+
x is not larger
939+
940+
julia> x > y ? "x is larger" : x == y ? "x and y are equal" : "y is larger"
941+
"y is larger"
939942
```
940943
"""
941944
kw"?", kw"?:"

base/essentials.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ macro _noub_meta()
348348
#=:inaccessiblememonly=#false,
349349
#=:noub=#true,
350350
#=:noub_if_noinbounds=#false,
351-
#=:consistent_overlay=#false))
351+
#=:consistent_overlay=#false,
352+
#=:nortcall=#false))
352353
end
353354
# can be used in place of `@assume_effects :notaskstate` (supposed to be used for bootstrapping)
354355
macro _notaskstate_meta()

base/experimental.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,9 @@ function show_error_hints(io, ex, args...)
319319
for handler in hinters
320320
try
321321
@invokelatest handler(io, ex, args...)
322-
catch err
322+
catch
323323
tn = typeof(handler).name
324-
@error "Hint-handler $handler for $(typeof(ex)) in $(tn.module) caused an error"
324+
@error "Hint-handler $handler for $(typeof(ex)) in $(tn.module) caused an error" exception=current_exceptions()
325325
end
326326
end
327327
end

base/loading.jl

+68-65
Original file line numberDiff line numberDiff line change
@@ -1350,7 +1350,9 @@ function run_module_init(mod::Module, i::Int=1)
13501350
end
13511351

13521352
function run_package_callbacks(modkey::PkgId)
1353-
run_extension_callbacks(modkey)
1353+
if !precompiling_extension
1354+
run_extension_callbacks(modkey)
1355+
end
13541356
assert_havelock(require_lock)
13551357
unlock(require_lock)
13561358
try
@@ -1405,13 +1407,12 @@ function insert_extension_triggers(env::String, pkg::PkgId)::Union{Nothing,Missi
14051407
proj_pkg = project_file_name_uuid(implicit_project_file, pkg.name)
14061408
if pkg == proj_pkg
14071409
d_proj = parsed_toml(implicit_project_file)
1408-
weakdeps = get(d_proj, "weakdeps", nothing)::Union{Nothing, Vector{String}, Dict{String,Any}}
14091410
extensions = get(d_proj, "extensions", nothing)::Union{Nothing, Dict{String, Any}}
14101411
extensions === nothing && return
1411-
weakdeps === nothing && return
1412-
if weakdeps isa Dict{String, Any}
1413-
return _insert_extension_triggers(pkg, extensions, weakdeps)
1414-
end
1412+
weakdeps = get(Dict{String, Any}, d_proj, "weakdeps")::Dict{String,Any}
1413+
deps = get(Dict{String, Any}, d_proj, "deps")::Dict{String,Any}
1414+
total_deps = merge(weakdeps, deps)
1415+
return _insert_extension_triggers(pkg, extensions, total_deps)
14151416
end
14161417

14171418
# Now look in manifest
@@ -1426,35 +1427,43 @@ function insert_extension_triggers(env::String, pkg::PkgId)::Union{Nothing,Missi
14261427
uuid = get(entry, "uuid", nothing)::Union{String, Nothing}
14271428
uuid === nothing && continue
14281429
if UUID(uuid) == pkg.uuid
1429-
weakdeps = get(entry, "weakdeps", nothing)::Union{Nothing, Vector{String}, Dict{String,Any}}
14301430
extensions = get(entry, "extensions", nothing)::Union{Nothing, Dict{String, Any}}
14311431
extensions === nothing && return
1432-
weakdeps === nothing && return
1433-
if weakdeps isa Dict{String, Any}
1434-
return _insert_extension_triggers(pkg, extensions, weakdeps)
1432+
weakdeps = get(Dict{String, Any}, entry, "weakdeps")::Union{Vector{String}, Dict{String,Any}}
1433+
deps = get(Dict{String, Any}, entry, "deps")::Union{Vector{String}, Dict{String,Any}}
1434+
1435+
function expand_deps_list(deps′::Vector{String})
1436+
deps′_expanded = Dict{String, Any}()
1437+
for (dep_name, entries) in d
1438+
dep_name in deps′ || continue
1439+
entries::Vector{Any}
1440+
if length(entries) != 1
1441+
error("expected a single entry for $(repr(dep_name)) in $(repr(project_file))")
1442+
end
1443+
entry = first(entries)::Dict{String, Any}
1444+
uuid = entry["uuid"]::String
1445+
deps′_expanded[dep_name] = uuid
1446+
end
1447+
return deps′_expanded
14351448
end
14361449

1437-
d_weakdeps = Dict{String, Any}()
1438-
for (dep_name, entries) in d
1439-
dep_name in weakdeps || continue
1440-
entries::Vector{Any}
1441-
if length(entries) != 1
1442-
error("expected a single entry for $(repr(dep_name)) in $(repr(project_file))")
1443-
end
1444-
entry = first(entries)::Dict{String, Any}
1445-
uuid = entry["uuid"]::String
1446-
d_weakdeps[dep_name] = uuid
1450+
if weakdeps isa Vector{String}
1451+
weakdeps = expand_deps_list(weakdeps)
1452+
end
1453+
if deps isa Vector{String}
1454+
deps = expand_deps_list(deps)
14471455
end
1448-
@assert length(d_weakdeps) == length(weakdeps)
1449-
return _insert_extension_triggers(pkg, extensions, d_weakdeps)
1456+
1457+
total_deps = merge(weakdeps, deps)
1458+
return _insert_extension_triggers(pkg, extensions, total_deps)
14501459
end
14511460
end
14521461
end
14531462
end
14541463
return nothing
14551464
end
14561465

1457-
function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}, weakdeps::Dict{String, Any})
1466+
function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}, totaldeps::Dict{String, Any})
14581467
for (ext, triggers) in extensions
14591468
triggers = triggers::Union{String, Vector{String}}
14601469
triggers isa String && (triggers = [triggers])
@@ -1468,7 +1477,7 @@ function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}
14681477
push!(trigger1, gid)
14691478
for trigger in triggers
14701479
# TODO: Better error message if this lookup fails?
1471-
uuid_trigger = UUID(weakdeps[trigger]::String)
1480+
uuid_trigger = UUID(totaldeps[trigger]::String)
14721481
trigger_id = PkgId(uuid_trigger, trigger)
14731482
if !haskey(explicit_loaded_modules, trigger_id) || haskey(package_locks, trigger_id)
14741483
trigger1 = get!(Vector{ExtensionId}, EXT_DORMITORY, trigger_id)
@@ -1480,6 +1489,7 @@ function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}
14801489
end
14811490
end
14821491

1492+
precompiling_package::Bool = false
14831493
loading_extension::Bool = false
14841494
precompiling_extension::Bool = false
14851495
function run_extension_callbacks(extid::ExtensionId)
@@ -2172,6 +2182,11 @@ For more details regarding code loading, see the manual sections on [modules](@r
21722182
[parallel computing](@ref code-availability).
21732183
"""
21742184
function require(into::Module, mod::Symbol)
2185+
if into === Base.__toplevel__ && precompiling_package
2186+
# this error type needs to match the error type compilecache throws for non-125 errors.
2187+
error("`using/import $mod` outside of a Module detected. Importing a package outside of a module \
2188+
is not allowed during package precompilation.")
2189+
end
21752190
if _require_world_age[] != typemax(UInt)
21762191
Base.invoke_in_world(_require_world_age[], __require, into, mod)
21772192
else
@@ -2750,41 +2765,10 @@ function load_path_setup_code(load_path::Bool=true)
27502765
return code
27512766
end
27522767

2753-
"""
2754-
check_src_module_wrap(srcpath::String)
2755-
2756-
Checks that a package entry file `srcpath` has a module declaration, and that it is before any using/import statements.
2757-
"""
2758-
function check_src_module_wrap(pkg::PkgId, srcpath::String)
2759-
module_rgx = r"^(|end |\"\"\" )\s*(?:@)*(?:bare)?module\s"
2760-
load_rgx = r"\b(?:using|import)\s"
2761-
load_seen = false
2762-
inside_string = false
2763-
for s in eachline(srcpath)
2764-
if count("\"\"\"", s) == 1
2765-
# ignore module docstrings
2766-
inside_string = !inside_string
2767-
end
2768-
inside_string && continue
2769-
if contains(s, module_rgx)
2770-
if load_seen
2771-
throw(ErrorException("Package $(repr("text/plain", pkg)) source file $srcpath has a using/import before a module declaration."))
2772-
end
2773-
return true
2774-
end
2775-
if startswith(s, load_rgx)
2776-
load_seen = true
2777-
end
2778-
end
2779-
throw(ErrorException("Package $(repr("text/plain", pkg)) source file $srcpath does not contain a module declaration."))
2780-
end
2781-
27822768
# this is called in the external process that generates precompiled package files
27832769
function include_package_for_output(pkg::PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String},
27842770
concrete_deps::typeof(_concrete_dependencies), source::Union{Nothing,String})
27852771

2786-
check_src_module_wrap(pkg, input)
2787-
27882772
append!(empty!(Base.DEPOT_PATH), depot_path)
27892773
append!(empty!(Base.DL_LOAD_PATH), dl_load_path)
27902774
append!(empty!(Base.LOAD_PATH), load_path)
@@ -2811,11 +2795,22 @@ function include_package_for_output(pkg::PkgId, input::String, depot_path::Vecto
28112795
finally
28122796
Core.Compiler.track_newly_inferred.x = false
28132797
end
2798+
# check that the package defined the expected module so we can give a nice error message if not
2799+
Base.check_package_module_loaded(pkg)
2800+
end
2801+
2802+
function check_package_module_loaded(pkg::PkgId)
2803+
if !haskey(Base.loaded_modules, pkg)
2804+
# match compilecache error type for non-125 errors
2805+
error("$(repr("text/plain", pkg)) did not define the expected module `$(pkg.name)`, \
2806+
check for typos in package module name")
2807+
end
2808+
return nothing
28142809
end
28152810

28162811
const PRECOMPILE_TRACE_COMPILE = Ref{String}()
28172812
function create_expr_cache(pkg::PkgId, input::String, output::String, output_o::Union{Nothing, String},
2818-
concrete_deps::typeof(_concrete_dependencies), flags::Cmd=``, internal_stderr::IO = stderr, internal_stdout::IO = stdout)
2813+
concrete_deps::typeof(_concrete_dependencies), flags::Cmd=``, internal_stderr::IO = stderr, internal_stdout::IO = stdout, isext::Bool=false)
28192814
@nospecialize internal_stderr internal_stdout
28202815
rm(output, force=true) # Remove file if it exists
28212816
output_o === nothing || rm(output_o, force=true)
@@ -2884,7 +2879,8 @@ function create_expr_cache(pkg::PkgId, input::String, output::String, output_o::
28842879
write(io.in, """
28852880
empty!(Base.EXT_DORMITORY) # If we have a custom sysimage with `EXT_DORMITORY` prepopulated
28862881
Base.track_nested_precomp($precomp_stack)
2887-
Base.precompiling_extension = $(loading_extension)
2882+
Base.precompiling_extension = $(loading_extension | isext)
2883+
Base.precompiling_package = true
28882884
Base.include_package_for_output($(pkg_str(pkg)), $(repr(abspath(input))), $(repr(depot_path)), $(repr(dl_load_path)),
28892885
$(repr(load_path)), $deps, $(repr(source_path(nothing))))
28902886
""")
@@ -2941,18 +2937,18 @@ This can be used to reduce package load times. Cache files are stored in
29412937
`DEPOT_PATH[1]/compiled`. See [Module initialization and precompilation](@ref)
29422938
for important notes.
29432939
"""
2944-
function compilecache(pkg::PkgId, internal_stderr::IO = stderr, internal_stdout::IO = stdout; flags::Cmd=``, reasons::Union{Dict{String,Int},Nothing}=Dict{String,Int}())
2940+
function compilecache(pkg::PkgId, internal_stderr::IO = stderr, internal_stdout::IO = stdout; flags::Cmd=``, reasons::Union{Dict{String,Int},Nothing}=Dict{String,Int}(), isext::Bool=false)
29452941
@nospecialize internal_stderr internal_stdout
29462942
path = locate_package(pkg)
29472943
path === nothing && throw(ArgumentError("$(repr("text/plain", pkg)) not found during precompilation"))
2948-
return compilecache(pkg, path, internal_stderr, internal_stdout; flags, reasons)
2944+
return compilecache(pkg, path, internal_stderr, internal_stdout; flags, reasons, isext)
29492945
end
29502946

29512947
const MAX_NUM_PRECOMPILE_FILES = Ref(10)
29522948

29532949
function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, internal_stdout::IO = stdout,
29542950
keep_loaded_modules::Bool = true; flags::Cmd=``, cacheflags::CacheFlags=CacheFlags(),
2955-
reasons::Union{Dict{String,Int},Nothing}=Dict{String,Int}())
2951+
reasons::Union{Dict{String,Int},Nothing}=Dict{String,Int}(), isext::Bool=false)
29562952

29572953
@nospecialize internal_stderr internal_stdout
29582954
# decide where to put the resulting cache file
@@ -2992,7 +2988,7 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in
29922988
close(tmpio_o)
29932989
close(tmpio_so)
29942990
end
2995-
p = create_expr_cache(pkg, path, tmppath, tmppath_o, concrete_deps, flags, internal_stderr, internal_stdout)
2991+
p = create_expr_cache(pkg, path, tmppath, tmppath_o, concrete_deps, flags, internal_stderr, internal_stdout, isext)
29962992

29972993
if success(p)
29982994
if cache_objects
@@ -3778,10 +3774,17 @@ end
37783774

37793775
# now check if this file's content hash has changed relative to its source files
37803776
if stalecheck
3781-
if !samefile(includes[1].filename, modpath) && !samefile(fixup_stdlib_path(includes[1].filename), modpath)
3782-
@debug "Rejecting cache file $cachefile because it is for file $(includes[1].filename) not file $modpath"
3783-
record_reason(reasons, "wrong source")
3784-
return true # cache file was compiled from a different path
3777+
if !samefile(includes[1].filename, modpath)
3778+
# In certain cases the path rewritten by `fixup_stdlib_path` may
3779+
# point to an unreadable directory, make sure we can `stat` the
3780+
# file before comparing it with `modpath`.
3781+
stdlib_path = fixup_stdlib_path(includes[1].filename)
3782+
if !(isreadable(stdlib_path) && samefile(stdlib_path, modpath))
3783+
!samefile(fixup_stdlib_path(includes[1].filename), modpath)
3784+
@debug "Rejecting cache file $cachefile because it is for file $(includes[1].filename) not file $modpath"
3785+
record_reason(reasons, "wrong source")
3786+
return true # cache file was compiled from a different path
3787+
end
37853788
end
37863789
for (modkey, req_modkey) in requires
37873790
# verify that `require(modkey, name(req_modkey))` ==> `req_modkey`

base/precompilation.jl

+2-47
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ function precompilepkgs(pkgs::Vector{String}=String[];
401401
all_extdeps_available = true
402402
for extdep_uuid in extdep_uuids
403403
extdep_name = env.names[extdep_uuid]
404-
if extdep_uuid in keys(env.deps) || Base.in_sysimage(Base.PkgId(extdep_uuid, extdep_name))
404+
if extdep_uuid in keys(env.deps)
405405
push!(ext_deps, Base.PkgId(extdep_uuid, extdep_name))
406406
else
407407
all_extdeps_available = false
@@ -429,51 +429,6 @@ function precompilepkgs(pkgs::Vector{String}=String[];
429429
# consider exts of direct deps to be direct deps so that errors are reported
430430
append!(direct_deps, keys(filter(d->last(d) in keys(env.project_deps), exts)))
431431

432-
# An extension effectively depends on another extension if it has all the the
433-
# dependencies of that other extension
434-
function expand_dependencies(depsmap)
435-
function visit!(visited, node, all_deps)
436-
if node in visited
437-
return
438-
end
439-
push!(visited, node)
440-
for dep in get(Set{Base.PkgId}, depsmap, node)
441-
if !(dep in all_deps)
442-
push!(all_deps, dep)
443-
visit!(visited, dep, all_deps)
444-
end
445-
end
446-
end
447-
448-
depsmap_transitive = Dict{Base.PkgId, Set{Base.PkgId}}()
449-
for package in keys(depsmap)
450-
# Initialize a set to keep track of all dependencies for 'package'
451-
all_deps = Set{Base.PkgId}()
452-
visited = Set{Base.PkgId}()
453-
visit!(visited, package, all_deps)
454-
# Update depsmap with the complete set of dependencies for 'package'
455-
depsmap_transitive[package] = all_deps
456-
end
457-
return depsmap_transitive
458-
end
459-
460-
depsmap_transitive = expand_dependencies(depsmap)
461-
462-
for (_, extensions_1) in pkg_exts_map
463-
for extension_1 in extensions_1
464-
deps_ext_1 = depsmap_transitive[extension_1]
465-
for (_, extensions_2) in pkg_exts_map
466-
for extension_2 in extensions_2
467-
extension_1 == extension_2 && continue
468-
deps_ext_2 = depsmap_transitive[extension_2]
469-
if issubset(deps_ext_2, deps_ext_1)
470-
push!(depsmap[extension_1], extension_2)
471-
end
472-
end
473-
end
474-
end
475-
end
476-
477432
@debug "precompile: deps collected"
478433
# this loop must be run after the full depsmap has been populated
479434
for (pkg, pkg_exts) in pkg_exts_map
@@ -839,7 +794,7 @@ function precompilepkgs(pkgs::Vector{String}=String[];
839794
t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock(io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor) do
840795
Base.with_logger(Base.NullLogger()) do
841796
# The false here means we ignore loaded modules, so precompile for a fresh session
842-
Base.compilecache(pkg, sourcepath, std_pipe, std_pipe, false; flags, cacheflags)
797+
Base.compilecache(pkg, sourcepath, std_pipe, std_pipe, false; flags, cacheflags, isext = haskey(exts, pkg))
843798
end
844799
end
845800
if ret isa Base.PrecompilableError

0 commit comments

Comments
 (0)