@@ -1572,6 +1572,42 @@ static int local_forall_exists_subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t
15721572 return sub ;
15731573}
15741574
1575+ static int equal_var (jl_tvar_t * v , jl_value_t * x , jl_stenv_t * e )
1576+ {
1577+ assert (e -> Loffset == 0 );
1578+ // Theoretically bounds change would be merged for union inputs.
1579+ // But intersection is not happy as splitting helps to avoid circular env.
1580+ assert (!e -> intersection || !jl_is_uniontype (x ));
1581+ jl_varbinding_t * vb = lookup (e , v );
1582+ if (e -> intersection && vb != NULL && vb -> lb == vb -> ub && jl_is_typevar (vb -> lb ))
1583+ return equal_var ((jl_tvar_t * )vb -> lb , x , e );
1584+ record_var_occurrence (vb , e , 2 );
1585+ if (vb == NULL )
1586+ return e -> ignore_free || (
1587+ local_forall_exists_subtype (x , v -> lb , e , 2 , !jl_has_free_typevars (x )) &&
1588+ local_forall_exists_subtype (v -> ub , x , e , 0 , 0 ));
1589+ if (!vb -> right )
1590+ return local_forall_exists_subtype (x , vb -> lb , e , 2 , !jl_has_free_typevars (x )) &&
1591+ local_forall_exists_subtype (vb -> ub , x , e , 0 , 0 );
1592+ if (vb -> lb == x )
1593+ return var_lt (v , x , e , 0 );
1594+ if (!subtype_ccheck (x , vb -> ub , e ))
1595+ return 0 ;
1596+ jl_value_t * lb = simple_join (vb -> lb , x );
1597+ JL_GC_PUSH1 (& lb );
1598+ if (!e -> intersection || !jl_is_typevar (lb ) || !reachable_var (lb , v , e ))
1599+ vb -> lb = lb ;
1600+ JL_GC_POP ();
1601+ if (vb -> ub == x )
1602+ return 1 ;
1603+ if (!subtype_ccheck (vb -> lb , x , e ))
1604+ return 0 ;
1605+ // skip `simple_meet` here as we have proven `x <: vb->ub`
1606+ if (!e -> intersection || !reachable_var (x , v , e ))
1607+ vb -> ub = x ;
1608+ return 1 ;
1609+ }
1610+
15751611static int forall_exists_equal (jl_value_t * x , jl_value_t * y , jl_stenv_t * e )
15761612{
15771613 if (obviously_egal (x , y )) return 1 ;
@@ -1602,6 +1638,12 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
16021638 }
16031639 }
16041640
1641+ if (e -> Loffset == 0 && jl_is_typevar (y ) && jl_is_type (x ) && (!e -> intersection || !jl_is_uniontype (x ))) {
1642+ // Fastpath for Type == TypeVar.
1643+ // Avoid duplicated `<:` check between adjacent `var_gt` and `var_lt`
1644+ return equal_var ((jl_tvar_t * )y , x , e );
1645+ }
1646+
16051647 jl_saved_unionstate_t oldLunions ; push_unionstate (& oldLunions , & e -> Lunions );
16061648
16071649 int sub = local_forall_exists_subtype (x , y , e , 2 , -1 );
0 commit comments