Skip to content

Commit b207c01

Browse files
JeffBezansonvtjnash
authored andcommitted
clean up implementation of ml_matches_visitor a bit (#31358)
Simplifies the code flow a little, and avoids computing a type intersection that we only used for `include_ambiguous`, which is not the common case.
1 parent 58a0016 commit b207c01

File tree

1 file changed

+48
-52
lines changed

1 file changed

+48
-52
lines changed

src/gf.c

+48-52
Original file line numberDiff line numberDiff line change
@@ -2477,7 +2477,7 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio
24772477
// for intersect(A, B) even though A is a dispatch tuple and !(A <: B).
24782478
// For dispatch purposes in such a case we know there's no match. This check
24792479
// fixes issue #30394.
2480-
if (jl_is_dispatch_tupletype(closure->match.type) && !closure->match.issubty)
2480+
if (!closure->match.issubty && jl_is_dispatch_tupletype(closure->match.type))
24812481
return 1;
24822482
// a method is shadowed if type <: S <: m->sig where S is the
24832483
// signature of another applicable method
@@ -2487,7 +2487,6 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio
24872487
*/
24882488
jl_method_t *meth = ml->func.method;
24892489
assert(meth);
2490-
int skip = 0;
24912490
size_t len = jl_array_len(closure->t);
24922491
if (closure->lim >= 0) {
24932492
// we can skip this match if the types are already covered
@@ -2499,72 +2498,69 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio
24992498
// but we still need it in case an intersection was approximate.
25002499
if (jl_is_datatype(prior_ti) && ((jl_datatype_t*)prior_ti)->isdispatchtuple &&
25012500
jl_subtype(closure->match.ti, prior_ti)) {
2502-
skip = 1;
2503-
break;
2501+
return 1;
25042502
}
25052503
}
25062504
}
2507-
if (!skip) {
2508-
int done = closure0->issubty; // stop; signature fully covers queried type
2509-
// if we reach a definition that fully covers the arguments but there are
2510-
// ambiguities, then this method might not actually match, so we shouldn't
2511-
// add it to the results.
2512-
int return_this_match = 1;
2513-
if (meth->ambig != jl_nothing && (!closure->include_ambiguous || done)) {
2514-
jl_svec_t *env = NULL;
2515-
jl_value_t *mti = NULL;
2516-
JL_GC_PUSH2(&env, &mti);
2517-
for (size_t j = 0; j < jl_array_len(meth->ambig); j++) {
2518-
jl_method_t *mambig = (jl_method_t*)jl_array_ptr_ref(meth->ambig, j);
2505+
int done = closure0->issubty; // stop; signature fully covers queried type
2506+
// if we reach a definition that fully covers the arguments but there are
2507+
// ambiguities, then this method might not actually match, so we shouldn't
2508+
// add it to the results.
2509+
int return_this_match = 1;
2510+
if (meth->ambig != jl_nothing && (!closure->include_ambiguous || done)) {
2511+
jl_svec_t *env = NULL;
2512+
jl_value_t *mti = NULL;
2513+
JL_GC_PUSH2(&env, &mti);
2514+
for (size_t j = 0; j < jl_array_len(meth->ambig); j++) {
2515+
jl_method_t *mambig = (jl_method_t*)jl_array_ptr_ref(meth->ambig, j);
2516+
if (closure->include_ambiguous) {
25192517
env = jl_emptysvec;
25202518
mti = jl_type_intersection_env((jl_value_t*)closure->match.type,
25212519
(jl_value_t*)mambig->sig, &env);
25222520
if (mti != (jl_value_t*)jl_bottom_type) {
2523-
if (closure->include_ambiguous) {
2524-
assert(done);
2525-
int k;
2526-
for (k = 0; k < len; k++) {
2527-
if ((jl_value_t*)mambig == jl_svecref(jl_array_ptr_ref(closure->t, k), 2))
2528-
break;
2529-
}
2530-
if (k >= len) {
2531-
if (len == 0) {
2532-
closure->t = (jl_value_t*)jl_alloc_vec_any(0);
2533-
}
2534-
mti = (jl_value_t*)jl_svec(3, mti, env, mambig);
2535-
jl_array_ptr_1d_push((jl_array_t*)closure->t, mti);
2536-
len++;
2537-
}
2538-
}
2539-
else {
2540-
// the current method definitely never matches if the intersection with this method
2541-
// is also fully covered by an ambiguous method's signature
2542-
if (jl_subtype(closure->match.ti, mambig->sig)) {
2543-
return_this_match = 0;
2521+
assert(done);
2522+
int k;
2523+
for (k = 0; k < len; k++) {
2524+
if ((jl_value_t*)mambig == jl_svecref(jl_array_ptr_ref(closure->t, k), 2))
25442525
break;
2526+
}
2527+
if (k >= len) {
2528+
if (len == 0) {
2529+
closure->t = (jl_value_t*)jl_alloc_vec_any(0);
25452530
}
2531+
mti = (jl_value_t*)jl_svec(3, mti, env, mambig);
2532+
jl_array_ptr_1d_push((jl_array_t*)closure->t, mti);
2533+
len++;
25462534
}
25472535
}
25482536
}
2549-
JL_GC_POP();
2550-
}
2551-
if (return_this_match) {
2552-
if (closure->lim >= 0 && len >= closure->lim) {
2553-
closure->t = (jl_value_t*)jl_false;
2554-
return 0; // terminate search
2555-
}
2556-
closure->matc = jl_svec(3, closure->match.ti, closure->match.env, meth);
2557-
if (len == 0) {
2558-
closure->t = (jl_value_t*)jl_alloc_vec_any(1);
2559-
jl_array_ptr_set(closure->t, 0, (jl_value_t*)closure->matc);
2560-
}
25612537
else {
2562-
jl_array_ptr_1d_push((jl_array_t*)closure->t, (jl_value_t*)closure->matc);
2538+
// the current method definitely never matches if the intersection with this method
2539+
// is also fully covered by an ambiguous method's signature
2540+
if (jl_subtype(closure->match.ti, mambig->sig)) {
2541+
return_this_match = 0;
2542+
break;
2543+
}
25632544
}
25642545
}
2565-
if (done)
2566-
return 0;
2546+
JL_GC_POP();
2547+
}
2548+
if (return_this_match) {
2549+
if (closure->lim >= 0 && len >= closure->lim) {
2550+
closure->t = (jl_value_t*)jl_false;
2551+
return 0; // terminate search
2552+
}
2553+
closure->matc = jl_svec(3, closure->match.ti, closure->match.env, meth);
2554+
if (len == 0) {
2555+
closure->t = (jl_value_t*)jl_alloc_vec_any(1);
2556+
jl_array_ptr_set(closure->t, 0, (jl_value_t*)closure->matc);
2557+
}
2558+
else {
2559+
jl_array_ptr_1d_push((jl_array_t*)closure->t, (jl_value_t*)closure->matc);
2560+
}
25672561
}
2562+
if (done)
2563+
return 0;
25682564
return 1;
25692565
}
25702566

0 commit comments

Comments
 (0)