Skip to content

Commit a4e0f47

Browse files
committed
Eliminate most invalidations from loading FixedPointNumbers
1 parent 5ec0608 commit a4e0f47

File tree

4 files changed

+37
-14
lines changed

4 files changed

+37
-14
lines changed

base/bool.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
# promote Bool to any other numeric type
44
promote_rule(::Type{Bool}, ::Type{T}) where {T<:Number} = T
55

6+
convert(::Type{Bool}, x::Bool) = x # prevent invalidation
7+
68
typemin(::Type{Bool}) = false
79
typemax(::Type{Bool}) = true
810

base/essentials.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ true
166166
"""
167167
function convert end
168168

169+
convert(::Type{Union{}}, x::Union{}) = throw(MethodError(convert, (Union{}, x)))
169170
convert(::Type{Union{}}, x) = throw(MethodError(convert, (Union{}, x)))
170171
convert(::Type{Any}, x) = x
171172
convert(::Type{T}, x::T) where {T} = x
@@ -447,6 +448,9 @@ Stacktrace:
447448
```
448449
"""
449450
sizeof(x) = Core.sizeof(x)
451+
# The next two methods prevent invalidation
452+
sizeof(::Type{Union{}}) = Core.sizeof(Union{})
453+
sizeof(::Type{T}) where T = Core.sizeof(T)
450454

451455
# simple Array{Any} operations needed for bootstrap
452456
@eval setindex!(A::Array{Any}, @nospecialize(x), i::Int) = arrayset($(Expr(:boundscheck)), A, x, i)

base/number.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## generic operations on numbers ##
44

5+
# prevent invalidation
6+
Union{}(x::Number) = throw(MethodError(convert, (Union{}, x)))
7+
convert(::Type{Union{}}, x::Number) = throw(MethodError(convert, (Union{}, x)))
8+
59
# Numbers are convertible
610
convert(::Type{T}, x::T) where {T<:Number} = x
711
convert(::Type{T}, x::Number) where {T<:Number} = T(x)
@@ -240,6 +244,9 @@ julia> zero(rand(2,2))
240244
"""
241245
zero(x::Number) = oftype(x,0)
242246
zero(::Type{T}) where {T<:Number} = convert(T,0)
247+
# prevent invalidation
248+
zero(x::Union{}) = throw(MethodError(zero, (x,)))
249+
zero(::Type{Union{}}) = throw(MethodError(zero, (Union{},)))
243250

244251
"""
245252
one(x)
@@ -275,6 +282,9 @@ julia> import Dates; one(Dates.Day(1))
275282
"""
276283
one(::Type{T}) where {T<:Number} = convert(T,1)
277284
one(x::T) where {T<:Number} = one(T)
285+
# prevent invalidation
286+
one(x::Union{}) = throw(MethodError(one, (x,)))
287+
one(::Type{Union{}}) = throw(MethodError(one, (Union{},)))
278288
# note that convert(T, 1) should throw an error if T is dimensionful,
279289
# so this fallback definition should be okay.
280290

@@ -298,6 +308,9 @@ julia> import Dates; oneunit(Dates.Day)
298308
"""
299309
oneunit(x::T) where {T} = T(one(x))
300310
oneunit(::Type{T}) where {T} = T(one(T))
311+
# prevent invalidation
312+
oneunit(x::Union{}) = throw(MethodError(oneunit, (x,)))
313+
oneunit(::Type{Union{}}) = throw(MethodError(oneunit, (Union{},)))
301314

302315
"""
303316
big(T::Type)

base/reduce.jl

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -306,25 +306,29 @@ with reduction `op` over an empty array with element type of `T`.
306306
307307
If not defined, this will throw an `ArgumentError`.
308308
"""
309-
reduce_empty(op, T) = _empty_reduce_error()
310-
reduce_empty(::typeof(+), T) = zero(T)
309+
reduce_empty(op, ::Type{T}) where T = _empty_reduce_error()
310+
reduce_empty(::typeof(+), ::Type{Union{}}) = _empty_reduce_error() # avoid invalidation
311+
reduce_empty(::typeof(+), ::Type{T}) where T = zero(T)
311312
reduce_empty(::typeof(+), ::Type{Bool}) = zero(Int)
312-
reduce_empty(::typeof(*), T) = one(T)
313+
reduce_empty(::typeof(*), ::Type{Union{}}) = _empty_reduce_error()
314+
reduce_empty(::typeof(*), ::Type{T}) where T = one(T)
313315
reduce_empty(::typeof(*), ::Type{<:AbstractChar}) = ""
314316
reduce_empty(::typeof(&), ::Type{Bool}) = true
315317
reduce_empty(::typeof(|), ::Type{Bool}) = false
316318

317-
reduce_empty(::typeof(add_sum), T) = reduce_empty(+, T)
319+
reduce_empty(::typeof(add_sum), ::Type{Union{}}) = _empty_reduce_error()
320+
reduce_empty(::typeof(add_sum), ::Type{T}) where T = reduce_empty(+, T)
318321
reduce_empty(::typeof(add_sum), ::Type{T}) where {T<:SmallSigned} = zero(Int)
319322
reduce_empty(::typeof(add_sum), ::Type{T}) where {T<:SmallUnsigned} = zero(UInt)
320-
reduce_empty(::typeof(mul_prod), T) = reduce_empty(*, T)
323+
reduce_empty(::typeof(mul_prod), ::Type{Union{}}) = _empty_reduce_error()
324+
reduce_empty(::typeof(mul_prod), ::Type{T}) where T = reduce_empty(*, T)
321325
reduce_empty(::typeof(mul_prod), ::Type{T}) where {T<:SmallSigned} = one(Int)
322326
reduce_empty(::typeof(mul_prod), ::Type{T}) where {T<:SmallUnsigned} = one(UInt)
323327

324-
reduce_empty(op::BottomRF, T) = reduce_empty(op.rf, T)
325-
reduce_empty(op::MappingRF, T) = mapreduce_empty(op.f, op.rf, T)
326-
reduce_empty(op::FilteringRF, T) = reduce_empty(op.rf, T)
327-
reduce_empty(op::FlipArgs, T) = reduce_empty(op.f, T)
328+
reduce_empty(op::BottomRF, ::Type{T}) where T = reduce_empty(op.rf, T)
329+
reduce_empty(op::MappingRF, ::Type{T}) where T = mapreduce_empty(op.f, op.rf, T)
330+
reduce_empty(op::FilteringRF, ::Type{T}) where T = reduce_empty(op.rf, T)
331+
reduce_empty(op::FlipArgs, ::Type{T}) where T = reduce_empty(op.f, T)
328332

329333
"""
330334
Base.mapreduce_empty(f, op, T)
@@ -336,12 +340,12 @@ of `T`.
336340
If not defined, this will throw an `ArgumentError`.
337341
"""
338342
mapreduce_empty(f, op, T) = _empty_reduce_error()
339-
mapreduce_empty(::typeof(identity), op, T) = reduce_empty(op, T)
340-
mapreduce_empty(::typeof(abs), op, T) = abs(reduce_empty(op, T))
341-
mapreduce_empty(::typeof(abs2), op, T) = abs2(reduce_empty(op, T))
343+
mapreduce_empty(::typeof(identity), op, ::Type{T}) where T = reduce_empty(op, T)
344+
mapreduce_empty(::typeof(abs), op, ::Type{T}) where T = abs(reduce_empty(op, T))
345+
mapreduce_empty(::typeof(abs2), op, ::Type{T}) where T = abs2(reduce_empty(op, T))
342346

343-
mapreduce_empty(f::typeof(abs), ::typeof(max), T) = abs(zero(T))
344-
mapreduce_empty(f::typeof(abs2), ::typeof(max), T) = abs2(zero(T))
347+
mapreduce_empty(::typeof(abs), ::typeof(max), ::Type{T}) where T = abs(zero(T))
348+
mapreduce_empty(::typeof(abs2), ::typeof(max), ::Type{T}) where T = abs2(zero(T))
345349

346350
# For backward compatibility:
347351
mapreduce_empty_iter(f, op, itr, ItrEltype) =

0 commit comments

Comments
 (0)