Skip to content

Commit 9df4f1a

Browse files
p-zubietanalimilan
authored andcommitted
More promote_op fixes
1 parent 1c4fa7c commit 9df4f1a

File tree

9 files changed

+45
-46
lines changed

9 files changed

+45
-46
lines changed

base/float.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ promote_rule(::Type{Float32}, ::Type{Float16}) = Float32
196196
promote_rule(::Type{Float64}, ::Type{Float16}) = Float64
197197
promote_rule(::Type{Float64}, ::Type{Float32}) = Float64
198198

199+
promote_op{Op<:typeof(trunc),T<:Union{Float32,Float64}}(::Op, ::Type{Signed}, ::Type{T}) = Int
200+
promote_op{Op<:typeof(trunc),T<:Union{Float32,Float64}}(::Op, ::Type{Unsigned}, ::Type{T}) = UInt
201+
for f in (ceil, floor, round, trunc)
202+
@eval promote_op{Op<:$(typeof(f)),T}(::Op, ::Type{T}, ::Any) = T
203+
end
204+
199205
widen(::Type{Float16}) = Float32
200206
widen(::Type{Float32}) = Float64
201207

base/irrationals.jl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +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}(::Any, ::Type{S}, ::Type{T}) = Float64
14-
promote_op{S<:Irrational,T<:Number}(::Any, ::Type{S}, ::Type{T}) = promote_type(S, T)
15-
promote_op{S<:Irrational,T<:Number}(::Any, ::Type{T}, ::Type{S}) = promote_type(T, S)
16-
1713
convert(::Type{AbstractFloat}, x::Irrational) = Float64(x)
1814
convert(::Type{Float16}, x::Irrational) = Float16(Float32(x))
1915
convert{T<:Real}(::Type{Complex{T}}, x::Irrational) = convert(Complex{T}, convert(T,x))

base/number.jl

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,16 @@ zero{T<:Number}(::Type{T}) = convert(T,0)
6363
one(x::Number) = oftype(x,1)
6464
one{T<:Number}(::Type{T}) = convert(T,1)
6565

66-
promote_op{S<:Number,T}(op::Type{T}, ::Type{S}) = T # to fix ambiguities
67-
function promote_op{S<:Number}(op::Any, ::Type{S})
68-
R = typeof(op(one(S)))
69-
R <: S ? S : R # preserve the most general (abstract) type when possible
66+
promote_op{R,S<:Number}(::Type{R}, ::Type{S}) = (@_pure_meta; R) # to fix ambiguities
67+
function promote_op{T<:Number}(op, ::Type{T})
68+
S = typeof(op(one(T)))
69+
# preserve the most general (abstract) type when possible
70+
return isleaftype(T) ? S : typejoin(S, T)
7071
end
71-
function promote_op{S<:Number,T<:Number}(op::Any, ::Type{S}, ::Type{T})
72-
R = typeof(op(one(S), one(T)))
72+
function promote_op{R<:Number,S<:Number}(op, ::Type{R}, ::Type{S})
73+
T = typeof(op(one(R), one(S)))
7374
# preserve the most general (abstract) type when possible
74-
if T <: S && R <: S
75-
return S
76-
elseif S <: T && R <: T
77-
return T
78-
else
79-
return R
80-
end
75+
return isleaftype(R) & isleaftype(S) ? T : typejoin(R, S, T)
8176
end
8277

8378
factorial(x::Number) = gamma(x + 1) # fallback for x not Integer

base/operators.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ end
4343
==(T::TypeVar, S::Type) = false
4444
==(T::Type, S::TypeVar) = false
4545

46+
for op in (<, >, <=, >=, (==))
47+
@eval promote_op{Op<:$(typeof(op))}(::Op, ::Any, ::Any) = ($(Expr(:meta, :pure)); Bool)
48+
end
49+
4650
## comparison fallbacks ##
4751

4852
!=(x,y) = !(x==y)

base/parse.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,5 @@ function parse(str::AbstractString; raise::Bool=true)
194194
end
195195
return ex
196196
end
197+
198+
promote_op{Op<:typeof(parse),T}(::Op, ::Type{T}, ::Any) = T

base/promotion.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,10 @@ minmax(x::Real, y::Real) = minmax(promote(x, y)...)
222222
# for the multiplication of two types,
223223
# promote_op{R<:MyType,S<:MyType}(::typeof(*), ::Type{R}, ::Type{S}) = MyType{multype(R,S)}
224224
promote_op(::Any) = (@_pure_meta; Bottom)
225-
promote_op(::Any, T) = (@_pure_meta; T)
225+
promote_op(::Any, ::Any) = (@_pure_meta; Any)
226+
promote_op(::Any, ::Any, ::Any) = (@_pure_meta; Any)
226227
promote_op{T}(::Type{T}, ::Any) = (@_pure_meta; T)
227-
promote_op{R,S}(::Any, ::Type{R}, ::Type{S}) = (@_pure_meta; promote_type(R, S))
228+
promote_op{Op<:typeof(convert),T}(::Op, ::Type{T}, ::Any) = (@_pure_meta, T)
228229
promote_op(op, T, S, U, V...) = (@_pure_meta; promote_op(op, T, promote_op(op, S, U, V...)))
229230

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

test/arrayops.jl

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,7 +1408,7 @@ b = rand(6,7)
14081408
# return type declarations (promote_op)
14091409
module RetTypeDecl
14101410
using Base.Test
1411-
import Base: +, *, .*, zero, one
1411+
import Base: +, *, .*, convert
14121412

14131413
immutable MeterUnits{T,P} <: Number
14141414
val::T
@@ -1422,10 +1422,8 @@ module RetTypeDecl
14221422
(*){T,pow}(x::Int, y::MeterUnits{T,pow}) = MeterUnits{typeof(x*one(T)),pow}(x*y.val)
14231423
(*){T}(x::MeterUnits{T,1}, y::MeterUnits{T,1}) = MeterUnits{T,2}(x.val*y.val)
14241424
(.*){T}(x::MeterUnits{T,1}, y::MeterUnits{T,1}) = MeterUnits{T,2}(x.val*y.val)
1425-
zero{T,pow}(x::MeterUnits{T,pow}) = MeterUnits{T,pow}(zero(T))
1426-
one{T,pow}(x::MeterUnits{T,pow}) = MeterUnits{T,pow}(one(T))
1427-
zero{T,pow}(x::Type{MeterUnits{T,pow}}) = MeterUnits{T,pow}(zero(T))
1428-
one{T,pow}(x::Type{MeterUnits{T,pow}}) = MeterUnits{T,pow}(one(T))
1425+
convert{T,pow}(::Type{MeterUnits{T,pow}}, y::Real) = MeterUnits{T,pow}(convert(T,y))
1426+
Base.promote_op{R,S}(::typeof(*), ::Type{MeterUnits{R,1}}, ::Type{MeterUnits{S,1}}) = MeterUnits{promote_type(R,S),2}
14291427

14301428
@test @inferred(m+[m,m]) == [m+m,m+m]
14311429
@test @inferred([m,m]+m) == [m+m,m+m]

test/broadcast.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,9 @@ m = [1:2;]'
165165
@test @inferred([0,1.2].+reshape([0,-2],1,1,2)) == reshape([0 -2; 1.2 -0.8],2,1,2)
166166
rt = Base.return_types(.+, Tuple{Array{Float64, 3}, Array{Int, 1}})
167167
@test length(rt) == 1 && rt[1] == Array{Float64, 3}
168-
rt = Base.return_types(broadcast, Tuple{typeof(+), Array{Float64, 3}, Array{Int, 1}})
168+
rt = Base.return_types(broadcast, Tuple{Float64, Array{Int, 3}})
169169
@test length(rt) == 1 && rt[1] == Array{Float64, 3}
170-
rt = Base.return_types(broadcast!, Tuple{typeof(+), Array{Float64, 3}, Array{Float64, 3}, Array{Int, 1}})
170+
rt = Base.return_types(broadcast!, Tuple{Function, Array{Float64, 3}, Array{Float64, 3}, Array{Int, 1}})
171171
@test length(rt) == 1 && rt[1] == Array{Float64, 3}
172172

173173
# f.(args...) syntax (#15032)

test/numbers.jl

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2764,20 +2764,19 @@ let types = (Base.BitInteger_types..., BigInt, Bool,
27642764
Complex{Int}, Complex{UInt}, Complex32, Complex64, Complex128)
27652765
for S in types
27662766
for op in (+, -)
2767-
@test Base.promote_op(op, S) === typeof(op(one(S)))
2768-
@inferred Base.promote_op(op, S)
2769-
@inferred op(one(S))
2767+
T = @inferred Base.promote_op(op, S)
2768+
t = @inferred op(one(S))
2769+
@test T === typeof(t)
27702770
end
27712771
end
27722772

2773-
@test Base.promote_op(!, Bool) === Bool
2774-
@inferred Base.promote_op(!, Bool)
2773+
@test @inferred(Base.promote_op(!, Bool)) === Bool
27752774

2776-
for S in types, T in types
2777-
for op in (+, -, *, /, ^, (==))
2778-
@test Base.promote_op(op, S, T) === typeof(op(one(S), one(T)))
2779-
@inferred Base.promote_op(op, S, T)
2780-
@inferred op(one(S), one(T))
2775+
for R in types, S in types
2776+
for op in (+, -, *, /, ^)
2777+
T = @inferred Base.promote_op(op, R, S)
2778+
t = @inferred op(one(R), one(S))
2779+
@test T === typeof(t)
27812780
end
27822781
end
27832782
end
@@ -2786,26 +2785,24 @@ let types = (Base.BitInteger_types..., BigInt, Bool,
27862785
Rational{Int}, Rational{BigInt},
27872786
Float16, Float32, Float64, BigFloat)
27882787
for S in types, T in types
2789-
for op in (<, >, <=, >=)
2790-
@test Base.promote_op(op, S, T) === typeof(op(one(S), one(T)))
2791-
@inferred Base.promote_op(op, S, T)
2792-
@inferred op(one(S), one(T))
2788+
for op in (<, >, <=, >=, (==))
2789+
@test @inferred(Base.promote_op(op, S, T)) === Bool
27932790
end
27942791
end
27952792
end
27962793

27972794
let types = (Base.BitInteger_types..., BigInt, Bool)
27982795
for S in types
2799-
@test Base.promote_op(~, S) === typeof(~one(S))
2800-
@inferred Base.promote_op(~, S)
2801-
@inferred ~one(S)
2796+
T = @inferred Base.promote_op(~, S)
2797+
t = @inferred ~one(S)
2798+
@test T === typeof(t)
28022799
end
28032800

28042801
for S in types, T in types
28052802
for op in (&, |, <<, >>, (>>>), %, ÷)
2806-
@test Base.promote_op(op, S, T) === typeof(op(one(S), one(T)))
2807-
@inferred Base.promote_op(op, S, T)
2808-
@inferred op(one(S), one(T))
2803+
T = @inferred Base.promote_op(op, S, T)
2804+
t = @inferred op(one(S), one(T))
2805+
@test T === typeof(t)
28092806
end
28102807
end
28112808
end

0 commit comments

Comments
 (0)