Skip to content

Commit 75c4eff

Browse files
committed
combine reduce_empty methods for Union{} eltypes
With #49470, these can all be dispatched to the same method now, avoiding unnecessary code duplication for this case. This partly reverts f2dcc44, but our edges against methods should be better than the ones against MethodError these days.
1 parent 551b37a commit 75c4eff

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)