The following two examples each produce supposedly impossible results or crash the repl entirely, even though the code is pure Julia. I did not manage to reduce the examples further, at least not by simplifying single lines:
For instance, in the first example, at line 17, changing Vector{Tuple{T,T}} to just Vector{T} fixes the output. In the second example, removing the first field x::UInt from Between so far leads to correct results.
Maybe I am still overlooking something, but as far as I can tell, there is nothing wrong with the code itself.
First example:
mutable struct Bottom{Val_T}
const val::Val_T
Bottom{Val_T}() where Val_T = new{Val_T}(Val_T())
end
struct Mid{Val_T}
val::Val_T
bottom::Bottom{Val_T}
end
function Mid{Val_T}() where Val_T
bottom = Bottom{Val_T}()
Mid(bottom.val, bottom)
end
mutable struct Val{T}
tuple_TT::Vector{Tuple{T,T}}
Val{T}() where T = new{T}()
end
struct TopLevel
mid::Union{Nothing,Mid{Val{TopLevel}}}
end
TopLevel() = TopLevel(Mid{Val{TopLevel}}())
foo(x::Mid) = x
function test()
x = TopLevel()
v = TopLevel[x, x]
y = v[1]
println(typeof(y) === typeof(x)) # true
x_mid = getfield(x, :mid)
println(typeof(x_mid)) # Mid{Val{TopLevel}}
foo(x_mid)
y_mid = getfield(y, :mid)
println(typeof(y_mid)) # TopLevel
try
foo(y_mid)
catch err
println(err) # MethodError(Main.foo, (TopLevel(Mid{Val{TopLevel}}(Val{TopLevel}(#undef), Bottom{Val{TopLevel}}(Val{TopLevel}(#undef)))),), h*) (*for some UInt h)
end
end
test()
Second example:
struct Between{Val_T}
x::UInt
y::Val_T
Between{Val_T}() where Val_T = new{Val_T}(UInt(0), Val_T())
end
mutable struct Bottom{Val_T}
const val::Val_T
Bottom{Val_T}() where Val_T = new{Val_T}(Val_T())
end
struct Mid{Val_T}
val::Val_T
bottom::Bottom{Val_T}
end
function Mid{Val_T}() where Val_T
bottom = Bottom{Val_T}()
Mid(bottom.val, bottom)
end
mutable struct Val{T}
tuple_TT::Vector{Tuple{T,T}}
Val{T}() where T = new{T}()
end
struct TopLevel
mid::Mid{Between{Val{TopLevel}}}
end
TopLevel() = TopLevel(Mid{Between{Val{TopLevel}}}())
function test()
x = TopLevel()
v = [x, x]
y = v[1]
println("types start equal: $(typeof(y) === typeof(x)) \n")
println(y.mid.bottom) # prints ReentrantLock()
x = TopLevel()
v = Any[x, x]
y = v[1]
println("types start equal: $(typeof(y) === typeof(x)) \n")
# println(y.mid) # when uncommented, the repl crashes seemingly randomly sometimes directly, sometimes after rerunning the script several times
end
test()