Skip to content

Commit 51cedb5

Browse files
committed
Revert "Simplify broadcast's eltype promotion mechanism and make it handle more cases. (#19723)"
This reverts commit 9cc7815.
1 parent 35d1780 commit 51cedb5

File tree

4 files changed

+23
-17
lines changed

4 files changed

+23
-17
lines changed

base/broadcast.jl

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -272,14 +272,24 @@ end
272272
@inline broadcast_elwise_op(f, As...) =
273273
broadcast!(f, similar(Array{promote_eltype_op(f, As...)}, broadcast_indices(As...)), As...)
274274

275-
eltypestuple(a) = (Base.@_pure_meta; Tuple{eltype(a)})
276-
eltypestuple(T::Type) = (Base.@_pure_meta; Tuple{Type{T}})
277-
eltypestuple(a, b...) = (Base.@_pure_meta; Tuple{eltypestuple(a).types..., eltypestuple(b...).types...})
278-
_broadcast_eltype(f, A, Bs...) = Base._return_type(f, eltypestuple(A, Bs...))
275+
ftype(f, A) = typeof(f)
276+
ftype(f, A...) = typeof(a -> f(a...))
277+
ftype(T::Type, A...) = Type{T}
278+
279+
typestuple(a) = (Base.@_pure_meta; Tuple{eltype(a)})
280+
typestuple(T::Type) = (Base.@_pure_meta; Tuple{Type{T}})
281+
typestuple(a, b...) = (Base.@_pure_meta; Tuple{typestuple(a).types..., typestuple(b...).types...})
282+
283+
ziptype(A) = typestuple(A)
284+
ziptype(A, B) = (Base.@_pure_meta; Iterators.Zip2{typestuple(A), typestuple(B)})
285+
@inline ziptype(A, B, C, D...) = Iterators.Zip{typestuple(A), ziptype(B, C, D...)}
286+
287+
_broadcast_type(f, T::Type, As...) = Base._return_type(f, typestuple(T, As...))
288+
_broadcast_type(f, A, Bs...) = Base._default_eltype(Base.Generator{ziptype(A, Bs...), ftype(f, A, Bs...)})
279289

280290
# broadcast methods that dispatch on the type of the final container
281291
@inline function broadcast_c(f, ::Type{Array}, A, Bs...)
282-
T = _broadcast_eltype(f, A, Bs...)
292+
T = _broadcast_type(f, A, Bs...)
283293
shape = broadcast_indices(A, Bs...)
284294
iter = CartesianRange(shape)
285295
if isleaftype(T)
@@ -297,7 +307,7 @@ function broadcast_c(f, ::Type{Tuple}, As...)
297307
end
298308
@inline function broadcast_c(f, ::Type{Nullable}, a...)
299309
nonnull = all(hasvalue, a)
300-
S = _broadcast_eltype(f, a...)
310+
S = _broadcast_type(f, a...)
301311
if isleaftype(S) && null_safe_eltype_op(f, a...)
302312
Nullable{S}(f(map(unsafe_get, a)...), nonnull)
303313
else

base/promotion.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,15 @@ end
231231
promote_op(::Any...) = (@_pure_meta; Any)
232232
function promote_op{S}(f, ::Type{S})
233233
@_inline_meta
234-
T = _return_type(f, Tuple{_default_type(S)})
234+
Z = Tuple{_default_type(S)}
235+
T = _default_eltype(Generator{Z, typeof(f)})
235236
isleaftype(S) && return isleaftype(T) ? T : Any
236237
return typejoin(S, T)
237238
end
238239
function promote_op{R,S}(f, ::Type{R}, ::Type{S})
239240
@_inline_meta
240-
T = _return_type(f, Tuple{_default_type(R), _default_type(S)})
241+
Z = Iterators.Zip2{Tuple{_default_type(R)}, Tuple{_default_type(S)}}
242+
T = _default_eltype(Generator{Z, typeof(a -> f(a...))})
241243
isleaftype(R) && isleaftype(S) && return isleaftype(T) ? T : Any
242244
return typejoin(R, S, T)
243245
end

base/sparse/higherorderfns.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ function _noshapecheck_map{Tf,N}(f::Tf, A::SparseVecOrMat, Bs::Vararg{SparseVecO
7373
fofzeros = f(_zeros_eltypes(A, Bs...)...)
7474
fpreszeros = _iszero(fofzeros)
7575
maxnnzC = fpreszeros ? min(length(A), _sumnnzs(A, Bs...)) : length(A)
76-
entrytypeC = Base.Broadcast._broadcast_eltype(f, A, Bs...)
76+
entrytypeC = Base.Broadcast._broadcast_type(f, A, Bs...)
7777
indextypeC = _promote_indtype(A, Bs...)
7878
C = _allocres(size(A), indextypeC, entrytypeC, maxnnzC)
7979
return fpreszeros ? _map_zeropres!(f, C, A, Bs...) :
@@ -101,7 +101,7 @@ function _diffshape_broadcast{Tf,N}(f::Tf, A::SparseVecOrMat, Bs::Vararg{SparseV
101101
fofzeros = f(_zeros_eltypes(A, Bs...)...)
102102
fpreszeros = _iszero(fofzeros)
103103
indextypeC = _promote_indtype(A, Bs...)
104-
entrytypeC = Base.Broadcast._broadcast_eltype(f, A, Bs...)
104+
entrytypeC = Base.Broadcast._broadcast_type(f, A, Bs...)
105105
shapeC = to_shape(Base.Broadcast.broadcast_indices(A, Bs...))
106106
maxnnzC = fpreszeros ? _checked_maxnnzbcres(shapeC, A, Bs...) : _densennz(shapeC)
107107
C = _allocres(shapeC, indextypeC, entrytypeC, maxnnzC)

test/broadcast.jl

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ StrangeType18623(x,y) = (x,y)
363363
let
364364
f(A, n) = broadcast(x -> +(x, n), A)
365365
@test @inferred(f([1.0], 1)) == [2.0]
366-
g() = (a = 1; Base.Broadcast._broadcast_eltype(x -> x + a, 1.0))
366+
g() = (a = 1; Base.Broadcast._broadcast_type(x -> x + a, 1.0))
367367
@test @inferred(g()) === Float64
368368
end
369369

@@ -418,9 +418,3 @@ let io = IOBuffer()
418418
broadcast(x -> print(io, x), [Nullable(1.0)])
419419
@test String(take!(io)) == "Nullable{Float64}(1.0)"
420420
end
421-
422-
# Test that broadcast's promotion mechanism handles closures accepting more than one argument.
423-
# (See issue #19641 and referenced issues and pull requests.)
424-
let f() = (a = 1; Base.Broadcast._broadcast_eltype((x, y) -> x + y + a, 1.0, 1.0))
425-
@test @inferred(f()) == Float64
426-
end

0 commit comments

Comments
 (0)