@@ -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 );
@@ -2766,15 +2759,10 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
27662759 jl_value_t * ub = NULL ;
27672760 JL_GC_PUSH1 (& ub );
27682761 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 ) {
2762+ if (R ) flip_offset (e );
2763+ int ccheck = intersect_var_ccheck_in_env (bb -> lb , bb -> ub , a , a , e , !R );
2764+ if (R ) flip_offset (e );
2765+ if (!ccheck ) {
27782766 JL_GC_POP ();
27792767 return jl_bottom_type ;
27802768 }
@@ -2784,6 +2772,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
27842772 e -> triangular ++ ;
27852773 ub = R ? intersect_aside (a , bb -> ub , e , bb -> depth0 ) : intersect_aside (bb -> ub , a , e , bb -> depth0 );
27862774 e -> triangular -- ;
2775+ jl_savedenv_t se ;
27872776 save_env (e , & se , 1 );
27882777 int issub = subtype_in_env_existential (bb -> lb , ub , e );
27892778 restore_env (e , & se , 1 );
@@ -3374,7 +3363,24 @@ static jl_value_t *intersect_unionall_(jl_value_t *t, jl_unionall_t *u, jl_stenv
33743363 if (jl_is_typevar (vb -> lb )) {
33753364 }
33763365 else if (!is_leaf_bound (vb -> lb )) {
3377- res = jl_bottom_type ;
3366+ JL_GC_PUSH1 (& res );
3367+ res = omit_bad_union (res , u -> var );
3368+ if (res != jl_bottom_type ) {
3369+ jl_varbinding_t * btemp = e -> vars ;
3370+ while (btemp != NULL ) {
3371+ if (jl_has_typevar (btemp -> lb , u -> var )) {
3372+ res = jl_bottom_type ;
3373+ break ;
3374+ }
3375+ btemp -> ub = omit_bad_union (btemp -> ub , u -> var );
3376+ if (btemp -> ub == jl_bottom_type && btemp -> ub != btemp -> lb ) {
3377+ res = jl_bottom_type ;
3378+ break ;
3379+ }
3380+ btemp = btemp -> prev ;
3381+ }
3382+ }
3383+ JL_GC_POP ();
33783384 }
33793385 }
33803386
@@ -3856,6 +3862,89 @@ static int subtype_by_bounds(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) JL_NOT
38563862 return compareto_var (x , (jl_tvar_t * )y , e , -1 ) || compareto_var (y , (jl_tvar_t * )x , e , 1 );
38573863}
38583864
3865+ 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 )
3866+ {
3867+ int easy_check1 = xlb == jl_bottom_type ||
3868+ yub == (jl_value_t * )jl_any_type ||
3869+ (e -> Loffset == 0 && obviously_in_union (yub , xlb ));
3870+ int easy_check2 = ylb == jl_bottom_type ||
3871+ xub == (jl_value_t * )jl_any_type ||
3872+ (e -> Loffset == 0 && obviously_in_union (xub , ylb ));
3873+ int nofree1 = 0 , nofree2 = 0 ;
3874+ if (!easy_check1 ) {
3875+ nofree1 = !jl_has_free_typevars (xlb ) && !jl_has_free_typevars (yub );
3876+ if (nofree1 && e -> Loffset == 0 ) {
3877+ easy_check1 = jl_subtype (xlb , yub );
3878+ if (!easy_check1 )
3879+ return 0 ;
3880+ }
3881+ }
3882+ if (!easy_check2 ) {
3883+ nofree2 = !jl_has_free_typevars (ylb ) && !jl_has_free_typevars (xub );
3884+ if (nofree2 && e -> Loffset == 0 ) {
3885+ easy_check2 = jl_subtype (ylb , xub );
3886+ if (!easy_check2 )
3887+ return 0 ;
3888+ }
3889+ }
3890+ if (easy_check1 && easy_check2 )
3891+ return 1 ;
3892+ int ccheck = 0 ;
3893+ if ((easy_check1 || nofree1 ) && (easy_check2 || nofree2 )) {
3894+ jl_varbinding_t * vars = e -> vars ;
3895+ e -> vars = NULL ;
3896+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3897+ if (ccheck && !easy_check2 ) {
3898+ flip_offset (e );
3899+ ccheck = subtype_in_env (ylb , xub , e );
3900+ flip_offset (e );
3901+ }
3902+ e -> vars = vars ;
3903+ return ccheck ;
3904+ }
3905+ jl_savedenv_t se ;
3906+ save_env (e , & se , 1 );
3907+ // first try normal flip.
3908+ if (flip ) flip_vars (e );
3909+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3910+ if (ccheck && !easy_check2 ) {
3911+ flip_offset (e );
3912+ ccheck = subtype_in_env (ylb , xub , e );
3913+ flip_offset (e );
3914+ }
3915+ if (flip ) flip_vars (e );
3916+ if (!ccheck ) {
3917+ // then try reverse flip.
3918+ restore_env (e , & se , 1 );
3919+ if (!flip ) flip_vars (e );
3920+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3921+ if (ccheck && !easy_check2 ) {
3922+ flip_offset (e );
3923+ ccheck = subtype_in_env (ylb , xub , e );
3924+ flip_offset (e );
3925+ }
3926+ if (!flip ) flip_vars (e );
3927+ }
3928+ if (!ccheck ) {
3929+ // then try existential.
3930+ restore_env (e , & se , 1 );
3931+ if (easy_check1 )
3932+ ccheck = 1 ;
3933+ else {
3934+ ccheck = subtype_in_env_existential (xlb , yub , e );
3935+ restore_env (e , & se , 1 );
3936+ }
3937+ if (ccheck && !easy_check2 ) {
3938+ flip_offset (e );
3939+ ccheck = subtype_in_env_existential (ylb , xub , e );
3940+ flip_offset (e );
3941+ restore_env (e , & se , 1 );
3942+ }
3943+ }
3944+ free_env (& se );
3945+ return ccheck ;
3946+ }
3947+
38593948static int has_typevar_via_env (jl_value_t * x , jl_tvar_t * t , jl_stenv_t * e )
38603949{
38613950 if (e -> Loffset == 0 ) {
@@ -3988,14 +4077,8 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa
39884077 ccheck = 1 ;
39894078 }
39904079 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 );
4080+ // try many subtype check to avoid false `Union{}`
4081+ ccheck = intersect_var_ccheck_in_env (xlb , xub , ylb , yub , e , R );
39994082 }
40004083 if (R ) flip_offset (e );
40014084 if (!ccheck )
0 commit comments