Skip to content

Commit

Permalink
make GC happy.
Browse files Browse the repository at this point in the history
  • Loading branch information
N5N3 committed Mar 9, 2024
1 parent a3c09f4 commit ffdbce2
Showing 1 changed file with 37 additions and 31 deletions.
68 changes: 37 additions & 31 deletions src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -2818,9 +2818,9 @@ static jl_value_t *omit_bad_union(jl_value_t *u, jl_tvar_t *t)
// Caller might not have rooted `res`
static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbinding_t *vb, jl_unionall_t *u, jl_stenv_t *e)
{
jl_value_t *varval = NULL, *nivar = NULL;
jl_tvar_t *newvar = vb->var;
JL_GC_PUSH3(&res, &newvar, &nivar);
jl_value_t *varval = NULL, *ilb = NULL, *iub = NULL, *nivar = NULL;
jl_tvar_t *newvar = vb->var, *ivar = NULL;
JL_GC_PUSH6(&res, &newvar, &ivar, &nivar, &ilb, &iub);
// try to reduce var to a single value
if (jl_is_long(vb->ub) && jl_is_typevar(vb->lb)) {
varval = vb->ub;
Expand Down Expand Up @@ -2914,71 +2914,74 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind
jl_ivarbinding_t *pwrap = NULL;
for (jl_ivarbinding_t *btemp = allvars, *pbtemp = NULL; btemp != NULL; btemp = btemp->next) {
int bdepth0 = btemp->root->depth0;
if (jl_has_typevar(*btemp->lb, vb->var)) {
assert(btemp->root->var == *btemp->var || bdepth0 == vb->depth0);
if (vb->lb == (jl_value_t*)*btemp->var) {
ivar = *btemp->var;
ilb = *btemp->lb;
iub = *btemp->ub;
if (jl_has_typevar(ilb, vb->var)) {
assert(btemp->root->var == ivar || bdepth0 == vb->depth0);
if (vb->lb == (jl_value_t*)ivar) {
JL_GC_POP();
JL_GC_POP();
return jl_bottom_type;
}
if (varval) {
JL_TRY {
*btemp->lb = jl_substitute_var(*btemp->lb, vb->var, varval);
*btemp->lb = jl_substitute_var(ilb, vb->var, varval);
}
JL_CATCH {
res = jl_bottom_type;
}
}
else if (*btemp->lb == (jl_value_t*)vb->var) {
else if (ilb == (jl_value_t*)vb->var) {
*btemp->lb = vb->lb;
}
else if (bdepth0 == vb->depth0 && !jl_has_typevar(vb->lb, *btemp->var) && !jl_has_typevar(vb->ub, *btemp->var)) {
else if (bdepth0 == vb->depth0 && !jl_has_typevar(vb->lb, ivar) && !jl_has_typevar(vb->ub, ivar)) {
// if our variable is T, and some outer variable has constraint S = Ref{T},
// move the `where T` outside `where S` instead of putting it here. issue #21243.
if (newvar != vb->var)
*btemp->lb = jl_substitute_var(*btemp->lb, vb->var, (jl_value_t*)newvar);
*btemp->lb = jl_substitute_var(ilb, vb->var, (jl_value_t*)newvar);
if (!wrapped) pwrap = pbtemp;
wrapped = 1;
}
else {
*btemp->lb = jl_new_struct(jl_unionall_type, vb->var, *btemp->lb);
*btemp->lb = jl_new_struct(jl_unionall_type, vb->var, ilb);
}
assert((jl_value_t*)*btemp->var != *btemp->lb);
assert((jl_value_t*)ivar != *btemp->lb);
}
if (jl_has_typevar(*btemp->ub, vb->var)) {
assert(btemp->root->var == *btemp->var || bdepth0 == vb->depth0);
if (vb->ub == (jl_value_t*)*btemp->var) {
*btemp->ub = omit_bad_union(*btemp->ub, vb->var);
if (*btemp->ub == jl_bottom_type && btemp->ub != btemp->lb) {
if (jl_has_typevar(iub, vb->var)) {
assert(btemp->root->var == ivar || bdepth0 == vb->depth0);
if (vb->ub == (jl_value_t*)ivar) {
*btemp->ub = omit_bad_union(iub, vb->var);
if (*btemp->ub == jl_bottom_type && *btemp->ub != *btemp->lb) {
JL_GC_POP();
JL_GC_POP();
return jl_bottom_type;
}
}
if (varval) {
JL_TRY {
*btemp->ub = jl_substitute_var(*btemp->ub, vb->var, varval);
*btemp->ub = jl_substitute_var(iub, vb->var, varval);
}
JL_CATCH {
res = jl_bottom_type;
}
}
else if (*btemp->ub == (jl_value_t*)vb->var) {
else if (iub == (jl_value_t*)vb->var) {
// TODO: this loses some constraints, such as in this test, where we replace T4<:S3 (e.g. T4==S3 since T4 only appears covariantly once) with T4<:Any
// a = Tuple{Float64,T3,T4} where T4 where T3
// b = Tuple{S2,Tuple{S3},S3} where S2 where S3
// Tuple{Float64, T3, T4} where {S3, T3<:Tuple{S3}, T4<:S3}
*btemp->ub = vb->ub;
}
else if (bdepth0 == vb->depth0 && !jl_has_typevar(vb->lb, *btemp->var) && !jl_has_typevar(vb->ub, *btemp->var)) {
else if (bdepth0 == vb->depth0 && !jl_has_typevar(vb->lb, ivar) && !jl_has_typevar(vb->ub, ivar)) {
if (newvar != vb->var)
*btemp->ub = jl_substitute_var(*btemp->ub, vb->var, (jl_value_t*)newvar);
*btemp->ub = jl_substitute_var(iub, vb->var, (jl_value_t*)newvar);
if (!wrapped) pwrap = pbtemp;
wrapped = 1;
}
else
*btemp->ub = jl_new_struct(jl_unionall_type, vb->var, *btemp->ub);
assert((jl_value_t*)*btemp->var != *btemp->ub);
*btemp->ub = jl_new_struct(jl_unionall_type, vb->var, iub);
assert((jl_value_t*)ivar != *btemp->ub);
}
pbtemp = btemp;
}
Expand Down Expand Up @@ -3033,18 +3036,21 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind

// Freeze the innervars' lb/ub and perform substitution if needed.
for (jl_ivarbinding_t *btemp1 = allvars; btemp1 != NULL; btemp1 = btemp1->next) {
jl_tvar_t *ivar = *btemp1->var;
ivar = *btemp1->var;
ilb = *btemp1->lb;
iub = *btemp1->ub;
int isinnervar = btemp1->root->var != ivar;
if (isinnervar && ((ivar->lb != *btemp1->lb) ||
(ivar->ub != *btemp1->ub))) {
nivar = (jl_value_t *)jl_new_typevar(ivar->name, *btemp1->lb, *btemp1->ub);
if (isinnervar && (ivar->lb != ilb || ivar->ub != iub)) {
nivar = (jl_value_t *)jl_new_typevar(ivar->name, ilb, iub);
if (jl_has_typevar(res, ivar))
res = jl_substitute_var(res, ivar, nivar);
for (jl_ivarbinding_t *btemp2 = btemp1->next; btemp2 != NULL; btemp2 = btemp2->next) {
if (jl_has_typevar(*btemp2->lb, ivar))
*btemp2->lb = jl_substitute_var(*btemp2->lb, ivar, nivar);
if (jl_has_typevar(*btemp2->ub, ivar))
*btemp2->ub = jl_substitute_var(*btemp2->ub, ivar, nivar);
ilb = *btemp2->lb;
iub = *btemp2->ub;
if (jl_has_typevar(ilb, ivar))
*btemp2->lb = jl_substitute_var(ilb, ivar, nivar);
if (jl_has_typevar(iub, ivar))
*btemp2->ub = jl_substitute_var(iub, ivar, nivar);
}
*btemp1->var = (jl_tvar_t *)nivar;
}
Expand Down

0 comments on commit ffdbce2

Please sign in to comment.