@@ -2210,13 +2210,29 @@ static int subtype_in_env_existential(jl_value_t *x, jl_value_t *y, jl_stenv_t *
2210
2210
return issub ;
2211
2211
}
2212
2212
2213
+ // See if var y is reachable from x via bounds; used to avoid cycles.
2214
+ static int reachable_var (jl_value_t * x , jl_tvar_t * y , jl_stenv_t * e )
2215
+ {
2216
+ if (in_union (x , (jl_value_t * )y ))
2217
+ return 1 ;
2218
+ if (!jl_is_typevar (x ))
2219
+ return 0 ;
2220
+ jl_varbinding_t * xv = lookup (e , (jl_tvar_t * )x );
2221
+ if (xv == NULL )
2222
+ return 0 ;
2223
+ return reachable_var (xv -> ub , y , e ) || reachable_var (xv -> lb , y , e );
2224
+ }
2225
+
2213
2226
static jl_value_t * intersect_var (jl_tvar_t * b , jl_value_t * a , jl_stenv_t * e , int8_t R , int param )
2214
2227
{
2215
2228
jl_varbinding_t * bb = lookup (e , b );
2216
2229
if (bb == NULL )
2217
2230
return R ? intersect_aside (a , b -> ub , e , 1 , 0 ) : intersect_aside (b -> ub , a , e , 0 , 0 );
2218
- if (bb -> lb == bb -> ub && jl_is_typevar (bb -> lb ) && bb -> lb != (jl_value_t * )b )
2231
+ if (reachable_var (bb -> lb , b , e ) || reachable_var (bb -> ub , b , e ))
2232
+ return a ;
2233
+ if (bb -> lb == bb -> ub && jl_is_typevar (bb -> lb )) {
2219
2234
return intersect (a , bb -> lb , e , param );
2235
+ }
2220
2236
if (!jl_is_type (a ) && !jl_is_typevar (a ))
2221
2237
return set_var_to_const (bb , a , NULL );
2222
2238
int d = bb -> depth0 ;
@@ -2521,7 +2537,11 @@ static jl_value_t *intersect_unionall_(jl_value_t *t, jl_unionall_t *u, jl_stenv
2521
2537
// if the var for this unionall (based on identity) already appears somewhere
2522
2538
// in the environment, rename to get a fresh var.
2523
2539
// TODO: might need to look inside types in btemp->lb and btemp->ub
2540
+ int envsize = 0 ;
2524
2541
while (btemp != NULL ) {
2542
+ envsize ++ ;
2543
+ if (envsize > 150 )
2544
+ return t ;
2525
2545
if (btemp -> var == u -> var || btemp -> lb == (jl_value_t * )u -> var ||
2526
2546
btemp -> ub == (jl_value_t * )u -> var ) {
2527
2547
u = rename_unionall (u );
@@ -2923,19 +2943,6 @@ static int subtype_by_bounds(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
2923
2943
return compareto_var (x , (jl_tvar_t * )y , e , -1 ) || compareto_var (y , (jl_tvar_t * )x , e , 1 );
2924
2944
}
2925
2945
2926
- // See if var y is reachable from x via bounds; used to avoid cycles.
2927
- static int reachable_var (jl_value_t * x , jl_tvar_t * y , jl_stenv_t * e )
2928
- {
2929
- if (x == (jl_value_t * )y )
2930
- return 1 ;
2931
- if (!jl_is_typevar (x ))
2932
- return 0 ;
2933
- jl_varbinding_t * xv = lookup (e , (jl_tvar_t * )x );
2934
- if (xv == NULL )
2935
- return 0 ;
2936
- return reachable_var (xv -> ub , y , e ) || reachable_var (xv -> lb , y , e );
2937
- }
2938
-
2939
2946
// `param` means we are currently looking at a parameter of a type constructor
2940
2947
// (as opposed to being outside any type constructor, or comparing variable bounds).
2941
2948
// this is used to record the positions where type variables occur for the
0 commit comments