The code:
module Test
func(x) = false
@generated function test(x::T) where T
if Base.invokelatest(func, T)
:( 1 )
else
:( 0 )
end
end
function test2(x::T) where T
if func(T)
1
else
0
end
end
end
Test.func(::Type{UInt64}) = true
println(Test.test(UInt64(1))) # outputs 0
println(Test.test2(UInt64(1))) # outputs 1
Basically, the underlying problem is that there’s a function test that needs to do a heavy computation, but only once for type T. In the process it calls func for type T, which also needs to do a heavy computation, but for some types T the user can provide a precomputed result.
As seen from the code, the @generated function does not pick up the user-defined method of func even with invokelatest(), while a non-generated test2() has no problem with it. Moreover, if one prints methods(func) in test(), it shows the user-defined method, but it still does not get called. Is it a bug or an intended behavior?