@@ -2678,31 +2678,22 @@ static void set_bound(jl_value_t **bound, jl_value_t *val, jl_tvar_t *v, jl_sten
26782678// subtype, treating all vars as existential
26792679static int subtype_in_env_existential (jl_value_t * x , jl_value_t * y , jl_stenv_t * e )
26802680{
2681- jl_varbinding_t * v = e -> vars ;
2682- int len = 0 ;
26832681 if (x == jl_bottom_type || y == (jl_value_t * )jl_any_type )
26842682 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 ;
26902685 int n = 0 ;
2691- v = e -> vars ;
2692- while (n < len ) {
2693- assert (v != NULL );
2686+ while (v != NULL ) {
26942687 rs [n ++ ] = v -> right ;
26952688 v -> right = 1 ;
26962689 v = v -> prev ;
26972690 }
26982691 int issub = subtype_in_env (x , y , e );
26992692 n = 0 ; v = e -> vars ;
2700- while (n < len ) {
2701- assert (v != NULL );
2693+ while (v != NULL ) {
27022694 v -> right = rs [n ++ ];
27032695 v = v -> prev ;
27042696 }
2705- free (rs );
27062697 return issub ;
27072698}
27082699
@@ -2750,6 +2741,8 @@ static int check_unsat_bound(jl_value_t *t, jl_tvar_t *v, jl_stenv_t *e) JL_NOTS
27502741}
27512742
27522743
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+
27532746static jl_value_t * intersect_var (jl_tvar_t * b , jl_value_t * a , jl_stenv_t * e , int8_t R , int param )
27542747{
27552748 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
27612754 return R ? intersect (a , bb -> lb , e , param ) : intersect (bb -> lb , a , e , param );
27622755 if (!jl_is_type (a ) && !jl_is_typevar (a ))
27632756 return set_var_to_const (bb , a , e , R );
2764- jl_savedenv_t se ;
27652757 if (param == 2 ) {
27662758 jl_value_t * ub = NULL ;
27672759 JL_GC_PUSH1 (& ub );
27682760 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 ) {
27782765 JL_GC_POP ();
27792766 return jl_bottom_type ;
27802767 }
@@ -2784,6 +2771,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
27842771 e -> triangular ++ ;
27852772 ub = R ? intersect_aside (a , bb -> ub , e , bb -> depth0 ) : intersect_aside (bb -> ub , a , e , bb -> depth0 );
27862773 e -> triangular -- ;
2774+ jl_savedenv_t se ;
27872775 save_env (e , & se , 1 );
27882776 int issub = subtype_in_env_existential (bb -> lb , ub , e );
27892777 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
38563844 return compareto_var (x , (jl_tvar_t * )y , e , -1 ) || compareto_var (y , (jl_tvar_t * )x , e , 1 );
38573845}
38583846
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+
38593930static int has_typevar_via_env (jl_value_t * x , jl_tvar_t * t , jl_stenv_t * e )
38603931{
38613932 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
39884059 ccheck = 1 ;
39894060 }
39904061 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 );
39994064 }
40004065 if (R ) flip_offset (e );
40014066 if (!ccheck )
0 commit comments