@@ -1661,7 +1661,9 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
1661
1661
jl_svec_t * specializations = jl_atomic_load_acquire (& m -> specializations );
1662
1662
jl_method_instance_t * * data = (jl_method_instance_t * * )jl_svec_data (specializations );
1663
1663
size_t i , l = jl_svec_len (specializations );
1664
+ int invalid = 0 ;
1664
1665
int shadowing = 0 ;
1666
+ int ambig = 0 ;
1665
1667
for (i = 0 ; i < l ; i ++ ) {
1666
1668
jl_method_instance_t * mi = jl_atomic_load_relaxed (& data [i ]);
1667
1669
if (mi == NULL )
@@ -1672,35 +1674,40 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
1672
1674
if (jl_type_morespecific (m -> sig , type ))
1673
1675
// not actually shadowing--the existing method is still better
1674
1676
break ;
1675
- if (!jl_type_morespecific (type , mi -> def .method -> sig )) {
1676
- // adding an ambiguity--see if there already was one
1677
- size_t k ;
1678
- for (k = 0 ; k < n ; k ++ ) {
1679
- jl_method_t * m2 = d [k ];
1680
- if (m == m2 || !jl_subtype (isect , m2 -> sig ))
1681
- continue ;
1682
- if (k > i ) {
1683
- if (jl_type_morespecific (m2 -> sig , type )) {
1684
- // not actually shadowing this--m2 will still be better
1685
- morespec [k ] = 1 ;
1686
- continue ;
1687
- }
1688
- }
1689
- if (!jl_type_morespecific (m -> sig , m2 -> sig ) &&
1690
- !jl_type_morespecific (m2 -> sig , m -> sig )) {
1677
+ shadowing = 1 ;
1678
+ ambig = !jl_type_morespecific (type , m -> sig );
1679
+ }
1680
+ // replacing a method--see if this really was the selected method previously
1681
+ // over the intersection
1682
+ if (ambig ) {
1683
+ size_t k ;
1684
+ for (k = 0 ; k < n ; k ++ ) {
1685
+ jl_method_t * m2 = d [k ];
1686
+ if (m == m2 || !jl_subtype (isect , m2 -> sig ))
1687
+ continue ;
1688
+ if (morespec [k ])
1689
+ break ;
1690
+ if (k > j ) { // possibly haven't actually computed morespec yet
1691
+ if (jl_type_morespecific (m2 -> sig , type )) {
1692
+ // not actually shadowing this--m2 will still be better
1693
+ morespec [k ] = 1 ;
1691
1694
break ;
1692
1695
}
1693
1696
}
1694
- if (k != n )
1695
- continue ;
1697
+ // since m2 was also a previous match over isect,
1698
+ // see if m was also previously dominant over m2
1699
+ if (!jl_type_morespecific (m -> sig , m2 -> sig ))
1700
+ break ;
1696
1701
}
1697
- shadowing = 1 ;
1702
+ if (k != n )
1703
+ continue ;
1698
1704
}
1705
+ invalid = 1 ;
1699
1706
if (mi -> backedges )
1700
1707
invalidate_backedges (mi , max_world , "jl_method_table_insert" );
1701
1708
}
1702
1709
}
1703
- if (shadowing == 0 )
1710
+ if (invalid == 0 )
1704
1711
morespec [j ] = 1 ; // the method won't need to be dropped from any cache
1705
1712
}
1706
1713
for (j = 0 ; j < n ; j ++ ) {
0 commit comments