From 99bdd00183d77c9ce15877dc524d0029f2087e8a Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 15 Mar 2022 15:18:41 -0400 Subject: [PATCH 1/2] make fieldtype computation stable/pure --- src/datatype.c | 4 ++-- src/jl_exported_funcs.inc | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/datatype.c b/src/datatype.c index a153a42214581..746ce75af0e3f 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -1788,9 +1788,9 @@ JL_DLLEXPORT int jl_field_isdefined(jl_value_t *v, size_t i) JL_NOTSAFEPOINT return fval != NULL ? 1 : 0; } -JL_DLLEXPORT size_t jl_get_field_offset(jl_datatype_t *ty, int field) JL_NOTSAFEPOINT +JL_DLLEXPORT size_t jl_get_field_offset(jl_datatype_t *ty, int field) { - if (ty->layout == NULL || field > jl_datatype_nfields(ty) || field < 1) + if (!jl_struct_try_layout(ty) || field > jl_datatype_nfields(ty) || field < 1) jl_bounds_error_int((jl_value_t*)ty, field); return jl_field_offset(ty, field - 1); } diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index 2aed69f47c30a..016ae11e5530e 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -214,7 +214,6 @@ XX(jl_get_excstack) \ XX(jl_get_fenv_consts) \ XX(jl_get_field) \ - XX(jl_get_field_offset) \ XX(jl_get_global) \ XX(jl_get_image_file) \ XX(jl_get_JIT) \ From e9ba166674e46d4082495993a70095ecea340d84 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 15 Mar 2022 15:59:57 -0400 Subject: [PATCH 2/2] types: fix layout issues for Tuple Fix #44614 --- src/jltypes.c | 12 ++++++++++-- test/core.jl | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) 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, :)