Assert type instability

Hi guys

Simple question. Take the function below

function bogus(n::Int)
    @assert n > 1
end

If I do @code_warntype on this function, I get

Arguments
#self#::Core.Const(bogus)
n::Int64
Body::Nothing
1 ─ %1 = (n > 1)::Bool
└── goto #3 if not %1
2 ─ return nothing
3 ─ %4 = Base.AssertionError(“n > 1”)::Any
│ Base.throw(%4)
└── Core.Const(:(return %5))

So I have a type instability in line 3. Why and how do I fix this?

function bogus(n::Int)
    @assert n > 1
    return nothing
end

[/quote]

Thanks for the reply. So it does not matter whether line 3 has “Any” on it? Just as long as the output is known?

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.

2 Likes

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))

Perhaps this is a macro issue or bug?

1 Like

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