# A parametric-type related crash on Julia 1.7+

I discovered a very strange crash scenario while developing my package. It seems to only happen on Julia 1.7+. For example, 1.6 runs perfectly well. It took me some time to create this “MWE” from my code base and I hope someone can look into the Julia source code to see what’s going on. Thanks!

``````struct T1{T}
m::T
end

struct T2{L}
tuple::NTuple{3, Int}

function T2{L}(t::NTuple{3, Int}) where {L}
new{sum(t)}(t)
end
end

struct T3{L, N}
a::Tuple{T2{L}}
param::NTuple{N, T1}
function T3(a::Tuple{T2{L}}, pars::NTuple{N, T1}) where {L, N}
new{L, N}(a, pars)
end
end

function f(ts)
pars = []
for t in ts
append!(pars, t.param)
end
pars
end

t1_1 = ((T1{Float64}(1.0), T1{Int}(2)))

t1_2 = ((T1{Float64}(1.2), T1{Int}(1)))

t2_1 = (T2{1}((1,0,0)),)

t2_2 = (T2{2}((2,0,0)),)

[T3(t2_1, t1_1), T3(t2_2, t1_2)] |> f
``````

After some debugging, I find out that this is because Julia tries to become smarter in Julia 1.7 and unfortunately miscalculates field offset.

The core problem is `t.param`, here `t` is inferred as an abstract type `T3{L, 2} where L`. But since `L` is only used for T2 and it doesn’t actually impact the size of T2 (I think you do this deliberately), the size of field `a` is always 24 (3 Int) and stored inline in T3, so a simple pointer arithmetic can be used to load the value of `param`.

In Julia 1.6 there’s no such optimization and Julia simply emits a dynamic call to `jl_f_getfield` and everything is fine. In Julia 1.7 the above optimization is applied and the field offset is wrongly calculated. It should be 24, but calculated as 8. It’s actually something like `fieldoffset(T3{L,2},2)`, where `L` is a type variable. So it will instead load the second element of the field `a`. If you change `t2_1` to `t2_1 = (T2{1}((1,100,0)),) `, then you can get a seg fault caused by dereferencing a 100(0x64) pointer. I think the logic is incorrect somewhere, but since I am not familiar with Julia’s type system so I simply left it here for further exploration.

4 Likes

@frankwswang Have you opened an issue on github? This is definitely a bug needed to be fixed.

2 Likes

No. I will file one now. Thanks for the explanation!

2 Likes