@@ -1004,6 +1004,42 @@ static void update_max_args(jl_methtable_t *mt, jl_tupletype_t *type)
10041004}
10051005
10061006// invalidate cached methods that overlap this definition
1007+ struct invalidate_spec_env {
1008+ jl_lambda_info_t * replaced ;
1009+ size_t max_world ;
1010+ int invalidated ;
1011+ };
1012+ static int invalidate_spec (jl_typemap_entry_t * oldentry , void * closure )
1013+ {
1014+ struct invalidate_spec_env * env = (struct invalidate_spec_env * )closure ;
1015+ if (oldentry -> func .linfo == env -> replaced ) {
1016+ if (oldentry -> max_world > env -> max_world ) {
1017+ oldentry -> max_world = env -> max_world ;
1018+ env -> invalidated = 1 ;
1019+ }
1020+ }
1021+ return 1 ;
1022+ }
1023+ static void invalidate_conflicting_recursive (jl_lambda_info_t * oldentry , size_t max_world )
1024+ {
1025+ if (oldentry -> backedges ) {
1026+ size_t i , l = jl_array_len (oldentry -> backedges );
1027+ for (i = 0 ; i < l ; i ++ ) {
1028+ struct invalidate_spec_env env ;
1029+ env .max_world = max_world ;
1030+ env .invalidated = 0 ;
1031+ env .replaced = (jl_lambda_info_t * )jl_array_ptr_ref (oldentry -> backedges , i );
1032+ jl_method_t * m = env .replaced -> def ;
1033+ jl_typemap_visitor (m -> specializations , invalidate_spec , & env );
1034+ jl_datatype_t * gf = jl_first_argument_datatype ((jl_value_t * )m -> sig );
1035+ assert (jl_is_datatype (gf ) && gf -> name -> mt );
1036+ jl_typemap_visitor (gf -> name -> mt -> cache , invalidate_spec , & env );
1037+
1038+ if (env .invalidated )
1039+ invalidate_conflicting_recursive (env .replaced , max_world );
1040+ }
1041+ }
1042+ }
10071043struct invalidate_conflicting_env {
10081044 struct typemap_intersection_env match ;
10091045 jl_array_t * shadowed ;
@@ -1013,10 +1049,11 @@ static int invalidate_conflicting(jl_typemap_entry_t *oldentry, struct typemap_i
10131049{
10141050 struct invalidate_conflicting_env * closure = container_of (closure0 , struct invalidate_conflicting_env , match );
10151051 size_t i , n = jl_array_len (closure -> shadowed );
1016- jl_value_t * * d = jl_array_ptr_data (closure -> shadowed );
1052+ jl_method_t * * d = ( jl_method_t * * ) jl_array_ptr_data (closure -> shadowed );
10171053 for (i = 0 ; i < n ; i ++ ) {
1018- if (d [i ] == ( jl_value_t * ) oldentry -> func .linfo -> def ) {
1054+ if (d [i ] == oldentry -> func .linfo -> def ) {
10191055 oldentry -> max_world = closure -> max_world ;
1056+ invalidate_conflicting_recursive (oldentry -> func .linfo , closure -> max_world );
10201057 return 1 ;
10211058 }
10221059 }
@@ -1064,6 +1101,12 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
10641101 env .match .type = (jl_value_t * )type ;
10651102 env .max_world = method -> min_world - 1 ;
10661103 jl_typemap_intersection_visitor (mt -> cache , jl_cachearg_offset (mt ), & env .match );
1104+
1105+ size_t i , n = jl_array_len (env .shadowed );
1106+ jl_method_t * * d = (jl_method_t * * )jl_array_ptr_data (env .shadowed );
1107+ for (i = 0 ; i < n ; i ++ ) {
1108+ jl_typemap_intersection_visitor (d [i ]-> specializations , 0 , & env .match );
1109+ }
10671110 }
10681111 update_max_args (mt , type );
10691112 JL_UNLOCK (& mt -> writelock );
0 commit comments