Skip to content

Commit e9ba166

Browse files
vtjnashDilumAluthge
authored andcommitted
types: fix layout issues for Tuple
Fix #44614
1 parent 99bdd00 commit e9ba166

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

src/jltypes.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ static int layout_uses_free_typevars(jl_value_t *v, jl_typeenv_t *env)
6363
return 0;
6464
if (dt->name == jl_namedtuple_typename)
6565
return layout_uses_free_typevars(jl_tparam0(dt), env) || layout_uses_free_typevars(jl_tparam1(dt), env);
66+
if (dt->name == jl_tuple_typename)
67+
// conservative, since we don't want to inline an abstract tuple,
68+
// and we currently declare !has_fixed_layout for these, but that
69+
// means we also won't be able to inline a tuple which is concrete
70+
// except for the use of free type-vars
71+
return 1;
6672
jl_svec_t *types = jl_get_fieldtypes(dt);
6773
size_t i, l = jl_svec_len(types);
6874
for (i = 0; i < l; i++) {
@@ -227,8 +233,10 @@ int jl_has_fixed_layout(jl_datatype_t *dt)
227233
return 1;
228234
if (dt->name->abstract)
229235
return 0;
230-
if (jl_is_tuple_type(dt) || jl_is_namedtuple_type(dt))
231-
return 0; // TODO: relax more?
236+
if (dt->name == jl_namedtuple_typename)
237+
return !layout_uses_free_typevars(jl_tparam0(dt), NULL) && !layout_uses_free_typevars(jl_tparam1(dt), NULL);
238+
if (dt->name == jl_tuple_typename)
239+
return 0;
232240
jl_svec_t *types = jl_get_fieldtypes(dt);
233241
size_t i, l = jl_svec_len(types);
234242
for (i = 0; i < l; i++) {

test/core.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7360,6 +7360,29 @@ struct A43411{S, T}
73607360
end
73617361
@test isbitstype(A43411{(:a,), Tuple{Int}})
73627362

7363+
# issue #44614
7364+
struct T44614_1{T}
7365+
m::T
7366+
end
7367+
struct T44614_2{L}
7368+
tuple::NTuple{3, Int64}
7369+
T44614_2{L}(t::NTuple{3, Int64}) where {L} = new{sum(t)}(t)
7370+
end
7371+
struct T44614_3{L, N}
7372+
a::Tuple{T44614_2{L}}
7373+
param::NTuple{N, T44614_1}
7374+
T44614_3(a::Tuple{T44614_2{L}}, pars::NTuple{N, T44614_1}) where {L, N} = new{L, N}(a, pars)
7375+
end
7376+
@test sizeof((T44614_2{L} where L).body) == 24
7377+
let T = T44614_3{L,2} where L
7378+
# these values are computable, but we currently don't know how to compute them properly
7379+
ex = ErrorException("Argument is an incomplete T44614_3 type and does not have a definite size.")
7380+
@test_throws ex sizeof(T.body)
7381+
@test_throws ex sizeof(T)
7382+
@test_throws BoundsError fieldoffset(T.body, 2)
7383+
@test fieldoffset(T{1}, 2) == 24
7384+
end
7385+
73637386
# Issue #34206/34207
73647387
function mre34206(a, n)
73657388
va = view(a, :)

0 commit comments

Comments
 (0)