@@ -2616,31 +2616,22 @@ static void set_bound(jl_value_t **bound, jl_value_t *val, jl_tvar_t *v, jl_sten
2616
2616
// subtype, treating all vars as existential
2617
2617
static int subtype_in_env_existential (jl_value_t * x , jl_value_t * y , jl_stenv_t * e )
2618
2618
{
2619
- jl_varbinding_t * v = e -> vars ;
2620
- int len = 0 ;
2621
2619
if (x == jl_bottom_type || y == (jl_value_t * )jl_any_type )
2622
2620
return 1 ;
2623
- while (v != NULL ) {
2624
- len ++ ;
2625
- v = v -> prev ;
2626
- }
2627
- int8_t * rs = (int8_t * )malloc_s (len );
2621
+ int8_t * rs = (int8_t * )alloca (current_env_length (e ));
2622
+ jl_varbinding_t * v = e -> vars ;
2628
2623
int n = 0 ;
2629
- v = e -> vars ;
2630
- while (n < len ) {
2631
- assert (v != NULL );
2624
+ while (v != NULL ) {
2632
2625
rs [n ++ ] = v -> right ;
2633
2626
v -> right = 1 ;
2634
2627
v = v -> prev ;
2635
2628
}
2636
2629
int issub = subtype_in_env (x , y , e );
2637
2630
n = 0 ; v = e -> vars ;
2638
- while (n < len ) {
2639
- assert (v != NULL );
2631
+ while (v != NULL ) {
2640
2632
v -> right = rs [n ++ ];
2641
2633
v = v -> prev ;
2642
2634
}
2643
- free (rs );
2644
2635
return issub ;
2645
2636
}
2646
2637
@@ -2688,6 +2679,8 @@ static int check_unsat_bound(jl_value_t *t, jl_tvar_t *v, jl_stenv_t *e) JL_NOTS
2688
2679
}
2689
2680
2690
2681
2682
+ static int intersect_var_ccheck_in_env (jl_value_t * xlb , jl_value_t * xub , jl_value_t * ylb , jl_value_t * yub , jl_stenv_t * e , int flip );
2683
+
2691
2684
static jl_value_t * intersect_var (jl_tvar_t * b , jl_value_t * a , jl_stenv_t * e , int8_t R , int param )
2692
2685
{
2693
2686
jl_varbinding_t * bb = lookup (e , b );
@@ -2699,20 +2692,14 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
2699
2692
return R ? intersect (a , bb -> lb , e , param ) : intersect (bb -> lb , a , e , param );
2700
2693
if (!jl_is_type (a ) && !jl_is_typevar (a ))
2701
2694
return set_var_to_const (bb , a , e , R );
2702
- jl_savedenv_t se ;
2703
2695
if (param == 2 ) {
2704
2696
jl_value_t * ub = NULL ;
2705
2697
JL_GC_PUSH1 (& ub );
2706
2698
if (!jl_has_free_typevars (a )) {
2707
- save_env (e , & se , 1 );
2708
- int issub = subtype_in_env_existential (bb -> lb , a , e );
2709
- restore_env (e , & se , 1 );
2710
- if (issub ) {
2711
- issub = subtype_in_env_existential (a , bb -> ub , e );
2712
- restore_env (e , & se , 1 );
2713
- }
2714
- free_env (& se );
2715
- if (!issub ) {
2699
+ if (R ) flip_offset (e );
2700
+ int ccheck = intersect_var_ccheck_in_env (bb -> lb , bb -> ub , a , a , e , !R );
2701
+ if (R ) flip_offset (e );
2702
+ if (!ccheck ) {
2716
2703
JL_GC_POP ();
2717
2704
return jl_bottom_type ;
2718
2705
}
@@ -2722,6 +2709,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
2722
2709
e -> triangular ++ ;
2723
2710
ub = R ? intersect_aside (a , bb -> ub , e , bb -> depth0 ) : intersect_aside (bb -> ub , a , e , bb -> depth0 );
2724
2711
e -> triangular -- ;
2712
+ jl_savedenv_t se ;
2725
2713
save_env (e , & se , 1 );
2726
2714
int issub = subtype_in_env_existential (bb -> lb , ub , e );
2727
2715
restore_env (e , & se , 1 );
@@ -3654,6 +3642,89 @@ static int subtype_by_bounds(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) JL_NOT
3654
3642
return compareto_var (x , (jl_tvar_t * )y , e , -1 ) || compareto_var (y , (jl_tvar_t * )x , e , 1 );
3655
3643
}
3656
3644
3645
+ static int intersect_var_ccheck_in_env (jl_value_t * xlb , jl_value_t * xub , jl_value_t * ylb , jl_value_t * yub , jl_stenv_t * e , int flip )
3646
+ {
3647
+ int easy_check1 = xlb == jl_bottom_type ||
3648
+ yub == (jl_value_t * )jl_any_type ||
3649
+ (e -> Loffset == 0 && obviously_in_union (yub , xlb ));
3650
+ int easy_check2 = ylb == jl_bottom_type ||
3651
+ xub == (jl_value_t * )jl_any_type ||
3652
+ (e -> Loffset == 0 && obviously_in_union (xub , ylb ));
3653
+ int nofree1 = 0 , nofree2 = 0 ;
3654
+ if (!easy_check1 ) {
3655
+ nofree1 = !jl_has_free_typevars (xlb ) && !jl_has_free_typevars (yub );
3656
+ if (nofree1 && e -> Loffset == 0 ) {
3657
+ easy_check1 = jl_subtype (xlb , yub );
3658
+ if (!easy_check1 )
3659
+ return 0 ;
3660
+ }
3661
+ }
3662
+ if (!easy_check2 ) {
3663
+ nofree2 = !jl_has_free_typevars (ylb ) && !jl_has_free_typevars (xub );
3664
+ if (nofree2 && e -> Loffset == 0 ) {
3665
+ easy_check2 = jl_subtype (ylb , xub );
3666
+ if (!easy_check2 )
3667
+ return 0 ;
3668
+ }
3669
+ }
3670
+ if (easy_check1 && easy_check2 )
3671
+ return 1 ;
3672
+ int ccheck = 0 ;
3673
+ if ((easy_check1 || nofree1 ) && (easy_check2 || nofree2 )) {
3674
+ jl_varbinding_t * vars = e -> vars ;
3675
+ e -> vars = NULL ;
3676
+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3677
+ if (ccheck && !easy_check2 ) {
3678
+ flip_offset (e );
3679
+ ccheck = subtype_in_env (ylb , xub , e );
3680
+ flip_offset (e );
3681
+ }
3682
+ e -> vars = vars ;
3683
+ return ccheck ;
3684
+ }
3685
+ jl_savedenv_t se ;
3686
+ save_env (e , & se , 1 );
3687
+ // first try normal flip.
3688
+ if (flip ) flip_vars (e );
3689
+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3690
+ if (ccheck && !easy_check2 ) {
3691
+ flip_offset (e );
3692
+ ccheck = subtype_in_env (ylb , xub , e );
3693
+ flip_offset (e );
3694
+ }
3695
+ if (flip ) flip_vars (e );
3696
+ if (!ccheck ) {
3697
+ // then try reverse flip.
3698
+ restore_env (e , & se , 1 );
3699
+ if (!flip ) flip_vars (e );
3700
+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3701
+ if (ccheck && !easy_check2 ) {
3702
+ flip_offset (e );
3703
+ ccheck = subtype_in_env (ylb , xub , e );
3704
+ flip_offset (e );
3705
+ }
3706
+ if (!flip ) flip_vars (e );
3707
+ }
3708
+ if (!ccheck ) {
3709
+ // then try existential.
3710
+ restore_env (e , & se , 1 );
3711
+ if (easy_check1 )
3712
+ ccheck = 1 ;
3713
+ else {
3714
+ ccheck = subtype_in_env_existential (xlb , yub , e );
3715
+ restore_env (e , & se , 1 );
3716
+ }
3717
+ if (ccheck && !easy_check2 ) {
3718
+ flip_offset (e );
3719
+ ccheck = subtype_in_env_existential (ylb , xub , e );
3720
+ flip_offset (e );
3721
+ restore_env (e , & se , 1 );
3722
+ }
3723
+ }
3724
+ free_env (& se );
3725
+ return ccheck ;
3726
+ }
3727
+
3657
3728
static int has_typevar_via_env (jl_value_t * x , jl_tvar_t * t , jl_stenv_t * e )
3658
3729
{
3659
3730
if (e -> Loffset == 0 ) {
@@ -3786,14 +3857,8 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa
3786
3857
ccheck = 1 ;
3787
3858
}
3788
3859
else {
3789
- if (R ) flip_vars (e );
3790
- ccheck = subtype_in_env (xlb , yub , e );
3791
- if (ccheck ) {
3792
- flip_offset (e );
3793
- ccheck = subtype_in_env (ylb , xub , e );
3794
- flip_offset (e );
3795
- }
3796
- if (R ) flip_vars (e );
3860
+ // try many subtype check to avoid false `Union{}`
3861
+ ccheck = intersect_var_ccheck_in_env (xlb , xub , ylb , yub , e , R );
3797
3862
}
3798
3863
if (R ) flip_offset (e );
3799
3864
if (!ccheck )
0 commit comments