@@ -64,6 +64,9 @@ typedef struct _varbinding {
64
64
int8_t occurs_inv ; // occurs in invariant position
65
65
int8_t occurs_cov ; // # of occurrences in covariant position
66
66
int8_t concrete ; // 1 if another variable has a constraint forcing this one to be concrete
67
+ // set if this variable's bounds contain a free variable that's been removed from
68
+ // the environment.
69
+ int8_t hasfree ;
67
70
// in covariant position, we need to try constraining a variable in different ways:
68
71
// 0 - unconstrained
69
72
// 1 - less than
@@ -139,14 +142,15 @@ static void save_env(jl_stenv_t *e, jl_value_t **root, jl_savedenv_t *se)
139
142
v = v -> prev ;
140
143
}
141
144
* root = (jl_value_t * )jl_alloc_svec (len * 3 );
142
- se -> buf = (int8_t * )(len ? malloc (len * 2 ) : NULL );
145
+ se -> buf = (int8_t * )(len ? malloc (len * 3 ) : NULL );
143
146
int i = 0 , j = 0 ; v = e -> vars ;
144
147
while (v != NULL ) {
145
148
jl_svecset (* root , i ++ , v -> lb );
146
149
jl_svecset (* root , i ++ , v -> ub );
147
150
jl_svecset (* root , i ++ , (jl_value_t * )v -> innervars );
148
151
se -> buf [j ++ ] = v -> occurs_inv ;
149
152
se -> buf [j ++ ] = v -> occurs_cov ;
153
+ se -> buf [j ++ ] = v -> hasfree ;
150
154
v = v -> prev ;
151
155
}
152
156
se -> rdepth = e -> Runions .depth ;
@@ -165,6 +169,7 @@ static void restore_env(jl_stenv_t *e, jl_value_t *root, jl_savedenv_t *se)
165
169
i ++ ;
166
170
v -> occurs_inv = se -> buf [j ++ ];
167
171
v -> occurs_cov = se -> buf [j ++ ];
172
+ v -> hasfree = se -> buf [j ++ ];
168
173
v = v -> prev ;
169
174
}
170
175
e -> Runions .depth = se -> rdepth ;
@@ -562,7 +567,7 @@ static int subtype_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_t *e, int8
562
567
}
563
568
btemp = btemp -> prev ;
564
569
}
565
- jl_varbinding_t vb = { u -> var , u -> var -> lb , u -> var -> ub , R , NULL , 0 , 0 , 0 , 0 , e -> invdepth , 0 , NULL , e -> vars };
570
+ jl_varbinding_t vb = { u -> var , u -> var -> lb , u -> var -> ub , R , NULL , 0 , 0 , 0 , 0 , 0 , e -> invdepth , 0 , NULL , e -> vars };
566
571
JL_GC_PUSH3 (& u , & vb .lb , & vb .ub );
567
572
e -> vars = & vb ;
568
573
int ans ;
@@ -599,6 +604,7 @@ static int subtype_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_t *e, int8
599
604
else {
600
605
ans = subtype (u -> body , t , e , param );
601
606
}
607
+ if (vb .hasfree ) ans = 0 ;
602
608
603
609
// handle the "diagonal dispatch" rule, which says that a type var occurring more
604
610
// than once, and only in covariant position, is constrained to concrete types. E.g.
@@ -638,14 +644,16 @@ static int subtype_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_t *e, int8
638
644
e -> vars = vb .prev ;
639
645
640
646
btemp = e -> vars ;
641
- while (btemp != NULL ) {
642
- jl_value_t * vi = btemp -> ub ;
643
- // TODO: this takes a significant amount of time
644
- if (vi != (jl_value_t * )vb .var && btemp -> var -> ub != vi && jl_has_typevar (vi , vb .var )) {
645
- btemp -> ub = jl_new_struct (jl_unionall_type , vb .var , vi );
646
- btemp -> lb = jl_bottom_type ;
647
+ if (vb .lb != vb .ub ) {
648
+ while (btemp != NULL ) {
649
+ jl_value_t * vu = btemp -> ub ;
650
+ jl_value_t * vl = btemp -> lb ;
651
+ // TODO: this takes a significant amount of time
652
+ if ((vu != (jl_value_t * )vb .var && btemp -> var -> ub != vu && jl_has_typevar (vu , vb .var )) ||
653
+ (vl != (jl_value_t * )vb .var && btemp -> var -> lb != vl && jl_has_typevar (vl , vb .var )))
654
+ btemp -> hasfree = 1 ;
655
+ btemp = btemp -> prev ;
647
656
}
648
- btemp = btemp -> prev ;
649
657
}
650
658
651
659
JL_GC_POP ();
@@ -1548,7 +1556,7 @@ static jl_value_t *intersect_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_
1548
1556
{
1549
1557
jl_value_t * res = NULL , * res2 = NULL , * save = NULL , * save2 = NULL ;
1550
1558
jl_savedenv_t se , se2 ;
1551
- jl_varbinding_t vb = { u -> var , u -> var -> lb , u -> var -> ub , R , NULL , 0 , 0 , 0 , 0 , e -> invdepth , 0 , NULL , e -> vars };
1559
+ jl_varbinding_t vb = { u -> var , u -> var -> lb , u -> var -> ub , R , NULL , 0 , 0 , 0 , 0 , 0 , e -> invdepth , 0 , NULL , e -> vars };
1552
1560
JL_GC_PUSH6 (& res , & save2 , & vb .lb , & vb .ub , & save , & vb .innervars );
1553
1561
save_env (e , & save , & se );
1554
1562
res = intersect_unionall_ (t , u , e , R , param , & vb );
0 commit comments