Minimal reproducible example:
julia> immutable MyFunc{F}
func::F
end
julia> (f::MyFunc{F}){F}(x) = f.func(x...)
julia> f = MyFunc(x -> 1 + x)
MyFunc{##15#16}(#15)
julia> f((1,))
2
julia> g(f, x) = f(x...)
g (generic function with 1 method)
julia> @code_warntype g(f, (1,))
Variables:
#self#::#g
f::MyFunc{##15#16}
x::Tuple{Int64}
Body:
begin
return (Core._apply)((Core.getfield)(f::MyFunc{##15#16},:func)::##15#16,(Core.getfield)(x::Tuple{Int64},1)::Int64)::Any
end::Any
cc @jrevels
It's due to splatting of a number and not a tuple.
julia> f(x) = (x...)
f (generic function with 1 method)
julia> @code_warntype f(1)
Variables:
#self#::#f
x::Int64
Body:
begin
return (Core._apply)(Core.tuple,x::Int64)::Tuple
end::Tuple
julia> f(1)
(1,)
And this seems to be caused by the special handling of Core._apply
not being able to handle scalar input (or generic iterables). Handling of generic iterables with compile time known size might be useful although it seems non-trivial....
would be fixed by https://github.com/JuliaLang/julia/pull/12579 then?
Sort of. Although it doesn't infer the length?
As long as numbers are iterable (which, most likely, they will continue to be) it's worth adding handling for this to _apply
inference.
This has now been fixed:
julia> @code_warntype g(f, (1,))
Variables:
#self#::#g
f::#f
x::Tuple{Int64}
Body:
begin
return (Core.tuple)((Core.getfield)(x::Tuple{Int64}, 1)::Int64, 1)::Tuple{Int64,Int64}
end::Tuple{Int64,Int64}
could use a test
Good point.
a partial related test was added in #20343, but it looks a bit different?
Does this really just need a test in order to close it?
Most helpful comment