Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mistaken inference error on first call #21369

Closed
timholy opened this issue Apr 13, 2017 · 4 comments
Closed

Mistaken inference error on first call #21369

timholy opened this issue Apr 13, 2017 · 4 comments
Assignees
Labels
compiler:inference Type inference kind:bug Indicates an unexpected problem or unintended behavior

Comments

@timholy
Copy link
Sponsor Member

timholy commented Apr 13, 2017

Distilled from ImageMagick.jl:

mapIM(x::Number) = x

function breaks(img, mapi=identity)
    local imgw
    try
        imgw = map(x->mapIM(mapi(x)), img)
    catch
        warn("this type didn't work")
        rethrow()
    end
end

mutable struct TestType end

breaks([TestType() TestType()])

Upon usage:

julia> include("/home/tim/tmp/im_bug.jl")
WARNING: this type didn't work
ERROR: LoadError: TypeError: Dense: in T, expected T<:Union{Complex{Float64}, Float64}, got Type{StackFrame}
Stacktrace:
 [1] _methods_by_ftype(::Any, ::Int64, ::UInt64, ::Array{UInt64,1}, ::Array{UInt64,1}) at ./reflection.jl:521
 [2] abstract_call_gf_by_type(::Any, ::Any, ::Core.Inference.InferenceState) at ./inference.jl:1267
 [3] abstract_call(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1864
 [4] abstract_eval_call(::Expr, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1894
 [5] abstract_eval(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1917
 [6] copy!(::Array{Any,1}, ::Core.Inference.Generator{Array{Any,1},Core.Inference.##187#188{Array{Any,1},Core.Inference.InferenceState}}) at ./abstractarray.jl:565
 [7] abstract_eval_call(::Expr, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1868
 [8] abstract_eval(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1917
 [9] abstract_interpret(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:2040
 [10] typeinf_frame(::Core.Inference.InferenceState) at ./inference.jl:2704
 [11] typeinf_loop(::Core.Inference.InferenceState) at ./inference.jl:2603
 [12] typeinf_frame(::Core.MethodInstance, ::Core.Inference.InferenceState, ::Bool, ::Bool, ::Core.Inference.InferenceParams) at ./inference.jl:2473
 [13] typeinf_edge(::Method, ::Any, ::SimpleVector, ::Core.Inference.InferenceState) at ./inference.jl:2496
 [14] abstract_call_gf_by_type(::Any, ::Any, ::Core.Inference.InferenceState) at ./inference.jl:1386
 [15] abstract_call(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1864
 [16] abstract_eval_call(::Expr, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1894
 [17] abstract_eval(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1917
 [18] typeinf_frame(::Core.Inference.InferenceState) at ./inference.jl:2757
 [19] typeinf_loop(::Core.Inference.InferenceState) at ./inference.jl:2603
 [20] typeinf_frame(::Core.MethodInstance, ::Core.Inference.InferenceState, ::Bool, ::Bool, ::Core.Inference.InferenceParams) at ./inference.jl:2473
 [21] typeinf_edge(::Method, ::Any, ::SimpleVector, ::Core.Inference.InferenceState) at ./inference.jl:2496
 [22] abstract_call_gf_by_type(::Any, ::Any, ::Core.Inference.InferenceState) at ./inference.jl:1386
 [23] abstract_call(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1864
 [24] abstract_eval_call(::Expr, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1894
 [25] abstract_eval(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1917
 [26] abstract_interpret(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:2040
 [27] typeinf_frame(::Core.Inference.InferenceState) at ./inference.jl:2704
 [28] typeinf_loop(::Core.Inference.InferenceState) at ./inference.jl:2603
 [29] typeinf_frame(::Core.MethodInstance, ::Core.Inference.InferenceState, ::Bool, ::Bool, ::Core.Inference.InferenceParams) at ./inference.jl:2473
 [30] typeinf_edge(::Method, ::Any, ::SimpleVector, ::Core.Inference.InferenceState) at ./inference.jl:2496
 [31] abstract_call_gf_by_type(::Any, ::Any, ::Core.Inference.InferenceState) at ./inference.jl:1386
 [32] abstract_call(::Any, ::Tuple{}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1864
 [33] abstract_apply(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1516
 [34] abstract_call(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1648
 [35] abstract_eval_call(::Expr, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1894
 [36] abstract_eval(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1917
 [37] typeinf_frame(::Core.Inference.InferenceState) at ./inference.jl:2757
 [38] typeinf_loop(::Core.Inference.InferenceState) at ./inference.jl:2620
 [39] typeinf_frame(::Core.MethodInstance, ::Void, ::Bool, ::Bool, ::Core.Inference.InferenceParams) at ./inference.jl:2473
 [40] typeinf_code(::Core.MethodInstance, ::Bool, ::Bool, ::Core.Inference.InferenceParams) at ./inference.jl:2543
 [41] typeinf_ext(::Core.MethodInstance, ::UInt64) at ./inference.jl:2582
 [42] #warn#515(::Array{Any,1}, ::Function, ::String, ::Vararg{String,N} where N) at ./util.jl:585
 [43] breaks(::Array{TestType,2}, ::Base.#identity) at /home/tim/tmp/im_bug.jl:8
 [44] breaks(::Array{TestType,2}) at /home/tim/tmp/im_bug.jl:4
 [45] include_from_node1(::String) at ./loading.jl:539
 [46] include(::String) at ./sysimg.jl:14
while loading /home/tim/tmp/im_bug.jl, in expression starting on line 15

julia> breaks([TestType() TestType()])
WARNING: this type didn't work
ERROR: MethodError: no method matching mapIM(::TestType)
Closest candidates are:
  mapIM(::Number) at /home/tim/tmp/im_bug.jl:1
Stacktrace:
 [1] _collect(::Array{TestType,2}, ::Base.Generator{Array{TestType,2},##3#4{Base.#identity}}, ::Base.EltypeUnknown, ::Base.HasShape) at ./array.jl:441
 [2] breaks(::Array{TestType,2}, ::Base.#identity) at /home/tim/tmp/im_bug.jl:6
 [3] breaks(::Array{TestType,2}) at /home/tim/tmp/im_bug.jl:4
@martinholters
Copy link
Member

Even simpler repro:

julia> function breaks()
           try
               error("ohoh")
           catch
               warn(STDERR, "this didn't work")
               rethrow()
           end
       end
breaks (generic function with 1 method)

julia> breaks()
WARNING: this didn't work
ERROR: TypeError: Dense: in T, expected T<:Union{Complex{Float64}, Float64}, got Type{StackFrame}
Stacktrace:
 [1] _methods_by_ftype(::Any, ::Int64, ::UInt64, ::Array{UInt64,1}, ::Array{UInt64,1}) at ./reflection.jl:521
 [2] abstract_call_gf_by_type(::Any, ::Any, ::Core.Inference.InferenceState) at ./inference.jl:1267
 [3] abstract_call(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1864
 [4] abstract_eval_call(::Expr, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1894
 [5] abstract_eval(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1917
 [6] copy!(::Array{Any,1}, ::Core.Inference.Generator{Array{Any,1},Core.Inference.##187#188{Array{Any,1},Core.Inference.InferenceState}}) at ./abstractarray.jl:565
 [7] abstract_eval_call(::Expr, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1868
 [8] abstract_eval(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1917
 [9] abstract_interpret(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:2040
 [10] typeinf_frame(::Core.Inference.InferenceState) at ./inference.jl:2704
 [11] typeinf_loop(::Core.Inference.InferenceState) at ./inference.jl:2603
 [12] typeinf_frame(::Core.MethodInstance, ::Core.Inference.InferenceState, ::Bool, ::Bool, ::Core.Inference.InferenceParams) at ./inference.jl:2473
 [13] typeinf_edge(::Method, ::Any, ::SimpleVector, ::Core.Inference.InferenceState) at ./inference.jl:2496
 [14] abstract_call_gf_by_type(::Any, ::Any, ::Core.Inference.InferenceState) at ./inference.jl:1386
 [15] abstract_call(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1864
 [16] abstract_eval_call(::Expr, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1894
 [17] abstract_eval(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1917
 [18] typeinf_frame(::Core.Inference.InferenceState) at ./inference.jl:2757
 [19] typeinf_loop(::Core.Inference.InferenceState) at ./inference.jl:2603
 [20] typeinf_frame(::Core.MethodInstance, ::Core.Inference.InferenceState, ::Bool, ::Bool, ::Core.Inference.InferenceParams) at ./inference.jl:2473
 [21] typeinf_edge(::Method, ::Any, ::SimpleVector, ::Core.Inference.InferenceState) at ./inference.jl:2496
 [22] abstract_call_gf_by_type(::Any, ::Any, ::Core.Inference.InferenceState) at ./inference.jl:1386
 [23] abstract_call(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1864
 [24] abstract_eval_call(::Expr, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1894
 [25] abstract_eval(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1917
 [26] abstract_interpret(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:2040
 [27] typeinf_frame(::Core.Inference.InferenceState) at ./inference.jl:2704
 [28] typeinf_loop(::Core.Inference.InferenceState) at ./inference.jl:2603
 [29] typeinf_frame(::Core.MethodInstance, ::Core.Inference.InferenceState, ::Bool, ::Bool, ::Core.Inference.InferenceParams) at ./inference.jl:2473
 [30] typeinf_edge(::Method, ::Any, ::SimpleVector, ::Core.Inference.InferenceState) at ./inference.jl:2496
 [31] abstract_call_gf_by_type(::Any, ::Any, ::Core.Inference.InferenceState) at ./inference.jl:1386
 [32] abstract_call(::Any, ::Tuple{}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1864
 [33] abstract_apply(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1516
 [34] abstract_call(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1648
 [35] abstract_eval_call(::Expr, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1894
 [36] abstract_eval(::Any, ::Array{Any,1}, ::Core.Inference.InferenceState) at ./inference.jl:1917
 [37] typeinf_frame(::Core.Inference.InferenceState) at ./inference.jl:2757
 [38] typeinf_loop(::Core.Inference.InferenceState) at ./inference.jl:2620
 [39] typeinf_frame(::Core.MethodInstance, ::Void, ::Bool, ::Bool, ::Core.Inference.InferenceParams) at ./inference.jl:2473
 [40] typeinf_code(::Core.MethodInstance, ::Bool, ::Bool, ::Core.Inference.InferenceParams) at ./inference.jl:2543
 [41] typeinf_ext(::Core.MethodInstance, ::UInt64) at ./inference.jl:2582
 [42] breaks() at ./REPL[1]:5

BUT (in a fresh session):

julia> function breaks()
                  try
                      error("ohoh")
                  catch
                      warn(STDERR, "this didn't work")
                      rethrow()
                  end
              end
breaks (generic function with 1 method)

julia> warn(STDERR, "this didn't work")
WARNING: this didn't work

julia> breaks()
WARNING: this didn't work
ERROR: ohoh
Stacktrace:
 [1] breaks() at ./REPL[0]:3

Also (fresh session again):

julia> warn(STDERR, "this didn't work")
WARNING: this didn't work

julia> rethrow()
ERROR: TypeError: Dense: in T, expected T<:Union{Complex{Float64}, Float64}, got Type{StackFrame}

So I guess this is #19979 and for some reason there is an exception thrown and caught inside the type inference of warn.

@JeffBezanson
Copy link
Sponsor Member

Yes, these internal exceptions are pretty annoying. Maybe finally time to tackle it.

What's happening is that we often need to try instantiating types, and only find out that the instantiation is invalid by catching the type error that's thrown. For example this case is intersecting:

Tuple{typeof(Base.convert), Type{Array{Base.StackTraces.StackFrame, 1}}, Any}
Tuple{typeof(Base.convert), Type{Array{T, 1}}, Base.SparseArrays.CHOLMOD.Dense{T}} where T

which overlap if, perversely, we have a CHOLMOD.Dense{StackFrame} (one of the funniest types I have seen, so that's a plus). We can only find this out by trying the full substitution of StackFrame for T in the second type.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Apr 13, 2017

I think that's one facet of it. I think the solution here is that we should save/restore the error/backtrace across calls to compilation / type-inference in jl_type_infer,jl_compile_for_dispatch, and jl_run_finalizer so that the operation of those functions is transparent to the callee. Someday later, we can consider making the rethrow function require an explicit object so that it is inherently scoped, but that should be OK to be entirely separate.

@JeffBezanson
Copy link
Sponsor Member

Yes, that would be good. Even easier, we could disable collection of backtraces in those contexts, which would save the compiler some time too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:inference Type inference kind:bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

4 participants