Inconsistent behaviour of Vararg UnionAll

dear out there,

I just stumbled upon the maybe most weird julia bug I experienced so far

f1(args::(Vararg{Any, N} where N); kwargs...) = (args, kwargs)
f2(args::(Vararg{Any, N} where N)) = (args, 1)
f3(args::(Vararg{Any}); kwargs...) = (args, kwargs)

@show f1(1,2,3) f2(1,2,3) f3(1,2,3)

will print

f1(1, 2, 3) = (((1, 2, 3),), Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}())
f2(1, 2, 3) = ((1, 2, 3), 1)
f3(1, 2, 3) = ((1, 2, 3), Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}())

The core difference is that for f1 the args get packed into an EXTRA level of Tuple…

Super weird, especially because

  • f1 and f2 share the same type on args and
  • f1 and f3 share in principle the same type on args (as the first is an explicit UnionAll, and the second the respective implicit UnionAll)

ideas?

EDIT:
Question for building a workaround:
Is there a way to easily normalize the explicit UnionAll Vararg{Any, N} where N into the correct behaving Vararg{Any}?

version: this run on julia 1.2.0

1 Like

it gets even weirder, just tested equality:

Vararg{Any} === Vararg{Any, N} where N
gives true

opened as bug report at https://github.com/JuliaLang/julia/issues/33987

1 Like
julia> f4(args::(Vararg{Any, N}); kwargs...) where {N} = (args, kwargs)
f4 (generic function with 1 method)

julia> @show f1(1,2,3) f3(1,2,3) f4(1,2,3);
f1(1, 2, 3) = (((1, 2, 3),), Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}())
f3(1, 2, 3) = ((1, 2, 3), Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}())
f4(1, 2, 3) = ((1, 2, 3), Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}())
1 Like