Skip to content

Commit

Permalink
fix #14825
Browse files Browse the repository at this point in the history
a new type's supertype was not taken into account while instantiating
the types of its fields
  • Loading branch information
JeffBezanson committed Jan 29, 2016
1 parent 0e09b2a commit 0dd74d5
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 29 deletions.
24 changes: 22 additions & 2 deletions src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 0 additions & 3 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
24 changes: 0 additions & 24 deletions src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
15 changes: 15 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 0dd74d5

Please sign in to comment.