Julia: Unreachable reached (1.5.0-beta1 & 1.4.0)

Created on 26 Jun 2020  Β·  8Comments  Β·  Source: JuliaLang/julia

I have reached the unreachable using the following bugscript.jl::

using InteractiveUtils

struct Joe{N}
    tup::NTuple{N}
    sym::Symbol
    Joe{N}(tup::NTuple{N}, sym::Symbol) where {N} = new(tup, sym)
end

Joe{N}(tup::NTuple{N}) where {N} = Joe{N}(tup, :a)

function bugfunc(::Type{T}) where {T}
    tup1 = (:a, :b)
    tup2 = (:a, :b)
    tup1, tup2 = zip(zip(tup1, tup2)...)
    T(tup1)
end

versioninfo()
bugfunc(Joe{2})
julia --startup-file=no -e 'include("bugscript.jl")'



md5-2bb69aa030d76d1342d66ffddea74293



Julia Version 1.5.0-beta1.0
Commit 6443f6c95a (2020-05-28 17:42 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
Unreachable reached at 0x7f343cc9ddfb

signal (4): Illegal instruction
in expression starting at /home/markus/TyΓΆ/julia/unreachable_MERA/bugscript.jl:19
bugfunc at /home/markus/TyΓΆ/julia/unreachable_MERA/bugscript.jl:15
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2231 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2398
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1689 [inlined]
do_call at /buildworker/worker/package_linux64/build/src/interpreter.c:117
eval_value at /buildworker/worker/package_linux64/build/src/interpreter.c:206
eval_stmt_value at /buildworker/worker/package_linux64/build/src/interpreter.c:157 [inlined]
eval_body at /buildworker/worker/package_linux64/build/src/interpreter.c:566
jl_interpret_toplevel_thunk at /buildworker/worker/package_linux64/build/src/interpreter.c:660
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:840
jl_parse_eval_all at /buildworker/worker/package_linux64/build/src/ast.c:913
jl_load_rewrite at /buildworker/worker/package_linux64/build/src/toplevel.c:914
include at ./client.jl:457
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2214 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2398
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1689 [inlined]
do_call at /buildworker/worker/package_linux64/build/src/interpreter.c:117
eval_value at /buildworker/worker/package_linux64/build/src/interpreter.c:206
eval_stmt_value at /buildworker/worker/package_linux64/build/src/interpreter.c:157 [inlined]
eval_body at /buildworker/worker/package_linux64/build/src/interpreter.c:566
jl_interpret_toplevel_thunk at /buildworker/worker/package_linux64/build/src/interpreter.c:660
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:840
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:790
jl_toplevel_eval_in at /buildworker/worker/package_linux64/build/src/toplevel.c:883
eval at ./boot.jl:331
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2214 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2398
exec_options at ./client.jl:272
_start at ./client.jl:506
jfptr__start_35292.clone_1 at /home/markus/Downloads/julia-1.5.0-beta1/lib/julia/sys.so (unknown line)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2214 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2398
jl_apply at /buildworker/worker/package_linux64/build/ui/../src/julia.h:1689 [inlined]
true_main at /buildworker/worker/package_linux64/build/ui/repl.c:106
main at /buildworker/worker/package_linux64/build/ui/repl.c:227
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
_start at /home/markus/Downloads/julia-1.5.0-beta1/bin/julia (unknown line)
Allocations: 3466189 (Pool: 3464834; Big: 1355); GC: 4
Illegal instruction (core dumped)

As mentioned in the title, this happens on at least 1.4.0 and 1.5.0-beta1.

The above is pretty much the smallest example I could reduce this down to, but let me know if I can do something else to help track this down further.

bug types and dispatch

Most helpful comment

Further reduction which also crashes on master:

struct Joe{N}
    Joe{N}(tup::NTuple{N}, sym::Symbol) where {N} = new()
end

Joe{N}(tup::NTuple{N}) where {N} = Joe{2}(tup, :a)

function bugfunc(::Type{T}) where {T}
    tup1 = Tuple{Any, Vararg}[(:a, :b)][1]
    T(tup1)
end

bugfunc(Joe{2})

Inference gets something wrong here:

julia> @code_typed bugfunc(Joe{2})
CodeInfo(
1 ─ %1 = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Tuple{Any,Vararg{Any,N} where N},1}, svec(Any, Int64), 0, :(:ccall), Array{Tuple{Any,Vararg{Any,N} where N},1}, 1, 1))::Array{Tuple{Any,Vararg{Any,N} where N},1}
β”‚        Base.arrayset(false, %1, (:a, :b), 1)::Array{Tuple{Any,Vararg{Any,N} where N},1}
β”‚   %3 = Base.arrayref(true, %1, 1)::Tuple{Any,Vararg{Any,N} where N}
β”‚        ($(Expr(:static_parameter, 1)))(%3)::Union{}
└──      unreachable
) => Union{}

julia> code_typed(Joe{2}, (Tuple{Any,Vararg},))
1-element Array{Any,1}:
 CodeInfo(
1 ─     (Joe{2})(tup, :a)::Union{}
└──     unreachable
) => Union{}

julia> Joe{2}((:a, :b))
Joe{2}()

All 8 comments

Seems to work on master.

Finally got to compiling julia from source: Yes, works on master for me too. Still failing on 1.5.0-rc1, so I guess the fix will be in 1.5.1?

Still failing on 1.5.0-rc1, so I guess the fix will be in 1.5.1?

If the PR that fixes it is identified and is eligible for backporting. The best way to find it is usually to do a bisection.

I unfortunately don't quite have the git-fu and time to do that. I'm fine closing this and waiting for 1.6 too, I can probably work around the bug until then.

Bisect took me to cb41bbbce7938bd716d24fc82094c6eb87beb26c, but that probably only circumvents some underlying bug here.

Further reduction which also crashes on master:

struct Joe{N}
    Joe{N}(tup::NTuple{N}, sym::Symbol) where {N} = new()
end

Joe{N}(tup::NTuple{N}) where {N} = Joe{2}(tup, :a)

function bugfunc(::Type{T}) where {T}
    tup1 = Tuple{Any, Vararg}[(:a, :b)][1]
    T(tup1)
end

bugfunc(Joe{2})

Inference gets something wrong here:

julia> @code_typed bugfunc(Joe{2})
CodeInfo(
1 ─ %1 = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Tuple{Any,Vararg{Any,N} where N},1}, svec(Any, Int64), 0, :(:ccall), Array{Tuple{Any,Vararg{Any,N} where N},1}, 1, 1))::Array{Tuple{Any,Vararg{Any,N} where N},1}
β”‚        Base.arrayset(false, %1, (:a, :b), 1)::Array{Tuple{Any,Vararg{Any,N} where N},1}
β”‚   %3 = Base.arrayref(true, %1, 1)::Tuple{Any,Vararg{Any,N} where N}
β”‚        ($(Expr(:static_parameter, 1)))(%3)::Union{}
└──      unreachable
) => Union{}

julia> code_typed(Joe{2}, (Tuple{Any,Vararg},))
1-element Array{Any,1}:
 CodeInfo(
1 ─     (Joe{2})(tup, :a)::Union{}
└──     unreachable
) => Union{}

julia> Joe{2}((:a, :b))
Joe{2}()

Slight further reduction:

struct Joe{N}
    Joe{N}(tup::NTuple{N}) where {N} = new()
end

joe(tup::NTuple) = Joe{2}(tup)

function bugfunc()
    tup1 = Tuple{Any, Vararg}[(:a, :b)][1]
    joe(tup1)
end

bugfunc()

The problem is

julia> methods(Joe{2}, Tuple{Tuple{T,Vararg{T,N}} where T where N})
# 0 methods for type constructor:

due to this type intersection problem:

julia> typeintersect(Tuple{Type{Joe{N}},Tuple{Vararg{T,N}} where T} where N, Tuple{Type{Joe{2}},Tuple{T,Vararg{T,N}} where T} where N)
Union{} # should be Tuple{Type{Joe{2}},Tuple{Vararg{T,2}} where T}

Note that these work:

julia> typeintersect(Tuple{Type{Joe{N}},Tuple{Vararg{T,N}} where T} where N, Tuple{Type{Joe{2}},Tuple{Vararg{T,N}} where T} where N)
Tuple{Type{Joe{2}},Tuple{Vararg{T,2}} where T}

julia> typeintersect(Tuple{Type{Joe{N}},Tuple{Vararg{T,N}} where T} where N, Tuple{Type{Joe{2}},Tuple{T,T,Vararg{T,N}} where T} where N)
Tuple{Type{Joe{2}},Tuple{T,T} where T}

Taking the M in MWE seriously: f(::NTuple{N}=[(f,),(1,2)][2],::Val{N}=Val(2)) where{N}=0;f()
(No, this is not meant to be helpful, just entertaining.)

Was this page helpful?
0 / 5 - 0 ratings