# Trying to understand the return type of an array comprehension if the function being called returns a Union

On nightly:

``````julia> f(x) = x > 3 ? x : nothing
f (generic function with 1 method)

julia> g(imax) = [f(i) for i in 1:imax]
g (generic function with 1 method)

julia> @code_warntype g(5)
MethodInstance for g(::Int64)
from g(imax) in Main at REPL[7]:1
Arguments
#self#::Core.Const(g)
imax::Int64
Locals
#5::var"#5#6"
Body::Union{Vector{Nothing}, Vector{Union{Nothing, Int64}}, Vector{Int64}}
1 ─      (#5 = %new(Main.:(var"#5#6")))
│   %2 = #5::Core.Const(var"#5#6"())
│   %3 = (1:imax)::Core.PartialStruct(UnitRange{Int64}, Any[Core.Const(1), Int64])
│   %4 = Base.Generator(%2, %3)::Core.PartialStruct(Base.Generator{UnitRange{Int64}, var"#5#6"}, Any[Core.Const(var"#5#6"()), Core.PartialStruct(UnitRange{Int64}, Any[Core.Const(1), Int64])])
│   %5 = Base.collect(%4)::Union{Vector{Nothing}, Vector{Union{Nothing, Int64}}, Vector{Int64}}
└──      return %5
``````

The return type here may be chosen to be `Vector{Union{Nothing, Int}}` instead of the union of types. I wonder if this is intentional, expecting union splitting in downstream usage? Or is this something that may be improved upon?

Guessing here: there is a chance the function returns a `Vector{Int}` (I.e. `imax.>3`). It would be a waste of potential to treat that as a `Vector{Union}`.