In the following two functions are identical except that fun2() has a keyword argument. However, @code_warntype fails to “go into” the invoke Main... part that should give a warntype!
This is not a failure — @code_warntype does not expand the callees recursively (unless they were inlined).
Just use @code_warntype fun2(v; kw = 1).
Also, note that if you are debugging type stablity, you should use arguments with concrete types. Abstract type parameters like in Vector{Real} preclude the optimizations that are allowed by knowing types at compile time (“type stability”), so are not really relevant.
Perhaps you misunderstand the role of @code_warntype: the idea is that it helps you detect type instabilities when you call with concrete types. This will be marked even if we don’t descend into the callees. Eg
julia> @noinline f(x) = x > 0 ? 1 : 1.0
f (generic function with 1 method)
julia> g(x) = f(x^2)
g (generic function with 1 method)
julia> @code_warntype g(1)
Variables
#self#::Core.Compiler.Const(g, false)
x::Int64
Body::Union{Float64, Int64}
1 ─ %1 = Core.apply_type(Base.Val, 2)::Core.Compiler.Const(Val{2}, false)
│ %2 = (%1)()::Core.Compiler.Const(Val{2}(), false)
│ %3 = Base.literal_pow(Main.:^, x, %2)::Int64
│ %4 = Main.f(%3)::Union{Float64, Int64}
└── return %4
where the ::Union{Float64, Int64} is highlighted if the terminal supports it. So you are not going to miss anything.