Hello!
I came across a weird type inference failure when using generators. Here is a MWE.
function example()
col = 2
ss = (col for _ in 1:5)
col += 3
return col, ss
end
function example2()
col = 2
ss = (col for _ in 1:5)
return col, ss
end
@code_warntype example()
@code_warntype example2()
example
has type instability:
Variables
#self#::Core.Compiler.Const(example, false)
#611::var"#611#612"
ss::Base.Generator{UnitRange{Int64},var"#611#612"}
col@_4::Core.Box
col@_5::Union{}
col@_6::Union{}
Body::Tuple{Any,Base.Generator{UnitRange{Int64},var"#611#612"}}
1 β (col@_4 = Core.Box())
β Core.setfield!(col@_4, :contents, 2)
β (#611 = %new(Main.:(var"#611#612"), col@_4))
β %4 = #611::var"#611#612"
β %5 = (1:5)::Core.Compiler.Const(1:5, false)
β (ss = Base.Generator(%4, %5))
β %7 = Core.isdefined(col@_4, :contents)::Bool
βββ goto #3 if not %7
2 β goto #4
3 β Core.NewvarNode(:(col@_5))
βββ col@_5
4 β %12 = Core.getfield(col@_4, :contents)::Any
β %13 = (%12 + 3)::Any
β Core.setfield!(col@_4, :contents, %13)
β %15 = Core.isdefined(col@_4, :contents)::Bool
βββ goto #6 if not %15
5 β goto #7
6 β Core.NewvarNode(:(col@_6))
βββ col@_6
7 β %20 = Core.getfield(col@_4, :contents)::Any
β %21 = Core.tuple(%20, ss::Core.Compiler.PartialStruct(Base.Generator{UnitRange{Int64},var"#611#612"}, Any[var"#611#612", Core.Compiler.Const(1:5, false)]))::Core.Compiler.PartialStruct(Tuple{Any,Base.Generator{UnitRange{Int64},var"#611#612"}}, Any[Any, Core.Compiler.PartialStruct(Base.Generator{UnitRange{Int64},var"#611#612"}, Any[var"#611#612", Core.Compiler.Const(1:5, false)])])
βββ return %21
However, example2
does not:
Variables
#self#::Core.Compiler.Const(example2, false)
#613::var"#613#614"{Int64}
col::Int64
ss::Base.Generator{UnitRange{Int64},var"#613#614"{Int64}}
Body::Tuple{Int64,Base.Generator{UnitRange{Int64},var"#613#614"{Int64}}}
1 β (col = 2)
β %2 = Main.:(var"#613#614")::Core.Compiler.Const(var"#613#614", false)
β %3 = Core.typeof(col::Core.Compiler.Const(2, false))::Core.Compiler.Const(Int64, false)
β %4 = Core.apply_type(%2, %3)::Core.Compiler.Const(var"#613#614"{Int64}, false)
β (#613 = %new(%4, col::Core.Compiler.Const(2, false)))
β %6 = #613::Core.Compiler.Const(var"#613#614"{Int64}(2), false)::Core.Compiler.Const(var"#613#614"{Int64}(2), false)
β %7 = (1:5)::Core.Compiler.Const(1:5, false)
β (ss = Base.Generator(%6, %7))
β %9 = Core.tuple(col::Core.Compiler.Const(2, false), ss::Core.Compiler.Const(Base.Generator{UnitRange{Int64},var"#613#614"{Int64}}(var"#613#614"{Int64}(2), 1:5), false))::Core.Compiler.Const((2, Base.Generator{UnitRange{Int64},var"#613#614"{Int64}}(var"#613#614"{Int64}(2), 1:5)), false)
βββ return %9
I cannot understand this in terms of usual type instability rules. Could this be a julia type inference bug?