@@ -556,6 +556,43 @@ static void isort_union(jl_value_t **a, size_t len) JL_NOTSAFEPOINT
556556 }
557557}
558558
559+ static int simple_subtype (jl_value_t * a , jl_value_t * b , int hasfree , int isUnion )
560+ {
561+ if (a == jl_bottom_type || b == (jl_value_t * )jl_any_type )
562+ return 1 ;
563+ if (jl_egal (a , b ))
564+ return 1 ;
565+ if (hasfree == 0 ) {
566+ int mergeable = isUnion ;
567+ if (!mergeable ) // issue #24521: don't merge Type{T} where typeof(T) varies
568+ mergeable = !(jl_is_type_type (a ) && jl_is_type_type (b ) &&
569+ jl_typeof (jl_tparam0 (a )) != jl_typeof (jl_tparam0 (b )));
570+ return mergeable && jl_subtype (a , b );
571+ }
572+ if (jl_is_typevar (a )) {
573+ jl_value_t * na = ((jl_tvar_t * )a )-> ub ;
574+ hasfree &= jl_has_free_typevars (na );
575+ return simple_subtype (na , b , hasfree , isUnion );
576+ }
577+ if (jl_is_typevar (b )) {
578+ jl_value_t * nb = ((jl_tvar_t * )b )-> lb ;
579+ // This branch is not valid if `b` obeys diagonal rule,
580+ // as it might normalize `Union` into a single `TypeVar`, e.g.
581+ // Tuple{Union{Int,T},T} where {T>:Int} != Tuple{T,T} where {T>:Int}
582+ if (is_leaf_bound (nb ))
583+ return 0 ;
584+ hasfree &= jl_has_free_typevars (nb ) << 1 ;
585+ return simple_subtype (a , nb , hasfree , isUnion );
586+ }
587+ if (b == (jl_value_t * )jl_datatype_type || b == (jl_value_t * )jl_typeofbottom_type ) {
588+ // This branch is not valid for `Union`/`UnionAll`, e.g.
589+ // (Type{Union{Int,T2} where {T2<:T1}} where {T1}){Int} == Type{Int64}
590+ // (Type{Union{Int,T1}} where {T1}){Int} == Type{Int64}
591+ return jl_is_type_type (a ) && jl_typeof (jl_tparam0 (a )) == b ;
592+ }
593+ return 0 ;
594+ }
595+
559596JL_DLLEXPORT jl_value_t * jl_type_union (jl_value_t * * ts , size_t n )
560597{
561598 if (n == 0 )
@@ -580,13 +617,9 @@ JL_DLLEXPORT jl_value_t *jl_type_union(jl_value_t **ts, size_t n)
580617 int has_free = temp [i ] != NULL && jl_has_free_typevars (temp [i ]);
581618 for (j = 0 ; j < nt ; j ++ ) {
582619 if (j != i && temp [i ] && temp [j ]) {
583- if (temp [i ] == jl_bottom_type ||
584- temp [j ] == (jl_value_t * )jl_any_type ||
585- jl_egal (temp [i ], temp [j ]) ||
586- (!has_free && !jl_has_free_typevars (temp [j ]) &&
587- jl_subtype (temp [i ], temp [j ]))) {
620+ int has_free2 = has_free | (jl_has_free_typevars (temp [j ]) << 1 );
621+ if (simple_subtype (temp [i ], temp [j ], has_free2 , 1 ))
588622 temp [i ] = NULL ;
589- }
590623 }
591624 }
592625 }
@@ -608,17 +641,7 @@ JL_DLLEXPORT jl_value_t *jl_type_union(jl_value_t **ts, size_t n)
608641 return tu ;
609642}
610643
611- // note: this is turned off as `Union` doesn't do such normalization.
612- // static int simple_subtype(jl_value_t *a, jl_value_t *b)
613- // {
614- // if (jl_is_kind(b) && jl_is_type_type(a) && jl_typeof(jl_tparam0(a)) == b)
615- // return 1;
616- // if (jl_is_typevar(b) && obviously_egal(a, ((jl_tvar_t*)b)->lb))
617- // return 1;
618- // return 0;
619- // }
620-
621- static int simple_subtype2 (jl_value_t * a , jl_value_t * b , int hasfree )
644+ static int simple_subtype2 (jl_value_t * a , jl_value_t * b , int hasfree , int isUnion )
622645{
623646 int subab = 0 , subba = 0 ;
624647 if (jl_egal (a , b )) {
@@ -630,9 +653,9 @@ static int simple_subtype2(jl_value_t *a, jl_value_t *b, int hasfree)
630653 else if (b == jl_bottom_type || a == (jl_value_t * )jl_any_type ) {
631654 subba = 1 ;
632655 }
633- else if (hasfree ) {
634- // subab = simple_subtype(a, b);
635- // subba = simple_subtype(b, a);
656+ else if (hasfree != 0 ) {
657+ subab = simple_subtype (a , b , hasfree , isUnion );
658+ subba = simple_subtype (b , a , hasfree , isUnion );
636659 }
637660 else if (jl_is_type_type (a ) && jl_is_type_type (b ) &&
638661 jl_typeof (jl_tparam0 (a )) != jl_typeof (jl_tparam0 (b ))) {
@@ -664,10 +687,11 @@ jl_value_t *simple_union(jl_value_t *a, jl_value_t *b)
664687 // first remove cross-redundancy and check if `a >: b` or `a <: b`.
665688 for (i = 0 ; i < nta ; i ++ ) {
666689 if (temp [i ] == NULL ) continue ;
667- int hasfree = jl_has_free_typevars (temp [i ]);
690+ int has_free = jl_has_free_typevars (temp [i ]);
668691 for (j = nta ; j < nt ; j ++ ) {
669692 if (temp [j ] == NULL ) continue ;
670- int subs = simple_subtype2 (temp [i ], temp [j ], hasfree || jl_has_free_typevars (temp [j ]));
693+ int has_free2 = has_free | (jl_has_free_typevars (temp [j ]) << 1 );
694+ int subs = simple_subtype2 (temp [i ], temp [j ], has_free2 , 0 );
671695 int subab = subs & 1 , subba = subs >> 1 ;
672696 if (subab ) {
673697 temp [i ] = NULL ;
@@ -697,15 +721,9 @@ jl_value_t *simple_union(jl_value_t *a, jl_value_t *b)
697721 size_t jmax = i < nta ? nta : nt ;
698722 for (j = jmin ; j < jmax ; j ++ ) {
699723 if (j != i && temp [i ] && temp [j ]) {
700- if (temp [i ] == jl_bottom_type ||
701- temp [j ] == (jl_value_t * )jl_any_type ||
702- jl_egal (temp [i ], temp [j ]) ||
703- (!has_free && !jl_has_free_typevars (temp [j ]) &&
704- // issue #24521: don't merge Type{T} where typeof(T) varies
705- !(jl_is_type_type (temp [i ]) && jl_is_type_type (temp [j ]) && jl_typeof (jl_tparam0 (temp [i ])) != jl_typeof (jl_tparam0 (temp [j ]))) &&
706- jl_subtype (temp [i ], temp [j ]))) {
724+ int has_free2 = has_free | (jl_has_free_typevars (temp [j ]) << 1 );
725+ if (simple_subtype (temp [i ], temp [j ], has_free2 , 0 ))
707726 temp [i ] = NULL ;
708- }
709727 }
710728 }
711729 }
@@ -769,7 +787,7 @@ jl_value_t *simple_intersect(jl_value_t *a, jl_value_t *b, int overesi)
769787 int hasfree = jl_has_free_typevars (temp [i ]);
770788 for (j = nta ; j < nt ; j ++ ) {
771789 if (temp [j ] == NULL ) continue ;
772- int subs = simple_subtype2 (temp [i ], temp [j ], hasfree || jl_has_free_typevars (temp [j ]));
790+ int subs = simple_subtype2 (temp [i ], temp [j ], hasfree || jl_has_free_typevars (temp [j ]), 0 );
773791 int subab = subs & 1 , subba = subs >> 1 ;
774792 if (subba && !subab ) {
775793 stemp [i ] = -1 ;
0 commit comments