diff --git a/src/jltypes.c b/src/jltypes.c index 5e84b200af937..86d78da3eeb58 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -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++) { @@ -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++) { diff --git a/test/core.jl b/test/core.jl index 394455681a9db..50332c1d8f6b6 100644 --- a/test/core.jl +++ b/test/core.jl @@ -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, :)