@@ -216,6 +216,17 @@ static void restore_env(jl_stenv_t *e, jl_value_t *root, jl_savedenv_t *se) JL_N
216216 memset (& e -> envout [e -> envidx ], 0 , (e -> envsz - e -> envidx )* sizeof (void * ));
217217}
218218
219+ static int current_env_length (jl_stenv_t * e )
220+ {
221+ jl_varbinding_t * v = e -> vars ;
222+ int len = 0 ;
223+ while (v ) {
224+ len ++ ;
225+ v = v -> prev ;
226+ }
227+ return len ;
228+ }
229+
219230// type utilities
220231
221232// quickly test that two types are identical
@@ -2302,16 +2313,40 @@ static int subtype_in_env_existential(jl_value_t *x, jl_value_t *y, jl_stenv_t *
23022313}
23032314
23042315// See if var y is reachable from x via bounds; used to avoid cycles.
2305- static int reachable_var (jl_value_t * x , jl_tvar_t * y , jl_stenv_t * e )
2316+ static int _reachable_var (jl_value_t * x , jl_tvar_t * y , jl_stenv_t * e )
23062317{
23072318 if (in_union (x , (jl_value_t * )y ))
23082319 return 1 ;
23092320 if (!jl_is_typevar (x ))
23102321 return 0 ;
23112322 jl_varbinding_t * xv = lookup (e , (jl_tvar_t * )x );
2312- if (xv == NULL )
2323+ if (xv == NULL || xv -> right )
23132324 return 0 ;
2314- return reachable_var (xv -> ub , y , e ) || reachable_var (xv -> lb , y , e );
2325+ xv -> right = 1 ;
2326+ return _reachable_var (xv -> ub , y , e ) || _reachable_var (xv -> lb , y , e );
2327+ }
2328+
2329+ static int reachable_var (jl_value_t * x , jl_tvar_t * y , jl_stenv_t * e )
2330+ {
2331+ int len = current_env_length (e );
2332+ int8_t * rs = (int8_t * )malloc_s (len );
2333+ int n = 0 ;
2334+ jl_varbinding_t * v = e -> vars ;
2335+ while (n < len ) {
2336+ assert (v != NULL );
2337+ rs [n ++ ] = v -> right ;
2338+ v -> right = 0 ;
2339+ v = v -> prev ;
2340+ }
2341+ int res = _reachable_var (x , y , e );
2342+ n = 0 ; v = e -> vars ;
2343+ while (n < len ) {
2344+ assert (v != NULL );
2345+ v -> right = rs [n ++ ];
2346+ v = v -> prev ;
2347+ }
2348+ free (rs );
2349+ return res ;
23152350}
23162351
23172352// check whether setting v == t implies v == SomeType{v}, which is unsatisfiable.
0 commit comments