Skip to content

Commit 2ee7311

Browse files
authored
Merge pull request #19421 from pabloferz/pz/ziptype
Fix return type in broadcast when there are Type arguments
2 parents 840820d + 02596f9 commit 2ee7311

File tree

4 files changed

+31
-28
lines changed

4 files changed

+31
-28
lines changed

base/abstractarray.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,10 +1768,10 @@ function mapslices(f, A::AbstractArray, dims::AbstractVector)
17681768
end
17691769

17701770
# These are needed because map(eltype, As) is not inferrable
1771-
promote_eltype_op(::Any) = (@_pure_meta; Any)
1772-
promote_eltype_op(op, A) = (@_pure_meta; promote_op(op, eltype(A)))
1773-
promote_eltype_op(op, A, B) = (@_pure_meta; promote_op(op, eltype(A), eltype(B)))
1774-
promote_eltype_op(op, A, B, C, D...) = (@_pure_meta; promote_eltype_op(op, eltype(A), promote_eltype_op(op, B, C, D...)))
1771+
promote_eltype_op(::Any) = Any
1772+
promote_eltype_op(op, A) = (@_inline_meta; promote_op(op, eltype(A)))
1773+
promote_eltype_op(op, A, B) = (@_inline_meta; promote_op(op, eltype(A), eltype(B)))
1774+
promote_eltype_op(op, A, B, C, D...) = (@_inline_meta; promote_eltype_op(op, eltype(A), promote_eltype_op(op, B, C, D...)))
17751775

17761776
## 1 argument
17771777

base/broadcast.jl

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
module Broadcast
44

55
using Base.Cartesian
6-
using Base: promote_eltype_op, _default_eltype, linearindices, tail, OneTo, to_shape,
6+
using Base: @pure, promote_eltype_op, _promote_op, linearindices, tail, OneTo, to_shape,
77
_msk_end, unsafe_bitgetindex, bitcache_chunks, bitcache_size, dumpbitcache
88
import Base: .+, .-, .*, ./, .\, .//, .==, .<, .!=, .<=, , .%, .<<, .>>, .^
99
import Base: broadcast
@@ -257,26 +257,22 @@ end
257257
@inline broadcast_elwise_op(f, As...) =
258258
broadcast!(f, similar(Array{promote_eltype_op(f, As...)}, broadcast_indices(As...)), As...)
259259

260-
ftype(f, A) = typeof(f)
261-
ftype(f, A...) = typeof(a -> f(a...))
262-
ftype(T::DataType, A) = Type{T}
263-
ftype(T::DataType, A...) = Type{T}
264-
ziptype(A) = Tuple{eltype(A)}
265-
ziptype(A, B) = Iterators.Zip2{Tuple{eltype(A)}, Tuple{eltype(B)}}
266-
@inline ziptype(A, B, C, D...) = Iterators.Zip{Tuple{eltype(A)}, ziptype(B, C, D...)}
260+
@pure typestuple(a) = Tuple{eltype(a)}
261+
@pure typestuple(T::Type) = Tuple{Type{T}}
262+
@pure typestuple(a, b...) = Tuple{typestuple(a).types..., typestuple(b...).types...}
267263

268264
# broadcast methods that dispatch on the type of the final container
269-
@inline function broadcast_c(f, ::Type{Array}, As...)
270-
T = _default_eltype(Base.Generator{ziptype(As...), ftype(f, As...)})
271-
shape = broadcast_indices(As...)
265+
@inline function broadcast_c(f, ::Type{Array}, A, Bs...)
266+
T = _promote_op(f, typestuple(A, Bs...))
267+
shape = broadcast_indices(A, Bs...)
272268
iter = CartesianRange(shape)
273269
if isleaftype(T)
274-
return broadcast_t(f, T, shape, iter, As...)
270+
return broadcast_t(f, T, shape, iter, A, Bs...)
275271
end
276272
if isempty(iter)
277273
return similar(Array{T}, shape)
278274
end
279-
return broadcast_t(f, Any, shape, iter, As...)
275+
return broadcast_t(f, Any, shape, iter, A, Bs...)
280276
end
281277
function broadcast_c(f, ::Type{Tuple}, As...)
282278
shape = broadcast_indices(As...)
@@ -351,7 +347,7 @@ julia> string.(("one","two","three","four"), ": ", 1:4)
351347
"four: 4"
352348
```
353349
"""
354-
@inline broadcast(f, As...) = broadcast_c(f, containertype(As...), As...)
350+
@inline broadcast(f, A, Bs...) = broadcast_c(f, containertype(A, Bs...), A, Bs...)
355351

356352
"""
357353
bitbroadcast(f, As...)

base/promotion.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,18 +222,22 @@ minmax(x::Real, y::Real) = minmax(promote(x, y)...)
222222
# operations, so it is advised against overriding them
223223
_default_type(T::Type) = (@_pure_meta; T)
224224

225+
if isdefined(Core, :Inference)
226+
_promote_op(f::ANY, t::ANY) = Core.Inference.return_type(f, t)
227+
else
228+
_promote_op(f::ANY, t::ANY) = Any
229+
end
230+
225231
promote_op(::Any...) = (@_pure_meta; Any)
226232
function promote_op{S}(f, ::Type{S})
227233
@_inline_meta
228-
Z = Tuple{_default_type(S)}
229-
T = _default_eltype(Generator{Z, typeof(f)})
234+
T = _promote_op(f, Tuple{_default_type(S)})
230235
isleaftype(S) && return isleaftype(T) ? T : Any
231236
return typejoin(S, T)
232237
end
233238
function promote_op{R,S}(f, ::Type{R}, ::Type{S})
234239
@_inline_meta
235-
Z = Iterators.Zip2{Tuple{_default_type(R)}, Tuple{_default_type(S)}}
236-
T = _default_eltype(Generator{Z, typeof(a -> f(a...))})
240+
T = _promote_op(f, Tuple{_default_type(R), _default_type(S)})
237241
isleaftype(R) && isleaftype(S) && return isleaftype(T) ? T : Any
238242
return typejoin(R, S, T)
239243
end

test/broadcast.jl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -341,14 +341,17 @@ end
341341
immutable StrangeType18623 end
342342
StrangeType18623(x) = x
343343
StrangeType18623(x,y) = (x,y)
344-
@test @inferred broadcast(StrangeType18623, 1:3) == [1,2,3]
345-
@test @inferred broadcast(StrangeType18623, 1:3, 4:6) == [(1,4),(2,5),(3,6)]
344+
@test @inferred(broadcast(StrangeType18623, 1:3)) == [1,2,3]
345+
@test @inferred(broadcast(StrangeType18623, 1:3, 4:6)) == [(1,4),(2,5),(3,6)]
346346

347347
@test typeof(Int.(Number[1, 2, 3])) === typeof((x->Int(x)).(Number[1, 2, 3]))
348348

349-
@test @inferred broadcast(CartesianIndex, 1:2) == [CartesianIndex(1), CartesianIndex(2)]
350-
@test @inferred broadcast(CartesianIndex, 1:2, 3:4) == [CartesianIndex(1,3), CartesianIndex(2,4)]
349+
@test @inferred(broadcast(CartesianIndex, 1:2)) == [CartesianIndex(1), CartesianIndex(2)]
350+
@test @inferred(broadcast(CartesianIndex, 1:2, 3:4)) == [CartesianIndex(1,3), CartesianIndex(2,4)]
351351

352352
# Issue 18622
353-
@test @inferred muladd.([1.0], [2.0], [3.0])::Vector{Float64} == [5.0]
354-
@test @inferred tuple.(1:3, 4:6, 7:9)::Vector{Tuple{Int,Int,Int}} == [(1,4,7), (2,5,8), (3,6,9)]
353+
@test @inferred(broadcast(muladd, [1.0], [2.0], [3.0])) == [5.0]
354+
@test @inferred(broadcast(tuple, 1:3, 4:6, 7:9)) == [(1,4,7), (2,5,8), (3,6,9)]
355+
356+
# 19419
357+
@test @inferred(broadcast(round, Int, [1])) == [1]

0 commit comments

Comments
 (0)