@@ -3018,7 +3018,8 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind
30183018 }
30193019
30203020 if (vb -> innervars != NULL ) {
3021- for (size_t i = 0 ; i < jl_array_nrows (vb -> innervars ); i ++ ) {
3021+ size_t len = jl_array_nrows (vb -> innervars ), count = 0 ;
3022+ for (size_t i = 0 ; i < len ; i ++ ) {
30223023 jl_tvar_t * var = (jl_tvar_t * )jl_array_ptr_ref (vb -> innervars , i );
30233024 // the `btemp->prev` walk is only giving a sort of post-order guarantee (since we are
30243025 // iterating 2 trees at once), so once we set `wrap`, there might remain other branches
@@ -3033,10 +3034,43 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind
30333034 if (wrap -> innervars == NULL )
30343035 wrap -> innervars = jl_alloc_array_1d (jl_array_any_type , 0 );
30353036 jl_array_ptr_1d_push (wrap -> innervars , (jl_value_t * )var );
3037+ jl_array_ptr_set (vb -> innervars , i , (jl_value_t * )NULL );
30363038 }
3037- else if (res != jl_bottom_type ) {
3038- if (jl_has_typevar (res , var ))
3039- res = jl_type_unionall ((jl_tvar_t * )var , res );
3039+ }
3040+ for (size_t i = 0 ; i < len ; i ++ ) {
3041+ jl_tvar_t * var = (jl_tvar_t * )jl_array_ptr_ref (vb -> innervars , i );
3042+ if (var ) {
3043+ if (count < i )
3044+ jl_array_ptr_set (vb -> innervars , count , (jl_value_t * )var );
3045+ count ++ ;
3046+ }
3047+ }
3048+ if (count != len )
3049+ jl_array_del_end (vb -> innervars , len - count );
3050+ if (res != jl_bottom_type ) {
3051+ while (count > 1 ) {
3052+ int changed = 0 ;
3053+ // Now need to re-sort the vb->innervars using the partial-ordering predicate `jl_has_typevar`.
3054+ // If this is slow, we could possibly switch to a simpler graph sort than this triple loop, such as Tarjan's SCC.
3055+ // But for now we use a variant on selection sort for partial-orders.
3056+ for (size_t i = 0 ; i < count - 1 ; i ++ ) {
3057+ jl_tvar_t * vari = (jl_tvar_t * )jl_array_ptr_ref (vb -> innervars , i );
3058+ for (size_t j = i + 1 ; j < count ; j ++ ) {
3059+ jl_tvar_t * varj = (jl_tvar_t * )jl_array_ptr_ref (vb -> innervars , j );
3060+ if (jl_has_typevar (varj -> lb , vari ) || jl_has_typevar (varj -> ub , vari )) {
3061+ jl_array_ptr_set (vb -> innervars , j , (jl_value_t * )vari );
3062+ jl_array_ptr_set (vb -> innervars , i , (jl_value_t * )varj );
3063+ changed = 1 ;
3064+ break ;
3065+ }
3066+ }
3067+ if (changed ) break ;
3068+ }
3069+ if (!changed ) break ;
3070+ }
3071+ for (size_t i = 0 ; i < count ; i ++ ) {
3072+ jl_tvar_t * var = (jl_tvar_t * )jl_array_ptr_ref (vb -> innervars , i );
3073+ res = jl_type_unionall (var , res );
30403074 }
30413075 }
30423076 }
0 commit comments