After some discussion in https://github.com/BenLauwens/SimJulia.jl/issues/63 it seems the following is a regression in 1.3. Running (where some of this code has been macroexpanded from ResumableFunctions):
using ResumableFunctions
using SimJulia
mutable struct var"##403" <: ResumableFunctions.FiniteStateMachineIterator{Any}
_state::UInt8
sim::Simulation
a::Int64
b::Int64
function var"##403"(sim::Simulation; )::var"##403"
fsmi = new()
fsmi._state = 0x00
fsmi.sim = sim
fsmi
end
end
function fibonnaci(sim::Simulation; )::var"##403"
var"##403"(sim; )
end
function (_fsmi::var"##403")(_arg::Any=nothing; )::Union{Any, Nothing, Bool}
_fsmi._state == 0x00 && @goto(_STATE_0)
_fsmi._state == 0x01 && @goto(_STATE_1)
error("@resumable function has stopped!")
@label _STATE_0
_fsmi._state = 0xff
_arg isa Exception && throw(_arg)
_fsmi.a = 0
_fsmi.b = 1
while true
println(_fsmi.a)
_fsmi._state = 0x01
return timeout(_fsmi.sim, 1)
@label _STATE_1
_fsmi._state = 0xff
_arg isa Exception && throw(_arg)
(_fsmi.a, _fsmi.b) = (_fsmi.b, _fsmi.a + _fsmi.b)
end
end
sim = Simulation()
@process fibonnaci(sim)
run(sim, 10)
crashes with
0
Unreachable reached at 0x7f1ab3271abf
signal (4): Illegal instruction
in expression starting at /home/kc/Documents/JuliaTests/failing.jl:44
execute at /home/kc/.julia/packages/SimJulia/alkAr/src/processes.jl:32
#3 at /home/kc/.julia/packages/SimJulia/alkAr/src/base.jl:51
_jl_invoke at /home/kc/julia/src/gf.c:2136 [inlined]
jl_apply_generic at /home/kc/julia/src/gf.c:2300
step at /home/kc/.julia/packages/SimJulia/alkAr/src/simulations.jl:39
run at /home/kc/.julia/packages/SimJulia/alkAr/src/base.jl:91
run at /home/kc/.julia/packages/SimJulia/alkAr/src/events.jl:29
unknown function (ip: 0x7f1ab3270cf6)
_jl_invoke at /home/kc/julia/src/gf.c:2136 [inlined]
jl_apply_generic at /home/kc/julia/src/gf.c:2300
jl_apply at /home/kc/julia/src/julia.h:1631 [inlined]
do_call at /home/kc/julia/src/interpreter.c:328
eval_value at /home/kc/julia/src/interpreter.c:417
eval_stmt_value at /home/kc/julia/src/interpreter.c:368 [inlined]
eval_body at /home/kc/julia/src/interpreter.c:764
jl_interpret_toplevel_thunk_callback at /home/kc/julia/src/interpreter.c:888
unknown function (ip: 0xfffffffffffffffe)
unknown function (ip: 0x7f1acf11458f)
unknown function (ip: 0xffffffffffffffff)
jl_interpret_toplevel_thunk at /home/kc/julia/src/interpreter.c:897
jl_toplevel_eval_flex at /home/kc/julia/src/toplevel.c:814
jl_parse_eval_all at /home/kc/julia/src/ast.c:873
jl_load at /home/kc/julia/src/toplevel.c:878
include at ./boot.jl:328 [inlined]
include_relative at ./loading.jl:1105
include at ./Base.jl:31
_jl_invoke at /home/kc/julia/src/gf.c:2130 [inlined]
jl_apply_generic at /home/kc/julia/src/gf.c:2300
exec_options at ./client.jl:295
_start at ./client.jl:468
jfptr__start_2083 at /home/kc/julia/usr/lib/julia/sys.so (unknown line)
_jl_invoke at /home/kc/julia/src/gf.c:2130 [inlined]
jl_apply_generic at /home/kc/julia/src/gf.c:2300
jl_apply at /home/kc/julia/ui/../src/julia.h:1631 [inlined]
true_main at /home/kc/julia/ui/repl.c:96
main at /home/kc/julia/ui/repl.c:217
__libc_start_main at /build/glibc-KRRWSm/glibc-2.29/csu/../csu/libc-start.c:308
_start at /home/kc/julia/julia (unknown line)
Allocations: 744501 (Pool: 744209; Big: 292); GC: 1
[1] 27250 illegal hardware instruction (core dumped) ~/julia/julia failing.jl
Running the code through JuliaInterpreter works fine.
Also, just renaming the variable var"##403"
to something else, (like MyTest
) makes the code work:
diff working.jl failing.jl
< mutable struct MyTest <: ResumableFunctions.FiniteStateMachineIterator{Any}
---
> mutable struct var"##403" <: ResumableFunctions.FiniteStateMachineIterator{Any}
10c9
< function MyTest(sim::Simulation; )::MyTest
---
> function var"##403"(sim::Simulation; )::var"##403"
17,18c16,17
< function fibonnaci(sim::Simulation; )::MyTest
< MyTest(sim; )
---
> function fibonnaci(sim::Simulation; )::var"##403"
> var"##403"(sim; )
20c19
< function (_fsmi::MyTest)(_arg::Any=nothing; )::Union{Any, Nothing, Bool}
---
> function (_fsmi::var"##403")(_arg::Any=nothing; )::Union{Any, Nothing, Bool}
โ ~/julia/julia working.jl
0
1
1
2
3
5
8
13
21
34
cc @c42f in case the renaming of the var".."
variable to fix the crash is not a red herring.
Reduced to:
module a
abstract type b{c} end
end
module d
using ..a
export g, @h
mutable struct g fsmi :: a.b
function g(func )
i = new()
i.fsmi = func(env )
execute(i, i)
end
end
macro h(expr)
esc(:(g($(expr.args...))))
end
function execute(f, i)
try
i.fsmi()
catch end
end
end
using .d
struct var"##403" <: a.b{Any}
function var"##403"(e)
new()
end
end
function fibonnaci(e)var"##403"(j)
end
function (::var"##403")()
end
@h fibonnaci()
Is it possible to learn this power?
I suspect Tim is doing https://discourse.julialang.org/t/ann-automatic-test-case-reduction/17700 ;)
Further reduction:
abstract type B end
mutable struct G
f :: B
function G(x)
g = new()
g.f = x
g.f()
end
end
n = Symbol("#1") # Needs to start with `#` ??
@eval begin
struct $n <: B
end
function (::$n)()
end
x = $n()
end
G(x)
Looks like maybe a failure in type inference which is somehow related to internally named types (?)
for n in [Symbol("#1"), :X]
@eval module A
abstract type B end
struct $n <: B
end
function (::$n)()
end
x = $n()
mutable struct G
f :: B
function G(x)
g = new()
g.f = x
g.f()
end
end
using InteractiveUtils
println("Code for $(typeof(x))")
show(@code_typed G(x))
println()
end
end
Produces:
Code for Main.A.var"#1"
CodeInfo(
1 โ %1 = Main.A.G::Core.Compiler.Const(Main.A.G, false)
โ %2 = %new(%1)::Main.A.G
โ Base.setfield!(%2, :f, $(QuoteNode(Main.A.var"#1"())))::Main.A.var"#1"
โ %4 = Base.getfield(%2, :f)::Main.A.B
โ (%4)()::Union{}
โโโ $(Expr(:unreachable))::Union{}
) => Union{}
Code for Main.A.X
CodeInfo(
1 โ %1 = Main.A.G::Core.Compiler.Const(Main.A.G, false)
โ %2 = %new(%1)::Main.A.G
โ Base.setfield!(%2, :f, $(QuoteNode(Main.A.X())))::Main.A.X
โ %4 = Base.getfield(%2, :f)::Main.A.B
โ %5 = (isa)(%4, Main.A.X)::Bool
โโโ goto #3 if not %5
2 โ goto #4
3 โ %8 = (%4)()::Core.Compiler.Const(nothing, false)
โโโ goto #4
4 โ %10 = ฯ (#2 => nothing, #3 => %8)::Core.Compiler.Const(nothing, false)
โโโ return %10
) => Nothing
yet both these should be exactly the same, given they have identical structure (other than the funny name for typeof(x)
)
@JeffBezanson, @vtjnash, perhaps one of you could look at this soonish? It's the last thing for 1.3-RC3 (and only known regression with 1.3).
Bisected to 99d2406c98a720e9f9e555109297b577232a01a4 cc @vtjnash
This block from that commit looks relevant:
https://github.com/JuliaLang/julia/blob/d0365753fb57f57bcea097c05de8c07aef706561/src/datatype.c#L490-L497
Most helpful comment
Is it possible to learn this power?