After looking into this, I think this may be tricky to avoid.  But yes,
possibly a bug or certainly a feature to improve on.

One of the culprits is the following expression inside the cat function:

[isa(x,AbstractArray) ? eltype(x) : typeof(x) for x in X]

Checking this:

f2(X...) = [isa(x,AbstractArray) ? eltype(x) : typeof(x) for x in X]
Base.code_warntype(f2, Base.typesof(Any[1,1:5]...)) #  
Array{Union{Type{Int64},Type{UnitRange{Int64}}},1}

I tried to get around this with something like:

tmp(x::AbstractArray) = eltype(x)
tmp{T}(x::T) = T
function cat2(catdims, X...)
    T = promote_type([tmp(x) for x in X]...)
    cat_t(catdims, T, X...)
end

but that is not type-stable either, even though
`f(X...) = [tmp(x) for x in X]` is.
So digging deeper I came up with these tests:

xx = Any[1:5, 1]
TT = Type{Int64}[Int64, Int64] # isa Array{Type{Int64},1)
TT2 = [Int64, Int64]    # isa Array{DataType,1)
TT3 = Any[Int64, Int64] # isa Array{DataType,1)
Base.code_warntype(promote_type, Base.typesof(TT...))  # works: Type{Int64}
Base.code_warntype(promote_type, Base.typesof(TT2...)) # works: Type{Int64}
Base.code_warntype(promote_type, Base.typesof(TT3...)) # works: Type{Int64}

# But using promote_type inside a function does not work:
p(x) = promote_type(x...)
@code_warntype p(TT) # Type{T}
# splatting seems to be the culprit:
p2(x) = promote_type(x[1],x[2])
@code_warntype p2(TT)

So it seems that using promote_type inside other functions is easily
type unstable. I would think this could be solved?

PS: Note that `@code_warntype` fails with splatting, thus the function
invocation above (https://github.com/JuliaLang/julia/issues/13264).

On Tue, 2015-09-22 at 02:26, Sheehan Olver <dlfivefi...@gmail.com> wrote:
> The code below can't infer the return type of cat.  Should I file an issue
> or is this expected?
>
>
> v=rand(5)
> @code_warntype cat(1,0.0,v,0.0)
> ...
> end::ANY

Reply via email to