@@ -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 ;
0 commit comments