@@ -516,7 +516,7 @@ static int subtype_ccheck(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
516
516
return sub ;
517
517
}
518
518
519
- static int subtype_left_var (jl_value_t * x , jl_value_t * y , jl_stenv_t * e )
519
+ static int subtype_left_var (jl_value_t * x , jl_value_t * y , jl_stenv_t * e , int param )
520
520
{
521
521
if (x == y )
522
522
return 1 ;
@@ -528,7 +528,7 @@ static int subtype_left_var(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
528
528
return 1 ;
529
529
if (x == (jl_value_t * )jl_any_type && jl_is_datatype (y ))
530
530
return 0 ;
531
- return subtype (x , y , e , 0 );
531
+ return subtype (x , y , e , param );
532
532
}
533
533
534
534
// use the current context to record where a variable occurred, for the purpose
@@ -566,10 +566,10 @@ static int var_lt(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int param)
566
566
{
567
567
jl_varbinding_t * bb = lookup (e , b );
568
568
if (bb == NULL )
569
- return e -> ignore_free || subtype_left_var (b -> ub , a , e );
569
+ return e -> ignore_free || subtype_left_var (b -> ub , a , e , param );
570
570
record_var_occurrence (bb , e , param );
571
571
if (!bb -> right ) // check ∀b . b<:a
572
- return subtype_left_var (bb -> ub , a , e );
572
+ return subtype_left_var (bb -> ub , a , e , param );
573
573
if (bb -> ub == a )
574
574
return 1 ;
575
575
if (!((bb -> lb == jl_bottom_type && !jl_is_type (a ) && !jl_is_typevar (a )) || subtype_ccheck (bb -> lb , a , e )))
@@ -590,7 +590,7 @@ static int var_lt(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int param)
590
590
if (aa && !aa -> right && in_union (bb -> lb , a ) && bb -> depth0 != aa -> depth0 && var_outside (e , b , (jl_tvar_t * )a )) {
591
591
// an "exists" var cannot equal a "forall" var inside it unless the forall
592
592
// var has equal bounds.
593
- return subtype_left_var (aa -> ub , aa -> lb , e );
593
+ return subtype_left_var (aa -> ub , aa -> lb , e , param );
594
594
}
595
595
}
596
596
return 1 ;
@@ -601,10 +601,10 @@ static int var_gt(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int param)
601
601
{
602
602
jl_varbinding_t * bb = lookup (e , b );
603
603
if (bb == NULL )
604
- return e -> ignore_free || subtype_left_var (a , b -> lb , e );
604
+ return e -> ignore_free || subtype_left_var (a , b -> lb , e , param );
605
605
record_var_occurrence (bb , e , param );
606
606
if (!bb -> right ) // check ∀b . b>:a
607
- return subtype_left_var (a , bb -> lb , e );
607
+ return subtype_left_var (a , bb -> lb , e , param );
608
608
if (bb -> lb == bb -> ub ) {
609
609
if (jl_is_typevar (bb -> lb ) && !jl_is_type (a ) && !jl_is_typevar (a ))
610
610
return var_gt ((jl_tvar_t * )bb -> lb , a , e , param );
@@ -618,7 +618,7 @@ static int var_gt(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int param)
618
618
if (jl_is_typevar (a )) {
619
619
jl_varbinding_t * aa = lookup (e , (jl_tvar_t * )a );
620
620
if (aa && !aa -> right && bb -> depth0 != aa -> depth0 && param == 2 && var_outside (e , b , (jl_tvar_t * )a ))
621
- return subtype_left_var (aa -> ub , aa -> lb , e );
621
+ return subtype_left_var (aa -> ub , aa -> lb , e , param );
622
622
}
623
623
return 1 ;
624
624
}
@@ -690,12 +690,42 @@ static int var_occurs_inside(jl_value_t *v, jl_tvar_t *var, int inside, int want
690
690
691
691
typedef int (* tvar_callback )(void * , int8_t , jl_stenv_t * , int );
692
692
693
+ static int var_occurs_invariant (jl_value_t * v , jl_tvar_t * var , int inv ) JL_NOTSAFEPOINT
694
+ {
695
+ if (v == (jl_value_t * )var ) {
696
+ return inv ;
697
+ }
698
+ else if (jl_is_uniontype (v )) {
699
+ return var_occurs_invariant (((jl_uniontype_t * )v )-> a , var , inv ) ||
700
+ var_occurs_invariant (((jl_uniontype_t * )v )-> b , var , inv );
701
+ }
702
+ else if (jl_is_unionall (v )) {
703
+ jl_unionall_t * ua = (jl_unionall_t * )v ;
704
+ if (ua -> var == var )
705
+ return 0 ;
706
+ if (var_occurs_invariant (ua -> var -> lb , var , inv ) || var_occurs_invariant (ua -> var -> ub , var , inv ))
707
+ return 1 ;
708
+ return var_occurs_invariant (ua -> body , var , inv );
709
+ }
710
+ else if (jl_is_datatype (v )) {
711
+ size_t i ;
712
+ int ins = !jl_is_tuple_type (v );
713
+ int va = jl_is_vararg_type (v );
714
+ for (i = 0 ; i < jl_nparams (v ); i ++ ) {
715
+ if (var_occurs_invariant (jl_tparam (v ,i ), var , va && i == 0 ? 0 : ins ))
716
+ return 1 ;
717
+ }
718
+ }
719
+ return 0 ;
720
+ }
721
+
693
722
static int with_tvar (tvar_callback callback , void * context , jl_unionall_t * u , int8_t R , jl_stenv_t * e , int param )
694
723
{
695
724
jl_varbinding_t vb = { u -> var , u -> var -> lb , u -> var -> ub , R , NULL , 0 , 0 , 0 , 0 ,
696
725
R ? e -> Rinvdepth : e -> invdepth , 0 , NULL , 0 , e -> vars };
697
726
JL_GC_PUSH4 (& u , & vb .lb , & vb .ub , & vb .innervars );
698
727
e -> vars = & vb ;
728
+ vb .occurs_inv = var_occurs_invariant (u -> body , u -> var , 0 );
699
729
int ans ;
700
730
if (R ) {
701
731
e -> envidx ++ ;
@@ -2494,7 +2524,8 @@ static jl_value_t *intersect_unionall_(jl_value_t *t, jl_unionall_t *u, jl_stenv
2494
2524
else {
2495
2525
res = intersect (u -> body , t , e , param );
2496
2526
}
2497
- vb -> concrete |= (!vb -> occurs_inv && vb -> occurs_cov > 1 && is_leaf_typevar (u -> var ));
2527
+ int static_occurs_inv = var_occurs_invariant (u -> body , u -> var , 0 );
2528
+ vb -> concrete |= (!static_occurs_inv && vb -> occurs_cov > 1 && is_leaf_typevar (u -> var ));
2498
2529
2499
2530
// handle the "diagonal dispatch" rule, which says that a type var occurring more
2500
2531
// than once, and only in covariant position, is constrained to concrete types. E.g.
0 commit comments