Skip to content

Commit dcaf0f5

Browse files
Merge branch 'master' into ib/repl_display_backend
2 parents 7f9aed2 + 0d363a8 commit dcaf0f5

File tree

50 files changed

+452
-568
lines changed

Some content is hidden

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

50 files changed

+452
-568
lines changed

HISTORY.md

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ Language changes
5252
* Errors during `getfield` now raise a new `FieldError` exception type instead of the generic
5353
`ErrorException` ([#54504]).
5454
* Macros in function-signature-position no longer require parentheses. E.g. `function @main(args) ... end` is now permitted, whereas `function (@main)(args) ... end` was required in prior Julia versions.
55+
* Calling `using` on a package name inside of that package of that name (especially relevant
56+
for a submodule) now explicitly uses that package without examining the Manifest and
57+
environment, which is identical to the behavior of `..Name`. This appears to better match
58+
how users expect this to behave in the wild. ([#57727])
5559

5660
Compiler/Runtime improvements
5761
-----------------------------

Makefile

+2-7
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,7 @@ julia-src-release julia-src-debug : julia-src-% : julia-deps julia_flisp.boot.in
110110
julia-cli-release julia-cli-debug: julia-cli-% : julia-deps
111111
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT)/cli $*
112112

113-
julia-sysimg-ji : $(TOP_LEVEL_PKG_LINK_TARGETS) julia-stdlib julia-base julia-cli-$(JULIA_BUILD_MODE) julia-src-$(JULIA_BUILD_MODE) | $(build_private_libdir)
114-
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) -f sysimage.mk sysimg-ji JULIA_EXECUTABLE='$(JULIA_EXECUTABLE)'
115-
116-
julia-sysimg-bc : $(TOP_LEVEL_PKG_LINK_TARGETS) julia-stdlib julia-base julia-cli-$(JULIA_BUILD_MODE) julia-src-$(JULIA_BUILD_MODE) | $(build_private_libdir)
117-
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) -f sysimage.mk sysimg-bc JULIA_EXECUTABLE='$(JULIA_EXECUTABLE)'
118-
119-
julia-sysimg-release julia-sysimg-debug : julia-sysimg-% : julia-sysimg-ji julia-src-%
113+
julia-sysimg-release julia-sysimg-debug : julia-sysimg-% : julia-src-% $(TOP_LEVEL_PKG_LINK_TARGETS) julia-stdlib julia-base julia-cli-% julia-src-% | $(build_private_libdir)
120114
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) -f sysimage.mk sysimg-$*
121115

122116
julia-debug julia-release : julia-% : julia-sysimg-% julia-src-% julia-symlink julia-libccalltest \
@@ -177,6 +171,7 @@ release-candidate: release testall
177171
@echo 14. Push to Juliaup (https://github.com/JuliaLang/juliaup/wiki/Adding-a-Julia-version)
178172
@echo 15. Announce on mailing lists
179173
@echo 16. Change master to release-0.X in base/version.jl and base/version_git.sh as in 4cb1e20
174+
@echo 17. Move NEWS.md contents to HISTORY.md
180175
@echo
181176

182177
$(build_man1dir)/julia.1: $(JULIAHOME)/doc/man/julia.1 | $(build_man1dir)

base/Base.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,6 @@ using .PermutedDimsArrays
213213
include("sort.jl")
214214
using .Sort
215215

216-
# BinaryPlatforms, used by Artifacts. Needs `Sort`.
217-
include("binaryplatforms.jl")
218-
219216
# Fast math
220217
include("fastmath.jl")
221218
using .FastMath
@@ -269,6 +266,9 @@ include("linking.jl")
269266
include("staticdata.jl")
270267
include("loading.jl")
271268

269+
# BinaryPlatforms, used by Artifacts. Needs `Sort`.
270+
include("binaryplatforms.jl")
271+
272272
# misc useful functions & macros
273273
include("timing.jl")
274274
include("client.jl")

base/array.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1356,7 +1356,7 @@ end
13561356

13571357
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
13581358
push!(a::AbstractVector, iter...) = append!(a, iter)
1359-
append!(a::AbstractVector, iter...) = (for v in iter; append!(a, v); end; return a)
1359+
append!(a::AbstractVector, iter...) = (foreach(v -> append!(a, v), iter); a)
13601360

13611361
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
13621362
n = Int(length(iter))::Int

base/binaryplatforms.jl

+57-16
Original file line numberDiff line numberDiff line change
@@ -841,20 +841,48 @@ function parse_dl_name_version(path::AbstractString, os::AbstractString)
841841
return parse_dl_name_version(string(path)::String, string(os)::String)
842842
end
843843

844+
function get_csl_member(member::Symbol)
845+
# If CompilerSupportLibraries_jll is an stdlib, we can just grab things from it
846+
csl_pkgids = filter(pkgid -> pkgid.name == "CompilerSupportLibraries_jll", keys(Base.loaded_modules))
847+
if !isempty(csl_pkgids)
848+
CSL_mod = Base.loaded_modules[first(csl_pkgids)]
849+
850+
# This can fail during bootstrap, so we skip in that case.
851+
if isdefined(CSL_mod, member)
852+
return getproperty(CSL_mod, member)
853+
end
854+
end
855+
856+
return nothing
857+
end
858+
844859
"""
845860
detect_libgfortran_version()
846861
847862
Inspects the current Julia process to determine the libgfortran version this Julia is
848-
linked against (if any).
863+
linked against (if any). Returns `nothing` if no libgfortran version dependence is
864+
detected.
849865
"""
850866
function detect_libgfortran_version()
851-
libgfortran_paths = filter!(x -> occursin("libgfortran", x), Libdl.dllist())
852-
if isempty(libgfortran_paths)
867+
function get_libgfortran_path()
868+
# If CompilerSupportLibraries_jll is an stdlib, we can just directly ask for
869+
# the path here, without checking `dllist()`:
870+
libgfortran_path = get_csl_member(:libgfortran_path)
871+
if libgfortran_path !== nothing
872+
return libgfortran_path::String
873+
end
874+
875+
# Otherwise, look for it having already been loaded by something
876+
libgfortran_paths = filter!(x -> occursin("libgfortran", x), Libdl.dllist())
877+
if !isempty(libgfortran_paths)
878+
return first(libgfortran_paths)::String
879+
end
880+
853881
# One day, I hope to not be linking against libgfortran in base Julia
854882
return nothing
855883
end
856-
libgfortran_path = first(libgfortran_paths)
857884

885+
libgfortran_path = get_libgfortran_path()
858886
name, version = parse_dl_name_version(libgfortran_path, os())
859887
if version === nothing
860888
# Even though we complain about this, we allow it to continue in the hopes that
@@ -878,24 +906,37 @@ it is linked against (if any). `max_minor_version` is the latest version in the
878906
3.4 series of GLIBCXX where the search is performed.
879907
"""
880908
function detect_libstdcxx_version(max_minor_version::Int=30)
881-
libstdcxx_paths = filter!(x -> occursin("libstdc++", x), Libdl.dllist())
882-
if isempty(libstdcxx_paths)
883-
# This can happen if we were built by clang, so we don't link against
884-
# libstdc++ at all.
909+
function get_libstdcxx_handle()
910+
# If CompilerSupportLibraries_jll is an stdlib, we can just directly open it
911+
libstdcxx = get_csl_member(:libstdcxx)
912+
if libstdcxx !== nothing
913+
return nothing
914+
end
915+
916+
# Otherwise, look for it having already been loaded by something
917+
libstdcxx_paths = filter!(x -> occursin("libstdc++", x), Libdl.dllist())
918+
if !isempty(libstdcxx_paths)
919+
return Libdl.dlopen(first(libstdcxx_paths), Libdl.RTLD_NOLOAD)::Ptr{Cvoid}
920+
end
921+
922+
# One day, I hope to not be linking against libgfortran in base Julia
885923
return nothing
886924
end
887925

888926
# Brute-force our way through GLIBCXX_* symbols to discover which version we're linked against
889-
hdl = Libdl.dlopen(first(libstdcxx_paths))::Ptr{Cvoid}
890-
# Try all GLIBCXX versions down to GCC v4.8:
891-
# https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
892-
for minor_version in max_minor_version:-1:18
893-
if Libdl.dlsym(hdl, "GLIBCXX_3.4.$(minor_version)"; throw_error=false) !== nothing
894-
Libdl.dlclose(hdl)
895-
return VersionNumber("3.4.$(minor_version)")
927+
libstdcxx = get_libstdcxx_handle()
928+
929+
if libstdcxx !== nothing
930+
# Try all GLIBCXX versions down to GCC v4.8:
931+
# https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
932+
for minor_version in max_minor_version:-1:18
933+
if Libdl.dlsym(libstdcxx, "GLIBCXX_3.4.$(minor_version)"; throw_error=false) !== nothing
934+
Libdl.dlclose(libstdcxx)
935+
return VersionNumber("3.4.$(minor_version)")
936+
end
896937
end
897938
end
898-
Libdl.dlclose(hdl)
939+
Libdl.dlclose(libstdcxx)
899940
return nothing
900941
end
901942

base/libdl.jl

+9-6
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,17 @@ struct LazyLibraryPath
333333
pieces::Tuple{Vararg{Any}}
334334
LazyLibraryPath(pieces...) = new(pieces)
335335
end
336-
Base.string(llp::LazyLibraryPath) = joinpath(String[string(p) for p in llp.pieces])
336+
@inline Base.string(llp::LazyLibraryPath) = joinpath(String[string(p) for p in llp.pieces])
337337
Base.cconvert(::Type{Cstring}, llp::LazyLibraryPath) = Base.cconvert(Cstring, string(llp))
338338
# Define `print` so that we can wrap this in a `LazyString`
339339
Base.print(io::IO, llp::LazyLibraryPath) = print(io, string(llp))
340340

341-
# Helper to get `Sys.BINDIR` at runtime
342-
struct SysBindirGetter; end
343-
Base.string(::SysBindirGetter) = dirname(Sys.BINDIR)
341+
# Helper to get `$(private_shlibdir)` at runtime
342+
struct PrivateShlibdirGetter; end
343+
const private_shlibdir = Base.OncePerProcess{String}() do
344+
dirname(dlpath("libjulia-internal"))
345+
end
346+
Base.string(::PrivateShlibdirGetter) = private_shlibdir()
344347

345348
"""
346349
BundledLazyLibraryPath
@@ -349,10 +352,10 @@ Helper type for lazily constructed library paths that are stored within the
349352
bundled Julia distribution, primarily for use by Base modules.
350353
351354
```
352-
libfoo = LazyLibrary(BundledLazyLibraryPath("lib/libfoo.so.1.2.3"))
355+
libfoo = LazyLibrary(BundledLazyLibraryPath("libfoo.so.1.2.3"))
353356
```
354357
"""
355-
BundledLazyLibraryPath(subpath) = LazyLibraryPath(SysBindirGetter(), subpath)
358+
BundledLazyLibraryPath(subpath) = LazyLibraryPath(PrivateShlibdirGetter(), subpath)
356359

357360

358361
"""

base/loading.jl

+39-24
Original file line numberDiff line numberDiff line change
@@ -1280,17 +1280,21 @@ function _include_from_serialized(pkg::PkgId, path::String, ocachepath::Union{No
12801280
sv = try
12811281
if ocachepath !== nothing
12821282
@debug "Loading object cache file $ocachepath for $(repr("text/plain", pkg))"
1283-
ccall(:jl_restore_package_image_from_file, Ref{SimpleVector}, (Cstring, Any, Cint, Cstring, Cint),
1283+
ccall(:jl_restore_package_image_from_file, Any, (Cstring, Any, Cint, Cstring, Cint),
12841284
ocachepath, depmods, #=completeinfo=#false, pkg.name, ignore_native)
12851285
else
12861286
@debug "Loading cache file $path for $(repr("text/plain", pkg))"
1287-
ccall(:jl_restore_incremental, Ref{SimpleVector}, (Cstring, Any, Cint, Cstring),
1287+
ccall(:jl_restore_incremental, Any, (Cstring, Any, Cint, Cstring),
12881288
path, depmods, #=completeinfo=#false, pkg.name)
12891289
end
12901290
finally
12911291
lock(require_lock)
12921292
end
1293+
if isa(sv, Exception)
1294+
return sv
1295+
end
12931296

1297+
sv = sv::SimpleVector
12941298
edges = sv[3]::Vector{Any}
12951299
ext_edges = sv[4]::Union{Nothing,Vector{Any}}
12961300
extext_methods = sv[5]::Vector{Any}
@@ -1438,7 +1442,6 @@ function run_module_init(mod::Module, i::Int=1)
14381442
end
14391443

14401444
function run_package_callbacks(modkey::PkgId)
1441-
@assert modkey != precompilation_target
14421445
run_extension_callbacks(modkey)
14431446
assert_havelock(require_lock)
14441447
unlock(require_lock)
@@ -1568,7 +1571,7 @@ function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}
15681571
uuid_trigger = UUID(totaldeps[trigger]::String)
15691572
trigger_id = PkgId(uuid_trigger, trigger)
15701573
push!(trigger_ids, trigger_id)
1571-
if !haskey(Base.loaded_modules, trigger_id) || haskey(package_locks, trigger_id) || (trigger_id == precompilation_target)
1574+
if !haskey(Base.loaded_modules, trigger_id) || haskey(package_locks, trigger_id)
15721575
trigger1 = get!(Vector{ExtensionId}, EXT_DORMITORY, trigger_id)
15731576
push!(trigger1, gid)
15741577
else
@@ -1581,7 +1584,6 @@ end
15811584
loading_extension::Bool = false
15821585
loadable_extensions::Union{Nothing,Vector{PkgId}} = nothing
15831586
precompiling_extension::Bool = false
1584-
precompilation_target::Union{Nothing,PkgId} = nothing
15851587
function run_extension_callbacks(extid::ExtensionId)
15861588
assert_havelock(require_lock)
15871589
succeeded = try
@@ -2178,7 +2180,6 @@ function canstart_loading(modkey::PkgId, build_id::UInt128, stalecheck::Bool)
21782180
# load already in progress for this module on the task
21792181
task, cond = loading
21802182
deps = String[modkey.name]
2181-
pkgid = modkey
21822183
assert_havelock(cond.lock)
21832184
if debug_loading_deadlocks && current_task() !== task
21842185
waiters = Dict{Task,Pair{Task,PkgId}}() # invert to track waiting tasks => loading tasks
@@ -2198,18 +2199,26 @@ function canstart_loading(modkey::PkgId, build_id::UInt128, stalecheck::Bool)
21982199
end
21992200
end
22002201
if current_task() === task
2201-
others = String[modkey.name] # repeat this to emphasize the cycle here
2202+
push!(deps, modkey.name) # repeat this to emphasize the cycle here
2203+
others = Set{String}()
22022204
for each in package_locks # list the rest of the packages being loaded too
22032205
if each[2][1] === task
22042206
other = each[1].name
2205-
other == modkey.name || other == pkgid.name || push!(others, other)
2207+
other == modkey.name || push!(others, other)
22062208
end
22072209
end
2210+
# remove duplicates from others already in deps
2211+
for dep in deps
2212+
delete!(others, dep)
2213+
end
22082214
msg = sprint(deps, others) do io, deps, others
22092215
print(io, "deadlock detected in loading ")
2210-
join(io, deps, " -> ")
2211-
print(io, " -> ")
2212-
join(io, others, " && ")
2216+
join(io, deps, " using ")
2217+
if !isempty(others)
2218+
print(io, " (while loading ")
2219+
join(io, others, " and ")
2220+
print(io, ")")
2221+
end
22132222
end
22142223
throw(ConcurrencyViolationError(msg))
22152224
end
@@ -2383,6 +2392,10 @@ function __require(into::Module, mod::Symbol)
23832392
error("`using/import $mod` outside of a Module detected. Importing a package outside of a module \
23842393
is not allowed during package precompilation.")
23852394
end
2395+
topmod = moduleroot(into)
2396+
if nameof(topmod) === mod
2397+
return topmod
2398+
end
23862399
@lock require_lock begin
23872400
LOADING_CACHE[] = LoadingCache()
23882401
try
@@ -2491,10 +2504,7 @@ function _require_prelocked(uuidkey::PkgId, env=nothing)
24912504
try
24922505
toplevel_load[] = false
24932506
m = __require_prelocked(uuidkey, env)
2494-
if m === nothing
2495-
error("package `$(uuidkey.name)` did not define the expected \
2496-
module `$(uuidkey.name)`, check for typos in package module name")
2497-
end
2507+
m isa Module || check_package_module_loaded_error(uuidkey)
24982508
finally
24992509
toplevel_load[] = last
25002510
end_loading(uuidkey, m)
@@ -2984,6 +2994,9 @@ const newly_inferred = CodeInstance[]
29842994
function include_package_for_output(pkg::PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String},
29852995
concrete_deps::typeof(_concrete_dependencies), source::Union{Nothing,String})
29862996

2997+
@lock require_lock begin
2998+
m = start_loading(pkg, UInt128(0), false)
2999+
@assert m === nothing
29873000
append!(empty!(Base.DEPOT_PATH), depot_path)
29883001
append!(empty!(Base.DL_LOAD_PATH), dl_load_path)
29893002
append!(empty!(Base.LOAD_PATH), load_path)
@@ -2992,6 +3005,8 @@ function include_package_for_output(pkg::PkgId, input::String, depot_path::Vecto
29923005
Base._track_dependencies[] = true
29933006
get!(Base.PkgOrigin, Base.pkgorigins, pkg).path = input
29943007
append!(empty!(Base._concrete_dependencies), concrete_deps)
3008+
end
3009+
29953010
uuid_tuple = pkg.uuid === nothing ? (UInt64(0), UInt64(0)) : convert(NTuple{2, UInt64}, pkg.uuid)
29963011

29973012
ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Base.__toplevel__, uuid_tuple)
@@ -3010,21 +3025,22 @@ function include_package_for_output(pkg::PkgId, input::String, depot_path::Vecto
30103025
ccall(:jl_set_newly_inferred, Cvoid, (Any,), nothing)
30113026
end
30123027
# check that the package defined the expected module so we can give a nice error message if not
3013-
Base.check_package_module_loaded(pkg)
3028+
m = maybe_root_module(pkg)
3029+
m isa Module || check_package_module_loaded_error(pkg)
30143030

30153031
# Re-populate the runtime's newly-inferred array, which will be included
30163032
# in the output. We removed it above to avoid including any code we may
30173033
# have compiled for error handling and validation.
30183034
ccall(:jl_set_newly_inferred, Cvoid, (Any,), newly_inferred)
3035+
@lock require_lock end_loading(pkg, m)
3036+
# insert_extension_triggers(pkg)
3037+
# run_package_callbacks(pkg)
30193038
end
30203039

3021-
function check_package_module_loaded(pkg::PkgId)
3022-
if !haskey(Base.loaded_modules, pkg)
3023-
# match compilecache error type for non-125 errors
3024-
error("$(repr("text/plain", pkg)) did not define the expected module `$(pkg.name)`, \
3025-
check for typos in package module name")
3026-
end
3027-
return nothing
3040+
function check_package_module_loaded_error(pkg)
3041+
# match compilecache error type for non-125 errors
3042+
error("package `$(pkg.name)` did not define the expected \
3043+
module `$(pkg.name)`, check for typos in package module name")
30283044
end
30293045

30303046
# protects against PkgId and UUID being imported and losing Base prefix
@@ -3100,7 +3116,6 @@ function create_expr_cache(pkg::PkgId, input::String, output::String, output_o::
31003116
Base.track_nested_precomp($(_pkg_str(vcat(Base.precompilation_stack, pkg))))
31013117
Base.loadable_extensions = $(_pkg_str(loadable_exts))
31023118
Base.precompiling_extension = $(loading_extension)
3103-
Base.precompilation_target = $(_pkg_str(pkg))
31043119
Base.include_package_for_output($(_pkg_str(pkg)), $(repr(abspath(input))), $(repr(depot_path)), $(repr(dl_load_path)),
31053120
$(repr(load_path)), $(_pkg_str(concrete_deps)), $(repr(source_path(nothing))))
31063121
""")

base/multidimensional.jl

+5-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,11 @@ module IteratorsMD
9191
flatten(I::Tuple{Any}) = Tuple(I[1])
9292
@inline flatten(I::Tuple) = (Tuple(I[1])..., flatten(tail(I))...)
9393
CartesianIndex(index::Tuple{Vararg{Union{Integer, CartesianIndex}}}) = CartesianIndex(index...)
94-
show(io::IO, i::CartesianIndex) = (print(io, "CartesianIndex"); show(io, i.I))
94+
function show(io::IO, i::CartesianIndex)
95+
print(io, "CartesianIndex(")
96+
join(io, i.I, ", ")
97+
print(io, ")")
98+
end
9599

96100
# length
97101
length(::CartesianIndex{N}) where {N} = N

base/toml_parser.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ isvalid_hex(c::Char) = isdigit(c) || ('a' <= c <= 'f') || ('A' <= c <= 'F')
770770
isvalid_oct(c::Char) = '0' <= c <= '7'
771771
isvalid_binary(c::Char) = '0' <= c <= '1'
772772

773-
const ValidSigs = Union{typeof.([isvalid_hex, isvalid_oct, isvalid_binary, isdigit])...}
773+
const ValidSigs = Union{typeof(isvalid_hex), typeof(isvalid_oct), typeof(isvalid_binary), typeof(isdigit)}
774774
# This function eats things accepted by `f` but also allows eating `_` in between
775775
# digits. Returns if it ate at lest one character and if it ate an underscore
776776
function accept_batch_underscore(l::Parser, f::ValidSigs, fail_if_underscore=true)::Err{Tuple{Bool, Bool}}

0 commit comments

Comments
 (0)