Strange failure in v0.6


#1

When trying to pre-compile one of our modules on v0.6, I got this strange inference failure.
Everything works fine on v0.4.7, v0.5.0 and v0.5.1.
The stack trace goes on and on, but never displays any information about where it was in the source code that triggered this failure.

I’m pretty sure about a week ago, everything compiled just fine on master.

julia> using ActionData
INFO: Precompiling module ActionData.
WARNING: An error occurred during inference. Type inference is now partially disabled.
Base.MethodError(f=Base.#string(), args=(Expr(:||, Expr(:call, :!, Expr(:call, :isa, :t, :Type)::Any)::Any, Expr(:<:, :t, :r)::Any)::Any,), world=0x0000000000000aa3)
rec_backtrace at /julia/julia-linux/src/stackwalk.c:84
record_backtrace at /julia/julia-linux/src/task.c:239
jl_throw at /julia/julia-linux/src/task.c:565
jl_method_error_bare at /julia/julia-linux/src/gf.c:1431
jl_method_error at /julia/julia-linux/src/gf.c:1449
jl_lookup_generic_ at /julia/julia-linux/src/gf.c:2202 [inlined]
jl_apply_generic at /julia/julia-linux/src/gf.c:2222
limit_type_depth at ./inference.jl:666
unknown function (ip: 0x7fcdf3009cc2)
jl_call_fptr_internal at /julia/julia-linux/src/julia_internal.h:326 [inlined]
jl_call_method_internal at /julia/julia-linux/src/julia_internal.h:345 [inlined]
jl_apply_generic at /julia/julia-linux/src/gf.c:2225
abstract_call_gf_by_type at ./inference.jl:1328
unknown function (ip: 0x7fcdf2fe3a96)
jl_call_fptr_internal at /julia/julia-linux/src/julia_internal.h:326 [inlined]
jl_call_method_internal at /julia/julia-linux/src/julia_internal.h:345 [inlined]
jl_apply_generic at /julia/julia-linux/src/gf.c:2225
abstract_call at ./inference.jl:1856
unknown function (ip: 0x7fcdf2fdf9ce)
jl_call_fptr_internal at /julia/julia-linux/src/julia_internal.h:326 [inlined]
jl_call_method_internal at /julia/julia-linux/src/julia_internal.h:345 [inlined]
jl_apply_generic at /julia/julia-linux/src/gf.c:2225
abstract_eval_call at ./inference.jl:1886
abstract_eval at ./inference.jl:1909
unknown function (ip: 0x7fcdf2fda9f6)
jl_call_fptr_internal at /julia/julia-linux/src/julia_internal.h:326 [inlined]
jl_call_method_internal at /julia/julia-linux/src/julia_internal.h:345 [inlined]
jl_apply_generic at /julia/julia-linux/src/gf.c:2225
copy! at ./abstractarray.jl:565
abstract_eval_call at ./inference.jl:1860
abstract_eval at ./inference.jl:1909
unknown function (ip: 0x7fcdf2fda9f6)
jl_call_fptr_internal at /julia/julia-linux/src/julia_internal.h:326 [inlined]
jl_call_method_internal at /julia/julia-linux/src/julia_internal.h:345 [inlined]
jl_apply_generic at /julia/julia-linux/src/gf.c:2225
typeinf_frame at ./inference.jl:2745
typeinf_loop at ./inference.jl:2591
typeinf_frame at ./inference.jl:2461
typeinf_edge at ./inference.jl:2484
unknown function (ip: 0x7fcdf2fe5b1a)
jl_call_fptr_internal at /julia/julia-linux/src/julia_internal.h:326 [inlined]
jl_call_method_internal at /julia/julia-linux/src/julia_internal.h:345 [inlined]
jl_apply_generic at /julia/julia-linux/src/gf.c:2225
abstract_call_gf_by_type at ./inference.jl:1378
unknown function (ip: 0x7fcdf2fe3a96)
jl_call_fptr_internal at /julia/julia-linux/src/julia_internal.h:326 [inlined]
jl_call_method_internal at /julia/julia-linux/src/julia_internal.h:345 [inlined]
jl_apply_generic at /julia/julia-linux/src/gf.c:2225
abstract_call at ./inference.jl:1856
unknown function (ip: 0x7fcdf3001d7a)
jl_call_fptr_internal at /julia/julia-linux/src/julia_internal.h:326 [inlined]
jl_call_method_internal at /julia/julia-linux/src/julia_internal.h:345 [inlined]
jl_apply_generic at /julia/julia-linux/src/gf.c:2225
return_type_tfunc at ./inference.jl:1535

(note: the stack trace goes on for quite a while, generally hitting the same places over and over)

Any ideas about where this could be coming from would be appreciated.


#2

Are you on master or the tagged 0.6-alpha? If the latter, perhaps try updating to master, that stack trace and message looks alot like one I occasionally saw during the bug I reported here which was eventually fixed a few days ago.


#3

I’m on master, v"0.6.0-pre.alpha.265".
I had noticed that there were a number of inference related bugs fixed recently, and wondered if this has been around for a while, or is something fairly new.
I’m going to try to build an earlier version of v0.6 and retest (because I thought [but I might be mistaken], that this worked for me on master a week or so ago).


#4

You can use git bisect to locate the bad commit.


#5

Good idea. As soon as I can get it to a MWE (that doesn’t have a bunch of proprietary code), I’ll do just that.


#6

Sorry to state the obvious, but have you tried clearing the ~/.julia/lib/cache? And FWIW, I’ve seen corruption on 0.6 due to Requires.jl.


#7

Yes, I always do that. I’m getting close to a MWE, hopefully will be able to post it tonight.


#8

Here is the best I’ve been able to cut it down to:

__precompile__()

module InfBug

immutable A1 end
immutable A2 end
immutable A3 end
immutable A4 end
immutable A5 end
immutable A6 end
immutable A7 end

# Note: one less in the Union, and it doesn't fail
const Ugh = Union{A1, A2, A3, A4, A5, A6, A7}

import Base: convert

immutable Foo
    a::Vector{UInt64}
end
convert(::Type{Vector{Foo}}, av::Vector{Any}) = Foo[Foo(vec) for vec in av]

immutable Bar
    a::Ugh
    b::Vector{UInt64}
end

function convert(::Type{Vector{Bar}}, a::Vector{Ugh},
                 b::Vector{Vector{UInt64}}=Vector{Vector{UInt64}}())
    (isempty(b)
     ? Vector{Bar}([Bar(i, Vector{UInt64}()) for i in a])
     : Vector{Bar}([Bar(i[1], i[2]) for i in zip(a, b)]))
end
end # module

I wasn’t able to get it any smaller than this, it is sensitive to the number of types in the Union, if I comment out one of the convert definitions it also doesn’t fail.

This happens in the call to write_dependency_list at /julia/julia-linux/src/dump.c:1308 [inlined] during precompilation.
I patched the function in inference.jl to give better information when the assertion fails, this is what it showed:

limit_type_depth: Base.Generator{Base.Iterators.Zip2{Array{Union{InfBug.A1, InfBug.A2, InfBug.A3, InfBug.A4, InfBug.A5, InfBug.A6, InfBug.A7}, 1}, Array{Array{UInt64, 1}, 1}}, InfBug.##2#4} <: Base.Generator{Base.Iterators.Zip2{Array{Any, 1}, Array{Array{UInt64, 1}, 1}}, InfBug.##2#4}
WARNING: An error occurred during inference. Type inference is now partially disabled.

I think that maybe @jeff.bezanson may need to take a look at this.


#9

cc: @martinholters. I’ve also copied this thread to the PR that introduced this assertion, https://github.com/JuliaLang/julia/pull/20626.


#10

Hrrm, I have a fix for this at https://github.com/JuliaLang/julia/pull/21192, but it now just triggers another bug (https://github.com/JuliaLang/julia/issues/21191) I found along the way…


#11

Thanks for jumping on this so quickly!

One thing when trying to figure out what was going on, the output of the @assert macro was not very useful, because you never get the important information, i.e. what the values of r and t are. I don’t know what the best way of writing an assertion that would only be compiled in with assertions on, but that would display (return in the error message) the actual values that caused the failure).

Also, for some reason, the backtrace doesn’t contain any information at all about what source code triggered the inference failure, this occurred in precompilation. I don’t know if the line number / file name information is still available when this occurs, and if it would be very difficult to have the information returned in the error message.

Thanks again!


#12

Yes, the output of the @assert is not pretty. I obviously hadn’t tested it… Anyway, it managed to figure out a wrong type had been computed and prevented it from being used by type inference.


#13

The @assert macro has an optional [text] argument, which is displayed if the assertion is false, that would be perfect in this case to give an informative message, i.e. something like @assert cond "Type $r ! <: $t" (or whatever)