@@ -2667,31 +2667,22 @@ static void set_bound(jl_value_t **bound, jl_value_t *val, jl_tvar_t *v, jl_sten
2667
2667
// subtype, treating all vars as existential
2668
2668
static int subtype_in_env_existential (jl_value_t * x , jl_value_t * y , jl_stenv_t * e )
2669
2669
{
2670
- jl_varbinding_t * v = e -> vars ;
2671
- int len = 0 ;
2672
2670
if (x == jl_bottom_type || y == (jl_value_t * )jl_any_type )
2673
2671
return 1 ;
2674
- while (v != NULL ) {
2675
- len ++ ;
2676
- v = v -> prev ;
2677
- }
2678
- int8_t * rs = (int8_t * )malloc_s (len );
2672
+ int8_t * rs = (int8_t * )alloca (current_env_length (e ));
2673
+ jl_varbinding_t * v = e -> vars ;
2679
2674
int n = 0 ;
2680
- v = e -> vars ;
2681
- while (n < len ) {
2682
- assert (v != NULL );
2675
+ while (v != NULL ) {
2683
2676
rs [n ++ ] = v -> right ;
2684
2677
v -> right = 1 ;
2685
2678
v = v -> prev ;
2686
2679
}
2687
2680
int issub = subtype_in_env (x , y , e );
2688
2681
n = 0 ; v = e -> vars ;
2689
- while (n < len ) {
2690
- assert (v != NULL );
2682
+ while (v != NULL ) {
2691
2683
v -> right = rs [n ++ ];
2692
2684
v = v -> prev ;
2693
2685
}
2694
- free (rs );
2695
2686
return issub ;
2696
2687
}
2697
2688
@@ -2739,6 +2730,8 @@ static int check_unsat_bound(jl_value_t *t, jl_tvar_t *v, jl_stenv_t *e) JL_NOTS
2739
2730
}
2740
2731
2741
2732
2733
+ 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 );
2734
+
2742
2735
static jl_value_t * intersect_var (jl_tvar_t * b , jl_value_t * a , jl_stenv_t * e , int8_t R , int param )
2743
2736
{
2744
2737
jl_varbinding_t * bb = lookup (e , b );
@@ -2750,20 +2743,14 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
2750
2743
return R ? intersect (a , bb -> lb , e , param ) : intersect (bb -> lb , a , e , param );
2751
2744
if (!jl_is_type (a ) && !jl_is_typevar (a ))
2752
2745
return set_var_to_const (bb , a , e , R );
2753
- jl_savedenv_t se ;
2754
2746
if (param == 2 ) {
2755
2747
jl_value_t * ub = NULL ;
2756
2748
JL_GC_PUSH1 (& ub );
2757
2749
if (!jl_has_free_typevars (a )) {
2758
- save_env (e , & se , 1 );
2759
- int issub = subtype_in_env_existential (bb -> lb , a , e );
2760
- restore_env (e , & se , 1 );
2761
- if (issub ) {
2762
- issub = subtype_in_env_existential (a , bb -> ub , e );
2763
- restore_env (e , & se , 1 );
2764
- }
2765
- free_env (& se );
2766
- if (!issub ) {
2750
+ if (R ) flip_offset (e );
2751
+ int ccheck = intersect_var_ccheck_in_env (bb -> lb , bb -> ub , a , a , e , !R );
2752
+ if (R ) flip_offset (e );
2753
+ if (!ccheck ) {
2767
2754
JL_GC_POP ();
2768
2755
return jl_bottom_type ;
2769
2756
}
@@ -2773,6 +2760,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
2773
2760
e -> triangular ++ ;
2774
2761
ub = R ? intersect_aside (a , bb -> ub , e , bb -> depth0 ) : intersect_aside (bb -> ub , a , e , bb -> depth0 );
2775
2762
e -> triangular -- ;
2763
+ jl_savedenv_t se ;
2776
2764
save_env (e , & se , 1 );
2777
2765
int issub = subtype_in_env_existential (bb -> lb , ub , e );
2778
2766
restore_env (e , & se , 1 );
@@ -3845,6 +3833,89 @@ static int subtype_by_bounds(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) JL_NOT
3845
3833
return compareto_var (x , (jl_tvar_t * )y , e , -1 ) || compareto_var (y , (jl_tvar_t * )x , e , 1 );
3846
3834
}
3847
3835
3836
+ 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 )
3837
+ {
3838
+ int easy_check1 = xlb == jl_bottom_type ||
3839
+ yub == (jl_value_t * )jl_any_type ||
3840
+ (e -> Loffset == 0 && obviously_in_union (yub , xlb ));
3841
+ int easy_check2 = ylb == jl_bottom_type ||
3842
+ xub == (jl_value_t * )jl_any_type ||
3843
+ (e -> Loffset == 0 && obviously_in_union (xub , ylb ));
3844
+ int nofree1 = 0 , nofree2 = 0 ;
3845
+ if (!easy_check1 ) {
3846
+ nofree1 = !jl_has_free_typevars (xlb ) && !jl_has_free_typevars (yub );
3847
+ if (nofree1 && e -> Loffset == 0 ) {
3848
+ easy_check1 = jl_subtype (xlb , yub );
3849
+ if (!easy_check1 )
3850
+ return 0 ;
3851
+ }
3852
+ }
3853
+ if (!easy_check2 ) {
3854
+ nofree2 = !jl_has_free_typevars (ylb ) && !jl_has_free_typevars (xub );
3855
+ if (nofree2 && e -> Loffset == 0 ) {
3856
+ easy_check2 = jl_subtype (ylb , xub );
3857
+ if (!easy_check2 )
3858
+ return 0 ;
3859
+ }
3860
+ }
3861
+ if (easy_check1 && easy_check2 )
3862
+ return 1 ;
3863
+ int ccheck = 0 ;
3864
+ if ((easy_check1 || nofree1 ) && (easy_check2 || nofree2 )) {
3865
+ jl_varbinding_t * vars = e -> vars ;
3866
+ e -> vars = NULL ;
3867
+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3868
+ if (ccheck && !easy_check2 ) {
3869
+ flip_offset (e );
3870
+ ccheck = subtype_in_env (ylb , xub , e );
3871
+ flip_offset (e );
3872
+ }
3873
+ e -> vars = vars ;
3874
+ return ccheck ;
3875
+ }
3876
+ jl_savedenv_t se ;
3877
+ save_env (e , & se , 1 );
3878
+ // first try normal flip.
3879
+ if (flip ) flip_vars (e );
3880
+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3881
+ if (ccheck && !easy_check2 ) {
3882
+ flip_offset (e );
3883
+ ccheck = subtype_in_env (ylb , xub , e );
3884
+ flip_offset (e );
3885
+ }
3886
+ if (flip ) flip_vars (e );
3887
+ if (!ccheck ) {
3888
+ // then try reverse flip.
3889
+ restore_env (e , & se , 1 );
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
+ }
3899
+ if (!ccheck ) {
3900
+ // then try existential.
3901
+ restore_env (e , & se , 1 );
3902
+ if (easy_check1 )
3903
+ ccheck = 1 ;
3904
+ else {
3905
+ ccheck = subtype_in_env_existential (xlb , yub , e );
3906
+ restore_env (e , & se , 1 );
3907
+ }
3908
+ if (ccheck && !easy_check2 ) {
3909
+ flip_offset (e );
3910
+ ccheck = subtype_in_env_existential (ylb , xub , e );
3911
+ flip_offset (e );
3912
+ restore_env (e , & se , 1 );
3913
+ }
3914
+ }
3915
+ free_env (& se );
3916
+ return ccheck ;
3917
+ }
3918
+
3848
3919
static int has_typevar_via_env (jl_value_t * x , jl_tvar_t * t , jl_stenv_t * e )
3849
3920
{
3850
3921
if (e -> Loffset == 0 ) {
@@ -3977,14 +4048,8 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa
3977
4048
ccheck = 1 ;
3978
4049
}
3979
4050
else {
3980
- if (R ) flip_vars (e );
3981
- ccheck = subtype_in_env (xlb , yub , e );
3982
- if (ccheck ) {
3983
- flip_offset (e );
3984
- ccheck = subtype_in_env (ylb , xub , e );
3985
- flip_offset (e );
3986
- }
3987
- if (R ) flip_vars (e );
4051
+ // try many subtype check to avoid false `Union{}`
4052
+ ccheck = intersect_var_ccheck_in_env (xlb , xub , ylb , yub , e , R );
3988
4053
}
3989
4054
if (R ) flip_offset (e );
3990
4055
if (!ccheck )
0 commit comments