-
Notifications
You must be signed in to change notification settings - Fork 42
Description
In a package I am JETing (to be precise: AbstractAlgebra.jl, but it shouldn't matter) some code is uses Rational keys in a Dict, leading to this report, which baffles me. I'll write more below it:
││││││││┌ hashindex(key::Rational, sz::Int64) @ Base ./dict.jl:128
│││││││││┌ hash(x::Rational) @ Base ./hashing.jl:28
││││││││││┌ hash(x::Rational{<:Union{Int16, Int32, Int64, Int8, UInt16, UInt32, UInt64, UInt8}}, h::UInt64) @ Base ./rational.jl:600
│││││││││││┌ ldexp(x::T, e::Int64) where T<:Union{Float16, Float32, Float64} @ Base.Math ./math.jl:893
││││││││││││┌ reinterpret(::Type{T} where T<:Union{Float16, Float32, Float64}, x::UInt16) @ Base ./essentials.jl:736
│││││││││││││┌ _reinterpret(::Type{T} where T<:Union{Float16, Float32, Float64}, x::UInt16) @ Base ./reinterpretarray.jl:858
││││││││││││││┌ packedsize(::Type{T} where T<:Union{Float16, Float32, Float64}) @ Base ./reinterpretarray.jl:815
│││││││││││││││┌ padding(T::Type{T} where T<:Union{Float16, Float32, Float64}) @ Base ./reinterpretarray.jl:755
││││││││││││││││┌ padding(T::Type{T} where T<:Union{Float16, Float32, Float64}, baseoffset::Int64) @ Base ./reinterpretarray.jl:759
│││││││││││││││││ invalid builtin function call: fT = fieldtype(T::Type{T} where T<:Union{Float16, Float32, Float64}, i)
││││││││││││││││└────────────────────
│││││││││││││┌ _reinterpret(::Type{T} where T<:Union{Float16, Float32, Float64}, x::UInt16) @ Base ./reinterpretarray.jl:874
││││││││││││││┌ _reinterpret_padding(::Type{T} where T<:Union{Float16, Float32, Float64}, x::UInt16) @ Base ./reinterpretarray.jl:891
│││││││││││││││┌ _copyfrompacked!(ptr_out::Ptr{T} where T<:Union{Float16, Float32, Float64}, ptr_in::Ptr{UInt16}) @ Base ./reinterpretarray.jl:841
││││││││││││││││ invalid builtin function call: fT = fieldtype(Out::Type{T} where T<:Union{Float16, Float32, Float64}, i)
│││││││││││││││└────────────────────
So it calls the hash(x::Rational{<:BitInteger64}, h::UInt) method, and the trouble maybe starts in this line of it:
return hash(ldexp(Float64(num),pow),h)Note how the first argument to ldexp is Float64(num) which I'd expect is always a Float64. But for some reason, JET seems to think it could be any T<:Union{Float16, Float32, Float64} ?
Now, of course one can write Float64(x) methods that return something that's not a Float64, but I don't think any such method is in the system when I run JET. To verify this, I run the following code as an experiment (I am sure there's a better way to do that, but hey, it did the job for me ;-) ):
julia> x = Base.RefValue{Base.BitInteger64}();
julia> foo(x::Base.RefValue{Base.BitInteger64}) = Float64(x[]);
julia> @code_warntype foo(x)
MethodInstance for foo(::Base.RefValue{Union{Int16, Int32, Int64, Int8, UInt16, UInt32, UInt64, UInt8}})
from foo(x::Base.RefValue{Union{Int16, Int32, Int64, Int8, UInt16, UInt32, UInt64, UInt8}}) @ Main REPL[4]:1
Arguments
#self#::Core.Const(Main.foo)
x::Base.RefValue{Union{Int16, Int32, Int64, Int8, UInt16, UInt32, UInt64, UInt8}}
Body::Float64
1 ─ %1 = Main.Float64::Core.Const(Float64)
│ %2 = Base.getindex(x)::Union{Int16, Int32, Int64, Int8, UInt16, UInt32, UInt64, UInt8}
│ %3 = (%1)(%2)::Float64
└── return %3So the compiler is able to establish the return type, but JET isn't?
Perhaps this is genuine, and the library code ought to be changed to use Float64(num)::Float64, but in this case I thought I should first report this here before trying such a "fix".