Skip to content

Commit 3ace05a

Browse files
committed
Make promote_op rely on Core.Inference.return_type
1 parent c10667f commit 3ace05a

File tree

19 files changed

+143
-167
lines changed

19 files changed

+143
-167
lines changed

base/abstractarray.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,12 +1407,12 @@ end
14071407

14081408
# These are needed because map(eltype, As) is not inferrable
14091409
promote_eltype_op(::Any) = (@_pure_meta; Bottom)
1410-
promote_eltype_op{T}(op, ::AbstractArray{T}) = (@_pure_meta; promote_op(op, T))
1411-
promote_eltype_op{T}(op, ::T ) = (@_pure_meta; promote_op(op, T))
1412-
promote_eltype_op{R,S}(op, ::AbstractArray{R}, ::AbstractArray{S}) = (@_pure_meta; promote_op(op, R, S))
1413-
promote_eltype_op{R,S}(op, ::AbstractArray{R}, ::S) = (@_pure_meta; promote_op(op, R, S))
1414-
promote_eltype_op{R,S}(op, ::R, ::AbstractArray{S}) = (@_pure_meta; promote_op(op, R, S))
1415-
promote_eltype_op(op, A, B, C, D...) = (@_pure_meta; promote_op(op, eltype(A), promote_eltype_op(op, B, C, D...)))
1410+
promote_eltype_op(op, A) = (@_pure_meta; _promote_op(op, eltype(A)))
1411+
promote_eltype_op{T}(op, ::AbstractArray{T}) = (@_pure_meta; _promote_op(op, T))
1412+
promote_eltype_op{T}(op, ::AbstractArray{T}, A) = (@_pure_meta; _promote_op(op, T, eltype(A)))
1413+
promote_eltype_op{T}(op, A, ::AbstractArray{T}) = (@_pure_meta; _promote_op(op, eltype(A), T))
1414+
promote_eltype_op{R,S}(op, ::AbstractArray{R}, ::AbstractArray{S}) = (@_pure_meta; _promote_op(op, R, S))
1415+
promote_eltype_op(op, A, B, C, D...) = (@_pure_meta; promote_eltype_op(op, promote_eltype_op(op, A, B), C, D...))
14161416

14171417
## 1 argument
14181418
map!{F}(f::F, A::AbstractArray) = map!(f, A, A)

base/arraymath.jl

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,30 +35,26 @@ function !(A::AbstractArray{Bool})
3535
end
3636

3737
## Binary arithmetic operators ##
38-
@pure promote_array_type{S<:Number, A<:AbstractArray}(F, ::Type{S}, ::Type{A}) =
39-
promote_array_type(F, S, eltype(A), promote_op(F, S, eltype(A)))
40-
@pure promote_array_type{S<:Number, A<:AbstractArray}(F, ::Type{A}, ::Type{S}) =
41-
promote_array_type(F, S, eltype(A), promote_op(F, eltype(A), S))
4238

43-
@pure promote_array_type{S, A, P}(F, ::Type{S}, ::Type{A}, ::Type{P}) = P
44-
@pure promote_array_type{S<:Real, A<:AbstractFloat, P}(F, ::Type{S}, ::Type{A}, ::Type{P}) = A
45-
@pure promote_array_type{S<:Integer, A<:Integer, P}(F::typeof(./), ::Type{S}, ::Type{A}, ::Type{P}) = P
46-
@pure promote_array_type{S<:Integer, A<:Integer, P}(F::typeof(.\), ::Type{S}, ::Type{A}, ::Type{P}) = P
47-
@pure promote_array_type{S<:Integer, A<:Integer, P}(F, ::Type{S}, ::Type{A}, ::Type{P}) = A
48-
@pure promote_array_type{S<:Integer, P}(F::typeof(./), ::Type{S}, ::Type{Bool}, ::Type{P}) = P
49-
@pure promote_array_type{S<:Integer, P}(F::typeof(.\), ::Type{S}, ::Type{Bool}, ::Type{P}) = P
50-
@pure promote_array_type{S<:Integer, P}(F, ::Type{S}, ::Type{Bool}, ::Type{P}) = P
39+
promote_array_type(F, ::Type, ::Type, T::Type) = T
40+
promote_array_type{S<:Real, A<:AbstractFloat}(F, ::Type{S}, ::Type{A}, ::Type) = A
41+
promote_array_type{S<:Integer, A<:Integer}(F, ::Type{S}, ::Type{A}, ::Type) = A
42+
promote_array_type{S<:Integer, A<:Integer}(::typeof(./), ::Type{S}, ::Type{A}, T::Type) = T
43+
promote_array_type{S<:Integer, A<:Integer}(::typeof(.\), ::Type{S}, ::Type{A}, T::Type) = T
44+
promote_array_type{S<:Integer}(::typeof(./), ::Type{S}, ::Type{Bool}, T::Type) = T
45+
promote_array_type{S<:Integer}(::typeof(.\), ::Type{S}, ::Type{Bool}, T::Type) = T
46+
promote_array_type{S<:Integer}(F, ::Type{S}, ::Type{Bool}, T::Type) = T
5147

5248
for f in (:+, :-, :div, :mod, :&, :|, :$)
53-
@eval ($f){S,T}(A::AbstractArray{S}, B::AbstractArray{T}) =
54-
_elementwise($f, A, B, promote_eltype_op($f, A, B))
49+
@eval ($f)(A::AbstractArray, B::AbstractArray) =
50+
_elementwise($f, promote_op($f, eltype(A), eltype(B)), A, B)
5551
end
56-
function _elementwise{S,T}(op, A::AbstractArray{S}, B::AbstractArray{T}, ::Type{Any})
57-
promote_shape(A,B) # check size compatibility
52+
function _elementwise(op, ::Type{Any}, A::AbstractArray, B::AbstractArray)
53+
promote_shape(A, B) # check size compatibility
5854
return broadcast(op, A, B)
5955
end
60-
function _elementwise{S,T,R}(op, A::AbstractArray{S}, B::AbstractArray{T}, ::Type{R})
61-
F = similar(A, R, promote_shape(A,B))
56+
function _elementwise(op, T::Type, A::AbstractArray, B::AbstractArray)
57+
F = similar(A, T, promote_shape(A, B))
6258
for (iF, iA, iB) in zip(eachindex(F), eachindex(A), eachindex(B))
6359
@inbounds F[iF] = op(A[iA], B[iB])
6460
end
@@ -67,15 +63,21 @@ end
6763

6864
for f in (:.+, :.-, :.*, :./, :.\, :.^, :, :.%, :.<<, :.>>, :div, :mod, :rem, :&, :|, :$)
6965
@eval begin
70-
function ($f){T}(A::Number, B::AbstractArray{T})
71-
F = similar(B, promote_array_type($f,typeof(A),typeof(B)))
66+
function ($f)(A::Number, B::AbstractArray)
67+
P = promote_op($f, typeof(A), eltype(B))
68+
T = promote_array_type($f, typeof(A), eltype(B), P)
69+
T === Any && return [($f)(A, b) for b in B]
70+
F = similar(B, T)
7271
for (iF, iB) in zip(eachindex(F), eachindex(B))
7372
@inbounds F[iF] = ($f)(A, B[iB])
7473
end
7574
return F
7675
end
77-
function ($f){T}(A::AbstractArray{T}, B::Number)
78-
F = similar(A, promote_array_type($f,typeof(A),typeof(B)))
76+
function ($f)(A::AbstractArray, B::Number)
77+
P = promote_op($f, eltype(A), typeof(B))
78+
T = promote_array_type($f, typeof(B), eltype(A), P)
79+
T === Any && return [($f)(a, B) for a in A]
80+
F = similar(A, T)
7981
for (iF, iA) in zip(eachindex(F), eachindex(A))
8082
@inbounds F[iF] = ($f)(A[iA], B)
8183
end

base/bitarray.jl

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,18 +1035,29 @@ for f in (:+, :-)
10351035
return r
10361036
end
10371037
end
1038+
10381039
for (f) in (:.+, :.-)
1039-
for (arg1, arg2, T, fargs) in ((:(B::BitArray), :(x::Bool) , Int , :(b, x)),
1040-
(:(B::BitArray), :(x::Number) , :(promote_array_type($f, BitArray, typeof(x))), :(b, x)),
1041-
(:(x::Bool) , :(B::BitArray), Int , :(x, b)),
1042-
(:(x::Number) , :(B::BitArray), :(promote_array_type($f, typeof(x), BitArray)), :(x, b)))
1040+
for (arg1, arg2, T, t) in ((:(B::BitArray), :(x::Bool) , Int , (:b, :x)),
1041+
(:(B::BitArray), :(x::Number) , :(Bool, typeof(x)), (:b, :x)),
1042+
(:(x::Bool) , :(B::BitArray), Int , (:x, :b)),
1043+
(:(x::Number) , :(B::BitArray), :(typeof(x), Bool), (:x, :b)))
10431044
@eval function ($f)($arg1, $arg2)
1044-
r = Array{$T}(size(B))
1045+
$(if T === Int
1046+
quote
1047+
r = Array{Int}(size(B))
1048+
end
1049+
else
1050+
quote
1051+
T = promote_op($f, $(T.args[1]), $(T.args[2]))
1052+
T === Any && return [($f)($(t[1]), $(t[2])) for b in B]
1053+
r = Array{T}(size(B))
1054+
end
1055+
end)
10451056
bi = start(B)
10461057
ri = 1
10471058
while !done(B, bi)
10481059
b, bi = next(B, bi)
1049-
@inbounds r[ri] = ($f)($fargs...)
1060+
@inbounds r[ri] = ($f)($(t[1]), $(t[2]))
10501061
ri += 1
10511062
end
10521063
return r
@@ -1078,9 +1089,8 @@ function div(x::Bool, B::BitArray)
10781089
end
10791090
function div(x::Number, B::BitArray)
10801091
all(B) || throw(DivideError())
1081-
pt = promote_array_type(div, typeof(x), BitArray)
10821092
y = div(x, true)
1083-
reshape(pt[ y for i = 1:length(B) ], size(B))
1093+
return fill(y, size(B))
10841094
end
10851095

10861096
function mod(A::BitArray, B::BitArray)
@@ -1099,15 +1109,16 @@ function mod(x::Bool, B::BitArray)
10991109
end
11001110
function mod(x::Number, B::BitArray)
11011111
all(B) || throw(DivideError())
1102-
pt = promote_array_type(mod, typeof(x), BitArray)
11031112
y = mod(x, true)
1104-
reshape(pt[ y for i = 1:length(B) ], size(B))
1113+
return fill(y, size(B))
11051114
end
11061115

11071116
for f in (:div, :mod)
11081117
@eval begin
11091118
function ($f)(B::BitArray, x::Number)
1110-
F = Array{promote_array_type($f, BitArray, typeof(x))}(size(B))
1119+
T = promote_op($f, Bool, typeof(x))
1120+
T === Any && return [($f)(b, x) for b in B]
1121+
F = Array{T}(size(B))
11111122
for i = 1:length(F)
11121123
F[i] = ($f)(B[i], x)
11131124
end

base/broadcast.jl

Lines changed: 2 additions & 2 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_op, promote_eltype, promote_eltype_op, @get!, _msk_end, unsafe_bitgetindex, linearindices, tail, OneTo, to_shape
6+
using Base: promote_eltype_op, @get!, _msk_end, unsafe_bitgetindex, linearindices, tail, OneTo, to_shape
77
import Base: .+, .-, .*, ./, .\, .//, .==, .<, .!=, .<=, , .%, .<<, .>>, .^
88
export broadcast, broadcast!, bitbroadcast, dotview
99
export broadcast_getindex, broadcast_setindex!
@@ -299,7 +299,7 @@ end
299299
## elementwise operators ##
300300

301301
for op in (:÷, :%, :<<, :>>, :-, :/, :\, ://, :^)
302-
@eval $(Symbol(:., op))(A::AbstractArray, B::AbstractArray) = broadcast($(op), A, B)
302+
@eval $(Symbol(:., op))(A::AbstractArray, B::AbstractArray) = broadcast($op, A, B)
303303
end
304304
.+(As::AbstractArray...) = broadcast(+, As...)
305305
.*(As::AbstractArray...) = broadcast(*, As...)

base/char.jl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@ hash(x::Char, h::UInt) = hash_uint64(((UInt64(x)+hashchar_seed)<<32) $ UInt64(h)
4040
+(x::Char, y::Integer) = Char(Int32(x) + Int32(y))
4141
+(x::Integer, y::Char) = y + x
4242

43-
Base.promote_op{I<:Integer}(::typeof(-), ::Type{Char}, ::Type{I}) = Char
44-
Base.promote_op{I<:Integer}(::typeof(+), ::Type{Char}, ::Type{I}) = Char
45-
Base.promote_op{I<:Integer}(::typeof(+), ::Type{I}, ::Type{Char}) = Char
46-
4743
bswap(x::Char) = Char(bswap(UInt32(x)))
4844

4945
print(io::IO, c::Char) = (write(io, c); nothing)

base/complex.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,8 @@ big{T<:AbstractFloat,N}(A::AbstractArray{Complex{T},N}) = convert(AbstractArray{
804804

805805
## promotion to complex ##
806806

807-
promote_array_type{S<:Union{Complex, Real}, AT<:AbstractFloat, P}(F, ::Type{S}, ::Type{Complex{AT}}, ::Type{P}) = Complex{AT}
807+
_default_type(T::Type{Complex}) = Complex{Int}
808+
promote_array_type{S<:Union{Complex, Real}, T<:AbstractFloat}(F, ::Type{S}, ::Type{Complex{T}}, ::Type) = Complex{T}
808809

809810
function complex{S<:Real,T<:Real}(A::AbstractArray{S}, B::AbstractArray{T})
810811
if size(A) != size(B); throw(DimensionMismatch()); end

base/dates/arithmetic.jl

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -94,21 +94,3 @@ end
9494
# AbstractArray{TimeType}, AbstractArray{TimeType}
9595
(-){T<:TimeType}(x::OrdinalRange{T}, y::OrdinalRange{T}) = collect(x) - collect(y)
9696
(-){T<:TimeType}(x::Range{T}, y::Range{T}) = collect(x) - collect(y)
97-
98-
# promotion rules
99-
100-
for op in (:+, :-, :.+, :.-)
101-
@eval begin
102-
Base.promote_op{P<:Period}(::typeof($op), ::Type{P}, ::Type{P}) = P
103-
Base.promote_op{P1<:Period,P2<:Period}(::typeof($op), ::Type{P1}, ::Type{P2}) = CompoundPeriod
104-
Base.promote_op{D<:Date}(::typeof($op), ::Type{D}, ::Type{D}) = Day
105-
Base.promote_op{D<:DateTime}(::typeof($op), ::Type{D}, ::Type{D}) = Millisecond
106-
end
107-
end
108-
109-
for op in (:/, :%, :div, :mod, :./, :.%)
110-
@eval begin
111-
Base.promote_op{P<:Period}(::typeof($op), ::Type{P}, ::Type{P}) = typeof($op(1,1))
112-
Base.promote_op{P<:Period,R<:Real}(::typeof($op), ::Type{P}, ::Type{R}) = P
113-
end
114-
end

base/float.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ promote_rule(::Type{Float64}, ::Type{Float32}) = Float64
230230
widen(::Type{Float16}) = Float32
231231
widen(::Type{Float32}) = Float64
232232

233+
_default_type(T::Union{Type{Real},Type{AbstractFloat}}) = Float64
234+
233235
## floating point arithmetic ##
234236
-(x::Float32) = box(Float32,neg_float(unbox(Float32,x)))
235237
-(x::Float64) = box(Float64,neg_float(unbox(Float64,x)))

base/int.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ promote_rule{T<:BitSigned64}(::Type{UInt64}, ::Type{T}) = UInt64
305305
promote_rule{T<:Union{UInt32, UInt64}}(::Type{T}, ::Type{Int128}) = Int128
306306
promote_rule{T<:BitSigned}(::Type{UInt128}, ::Type{T}) = UInt128
307307

308+
_default_type(T::Type{Unsigned}) = UInt
309+
_default_type(T::Union{Type{Integer},Type{Signed}}) = Int
310+
308311
## traits ##
309312

310313
typemin(::Type{Int8 }) = Int8(-128)

base/irrationals.jl

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@ promote_rule{s}(::Type{Irrational{s}}, ::Type{Float32}) = Float32
1010
promote_rule{s,t}(::Type{Irrational{s}}, ::Type{Irrational{t}}) = Float64
1111
promote_rule{s,T<:Number}(::Type{Irrational{s}}, ::Type{T}) = promote_type(Float64,T)
1212

13-
promote_op{S<:Irrational,T<:Irrational}(op::Any, ::Type{S}, ::Type{T}) =
14-
promote_op(op, Float64, Float64)
15-
promote_op{S<:Irrational,T<:Number}(op::Any, ::Type{S}, ::Type{T}) =
16-
promote_op(op, Float64, T)
17-
promote_op{S<:Irrational,T<:Number}(op::Any, ::Type{T}, ::Type{S}) =
18-
promote_op(op, T, Float64)
19-
2013
convert(::Type{AbstractFloat}, x::Irrational) = Float64(x)
2114
convert(::Type{Float16}, x::Irrational) = Float16(Float32(x))
2215
convert{T<:Real}(::Type{Complex{T}}, x::Irrational) = convert(Complex{T}, convert(T,x))

0 commit comments

Comments
 (0)