Skip to content

Commit afe784a

Browse files
committed
re-disable isambiguous test when type-intersection fails
Removes a part of #36962 that was the source of major ire by several users: This restores some abort code paths that I had put in place to cause isambiguous to return incorrect answers in this particular case. Even though the underlying algorithm can now deal with these cases correctly, users were not pleased that the algorithm was now handling these cases correctly and attacked with gusto. Additionally, it fixes a performance bug in ml-matches, where I'd accidentally set two flags in the wrong direction, which were still conservatively correct, but prevented us from using the fast path.
1 parent 51592ab commit afe784a

File tree

5 files changed

+31
-152
lines changed

5 files changed

+31
-152
lines changed

base/reflection.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1462,7 +1462,12 @@ function isambiguous(m1::Method, m2::Method; ambiguous_bottom::Bool=false)
14621462
if ti2 <: m1.sig && ti2 <: m2.sig
14631463
ti = ti2
14641464
elseif ti != ti2
1465-
inner(ti2) || return false
1465+
# TODO: this would be the correct way to handle this case, but
1466+
# people complained so we don't do it
1467+
# inner(ti2) || return false
1468+
return false # report that the type system failed to decide if it was ambiguous by saying they definitely aren't
1469+
else
1470+
return false # report that the type system failed to decide if it was ambiguous by saying they definitely aren't
14661471
end
14671472
end
14681473
inner(ti) || return false

src/gf.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,7 @@ static int jl_type_intersection2(jl_value_t *t1, jl_value_t *t2, jl_value_t **is
15571557
*isect = jl_type_intersection(t1, t2);
15581558
if (*isect == jl_bottom_type)
15591559
return 0;
1560+
// determine if type-intersection can be convinced to give a better, non-bad answer
15601561
if (!(jl_subtype(*isect, t1) && jl_subtype(*isect, t2))) {
15611562
// if the intersection was imprecise, see if we can do
15621563
// better by switching the types
@@ -2759,7 +2760,7 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, int offs,
27592760
if (!all_subtypes && minmax != NULL && !minmax_ambig) {
27602761
jl_method_t *minmaxm = minmax->method;
27612762
if (!include_ambiguous)
2762-
all_subtypes = 0;
2763+
all_subtypes = 1;
27632764
for (i = 0; i < len; i++) {
27642765
jl_method_match_t *matc = (jl_method_match_t*)jl_array_ptr_ref(env.t, i);
27652766
if (matc->fully_covers != FULLY_COVERS) {
@@ -2893,23 +2894,26 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, int offs,
28932894
jl_type_intersection2((jl_value_t*)matc->spec_types, (jl_value_t*)matc2->spec_types, &env.match.ti, &isect2);
28942895
ti = env.match.ti;
28952896
}
2896-
if (ti != jl_bottom_type && !jl_type_morespecific((jl_value_t*)m2->sig, (jl_value_t*)m->sig)) {
2897-
// m and m2 are ambiguous, but let's see if we can find another method (m3)
2898-
// that dominates their intersection, and means we can ignore this
2899-
size_t k;
2900-
for (k = j; k > 0; k--) {
2901-
jl_method_match_t *matc3 = (jl_method_match_t*)jl_array_ptr_ref(env.t, k - 1);
2902-
jl_method_t *m3 = matc3->method;
2903-
if ((jl_subtype(ti, m3->sig) || (isect2 && jl_subtype(isect2, m3->sig)))
2904-
&& jl_type_morespecific((jl_value_t*)m3->sig, (jl_value_t*)m->sig)
2905-
&& jl_type_morespecific((jl_value_t*)m3->sig, (jl_value_t*)m2->sig))
2906-
break;
2897+
if (ti != jl_bottom_type) {
2898+
if (!jl_type_morespecific((jl_value_t*)m2->sig, (jl_value_t*)m->sig)) {
2899+
// m and m2 are ambiguous, but let's see if we can find another method (m3)
2900+
// that dominates their intersection, and means we can ignore this
2901+
size_t k;
2902+
for (k = j; k > 0; k--) {
2903+
jl_method_match_t *matc3 = (jl_method_match_t*)jl_array_ptr_ref(env.t, k - 1);
2904+
jl_method_t *m3 = matc3->method;
2905+
if ((jl_subtype(ti, m3->sig) || (isect2 && jl_subtype(isect2, m3->sig)))
2906+
&& jl_type_morespecific((jl_value_t*)m3->sig, (jl_value_t*)m->sig)
2907+
&& jl_type_morespecific((jl_value_t*)m3->sig, (jl_value_t*)m2->sig))
2908+
break;
2909+
}
2910+
if (k == 0) {
2911+
ambig_groupid[i] = j - 1; // ambiguity covering range [i:j)
2912+
}
29072913
}
2908-
if (k == 0)
2909-
ambig_groupid[i] = j - 1; // ambiguity covering range [i:j)
2914+
disjoint = 0;
29102915
}
29112916
isect2 = NULL;
2912-
disjoint = 0;
29132917
}
29142918
}
29152919
if (disjoint && lim >= 0) {

0 commit comments

Comments
 (0)