Skip to content

Commit b71523e

Browse files
authored
combine reduce_empty methods for Union{} eltypes (#51948)
With #49470, these can all be dispatched to the same method now, avoiding unnecessary code duplication for this case.
1 parent 8cf7598 commit b71523e

File tree

3 files changed

+14
-22
lines changed

3 files changed

+14
-22
lines changed

base/errorshow.jl

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,6 @@ function showerror(io::IO, ex::MethodError)
254254
return showerror_ambiguous(io, meth, f, arg_types)
255255
end
256256
arg_types_param::SimpleVector = arg_types.parameters
257-
show_candidates = true
258257
print(io, "MethodError: ")
259258
ft = typeof(f)
260259
f_is_function = false
@@ -270,9 +269,6 @@ function showerror(io::IO, ex::MethodError)
270269
if f === Base.convert && length(arg_types_param) == 2 && !is_arg_types
271270
f_is_function = true
272271
show_convert_error(io, ex, arg_types_param)
273-
elseif f === mapreduce_empty || f === reduce_empty
274-
print(io, "reducing over an empty collection is not allowed; consider supplying `init` to the reducer")
275-
show_candidates = false
276272
elseif isempty(methods(f)) && isa(f, DataType) && isabstracttype(f)
277273
print(io, "no constructors have been defined for ", f)
278274
elseif isempty(methods(f)) && !isa(f, Function) && !isa(f, Type)
@@ -346,11 +342,12 @@ function showerror(io::IO, ex::MethodError)
346342
end
347343
end
348344
Experimental.show_error_hints(io, ex, arg_types_param, kwargs)
349-
show_candidates && try
345+
try
350346
show_method_candidates(io, ex, kwargs)
351347
catch ex
352348
@error "Error showing method candidates, aborted" exception=ex,catch_backtrace()
353349
end
350+
nothing
354351
end
355352

356353
striptype(::Type{T}) where {T} = T

base/reduce.jl

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,11 @@ pairwise_blocksize(::typeof(abs2), ::typeof(+)) = 4096
316316

317317

318318
# handling empty arrays
319-
_empty_reduce_error() = throw(ArgumentError("reducing over an empty collection is not allowed"))
320-
_empty_reduce_error(@nospecialize(f), @nospecialize(T::Type)) = throw(ArgumentError("""
321-
reducing with $f over an empty collection of element type $T is not allowed.
322-
You may be able to prevent this error by supplying an `init` value to the reducer."""))
319+
_empty_reduce_error() = throw(ArgumentError("reducing over an empty collection is not allowed; consider supplying `init` to the reducer"))
320+
reduce_empty(f, T) = _empty_reduce_error()
321+
mapreduce_empty(f, op, T) = _empty_reduce_error()
322+
reduce_empty(f, ::Type{Union{}}, splat...) = _empty_reduce_error()
323+
mapreduce_empty(f, op, ::Type{Union{}}, splat...) = _empty_reduce_error()
323324

324325
"""
325326
Base.reduce_empty(op, T)
@@ -339,20 +340,16 @@ is generally ambiguous, and especially so when the element type is unknown).
339340
340341
As an alternative, consider supplying an `init` value to the reducer.
341342
"""
342-
reduce_empty(::typeof(+), ::Type{Union{}}) = _empty_reduce_error(+, Union{})
343343
reduce_empty(::typeof(+), ::Type{T}) where {T} = zero(T)
344344
reduce_empty(::typeof(+), ::Type{Bool}) = zero(Int)
345-
reduce_empty(::typeof(*), ::Type{Union{}}) = _empty_reduce_error(*, Union{})
346345
reduce_empty(::typeof(*), ::Type{T}) where {T} = one(T)
347346
reduce_empty(::typeof(*), ::Type{<:AbstractChar}) = ""
348347
reduce_empty(::typeof(&), ::Type{Bool}) = true
349348
reduce_empty(::typeof(|), ::Type{Bool}) = false
350349

351-
reduce_empty(::typeof(add_sum), ::Type{Union{}}) = _empty_reduce_error(add_sum, Union{})
352350
reduce_empty(::typeof(add_sum), ::Type{T}) where {T} = reduce_empty(+, T)
353351
reduce_empty(::typeof(add_sum), ::Type{T}) where {T<:SmallSigned} = zero(Int)
354352
reduce_empty(::typeof(add_sum), ::Type{T}) where {T<:SmallUnsigned} = zero(UInt)
355-
reduce_empty(::typeof(mul_prod), ::Type{Union{}}) = _empty_reduce_error(mul_prod, Union{})
356353
reduce_empty(::typeof(mul_prod), ::Type{T}) where {T} = reduce_empty(*, T)
357354
reduce_empty(::typeof(mul_prod), ::Type{T}) where {T<:SmallSigned} = one(Int)
358355
reduce_empty(::typeof(mul_prod), ::Type{T}) where {T<:SmallUnsigned} = one(UInt)
@@ -753,7 +750,7 @@ julia> maximum([1,2,3])
753750
3
754751
755752
julia> maximum(())
756-
ERROR: MethodError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
753+
ERROR: ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
757754
Stacktrace:
758755
[...]
759756
@@ -785,7 +782,7 @@ julia> minimum([1,2,3])
785782
1
786783
787784
julia> minimum([])
788-
ERROR: MethodError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
785+
ERROR: ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
789786
Stacktrace:
790787
[...]
791788

test/reduce.jl

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ end
5353
@test reduce(max, [8 6 7 5 3 0 9]) == 9
5454
@test reduce(+, 1:5; init=1000) == (1000 + 1 + 2 + 3 + 4 + 5)
5555
@test reduce(+, 1) == 1
56-
@test_throws "reducing with * over an empty collection of element type Union{} is not allowed" reduce(*, ())
57-
@test_throws "reducing with * over an empty collection of element type Union{} is not allowed" reduce(*, Union{}[])
56+
@test_throws "reducing over an empty collection is not allowed" reduce(*, ())
57+
@test_throws "reducing over an empty collection is not allowed" reduce(*, Union{}[])
5858

5959
# mapreduce
6060
@test mapreduce(-, +, [-10 -9 -3]) == ((10 + 9) + 3)
@@ -91,8 +91,7 @@ end
9191
@test mapreduce(abs2, *, Float64[]) === 1.0
9292
@test mapreduce(abs2, max, Float64[]) === 0.0
9393
@test mapreduce(abs, max, Float64[]) === 0.0
94-
@test_throws ["reducing over an empty collection is not allowed",
95-
"consider supplying `init`"] mapreduce(abs2, &, Float64[])
94+
@test_throws "reducing over an empty collection is not allowed" mapreduce(abs2, &, Float64[])
9695
@test_throws str -> !occursin("Closest candidates are", str) mapreduce(abs2, &, Float64[])
9796
@test_throws "reducing over an empty collection is not allowed" mapreduce(abs2, |, Float64[])
9897

@@ -144,9 +143,8 @@ fz = float(z)
144143
@test sum(z) === 136
145144
@test sum(fz) === 136.0
146145

147-
@test_throws "reducing with add_sum over an empty collection of element type Union{} is not allowed" sum(Union{}[])
148-
@test_throws ["reducing over an empty collection is not allowed",
149-
"consider supplying `init`"] sum(sin, Int[])
146+
@test_throws "reducing over an empty collection is not allowed" sum(Union{}[])
147+
@test_throws "reducing over an empty collection is not allowed" sum(sin, Int[])
150148
@test sum(sin, 3) == sin(3.0)
151149
@test sum(sin, [3]) == sin(3.0)
152150
a = sum(sin, z)

0 commit comments

Comments
 (0)