I had a brief look through the source code, and it indeed looks like arguments are considered independently when determining specificity.
My reading of the source code involved a lot of educated guessing, so here’s my reasoning in case anyone wants to double-check:
-
According to the dev docs,
jl_type_morespecific(a,b)
is the function which determines method specificity. -
This function first does a couple of checks that AFAICT don’t apply to our case, and then calls
type_morespecific()
.JL_DLLEXPORT int jl_type_morespecific(jl_value_t *a, jl_value_t *b) { if (obviously_disjoint(a, b, 1)) return 0; if (jl_has_free_typevars(a) || jl_has_free_typevars(b)) return 0; if (jl_subtype(b, a)) return 0; if (jl_subtype(a, b)) return 1; return type_morespecific_(a, b, a, b, 0, NULL); }
-
Both inputs are tuples, so
type_morespecific()
dispatches totuple_morespecific()
:static int type_morespecific_(jl_value_t *a, jl_value_t *b, jl_value_t *a0, jl_value_t *b0, int invariant, jl_typeenv_t *env) { # ... if (jl_is_tuple_type(a) && jl_is_tuple_type(b)) { # ... return tuple_morespecific((jl_datatype_t*)a, (jl_datatype_t*)b, a0, b0, invariant, env); } # ... }
-
tuple_morespecific()
is quite complicated, but most of the decision-making seems to be based on a variable calledsome_morespecific
, which to me sounds a lot like we’re checking whether some of the elements in the first tuple are more specific than their counterparts in the second tuple.