Skip to content

Commit 3f9c43b

Browse files
committed
gf: invalidate when adding new methods
Error introduced by #36733 Fixes 38435
1 parent 5f10eb9 commit 3f9c43b

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

src/gf.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,21 +1667,33 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
16671667
size_t ins = 0;
16681668
for (i = 1; i < na; i += 2) {
16691669
jl_value_t *backedgetyp = backedges[i - 1];
1670+
int missing = 0;
16701671
if (jl_type_intersection2(backedgetyp, (jl_value_t*)type, &isect, &isect2)) {
1671-
// see if the intersection was actually already fully
1672-
// covered by anything (method or ambiguity is okay)
1672+
// See if the intersection was actually already fully
1673+
// covered, but that the new method is ambiguous.
1674+
// -> no previous method: now there is one, need to update the missing edge
1675+
// -> one+ previously matching method(s):
1676+
// -> more specific then all of them: need to update the missing edge
1677+
// -> some may have been ambiguous: now there is a replacement
1678+
// -> some may have been called: now there is a replacement (also will be detected in the loop later)
1679+
// -> less specific or ambiguous with any one of them: can ignore the missing edge (not missing)
1680+
// -> some may have been ambiguous: still are
1681+
// -> some may have been called: they may be partly replaced (will be detected in the loop later)
1682+
missing = 1;
16731683
size_t j;
16741684
for (j = 0; j < n; j++) {
16751685
jl_method_t *m = d[j];
1676-
if (jl_subtype(isect, m->sig))
1677-
break;
1678-
if (isect2 && jl_subtype(isect2, m->sig))
1679-
break;
1686+
if (jl_subtype(isect, m->sig) || (isect2 && jl_subtype(isect2, m->sig))) {
1687+
// We now know that there actually was a previous
1688+
// method for this part of the type intersection.
1689+
if (!jl_type_morespecific(type, m->sig)) {
1690+
missing = 0;
1691+
break;
1692+
}
1693+
}
16801694
}
1681-
if (j != n)
1682-
isect = jl_bottom_type;
16831695
}
1684-
if (isect != jl_bottom_type) {
1696+
if (missing) {
16851697
jl_method_instance_t *backedge = (jl_method_instance_t*)backedges[i];
16861698
invalidate_external(backedge, max_world);
16871699
invalidate_method_instance(backedge, max_world, 0);
@@ -1723,7 +1735,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
17231735
isect3 = jl_type_intersection(m->sig, (jl_value_t*)mi->specTypes);
17241736
if (jl_type_intersection2(type, isect3, &isect, &isect2)) {
17251737
if (morespec[j] == (char)morespec_unknown)
1726-
morespec[j] = (char)jl_type_morespecific(m->sig, type) ? morespec_is : morespec_isnot;
1738+
morespec[j] = (char)(jl_type_morespecific(m->sig, type) ? morespec_is : morespec_isnot);
17271739
if (morespec[j] == (char)morespec_is)
17281740
// not actually shadowing--the existing method is still better
17291741
break;
@@ -1738,7 +1750,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
17381750
if (m == m2 || !(jl_subtype(isect, m2->sig) || (isect && jl_subtype(isect, m2->sig))))
17391751
continue;
17401752
if (morespec[k] == (char)morespec_unknown)
1741-
morespec[k] = (char)jl_type_morespecific(m2->sig, type) ? morespec_is : morespec_isnot;
1753+
morespec[k] = (char)(jl_type_morespecific(m2->sig, type) ? morespec_is : morespec_isnot);
17421754
if (morespec[k] == (char)morespec_is)
17431755
// not actually shadowing this--m2 will still be better
17441756
break;

test/worlds.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,14 @@ notify(c26506_1)
200200
wait(c26506_2)
201201
@test result26506[1] == 3
202202

203+
# issue #38435
204+
f38435(::Int, ::Any) = 1
205+
f38435(::Any, ::Int) = 2
206+
g38435(x) = f38435(x, x)
207+
@test_throws MethodError(f38435, (1, 1), Base.get_world_counter()) g38435(1)
208+
f38435(::Int, ::Int) = 3.0
209+
@test g38435(1) === 3.0
210+
203211

204212
## Invalidation tests
205213

0 commit comments

Comments
 (0)