Skip to content

Commit d2a4568

Browse files
committed
fixup! make Tuple{Union{}} unconstructable
1 parent e62b6e3 commit d2a4568

File tree

5 files changed

+29
-20
lines changed

5 files changed

+29
-20
lines changed

base/broadcast.jl

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -732,17 +732,21 @@ broadcastable(x) = collect(x)
732732
broadcastable(::Union{AbstractDict, NamedTuple}) = throw(ArgumentError("broadcasting over dictionaries and `NamedTuple`s is reserved"))
733733

734734
## Computation of inferred result type, for empty and concretely inferred cases only
735-
_broadcast_getindex_eltype(bc::Broadcasted) = Base._return_type(bc.f, eltypes(bc.args))
735+
_broadcast_getindex_eltype(bc::Broadcasted) = combine_eltypes(bc.f, bc.args)
736736
_broadcast_getindex_eltype(A) = eltype(A) # Tuple, Array, etc.
737737

738738
eltypes(::Tuple{}) = Tuple{}
739-
eltypes(t::Tuple{Any}) = Tuple{_broadcast_getindex_eltype(t[1])}
740-
eltypes(t::Tuple{Any,Any}) = Tuple{_broadcast_getindex_eltype(t[1]), _broadcast_getindex_eltype(t[2])}
741-
eltypes(t::Tuple) = Tuple{_broadcast_getindex_eltype(t[1]), eltypes(tail(t)).types...}
739+
eltypes(t::Tuple{Any}) = Iterators.TupleOrBottom(_broadcast_getindex_eltype(t[1]))
740+
eltypes(t::Tuple{Any,Any}) = Iterators.TupleOrBottom(_broadcast_getindex_eltype(t[1]), _broadcast_getindex_eltype(t[2]))
741+
# eltypes(t::Tuple) = (TT = eltypes(tail(t)); TT === Union{} ? Union{} : Iterators.TupleOrBottom(_broadcast_getindex_eltype(t[1]), TT.parameters...))
742+
eltypes(t::Tuple) = Iterators.TupleOrBottom(ntuple(i -> _broadcast_getindex_eltype(t[i]), Val(length(t)))...)
742743

743744
# Inferred eltype of result of broadcast(f, args...)
744-
combine_eltypes(f, args::Tuple) =
745-
promote_typejoin_union(Base._return_type(f, eltypes(args)))
745+
function combine_eltypes(f, args::Tuple)
746+
argT = eltypes(args)
747+
argT === Union{} && return Union{}
748+
return promote_typejoin_union(Base._return_type(f, argT))
749+
end
746750

747751
## Broadcasting core
748752

base/iterators.jl

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ using .Base:
1212
@inline, Pair, Pairs, AbstractDict, IndexLinear, IndexStyle, AbstractVector, Vector,
1313
SizeUnknown, HasLength, HasShape, IsInfinite, EltypeUnknown, HasEltype, OneTo,
1414
@propagate_inbounds, @isdefined, @boundscheck, @inbounds, Generator,
15-
AbstractRange, AbstractUnitRange, UnitRange, LinearIndices,
15+
AbstractRange, AbstractUnitRange, UnitRange, LinearIndices, TupleOrBottom,
1616
(:), |, +, -, *, !==, !, ==, !=, <=, <, >, >=, missing,
1717
any, _counttuple, eachindex, ntuple, zero, prod, reduce, in, firstindex, lastindex,
1818
tail, fieldtypes, min, max, minimum, zero, oneunit, promote, promote_shape
@@ -41,12 +41,6 @@ if Base !== Core.Compiler
4141
export partition
4242
end
4343

44-
function TupleOrBottom(tt...)
45-
any(p -> p === Union{}, tt) && return Union{}
46-
return Tuple{tt...}
47-
end
48-
49-
5044
"""
5145
Iterators.map(f, iterators...)
5246

base/promotion.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,11 @@ else
472472
_return_type(@nospecialize(f), @nospecialize(t)) = Any
473473
end
474474

475+
function TupleOrBottom(tt...)
476+
any(p -> p === Union{}, tt) && return Union{}
477+
return Tuple{tt...}
478+
end
479+
475480
"""
476481
promote_op(f, argtypes...)
477482
@@ -483,7 +488,12 @@ Guess what an appropriate container eltype would be for storing results of
483488
the container eltype on the type of the actual elements. Only in the absence of any
484489
elements (for an empty result container), it may be unavoidable to call `promote_op`.
485490
"""
486-
promote_op(f, S::Type...) = _return_type(f, Tuple{S...})
491+
function promote_op(f, S::Type...)
492+
argT = TupleOrBottom(S...)
493+
argT === Union{} && return Union{}
494+
return _return_type(f, argT)
495+
end
496+
487497

488498
## catch-alls to prevent infinite recursion when definitions are missing ##
489499

base/slicearray.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ unitaxis(::AbstractArray) = Base.OneTo(1)
4040

4141
function Slices(A::P, slicemap::SM, ax::AX) where {P,SM,AX}
4242
N = length(ax)
43-
S = Base._return_type(view, Tuple{P, map((a,l) -> l === (:) ? Colon : eltype(a), axes(A), slicemap)...})
43+
argT = map((a,l) -> l === (:) ? Colon : eltype(a), axes(A), slicemap)
44+
S = Base.promote_op(view, P, argT...)
4445
Slices{P,SM,AX,S,N}(A, slicemap, ax)
4546
end
4647

stdlib/LinearAlgebra/src/uniformscaling.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ for (t1, t2) in ((:UnitUpperTriangular, :UpperTriangular),
179179
(:UnitLowerTriangular, :LowerTriangular))
180180
@eval begin
181181
function (+)(UL::$t1, J::UniformScaling)
182-
ULnew = copymutable_oftype(UL.data, Base._return_type(+, Tuple{eltype(UL), typeof(J)}))
182+
ULnew = copymutable_oftype(UL.data, Base.promote_op(+, eltype(UL), typeof(J)))
183183
for i in axes(ULnew, 1)
184184
ULnew[i,i] = one(ULnew[i,i]) + J
185185
end
@@ -193,7 +193,7 @@ end
193193
# However, to preserve type stability, we do not special-case a
194194
# UniformScaling{<:Complex} that happens to be real.
195195
function (+)(A::Hermitian, J::UniformScaling{<:Complex})
196-
TS = Base._return_type(+, Tuple{eltype(A), typeof(J)})
196+
TS = Base.promote_op(+, eltype(A), typeof(J))
197197
B = copytri!(copymutable_oftype(parent(A), TS), A.uplo, true)
198198
for i in diagind(B)
199199
B[i] = A[i] + J
@@ -202,7 +202,7 @@ function (+)(A::Hermitian, J::UniformScaling{<:Complex})
202202
end
203203

204204
function (-)(J::UniformScaling{<:Complex}, A::Hermitian)
205-
TS = Base._return_type(+, Tuple{eltype(A), typeof(J)})
205+
TS = Base.promote_op(+, eltype(A), typeof(J))
206206
B = copytri!(copymutable_oftype(parent(A), TS), A.uplo, true)
207207
B .= .-B
208208
for i in diagind(B)
@@ -213,7 +213,7 @@ end
213213

214214
function (+)(A::AbstractMatrix, J::UniformScaling)
215215
checksquare(A)
216-
B = copymutable_oftype(A, Base._return_type(+, Tuple{eltype(A), typeof(J)}))
216+
B = copymutable_oftype(A, Base.promote_op(+, eltype(A), typeof(J)))
217217
for i in intersect(axes(A,1), axes(A,2))
218218
@inbounds B[i,i] += J
219219
end
@@ -222,7 +222,7 @@ end
222222

223223
function (-)(J::UniformScaling, A::AbstractMatrix)
224224
checksquare(A)
225-
B = convert(AbstractMatrix{Base._return_type(+, Tuple{eltype(A), typeof(J)})}, -A)
225+
B = convert(AbstractMatrix{Base.promote_op(+, eltype(A), typeof(J))}, -A)
226226
for i in intersect(axes(A,1), axes(A,2))
227227
@inbounds B[i,i] += J
228228
end

0 commit comments

Comments
 (0)