Comprehension doesn't infer type of parametric type collection when empty

When comprehension returns a empty collection of a parametric type, the type is lost.
In simple code:

struct A{T}
    a::T
end

vs = [A(1), A(2), A(3), A(1.0), A(2.0), A(3.0)]
#6-element Vector{A}:
# A{Int64}(1)
# A{Int64}(2)
# A{Int64}(3)
# A{Float64}(1.0)
# A{Float64}(2.0)
# A{Float64}(3.0)


# doesn't infer the type
[v for v in vs if v.a == 7]
#Any[]

# infers the type successfully
Iterators.filter(x -> x.a ==7, vs) |> collect
#A[]

Is this normal ?

This can ofc break some code since multiple dispatch will fail in code following.

A lot of people seem to point to this issue performance of captured variables in closures · Issue #15276 · JuliaLang/julia · GitHub when problematic comprehension inference is discussed. Is it also for this situation the case or is it something else ?

1 Like
eltype(vs)[v for v in vs if v.a == 7]

It’d of course be better if vs itself were concretely typed, or were a small union of types, e.g.

vs = Union{A{Int},A{Float64}}[A(1), A(2), A(3), A(1.0), A(2.0), A(3.0)]

This isn’t a comprehension capturing closures in the anonymous function. It isn’t capturing anything.

I pasted the code example in replit and labstack for a quick check of behavior on older versions (1.4.1, 1.6.2), and the comprehension is an empty Vector{A}. I’m assuming sometime since then, there was a change in comprehension type inference.