@@ -1069,7 +1069,8 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e);
10691069
10701070static int subtype_tuple_varargs (
10711071 jl_vararg_t * vtx , jl_vararg_t * vty ,
1072- size_t vx , size_t vy ,
1072+ jl_value_t * lastx , jl_value_t * lasty ,
1073+ size_t vx , size_t vy , size_t x_reps ,
10731074 jl_stenv_t * e , int param )
10741075{
10751076 jl_value_t * xp0 = jl_unwrap_vararg (vtx ); jl_value_t * xp1 = jl_unwrap_vararg_num (vtx );
@@ -1111,12 +1112,30 @@ static int subtype_tuple_varargs(
11111112 }
11121113 }
11131114 }
1114-
1115- // in Vararg{T1} <: Vararg{T2}, need to check subtype twice to
1116- // simulate the possibility of multiple arguments, which is needed
1117- // to implement the diagonal rule correctly.
1118- if (!subtype (xp0 , yp0 , e , param )) return 0 ;
1119- if (!subtype (xp0 , yp0 , e , 1 )) return 0 ;
1115+ int x_same = vx > 1 || (lastx && obviously_egal (xp0 , lastx ));
1116+ int y_same = vy > 1 || (lasty && obviously_egal (yp0 , lasty ));
1117+ // keep track of number of consecutive identical subtyping
1118+ x_reps = y_same && x_same ? x_reps + 1 : 1 ;
1119+ if (x_reps > 2 ) {
1120+ // an identical type on the left doesn't need to be compared to the same
1121+ // element type on the right more than twice.
1122+ }
1123+ else if (x_same && e -> Runions .depth == 0 && y_same &&
1124+ !jl_has_free_typevars (xp0 ) && !jl_has_free_typevars (yp0 )) {
1125+ // fast path for repeated elements
1126+ }
1127+ else if ((e -> Runions .depth == 0 ? !jl_has_free_typevars (xp0 ) : jl_is_concrete_type (xp0 )) && !jl_has_free_typevars (yp0 )) {
1128+ // fast path for separable sub-formulas
1129+ if (!jl_subtype (xp0 , yp0 ))
1130+ return 0 ;
1131+ }
1132+ else {
1133+ // in Vararg{T1} <: Vararg{T2}, need to check subtype twice to
1134+ // simulate the possibility of multiple arguments, which is needed
1135+ // to implement the diagonal rule correctly.
1136+ if (!subtype (xp0 , yp0 , e , param )) return 0 ;
1137+ if (x_reps < 2 && !subtype (xp0 , yp0 , e , 1 )) return 0 ;
1138+ }
11201139
11211140constrain_length :
11221141 if (!yp1 ) {
@@ -1246,7 +1265,8 @@ static int subtype_tuple_tail(jl_datatype_t *xd, jl_datatype_t *yd, int8_t R, jl
12461265 return subtype_tuple_varargs (
12471266 (jl_vararg_t * )xi ,
12481267 (jl_vararg_t * )yi ,
1249- vx , vy , e , param );
1268+ lastx , lasty ,
1269+ vx , vy , x_reps , e , param );
12501270 }
12511271
12521272 if (j >= ly )
@@ -1267,7 +1287,7 @@ static int subtype_tuple_tail(jl_datatype_t *xd, jl_datatype_t *yd, int8_t R, jl
12671287 (yi == lastx && !vx && vy && jl_is_concrete_type (xi )))) {
12681288 // fast path for repeated elements
12691289 }
1270- else if (e -> Runions .depth == 0 && !jl_has_free_typevars (xi ) && !jl_has_free_typevars (yi )) {
1290+ else if (( e -> Runions .depth == 0 ? !jl_has_free_typevars (xi ) : jl_is_concrete_type ( xi ) ) && !jl_has_free_typevars (yi )) {
12711291 // fast path for separable sub-formulas
12721292 if (!jl_subtype (xi , yi ))
12731293 return 0 ;
0 commit comments