@@ -200,12 +200,9 @@ static void restore_env(jl_stenv_t *e, jl_value_t *root, jl_savedenv_t *se) JL_N
200
200
jl_varbinding_t * v = e -> vars ;
201
201
int i = 0 , j = 0 ;
202
202
while (v != NULL ) {
203
- if (root ) v -> lb = jl_svecref (root , i );
204
- i ++ ;
205
- if (root ) v -> ub = jl_svecref (root , i );
206
- i ++ ;
207
- if (root ) v -> innervars = (jl_array_t * )jl_svecref (root , i );
208
- i ++ ;
203
+ if (root ) v -> lb = jl_svecref (root , i ++ );
204
+ if (root ) v -> ub = jl_svecref (root , i ++ );
205
+ if (root ) v -> innervars = (jl_array_t * )jl_svecref (root , i ++ );
209
206
v -> occurs_inv = se -> buf [j ++ ];
210
207
v -> occurs_cov = se -> buf [j ++ ];
211
208
v = v -> prev ;
@@ -2323,6 +2320,11 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
2323
2320
JL_GC_POP ();
2324
2321
return jl_bottom_type ;
2325
2322
}
2323
+ if (jl_is_uniontype (ub ) && !jl_is_uniontype (a )) {
2324
+ bb -> ub = ub ;
2325
+ bb -> lb = jl_bottom_type ;
2326
+ ub = (jl_value_t * )b ;
2327
+ }
2326
2328
}
2327
2329
if (ub != (jl_value_t * )b ) {
2328
2330
if (jl_has_free_typevars (ub )) {
@@ -3166,26 +3168,50 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa
3166
3168
return jl_bottom_type ;
3167
3169
}
3168
3170
3171
+ static int merge_env (jl_stenv_t * e , jl_value_t * * root , jl_savedenv_t * se , int count )
3172
+ {
3173
+ if (!count ) {
3174
+ save_env (e , root , se );
3175
+ return 1 ;
3176
+ }
3177
+ int n = 0 ;
3178
+ jl_varbinding_t * v = e -> vars ;
3179
+ jl_value_t * ub = NULL , * vub = NULL ;
3180
+ JL_GC_PUSH2 (& ub , & vub );
3181
+ while (v != NULL ) {
3182
+ if (v -> ub != v -> var -> ub || v -> lb != v -> var -> lb ) {
3183
+ jl_value_t * lb = jl_svecref (* root , n );
3184
+ if (v -> lb != lb )
3185
+ jl_svecset (* root , n , lb ? jl_bottom_type : v -> lb );
3186
+ ub = jl_svecref (* root , n + 1 );
3187
+ vub = v -> ub ;
3188
+ if (vub != ub )
3189
+ jl_svecset (* root , n + 1 , ub ? simple_join (ub , vub ) : vub );
3190
+ }
3191
+ n = n + 3 ;
3192
+ v = v -> prev ;
3193
+ }
3194
+ JL_GC_POP ();
3195
+ return count + 1 ;
3196
+ }
3197
+
3169
3198
static jl_value_t * intersect_all (jl_value_t * x , jl_value_t * y , jl_stenv_t * e )
3170
3199
{
3171
3200
e -> Runions .depth = 0 ;
3172
3201
e -> Runions .more = 0 ;
3173
3202
e -> Runions .used = 0 ;
3174
3203
jl_value_t * * is ;
3175
- JL_GC_PUSHARGS (is , 3 );
3204
+ JL_GC_PUSHARGS (is , 4 );
3176
3205
jl_value_t * * saved = & is [2 ];
3177
- jl_savedenv_t se ;
3206
+ jl_value_t * * merged = & is [3 ];
3207
+ jl_savedenv_t se , me ;
3178
3208
save_env (e , saved , & se );
3179
3209
int lastset = 0 , niter = 0 , total_iter = 0 ;
3180
3210
jl_value_t * ii = intersect (x , y , e , 0 );
3181
3211
is [0 ] = ii ; // root
3182
- if (ii == jl_bottom_type ) {
3183
- restore_env (e , * saved , & se );
3184
- }
3185
- else {
3186
- free_env (& se );
3187
- save_env (e , saved , & se );
3188
- }
3212
+ if (is [0 ] != jl_bottom_type )
3213
+ niter = merge_env (e , merged , & me , niter );
3214
+ restore_env (e , * saved , & se );
3189
3215
while (e -> Runions .more ) {
3190
3216
if (e -> emptiness_only && ii != jl_bottom_type )
3191
3217
break ;
@@ -3199,28 +3225,27 @@ static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
3199
3225
3200
3226
is [0 ] = ii ;
3201
3227
is [1 ] = intersect (x , y , e , 0 );
3202
- if (is [1 ] == jl_bottom_type ) {
3203
- restore_env (e , * saved , & se );
3204
- }
3205
- else {
3206
- free_env (& se );
3207
- save_env (e , saved , & se );
3208
- }
3228
+ if (is [1 ] != jl_bottom_type )
3229
+ niter = merge_env (e , merged , & me , niter );
3230
+ restore_env (e , * saved , & se );
3209
3231
if (is [0 ] == jl_bottom_type )
3210
3232
ii = is [1 ];
3211
3233
else if (is [1 ] == jl_bottom_type )
3212
3234
ii = is [0 ];
3213
3235
else {
3214
3236
// TODO: the repeated subtype checks in here can get expensive
3215
3237
ii = jl_type_union (is , 2 );
3216
- niter ++ ;
3217
3238
}
3218
3239
total_iter ++ ;
3219
- if (niter > 3 || total_iter > 400000 ) {
3240
+ if (niter > 4 || total_iter > 400000 ) {
3220
3241
ii = y ;
3221
3242
break ;
3222
3243
}
3223
3244
}
3245
+ if (niter ){
3246
+ restore_env (e , * merged , & me );
3247
+ free_env (& me );
3248
+ }
3224
3249
free_env (& se );
3225
3250
JL_GC_POP ();
3226
3251
return ii ;
0 commit comments