Skip to content

Commit a947044

Browse files
committed
add function to compute the type of the vararg variable in a method signature
ref #16159 ref #12783
1 parent bcd0c13 commit a947044

File tree

2 files changed

+53
-9
lines changed

2 files changed

+53
-9
lines changed

src/gf.c

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -307,18 +307,63 @@ jl_value_t *jl_nth_slot_type(jl_tupletype_t *sig, size_t i)
307307
return NULL;
308308
}
309309

310+
// compute the type of the Vararg variable of a Vararg signature
311+
jl_tupletype_t *jl_compute_vararg_type(jl_tupletype_t *tt, int nreq)
312+
{
313+
size_t i, np = jl_nparams(tt);
314+
jl_svec_t *p = jl_alloc_svec(np - nreq);
315+
JL_GC_PUSH1(&p);
316+
for (i = nreq; i < np; i++) {
317+
jl_value_t *elt = jl_svecref(tt->parameters, i);
318+
jl_value_t *va_N = NULL;
319+
jl_svecset(p, i - nreq, elt);
320+
if (jl_is_vararg_type(elt)) {
321+
va_N = jl_tparam1(elt);
322+
elt = jl_tparam0(elt);
323+
}
324+
if (jl_is_type_type(elt)) {
325+
elt = jl_typeof(jl_tparam0(elt));
326+
if (elt == (jl_value_t*)jl_tvar_type)
327+
elt = (jl_value_t*)jl_type_type;
328+
if (va_N)
329+
elt = (jl_value_t*)jl_wrap_vararg(elt, va_N);
330+
jl_svecset(p, i - nreq, elt);
331+
}
332+
assert(elt != (jl_value_t*)jl_tvar_type);
333+
}
334+
tt = jl_apply_tuple_type(p);
335+
JL_GC_POP();
336+
return tt;
337+
}
338+
310339
// after intersection, the argument tuple type needs to be corrected to reflect the signature match
311340
// that occurred, if the arguments contained a Type but the signature matched on the kind
312341
static jl_tupletype_t *join_tsig(jl_tupletype_t *tt, jl_tupletype_t *sig)
313342
{
343+
size_t i, n, np = jl_nparams(tt), nsig = jl_datatype_nfields(sig);
344+
if (nsig == 0)
345+
return tt;
314346
jl_svec_t *newparams = NULL;
315347
JL_GC_PUSH1(&newparams);
316-
int changed = 0;
317-
size_t i, np;
318-
for (i = 0, np = jl_nparams(tt); i < np; i++) {
319-
jl_value_t *elt = jl_tparam(tt, i);
348+
jl_value_t *va = jl_tparam(sig, nsig - 1);
349+
if (va && jl_is_vararg_type(va)) {
350+
va = jl_tparam0(va);
351+
n = nsig - 1;
352+
assert(np >= n);
353+
}
354+
else {
355+
va = NULL;
356+
n = nsig;
357+
assert(np == nsig);
358+
}
359+
for (i = 0; i < np; i++) {
320360
jl_value_t *newelt = NULL;
321-
jl_value_t *decl_i = jl_nth_slot_type(sig, i);
361+
jl_value_t *elt = jl_tparam(tt, i);
362+
jl_value_t *decl_i;
363+
if (va == NULL || i < n)
364+
decl_i = jl_tparam(sig, i);
365+
else
366+
decl_i = va;
322367

323368
if (jl_is_type_type(elt)) {
324369
// if the declared type was not Any or Union{Type, ...},
@@ -343,14 +388,12 @@ static jl_tupletype_t *join_tsig(jl_tupletype_t *tt, jl_tupletype_t *sig)
343388
}
344389
// prepare to build a new type with the replacement above
345390
if (newelt) {
346-
if (!changed) {
391+
if (newparams == NULL)
347392
newparams = jl_svec_copy(tt->parameters);
348-
changed = 1;
349-
}
350393
jl_svecset(newparams, i, newelt);
351394
}
352395
}
353-
if (changed)
396+
if (newparams)
354397
tt = jl_apply_tuple_type(newparams);
355398
JL_GC_POP();
356399
return tt;

src/julia_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ jl_expr_t *jl_lam_body(jl_expr_t *l);
223223
jl_value_t *jl_first_argument_datatype(jl_value_t *argtypes);
224224
int jl_has_intrinsics(jl_lambda_info_t *li, jl_value_t *v, jl_module_t *m);
225225

226+
jl_tupletype_t *jl_compute_vararg_type(jl_tupletype_t *tt, int nreq);
226227
jl_value_t *jl_nth_slot_type(jl_tupletype_t *sig, size_t i);
227228
void jl_compute_field_offsets(jl_datatype_t *st);
228229
jl_array_t *jl_new_array_for_deserialization(jl_value_t *atype, uint32_t ndims, size_t *dims,

0 commit comments

Comments
 (0)