I got a little confused about how type inference works, when trying to find out what happens when types are passed as values to a function like in rand(Int64)
. So far I thought that the compiler tries to infer the returned type of a function only using typeof(arg)
for every argument arg
. However, to me it seems that that then e.g. code_warntype(rand, (typeof(Int64), ))
and @code_warntype rand(Int64)
would have to be equivalent, while actually they give different results (the following is in v0.6.2 but the same happens in the 0.7 alpha):
julia> @code_warntype rand(Int64)
Variables:
#self# <optimized out>
T <optimized out>
Body:
begin
$(Expr(:inbounds, false))
# meta: location random.jl rand 358
SSAValue(0) = $(Expr(:invoke, MethodInstance for rand(::MersenneTwister, ::Type{UInt64}), :(Base.Random.rand), :(Base.Random.GLOBAL_RNG), :(Base.Random.UInt64)))
# meta: pop location
$(Expr(:inbounds, :pop))
return (Base.bitcast)(Int64, SSAValue(0))
end::Int64
where the type is inferred correctly and
julia> code_warntype(rand, (typeof(Int64), ))
Variables:
#self# <optimized out>
T::DataType
Body:
begin
return (Base.Random.rand)(Base.Random.GLOBAL_RNG, T::DataType)::Any
end::Any
where it is not. This doesn’t seem to fit the documentation of @code_warntype, which states, that it “Evaluates the arguments to the function or macro call, determines their types, and calls code_warntype on the resulting expression.”.
I didn’t find any questions on discourse about this. In the documentation I found out about the singleton types Type{T}
and that you can specialize methods on type values with that (which apparently is the case for rand
) but I don’t see how this fits into inference.
Also, as code_warntype
is the only way I know to get information about type inference, I’m not sure whether this is a question about code_warntype
or about type inference. I think my confusion boils down to the following two questions though:
- Is it wrong to say that the compiler only uses information in
typeof.(args)
during inference? - When checking for type stability, should I trust
@code_warntype
orcode_warntype()
?