Incorrectly Inferred Return Type

I have a case where code_warntype shows a function returning a difference concrete type from what it actually returns. Here is the code:

abstract type AbstractFoo end

mutable struct FooBase <: AbstractFoo
  a::Int
  # no foo_inner: terminates any recursion
end


mutable struct Foo1 <: AbstractFoo
  foo_inner::FooBase

  function Foo1()
    return new(FooBase(1))
  end
end

mutable struct Foo2 <: AbstractFoo
  foo_inner::Foo1

  function Foo2()
    return new(Foo1())
  end
end


mutable struct Foo3 <: AbstractFoo
  foo_inner::Foo2

  function Foo3()
    return new(Foo2())
  end
end


mutable struct Foo4 <: AbstractFoo
  foo_inner::Foo3

  function Foo4()
    return new(Foo3())
  end
end



# T1 <: T2 implies T1 == T2 as long as all T1 and T2 are concrete
function getInnerFoo(foo::T1, ::Type{T2}) where {T2 <: AbstractFoo, T1 <: T2}
  return foo
end

function getInnerFoo(foo::T1, ::Type{T2}) where {T1 <: AbstractFoo, T2 <: AbstractFoo}
  return getInnerFoo(foo.foo_inner, T2)
end

obj = Foo4()

obj2 = getInnerFoo(obj, Foo2)
println("typeof(obj2) = ", typeof(obj2))
@code_warntype getInnerFoo(obj, Foo2)

On Julia 0.6.2, the output is:

typeof(obj2) = Foo2
Variables:
  #self# <optimized out>
  foo::Foo4
  #unused# <optimized out>

Body:
  begin 
      return foo::Foo4
  end::Foo4
Variables:
  #self# <optimized out>
  foo::Foo4
  #unused# <optimized out>

Body:
  begin 
      return (Main.getInnerFoo)((Core.getfield)(foo::Foo4, :foo_inner)::Foo3, $(Expr(:static_parameter, 2)))::Foo3
  end::Foo3

The typeof line shows the runtime type of obj2 is Foo2, but the final line of the output of code_warntype shows it returning Foo3 (if I am interpreting the output correctly). I get similar results on Julia 1.0.1

My understanding is inference can return a union or abstract type, but should not return a concrete type that is incorrect. Is this a bug?

3 Likes

Yes that looks like a bug. Thanks for the clear example. Please file it on github.

1 Like

Filed: Incorrectly Inferred Return type · Issue #30394 · JuliaLang/julia · GitHub

3 Likes