@@ -1660,6 +1660,42 @@ static int local_forall_exists_subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t
16601660 return sub ;
16611661}
16621662
1663+ static int equal_var (jl_tvar_t * v , jl_value_t * x , jl_stenv_t * e )
1664+ {
1665+ assert (e -> Loffset == 0 );
1666+ // Theoretically bounds change would be merged for union inputs.
1667+ // But intersection is not happy as splitting helps to avoid circular env.
1668+ assert (!e -> intersection || !jl_is_uniontype (x ));
1669+ jl_varbinding_t * vb = lookup (e , v );
1670+ if (e -> intersection && vb != NULL && vb -> lb == vb -> ub && jl_is_typevar (vb -> lb ))
1671+ return equal_var ((jl_tvar_t * )vb -> lb , x , e );
1672+ record_var_occurrence (vb , e , 2 );
1673+ if (vb == NULL )
1674+ return e -> ignore_free || (
1675+ local_forall_exists_subtype (x , v -> lb , e , 2 , !jl_has_free_typevars (x )) &&
1676+ local_forall_exists_subtype (v -> ub , x , e , 0 , 0 ));
1677+ if (!vb -> right )
1678+ return local_forall_exists_subtype (x , vb -> lb , e , 2 , !jl_has_free_typevars (x )) &&
1679+ local_forall_exists_subtype (vb -> ub , x , e , 0 , 0 );
1680+ if (vb -> lb == x )
1681+ return var_lt (v , x , e , 0 );
1682+ if (!subtype_ccheck (x , vb -> ub , e ))
1683+ return 0 ;
1684+ jl_value_t * lb = simple_join (vb -> lb , x );
1685+ JL_GC_PUSH1 (& lb );
1686+ if (!e -> intersection || !jl_is_typevar (lb ) || !reachable_var (lb , v , e ))
1687+ vb -> lb = lb ;
1688+ JL_GC_POP ();
1689+ if (vb -> ub == x )
1690+ return 1 ;
1691+ if (!subtype_ccheck (vb -> lb , x , e ))
1692+ return 0 ;
1693+ // skip `simple_meet` here as we have proven `x <: vb->ub`
1694+ if (!e -> intersection || !reachable_var (x , v , e ))
1695+ vb -> ub = x ;
1696+ return 1 ;
1697+ }
1698+
16631699static int forall_exists_equal (jl_value_t * x , jl_value_t * y , jl_stenv_t * e )
16641700{
16651701 if (obviously_egal (x , y )) return 1 ;
@@ -1690,6 +1726,12 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
16901726 }
16911727 }
16921728
1729+ if (e -> Loffset == 0 && jl_is_typevar (y ) && jl_is_type (x ) && (!e -> intersection || !jl_is_uniontype (x ))) {
1730+ // Fastpath for Type == TypeVar.
1731+ // Avoid duplicated `<:` check between adjacent `var_gt` and `var_lt`
1732+ return equal_var ((jl_tvar_t * )y , x , e );
1733+ }
1734+
16931735 jl_saved_unionstate_t oldLunions ; push_unionstate (& oldLunions , & e -> Lunions );
16941736
16951737 int sub = local_forall_exists_subtype (x , y , e , 2 , -1 );
0 commit comments