Julia: splatting is type-unstable with parametric type argument

Created on 10 Jun 2017  路  6Comments  路  Source: JuliaLang/julia

Perhaps that's not its strictly-intended usage, but I've found it useful to temporarily pepper my code with @inferred to catch type-instabilities. Unfortunately, it seems that the output of @inferred can be type-unstable (0.6, rc2), which is an issue for checking the type-stability of heterogeneous tree traversal algorithms.

struct AA{A}
   a::A
end

struct CC{A}
    a::A
end

my_construct(::Type{AA}, a) = 1
my_construct(::Type{CC}, a) = 1.0

foo(x) = @inferred my_construct(CC, x.a)

@inferred foo(CC(2))   #return type Float64 does not match inferred return type Union{Float64, Int64}

Most helpful comment

aka #10980 ?

All 6 comments

my_construct(::Type{Complex}, a) = 1
my_construct(::Type{Array}, a) = 1.0

function foo(x)
    args = (Array, x)
    my_construct(args...)
end

@code_warntype foo(1)

@inferred is not really designed for this; for this use I think we'd want something that's a no-op at run time but that throws an error at compile time if the wrapped expression couldn't be precisely inferred.

That would be great!

aka #10980 ?

julia> function foo(x)
           args = (Array, x)
           args[1]
       end
foo (generic function with 1 method)

julia> @code_warntype foo(1)
Variables:
  #self#::#foo
  x::Int64
  args::Any

Body:
  begin
      SSAValue(0) = Main.Array
      SSAValue(1) = x::Int64
      #= line 3 =#
      return SSAValue(0)
  end::UnionAll

julia> function foo(x)
           args = (Array, 1)
           args[1]
       end
foo (generic function with 1 method)

julia> @code_warntype foo(1)
Variables:
  #self#::#foo
  x::Int64
  args::Any

Body:
  begin
      SSAValue(0) = Main.Array
      #= line 3 =#
      return SSAValue(0)
  end::Type{Array}

So unless args can be inferred as Const, args[1] is inferred as typeof(Array) == UnionAll instead of Type{Array}. That's because of the check in this line. Unfortunately, the reason it was introduced back in afd4eb038dcd9fa3e512509f4c332a9e7763ba59 is anything but clear to me. Do we actually still need that?

EDIT:
We do:

julia> typeof((Array,1))
Tuple{UnionAll,Int64}

Inferring that as Type{Tuple{Type{Array}, Int64} is obviously a bad idea.

This is fixed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yurivish picture yurivish  路  3Comments

sbromberger picture sbromberger  路  3Comments

omus picture omus  路  3Comments

omus picture omus  路  3Comments

Keno picture Keno  路  3Comments