@@ -2678,31 +2678,22 @@ static void set_bound(jl_value_t **bound, jl_value_t *val, jl_tvar_t *v, jl_sten
2678
2678
// subtype, treating all vars as existential
2679
2679
static int subtype_in_env_existential (jl_value_t * x , jl_value_t * y , jl_stenv_t * e )
2680
2680
{
2681
- jl_varbinding_t * v = e -> vars ;
2682
- int len = 0 ;
2683
2681
if (x == jl_bottom_type || y == (jl_value_t * )jl_any_type )
2684
2682
return 1 ;
2685
- while (v != NULL ) {
2686
- len ++ ;
2687
- v = v -> prev ;
2688
- }
2689
- int8_t * rs = (int8_t * )malloc_s (len );
2683
+ int8_t * rs = (int8_t * )alloca (current_env_length (e ));
2684
+ jl_varbinding_t * v = e -> vars ;
2690
2685
int n = 0 ;
2691
- v = e -> vars ;
2692
- while (n < len ) {
2693
- assert (v != NULL );
2686
+ while (v != NULL ) {
2694
2687
rs [n ++ ] = v -> right ;
2695
2688
v -> right = 1 ;
2696
2689
v = v -> prev ;
2697
2690
}
2698
2691
int issub = subtype_in_env (x , y , e );
2699
2692
n = 0 ; v = e -> vars ;
2700
- while (n < len ) {
2701
- assert (v != NULL );
2693
+ while (v != NULL ) {
2702
2694
v -> right = rs [n ++ ];
2703
2695
v = v -> prev ;
2704
2696
}
2705
- free (rs );
2706
2697
return issub ;
2707
2698
}
2708
2699
@@ -2750,6 +2741,8 @@ static int check_unsat_bound(jl_value_t *t, jl_tvar_t *v, jl_stenv_t *e) JL_NOTS
2750
2741
}
2751
2742
2752
2743
2744
+ 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 );
2745
+
2753
2746
static jl_value_t * intersect_var (jl_tvar_t * b , jl_value_t * a , jl_stenv_t * e , int8_t R , int param )
2754
2747
{
2755
2748
jl_varbinding_t * bb = lookup (e , b );
@@ -2761,20 +2754,14 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
2761
2754
return R ? intersect (a , bb -> lb , e , param ) : intersect (bb -> lb , a , e , param );
2762
2755
if (!jl_is_type (a ) && !jl_is_typevar (a ))
2763
2756
return set_var_to_const (bb , a , e , R );
2764
- jl_savedenv_t se ;
2765
2757
if (param == 2 ) {
2766
2758
jl_value_t * ub = NULL ;
2767
2759
JL_GC_PUSH1 (& ub );
2768
2760
if (!jl_has_free_typevars (a )) {
2769
- save_env (e , & se , 1 );
2770
- int issub = subtype_in_env_existential (bb -> lb , a , e );
2771
- restore_env (e , & se , 1 );
2772
- if (issub ) {
2773
- issub = subtype_in_env_existential (a , bb -> ub , e );
2774
- restore_env (e , & se , 1 );
2775
- }
2776
- free_env (& se );
2777
- if (!issub ) {
2761
+ if (R ) flip_offset (e );
2762
+ int ccheck = intersect_var_ccheck_in_env (bb -> lb , bb -> ub , a , a , e , !R );
2763
+ if (R ) flip_offset (e );
2764
+ if (!ccheck ) {
2778
2765
JL_GC_POP ();
2779
2766
return jl_bottom_type ;
2780
2767
}
@@ -2784,6 +2771,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
2784
2771
e -> triangular ++ ;
2785
2772
ub = R ? intersect_aside (a , bb -> ub , e , bb -> depth0 ) : intersect_aside (bb -> ub , a , e , bb -> depth0 );
2786
2773
e -> triangular -- ;
2774
+ jl_savedenv_t se ;
2787
2775
save_env (e , & se , 1 );
2788
2776
int issub = subtype_in_env_existential (bb -> lb , ub , e );
2789
2777
restore_env (e , & se , 1 );
@@ -3856,6 +3844,89 @@ static int subtype_by_bounds(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) JL_NOT
3856
3844
return compareto_var (x , (jl_tvar_t * )y , e , -1 ) || compareto_var (y , (jl_tvar_t * )x , e , 1 );
3857
3845
}
3858
3846
3847
+ 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 )
3848
+ {
3849
+ int easy_check1 = xlb == jl_bottom_type ||
3850
+ yub == (jl_value_t * )jl_any_type ||
3851
+ (e -> Loffset == 0 && obviously_in_union (yub , xlb ));
3852
+ int easy_check2 = ylb == jl_bottom_type ||
3853
+ xub == (jl_value_t * )jl_any_type ||
3854
+ (e -> Loffset == 0 && obviously_in_union (xub , ylb ));
3855
+ int nofree1 = 0 , nofree2 = 0 ;
3856
+ if (!easy_check1 ) {
3857
+ nofree1 = !jl_has_free_typevars (xlb ) && !jl_has_free_typevars (yub );
3858
+ if (nofree1 && e -> Loffset == 0 ) {
3859
+ easy_check1 = jl_subtype (xlb , yub );
3860
+ if (!easy_check1 )
3861
+ return 0 ;
3862
+ }
3863
+ }
3864
+ if (!easy_check2 ) {
3865
+ nofree2 = !jl_has_free_typevars (ylb ) && !jl_has_free_typevars (xub );
3866
+ if (nofree2 && e -> Loffset == 0 ) {
3867
+ easy_check2 = jl_subtype (ylb , xub );
3868
+ if (!easy_check2 )
3869
+ return 0 ;
3870
+ }
3871
+ }
3872
+ if (easy_check1 && easy_check2 )
3873
+ return 1 ;
3874
+ int ccheck = 0 ;
3875
+ if ((easy_check1 || nofree1 ) && (easy_check2 || nofree2 )) {
3876
+ jl_varbinding_t * vars = e -> vars ;
3877
+ e -> vars = NULL ;
3878
+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3879
+ if (ccheck && !easy_check2 ) {
3880
+ flip_offset (e );
3881
+ ccheck = subtype_in_env (ylb , xub , e );
3882
+ flip_offset (e );
3883
+ }
3884
+ e -> vars = vars ;
3885
+ return ccheck ;
3886
+ }
3887
+ jl_savedenv_t se ;
3888
+ save_env (e , & se , 1 );
3889
+ // first try normal flip.
3890
+ if (flip ) flip_vars (e );
3891
+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3892
+ if (ccheck && !easy_check2 ) {
3893
+ flip_offset (e );
3894
+ ccheck = subtype_in_env (ylb , xub , e );
3895
+ flip_offset (e );
3896
+ }
3897
+ if (flip ) flip_vars (e );
3898
+ if (!ccheck ) {
3899
+ // then try reverse flip.
3900
+ restore_env (e , & se , 1 );
3901
+ if (!flip ) flip_vars (e );
3902
+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3903
+ if (ccheck && !easy_check2 ) {
3904
+ flip_offset (e );
3905
+ ccheck = subtype_in_env (ylb , xub , e );
3906
+ flip_offset (e );
3907
+ }
3908
+ if (!flip ) flip_vars (e );
3909
+ }
3910
+ if (!ccheck ) {
3911
+ // then try existential.
3912
+ restore_env (e , & se , 1 );
3913
+ if (easy_check1 )
3914
+ ccheck = 1 ;
3915
+ else {
3916
+ ccheck = subtype_in_env_existential (xlb , yub , e );
3917
+ restore_env (e , & se , 1 );
3918
+ }
3919
+ if (ccheck && !easy_check2 ) {
3920
+ flip_offset (e );
3921
+ ccheck = subtype_in_env_existential (ylb , xub , e );
3922
+ flip_offset (e );
3923
+ restore_env (e , & se , 1 );
3924
+ }
3925
+ }
3926
+ free_env (& se );
3927
+ return ccheck ;
3928
+ }
3929
+
3859
3930
static int has_typevar_via_env (jl_value_t * x , jl_tvar_t * t , jl_stenv_t * e )
3860
3931
{
3861
3932
if (e -> Loffset == 0 ) {
@@ -3988,14 +4059,8 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa
3988
4059
ccheck = 1 ;
3989
4060
}
3990
4061
else {
3991
- if (R ) flip_vars (e );
3992
- ccheck = subtype_in_env (xlb , yub , e );
3993
- if (ccheck ) {
3994
- flip_offset (e );
3995
- ccheck = subtype_in_env (ylb , xub , e );
3996
- flip_offset (e );
3997
- }
3998
- if (R ) flip_vars (e );
4062
+ // try many subtype check to avoid false `Union{}`
4063
+ ccheck = intersect_var_ccheck_in_env (xlb , xub , ylb , yub , e , R );
3999
4064
}
4000
4065
if (R ) flip_offset (e );
4001
4066
if (!ccheck )
0 commit comments