@@ -1659,21 +1659,33 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
1659
1659
size_t ins = 0 ;
1660
1660
for (i = 1 ; i < na ; i += 2 ) {
1661
1661
jl_value_t * backedgetyp = backedges [i - 1 ];
1662
+ int missing = 0 ;
1662
1663
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 ;
1665
1675
size_t j ;
1666
1676
for (j = 0 ; j < n ; j ++ ) {
1667
1677
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
+ }
1672
1686
}
1673
- if (j != n )
1674
- isect = jl_bottom_type ;
1675
1687
}
1676
- if (isect != jl_bottom_type ) {
1688
+ if (missing ) {
1677
1689
jl_method_instance_t * backedge = (jl_method_instance_t * )backedges [i ];
1678
1690
invalidate_external (backedge , max_world );
1679
1691
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
1715
1727
isect3 = jl_type_intersection (m -> sig , (jl_value_t * )mi -> specTypes );
1716
1728
if (jl_type_intersection2 (type , isect3 , & isect , & isect2 )) {
1717
1729
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 ) ;
1719
1731
if (morespec [j ] == (char )morespec_is )
1720
1732
// not actually shadowing--the existing method is still better
1721
1733
break ;
@@ -1730,7 +1742,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
1730
1742
if (m == m2 || !(jl_subtype (isect , m2 -> sig ) || (isect && jl_subtype (isect , m2 -> sig ))))
1731
1743
continue ;
1732
1744
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 ) ;
1734
1746
if (morespec [k ] == (char )morespec_is )
1735
1747
// not actually shadowing this--m2 will still be better
1736
1748
break ;
0 commit comments