Skip to content

Commit 40a4773

Browse files
committed
fix promote_op function
This function had some weird and broken extraneous code, using Core.Inference directly is not recommended, but where we are going to do it anyways, we should at least do it correctly. The `cumsum` code had a test to assert that `Real + Real` was convertable to `Real`. This was hacked into the code poorly. It is now hacked in directly. We can separately debate if this is a good idea, I am simply preserving the existing behavior of the code but implementing it correctly (by changing the behavior of the actual function, instead of by convincing inference to return the incorrect answer).
1 parent 24f1316 commit 40a4773

File tree

8 files changed

+14
-45
lines changed

8 files changed

+14
-45
lines changed

base/complex.jl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,3 @@ function complex(A::AbstractArray{T}) where T
991991
end
992992
convert(AbstractArray{typeof(complex(zero(T)))}, A)
993993
end
994-
995-
## promotion to complex ##
996-
997-
_default_type(T::Type{Complex}) = Complex{Int}

base/float.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,6 @@ promote_rule(::Type{Float64}, ::Type{Float32}) = Float64
381381
widen(::Type{Float16}) = Float32
382382
widen(::Type{Float32}) = Float64
383383

384-
_default_type(T::Union{Type{Real},Type{AbstractFloat}}) = Float64
385-
386384
## floating point arithmetic ##
387385
-(x::Float64) = neg_float(x)
388386
-(x::Float32) = neg_float(x)

base/int.jl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -632,9 +632,6 @@ promote_rule(::Type{UInt32}, ::Type{Int32} ) = UInt32
632632
promote_rule(::Type{UInt64}, ::Type{Int64} ) = UInt64
633633
promote_rule(::Type{UInt128}, ::Type{Int128}) = UInt128
634634

635-
_default_type(::Type{Unsigned}) = UInt
636-
_default_type(::Union{Type{Integer},Type{Signed}}) = Int
637-
638635
## traits ##
639636

640637
"""

base/intfuncs.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ end
169169
invmod(n::Integer, m::Integer) = invmod(promote(n,m)...)
170170

171171
# ^ for any x supporting *
172-
to_power_type(x) = convert(promote_op(*, typeof(x), typeof(x)), x)
172+
to_power_type(x) = convert(Base._return_type(*, Tuple{typeof(x), typeof(x)}), x)
173173
@noinline throw_domerr_powbysq(::Any, p) = throw(DomainError(p,
174174
string("Cannot raise an integer x to a negative power ", p, '.',
175175
"\nConvert input to float.")))

base/number.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,6 @@ julia> import Dates; oneunit(Dates.Day)
320320
oneunit(x::T) where {T} = T(one(x))
321321
oneunit(::Type{T}) where {T} = T(one(T))
322322

323-
_default_type(::Type{Number}) = Int
324-
325323
"""
326324
big(T::Type)
327325

base/promotion.jl

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,6 @@ max(x::Real, y::Real) = max(promote(x,y)...)
364364
min(x::Real, y::Real) = min(promote(x,y)...)
365365
minmax(x::Real, y::Real) = minmax(promote(x, y)...)
366366

367-
# "Promotion" that takes a function into account and tries to preserve
368-
# non-concrete types. These are meant to be used mainly by elementwise
369-
# operations, so it is advised against overriding them
370-
_default_type(T::Type) = T
371-
372367
if isdefined(Core, :Compiler)
373368
const _return_type = Core.Compiler.return_type
374369
else
@@ -381,29 +376,12 @@ end
381376
Guess what an appropriate container eltype would be for storing results of
382377
`f(::argtypes...)`. The guess is in part based on type inference, so can change any time.
383378
384-
!!! warning
385-
In pathological cases, the type returned by `promote_op(f, argtypes...)` may not even
386-
be a supertype of the return value of `f(::argtypes...)`. Therefore, `promote_op`
387-
should _not_ be used e.g. in the preallocation of an output array.
388-
389379
!!! warning
390380
Due to its fragility, use of `promote_op` should be avoided. It is preferable to base
391381
the container eltype on the type of the actual elements. Only in the absence of any
392382
elements (for an empty result container), it may be unavoidable to call `promote_op`.
393383
"""
394-
promote_op(::Any...) = Any
395-
function promote_op(f, ::Type{S}) where S
396-
TT = Tuple{_default_type(S)}
397-
T = _return_type(f, TT)
398-
isdispatchtuple(Tuple{S}) && return isdispatchtuple(Tuple{T}) ? T : Any
399-
return typejoin(S, T)
400-
end
401-
function promote_op(f, ::Type{R}, ::Type{S}) where {R,S}
402-
TT = Tuple{_default_type(R), _default_type(S)}
403-
T = _return_type(f, TT)
404-
isdispatchtuple(Tuple{R}) && isdispatchtuple(Tuple{S}) && return isdispatchtuple(Tuple{T}) ? T : Any
405-
return typejoin(R, S, T)
406-
end
384+
promote_op(f, S::Type...) = _return_type(f, Tuple{S...})
407385

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

base/reduce.jl

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,26 @@ else
1313
end
1414

1515
"""
16-
Base.add_sum(x,y)
16+
Base.add_sum(x, y)
1717
1818
The reduction operator used in `sum`. The main difference from [`+`](@ref) is that small
1919
integers are promoted to `Int`/`UInt`.
2020
"""
21-
add_sum(x,y) = x + y
22-
add_sum(x::SmallSigned,y::SmallSigned) = Int(x) + Int(y)
23-
add_sum(x::SmallUnsigned,y::SmallUnsigned) = UInt(x) + UInt(y)
21+
add_sum(x, y) = x + y
22+
add_sum(x::SmallSigned, y::SmallSigned) = Int(x) + Int(y)
23+
add_sum(x::SmallUnsigned, y::SmallUnsigned) = UInt(x) + UInt(y)
24+
add_sum(x::Real, y::Real)::Real = x + y
2425

2526
"""
26-
Base.mul_prod(x,y)
27+
Base.mul_prod(x, y)
2728
2829
The reduction operator used in `prod`. The main difference from [`*`](@ref) is that small
2930
integers are promoted to `Int`/`UInt`.
3031
"""
31-
mul_prod(x,y) = x * y
32-
mul_prod(x::SmallSigned,y::SmallSigned) = Int(x) * Int(y)
33-
mul_prod(x::SmallUnsigned,y::SmallUnsigned) = UInt(x) * UInt(y)
32+
mul_prod(x, y) = x * y
33+
mul_prod(x::SmallSigned, y::SmallSigned) = Int(x) * Int(y)
34+
mul_prod(x::SmallUnsigned, y::SmallUnsigned) = UInt(x) * UInt(y)
35+
mul_prod(x::Real, y::Real)::Real = x * y
3436

3537
## foldl && mapfoldl
3638

@@ -56,7 +58,7 @@ function mapfoldl_impl(f, op, nt::NamedTuple{()}, itr)
5658
end
5759
(x, i) = y
5860
init = mapreduce_first(f, op, x)
59-
mapfoldl_impl(f, op, (init=init,), itr, i)
61+
return mapfoldl_impl(f, op, (init=init,), itr, i)
6062
end
6163

6264

stdlib/LinearAlgebra/src/adjtrans.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

3-
using Base: @propagate_inbounds, _return_type, _default_type, @_inline_meta
3+
using Base: @propagate_inbounds, @_inline_meta
44
import Base: length, size, axes, IndexStyle, getindex, setindex!, parent, vec, convert, similar
55

66
### basic definitions (types, aliases, constructors, abstractarray interface, sundry similar)

0 commit comments

Comments
 (0)