@@ -1682,18 +1682,33 @@ JL_DLLEXPORT void jl_method_table_disable(jl_methtable_t *mt, jl_method_t *metho
1682
1682
JL_UNLOCK (& mt -> writelock );
1683
1683
}
1684
1684
1685
+ static int is_call_ambiguous (jl_methtable_t * mt , jl_value_t * types JL_PROPAGATES_ROOT , size_t world )
1686
+ {
1687
+ struct jl_typemap_assoc search = {(jl_value_t * )types , world , NULL , 0 , ~(size_t )0 };
1688
+ jl_typemap_entry_t * entry = jl_typemap_assoc_by_type (mt -> defs , & search , /*offs*/ 0 , /*subtype*/ 1 );
1689
+ if (entry == NULL )
1690
+ return 0 ; // we added a new definition to consider
1691
+ jl_typemap_entry_t * m = jl_typemap_morespecific_by_type (entry , (jl_value_t * )types , NULL , world );
1692
+ if (m == NULL ) {
1693
+ // TODO: this isn't quite right, since we just ask if the entry dominates
1694
+ // over all subtypes of `types`, but wanted to ask the inverse question
1695
+ return 1 ; // a new ambiguity doesn't change the result of method lookup
1696
+ }
1697
+ return 0 ; // existing and/or method already covered this intersection (TODO: which is it?)
1698
+ }
1699
+
1685
1700
JL_DLLEXPORT void jl_method_table_insert (jl_methtable_t * mt , jl_method_t * method , jl_tupletype_t * simpletype )
1686
1701
{
1687
1702
JL_TIMING (ADD_METHOD );
1688
1703
assert (jl_is_method (method ));
1689
1704
assert (jl_is_mtable (mt ));
1690
1705
jl_value_t * type = method -> sig ;
1691
- jl_value_t * oldvalue = NULL ;
1706
+ jl_value_t * oldvalue = NULL , * isect = NULL ;
1692
1707
if (method -> primary_world == 1 )
1693
1708
method -> primary_world = ++ jl_world_counter ;
1694
1709
size_t max_world = method -> primary_world - 1 ;
1695
1710
int invalidated = 0 ;
1696
- JL_GC_PUSH1 (& oldvalue );
1711
+ JL_GC_PUSH2 (& oldvalue , & isect );
1697
1712
JL_LOCK (& mt -> writelock );
1698
1713
// first delete the existing entry (we'll disable it later)
1699
1714
struct jl_typemap_assoc search = {(jl_value_t * )type , method -> primary_world , NULL , 0 , ~(size_t )0 };
@@ -1718,7 +1733,8 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
1718
1733
size_t ins = 0 ;
1719
1734
for (i = 1 ; i < na ; i += 2 ) {
1720
1735
jl_value_t * backedgetyp = backedges [i - 1 ];
1721
- if (!jl_has_empty_intersection (backedgetyp , (jl_value_t * )type )) {
1736
+ isect = jl_type_intersection (backedgetyp , (jl_value_t * )type );
1737
+ if (isect != jl_bottom_type && !is_call_ambiguous (mt , isect , max_world )) {
1722
1738
jl_method_instance_t * backedge = (jl_method_instance_t * )backedges [i ];
1723
1739
invalidate_method_instance (backedge , max_world , 0 );
1724
1740
invalidated = 1 ;
@@ -1766,9 +1782,12 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
1766
1782
size_t i , l = jl_svec_len (specializations );
1767
1783
for (i = 0 ; i < l ; i ++ ) {
1768
1784
jl_method_instance_t * mi = (jl_method_instance_t * )jl_svecref (specializations , i );
1769
- if (mi != NULL && !jl_has_empty_intersection (type , (jl_value_t * )mi -> specTypes ))
1770
- if (invalidate_backedges (mi , max_world ))
1771
- invalidated = 1 ;
1785
+ if (mi != NULL ) {
1786
+ isect = jl_type_intersection (type , (jl_value_t * )mi -> specTypes );
1787
+ if (isect != jl_bottom_type && !is_call_ambiguous (mt , isect , max_world ))
1788
+ if (invalidate_backedges (mi , max_world ))
1789
+ invalidated = 1 ;
1790
+ }
1772
1791
}
1773
1792
}
1774
1793
}
0 commit comments