@@ -2667,31 +2667,22 @@ static void set_bound(jl_value_t **bound, jl_value_t *val, jl_tvar_t *v, jl_sten
26672667// subtype, treating all vars as existential
26682668static int subtype_in_env_existential (jl_value_t * x , jl_value_t * y , jl_stenv_t * e )
26692669{
2670- jl_varbinding_t * v = e -> vars ;
2671- int len = 0 ;
26722670 if (x == jl_bottom_type || y == (jl_value_t * )jl_any_type )
26732671 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 ;
26792674 int n = 0 ;
2680- v = e -> vars ;
2681- while (n < len ) {
2682- assert (v != NULL );
2675+ while (v != NULL ) {
26832676 rs [n ++ ] = v -> right ;
26842677 v -> right = 1 ;
26852678 v = v -> prev ;
26862679 }
26872680 int issub = subtype_in_env (x , y , e );
26882681 n = 0 ; v = e -> vars ;
2689- while (n < len ) {
2690- assert (v != NULL );
2682+ while (v != NULL ) {
26912683 v -> right = rs [n ++ ];
26922684 v = v -> prev ;
26932685 }
2694- free (rs );
26952686 return issub ;
26962687}
26972688
@@ -2739,6 +2730,8 @@ static int check_unsat_bound(jl_value_t *t, jl_tvar_t *v, jl_stenv_t *e) JL_NOTS
27392730}
27402731
27412732
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+
27422735static jl_value_t * intersect_var (jl_tvar_t * b , jl_value_t * a , jl_stenv_t * e , int8_t R , int param )
27432736{
27442737 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
27502743 return R ? intersect (a , bb -> lb , e , param ) : intersect (bb -> lb , a , e , param );
27512744 if (!jl_is_type (a ) && !jl_is_typevar (a ))
27522745 return set_var_to_const (bb , a , e , R );
2753- jl_savedenv_t se ;
27542746 if (param == 2 ) {
27552747 jl_value_t * ub = NULL ;
27562748 JL_GC_PUSH1 (& ub );
27572749 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 ) {
27672754 JL_GC_POP ();
27682755 return jl_bottom_type ;
27692756 }
@@ -2773,6 +2760,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
27732760 e -> triangular ++ ;
27742761 ub = R ? intersect_aside (a , bb -> ub , e , bb -> depth0 ) : intersect_aside (bb -> ub , a , e , bb -> depth0 );
27752762 e -> triangular -- ;
2763+ jl_savedenv_t se ;
27762764 save_env (e , & se , 1 );
27772765 int issub = subtype_in_env_existential (bb -> lb , ub , e );
27782766 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
38453833 return compareto_var (x , (jl_tvar_t * )y , e , -1 ) || compareto_var (y , (jl_tvar_t * )x , e , 1 );
38463834}
38473835
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+
38483919static int has_typevar_via_env (jl_value_t * x , jl_tvar_t * t , jl_stenv_t * e )
38493920{
38503921 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
39774048 ccheck = 1 ;
39784049 }
39794050 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 );
39884053 }
39894054 if (R ) flip_offset (e );
39904055 if (!ccheck )
0 commit comments