Without an explicit return, the function returns the last evaluated expression. Any is not concrete and thus causes instability. The path through the code where throw occurs, returns Any, although in that case the function never actually return. By adding an explicit return after the assert, you guarantee the inferred function return type is concrete.
Technically it already figured out that your function will return something of type Nothing. I’m not quite sure why there is an Any there, but perhaps it has been judged that it is not worth inferring the type of the exception? Anyways, if it is a problem, it’s not really your problem.
The explicit return nothing helps for clarity, but I’m not sure if it actually changes the behavior of anything.
If you really wanted to resolve the type warning, you could try writing it explicitly as follows.
julia> function bogus(n::Int)
if n > 1
nothing
else
Base.throw(Base.AssertionError("n > 1"))
end
end
bogus (generic function with 1 method)
julia> @code_warntype bogus(5)
MethodInstance for bogus(::Int64)
from bogus(n::Int64) in Main at REPL[15]:1
Arguments
#self#::Core.Const(bogus)
n::Int64
Body::Nothing
1 ─ %1 = (n > 1)::Bool
└── goto #3 if not %1
2 ─ return Main.nothing
3 ─ %4 = Base.throw::Core.Const(throw)
│ %5 = Base.AssertionError::Core.Const(AssertionError)
│ %6 = (%5)("n > 1")::AssertionError
│ (%4)(%6)
└── Core.Const(:(return %7))
Thanks for replying. Yes I agree that this may not be an issue about the type stability of the function itself, but like you say, it might be a bug in the macro