Skip to content

Commit 4e8ce61

Browse files
authored
Merge pull request #46663 from JuliaLang/backports-release-1.8
Backports for Julia 1.8.2
2 parents afb6c60 + 285b75c commit 4e8ce61

File tree

60 files changed

+544
-311
lines changed

Some content is hidden

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

60 files changed

+544
-311
lines changed

.github/workflows/statuses.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ jobs:
4848
- run: |
4949
declare -a CONTEXT_LIST=(
5050
"buildbot/tester_freebsd64"
51-
"buildbot/tester_macos64"
5251
"buildbot/tester_win32"
5352
"buildbot/tester_win64"
5453
)

base/array.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2308,7 +2308,7 @@ findall(testf::Function, A) = collect(first(p) for p in pairs(A) if testf(last(p
23082308

23092309
# Broadcasting is much faster for small testf, and computing
23102310
# integer indices from logical index using findall has a negligible cost
2311-
findall(testf::Function, A::AbstractArray) = findall(testf.(A))
2311+
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))
23122312

23132313
"""
23142314
findall(A)

base/binaryplatforms.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,7 @@ function platforms_match(a::AbstractPlatform, b::AbstractPlatform)
10271027

10281028
# Call the comparator, passing in which objects requested this comparison (one, the other, or both)
10291029
# For some comparators this doesn't matter, but for non-symmetrical comparisons, it does.
1030-
if !comparator(ak, bk, a_comp == comparator, b_comp == comparator)
1030+
if !(comparator(ak, bk, a_comp == comparator, b_comp == comparator)::Bool)
10311031
return false
10321032
end
10331033
end

base/compiler/abstractinterpretation.jl

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
111111
result = abstract_call_method(interp, method, sig_n, svec(), multiple_matches, sv)
112112
rt = result.rt
113113
edge = result.edge
114-
edge !== nothing && push!(edges, edge)
114+
edge === nothing || push!(edges, edge)
115115
this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i]
116116
this_arginfo = ArgInfo(fargs, this_argtypes)
117117
const_call_result = abstract_call_method_with_const_args(interp, result,
@@ -136,25 +136,11 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
136136
this_conditional = ignorelimited(this_rt)
137137
this_rt = widenwrappedconditional(this_rt)
138138
else
139-
if infer_compilation_signature(interp)
140-
# Also infer the compilation signature for this method, so it's available
141-
# to the compiler in case it ends up needing it (which is likely).
142-
csig = get_compileable_sig(method, sig, match.sparams)
143-
if csig !== nothing && csig !== sig
144-
# The result of this inference is not directly used, so temporarily empty
145-
# the use set for the current SSA value.
146-
saved_uses = sv.ssavalue_uses[sv.currpc]
147-
sv.ssavalue_uses[sv.currpc] = empty_bitset
148-
abstract_call_method(interp, method, csig, match.sparams, multiple_matches, sv)
149-
sv.ssavalue_uses[sv.currpc] = saved_uses
150-
end
151-
end
152-
153139
result = abstract_call_method(interp, method, sig, match.sparams, multiple_matches, sv)
154140
this_conditional = ignorelimited(result.rt)
155141
this_rt = widenwrappedconditional(result.rt)
156142
edge = result.edge
157-
edge !== nothing && push!(edges, edge)
143+
edge === nothing || push!(edges, edge)
158144
# try constant propagation with argtypes for this match
159145
# this is in preparation for inlining, or improving the return result
160146
this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i]
@@ -214,6 +200,26 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
214200

215201
rettype = from_interprocedural!(rettype, sv, arginfo, conditionals)
216202

203+
# Also considering inferring the compilation signature for this method, so
204+
# it is available to the compiler in case it ends up needing it.
205+
if infer_compilation_signature(interp) && 1 == seen == napplicable && rettype !== Any && rettype !== Union{} && !is_removable_if_unused(all_effects)
206+
match = applicable[1]::MethodMatch
207+
method = match.method
208+
sig = match.spec_types
209+
mi = specialize_method(match; preexisting=true)
210+
if mi !== nothing && !const_prop_methodinstance_heuristic(interp, match, mi::MethodInstance, arginfo, sv)
211+
csig = get_compileable_sig(method, sig, match.sparams)
212+
if csig !== nothing && csig !== sig
213+
# The result of this inference is not directly used, so temporarily empty
214+
# the use set for the current SSA value.
215+
saved_uses = sv.ssavalue_uses[sv.currpc]
216+
sv.ssavalue_uses[sv.currpc] = empty_bitset
217+
abstract_call_method(interp, method, csig, match.sparams, multiple_matches, sv)
218+
sv.ssavalue_uses[sv.currpc] = saved_uses
219+
end
220+
end
221+
end
222+
217223
if call_result_unused(sv) && !(rettype === Bottom)
218224
add_remark!(interp, sv, "Call result type was widened because the return value is unused")
219225
# We're mainly only here because the optimizer might want this code,
@@ -765,13 +771,25 @@ function collect_const_args((; argtypes)::ArgInfo)
765771
isa(a, Const) ? a.val :
766772
isconstType(a) ? (a::DataType).parameters[1] :
767773
(a::DataType).instance
768-
end for i in 2:length(argtypes) ]
774+
end for i = 2:length(argtypes) ]
775+
end
776+
777+
struct InvokeCall
778+
types # ::Type
779+
lookupsig # ::Type
780+
InvokeCall(@nospecialize(types), @nospecialize(lookupsig)) = new(types, lookupsig)
769781
end
770782

771783
function concrete_eval_call(interp::AbstractInterpreter,
772-
@nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState)
784+
@nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState,
785+
invokecall::Union{Nothing,InvokeCall}=nothing)
773786
concrete_eval_eligible(interp, f, result, arginfo, sv) || return nothing
774787
args = collect_const_args(arginfo)
788+
if invokecall !== nothing
789+
# this call should be `invoke`d, rewrite `args` back now
790+
pushfirst!(args, f, invokecall.types)
791+
f = invoke
792+
end
775793
world = get_world_counter(interp)
776794
value = try
777795
Core._call_in_world_total(world, f, args...)
@@ -811,13 +829,13 @@ struct ConstCallResults
811829
new(rt, const_result, effects)
812830
end
813831

814-
function abstract_call_method_with_const_args(interp::AbstractInterpreter, result::MethodCallResult,
815-
@nospecialize(f), arginfo::ArgInfo, match::MethodMatch,
816-
sv::InferenceState)
832+
function abstract_call_method_with_const_args(interp::AbstractInterpreter,
833+
result::MethodCallResult, @nospecialize(f), arginfo::ArgInfo, match::MethodMatch,
834+
sv::InferenceState, invokecall::Union{Nothing,InvokeCall}=nothing)
817835
if !const_prop_enabled(interp, sv, match)
818836
return nothing
819837
end
820-
val = concrete_eval_call(interp, f, result, arginfo, sv)
838+
val = concrete_eval_call(interp, f, result, arginfo, sv, invokecall)
821839
if val !== nothing
822840
add_backedge!(result.edge, sv)
823841
return val
@@ -1547,10 +1565,10 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
15471565
nargtype isa DataType || return CallMeta(Any, Effects(), false) # other cases are not implemented below
15481566
isdispatchelem(ft) || return CallMeta(Any, Effects(), false) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
15491567
ft = ft::DataType
1550-
types = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types)::Type
1568+
lookupsig = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types)::Type
15511569
nargtype = Tuple{ft, nargtype.parameters...}
15521570
argtype = Tuple{ft, argtype.parameters...}
1553-
match, valid_worlds, overlayed = findsup(types, method_table(interp))
1571+
match, valid_worlds, overlayed = findsup(lookupsig, method_table(interp))
15541572
match === nothing && return CallMeta(Any, Effects(), false)
15551573
update_valid_age!(sv, valid_worlds)
15561574
method = match.method
@@ -1569,8 +1587,10 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
15691587
# t, a = ti.parameters[i], argtypes′[i]
15701588
# argtypes′[i] = t ⊑ a ? t : a
15711589
# end
1572-
const_call_result = abstract_call_method_with_const_args(interp, result,
1573-
overlayed ? nothing : singleton_type(ft′), arginfo, match, sv)
1590+
f = overlayed ? nothing : singleton_type(ft′)
1591+
invokecall = InvokeCall(types, lookupsig)
1592+
const_call_result = abstract_call_method_with_const_args(interp,
1593+
result, f, arginfo, match, sv, invokecall)
15741594
const_result = nothing
15751595
if const_call_result !== nothing
15761596
if const_call_result.rt rt

base/compiler/methodtable.jl

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,23 @@ struct OverlayMethodTable <: MethodTableView
4444
mt::Core.MethodTable
4545
end
4646

47+
struct MethodMatchKey
48+
sig # ::Type
49+
limit::Int
50+
MethodMatchKey(@nospecialize(sig), limit::Int) = new(sig, limit)
51+
end
52+
4753
"""
4854
struct CachedMethodTable <: MethodTableView
4955
5056
Overlays another method table view with an additional local fast path cache that
5157
can respond to repeated, identical queries faster than the original method table.
5258
"""
5359
struct CachedMethodTable{T} <: MethodTableView
54-
cache::IdDict{Any, Union{Missing, MethodMatchResult}}
60+
cache::IdDict{MethodMatchKey, Union{Missing,MethodMatchResult}}
5561
table::T
5662
end
57-
CachedMethodTable(table::T) where T = CachedMethodTable{T}(IdDict{Any, Union{Missing, MethodMatchResult}}(), table)
63+
CachedMethodTable(table::T) where T = CachedMethodTable{T}(IdDict{MethodMatchKey, Union{Missing,MethodMatchResult}}(), table)
5864

5965
"""
6066
findall(sig::Type, view::MethodTableView; limit::Int=typemax(Int)) ->
@@ -109,9 +115,11 @@ function findall(@nospecialize(sig::Type), table::CachedMethodTable; limit::Int=
109115
# as for concrete types, we cache result at on the next level
110116
return findall(sig, table.table; limit)
111117
end
112-
box = Core.Box(sig)
113-
return get!(table.cache, sig) do
114-
findall(box.contents, table.table; limit)
118+
key = MethodMatchKey(sig, limit)
119+
if haskey(table.cache, key)
120+
return table.cache[key]
121+
else
122+
return table.cache[key] = findall(sig, table.table; limit)
115123
end
116124
end
117125

base/compiler/ssair/inlining.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,11 @@ function inline_invoke!(
10661066
return nothing
10671067
end
10681068

1069+
function invoke_signature(invokesig::Vector{Any})
1070+
ft, argtyps = widenconst(invokesig[2]), instanceof_tfunc(widenconst(invokesig[3]))[1]
1071+
return rewrap_unionall(Tuple{ft, unwrap_unionall(argtyps).parameters...}, argtyps)
1072+
end
1073+
10691074
function narrow_opaque_closure!(ir::IRCode, stmt::Expr, @nospecialize(info), state::InliningState)
10701075
if isa(info, OpaqueClosureCreateInfo)
10711076
lbt = argextype(stmt.args[2], ir)

base/gmp.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -667,8 +667,12 @@ function prod(arr::AbstractArray{BigInt})
667667
# to account for the rounding to limbs in MPZ.mul!
668668
# (BITS_PER_LIMB-1 would typically be enough, to which we add
669669
# 1 for the initial multiplication by init=1 in foldl)
670-
nbits = GC.@preserve arr sum(arr; init=BITS_PER_LIMB) do x
671-
abs(x.size) * BITS_PER_LIMB - leading_zeros(unsafe_load(x.d))
670+
nbits = BITS_PER_LIMB
671+
for x in arr
672+
iszero(x) && return zero(BigInt)
673+
xsize = abs(x.size)
674+
lz = GC.@preserve x leading_zeros(unsafe_load(x.d, xsize))
675+
nbits += xsize * BITS_PER_LIMB - lz
672676
end
673677
init = BigInt(; nbits)
674678
MPZ.set_si!(init, 1)

base/loading.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,12 +1587,14 @@ function create_expr_cache(pkg::PkgId, input::String, output::String, concrete_d
15871587
deps_eltype = sprint(show, eltype(concrete_deps); context = :module=>nothing)
15881588
deps = deps_eltype * "[" * join(deps_strs, ",") * "]"
15891589
trace = isassigned(PRECOMPILE_TRACE_COMPILE) ? `--trace-compile=$(PRECOMPILE_TRACE_COMPILE[])` : ``
1590-
io = open(pipeline(`$(julia_cmd()::Cmd) -O0
1591-
--output-ji $output --output-incremental=yes
1592-
--startup-file=no --history-file=no --warn-overwrite=yes
1593-
--color=$(have_color === nothing ? "auto" : have_color ? "yes" : "no")
1594-
$trace
1595-
-`, stderr = internal_stderr, stdout = internal_stdout),
1590+
io = open(pipeline(addenv(`$(julia_cmd()::Cmd) -O0
1591+
--output-ji $output --output-incremental=yes
1592+
--startup-file=no --history-file=no --warn-overwrite=yes
1593+
--color=$(have_color === nothing ? "auto" : have_color ? "yes" : "no")
1594+
$trace
1595+
-`,
1596+
"OPENBLAS_NUM_THREADS" => 1),
1597+
stderr = internal_stderr, stdout = internal_stdout),
15961598
"w", stdout)
15971599
# write data over stdin to avoid the (unlikely) case of exceeding max command line size
15981600
write(io.in, """

base/namedtuple.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ function NamedTuple{names}(nt::NamedTuple) where {names}
111111
types = Tuple{(fieldtype(nt, idx[n]) for n in 1:length(idx))...}
112112
Expr(:new, :(NamedTuple{names, $types}), Any[ :(getfield(nt, $(idx[n]))) for n in 1:length(idx) ]...)
113113
else
114-
types = Tuple{(fieldtype(typeof(nt), names[n]) for n in 1:length(names))...}
114+
length_names = length(names)::Integer
115+
types = Tuple{(fieldtype(typeof(nt), names[n]) for n in 1:length_names)...}
115116
NamedTuple{names, types}(map(Fix1(getfield, nt), names))
116117
end
117118
end
@@ -318,8 +319,8 @@ values(nt::NamedTuple) = Tuple(nt)
318319
haskey(nt::NamedTuple, key::Union{Integer, Symbol}) = isdefined(nt, key)
319320
get(nt::NamedTuple, key::Union{Integer, Symbol}, default) = haskey(nt, key) ? getfield(nt, key) : default
320321
get(f::Callable, nt::NamedTuple, key::Union{Integer, Symbol}) = haskey(nt, key) ? getfield(nt, key) : f()
321-
tail(t::NamedTuple{names}) where names = NamedTuple{tail(names)}(t)
322-
front(t::NamedTuple{names}) where names = NamedTuple{front(names)}(t)
322+
tail(t::NamedTuple{names}) where names = NamedTuple{tail(names::Tuple)}(t)
323+
front(t::NamedTuple{names}) where names = NamedTuple{front(names::Tuple)}(t)
323324

324325
@pure function diff_names(an::Tuple{Vararg{Symbol}}, bn::Tuple{Vararg{Symbol}})
325326
@nospecialize an bn

base/ordering.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ lt(o::Lt, a, b) = o.lt(a,b)
122122
@propagate_inbounds function lt(p::Perm, a::Integer, b::Integer)
123123
da = p.data[a]
124124
db = p.data[b]
125-
lt(p.order, da, db) | (!lt(p.order, db, da) & (a < b))
125+
(lt(p.order, da, db)::Bool) | (!(lt(p.order, db, da)::Bool) & (a < b))
126126
end
127127

128128
_ord(lt::typeof(isless), by::typeof(identity), order::Ordering) = order

base/permuteddimsarray.jl

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,21 @@ end
263263
P
264264
end
265265

266-
function Base._mapreduce_dim(f, op, init::Base._InitialValue, A::PermutedDimsArray, dims::Colon)
266+
const CommutativeOps = Union{typeof(+),typeof(Base.add_sum),typeof(min),typeof(max),typeof(Base._extrema_rf),typeof(|),typeof(&)}
267+
268+
function Base._mapreduce_dim(f, op::CommutativeOps, init::Base._InitialValue, A::PermutedDimsArray, dims::Colon)
269+
Base._mapreduce_dim(f, op, init, parent(A), dims)
270+
end
271+
function Base._mapreduce_dim(f::typeof(identity), op::Union{typeof(Base.mul_prod),typeof(*)}, init::Base._InitialValue, A::PermutedDimsArray{<:Union{Real,Complex}}, dims::Colon)
267272
Base._mapreduce_dim(f, op, init, parent(A), dims)
268273
end
269274

270-
function Base.mapreducedim!(f, op, B::AbstractArray{T,N}, A::PermutedDimsArray{T,N,perm,iperm}) where {T,N,perm,iperm}
275+
function Base.mapreducedim!(f, op::CommutativeOps, B::AbstractArray{T,N}, A::PermutedDimsArray{S,N,perm,iperm}) where {T,S,N,perm,iperm}
276+
C = PermutedDimsArray{T,N,iperm,perm,typeof(B)}(B) # make the inverse permutation for the output
277+
Base.mapreducedim!(f, op, C, parent(A))
278+
B
279+
end
280+
function Base.mapreducedim!(f::typeof(identity), op::Union{typeof(Base.mul_prod),typeof(*)}, B::AbstractArray{T,N}, A::PermutedDimsArray{<:Union{Real,Complex},N,perm,iperm}) where {T,N,perm,iperm}
271281
C = PermutedDimsArray{T,N,iperm,perm,typeof(B)}(B) # make the inverse permutation for the output
272282
Base.mapreducedim!(f, op, C, parent(A))
273283
B

base/process.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ function open(f::Function, cmds::AbstractCmd, args...; kwargs...)
430430
rethrow()
431431
end
432432
close(P.in)
433-
if !eof(P.out)
433+
if !(eof(P.out)::Bool)
434434
waitkill(P)
435435
throw(_UVError("open(do)", UV_EPIPE))
436436
end

base/sort.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,8 @@ const SMALL_ALGORITHM = InsertionSort
496496
const SMALL_THRESHOLD = 20
497497

498498
function sort!(v::AbstractVector, lo::Integer, hi::Integer, ::InsertionSortAlg, o::Ordering)
499-
@inbounds for i = lo+1:hi
499+
lo_plus_1 = (lo + 1)::Integer
500+
@inbounds for i = lo_plus_1:hi
500501
j = i
501502
x = v[i]
502503
while j > lo

base/special/exp.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ const J_TABLE = (0x0000000000000000, 0xaac00b1afa5abcbe, 0x9b60163da9fb3335, 0xa
177177
# XXX we want to mark :consistent-cy here so that this function can be concrete-folded,
178178
# because the effect analysis currently can't prove it in the presence of `@inbounds` or
179179
# `:boundscheck`, but still the access to `J_TABLE` is really safe here
180-
@noinline Base.@assume_effects :consistent @inline function table_unpack(ind::Int32)
180+
Base.@assume_effects :consistent function table_unpack(ind::Int32)
181181
ind = ind & 255 + 1 # 255 == length(J_TABLE) - 1
182182
j = @inbounds J_TABLE[ind]
183183
jU = reinterpret(Float64, JU_CONST | (j&JU_MASK))

base/stream.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ function wait_readnb(x::LibuvStream, nb::Int)
409409
while bytesavailable(x.buffer) < nb
410410
x.readerror === nothing || throw(x.readerror)
411411
isopen(x) || break
412-
x.status != StatusEOF || break
412+
x.status == StatusEOF && break
413413
x.throttle = max(nb, x.throttle)
414414
start_reading(x) # ensure we are reading
415415
iolock_end()
@@ -662,9 +662,11 @@ function uv_readcb(handle::Ptr{Cvoid}, nread::Cssize_t, buf::Ptr{Cvoid})
662662
elseif nread == UV_EOF # libuv called uv_stop_reading already
663663
if stream.status != StatusClosing
664664
stream.status = StatusEOF
665-
if stream isa TTY # TODO: || ccall(:uv_is_writable, Cint, (Ptr{Cvoid},), stream.handle) != 0
666-
# stream can still be used either by reseteof # TODO: or write
667-
notify(stream.cond)
665+
notify(stream.cond)
666+
if stream isa TTY
667+
# stream can still be used by reseteof (or possibly write)
668+
elseif !(stream isa PipeEndpoint) && ccall(:uv_is_writable, Cint, (Ptr{Cvoid},), stream.handle) != 0
669+
# stream can still be used by write
668670
else
669671
# underlying stream is no longer useful: begin finalization
670672
ccall(:jl_close_uv, Cvoid, (Ptr{Cvoid},), stream.handle)
@@ -673,6 +675,7 @@ function uv_readcb(handle::Ptr{Cvoid}, nread::Cssize_t, buf::Ptr{Cvoid})
673675
end
674676
else
675677
stream.readerror = _UVError("read", nread)
678+
notify(stream.cond)
676679
# This is a fatal connection error
677680
ccall(:jl_close_uv, Cvoid, (Ptr{Cvoid},), stream.handle)
678681
stream.status = StatusClosing

0 commit comments

Comments
 (0)