Skip to content

Commit

Permalink
Fix the return type in broadcast
Browse files Browse the repository at this point in the history
  • Loading branch information
pabloferz committed Dec 12, 2016
1 parent 579cfcb commit 0f50336
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 17 deletions.
8 changes: 4 additions & 4 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1768,10 +1768,10 @@ function mapslices(f, A::AbstractArray, dims::AbstractVector)
end

# These are needed because map(eltype, As) is not inferrable
promote_eltype_op(::Any) = (@_pure_meta; Any)
promote_eltype_op(op, A) = (@_pure_meta; promote_op(op, eltype(A)))
promote_eltype_op(op, A, B) = (@_pure_meta; promote_op(op, eltype(A), eltype(B)))
promote_eltype_op(op, A, B, C, D...) = (@_pure_meta; promote_eltype_op(op, eltype(A), promote_eltype_op(op, B, C, D...)))
promote_eltype_op(::Any) = Any
promote_eltype_op(op, A) = (@_inline_meta; promote_op(op, eltype(A)))
promote_eltype_op(op, A, B) = (@_inline_meta; promote_op(op, eltype(A), eltype(B)))
promote_eltype_op(op, A, B, C, D...) = (@_inline_meta; promote_eltype_op(op, eltype(A), promote_eltype_op(op, B, C, D...)))

## 1 argument

Expand Down
14 changes: 5 additions & 9 deletions base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Broadcast

using Base.Cartesian
using Base: promote_eltype_op, _default_eltype, linearindices, tail, OneTo, to_shape,
using Base: @pure, promote_eltype_op, _promote_op, linearindices, tail, OneTo, to_shape,
_msk_end, unsafe_bitgetindex, bitcache_chunks, bitcache_size, dumpbitcache
import Base: .+, .-, .*, ./, .\, .//, .==, .<, .!=, .<=, , .%, .<<, .>>, .^
import Base: broadcast
Expand Down Expand Up @@ -257,17 +257,13 @@ end
@inline broadcast_elwise_op(f, As...) =
broadcast!(f, similar(Array{promote_eltype_op(f, As...)}, broadcast_indices(As...)), As...)

ftype(f, A) = typeof(f)
ftype(f, A...) = typeof(a -> f(a...))
ftype(T::DataType, A) = Type{T}
ftype(T::DataType, A...) = Type{T}
ziptype(A) = Tuple{eltype(A)}
ziptype(A, B) = Iterators.Zip2{Tuple{eltype(A)}, Tuple{eltype(B)}}
@inline ziptype(A, B, C, D...) = Iterators.Zip{Tuple{eltype(A)}, ziptype(B, C, D...)}
@pure typestuple(a) = Tuple{eltype(a)}
@pure typestuple(T::Type) = Tuple{Type{T}}
@pure typestuple(a, b...) = Tuple{typestuple(a).types..., typestuple(b...).types...}

# broadcast methods that dispatch on the type of the final container
@inline function broadcast_c(f, ::Type{Array}, As...)
T = _default_eltype(Base.Generator{ziptype(As...), ftype(f, As...)})
T = _promote_op(f, typestuple(As...))
shape = broadcast_indices(As...)
iter = CartesianRange(shape)
if isleaftype(T)
Expand Down
12 changes: 8 additions & 4 deletions base/promotion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -222,18 +222,22 @@ minmax(x::Real, y::Real) = minmax(promote(x, y)...)
# operations, so it is advised against overriding them
_default_type(T::Type) = (@_pure_meta; T)

if isdefined(Core, :Inference)
_promote_op(f::ANY, t::ANY) = Core.Inference.return_type(f, t)
else
_promote_op(f::ANY, t::ANY) = Any
end

promote_op(::Any...) = (@_pure_meta; Any)
function promote_op{S}(f, ::Type{S})
@_inline_meta
Z = Tuple{_default_type(S)}
T = _default_eltype(Generator{Z, typeof(f)})
T = _promote_op(f, Tuple{_default_type(S)})
isleaftype(S) && return isleaftype(T) ? T : Any
return typejoin(S, T)
end
function promote_op{R,S}(f, ::Type{R}, ::Type{S})
@_inline_meta
Z = Iterators.Zip2{Tuple{_default_type(R)}, Tuple{_default_type(S)}}
T = _default_eltype(Generator{Z, typeof(a -> f(a...))})
T = _promote_op(f, Tuple{_default_type(R), _default_type(S)})
isleaftype(R) && isleaftype(S) && return isleaftype(T) ? T : Any
return typejoin(R, S, T)
end
Expand Down
3 changes: 3 additions & 0 deletions test/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,6 @@ StrangeType18623(x,y) = (x,y)
# Issue 18622
@test @inferred muladd.([1.0], [2.0], [3.0])::Vector{Float64} == [5.0]
@test @inferred tuple.(1:3, 4:6, 7:9)::Vector{Tuple{Int,Int,Int}} == [(1,4,7), (2,5,8), (3,6,9)]

# 19419
@test @inferred broadcast(round, Int, [1])::Vector{Int} == [1]

0 comments on commit 0f50336

Please sign in to comment.