I was playing with JET and noticed that it does not like notation like while (i=f())!==nothing ... while it is perfectly happy with i=f(); while i!==nothing .... f is a function that returns Union{Int,Nothing}. It seems the “inline assignment” inside of the while predicate is the reason for this and I was hoping I can get more feedback concerning the root cause. Is this a bad way to write julia code? Here is a full example with two naive versions of Base.invperm:
using JET
using Random
function inline_assign_while_loop(permutation::Vector{Int})
    indices = Int[]
    v = 1
    while (i=findfirst(==(v),permutation)) !== nothing
        push!(indices, i)
        v += 1
    end
    indices
end
function normal_assign_while_loop(permutation::Vector{Int})
    indices = Int[]
    v = 1
    i = findfirst(==(v),permutation)
    while i !== nothing
        push!(indices, i)
        v += 1
        i = findfirst(==(v),permutation)
    end
    indices
end
test_perm = randperm(10)
@assert inline_assign_while_loop(test_perm) == normal_assign_while_loop(test_perm) == invperm(test_perm)
# A possible error reported by JET because i!==nothing is not inferred
@report_call inline_assign_while_loop(test_perm) 
# No possible error reported by JET
@report_call normal_assign_while_loop(test_perm)
@code_warntype is also happier with normal_assign_while_loop, so I assume the issue is not with JET, rather with the type inference.
My question is: Is this something that Julia’s type inference should be doing better or is there something that I did explicitly wrong (or both)?
I prefer using the problematic inline assignment inside the while predicate because that way I need to write it only once (instead of writing it once before the loop and once inside the loop body). I know this is an inefficient quadratic algorithm for invperm, I am using it just as an example.