@code_warntype, for loops and spurious Union types

If I define some function that includes a for loop and run @code_warntype on it:

function f()
    for i in 1:10
        i
    end
    return
end

@code_warntype f()

The variables listed always contain a Union type:

Variables
  #self#::Core.Compiler.Const(f, false)
  @_2::Union{Nothing, Tuple{Int64,Int64}}
  i::Int64

Whch means the function shows up as yellow/dynamic in the atom profiler, which is kinda weird.

What’s going on here?

That’s just how iterate works, see

https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-iteration-1

It is not spurious, but usually innocuous: your code will be optimized.

That makes sense. It’s still annoying in large functions where you can’t easily tell for-loop type instability from more serious kinds at a glance. Maybe Juno could ignore Union{Nothing,Tuple{Int,Int}}.

Note that in the REPL, Union is highlighted with a different color than other type instabilities. Eg

In the atom profiler yellow is for all dynamic dispatch, red for allocation - but for loops can show up as either. Which further complicates it.

That’s an issue with Atom then I guess (note that I am not a user, so I may not be aware of some customization which fixes this).