@@ -1682,18 +1682,41 @@ 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 jl_is_call_ambiguous (jl_value_t * types , jl_method_t * m )
1686
+ {
1687
+ if (m -> ambig == jl_nothing )
1688
+ return 0 ;
1689
+ for (size_t i = 0 ; i < jl_array_len (m -> ambig ); i ++ ) {
1690
+ jl_typemap_entry_t * mambig = (jl_typemap_entry_t * )jl_array_ptr_ref (m -> ambig , i );
1691
+ if (mambig -> min_world <= jl_world_counter && jl_world_counter <= mambig -> max_world )
1692
+ if (jl_subtype ((jl_value_t * )types , (jl_value_t * )mambig -> sig ))
1693
+ return 1 ;
1694
+ }
1695
+ return 0 ;
1696
+ }
1697
+
1698
+ static int jl_is_function_call_ambiguous (jl_value_t * types JL_PROPAGATES_ROOT , size_t world )
1699
+ {
1700
+ jl_methtable_t * mt = jl_first_argument_datatype (types )-> name -> mt ;
1701
+ struct jl_typemap_assoc search = {types , world , NULL , 0 , ~(size_t )0 };
1702
+ jl_typemap_entry_t * entry = jl_typemap_assoc_by_type (mt -> defs , & search , 0 , 1 );
1703
+ if (!entry )
1704
+ return 0 ;
1705
+ return jl_is_call_ambiguous (types , entry -> func .method );
1706
+ }
1707
+
1685
1708
JL_DLLEXPORT void jl_method_table_insert (jl_methtable_t * mt , jl_method_t * method , jl_tupletype_t * simpletype )
1686
1709
{
1687
1710
JL_TIMING (ADD_METHOD );
1688
1711
assert (jl_is_method (method ));
1689
1712
assert (jl_is_mtable (mt ));
1690
1713
jl_value_t * type = method -> sig ;
1691
- jl_value_t * oldvalue = NULL ;
1714
+ jl_value_t * oldvalue = NULL , * isect = NULL ;
1692
1715
if (method -> primary_world == 1 )
1693
1716
method -> primary_world = ++ jl_world_counter ;
1694
1717
size_t max_world = method -> primary_world - 1 ;
1695
1718
int invalidated = 0 ;
1696
- JL_GC_PUSH1 (& oldvalue );
1719
+ JL_GC_PUSH2 (& oldvalue , & isect );
1697
1720
JL_LOCK (& mt -> writelock );
1698
1721
// first delete the existing entry (we'll disable it later)
1699
1722
struct jl_typemap_assoc search = {(jl_value_t * )type , method -> primary_world , NULL , 0 , ~(size_t )0 };
@@ -1718,7 +1741,8 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
1718
1741
size_t ins = 0 ;
1719
1742
for (i = 1 ; i < na ; i += 2 ) {
1720
1743
jl_value_t * backedgetyp = backedges [i - 1 ];
1721
- if (!jl_has_empty_intersection (backedgetyp , (jl_value_t * )type )) {
1744
+ isect = jl_type_intersection (backedgetyp , (jl_value_t * )type );
1745
+ if (isect != jl_bottom_type && !jl_is_function_call_ambiguous (isect , max_world )) {
1722
1746
jl_method_instance_t * backedge = (jl_method_instance_t * )backedges [i ];
1723
1747
invalidate_method_instance (backedge , max_world , 0 );
1724
1748
invalidated = 1 ;
@@ -1766,9 +1790,12 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
1766
1790
size_t i , l = jl_svec_len (specializations );
1767
1791
for (i = 0 ; i < l ; i ++ ) {
1768
1792
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 ;
1793
+ if (mi != NULL ) {
1794
+ isect = jl_type_intersection (type , (jl_value_t * )mi -> specTypes );
1795
+ if (isect != jl_bottom_type && !jl_is_function_call_ambiguous (isect , max_world ))
1796
+ if (invalidate_backedges (mi , max_world ))
1797
+ invalidated = 1 ;
1798
+ }
1772
1799
}
1773
1800
}
1774
1801
}
0 commit comments