@@ -2210,13 +2210,29 @@ static int subtype_in_env_existential(jl_value_t *x, jl_value_t *y, jl_stenv_t *
22102210 return issub ;
22112211}
22122212
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+
22132226static jl_value_t * intersect_var (jl_tvar_t * b , jl_value_t * a , jl_stenv_t * e , int8_t R , int param )
22142227{
22152228 jl_varbinding_t * bb = lookup (e , b );
22162229 if (bb == NULL )
22172230 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 )) {
22192234 return intersect (a , bb -> lb , e , param );
2235+ }
22202236 if (!jl_is_type (a ) && !jl_is_typevar (a ))
22212237 return set_var_to_const (bb , a , NULL );
22222238 int d = bb -> depth0 ;
@@ -2521,7 +2537,11 @@ static jl_value_t *intersect_unionall_(jl_value_t *t, jl_unionall_t *u, jl_stenv
25212537 // if the var for this unionall (based on identity) already appears somewhere
25222538 // in the environment, rename to get a fresh var.
25232539 // TODO: might need to look inside types in btemp->lb and btemp->ub
2540+ int envsize = 0 ;
25242541 while (btemp != NULL ) {
2542+ envsize ++ ;
2543+ if (envsize > 150 )
2544+ return t ;
25252545 if (btemp -> var == u -> var || btemp -> lb == (jl_value_t * )u -> var ||
25262546 btemp -> ub == (jl_value_t * )u -> var ) {
25272547 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)
29232943 return compareto_var (x , (jl_tvar_t * )y , e , -1 ) || compareto_var (y , (jl_tvar_t * )x , e , 1 );
29242944}
29252945
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-
29392946// `param` means we are currently looking at a parameter of a type constructor
29402947// (as opposed to being outside any type constructor, or comparing variable bounds).
29412948// this is used to record the positions where type variables occur for the
0 commit comments