@@ -2616,31 +2616,22 @@ static void set_bound(jl_value_t **bound, jl_value_t *val, jl_tvar_t *v, jl_sten
26162616// subtype, treating all vars as existential
26172617static int subtype_in_env_existential (jl_value_t * x , jl_value_t * y , jl_stenv_t * e )
26182618{
2619- jl_varbinding_t * v = e -> vars ;
2620- int len = 0 ;
26212619 if (x == jl_bottom_type || y == (jl_value_t * )jl_any_type )
26222620 return 1 ;
2623- while (v != NULL ) {
2624- len ++ ;
2625- v = v -> prev ;
2626- }
2627- int8_t * rs = (int8_t * )malloc_s (len );
2621+ int8_t * rs = (int8_t * )alloca (current_env_length (e ));
2622+ jl_varbinding_t * v = e -> vars ;
26282623 int n = 0 ;
2629- v = e -> vars ;
2630- while (n < len ) {
2631- assert (v != NULL );
2624+ while (v != NULL ) {
26322625 rs [n ++ ] = v -> right ;
26332626 v -> right = 1 ;
26342627 v = v -> prev ;
26352628 }
26362629 int issub = subtype_in_env (x , y , e );
26372630 n = 0 ; v = e -> vars ;
2638- while (n < len ) {
2639- assert (v != NULL );
2631+ while (v != NULL ) {
26402632 v -> right = rs [n ++ ];
26412633 v = v -> prev ;
26422634 }
2643- free (rs );
26442635 return issub ;
26452636}
26462637
@@ -2688,6 +2679,8 @@ static int check_unsat_bound(jl_value_t *t, jl_tvar_t *v, jl_stenv_t *e) JL_NOTS
26882679}
26892680
26902681
2682+ 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 );
2683+
26912684static jl_value_t * intersect_var (jl_tvar_t * b , jl_value_t * a , jl_stenv_t * e , int8_t R , int param )
26922685{
26932686 jl_varbinding_t * bb = lookup (e , b );
@@ -2699,20 +2692,14 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
26992692 return R ? intersect (a , bb -> lb , e , param ) : intersect (bb -> lb , a , e , param );
27002693 if (!jl_is_type (a ) && !jl_is_typevar (a ))
27012694 return set_var_to_const (bb , a , e , R );
2702- jl_savedenv_t se ;
27032695 if (param == 2 ) {
27042696 jl_value_t * ub = NULL ;
27052697 JL_GC_PUSH1 (& ub );
27062698 if (!jl_has_free_typevars (a )) {
2707- save_env (e , & se , 1 );
2708- int issub = subtype_in_env_existential (bb -> lb , a , e );
2709- restore_env (e , & se , 1 );
2710- if (issub ) {
2711- issub = subtype_in_env_existential (a , bb -> ub , e );
2712- restore_env (e , & se , 1 );
2713- }
2714- free_env (& se );
2715- if (!issub ) {
2699+ if (R ) flip_offset (e );
2700+ int ccheck = intersect_var_ccheck_in_env (bb -> lb , bb -> ub , a , a , e , !R );
2701+ if (R ) flip_offset (e );
2702+ if (!ccheck ) {
27162703 JL_GC_POP ();
27172704 return jl_bottom_type ;
27182705 }
@@ -2722,6 +2709,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
27222709 e -> triangular ++ ;
27232710 ub = R ? intersect_aside (a , bb -> ub , e , bb -> depth0 ) : intersect_aside (bb -> ub , a , e , bb -> depth0 );
27242711 e -> triangular -- ;
2712+ jl_savedenv_t se ;
27252713 save_env (e , & se , 1 );
27262714 int issub = subtype_in_env_existential (bb -> lb , ub , e );
27272715 restore_env (e , & se , 1 );
@@ -3654,6 +3642,89 @@ static int subtype_by_bounds(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) JL_NOT
36543642 return compareto_var (x , (jl_tvar_t * )y , e , -1 ) || compareto_var (y , (jl_tvar_t * )x , e , 1 );
36553643}
36563644
3645+ 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 )
3646+ {
3647+ int easy_check1 = xlb == jl_bottom_type ||
3648+ yub == (jl_value_t * )jl_any_type ||
3649+ (e -> Loffset == 0 && obviously_in_union (yub , xlb ));
3650+ int easy_check2 = ylb == jl_bottom_type ||
3651+ xub == (jl_value_t * )jl_any_type ||
3652+ (e -> Loffset == 0 && obviously_in_union (xub , ylb ));
3653+ int nofree1 = 0 , nofree2 = 0 ;
3654+ if (!easy_check1 ) {
3655+ nofree1 = !jl_has_free_typevars (xlb ) && !jl_has_free_typevars (yub );
3656+ if (nofree1 && e -> Loffset == 0 ) {
3657+ easy_check1 = jl_subtype (xlb , yub );
3658+ if (!easy_check1 )
3659+ return 0 ;
3660+ }
3661+ }
3662+ if (!easy_check2 ) {
3663+ nofree2 = !jl_has_free_typevars (ylb ) && !jl_has_free_typevars (xub );
3664+ if (nofree2 && e -> Loffset == 0 ) {
3665+ easy_check2 = jl_subtype (ylb , xub );
3666+ if (!easy_check2 )
3667+ return 0 ;
3668+ }
3669+ }
3670+ if (easy_check1 && easy_check2 )
3671+ return 1 ;
3672+ int ccheck = 0 ;
3673+ if ((easy_check1 || nofree1 ) && (easy_check2 || nofree2 )) {
3674+ jl_varbinding_t * vars = e -> vars ;
3675+ e -> vars = NULL ;
3676+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3677+ if (ccheck && !easy_check2 ) {
3678+ flip_offset (e );
3679+ ccheck = subtype_in_env (ylb , xub , e );
3680+ flip_offset (e );
3681+ }
3682+ e -> vars = vars ;
3683+ return ccheck ;
3684+ }
3685+ jl_savedenv_t se ;
3686+ save_env (e , & se , 1 );
3687+ // first try normal flip.
3688+ if (flip ) flip_vars (e );
3689+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3690+ if (ccheck && !easy_check2 ) {
3691+ flip_offset (e );
3692+ ccheck = subtype_in_env (ylb , xub , e );
3693+ flip_offset (e );
3694+ }
3695+ if (flip ) flip_vars (e );
3696+ if (!ccheck ) {
3697+ // then try reverse flip.
3698+ restore_env (e , & se , 1 );
3699+ if (!flip ) flip_vars (e );
3700+ ccheck = easy_check1 || subtype_in_env (xlb , yub , e );
3701+ if (ccheck && !easy_check2 ) {
3702+ flip_offset (e );
3703+ ccheck = subtype_in_env (ylb , xub , e );
3704+ flip_offset (e );
3705+ }
3706+ if (!flip ) flip_vars (e );
3707+ }
3708+ if (!ccheck ) {
3709+ // then try existential.
3710+ restore_env (e , & se , 1 );
3711+ if (easy_check1 )
3712+ ccheck = 1 ;
3713+ else {
3714+ ccheck = subtype_in_env_existential (xlb , yub , e );
3715+ restore_env (e , & se , 1 );
3716+ }
3717+ if (ccheck && !easy_check2 ) {
3718+ flip_offset (e );
3719+ ccheck = subtype_in_env_existential (ylb , xub , e );
3720+ flip_offset (e );
3721+ restore_env (e , & se , 1 );
3722+ }
3723+ }
3724+ free_env (& se );
3725+ return ccheck ;
3726+ }
3727+
36573728static int has_typevar_via_env (jl_value_t * x , jl_tvar_t * t , jl_stenv_t * e )
36583729{
36593730 if (e -> Loffset == 0 ) {
@@ -3786,14 +3857,8 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa
37863857 ccheck = 1 ;
37873858 }
37883859 else {
3789- if (R ) flip_vars (e );
3790- ccheck = subtype_in_env (xlb , yub , e );
3791- if (ccheck ) {
3792- flip_offset (e );
3793- ccheck = subtype_in_env (ylb , xub , e );
3794- flip_offset (e );
3795- }
3796- if (R ) flip_vars (e );
3860+ // try many subtype check to avoid false `Union{}`
3861+ ccheck = intersect_var_ccheck_in_env (xlb , xub , ylb , yub , e , R );
37973862 }
37983863 if (R ) flip_offset (e );
37993864 if (!ccheck )
0 commit comments