@@ -304,11 +304,13 @@ static int obviously_disjoint(jl_value_t *a, jl_value_t *b, int specificity)
304
304
return 0 ;
305
305
if (specificity && a == (jl_value_t * )jl_typeofbottom_type )
306
306
return 0 ;
307
- if (jl_is_concrete_type (a ) && jl_is_concrete_type (b ) &&
308
- // TODO: remove these 2 lines if and when Tuple{Union{}} === Union{}
309
- (((jl_datatype_t * )a )-> name != jl_tuple_typename ||
310
- ((jl_datatype_t * )b )-> name != jl_tuple_typename ))
311
- return 1 ;
307
+ // TODO: this would be a nice fast-path to have, unfortuanately,
308
+ // datatype allocation fails to correctly hash-cons them
309
+ // and the subtyping tests include tests for this case
310
+ //if (jl_is_concrete_type(a) && jl_is_concrete_type(b) &&
311
+ // (((jl_datatype_t*)a)->name != jl_tuple_typename ||
312
+ // ((jl_datatype_t*)b)->name != jl_tuple_typename))
313
+ // return 1;
312
314
if (jl_is_unionall (a )) a = jl_unwrap_unionall (a );
313
315
if (jl_is_unionall (b )) b = jl_unwrap_unionall (b );
314
316
if (jl_is_datatype (a ) && jl_is_datatype (b )) {
@@ -355,25 +357,24 @@ static int obviously_disjoint(jl_value_t *a, jl_value_t *b, int specificity)
355
357
np = jl_nparams (ad );
356
358
}
357
359
size_t i ;
358
- for ( i = 0 ; i < np ; i ++ ) {
359
- jl_value_t * ai = jl_tparam (ad ,i );
360
- jl_value_t * bi = jl_tparam (bd ,i );
360
+ for ( i = 0 ; i < np ; i ++ ) {
361
+ jl_value_t * ai = jl_tparam (ad , i );
362
+ jl_value_t * bi = jl_tparam (bd , i );
361
363
if (jl_is_typevar (ai ) || jl_is_typevar (bi ))
362
- continue ;
364
+ continue ; // it's possible that Union{} is in this intersection
363
365
if (jl_is_type (ai )) {
364
366
if (jl_is_type (bi )) {
365
367
if (istuple && (ai == jl_bottom_type || bi == jl_bottom_type ))
366
368
; // TODO: this can return 1 if and when Tuple{Union{}} === Union{}
367
369
else if (obviously_disjoint (ai , bi , specificity ))
368
370
return 1 ;
369
371
}
370
- else if (!specificity ) {
371
- // Tuple{1} is more specific than Tuple{Any}
372
+ else if (ai != (jl_value_t * )jl_any_type ) {
372
373
return 1 ;
373
374
}
374
375
}
375
376
else if (jl_is_type (bi )) {
376
- if (! specificity )
377
+ if (bi != ( jl_value_t * ) jl_any_type )
377
378
return 1 ;
378
379
}
379
380
else if (!jl_egal (ai , bi )) {
@@ -1620,17 +1621,35 @@ static int obvious_subtype(jl_value_t *x, jl_value_t *y, jl_value_t *y0, int *su
1620
1621
int istuple = (((jl_datatype_t * )y )-> name == jl_tuple_typename );
1621
1622
int iscov = istuple || (((jl_datatype_t * )y )-> name == jl_vararg_typename );
1622
1623
// TODO: this would be a nice fast-path to have, unfortuanately,
1623
- // datatype allocation fails to correctly cons them
1624
+ // datatype allocation fails to correctly hash- cons them
1624
1625
// and the subtyping tests include tests for this case
1625
1626
//if (!iscov && ((jl_datatype_t*)y)->isconcretetype && !jl_is_type_type(x)) {
1626
1627
// *subtype = 0;
1627
1628
// return 1;
1628
1629
//}
1629
1630
if (jl_is_datatype (x )) {
1631
+ // Weaker version of above, but runs into the same problem
1632
+ //if (((jl_datatype_t*)x)->isconcretetype && ((jl_datatype_t*)y)->isconcretetype && (!istuple || !istuple_x)) {
1633
+ // *subtype = 0;
1634
+ // return 1;
1635
+ //}
1630
1636
int uncertain = 0 ;
1631
1637
if (((jl_datatype_t * )x )-> name != ((jl_datatype_t * )y )-> name ) {
1632
- if (jl_is_type_type (x ) || jl_is_type_type (y ))
1633
- return 0 ;
1638
+ if (jl_is_type_type (x ) && jl_is_kind (y )) {
1639
+ jl_value_t * t0 = jl_tparam0 (x );
1640
+ if (jl_is_typevar (t0 ))
1641
+ return 0 ;
1642
+ * subtype = jl_typeof (t0 ) == y ;
1643
+ return 1 ;
1644
+ }
1645
+ if (jl_is_type_type (y )) {
1646
+ jl_value_t * t0 = jl_tparam0 (y );
1647
+ assert (!jl_is_type_type (x ));
1648
+ if (jl_is_kind (x ) && jl_is_typevar (t0 ))
1649
+ return 0 ;
1650
+ * subtype = 0 ;
1651
+ return 1 ;
1652
+ }
1634
1653
jl_datatype_t * temp = (jl_datatype_t * )x ;
1635
1654
while (temp -> name != ((jl_datatype_t * )y )-> name ) {
1636
1655
temp = temp -> super ;
@@ -1818,13 +1837,22 @@ JL_DLLEXPORT int jl_obvious_subtype(jl_value_t *x, jl_value_t *y, int *subtype)
1818
1837
JL_DLLEXPORT int jl_subtype_env (jl_value_t * x , jl_value_t * y , jl_value_t * * env , int envsz )
1819
1838
{
1820
1839
jl_stenv_t e ;
1821
- if (envsz == 0 ) {
1822
- if (y == (jl_value_t * )jl_any_type || x == jl_bottom_type || x == y )
1823
- return 1 ;
1824
- if (jl_typeof (x ) == jl_typeof (y ) &&
1825
- (jl_is_unionall (y ) || jl_is_uniontype (y )) &&
1826
- jl_egal (x , y ))
1827
- return 1 ;
1840
+ if (y == (jl_value_t * )jl_any_type || x == jl_bottom_type )
1841
+ return 1 ;
1842
+ if (x == y ||
1843
+ (jl_typeof (x ) == jl_typeof (y ) &&
1844
+ (jl_is_unionall (y ) || jl_is_uniontype (y )) &&
1845
+ jl_egal (x , y ))) {
1846
+ if (envsz != 0 ) { // quickly copy env from x
1847
+ jl_unionall_t * ua = (jl_unionall_t * )x ;
1848
+ int i ;
1849
+ for (i = 0 ; i < envsz ; i ++ ) {
1850
+ assert (jl_is_unionall (ua ));
1851
+ env [i ] = (jl_value_t * )ua -> var ;
1852
+ ua = (jl_unionall_t * )ua -> body ;
1853
+ }
1854
+ }
1855
+ return 1 ;
1828
1856
}
1829
1857
int obvious_subtype = 2 ;
1830
1858
if (jl_obvious_subtype (x , y , & obvious_subtype )) {
@@ -3226,6 +3254,37 @@ jl_value_t *switch_union_tuple(jl_value_t *a, jl_value_t *b)
3226
3254
return ans ;
3227
3255
}
3228
3256
3257
+ // `a` might have a non-empty intersection with some concrete type b even if !(a<:b) and !(b<:a)
3258
+ // For example a=`Tuple{Type{<:Vector}}` and b=`Tuple{DataType}`
3259
+ int might_intersect_concrete (jl_value_t * a )
3260
+ {
3261
+ if (jl_is_unionall (a ))
3262
+ a = jl_unwrap_unionall (a );
3263
+ if (jl_is_typevar (a ))
3264
+ return 1 ; // (maybe)
3265
+ if (jl_is_uniontype (a ))
3266
+ return might_intersect_concrete (((jl_uniontype_t * )a )-> a ) ||
3267
+ might_intersect_concrete (((jl_uniontype_t * )a )-> b );
3268
+ if (jl_is_vararg_type (a ))
3269
+ return might_intersect_concrete (jl_tparam0 (a ));
3270
+ if (jl_is_type_type (a ))
3271
+ return 1 ;
3272
+ if (jl_is_datatype (a )) {
3273
+ int tpl = jl_is_tuple_type (a );
3274
+ int i , n = jl_nparams (a );
3275
+ for (i = 0 ; i < n ; i ++ ) {
3276
+ jl_value_t * p = jl_tparam (a , i );
3277
+ if (jl_is_typevar (p ))
3278
+ return 1 ;
3279
+ if (tpl && p == jl_bottom_type )
3280
+ return 1 ;
3281
+ if (tpl && might_intersect_concrete (p ))
3282
+ return 1 ;
3283
+ }
3284
+ }
3285
+ return 0 ;
3286
+ }
3287
+
3229
3288
// sets *issubty to 1 iff `a` is a subtype of `b`
3230
3289
jl_value_t * jl_type_intersection_env_s (jl_value_t * a , jl_value_t * b , jl_svec_t * * penv , int * issubty )
3231
3290
{
@@ -3238,18 +3297,25 @@ jl_value_t *jl_type_intersection_env_s(jl_value_t *a, jl_value_t *b, jl_svec_t *
3238
3297
int sz = 0 , i = 0 ;
3239
3298
jl_value_t * * env , * * ans ;
3240
3299
JL_GC_PUSHARGS (env , szb + 1 );
3241
- ans = & env [szb ]; * ans = jl_bottom_type ;
3300
+ ans = & env [szb ];
3301
+ * ans = jl_bottom_type ;
3302
+ int lta = jl_is_concrete_type (a );
3303
+ int ltb = jl_is_concrete_type (b );
3242
3304
if (jl_subtype_env (a , b , env , szb )) {
3243
3305
* ans = a ; sz = szb ;
3244
3306
if (issubty ) * issubty = 1 ;
3245
3307
}
3308
+ else if (lta && ltb ) {
3309
+ goto bot ;
3310
+ }
3246
3311
else if (jl_subtype (b , a )) {
3247
3312
* ans = b ;
3248
3313
}
3249
3314
else {
3250
- int lta = jl_is_concrete_type (a );
3251
- int ltb = jl_is_concrete_type (b );
3252
- if (lta && ltb )
3315
+ // TODO: these tests could probably be ordered better with above
3316
+ if (lta && !might_intersect_concrete (b ))
3317
+ goto bot ;
3318
+ if (ltb && !might_intersect_concrete (a ))
3253
3319
goto bot ;
3254
3320
jl_stenv_t e ;
3255
3321
init_stenv (& e , NULL , 0 );
0 commit comments