From 0c78b7861ae4d172f908b27a8e8d9788c87750ac Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Mon, 16 May 2016 15:18:50 -0400 Subject: [PATCH] ensure that instances are only created for types with unique ids fix #16301 doesn't completely fix #12096, but avoids the symptoms --- src/interpreter.c | 2 +- src/jltypes.c | 7 ++++--- src/julia.h | 10 +++++++--- test/core.jl | 9 +++++++++ 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/interpreter.c b/src/interpreter.c index 8950f396937e8..32a087e6033b9 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -384,7 +384,7 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, jl_lambda_info_t *la jl_rethrow(); } jl_compute_field_offsets(dt); - if (para == (jl_value_t*)jl_emptysvec && jl_is_datatype_singleton(dt)) { + if (para == (jl_value_t*)jl_emptysvec && jl_is_datatype_make_singleton(dt)) { dt->instance = newstruct(dt); jl_gc_wb(dt, dt->instance); } diff --git a/src/jltypes.c b/src/jltypes.c index b90caf100af49..6293ebde84f48 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -2183,7 +2183,7 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i jl_precompute_memoized_dt(ndt); // assign uid as early as possible - if (cacheable && !ndt->abstract && ndt->uid==0) + if (cacheable && !ndt->abstract) ndt->uid = jl_assign_type_uid(); if (istuple) @@ -2207,7 +2207,7 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i else { jl_compute_field_offsets(ndt); } - if (jl_is_datatype_singleton(ndt)) { + if (jl_is_datatype_make_singleton(ndt)) { ndt->instance = newstruct(ndt); jl_gc_wb(ndt, ndt->instance); } @@ -3416,7 +3416,8 @@ void jl_init_types(void) jl_tupletype_t *empty_tuple_type = jl_apply_tuple_type(jl_emptysvec); empty_tuple_type->uid = jl_assign_type_uid(); - jl_emptytuple = ((jl_datatype_t*)empty_tuple_type)->instance; + jl_emptytuple = newstruct(empty_tuple_type); + empty_tuple_type->instance = jl_emptytuple; // non-primitive definitions follow jl_int32_type = NULL; diff --git a/src/julia.h b/src/julia.h index 860fd09ca1245..4efb79483a77e 100644 --- a/src/julia.h +++ b/src/julia.h @@ -898,9 +898,13 @@ STATIC_INLINE int jl_isbits(void *t) // corresponding to isbits() in julia STATIC_INLINE int jl_is_datatype_singleton(jl_datatype_t *d) { - return (d->instance != NULL || - (!d->abstract && d->size == 0 && d != jl_sym_type && d->name != jl_array_typename && - (d->name->names == jl_emptysvec || !d->mutabl))); + return (d->instance != NULL); +} + +STATIC_INLINE int jl_is_datatype_make_singleton(jl_datatype_t *d) +{ + return (!d->abstract && d->size == 0 && d != jl_sym_type && d->name != jl_array_typename && + d->uid != 0 && (d->name->names == jl_emptysvec || !d->mutabl)); } STATIC_INLINE int jl_is_abstracttype(void *v) diff --git a/test/core.jl b/test/core.jl index eea3f903d608a..9646ce4d6d661 100644 --- a/test/core.jl +++ b/test/core.jl @@ -4127,3 +4127,12 @@ let a = Any[] @test (push!(a,10); f()) - (push!(a,2); f()) == 8 @test a == [10, 2] end + +# issue #12096 +let a = Val{Val{TypeVar(:_, Int, true)}}, + b = Val{Val{TypeVar(:_, Int)}} + + @test !isdefined(a, :instance) + @test isdefined(b, :instance) + @test isleaftype(b) +end