Skip to content

Commit 9ee861f

Browse files
authored
Backports for Julia 1.10.7 (#56381)
Backported PRs: - [x] #50832 <!-- Subtype: bug fix for bounds with deeper covariant var --> - [x] #51782 <!-- Fix remove-addrspaces pass in the presence of globals with addrspaces --> - [x] #55720 <!-- Fix `pkgdir` for extensions --> - [x] #55773 <!-- Add compat entry for `Base.donotdelete` --> - [x] #55886 <!-- irrationals: restrict assume effects annotations to known types --> - [x] #55867 <!-- update `hash` doc string: `widen` not required any more --> - [x] #56148 <!-- Make loading work when stdlib deps are missing in the manifest --> - [x] #55870 <!-- fix infinite recursion in `promote_type` for `Irrational` --> - [x] #56252 <!-- REPL: fix brace detection when ' is used for transpose --> - [x] #56264 <!-- inference: fix inference error from constructing invalid `TypeVar` --> - [x] #56276 <!-- move time_imports and trace_* macros to Base but remain owned by InteractiveUtils --> - [x] #56254 <!-- REPL: don't complete str and cmd macros when the input matches the internal name like `r_` to `r"` --> - [x] #56280 <!-- Fix trampoline warning on x86 as well --> - [x] #56304 <!-- typeintersect: more fastpath to skip intersect under circular env --> - [x] #56306 <!-- InteractiveUtils.jl: fixes issue where subtypes resolves bindings and causes deprecation warnings --> - [x] #42080 <!-- recommend explicit `using Foo: Foo, ...` in package code (was: "using considered harmful") --> - [x] #56441 <!-- Profile: mention `kill -s SIGUSR1 julia_pid` for Linux --> - [x] #56511 <!-- The `info` in LAPACK calls should be a Ref instead of a Ptr --> - [x] #55052 <!-- Fix `(l/r)mul!` with `Diagonal`/`Bidiagonal` --> - [x] #52694 <!-- Reinstate similar for AbstractQ for backward compatibility -->
2 parents 67dffc4 + db84d85 commit 9ee861f

File tree

66 files changed

+793
-348
lines changed

Some content is hidden

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

66 files changed

+793
-348
lines changed

base/compiler/ssair/domtree.jl

+1-4
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,7 @@ function SNCA!(domtree::GenericDomTree{IsPostDom}, blocks::Vector{BasicBlock}, m
332332
ancestors = copy(D.to_parent_pre)
333333
relevant_blocks = IsPostDom ? (1:max_pre) : (2:max_pre)
334334
for w::PreNumber in reverse(relevant_blocks)
335-
# LLVM initializes this to the parent, the paper initializes this to
336-
# `w`, but it doesn't really matter (the parent is a predecessor, so at
337-
# worst we'll discover it below). Save a memory reference here.
338-
semi_w = typemax(PreNumber)
335+
semi_w = ancestors[w]
339336
last_linked = PreNumber(w + 1)
340337
for v dom_edges(domtree, blocks, D.from_pre[w])
341338
# For the purpose of the domtree, ignore virtual predecessors into

base/compiler/tfuncs.jl

+10-2
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,16 @@ add_tfunc(svec, 0, INT_INF, @nospecs((𝕃::AbstractLattice, args...)->SimpleVec
574574
return TypeVar
575575
end
576576
end
577-
tv = TypeVar(nval, lb, ub)
578-
return PartialTypeVar(tv, lb_certain, ub_certain)
577+
lb_valid = lb isa Type || lb isa TypeVar
578+
ub_valid = ub isa Type || ub isa TypeVar
579+
if lb_valid && ub_valid
580+
tv = TypeVar(nval, lb, ub)
581+
return PartialTypeVar(tv, lb_certain, ub_certain)
582+
elseif !lb_valid && lb_certain
583+
return Union{}
584+
elseif !ub_valid && ub_certain
585+
return Union{}
586+
end
579587
end
580588
return TypeVar
581589
end

base/docs/basedocs.jl

+11
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ kw"help", kw"Julia", kw"julia", kw""
3636
available for direct use. Names can also be used via dot syntax (e.g. `Foo.foo` to access
3737
the name `foo`), whether they are `export`ed or not.
3838
See the [manual section about modules](@ref modules) for details.
39+
40+
!!! note
41+
When two or more packages/modules export a name and that name does not refer to the
42+
same thing in each of the packages, and the packages are loaded via `using` without
43+
an explicit list of names, it is an error to reference that name without qualification.
44+
It is thus recommended that code intended to be forward-compatible with future versions
45+
of its dependencies and of Julia, e.g., code in released packages, list the names it
46+
uses from each loaded package, e.g., `using Foo: Foo, f` rather than `using Foo`.
3947
"""
4048
kw"using"
4149

@@ -3285,6 +3293,9 @@ unused and delete the entire benchmark code).
32853293
`donotdelete(1+1)`, no add instruction needs to be executed at runtime and
32863294
the code is semantically equivalent to `donotdelete(2).`
32873295
3296+
!!! compat "Julia 1.8"
3297+
This method was added in Julia 1.8.
3298+
32883299
# Examples
32893300
32903301
```julia

base/hashing.jl

+1-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ optional second argument `h` is another hash code to be mixed with the result.
1111
New types should implement the 2-argument form, typically by calling the 2-argument `hash`
1212
method recursively in order to mix hashes of the contents with each other (and with `h`).
1313
Typically, any type that implements `hash` should also implement its own [`==`](@ref) (hence
14-
[`isequal`](@ref)) to guarantee the property mentioned above. Types supporting subtraction
15-
(operator `-`) should also implement [`widen`](@ref), which is required to hash
16-
values inside heterogeneous arrays.
14+
[`isequal`](@ref)) to guarantee the property mentioned above.
1715
1816
The hash value may change when a new Julia process is started.
1917

base/irrationals.jl

+24-9
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,22 @@ promote_rule(::Type{<:AbstractIrrational}, ::Type{Float16}) = Float16
4242
promote_rule(::Type{<:AbstractIrrational}, ::Type{Float32}) = Float32
4343
promote_rule(::Type{<:AbstractIrrational}, ::Type{<:AbstractIrrational}) = Float64
4444
promote_rule(::Type{<:AbstractIrrational}, ::Type{T}) where {T<:Real} = promote_type(Float64, T)
45-
promote_rule(::Type{S}, ::Type{T}) where {S<:AbstractIrrational,T<:Number} = promote_type(promote_type(S, real(T)), T)
45+
46+
function promote_rule(::Type{S}, ::Type{T}) where {S<:AbstractIrrational,T<:Number}
47+
U = promote_type(S, real(T))
48+
if S <: U
49+
# prevent infinite recursion
50+
promote_type(Float64, T)
51+
else
52+
promote_type(U, T)
53+
end
54+
end
4655

4756
AbstractFloat(x::AbstractIrrational) = Float64(x)::Float64
4857
Float16(x::AbstractIrrational) = Float16(Float32(x)::Float32)
4958
Complex{T}(x::AbstractIrrational) where {T<:Real} = Complex{T}(T(x))
5059

51-
# XXX this may change `DEFAULT_PRECISION`, thus not effect free
52-
@assume_effects :total function Rational{T}(x::AbstractIrrational) where T<:Integer
60+
function _irrational_to_rational(::Type{T}, x::AbstractIrrational) where T<:Integer
5361
o = precision(BigFloat)
5462
p = 256
5563
while true
@@ -63,13 +71,16 @@ Complex{T}(x::AbstractIrrational) where {T<:Real} = Complex{T}(T(x))
6371
p += 32
6472
end
6573
end
66-
Rational{BigInt}(x::AbstractIrrational) = throw(ArgumentError("Cannot convert an AbstractIrrational to a Rational{BigInt}: use rationalize(BigInt, x) instead"))
74+
Rational{T}(x::AbstractIrrational) where {T<:Integer} = _irrational_to_rational(T, x)
75+
_throw_argument_error_irrational_to_rational_bigint() = throw(ArgumentError("Cannot convert an AbstractIrrational to a Rational{BigInt}: use rationalize(BigInt, x) instead"))
76+
Rational{BigInt}(::AbstractIrrational) = _throw_argument_error_irrational_to_rational_bigint()
6777

68-
@assume_effects :total function (t::Type{T})(x::AbstractIrrational, r::RoundingMode) where T<:Union{Float32,Float64}
78+
function _irrational_to_float(::Type{T}, x::AbstractIrrational, r::RoundingMode) where T<:Union{Float32,Float64}
6979
setprecision(BigFloat, 256) do
7080
T(BigFloat(x)::BigFloat, r)
7181
end
7282
end
83+
(::Type{T})(x::AbstractIrrational, r::RoundingMode) where {T<:Union{Float32,Float64}} = _irrational_to_float(T, x, r)
7384

7485
float(::Type{<:AbstractIrrational}) = Float64
7586

@@ -107,14 +118,18 @@ end
107118
<=(x::AbstractFloat, y::AbstractIrrational) = x < y
108119

109120
# Irrational vs Rational
110-
@assume_effects :total function rationalize(::Type{T}, x::AbstractIrrational; tol::Real=0) where T
121+
function _rationalize_irrational(::Type{T}, x::AbstractIrrational, tol::Real) where {T<:Integer}
111122
return rationalize(T, big(x), tol=tol)
112123
end
113-
@assume_effects :total function lessrational(rx::Rational{<:Integer}, x::AbstractIrrational)
114-
# an @assume_effects :total version of `<` for determining if the rationalization of
115-
# an irrational number required rounding up or down
124+
function rationalize(::Type{T}, x::AbstractIrrational; tol::Real=0) where {T<:Integer}
125+
return _rationalize_irrational(T, x, tol)
126+
end
127+
function _lessrational(rx::Rational, x::AbstractIrrational)
116128
return rx < big(x)
117129
end
130+
function lessrational(rx::Rational, x::AbstractIrrational)
131+
return _lessrational(rx, x)
132+
end
118133
function <(x::AbstractIrrational, y::Rational{T}) where T
119134
T <: Unsigned && x < 0.0 && return true
120135
rx = rationalize(T, x)

base/loading.jl

+102-39
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,21 @@ function find_package(arg)
305305
return locate_package(pkg, env)
306306
end
307307

308+
# is there a better/faster ground truth?
309+
function is_stdlib(pkgid::PkgId)
310+
pkgid.name in readdir(Sys.STDLIB) || return false
311+
stdlib_root = joinpath(Sys.STDLIB, pkgid.name)
312+
project_file = locate_project_file(stdlib_root)
313+
if project_file isa String
314+
d = parsed_toml(project_file)
315+
uuid = get(d, "uuid", nothing)
316+
if uuid !== nothing
317+
return UUID(uuid) == pkgid.uuid
318+
end
319+
end
320+
return false
321+
end
322+
308323
"""
309324
Base.identify_package_env(name::String)::Union{Tuple{PkgId, String}, Nothing}
310325
Base.identify_package_env(where::Union{Module,PkgId}, name::String)::Union{Tuple{PkgId, String} Nothing}
@@ -333,6 +348,12 @@ function identify_package_env(where::PkgId, name::String)
333348
end
334349
break # found in implicit environment--return "not found"
335350
end
351+
if pkg_env === nothing && is_stdlib(where)
352+
# if not found it could be that manifests are from a different julia version/commit
353+
# where stdlib dependencies have changed, so look up deps based on the stdlib Project.toml
354+
# as a fallback
355+
pkg_env = identify_stdlib_project_dep(where, name)
356+
end
336357
end
337358
if cache !== nothing
338359
cache.identified_where[(where, name)] = pkg_env
@@ -359,6 +380,22 @@ function identify_package_env(name::String)
359380
return pkg_env
360381
end
361382

383+
function identify_stdlib_project_dep(stdlib::PkgId, depname::String)
384+
@debug """
385+
Stdlib $(repr("text/plain", stdlib)) is trying to load `$depname`
386+
which is not listed as a dep in the load path manifests, so resorting to search
387+
in the stdlib Project.tomls for true deps"""
388+
stdlib_projfile = locate_project_file(joinpath(Sys.STDLIB, stdlib.name))
389+
stdlib_projfile === nothing && return nothing
390+
found = explicit_project_deps_get(stdlib_projfile, depname)
391+
if found !== nothing
392+
@debug "$(repr("text/plain", stdlib)) indeed depends on $depname in project $stdlib_projfile"
393+
pkgid = PkgId(found, depname)
394+
return pkgid, stdlib_projfile
395+
end
396+
return nothing
397+
end
398+
362399
_nothing_or_first(x) = x === nothing ? nothing : first(x)
363400

364401
"""
@@ -499,6 +536,8 @@ package root.
499536
To get the root directory of the package that implements the current module
500537
the form `pkgdir(@__MODULE__)` can be used.
501538
539+
If an extension module is given, the root of the parent package is returned.
540+
502541
```julia-repl
503542
julia> pkgdir(Foo)
504543
"/path/to/Foo.jl"
@@ -514,7 +553,19 @@ function pkgdir(m::Module, paths::String...)
514553
rootmodule = moduleroot(m)
515554
path = pathof(rootmodule)
516555
path === nothing && return nothing
517-
return joinpath(dirname(dirname(path)), paths...)
556+
original = path
557+
path, base = splitdir(dirname(path))
558+
if base == "src"
559+
# package source in `../src/Foo.jl`
560+
elseif base == "ext"
561+
# extension source in `../ext/FooExt.jl`
562+
elseif basename(path) == "ext"
563+
# extension source in `../ext/FooExt/FooExt.jl`
564+
path = dirname(path)
565+
else
566+
error("Unexpected path structure for module source: $original")
567+
end
568+
return joinpath(path, paths...)
518569
end
519570

520571
function get_pkgversion_from_path(path)
@@ -827,14 +878,14 @@ function explicit_manifest_deps_get(project_file::String, where::PkgId, name::St
827878
entry = entry::Dict{String, Any}
828879
uuid = get(entry, "uuid", nothing)::Union{String, Nothing}
829880
uuid === nothing && continue
881+
# deps is either a list of names (deps = ["DepA", "DepB"]) or
882+
# a table of entries (deps = {"DepA" = "6ea...", "DepB" = "55d..."}
883+
deps = get(entry, "deps", nothing)::Union{Vector{String}, Dict{String, Any}, Nothing}
830884
if UUID(uuid) === where.uuid
831885
found_where = true
832-
# deps is either a list of names (deps = ["DepA", "DepB"]) or
833-
# a table of entries (deps = {"DepA" = "6ea...", "DepB" = "55d..."}
834-
deps = get(entry, "deps", nothing)::Union{Vector{String}, Dict{String, Any}, Nothing}
835886
if deps isa Vector{String}
836887
found_name = name in deps
837-
break
888+
found_name && @goto done
838889
elseif deps isa Dict{String, Any}
839890
deps = deps::Dict{String, Any}
840891
for (dep, uuid) in deps
@@ -853,30 +904,33 @@ function explicit_manifest_deps_get(project_file::String, where::PkgId, name::St
853904
return PkgId(UUID(uuid), name)
854905
end
855906
exts = extensions[where.name]::Union{String, Vector{String}}
907+
weakdeps = get(entry, "weakdeps", nothing)::Union{Vector{String}, Dict{String, Any}, Nothing}
856908
if (exts isa String && name == exts) || (exts isa Vector{String} && name in exts)
857-
weakdeps = get(entry, "weakdeps", nothing)::Union{Vector{String}, Dict{String, Any}, Nothing}
858-
if weakdeps !== nothing
859-
if weakdeps isa Vector{String}
860-
found_name = name in weakdeps
861-
break
862-
elseif weakdeps isa Dict{String, Any}
863-
weakdeps = weakdeps::Dict{String, Any}
864-
for (dep, uuid) in weakdeps
865-
uuid::String
866-
if dep === name
867-
return PkgId(UUID(uuid), name)
909+
for deps′ in [weakdeps, deps]
910+
if deps′ !== nothing
911+
if deps′ isa Vector{String}
912+
found_name = name in deps′
913+
found_name && @goto done
914+
elseif deps′ isa Dict{String, Any}
915+
deps′ = deps′::Dict{String, Any}
916+
for (dep, uuid) in deps′
917+
uuid::String
918+
if dep === name
919+
return PkgId(UUID(uuid), name)
920+
end
921+
end
868922
end
869923
end
870924
end
871925
end
872-
end
873926
# `name` is not an ext, do standard lookup as if this was the parent
874927
return identify_package(PkgId(UUID(uuid), dep_name), name)
875928
end
876929
end
877930
end
878931
end
879932
end
933+
@label done
880934
found_where || return nothing
881935
found_name || return PkgId(name)
882936
# Only reach here if deps was not a dict which mean we have a unique name for the dep
@@ -1211,12 +1265,13 @@ function insert_extension_triggers(env::String, pkg::PkgId)::Union{Nothing,Missi
12111265
proj_pkg = project_file_name_uuid(project_file, pkg.name)
12121266
if pkg == proj_pkg
12131267
d_proj = parsed_toml(project_file)
1214-
weakdeps = get(d_proj, "weakdeps", nothing)::Union{Nothing, Vector{String}, Dict{String,Any}}
12151268
extensions = get(d_proj, "extensions", nothing)::Union{Nothing, Dict{String, Any}}
12161269
extensions === nothing && return
1217-
weakdeps === nothing && return
1218-
if weakdeps isa Dict{String, Any}
1219-
return _insert_extension_triggers(pkg, extensions, weakdeps)
1270+
weakdeps = get(Dict{String, Any}, d_proj, "weakdeps")::Union{Vector{String}, Dict{String,Any}}
1271+
deps = get(Dict{String, Any}, d_proj, "deps")::Union{Vector{String}, Dict{String,Any}}
1272+
if weakdeps isa Dict{String,Any} && deps isa Dict{String,Any}
1273+
total_deps = merge(weakdeps, deps)
1274+
return _insert_extension_triggers(pkg, extensions, total_deps)
12201275
end
12211276
end
12221277

@@ -1231,35 +1286,43 @@ function insert_extension_triggers(env::String, pkg::PkgId)::Union{Nothing,Missi
12311286
uuid = get(entry, "uuid", nothing)::Union{String, Nothing}
12321287
uuid === nothing && continue
12331288
if UUID(uuid) == pkg.uuid
1234-
weakdeps = get(entry, "weakdeps", nothing)::Union{Nothing, Vector{String}, Dict{String,Any}}
12351289
extensions = get(entry, "extensions", nothing)::Union{Nothing, Dict{String, Any}}
12361290
extensions === nothing && return
1237-
weakdeps === nothing && return
1238-
if weakdeps isa Dict{String, Any}
1239-
return _insert_extension_triggers(pkg, extensions, weakdeps)
1291+
weakdeps = get(Dict{String, Any}, entry, "weakdeps")::Union{Vector{String}, Dict{String,Any}}
1292+
deps = get(Dict{String, Any}, entry, "deps")::Union{Vector{String}, Dict{String,Any}}
1293+
1294+
function expand_deps_list(deps′::Vector{String})
1295+
deps′_expanded = Dict{String, Any}()
1296+
for (dep_name, entries) in d
1297+
dep_name in deps′ || continue
1298+
entries::Vector{Any}
1299+
if length(entries) != 1
1300+
error("expected a single entry for $(repr(dep_name)) in $(repr(project_file))")
1301+
end
1302+
entry = first(entries)::Dict{String, Any}
1303+
uuid = entry["uuid"]::String
1304+
deps′_expanded[dep_name] = uuid
1305+
end
1306+
return deps′_expanded
12401307
end
12411308

1242-
d_weakdeps = Dict{String, Any}()
1243-
for (dep_name, entries) in d
1244-
dep_name in weakdeps || continue
1245-
entries::Vector{Any}
1246-
if length(entries) != 1
1247-
error("expected a single entry for $(repr(dep_name)) in $(repr(project_file))")
1248-
end
1249-
entry = first(entries)::Dict{String, Any}
1250-
uuid = entry["uuid"]::String
1251-
d_weakdeps[dep_name] = uuid
1309+
if weakdeps isa Vector{String}
1310+
weakdeps = expand_deps_list(weakdeps)
12521311
end
1253-
@assert length(d_weakdeps) == length(weakdeps)
1254-
return _insert_extension_triggers(pkg, extensions, d_weakdeps)
1312+
if deps isa Vector{String}
1313+
deps = expand_deps_list(deps)
1314+
end
1315+
1316+
total_deps = merge(weakdeps, deps)
1317+
return _insert_extension_triggers(pkg, extensions, total_deps)
12551318
end
12561319
end
12571320
end
12581321
end
12591322
return nothing
12601323
end
12611324

1262-
function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}, weakdeps::Dict{String, Any})
1325+
function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}, totaldeps::Dict{String, Any})
12631326
for (ext, triggers) in extensions
12641327
triggers = triggers::Union{String, Vector{String}}
12651328
triggers isa String && (triggers = [triggers])
@@ -1273,7 +1336,7 @@ function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}
12731336
push!(trigger1, gid)
12741337
for trigger in triggers
12751338
# TODO: Better error message if this lookup fails?
1276-
uuid_trigger = UUID(weakdeps[trigger]::String)
1339+
uuid_trigger = UUID(totaldeps[trigger]::String)
12771340
trigger_id = PkgId(uuid_trigger, trigger)
12781341
if !haskey(Base.loaded_modules, trigger_id) || haskey(package_locks, trigger_id)
12791342
trigger1 = get!(Vector{ExtensionId}, EXT_DORMITORY, trigger_id)

0 commit comments

Comments
 (0)