Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b1d890b

Browse files
N5N3kshyatt
authored andcommittedSep 12, 2024
subtype: minor clean up for fast path for lhs union and rhs typevar (#55645)
Follow up #55413. The error pattern mentioned in #55413 (comment) care's `∃y`'s ub in env rather than its original ub. So it seems more robust to check the bounds in env directly. The equivalent typevar propagation is lifted from `subtype_var` for the same reason.
1 parent 9688f59 commit b1d890b

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed
 

‎src/subtype.c

+13-2
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,7 @@ static int subtype_tuple(jl_datatype_t *xd, jl_datatype_t *yd, jl_stenv_t *e, in
13041304
}
13051305

13061306
static int try_subtype_by_bounds(jl_value_t *a, jl_value_t *b, jl_stenv_t *e);
1307+
static int has_exists_typevar(jl_value_t *x, jl_stenv_t *e) JL_NOTSAFEPOINT;
13071308

13081309
// `param` means we are currently looking at a parameter of a type constructor
13091310
// (as opposed to being outside any type constructor, or comparing variable bounds).
@@ -1314,7 +1315,7 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param)
13141315
if (jl_is_uniontype(x)) {
13151316
if (obviously_egal(x, y))
13161317
return 1;
1317-
if (e->Runions.depth == 0 && jl_is_typevar(y) && !jl_has_free_typevars(x) && !jl_has_free_typevars(((jl_tvar_t*)y)->ub)) {
1318+
if (e->Runions.depth == 0 && jl_is_typevar(y) && !jl_has_free_typevars(x)) {
13181319
// Similar to fast path for repeated elements: if there have been no outer
13191320
// unions on the right, and the right side is a typevar, then we can handle the
13201321
// typevar first before picking a union element, under the theory that it may
@@ -1325,7 +1326,17 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param)
13251326
// free typevars, since the typevars presence might lead to those elements
13261327
// getting eliminated (omit_bad_union) or degenerate (Union{Ptr{T}, Ptr}) or
13271328
// combined (Union{T, S} where {T, S <: T}).
1328-
return subtype_var((jl_tvar_t*)y, x, e, 1, param);
1329+
jl_tvar_t *yvar = (jl_tvar_t *)y;
1330+
jl_varbinding_t *yb = lookup(e, yvar);
1331+
while (e->intersection && yb != NULL && yb->lb == yb->ub && jl_is_typevar(yb->lb)) {
1332+
yvar = (jl_tvar_t *)yb->lb;
1333+
yb = lookup(e, yvar);
1334+
}
1335+
// Note: `x <: ∃y` performs a local ∀-∃ check between `x` and `yb->ub`.
1336+
// We need to ensure that there's no ∃ typevar as otherwise that check
1337+
// might cause false alarm due to the accumulated env change.
1338+
if (yb == NULL || yb->right == 0 || !has_exists_typevar(yb->ub, e))
1339+
return subtype_var(yvar, x, e, 1, param);
13291340
}
13301341
x = pick_union_element(x, e, 0);
13311342
}

0 commit comments

Comments
 (0)
Please sign in to comment.