Skip to content

Commit 398d07a

Browse files
vtjnashKristofferC
authored andcommitted
gf: invalidate when adding new methods (#39343)
Error introduced by #36733 Fixes #38435 (cherry picked from commit cdaf740)
1 parent baf8414 commit 398d07a

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
@@ -1659,21 +1659,33 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
16591659
size_t ins = 0;
16601660
for (i = 1; i < na; i += 2) {
16611661
jl_value_t *backedgetyp = backedges[i - 1];
1662+
int missing = 0;
16621663
if (jl_type_intersection2(backedgetyp, (jl_value_t*)type, &isect, &isect2)) {
1663-
// see if the intersection was actually already fully
1664-
// covered by anything (method or ambiguity is okay)
1664+
// See if the intersection was actually already fully
1665+
// covered, but that the new method is ambiguous.
1666+
// -> no previous method: now there is one, need to update the missing edge
1667+
// -> one+ previously matching method(s):
1668+
// -> more specific then all of them: need to update the missing edge
1669+
// -> some may have been ambiguous: now there is a replacement
1670+
// -> some may have been called: now there is a replacement (also will be detected in the loop later)
1671+
// -> less specific or ambiguous with any one of them: can ignore the missing edge (not missing)
1672+
// -> some may have been ambiguous: still are
1673+
// -> some may have been called: they may be partly replaced (will be detected in the loop later)
1674+
missing = 1;
16651675
size_t j;
16661676
for (j = 0; j < n; j++) {
16671677
jl_method_t *m = d[j];
1668-
if (jl_subtype(isect, m->sig))
1669-
break;
1670-
if (isect2 && jl_subtype(isect2, m->sig))
1671-
break;
1678+
if (jl_subtype(isect, m->sig) || (isect2 && jl_subtype(isect2, m->sig))) {
1679+
// We now know that there actually was a previous
1680+
// method for this part of the type intersection.
1681+
if (!jl_type_morespecific(type, m->sig)) {
1682+
missing = 0;
1683+
break;
1684+
}
1685+
}
16721686
}
1673-
if (j != n)
1674-
isect = jl_bottom_type;
16751687
}
1676-
if (isect != jl_bottom_type) {
1688+
if (missing) {
16771689
jl_method_instance_t *backedge = (jl_method_instance_t*)backedges[i];
16781690
invalidate_external(backedge, max_world);
16791691
invalidate_method_instance(backedge, max_world, 0);
@@ -1715,7 +1727,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
17151727
isect3 = jl_type_intersection(m->sig, (jl_value_t*)mi->specTypes);
17161728
if (jl_type_intersection2(type, isect3, &isect, &isect2)) {
17171729
if (morespec[j] == (char)morespec_unknown)
1718-
morespec[j] = (char)jl_type_morespecific(m->sig, type) ? morespec_is : morespec_isnot;
1730+
morespec[j] = (char)(jl_type_morespecific(m->sig, type) ? morespec_is : morespec_isnot);
17191731
if (morespec[j] == (char)morespec_is)
17201732
// not actually shadowing--the existing method is still better
17211733
break;
@@ -1730,7 +1742,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
17301742
if (m == m2 || !(jl_subtype(isect, m2->sig) || (isect && jl_subtype(isect, m2->sig))))
17311743
continue;
17321744
if (morespec[k] == (char)morespec_unknown)
1733-
morespec[k] = (char)jl_type_morespecific(m2->sig, type) ? morespec_is : morespec_isnot;
1745+
morespec[k] = (char)(jl_type_morespecific(m2->sig, type) ? morespec_is : morespec_isnot);
17341746
if (morespec[k] == (char)morespec_is)
17351747
// not actually shadowing this--m2 will still be better
17361748
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)