Construct `Union{T, U} where T<:Integer where U<:Float64` from `Union{TypeVar(:T, Integer), TypeVar(:U, Float64)}`

I’m trying to construct a type programmatically but failing to do so. The crux of my problem is that UnionAll(TypeVar(:T, Integer), Union{TypeVar(:T, Integer), TypeVar(:U, Float64)}) doesn’t return a UnionAll type, and instead returns a Union . I’m wondering if this is intended or a bug in Julia? If it is intended, what is the recommended way to construct this specific UnionAll?

In the latest Julia nightly, this is what I get:

julia> UnionAll(TypeVar(:T, Integer), Union{TypeVar(:T, Integer), TypeVar(:U, Float64)}) Union{T<:Integer, U<:Float64}

I was expecting to get:

Union{T, U<:Float64} where T<:Integer

Here’s a screenshot of the Julia REPL where I was exploring the fields and the types of the various types involved:

julia> u = Union{TypeVar(:T, Integer), TypeVar(:U, Float64)}
Union{T<:Integer, U<:Float64}

julia> UnionAll(u.a, UnionAll(u.b, u))
Union{T, U} where {T<:Integer, U<:Float64}

Ref: More about types · The Julia Language

Edit: That said, yes, I kinda feel like

julia> u = Union{TypeVar(:T, Integer), TypeVar(:U, Float64)}
Union{T<:Integer, U<:Float64}

julia> u2 = Union{TypeVar(:T, Integer), TypeVar(:U, Float64)}
Union{T<:Integer, U<:Float64}

julia> UnionAll(u.a, u2)
Union{T<:Integer, U<:Float64}

julia> UnionAll(u.a, u)
Union{T, U<:Float64} where T<:Integer

is a bug.

3 Likes

Wow. So it has to be the same instance?

Yup. I suspect this happens because two instances of the “same” TypeVar aren’t ever equal/egal, but didn’t look at the implementation to check whether that’s actually the issue here.