Skip to content

Commit

Permalink
Skip the subtype check in rename_unionall
Browse files Browse the repository at this point in the history
  • Loading branch information
N5N3 committed Apr 5, 2023
1 parent 280f999 commit f1de0a9
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 26 deletions.
44 changes: 31 additions & 13 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1015,15 +1015,15 @@ struct _jl_typestack_t;
typedef struct _jl_typestack_t jl_typestack_t;

static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **iparams, size_t ntp,
jl_typestack_t *stack, jl_typeenv_t *env);
jl_typestack_t *stack, jl_typeenv_t *env, int check);

// Build an environment mapping a TypeName's parameters to parameter values.
// This is the environment needed for instantiating a type's supertype and field types.
static jl_value_t *inst_datatype_env(jl_value_t *dt, jl_svec_t *p, jl_value_t **iparams, size_t ntp,
jl_typestack_t *stack, jl_typeenv_t *env, int c)
{
if (jl_is_datatype(dt))
return inst_datatype_inner((jl_datatype_t*)dt, p, iparams, ntp, stack, env);
return inst_datatype_inner((jl_datatype_t*)dt, p, iparams, ntp, stack, env, 1);
assert(jl_is_unionall(dt));
jl_unionall_t *ua = (jl_unionall_t*)dt;
jl_typeenv_t e = { ua->var, iparams[c], env };
Expand Down Expand Up @@ -1154,6 +1154,18 @@ JL_DLLEXPORT jl_value_t *jl_instantiate_unionall(jl_unionall_t *u, jl_value_t *p
return inst_type_w_(u->body, &env, NULL, 1);
}

jl_unionall_t *jl_rename_unionall(jl_unionall_t *u)
{
jl_tvar_t *v = jl_new_typevar(u->var->name, u->var->lb, u->var->ub);
jl_value_t *t = NULL;
JL_GC_PUSH2(&v, &t);
jl_typeenv_t env = { u->var, (jl_value_t *)v, NULL };
t = inst_type_w_(u->body, &env, NULL, 0);
t = jl_new_struct(jl_unionall_type, v, t);
JL_GC_POP();
return (jl_unionall_t*)t;
}

jl_value_t *jl_substitute_var(jl_value_t *t, jl_tvar_t *var, jl_value_t *val)
{
jl_typeenv_t env = { var, val, NULL };
Expand Down Expand Up @@ -1503,13 +1515,13 @@ jl_value_t *normalize_unionalls(jl_value_t *t)
static jl_value_t *_jl_instantiate_type_in_env(jl_value_t *ty, jl_unionall_t *env, jl_value_t **vals, jl_typeenv_t *prev, jl_typestack_t *stack);

static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **iparams, size_t ntp,
jl_typestack_t *stack, jl_typeenv_t *env)
jl_typestack_t *stack, jl_typeenv_t *env, int check)
{
jl_typestack_t top;
jl_typename_t *tn = dt->name;
int istuple = (tn == jl_tuple_typename);
int isnamedtuple = (tn == jl_namedtuple_typename);
if (tn != jl_type_typename) {
if (check && tn != jl_type_typename) {
size_t i;
for (i = 0; i < ntp; i++)
iparams[i] = normalize_unionalls(iparams[i]);
Expand Down Expand Up @@ -1566,7 +1578,7 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
if (stack_lkup)
return stack_lkup;

if (!istuple) {
if (check && !istuple) {
// check parameters against bounds in type definition
check_datatype_parameters(tn, iparams, ntp);
}
Expand Down Expand Up @@ -1686,7 +1698,7 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
ndt->super = jl_any_type;
}
else if (dt->super) {
ndt->super = (jl_datatype_t*)inst_type_w_((jl_value_t*)dt->super, env, stack, 1);
ndt->super = (jl_datatype_t*)inst_type_w_((jl_value_t*)dt->super, env, stack, check);
jl_gc_wb(ndt, ndt->super);
}
jl_svec_t *ftypes = dt->types;
Expand Down Expand Up @@ -1734,7 +1746,7 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value

static jl_tupletype_t *jl_apply_tuple_type_v_(jl_value_t **p, size_t np, jl_svec_t *params)
{
return (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, p, np, NULL, NULL);
return (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, p, np, NULL, NULL, 1);
}

JL_DLLEXPORT jl_tupletype_t *jl_apply_tuple_type(jl_svec_t *params)
Expand Down Expand Up @@ -1773,7 +1785,7 @@ jl_tupletype_t *jl_inst_arg_tuple_type(jl_value_t *arg1, jl_value_t **args, size
}
jl_svecset(params, i, ai);
}
tt = (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, jl_svec_data(params), nargs, NULL, NULL);
tt = (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, jl_svec_data(params), nargs, NULL, NULL, 1);
JL_GC_POP();
}
return tt;
Expand Down Expand Up @@ -1844,14 +1856,14 @@ static jl_value_t *inst_tuple_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_
int i;
for (i = 0; i < ntp; i++) {
jl_value_t *elt = jl_svecref(tp, i);
jl_value_t *pi = inst_type_w_(elt, env, stack, 0);
jl_value_t *pi = inst_type_w_(elt, env, stack, check);
iparams[i] = pi;
if (ip_heap)
jl_gc_wb(ip_heap, pi);
bound |= (pi != elt);
}
if (bound)
t = inst_datatype_inner(tt, ip_heap, iparams, ntp, stack, env);
t = inst_datatype_inner(tt, ip_heap, iparams, ntp, stack, env, check);
JL_GC_POP();
return t;
}
Expand Down Expand Up @@ -1904,8 +1916,14 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_t
JL_GC_PUSH2(&a, &b);
b = inst_type_w_(u->b, env, stack, check);
if (a != u->a || b != u->b) {
jl_value_t *uargs[2] = {a, b};
t = jl_type_union(uargs, 2);
if (check) {
jl_value_t *uargs[2] = {a, b};
t = jl_type_union(uargs, 2);
}
else {
// fast path for `jl_rename_unionall`.
t = jl_new_struct(jl_uniontype_type, a, b);
}
}
JL_GC_POP();
return t;
Expand Down Expand Up @@ -1947,7 +1965,7 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_t
}
// if t's parameters are not bound in the environment, return it uncopied (#9378)
if (bound)
t = inst_datatype_inner(tt, NULL, iparams, ntp, stack, env);
t = inst_datatype_inner(tt, NULL, iparams, ntp, stack, env, check);
JL_GC_POP();
return t;
}
Expand Down
1 change: 1 addition & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ JL_DLLEXPORT int jl_type_morespecific_no_subtype(jl_value_t *a, jl_value_t *b);
jl_value_t *jl_instantiate_type_with(jl_value_t *t, jl_value_t **env, size_t n);
JL_DLLEXPORT jl_value_t *jl_instantiate_type_in_env(jl_value_t *ty, jl_unionall_t *env, jl_value_t **vals);
jl_value_t *jl_substitute_var(jl_value_t *t, jl_tvar_t *var, jl_value_t *val);
jl_unionall_t *jl_rename_unionall(jl_unionall_t *u);
JL_DLLEXPORT jl_value_t *jl_unwrap_unionall(jl_value_t *v JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT;
JL_DLLEXPORT jl_value_t *jl_rewrap_unionall(jl_value_t *t, jl_value_t *u);
JL_DLLEXPORT jl_value_t *jl_rewrap_unionall_(jl_value_t *t, jl_value_t *u);
Expand Down
15 changes: 2 additions & 13 deletions src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,17 +630,6 @@ static jl_value_t *simple_meet(jl_value_t *a, jl_value_t *b, int overesi)
return overesi ? b : jl_bottom_type;
}

static jl_unionall_t *rename_unionall(jl_unionall_t *u)
{
jl_tvar_t *v = jl_new_typevar(u->var->name, u->var->lb, u->var->ub);
jl_value_t *t = NULL;
JL_GC_PUSH2(&v, &t);
t = jl_instantiate_unionall(u, (jl_value_t*)v);
t = jl_new_struct(jl_unionall_type, v, t);
JL_GC_POP();
return (jl_unionall_t*)t;
}

// main subtyping algorithm

static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param);
Expand Down Expand Up @@ -935,7 +924,7 @@ static jl_unionall_t *unalias_unionall(jl_unionall_t *u, jl_stenv_t *e)
// outer var can only refer to inner var if bounds changed
(btemp->lb != btemp->var->lb && jl_has_typevar(btemp->lb, u->var)) ||
(btemp->ub != btemp->var->ub && jl_has_typevar(btemp->ub, u->var))) {
u = rename_unionall(u);
u = jl_rename_unionall(u);
break;
}
btemp = btemp->prev;
Expand Down Expand Up @@ -2945,7 +2934,7 @@ static jl_value_t *intersect_unionall_(jl_value_t *t, jl_unionall_t *u, jl_stenv
}
if (btemp->var == u->var || btemp->lb == (jl_value_t*)u->var ||
btemp->ub == (jl_value_t*)u->var) {
u = rename_unionall(u);
u = jl_rename_unionall(u);
break;
}
btemp = btemp->prev;
Expand Down

0 comments on commit f1de0a9

Please sign in to comment.