@@ -1512,6 +1512,23 @@ static int may_contain_union_decision(jl_value_t *x, jl_stenv_t *e, jl_typeenv_t
1512
1512
may_contain_union_decision (xb ? xb -> ub : ((jl_tvar_t * )x )-> ub , e , & newlog );
1513
1513
}
1514
1514
1515
+ static int has_exists_typevar (jl_value_t * x , jl_stenv_t * e ) JL_NOTSAFEPOINT
1516
+ {
1517
+ jl_typeenv_t * env = NULL ;
1518
+ jl_varbinding_t * v = e -> vars ;
1519
+ while (v != NULL ) {
1520
+ if (v -> right ) {
1521
+ jl_typeenv_t * newenv = (jl_typeenv_t * )alloca (sizeof (jl_typeenv_t ));
1522
+ newenv -> var = v -> var ;
1523
+ newenv -> val = NULL ;
1524
+ newenv -> prev = env ;
1525
+ env = newenv ;
1526
+ }
1527
+ v = v -> prev ;
1528
+ }
1529
+ return env != NULL && jl_has_bound_typevars (x , env );
1530
+ }
1531
+
1515
1532
static int local_forall_exists_subtype (jl_value_t * x , jl_value_t * y , jl_stenv_t * e , int param , int limit_slow )
1516
1533
{
1517
1534
int16_t oldRmore = e -> Runions .more ;
@@ -1531,13 +1548,19 @@ static int local_forall_exists_subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t
1531
1548
int count = 0 , noRmore = 0 ;
1532
1549
sub = _forall_exists_subtype (x , y , e , param , & count , & noRmore );
1533
1550
pop_unionstate (& e -> Runions , & oldRunions );
1534
- // we should not try the slow path if `forall_exists_subtype` has tested all cases;
1535
- // Once limit_slow == 1, also skip it if
1536
- // 1) `forall_exists_subtype` return false
1551
+ // We could skip the slow path safely if
1552
+ // 1) `_∀_∃_subtype` has tested all cases
1553
+ // 2) `_∀_∃_subtype` returns 1 && `x` and `y` contain no ∃ typevar
1554
+ // Once `limit_slow == 1`, also skip it if
1555
+ // 1) `_∀_∃_subtype` returns 0
1537
1556
// 2) the left `Union` looks big
1557
+ // TODO: `limit_slow` ignores complexity from inner `local_∀_exists_subtype`.
1538
1558
if (limit_slow == -1 )
1539
1559
limit_slow = kindx || kindy ;
1540
- if (noRmore || (limit_slow && (count > 3 || !sub )))
1560
+ int skip = noRmore || (limit_slow && (count > 3 || !sub )) ||
1561
+ (sub && (kindx || !has_exists_typevar (x , e )) &&
1562
+ (kindy || !has_exists_typevar (y , e )));
1563
+ if (skip )
1541
1564
e -> Runions .more = oldRmore ;
1542
1565
}
1543
1566
else {
0 commit comments