Skip to content

Commit cdaf740

Browse files
authored
gf: invalidate when adding new methods (#39343)
Error introduced by #36733 Fixes #38435
1 parent fd8f97e commit cdaf740

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
@@ -1666,21 +1666,33 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
16661666
size_t ins = 0;
16671667
for (i = 1; i < na; i += 2) {
16681668
jl_value_t *backedgetyp = backedges[i - 1];
1669+
int missing = 0;
16691670
if (jl_type_intersection2(backedgetyp, (jl_value_t*)type, &isect, &isect2)) {
1670-
// see if the intersection was actually already fully
1671-
// covered by anything (method or ambiguity is okay)
1671+
// See if the intersection was actually already fully
1672+
// covered, but that the new method is ambiguous.
1673+
// -> no previous method: now there is one, need to update the missing edge
1674+
// -> one+ previously matching method(s):
1675+
// -> more specific then all of them: need to update the missing edge
1676+
// -> some may have been ambiguous: now there is a replacement
1677+
// -> some may have been called: now there is a replacement (also will be detected in the loop later)
1678+
// -> less specific or ambiguous with any one of them: can ignore the missing edge (not missing)
1679+
// -> some may have been ambiguous: still are
1680+
// -> some may have been called: they may be partly replaced (will be detected in the loop later)
1681+
missing = 1;
16721682
size_t j;
16731683
for (j = 0; j < n; j++) {
16741684
jl_method_t *m = d[j];
1675-
if (jl_subtype(isect, m->sig))
1676-
break;
1677-
if (isect2 && jl_subtype(isect2, m->sig))
1678-
break;
1685+
if (jl_subtype(isect, m->sig) || (isect2 && jl_subtype(isect2, m->sig))) {
1686+
// We now know that there actually was a previous
1687+
// method for this part of the type intersection.
1688+
if (!jl_type_morespecific(type, m->sig)) {
1689+
missing = 0;
1690+
break;
1691+
}
1692+
}
16791693
}
1680-
if (j != n)
1681-
isect = jl_bottom_type;
16821694
}
1683-
if (isect != jl_bottom_type) {
1695+
if (missing) {
16841696
jl_method_instance_t *backedge = (jl_method_instance_t*)backedges[i];
16851697
invalidate_external(backedge, max_world);
16861698
invalidate_method_instance(backedge, max_world, 0);
@@ -1722,7 +1734,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
17221734
isect3 = jl_type_intersection(m->sig, (jl_value_t*)mi->specTypes);
17231735
if (jl_type_intersection2(type, isect3, &isect, &isect2)) {
17241736
if (morespec[j] == (char)morespec_unknown)
1725-
morespec[j] = (char)jl_type_morespecific(m->sig, type) ? morespec_is : morespec_isnot;
1737+
morespec[j] = (char)(jl_type_morespecific(m->sig, type) ? morespec_is : morespec_isnot);
17261738
if (morespec[j] == (char)morespec_is)
17271739
// not actually shadowing--the existing method is still better
17281740
break;
@@ -1737,7 +1749,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
17371749
if (m == m2 || !(jl_subtype(isect, m2->sig) || (isect && jl_subtype(isect, m2->sig))))
17381750
continue;
17391751
if (morespec[k] == (char)morespec_unknown)
1740-
morespec[k] = (char)jl_type_morespecific(m2->sig, type) ? morespec_is : morespec_isnot;
1752+
morespec[k] = (char)(jl_type_morespecific(m2->sig, type) ? morespec_is : morespec_isnot);
17411753
if (morespec[k] == (char)morespec_is)
17421754
// not actually shadowing this--m2 will still be better
17431755
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)