@@ -1012,7 +1012,8 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e);
1012
1012
1013
1013
static int subtype_tuple_varargs (
1014
1014
jl_vararg_t * vtx , jl_vararg_t * vty ,
1015
- size_t vx , size_t vy ,
1015
+ jl_value_t * lastx , jl_value_t * lasty ,
1016
+ size_t vx , size_t vy , size_t x_reps ,
1016
1017
jl_stenv_t * e , int param )
1017
1018
{
1018
1019
jl_value_t * xp0 = jl_unwrap_vararg (vtx ); jl_value_t * xp1 = jl_unwrap_vararg_num (vtx );
@@ -1063,12 +1064,30 @@ static int subtype_tuple_varargs(
1063
1064
}
1064
1065
}
1065
1066
}
1066
-
1067
- // in Vararg{T1} <: Vararg{T2}, need to check subtype twice to
1068
- // simulate the possibility of multiple arguments, which is needed
1069
- // to implement the diagonal rule correctly.
1070
- if (!subtype (xp0 , yp0 , e , param )) return 0 ;
1071
- if (!subtype (xp0 , yp0 , e , 1 )) return 0 ;
1067
+ int x_same = vx > 1 || (lastx && obviously_egal (xp0 , lastx ));
1068
+ int y_same = vy > 1 || (lasty && obviously_egal (yp0 , lasty ));
1069
+ // keep track of number of consecutive identical subtyping
1070
+ x_reps = y_same && x_same ? x_reps + 1 : 1 ;
1071
+ if (x_reps > 2 ) {
1072
+ // an identical type on the left doesn't need to be compared to the same
1073
+ // element type on the right more than twice.
1074
+ }
1075
+ else if (x_same && e -> Runions .depth == 0 && y_same &&
1076
+ !jl_has_free_typevars (xp0 ) && !jl_has_free_typevars (yp0 )) {
1077
+ // fast path for repeated elements
1078
+ }
1079
+ else if ((e -> Runions .depth == 0 ? !jl_has_free_typevars (xp0 ) : jl_is_concrete_type (xp0 )) && !jl_has_free_typevars (yp0 )) {
1080
+ // fast path for separable sub-formulas
1081
+ if (!jl_subtype (xp0 , yp0 ))
1082
+ return 0 ;
1083
+ }
1084
+ else {
1085
+ // in Vararg{T1} <: Vararg{T2}, need to check subtype twice to
1086
+ // simulate the possibility of multiple arguments, which is needed
1087
+ // to implement the diagonal rule correctly.
1088
+ if (!subtype (xp0 , yp0 , e , param )) return 0 ;
1089
+ if (x_reps < 2 && !subtype (xp0 , yp0 , e , 1 )) return 0 ;
1090
+ }
1072
1091
1073
1092
constrain_length :
1074
1093
if (!yp1 ) {
@@ -1192,7 +1211,8 @@ static int subtype_tuple_tail(jl_datatype_t *xd, jl_datatype_t *yd, int8_t R, jl
1192
1211
return subtype_tuple_varargs (
1193
1212
(jl_vararg_t * )xi ,
1194
1213
(jl_vararg_t * )yi ,
1195
- vx , vy , e , param );
1214
+ lastx , lasty ,
1215
+ vx , vy , x_reps , e , param );
1196
1216
}
1197
1217
1198
1218
if (j >= ly )
@@ -1213,7 +1233,7 @@ static int subtype_tuple_tail(jl_datatype_t *xd, jl_datatype_t *yd, int8_t R, jl
1213
1233
(yi == lastx && !vx && vy && jl_is_concrete_type (xi )))) {
1214
1234
// fast path for repeated elements
1215
1235
}
1216
- else if (e -> Runions .depth == 0 && !jl_has_free_typevars (xi ) && !jl_has_free_typevars (yi )) {
1236
+ else if (( e -> Runions .depth == 0 ? !jl_has_free_typevars (xi ) : jl_is_concrete_type ( xi ) ) && !jl_has_free_typevars (yi )) {
1217
1237
// fast path for separable sub-formulas
1218
1238
if (!jl_subtype (xi , yi ))
1219
1239
return 0 ;
0 commit comments