@@ -2561,7 +2561,7 @@ inside_class(cctx_T *cctx_arg, class_T *cl)
25612561{
25622562 for (cctx_T * cctx = cctx_arg ; cctx != NULL ; cctx = cctx -> ctx_outer )
25632563 if (cctx -> ctx_ufunc != NULL
2564- && class_instance_of (cctx -> ctx_ufunc -> uf_class , cl ))
2564+ && class_instance_of (cctx -> ctx_ufunc -> uf_class , cl , TRUE ))
25652565 return TRUE;
25662566 return FALSE;
25672567}
@@ -2871,29 +2871,39 @@ member_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len)
28712871 * interfaces matches the class "other_cl".
28722872 */
28732873 int
2874- class_instance_of (class_T * cl , class_T * other_cl )
2874+ class_instance_of (class_T * cl , class_T * other_cl , int covariance_check )
28752875{
28762876 if (cl == other_cl )
28772877 return TRUE;
28782878
2879- // Recursively check the base classes.
2880- for (; cl != NULL ; cl = cl -> class_extends )
2879+ if (covariance_check )
28812880 {
2882- if (cl == other_cl )
2883- return TRUE;
2884- // Check the implemented interfaces and the super interfaces
2885- for (int i = cl -> class_interface_count - 1 ; i >= 0 ; -- i )
2881+ // Recursively check the base classes.
2882+ for (; cl != NULL ; cl = cl -> class_extends )
28862883 {
2887- class_T * intf = cl -> class_interfaces_cl [i ];
2888- while (intf != NULL )
2884+ if (cl == other_cl )
2885+ return TRUE;
2886+ // Check the implemented interfaces and the super interfaces
2887+ for (int i = cl -> class_interface_count - 1 ; i >= 0 ; -- i )
28892888 {
2890- if (intf == other_cl )
2891- return TRUE;
2892- // check the super interfaces
2893- intf = intf -> class_extends ;
2889+ class_T * intf = cl -> class_interfaces_cl [i ];
2890+ while (intf != NULL )
2891+ {
2892+ if (intf == other_cl )
2893+ return TRUE;
2894+ // check the super interfaces
2895+ intf = intf -> class_extends ;
2896+ }
28942897 }
28952898 }
28962899 }
2900+ else
2901+ {
2902+ // contra-variance
2903+ for (; other_cl != NULL ; other_cl = other_cl -> class_extends )
2904+ if (cl == other_cl )
2905+ return TRUE;
2906+ }
28972907
28982908 return FALSE;
28992909}
@@ -2928,7 +2938,7 @@ f_instanceof(typval_T *argvars, typval_T *rettv)
29282938 }
29292939
29302940 if (class_instance_of (object_tv -> vval .v_object -> obj_class ,
2931- li -> li_tv .vval .v_class ) == TRUE)
2941+ li -> li_tv .vval .v_class , TRUE ) == TRUE)
29322942 {
29332943 rettv -> vval .v_number = VVAL_TRUE ;
29342944 return ;
@@ -2937,8 +2947,9 @@ f_instanceof(typval_T *argvars, typval_T *rettv)
29372947 }
29382948 else if (classinfo_tv -> v_type == VAR_CLASS )
29392949 {
2940- rettv -> vval .v_number = class_instance_of (object_tv -> vval .v_object -> obj_class ,
2941- classinfo_tv -> vval .v_class );
2950+ rettv -> vval .v_number = class_instance_of (
2951+ object_tv -> vval .v_object -> obj_class ,
2952+ classinfo_tv -> vval .v_class , TRUE);
29422953 }
29432954}
29442955
0 commit comments