JETLS warnings

I have the following code:

    local pos_B, pos_C, pos_D
    for i in 1:4
        particle=particles[i]
        x, y, z = particle[1], particle[2], particle[3]
    
        if i==2
            pos_B = SVector(x,y,z)
        elseif  i==3
            pos_C = SVector(x,y,z)
        elseif i==4
            pos_D = SVector(x,y,z)
        end
        push!(X, x)
        push!(Y, y)
        push!(Z, z)
    end
    ss.X .= X
    ss.Y .= Y
    ss.Z .= Z
    pos_centre = 0.5 * (pos_C + pos_D)

I get the warning:

local variable `pos_C` may be undefined

The same for pos_D.

Is this a problem with my code or with JET.jl or with JETLS.jl ?

JET/JETLS do static analysis, so while your code is correct, it’s unreasonable to expect JET (and probably Julia’s compiler) to follow it since it can’t reason about 1:4 without doing constant propagation / loop unrolling.

I’d consider rewriting it as

function f(particle)
        x, y, z = particle[1], particle[2], particle[3]
        push!(X, x)
        push!(Y, y)
        push!(Z, z)
        return SVector(x,y,z)
end
f(particle[1])
pos_B = f(particle[2])
pos_C = f(particle[3])
pos_D = f(particle[4])
...

AFAIK this is easier for the compiler to reason about.

2 Likes

imo this is just one of the warnings you check your code with instead of trying to get rid of. At first glance, it all looks inferrable (of course you should check for your call), and AOT compilers generally don’t bother to inspect conditional initializations in loops. They either risk uninitialized data or refuse to compile, e.g. Rust:

2 |     let mut r;
  |         ----- binding declared here but left uninitialized
3 |     for i in 1..3 {
  |              ---- if the `for` loop runs 0 times, `r` is not initialized
4 |         if i == 2 {
  |            ------ if this `if` condition is `false`, `r` is not initialized
5 |             r = 0;
6 |         }
  |          - an `else` arm might be missing here, initializing `r`
7 |     }
8 |     println!("r: {r}");
  |                   ^ `r` used here but it is possibly-uninitialized

It wouldn’t be too much work to statically check literal integers and ranges, but that special treatment would not work on non-literal objects and other types, which are very common.