Skip to content

Commit

Permalink
Avoid repeated failing equal_union.
Browse files Browse the repository at this point in the history
We'd better skip checked `equal_union` by set `state[i] = 1`
  • Loading branch information
N5N3 committed Feb 1, 2023
1 parent 43439f1 commit bead5c3
Showing 1 changed file with 7 additions and 23 deletions.
30 changes: 7 additions & 23 deletions src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -1258,19 +1258,6 @@ static int subtype_tuple(jl_datatype_t *xd, jl_datatype_t *yd, jl_stenv_t *e, in
return ans;
}

static int equal_unions(jl_uniontype_t *x, jl_uniontype_t *y, jl_stenv_t *e)
{
jl_value_t *saved=NULL; jl_savedenv_t se;
JL_GC_PUSH1(&saved);
save_env(e, &saved, &se);
int eq = forall_exists_equal(x->a, y->a, e) && forall_exists_equal(x->b, y->b, e);
if (!eq)
restore_env(e, saved, &se);
free_env(&se);
JL_GC_POP();
return eq;
}

// `param` means we are currently looking at a parameter of a type constructor
// (as opposed to being outside any type constructor, or comparing variable bounds).
// this is used to record the positions where type variables occur for the
Expand Down Expand Up @@ -1452,18 +1439,15 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
(is_definite_length_tuple_type(x) && is_indefinite_length_tuple_type(y)))
return 0;

if (jl_is_uniontype(x) && jl_is_uniontype(y)) {
// For 2 unions, try a more efficient greedy algorithm that compares the unions
// componentwise. If it returns `false`, we forget it and proceed with the usual
// algorithm. If it returns `true` we try returning `true`, but need to come back
// here to try the usual algorithm if subtyping later fails.
jl_unionstate_t *state = &e->Runions;
jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, state);
if ((jl_is_uniontype(x) && jl_is_uniontype(y))) {
// For 2 unions, first try a more efficient greedy algorithm that compares the unions
// componentwise. If failed, `exists_subtype` would memorize that this branch should be skipped.

if (pick_union_decision(e, 1) == 0) {
if (equal_unions((jl_uniontype_t*)x, (jl_uniontype_t*)y, e))
return 1;
pop_unionstate(state, &oldRunions);
return forall_exists_equal(((jl_uniontype_t *)x)->a, ((jl_uniontype_t *)y)->a, e) &&
forall_exists_equal(((jl_uniontype_t *)x)->b, ((jl_uniontype_t *)y)->b, e);
}

}

jl_saved_unionstate_t oldLunions; push_unionstate(&oldLunions, &e->Lunions);
Expand Down

0 comments on commit bead5c3

Please sign in to comment.