@@ -1667,21 +1667,33 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
1667
1667
size_t ins = 0 ;
1668
1668
for (i = 1 ; i < na ; i += 2 ) {
1669
1669
jl_value_t * backedgetyp = backedges [i - 1 ];
1670
+ int missing = 0 ;
1670
1671
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 ;
1673
1683
size_t j ;
1674
1684
for (j = 0 ; j < n ; j ++ ) {
1675
1685
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
+ }
1680
1694
}
1681
- if (j != n )
1682
- isect = jl_bottom_type ;
1683
1695
}
1684
- if (isect != jl_bottom_type ) {
1696
+ if (missing ) {
1685
1697
jl_method_instance_t * backedge = (jl_method_instance_t * )backedges [i ];
1686
1698
invalidate_external (backedge , max_world );
1687
1699
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
1723
1735
isect3 = jl_type_intersection (m -> sig , (jl_value_t * )mi -> specTypes );
1724
1736
if (jl_type_intersection2 (type , isect3 , & isect , & isect2 )) {
1725
1737
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 ) ;
1727
1739
if (morespec [j ] == (char )morespec_is )
1728
1740
// not actually shadowing--the existing method is still better
1729
1741
break ;
@@ -1738,7 +1750,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
1738
1750
if (m == m2 || !(jl_subtype (isect , m2 -> sig ) || (isect && jl_subtype (isect , m2 -> sig ))))
1739
1751
continue ;
1740
1752
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 ) ;
1742
1754
if (morespec [k ] == (char )morespec_is )
1743
1755
// not actually shadowing this--m2 will still be better
1744
1756
break ;
0 commit comments