diff --git a/src/interpreter.c b/src/interpreter.c index d006b5496e250..7d3a4504ecc5a 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -102,6 +102,23 @@ static void check_can_assign_type(jl_binding_t *b) jl_symbol_name(b->name)); } +void jl_reinstantiate_inner_types(jl_datatype_t *t); + +void jl_set_datatype_super(jl_datatype_t *tt, jl_value_t *super) +{ + if (!jl_is_datatype(super) || !jl_is_abstracttype(super) || + tt->name == ((jl_datatype_t*)super)->name || + jl_subtype(super,(jl_value_t*)jl_vararg_type,0) || + jl_is_tuple_type(super) || + jl_subtype(super,(jl_value_t*)jl_type_type,0) || + super == (jl_value_t*)jl_builtin_type) { + jl_errorf("invalid subtyping in definition of %s", + jl_symbol_name(tt->name->name)); + } + tt->super = (jl_datatype_t*)super; + jl_gc_wb(tt, tt->super); +} + static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl, size_t ngensym) { if (jl_is_symbol(e)) { @@ -295,6 +312,7 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl, size_t ng jl_gc_wb_binding(b, dt); super = eval(args[2], locals, nl, ngensym); jl_set_datatype_super(dt, super); + jl_reinstantiate_inner_types(dt); b->value = temp; if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) { jl_checked_assignment(b, (jl_value_t*)dt); @@ -326,6 +344,7 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl, size_t ng jl_gc_wb_binding(b, dt); super = eval(args[3], locals, nl, ngensym); jl_set_datatype_super(dt, super); + jl_reinstantiate_inner_types(dt); b->value = temp; if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) { jl_checked_assignment(b, (jl_value_t*)dt); @@ -355,6 +374,8 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl, size_t ng jl_gc_wb_binding(b,dt); JL_TRY { + super = eval(args[3], locals, nl, ngensym); + jl_set_datatype_super(dt, super); // operations that can fail inside_typedef = 1; dt->types = (jl_svec_t*)eval(args[4], locals, nl, ngensym); @@ -367,8 +388,7 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl, size_t ng "type definition", (jl_value_t*)jl_type_type, elt); } - super = eval(args[3], locals, nl, ngensym); - jl_set_datatype_super(dt, super); + jl_reinstantiate_inner_types(dt); } JL_CATCH { b->value = temp; diff --git a/src/jltypes.c b/src/jltypes.c index c2390c960d0cc..af772996729ac 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -2372,6 +2372,9 @@ void jl_reinstantiate_inner_types(jl_datatype_t *t) top.tt = t; top.prev = NULL; size_t n = jl_svec_len(t->parameters); + if (n == 0) return; + t->name->cache = jl_emptysvec; + t->name->linearcache = jl_emptysvec; jl_value_t **env = (jl_value_t**)alloca(n*2*sizeof(void*)); for(int i=0; i < n; i++) { env[i*2] = jl_svecref(t->parameters,i); diff --git a/src/julia_internal.h b/src/julia_internal.h index 6318cf7cfac2d..919654a4dd931 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -210,9 +210,6 @@ jl_value_t *jl_first_argument_datatype(jl_value_t *argtypes); jl_value_t *jl_preresolve_globals(jl_value_t *expr, jl_lambda_info_t *lam); int jl_has_intrinsics(jl_lambda_info_t *li, jl_expr_t *e, jl_module_t *m); -void jl_set_datatype_super(jl_datatype_t *tt, jl_value_t *super); -void jl_add_constructors(jl_datatype_t *t); - jl_value_t *jl_nth_slot_type(jl_tupletype_t *sig, size_t i); void jl_compute_field_offsets(jl_datatype_t *st); jl_array_t *jl_new_array_for_deserialization(jl_value_t *atype, uint32_t ndims, size_t *dims, diff --git a/src/toplevel.c b/src/toplevel.c index 24592a6d17766..5a4d977b5ecf8 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -582,30 +582,6 @@ JL_DLLEXPORT jl_value_t *jl_load_(jl_value_t *str) return jl_load(jl_string_data(str), jl_string_len(str)); } -// type definition ------------------------------------------------------------ - -void jl_reinstantiate_inner_types(jl_datatype_t *t); - -void jl_set_datatype_super(jl_datatype_t *tt, jl_value_t *super) -{ - if (!jl_is_datatype(super) || !jl_is_abstracttype(super) || - tt->name == ((jl_datatype_t*)super)->name || - jl_subtype(super,(jl_value_t*)jl_vararg_type,0) || - jl_is_tuple_type(super) || - jl_subtype(super,(jl_value_t*)jl_type_type,0) || - super == (jl_value_t*)jl_builtin_type) { - jl_errorf("invalid subtyping in definition of %s", - jl_symbol_name(tt->name->name)); - } - tt->super = (jl_datatype_t*)super; - jl_gc_wb(tt, tt->super); - if (jl_svec_len(tt->parameters) > 0) { - tt->name->cache = jl_emptysvec; - tt->name->linearcache = jl_emptysvec; - jl_reinstantiate_inner_types(tt); - } -} - // method definition ---------------------------------------------------------- extern int jl_boot_file_loaded; diff --git a/test/core.jl b/test/core.jl index 283c74cb520b7..51acdb9aeb0f7 100644 --- a/test/core.jl +++ b/test/core.jl @@ -3696,3 +3696,18 @@ let c=1 @test b() == 1 end + +# issue #14825 +abstract abstest_14825 + +type t1_14825{A <: abstest_14825, B} + x::A + y::B +end + +type t2_14825{C, B} <: abstest_14825 + x::C + y::t1_14825{t2_14825{C, B}, B} +end + +@test t2_14825{Int,Int}.types[2] <: t1_14825