Skip to content

Commit d540832

Browse files
authored
Merge pull request #17618 from JuliaLang/jn/redef-type
allow redefinition of egal parametric types
2 parents b43773f + ca09e98 commit d540832

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

src/interpreter.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,20 +94,35 @@ extern int jl_boot_file_loaded;
9494
extern int inside_typedef;
9595

9696
// this is a heuristic for allowing "redefining" a type to something identical
97+
static int equiv_svec_dt(jl_svec_t *sa, jl_svec_t *sb)
98+
{
99+
size_t i, l = jl_svec_len(sa);
100+
if (l != jl_svec_len(sb)) return 0;
101+
for (i = 0; i < l; i++) {
102+
jl_value_t *a = jl_svecref(sa, i);
103+
jl_value_t *b = jl_svecref(sb, i);
104+
if (jl_typeof(a) != jl_typeof(b))
105+
return 0;
106+
if (jl_is_typevar(a) && ((jl_tvar_t*)a)->name != ((jl_tvar_t*)b)->name)
107+
return 0;
108+
if (!jl_subtype(a, b, 0) || !jl_subtype(b, a, 0))
109+
return 0;
110+
}
111+
return 1;
112+
}
97113
static int equiv_type(jl_datatype_t *dta, jl_datatype_t *dtb)
98114
{
99115
return (jl_typeof(dta) == jl_typeof(dtb) &&
100-
// TODO: can't yet handle parametric types due to how constructors work
101-
dta->parameters == jl_emptysvec &&
102116
dta->name->name == dtb->name->name &&
103-
jl_egal((jl_value_t*)dta->types, (jl_value_t*)dtb->types) &&
104117
dta->abstract == dtb->abstract &&
105118
dta->mutabl == dtb->mutabl &&
106119
dta->size == dtb->size &&
107120
dta->ninitialized == dtb->ninitialized &&
108-
jl_egal((jl_value_t*)dta->super, (jl_value_t*)dtb->super) &&
109-
jl_egal((jl_value_t*)dta->name->names, (jl_value_t*)dtb->name->names) &&
110-
jl_egal((jl_value_t*)dta->parameters, (jl_value_t*)dtb->parameters));
121+
equiv_svec_dt(dta->parameters, dtb->parameters) &&
122+
equiv_svec_dt(dta->types, dtb->types) &&
123+
jl_subtype((jl_value_t*)dta->super, (jl_value_t*)dtb->super, 0) &&
124+
jl_subtype((jl_value_t*)dtb->super, (jl_value_t*)dta->super, 0) &&
125+
jl_egal((jl_value_t*)dta->name->names, (jl_value_t*)dtb->name->names));
111126
}
112127

113128
static void check_can_assign_type(jl_binding_t *b)
@@ -297,7 +312,7 @@ static jl_value_t *eval(jl_value_t *e, interpreter_state *s)
297312
jl_rethrow();
298313
}
299314
b->value = temp;
300-
if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) {
315+
if (temp == NULL || !equiv_type(dt, (jl_datatype_t*)temp)) {
301316
jl_checked_assignment(b, (jl_value_t*)dt);
302317
}
303318
JL_GC_POP();
@@ -339,7 +354,7 @@ static jl_value_t *eval(jl_value_t *e, interpreter_state *s)
339354
jl_rethrow();
340355
}
341356
b->value = temp;
342-
if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) {
357+
if (temp == NULL || !equiv_type(dt, (jl_datatype_t*)temp)) {
343358
jl_checked_assignment(b, (jl_value_t*)dt);
344359
}
345360
JL_GC_POP();
@@ -405,12 +420,9 @@ static jl_value_t *eval(jl_value_t *e, interpreter_state *s)
405420
}
406421

407422
b->value = temp;
408-
if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) {
423+
if (temp == NULL || !equiv_type(dt, (jl_datatype_t*)temp)) {
409424
jl_checked_assignment(b, (jl_value_t*)dt);
410425
}
411-
else {
412-
// TODO: remove all old ctors and set temp->name->ctor_factory = dt->name->ctor_factory
413-
}
414426

415427
JL_GC_POP();
416428
return (jl_value_t*)jl_nothing;

0 commit comments

Comments
 (0)