Skip to content

Commit

Permalink
types: fix layout issues for Tuple
Browse files Browse the repository at this point in the history
Fix #44614
  • Loading branch information
vtjnash authored and DilumAluthge committed Mar 22, 2022
1 parent 99bdd00 commit e9ba166
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ static int layout_uses_free_typevars(jl_value_t *v, jl_typeenv_t *env)
return 0;
if (dt->name == jl_namedtuple_typename)
return layout_uses_free_typevars(jl_tparam0(dt), env) || layout_uses_free_typevars(jl_tparam1(dt), env);
if (dt->name == jl_tuple_typename)
// conservative, since we don't want to inline an abstract tuple,
// and we currently declare !has_fixed_layout for these, but that
// means we also won't be able to inline a tuple which is concrete
// except for the use of free type-vars
return 1;
jl_svec_t *types = jl_get_fieldtypes(dt);
size_t i, l = jl_svec_len(types);
for (i = 0; i < l; i++) {
Expand Down Expand Up @@ -227,8 +233,10 @@ int jl_has_fixed_layout(jl_datatype_t *dt)
return 1;
if (dt->name->abstract)
return 0;
if (jl_is_tuple_type(dt) || jl_is_namedtuple_type(dt))
return 0; // TODO: relax more?
if (dt->name == jl_namedtuple_typename)
return !layout_uses_free_typevars(jl_tparam0(dt), NULL) && !layout_uses_free_typevars(jl_tparam1(dt), NULL);
if (dt->name == jl_tuple_typename)
return 0;
jl_svec_t *types = jl_get_fieldtypes(dt);
size_t i, l = jl_svec_len(types);
for (i = 0; i < l; i++) {
Expand Down
23 changes: 23 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7360,6 +7360,29 @@ struct A43411{S, T}
end
@test isbitstype(A43411{(:a,), Tuple{Int}})

# issue #44614
struct T44614_1{T}
m::T
end
struct T44614_2{L}
tuple::NTuple{3, Int64}
T44614_2{L}(t::NTuple{3, Int64}) where {L} = new{sum(t)}(t)
end
struct T44614_3{L, N}
a::Tuple{T44614_2{L}}
param::NTuple{N, T44614_1}
T44614_3(a::Tuple{T44614_2{L}}, pars::NTuple{N, T44614_1}) where {L, N} = new{L, N}(a, pars)
end
@test sizeof((T44614_2{L} where L).body) == 24
let T = T44614_3{L,2} where L
# these values are computable, but we currently don't know how to compute them properly
ex = ErrorException("Argument is an incomplete T44614_3 type and does not have a definite size.")
@test_throws ex sizeof(T.body)
@test_throws ex sizeof(T)
@test_throws BoundsError fieldoffset(T.body, 2)
@test fieldoffset(T{1}, 2) == 24
end

# Issue #34206/34207
function mre34206(a, n)
va = view(a, :)
Expand Down

0 comments on commit e9ba166

Please sign in to comment.