@@ -1190,24 +1190,6 @@ static int subtype_tuple(jl_datatype_t *xd, jl_datatype_t *yd, jl_stenv_t *e, in
11901190 return ans ;
11911191}
11921192
1193- static int subtype_naked_vararg (jl_datatype_t * xd , jl_datatype_t * yd , jl_stenv_t * e , int param )
1194- {
1195- // Vararg: covariant in first parameter, invariant in second
1196- jl_value_t * xp1 = jl_unwrap_vararg (xd ), * xp2 = jl_unwrap_vararg_num (xd ), * yp1 = jl_unwrap_vararg (yd ), * yp2 = jl_unwrap_vararg_num (yd );
1197- // in Vararg{T1} <: Vararg{T2}, need to check subtype twice to
1198- // simulate the possibility of multiple arguments, which is needed
1199- // to implement the diagonal rule correctly.
1200- if (!subtype (xp1 , yp1 , e , param )) return 0 ;
1201- if (!subtype (xp1 , yp1 , e , 1 )) return 0 ;
1202- e -> invdepth ++ ;
1203- e -> Rinvdepth ++ ;
1204- // Vararg{T,N} <: Vararg{T2,N2}; equate N and N2
1205- int ans = forall_exists_equal (xp2 , yp2 , e );
1206- e -> invdepth -- ;
1207- e -> Rinvdepth -- ;
1208- return ans ;
1209- }
1210-
12111193// `param` means we are currently looking at a parameter of a type constructor
12121194// (as opposed to being outside any type constructor, or comparing variable bounds).
12131195// this is used to record the positions where type variables occur for the
@@ -1303,8 +1285,8 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param)
13031285 }
13041286 if (jl_is_unionall (y ))
13051287 return subtype_unionall (x , (jl_unionall_t * )y , e , 1 , param );
1306- if (( jl_is_datatype ( x ) || jl_is_vararg_type ( x )) &&
1307- (jl_is_datatype (y ) || jl_is_vararg_type ( y ) )) {
1288+ assert (! jl_is_vararg_marker ( x ) && ! jl_is_vararg_marker ( y ));
1289+ if (jl_is_datatype (x ) && jl_is_datatype ( y )) {
13081290 if (x == y ) return 1 ;
13091291 if (y == (jl_value_t * )jl_any_type ) return 1 ;
13101292 jl_datatype_t * xd = (jl_datatype_t * )x , * yd = (jl_datatype_t * )y ;
@@ -1334,15 +1316,6 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param)
13341316 e -> invdepth = saved ;
13351317 return issub ;
13361318 }
1337- if (jl_is_vararg_marker (xd )) {
1338- if (!jl_is_vararg_marker (yd ))
1339- return 0 ;
1340- // N.B.: This case is only used for raw varargs that are not part
1341- // of a tuple (those that are have special handling in subtype_tuple).
1342- // Vararg isn't really a proper type, but it does sometimes show up
1343- // as e.g. Type{Vararg}, so we'd like to handle that correctly.
1344- return subtype_naked_vararg (xd , yd , e , param );
1345- }
13461319 while (xd != jl_any_type && xd -> name != yd -> name ) {
13471320 if (xd -> super == NULL )
13481321 jl_errorf ("circular type parameter constraint in definition of %s" , jl_symbol_name (xd -> name -> name ));
@@ -2723,6 +2696,51 @@ static int intersect_vararg_length(jl_value_t *v, ssize_t n, jl_stenv_t *e, int8
27232696 return 1 ;
27242697}
27252698
2699+ static jl_value_t * intersect_invariant (jl_value_t * x , jl_value_t * y , jl_stenv_t * e );
2700+ static jl_value_t * intersect_varargs (jl_vararg_marker_t * vmx , jl_vararg_marker_t * vmy , jl_stenv_t * e , int param )
2701+ {
2702+ // Vararg: covariant in first parameter, invariant in second
2703+ jl_value_t * xp1 = jl_unwrap_vararg (vmx ), * xp2 = jl_unwrap_vararg_num (vmx ),
2704+ * yp1 = jl_unwrap_vararg (vmy ), * yp2 = jl_unwrap_vararg_num (vmy );
2705+ // in Vararg{T1} <: Vararg{T2}, need to check subtype twice to
2706+ // simulate the possibility of multiple arguments, which is needed
2707+ // to implement the diagonal rule correctly.
2708+ if (intersect (xp1 , yp1 , e , param == 0 ? 1 : param ) == jl_bottom_type )
2709+ return jl_bottom_type ;
2710+ jl_value_t * i2 = NULL , * ii = intersect (xp1 , yp1 , e , 1 );
2711+ if (ii == jl_bottom_type ) return jl_bottom_type ;
2712+ if (!xp2 && !yp2 )
2713+ return jl_wrap_vararg (ii , NULL );
2714+ JL_GC_PUSH2 (& ii , & i2 );
2715+ if (xp2 && jl_is_typevar (xp2 )) {
2716+ jl_varbinding_t * xb = lookup (e , (jl_tvar_t * )xp2 );
2717+ if (xb ) xb -> intvalued = 1 ;
2718+ if (!yp2 ) {
2719+ i2 = bound_var_below ((jl_tvar_t * )xp2 , xb , e );
2720+ }
2721+ }
2722+ if (yp2 && jl_is_typevar (yp2 )) {
2723+ jl_varbinding_t * yb = lookup (e , (jl_tvar_t * )yp2 );
2724+ if (yb ) yb -> intvalued = 1 ;
2725+ if (!xp2 ) {
2726+ i2 = bound_var_below ((jl_tvar_t * )yp2 , yb , e );
2727+ }
2728+ }
2729+ if (xp2 && yp2 ) {
2730+ // Vararg{T,N} <: Vararg{T2,N2}; equate N and N2
2731+ i2 = intersect_invariant (xp2 , yp2 , e );
2732+ if (i2 == NULL || i2 == jl_bottom_type || (jl_is_long (i2 ) && jl_unbox_long (i2 ) < 0 ) ||
2733+ !((jl_is_typevar (i2 ) && ((jl_tvar_t * )i2 )-> lb == jl_bottom_type &&
2734+ ((jl_tvar_t * )i2 )-> ub == (jl_value_t * )jl_any_type ) || jl_is_long (i2 ))) {
2735+ i2 = jl_bottom_type ;
2736+ }
2737+ }
2738+ ii = i2 == jl_bottom_type ? jl_bottom_type : jl_wrap_vararg (ii , i2 );
2739+ JL_GC_POP ();
2740+ return ii ;
2741+ }
2742+
2743+
27262744static jl_value_t * intersect_tuple (jl_datatype_t * xd , jl_datatype_t * yd , jl_stenv_t * e , int param )
27272745{
27282746 size_t lx = jl_nparams (xd ), ly = jl_nparams (yd );
@@ -2754,29 +2772,34 @@ static jl_value_t *intersect_tuple(jl_datatype_t *xd, jl_datatype_t *yd, jl_sten
27542772 res = (jl_value_t * )jl_apply_tuple_type_v (jl_svec_data (params ), i );
27552773 break ;
27562774 }
2757- if (vx && !vy )
2758- xi = jl_unwrap_vararg (xi );
2759- if (vy && !vx )
2760- yi = jl_unwrap_vararg (yi );
27612775 jl_varbinding_t * xb = NULL , * yb = NULL ;
2776+ jl_value_t * ii = NULL ;
27622777 if (vx && vy ) {
27632778 // {A^n...,Vararg{T,N}} ∩ {Vararg{S,M}} = {(A∩S)^n...,Vararg{T∩S,N}} plus N = M-n
2764- jl_value_t * xlen = jl_unwrap_vararg_num (jl_unwrap_unionall ( xi ) );
2779+ jl_value_t * xlen = jl_unwrap_vararg_num (xi );
27652780 if (xlen && jl_is_typevar (xlen )) {
27662781 xb = lookup (e , (jl_tvar_t * )xlen );
27672782 if (xb )
27682783 xb -> offset = ly - lx ;
27692784 }
2770- jl_value_t * ylen = jl_unwrap_vararg_num (jl_unwrap_unionall ( yi ) );
2785+ jl_value_t * ylen = jl_unwrap_vararg_num (yi );
27712786 if (ylen && jl_is_typevar (ylen )) {
27722787 yb = lookup (e , (jl_tvar_t * )ylen );
27732788 if (yb )
27742789 yb -> offset = lx - ly ;
27752790 }
2791+ ii = intersect_varargs ((jl_vararg_marker_t * )xi ,
2792+ (jl_vararg_marker_t * )yi ,
2793+ e , param );
2794+ if (xb ) xb -> offset = 0 ;
2795+ if (yb ) yb -> offset = 0 ;
2796+ } else {
2797+ if (vx )
2798+ xi = jl_unwrap_vararg (xi );
2799+ if (vy )
2800+ yi = jl_unwrap_vararg (yi );
2801+ ii = intersect (xi , yi , e , param == 0 ? 1 : param );
27762802 }
2777- jl_value_t * ii = intersect (xi , yi , e , param == 0 ? 1 : param );
2778- if (xb ) xb -> offset = 0 ;
2779- if (yb ) yb -> offset = 0 ;
27802803 if (ii == jl_bottom_type ) {
27812804 if (vx && vy ) {
27822805 int len = i > j ? i : j ;
@@ -3080,47 +3103,7 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa
30803103 }
30813104 if (jl_is_unionall (y ))
30823105 return intersect_unionall (x , (jl_unionall_t * )y , e , 1 , param );
3083- if (jl_is_vararg_marker (x ) && jl_is_vararg_marker (y )) {
3084- // Vararg: covariant in first parameter, invariant in second
3085- jl_value_t * xp1 = jl_unwrap_vararg (x ), * xp2 = jl_unwrap_vararg_num (x ),
3086- * yp1 = jl_unwrap_vararg (y ), * yp2 = jl_unwrap_vararg_num (y );
3087- // in Vararg{T1} <: Vararg{T2}, need to check subtype twice to
3088- // simulate the possibility of multiple arguments, which is needed
3089- // to implement the diagonal rule correctly.
3090- if (intersect (xp1 , yp1 , e , param == 0 ? 1 : param ) == jl_bottom_type )
3091- return jl_bottom_type ;
3092- jl_value_t * i2 = NULL , * ii = intersect (xp1 , yp1 , e , 1 );
3093- if (ii == jl_bottom_type ) return jl_bottom_type ;
3094- if (!xp2 && !yp2 )
3095- return jl_wrap_vararg (ii , NULL );
3096- JL_GC_PUSH2 (& ii , & i2 );
3097- if (xp2 && jl_is_typevar (xp2 )) {
3098- jl_varbinding_t * xb = lookup (e , (jl_tvar_t * )xp2 );
3099- if (xb ) xb -> intvalued = 1 ;
3100- if (!yp2 ) {
3101- i2 = bound_var_below ((jl_tvar_t * )xp2 , xb , e );
3102- }
3103- }
3104- if (yp2 && jl_is_typevar (yp2 )) {
3105- jl_varbinding_t * yb = lookup (e , (jl_tvar_t * )yp2 );
3106- if (yb ) yb -> intvalued = 1 ;
3107- if (!xp2 ) {
3108- i2 = bound_var_below ((jl_tvar_t * )yp2 , yb , e );
3109- }
3110- }
3111- if (xp2 && yp2 ) {
3112- // Vararg{T,N} <: Vararg{T2,N2}; equate N and N2
3113- i2 = intersect_invariant (xp2 , yp2 , e );
3114- if (i2 == NULL || i2 == jl_bottom_type || (jl_is_long (i2 ) && jl_unbox_long (i2 ) < 0 ) ||
3115- !((jl_is_typevar (i2 ) && ((jl_tvar_t * )i2 )-> lb == jl_bottom_type &&
3116- ((jl_tvar_t * )i2 )-> ub == (jl_value_t * )jl_any_type ) || jl_is_long (i2 ))) {
3117- i2 = jl_bottom_type ;
3118- }
3119- }
3120- ii = i2 == jl_bottom_type ? jl_bottom_type : jl_wrap_vararg (ii , i2 );
3121- JL_GC_POP ();
3122- return ii ;
3123- }
3106+ assert (!jl_is_vararg_marker (x ) && !jl_is_vararg_marker (y ));
31243107 if (jl_is_datatype (x ) && jl_is_datatype (y )) {
31253108 jl_datatype_t * xd = (jl_datatype_t * )x , * yd = (jl_datatype_t * )y ;
31263109 if (param < 2 ) {
0 commit comments