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