@@ -708,16 +708,37 @@ static int var_occurs_invariant(jl_value_t *v, jl_tvar_t *var, int inv) JL_NOTSA
708
708
return var_occurs_inside (v , var , 0 , 1 );
709
709
}
710
710
711
- static int with_tvar ( tvar_callback callback , void * context , jl_unionall_t * u , int8_t R , jl_stenv_t * e , int param )
711
+ static jl_unionall_t * unalias_unionall ( jl_unionall_t * u , jl_stenv_t * e )
712
712
{
713
+ jl_varbinding_t * btemp = e -> vars ;
714
+ // if the var for this unionall (based on identity) already appears somewhere
715
+ // in the environment, rename to get a fresh var.
716
+ JL_GC_PUSH1 (& u );
717
+ while (btemp != NULL ) {
718
+ if (btemp -> var == u -> var ||
719
+ // outer var can only refer to inner var if bounds changed
720
+ (btemp -> lb != btemp -> var -> lb && jl_has_typevar (btemp -> lb , u -> var )) ||
721
+ (btemp -> ub != btemp -> var -> ub && jl_has_typevar (btemp -> ub , u -> var ))) {
722
+ u = rename_unionall (u );
723
+ break ;
724
+ }
725
+ btemp = btemp -> prev ;
726
+ }
727
+ JL_GC_POP ();
728
+ return u ;
729
+ }
730
+
731
+ static int subtype_unionall (jl_value_t * t , jl_unionall_t * u , jl_stenv_t * e , int8_t R , int param )
732
+ {
733
+ u = unalias_unionall (u , e );
713
734
jl_varbinding_t vb = { u -> var , u -> var -> lb , u -> var -> ub , R , 0 , 0 , 0 , 0 ,
714
735
R ? e -> Rinvdepth : e -> invdepth , 0 , NULL , 0 , e -> vars };
715
736
JL_GC_PUSH4 (& u , & vb .lb , & vb .ub , & vb .innervars );
716
737
e -> vars = & vb ;
717
738
int ans ;
718
739
if (R ) {
719
740
e -> envidx ++ ;
720
- ans = callback ( context , R , e , param );
741
+ ans = subtype ( t , u -> body , e , param );
721
742
e -> envidx -- ;
722
743
// widen Type{x} to typeof(x) in argument position
723
744
if (!vb .occurs_inv )
@@ -750,7 +771,8 @@ static int with_tvar(tvar_callback callback, void *context, jl_unionall_t *u, in
750
771
}
751
772
}
752
773
else {
753
- ans = callback (context , R , e , param );
774
+ ans = R ? subtype (t , u -> body , e , param ) :
775
+ subtype (u -> body , t , e , param );
754
776
}
755
777
756
778
// handle the "diagonal dispatch" rule, which says that a type var occurring more
@@ -802,53 +824,6 @@ static int with_tvar(tvar_callback callback, void *context, jl_unionall_t *u, in
802
824
return ans ;
803
825
}
804
826
805
- static jl_unionall_t * unalias_unionall (jl_unionall_t * u , jl_stenv_t * e )
806
- {
807
- jl_varbinding_t * btemp = e -> vars ;
808
- // if the var for this unionall (based on identity) already appears somewhere
809
- // in the environment, rename to get a fresh var.
810
- JL_GC_PUSH1 (& u );
811
- while (btemp != NULL ) {
812
- if (btemp -> var == u -> var ||
813
- // outer var can only refer to inner var if bounds changed
814
- (btemp -> lb != btemp -> var -> lb && jl_has_typevar (btemp -> lb , u -> var )) ||
815
- (btemp -> ub != btemp -> var -> ub && jl_has_typevar (btemp -> ub , u -> var ))) {
816
- u = rename_unionall (u );
817
- break ;
818
- }
819
- btemp = btemp -> prev ;
820
- }
821
- JL_GC_POP ();
822
- return u ;
823
- }
824
-
825
- struct subtype_unionall_env {
826
- jl_value_t * t ;
827
- jl_value_t * ubody ;
828
- };
829
-
830
- static int subtype_unionall_callback (struct subtype_unionall_env * env , int8_t R , jl_stenv_t * s , int param ) {
831
- JL_GC_PROMISE_ROOTED (env -> t );
832
- JL_GC_PROMISE_ROOTED (env -> ubody );
833
- if (R ) {
834
- return subtype (env -> t , env -> ubody , s , param );
835
- }
836
- else {
837
- return subtype (env -> ubody , env -> t , s , param );
838
- }
839
- }
840
-
841
- // compare UnionAll type `u` to `t`. `R==1` if `u` came from the right side of A <: B.
842
- static int subtype_unionall (jl_value_t * t , jl_unionall_t * u , jl_stenv_t * e , int8_t R , int param )
843
- {
844
- u = unalias_unionall (u , e );
845
- struct subtype_unionall_env env = {t , u -> body };
846
- JL_GC_PUSH1 (& u );
847
- int res = with_tvar ((tvar_callback )subtype_unionall_callback , (void * )& env , u , R , e , param );
848
- JL_GC_POP ();
849
- return res ;
850
- }
851
-
852
827
// check n <: (length of vararg type v)
853
828
static int check_vararg_length (jl_value_t * v , ssize_t n , jl_stenv_t * e )
854
829
{
@@ -1004,21 +979,7 @@ static int subtype_tuple_tail(struct subtype_tuple_env *env, int8_t R, jl_stenv_
1004
979
if (env -> i == env -> lx - 1 && env -> vvx ) {
1005
980
if (!env -> vtx ) {
1006
981
xi = jl_tparam (env -> xd , env -> i );
1007
- // Unbounded vararg on the LHS without vararg on the RHS should
1008
- // have been caught earlier.
1009
- assert (env -> vvy || !jl_is_unionall (xi ));
1010
- if (jl_is_unionall (xi )) {
1011
- // TODO: If !var_occurs_inside(jl_tparam0(xid), p1, 0, 1),
1012
- // we could avoid introducing the tvar into the environment
1013
- jl_unionall_t * u = (jl_unionall_t * )xi ;
1014
- u = unalias_unionall (u , e );
1015
- env -> vtx = (jl_value_t * )u ;
1016
- // goto loop, but with the tvar introduced
1017
- JL_GC_PUSH1 (& u );
1018
- int res = with_tvar ((tvar_callback )subtype_tuple_tail , env , u , 0 , e , param );
1019
- JL_GC_POP ();
1020
- return res ;
1021
- }
982
+ assert (jl_is_vararg (xi ));
1022
983
env -> vtx = xi ;
1023
984
}
1024
985
xi = env -> vtx ;
@@ -1032,16 +993,7 @@ static int subtype_tuple_tail(struct subtype_tuple_env *env, int8_t R, jl_stenv_
1032
993
if (env -> j == env -> ly - 1 && env -> vvy ) {
1033
994
if (!env -> vty ) {
1034
995
yi = jl_tparam (env -> yd , env -> j );
1035
- if (jl_is_unionall (yi )) {
1036
- jl_unionall_t * u = (jl_unionall_t * )yi ;
1037
- u = unalias_unionall (u , e );
1038
- env -> vty = (jl_value_t * )u ;
1039
- // goto loop, but with the tvar introduced
1040
- JL_GC_PUSH1 (& u );
1041
- int res = with_tvar ((tvar_callback )subtype_tuple_tail , env , u , 1 , e , param );
1042
- JL_GC_POP ();
1043
- return res ;
1044
- }
996
+ assert (jl_is_vararg (yi ));
1045
997
env -> vty = yi ;
1046
998
}
1047
999
yi = env -> vty ;
0 commit comments