@@ -2217,48 +2217,6 @@ JL_DLLEXPORT jl_svec_t *jl_env_from_type_intersection(jl_value_t *a, jl_value_t
2217
2217
2218
2218
// specificity comparison
2219
2219
2220
- /*
2221
- Simplification of varargs tuple types:
2222
- JL_TUPLE_FIXED: tuples of known length (e.g., JL_VARARG_NONE or JL_VARARG_INT)
2223
- JL_TUPLE_VAR: tuples of unknown length (e.g., JL_VARARG_BOUND or JL_VARARG_UNBOUND)
2224
-
2225
- In some cases, JL_VARARG_BOUND tuples get described as JL_TUPLE_FIXED,
2226
- if the constraints on length are already known.
2227
-
2228
- lenr = "representation length" (the number of parameters)
2229
- lenf = "full length" (including the Vararg length, if known)
2230
-
2231
- In general, lenf >= lenr-1. The lower bound is achieved only for a Vararg of length 0.
2232
- */
2233
- typedef enum {
2234
- JL_TUPLE_FIXED = 0 ,
2235
- JL_TUPLE_VAR = 1
2236
- } jl_tuple_lenkind_t ;
2237
-
2238
- static size_t tuple_vararg_params (jl_svec_t * a , jl_vararg_kind_t * kind , jl_tuple_lenkind_t * lenkind )
2239
- {
2240
- jl_value_t * * data = jl_svec_data (a ); size_t lenr = jl_svec_len (a );
2241
- size_t lenf = lenr ;
2242
- if (lenr == 0 ) {
2243
- * kind = JL_VARARG_NONE ;
2244
- * lenkind = JL_TUPLE_FIXED ;
2245
- return lenf ;
2246
- }
2247
- * lenkind = JL_TUPLE_VAR ;
2248
- jl_value_t * last = data [lenr - 1 ];
2249
- * kind = jl_vararg_kind (last );
2250
- if (* kind == JL_VARARG_NONE || * kind == JL_VARARG_INT )
2251
- * lenkind = JL_TUPLE_FIXED ;
2252
- if (* kind == JL_VARARG_INT || * kind == JL_VARARG_BOUND ) {
2253
- jl_value_t * N = jl_tparam1 (jl_unwrap_unionall (last ));
2254
- if (jl_is_long (N )) {
2255
- lenf += jl_unbox_long (N )- 1 ;
2256
- * lenkind = JL_TUPLE_FIXED ;
2257
- }
2258
- }
2259
- return lenf ;
2260
- }
2261
-
2262
2220
static int eq_msp (jl_value_t * a , jl_value_t * b , jl_typeenv_t * env )
2263
2221
{
2264
2222
// equate ANY and Any for specificity purposes, #16153
@@ -2298,97 +2256,100 @@ static int type_morespecific_(jl_value_t *a, jl_value_t *b, int invariant, jl_ty
2298
2256
2299
2257
static int num_occurs (jl_tvar_t * v , jl_typeenv_t * env );
2300
2258
2259
+ static jl_value_t * nth_tuple_elt (jl_datatype_t * t , size_t i )
2260
+ {
2261
+ size_t len = jl_field_count (t );
2262
+ if (len == 0 )
2263
+ return NULL ;
2264
+ if (i < len - 1 )
2265
+ return jl_tparam (t , i );
2266
+ jl_value_t * last = jl_unwrap_unionall (jl_tparam (t , len - 1 ));
2267
+ if (jl_is_vararg_type (last )) {
2268
+ jl_value_t * n = jl_tparam1 (last );
2269
+ if (jl_is_long (n ) && i >= len - 1 + jl_unbox_long (n ))
2270
+ return NULL ;
2271
+ return jl_tparam0 (last );
2272
+ }
2273
+ if (i == len - 1 )
2274
+ return jl_tparam (t , i );
2275
+ return NULL ;
2276
+ }
2277
+
2301
2278
static int tuple_morespecific (jl_datatype_t * cdt , jl_datatype_t * pdt , int invariant , jl_typeenv_t * env )
2302
2279
{
2303
- size_t clenr = jl_nparams (cdt );
2304
- jl_value_t * * child = jl_svec_data (cdt -> parameters );
2305
2280
size_t plenr = jl_nparams (pdt );
2306
- jl_value_t * * parent = jl_svec_data (pdt -> parameters );
2307
- size_t plenf , clenf ;
2308
- jl_vararg_kind_t ckind , pkind ;
2309
- jl_tuple_lenkind_t clenkind , plenkind ;
2310
- clenf = tuple_vararg_params (cdt -> parameters , & ckind , & clenkind );
2311
- plenf = tuple_vararg_params (pdt -> parameters , & pkind , & plenkind );
2312
- size_t ci = 0 , pi = 0 ;
2313
- int cseq = 0 , pseq = 0 , cdiag = 0 , pdiag = 0 ;
2281
+ if (plenr == 0 ) return 0 ;
2282
+ size_t clenr = jl_nparams (cdt );
2283
+ if (clenr == 0 ) return 1 ;
2284
+ int i = 0 ;
2285
+ int cva = jl_vararg_kind (jl_tparam (cdt ,clenr - 1 )) > JL_VARARG_INT ;
2286
+ int pva = jl_vararg_kind (jl_tparam (pdt ,plenr - 1 )) > JL_VARARG_INT ;
2287
+ int cdiag = 0 , pdiag = 0 ;
2314
2288
int some_morespecific = 0 ;
2315
- jl_value_t * ce = NULL , * pe = NULL ;
2316
2289
while (1 ) {
2317
- if (!cseq )
2318
- cseq = (ci < clenr ) && clenkind != JL_TUPLE_FIXED && jl_is_vararg_type (child [ci ]);
2319
- if (!pseq )
2320
- pseq = (pi < plenr ) && plenkind != JL_TUPLE_FIXED && jl_is_vararg_type (parent [pi ]);
2321
-
2322
- if (ci >= clenf && !cseq ) {
2323
- if (pseq && plenr <= clenr + 1 ) return 1 ;
2324
- // shorter tuples are more specific, to ensure transitivity with varargs
2325
- if (!pseq && clenr < plenr ) return 1 ;
2326
- if (!pseq && clenr > plenr ) return 0 ;
2327
- break ;
2328
- }
2329
- if (pi >= plenf && !pseq ) {
2330
- if (!cseq && plenr < clenr && !some_morespecific ) return 0 ;
2331
- break ;
2332
- }
2290
+ if (cva && pva && i >= clenr && i >= plenr ) break ;
2291
+ jl_value_t * ce = nth_tuple_elt (cdt , i );
2292
+ jl_value_t * pe = nth_tuple_elt (pdt , i );
2333
2293
2334
- if (ci < clenr ) {
2335
- ce = child [ ci ] ;
2336
- if ( jl_is_vararg_type ( ce )) ce = jl_unwrap_vararg ( ce ) ;
2294
+ if (ce == NULL ) {
2295
+ if ( pe == NULL ) break ;
2296
+ return 1 ;
2337
2297
}
2338
- if (pi < plenr ) {
2339
- pe = parent [ pi ] ;
2340
- if ( jl_is_vararg_type ( pe )) pe = jl_unwrap_vararg ( pe ) ;
2298
+ if (pe == NULL ) {
2299
+ if (! cva && ! some_morespecific ) return 0 ;
2300
+ break ;
2341
2301
}
2342
-
2343
2302
if (type_morespecific_ (pe , ce , invariant , env )) {
2344
2303
assert (!type_morespecific_ (ce , pe , invariant , env ));
2345
2304
return 0 ;
2346
2305
}
2347
-
2348
2306
if (!cdiag && jl_is_typevar (ce ) && num_occurs ((jl_tvar_t * )ce ,env ) > 1 )
2349
2307
cdiag = 1 ;
2350
2308
if (!pdiag && jl_is_typevar (pe ) && num_occurs ((jl_tvar_t * )pe ,env ) > 1 )
2351
2309
pdiag = 1 ;
2352
2310
2353
2311
// in Tuple{a,b...} and Tuple{c,d...} allow b and d to be disjoint
2354
- if (cseq && pseq && (some_morespecific || (cdiag && !pdiag ))) return 1 ;
2312
+ if (cva && pva && i >= clenr - 1 && i >= plenr - 1 && (some_morespecific || (cdiag && !pdiag ))) return 1 ;
2355
2313
2356
2314
int cms = type_morespecific_ (ce , pe , invariant , env );
2357
2315
int eqv = !cms && eq_msp (ce , pe , env );
2358
2316
2359
2317
if (!cms && !eqv ) return 0 ;
2360
2318
2361
2319
if (cms ) some_morespecific = 1 ;
2362
-
2363
- if (cms && ci == clenr - 1 && pi == plenr - 1 && clenr == plenr && !cseq && pseq ) {
2364
- // make Vararg{X, 1} more specific than Vararg{X, N}
2365
- if (jl_is_vararg_type (child [ci ]) && eqv )
2366
- return 1 ;
2367
- }
2368
-
2369
- if (cseq && pseq ) {
2370
- if (clenr > plenr && (!pdiag || cdiag ))
2371
- return 1 ;
2372
- break ;
2373
- }
2374
- ci ++ ;
2375
- pi ++ ;
2320
+ i ++ ;
2376
2321
}
2322
+ if (cva && pva && clenr > plenr && (!pdiag || cdiag ))
2323
+ return 1 ;
2377
2324
return some_morespecific || (cdiag && !pdiag );
2378
2325
}
2379
2326
2327
+ static size_t tuple_full_length (jl_value_t * t )
2328
+ {
2329
+ size_t n = jl_nparams (t );
2330
+ if (n == 0 ) return 0 ;
2331
+ jl_value_t * last = jl_unwrap_unionall (jl_tparam (t ,n - 1 ));
2332
+ if (jl_is_vararg_type (last )) {
2333
+ jl_value_t * N = jl_tparam1 (last );
2334
+ if (jl_is_long (N ))
2335
+ n += jl_unbox_long (N )- 1 ;
2336
+ }
2337
+ return n ;
2338
+ }
2339
+
2380
2340
// Called when a is a bound-vararg and b is not a vararg. Sets the vararg length
2381
2341
// in a to match b, as long as this makes some earlier argument more specific.
2382
2342
static int args_morespecific_fix1 (jl_value_t * a , jl_value_t * b , int swap , jl_typeenv_t * env )
2383
2343
{
2384
2344
size_t n = jl_nparams (a );
2385
- int nfix = jl_nparams (b )- n + 1 ;
2386
- assert (jl_is_va_tuple (a ));
2387
- assert (nfix >= 0 );
2345
+ int nfix = tuple_full_length (b )- n + 1 ;
2346
+ if (nfix <= 0 )
2347
+ return -1 ;
2348
+ assert (jl_is_va_tuple ((jl_datatype_t * )a ));
2388
2349
jl_datatype_t * newtta = NULL ;
2389
- jl_value_t * env [2 ] = { jl_tparam1 (jl_unwrap_unionall (jl_tparam (a , n - 1 ))), jl_box_long (nfix ) };
2390
- JL_GC_PUSH2 (& newtta , & env [1 ]);
2391
- newtta = (jl_datatype_t * )jl_instantiate_type_with ((jl_value_t * )a , env , 1 );
2350
+ jl_value_t * e [2 ] = { jl_tparam1 (jl_unwrap_unionall (jl_tparam (a , n - 1 ))), jl_box_long (nfix ) };
2351
+ JL_GC_PUSH2 (& newtta , & e [1 ]);
2352
+ newtta = (jl_datatype_t * )jl_instantiate_type_with ((jl_value_t * )a , e , 1 );
2392
2353
int changed = 0 ;
2393
2354
for (size_t i = 0 ; i < n - 1 ; i ++ ) {
2394
2355
if (jl_tparam (a , i ) != jl_tparam (newtta , i )) {
@@ -2473,19 +2434,14 @@ static int type_morespecific_(jl_value_t *a, jl_value_t *b, int invariant, jl_ty
2473
2434
}
2474
2435
2475
2436
if (jl_is_tuple_type (a ) && jl_is_tuple_type (b )) {
2476
- jl_datatype_t * tta = (jl_datatype_t * )a ;
2477
- jl_datatype_t * ttb = (jl_datatype_t * )b ;
2478
- size_t alenf , blenf ;
2479
- jl_vararg_kind_t akind , bkind ;
2480
- jl_tuple_lenkind_t alenkind , blenkind ;
2481
- alenf = tuple_vararg_params (tta -> parameters , & akind , & alenkind );
2482
- blenf = tuple_vararg_params (ttb -> parameters , & bkind , & blenkind );
2483
2437
// When one is JL_VARARG_BOUND and the other has fixed length,
2484
2438
// allow the argument length to fix the tvar
2439
+ jl_vararg_kind_t ak = jl_va_tuple_kind ((jl_datatype_t * )a );
2440
+ jl_vararg_kind_t bk = jl_va_tuple_kind ((jl_datatype_t * )b );
2485
2441
int ans = -1 ;
2486
- if (akind == JL_VARARG_BOUND && blenkind == JL_TUPLE_FIXED && blenf >= alenf )
2442
+ if (ak == JL_VARARG_BOUND && bk < JL_VARARG_BOUND )
2487
2443
ans = args_morespecific_fix1 (a , b , 0 , env );
2488
- if (bkind == JL_VARARG_BOUND && alenkind == JL_TUPLE_FIXED && alenf >= blenf )
2444
+ if (bk == JL_VARARG_BOUND && ak < JL_VARARG_BOUND )
2489
2445
ans = args_morespecific_fix1 (b , a , 1 , env );
2490
2446
if (ans != -1 ) return ans ;
2491
2447
return tuple_morespecific ((jl_datatype_t * )a , (jl_datatype_t * )b , invariant , env );
0 commit comments