@@ -1304,6 +1304,7 @@ static int subtype_tuple(jl_datatype_t *xd, jl_datatype_t *yd, jl_stenv_t *e, in
1304
1304
}
1305
1305
1306
1306
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 ;
1307
1308
1308
1309
// `param` means we are currently looking at a parameter of a type constructor
1309
1310
// (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)
1314
1315
if (jl_is_uniontype (x )) {
1315
1316
if (obviously_egal (x , y ))
1316
1317
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 )) {
1318
1319
// Similar to fast path for repeated elements: if there have been no outer
1319
1320
// unions on the right, and the right side is a typevar, then we can handle the
1320
1321
// 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)
1325
1326
// free typevars, since the typevars presence might lead to those elements
1326
1327
// getting eliminated (omit_bad_union) or degenerate (Union{Ptr{T}, Ptr}) or
1327
1328
// 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 );
1329
1340
}
1330
1341
x = pick_union_element (x , e , 0 );
1331
1342
}
0 commit comments