Skip to content

Commit 0af1e8b

Browse files
JeffBezansonfcard
authored andcommitted
fix order of type cache insertion and UID assignment
reinstates and hopefully fixes the problem in JuliaLang#11606
1 parent d38f3f3 commit 0af1e8b

File tree

2 files changed

+35
-19
lines changed

2 files changed

+35
-19
lines changed

src/jltypes.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1905,7 +1905,7 @@ static int is_cacheable(jl_datatype_t *type)
19051905
static void cache_insert_type(jl_value_t *type, ssize_t insert_at, int ordered)
19061906
{
19071907
assert(jl_is_datatype(type));
1908-
// assign uid
1908+
// assign uid if it hasn't been done already
19091909
if (!jl_is_abstracttype(type) && ((jl_datatype_t*)type)->uid==0)
19101910
((jl_datatype_t*)type)->uid = jl_assign_type_uid();
19111911
jl_svec_t *cache;
@@ -1962,6 +1962,24 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_value_t **env, size_t n,
19621962
static jl_svec_t *inst_all(jl_svec_t *p, jl_value_t **env, size_t n,
19631963
jl_typestack_t *stack, int check);
19641964

1965+
static jl_value_t *lookup_type_stack(jl_typestack_t *stack, jl_datatype_t *tt, size_t ntp,
1966+
jl_value_t **iparams)
1967+
{
1968+
// if an identical instantiation is already in process somewhere up the
1969+
// stack, return it. this computes a fixed point for recursive types.
1970+
jl_typename_t *tn = tt->name;
1971+
while (stack != NULL) {
1972+
if (stack->tt->name == tn &&
1973+
ntp == jl_svec_len(stack->tt->parameters) &&
1974+
typekey_eq(stack->tt, iparams, ntp)) {
1975+
jl_value_t *lkup = (jl_value_t*)stack->tt;
1976+
return lkup == tn->primary ? NULL : lkup;
1977+
}
1978+
stack = stack->prev;
1979+
}
1980+
return NULL;
1981+
}
1982+
19651983
static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **iparams, size_t ntp,
19661984
int cacheable, int isabstract, jl_typestack_t *stack,
19671985
jl_value_t **env, size_t n)
@@ -1976,6 +1994,9 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
19761994
if (lkup != NULL)
19771995
return lkup;
19781996
}
1997+
jl_value_t *stack_lkup = lookup_type_stack(stack, dt, ntp, iparams);
1998+
if (stack_lkup)
1999+
return stack_lkup;
19792000

19802001
// always use original type constructor
19812002
if (!istuple) {
@@ -2019,7 +2040,9 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
20192040
ndt->size = 0;
20202041
ndt->alignment = 1;
20212042

2022-
if (cacheable) jl_cache_type_(ndt);
2043+
// assign uid as early as possible
2044+
if (cacheable && !ndt->abstract && ndt->uid==0)
2045+
ndt->uid = jl_assign_type_uid();
20232046

20242047
if (istuple)
20252048
ndt->super = jl_any_type;
@@ -2058,6 +2081,9 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
20582081
ndt->ninitialized = ntp;
20592082
else
20602083
ndt->ninitialized = dt->ninitialized;
2084+
2085+
if (cacheable) jl_cache_type_(ndt);
2086+
20612087
JL_GC_POP();
20622088
return (jl_value_t*)ndt;
20632089
}
@@ -2224,23 +2250,6 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_value_t **env, size_t n,
22242250
// if t's parameters are not bound in the environment, return it uncopied (#9378)
22252251
if (!bound && t == tc) { JL_GC_POP(); return (jl_value_t*)t; }
22262252

2227-
// if an identical instantiation is already in process somewhere
2228-
// up the stack, return it. this computes a fixed point for
2229-
// recursive types.
2230-
jl_typestack_t *tmp = stack;
2231-
jl_value_t *lkup = NULL;
2232-
while (tmp != NULL) {
2233-
if (tmp->tt->name==tn && ntp==jl_svec_len(tmp->tt->parameters) &&
2234-
typekey_eq(tmp->tt, iparams, ntp)) {
2235-
lkup = (jl_value_t*)tmp->tt;
2236-
break;
2237-
}
2238-
tmp = tmp->prev;
2239-
}
2240-
if (lkup != NULL && lkup != (jl_value_t*)tc) {
2241-
JL_GC_POP();
2242-
return lkup;
2243-
}
22442253
jl_value_t *result = inst_datatype((jl_datatype_t*)tt, NULL, iparams, ntp, cacheable, isabstract,
22452254
stack, env, n);
22462255
JL_GC_POP();

test/core.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2965,3 +2965,10 @@ using M7864
29652965
# issue #11715
29662966
f11715(x) = (x === Tuple{Any})
29672967
@test f11715(Tuple{Any})
2968+
2969+
# part of #11597
2970+
# make sure invalid, partly-constructed types don't end up in the cache
2971+
abstract C11597{T<:Union(Void, Int)}
2972+
type D11597{T} <: C11597{T} d::T end
2973+
@test_throws TypeError D11597(1.0)
2974+
@test_throws TypeError repr(D11597(1.0))

0 commit comments

Comments
 (0)