Skip to content

Commit 292f1a9

Browse files
authored
types: fix cache computation (#41935)
Need to compute `cacheable` after normalization, since the purpose of the normalization was to turn these into normal cacheable objects, when applicable. Brokenness exposed by #36211 Fixes #41503
1 parent c88db4e commit 292f1a9

File tree

2 files changed

+37
-38
lines changed

2 files changed

+37
-38
lines changed

src/jltypes.c

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -897,19 +897,19 @@ struct _jl_typestack_t;
897897
typedef struct _jl_typestack_t jl_typestack_t;
898898

899899
static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **iparams, size_t ntp,
900-
int cacheable, jl_typestack_t *stack, jl_typeenv_t *env);
900+
jl_typestack_t *stack, jl_typeenv_t *env);
901901

902902
// Build an environment mapping a TypeName's parameters to parameter values.
903903
// This is the environment needed for instantiating a type's supertype and field types.
904904
static jl_value_t *inst_datatype_env(jl_value_t *dt, jl_svec_t *p, jl_value_t **iparams, size_t ntp,
905-
int cacheable, jl_typestack_t *stack, jl_typeenv_t *env, int c)
905+
jl_typestack_t *stack, jl_typeenv_t *env, int c)
906906
{
907907
if (jl_is_datatype(dt))
908-
return inst_datatype_inner((jl_datatype_t*)dt, p, iparams, ntp, cacheable, stack, env);
908+
return inst_datatype_inner((jl_datatype_t*)dt, p, iparams, ntp, stack, env);
909909
assert(jl_is_unionall(dt));
910910
jl_unionall_t *ua = (jl_unionall_t*)dt;
911911
jl_typeenv_t e = { ua->var, iparams[c], env };
912-
return inst_datatype_env(ua->body, p, iparams, ntp, cacheable, stack, &e, c + 1);
912+
return inst_datatype_env(ua->body, p, iparams, ntp, stack, &e, c + 1);
913913
}
914914

915915
jl_value_t *jl_apply_type(jl_value_t *tc, jl_value_t **params, size_t n)
@@ -925,14 +925,7 @@ jl_value_t *jl_apply_type(jl_value_t *tc, jl_value_t **params, size_t n)
925925
jl_value_t *u = jl_unwrap_unionall(tc);
926926
if (jl_is_datatype(u) && n == jl_nparams((jl_datatype_t*)u) &&
927927
((jl_datatype_t*)u)->name->wrapper == tc) {
928-
int cacheable = 1;
929-
for (i = 0; i < n; i++) {
930-
if (jl_has_free_typevars(params[i])) {
931-
cacheable = 0;
932-
break;
933-
}
934-
}
935-
return inst_datatype_env(tc, NULL, params, n, cacheable, NULL, NULL, 0);
928+
return inst_datatype_env(tc, NULL, params, n, NULL, NULL, 0);
936929
}
937930
}
938931
JL_GC_PUSH1(&tc);
@@ -1002,8 +995,8 @@ jl_datatype_t *jl_apply_cmpswap_type(jl_value_t *dt)
1002995
jl_value_t *params[2];
1003996
jl_value_t *names = jl_atomic_load_relaxed(&cmpswap_names);
1004997
if (names == NULL) {
1005-
params[0] = jl_symbol("old");
1006-
params[1] = jl_symbol("success");
998+
params[0] = (jl_value_t*)jl_symbol("old");
999+
params[1] = (jl_value_t*)jl_symbol("success");
10071000
jl_value_t *lnames = jl_f_tuple(NULL, params, 2);
10081001
if (jl_atomic_cmpswap(&cmpswap_names, &names, lnames))
10091002
names = jl_atomic_load_relaxed(&cmpswap_names); // == lnames
@@ -1012,7 +1005,7 @@ jl_datatype_t *jl_apply_cmpswap_type(jl_value_t *dt)
10121005
params[1] = (jl_value_t*)jl_bool_type;
10131006
jl_datatype_t *tuptyp = jl_apply_tuple_type_v(params, 2);
10141007
JL_GC_PROMISE_ROOTED(tuptyp); // (JL_ALWAYS_LEAFTYPE)
1015-
jl_datatype_t *rettyp = (jl_datatype_t*)jl_apply_type2(jl_namedtuple_type, names, tuptyp);
1008+
jl_datatype_t *rettyp = (jl_datatype_t*)jl_apply_type2((jl_value_t*)jl_namedtuple_type, names, (jl_value_t*)tuptyp);
10161009
JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE)
10171010
return rettyp;
10181011
}
@@ -1343,18 +1336,32 @@ jl_value_t *normalize_unionalls(jl_value_t *t)
13431336
static jl_value_t *_jl_instantiate_type_in_env(jl_value_t *ty, jl_unionall_t *env, jl_value_t **vals, jl_typeenv_t *prev, jl_typestack_t *stack);
13441337

13451338
static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **iparams, size_t ntp,
1346-
int cacheable, jl_typestack_t *stack, jl_typeenv_t *env)
1339+
jl_typestack_t *stack, jl_typeenv_t *env)
13471340
{
13481341
jl_typestack_t top;
13491342
jl_typename_t *tn = dt->name;
13501343
int istuple = (tn == jl_tuple_typename);
13511344
int isnamedtuple = (tn == jl_namedtuple_typename);
13521345
if (dt->name != jl_type_typename) {
1353-
for (size_t i = 0; i < ntp; i++)
1346+
size_t i;
1347+
for (i = 0; i < ntp; i++)
13541348
iparams[i] = normalize_unionalls(iparams[i]);
13551349
}
13561350

1357-
// check type cache
1351+
// check type cache, if applicable
1352+
int cacheable = 1;
1353+
if (istuple) {
1354+
size_t i;
1355+
for (i = 0; cacheable && i < ntp; i++)
1356+
if (!jl_is_concrete_type(iparams[i]) && iparams[i] != jl_bottom_type)
1357+
cacheable = 0;
1358+
}
1359+
else {
1360+
size_t i;
1361+
for (i = 0; cacheable && i < ntp; i++)
1362+
if (jl_has_free_typevars(iparams[i]))
1363+
cacheable = 0;
1364+
}
13581365
if (cacheable) {
13591366
size_t i;
13601367
for (i = 0; i < ntp; i++) {
@@ -1553,13 +1560,7 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
15531560

15541561
static jl_tupletype_t *jl_apply_tuple_type_v_(jl_value_t **p, size_t np, jl_svec_t *params)
15551562
{
1556-
int cacheable = 1;
1557-
for (size_t i = 0; i < np; i++) {
1558-
assert(p[i]);
1559-
if (!jl_is_concrete_type(p[i]) && p[i] != jl_bottom_type)
1560-
cacheable = 0;
1561-
}
1562-
return (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, p, np, cacheable, NULL, NULL);
1563+
return (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, p, np, NULL, NULL);
15631564
}
15641565

15651566
JL_DLLEXPORT jl_tupletype_t *jl_apply_tuple_type(jl_svec_t *params)
@@ -1581,7 +1582,6 @@ jl_tupletype_t *jl_inst_arg_tuple_type(jl_value_t *arg1, jl_value_t **args, size
15811582
{
15821583
jl_tupletype_t *tt = (jl_datatype_t*)lookup_typevalue(jl_tuple_typename, arg1, args, nargs, leaf);
15831584
if (tt == NULL) {
1584-
int cacheable = 1;
15851585
size_t i;
15861586
jl_svec_t *params = jl_alloc_svec(nargs);
15871587
JL_GC_PUSH1(&params);
@@ -1593,14 +1593,13 @@ jl_tupletype_t *jl_inst_arg_tuple_type(jl_value_t *arg1, jl_value_t **args, size
15931593
// `jl_typeof(ai)`, but that will require some redesign of the caching
15941594
// logic.
15951595
ai = (jl_value_t*)jl_wrap_Type(ai);
1596-
cacheable = 0;
15971596
}
15981597
else {
15991598
ai = jl_typeof(ai);
16001599
}
16011600
jl_svecset(params, i, ai);
16021601
}
1603-
tt = (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, jl_svec_data(params), nargs, cacheable, NULL, NULL);
1602+
tt = (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, jl_svec_data(params), nargs, NULL, NULL);
16041603
JL_GC_POP();
16051604
}
16061605
return tt;
@@ -1668,9 +1667,6 @@ static jl_value_t *inst_tuple_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_
16681667
iparams = jl_svec_data(ip_heap);
16691668
}
16701669
int bound = 0;
1671-
int cacheable = 1;
1672-
if (jl_is_va_tuple(tt))
1673-
cacheable = 0;
16741670
int i;
16751671
for (i = 0; i < ntp; i++) {
16761672
jl_value_t *elt = jl_svecref(tp, i);
@@ -1679,11 +1675,9 @@ static jl_value_t *inst_tuple_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_
16791675
if (ip_heap)
16801676
jl_gc_wb(ip_heap, pi);
16811677
bound |= (pi != elt);
1682-
if (cacheable && !jl_is_concrete_type(pi))
1683-
cacheable = 0;
16841678
}
16851679
if (bound)
1686-
t = inst_datatype_inner(tt, ip_heap, iparams, ntp, cacheable, stack, env);
1680+
t = inst_datatype_inner(tt, ip_heap, iparams, ntp, stack, env);
16871681
JL_GC_POP();
16881682
return t;
16891683
}
@@ -1770,18 +1764,16 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_t
17701764
size_t ntp = jl_svec_len(tp);
17711765
jl_value_t **iparams;
17721766
JL_GC_PUSHARGS(iparams, ntp);
1773-
int cacheable = 1, bound = 0;
1767+
int bound = 0;
17741768
for (i = 0; i < ntp; i++) {
17751769
jl_value_t *elt = jl_svecref(tp, i);
17761770
jl_value_t *pi = inst_type_w_(elt, env, stack, check);
17771771
iparams[i] = pi;
17781772
bound |= (pi != elt);
1779-
if (cacheable && jl_has_free_typevars(pi))
1780-
cacheable = 0;
17811773
}
17821774
// if t's parameters are not bound in the environment, return it uncopied (#9378)
17831775
if (bound)
1784-
t = inst_datatype_inner(tt, NULL, iparams, ntp, cacheable, stack, env);
1776+
t = inst_datatype_inner(tt, NULL, iparams, ntp, stack, env);
17851777
JL_GC_POP();
17861778
return t;
17871779
}

test/core.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7579,3 +7579,10 @@ const T35130 = Tuple{Vector{Int}, <:Any}
75797579
end
75807580
h35130(x) = A35130(Any[x][1]::Vector{T35130})
75817581
@test h35130(T35130[([1],1)]) isa A35130
7582+
7583+
# issue #41503
7584+
let S = Tuple{Tuple{Tuple{K, UInt128} where K<:Tuple{Int64}, Int64}},
7585+
T = Tuple{Tuple{Tuple{Tuple{Int64}, UInt128}, Int64}}
7586+
@test pointer_from_objref(T) === pointer_from_objref(S)
7587+
@test isbitstype(T)
7588+
end

0 commit comments

Comments
 (0)