]> granicus.if.org Git - vim/commitdiff
patch 8.2.3249: Vim9: error for re-imported function with default argument v8.2.3249
authorBram Moolenaar <Bram@vim.org>
Thu, 29 Jul 2021 20:48:54 +0000 (22:48 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 29 Jul 2021 20:48:54 +0000 (22:48 +0200)
Problem:    Vim9: error for re-imported function with default argument.
Solution:   Do not check argument type if it is still unknown. (closes #8653)

src/eval.c
src/proto/vim9type.pro
src/testdir/test_vim9_script.vim
src/version.c
src/vim.h
src/vim9execute.c
src/vim9script.c
src/vim9type.c

index 0d41f17805330700fe0f912289a705528bf89295..769816d2cc20940e03c238e5ac5f5d3b2af6eb5f 100644 (file)
@@ -3359,7 +3359,7 @@ eval7t(
        {
            type_T *actual = typval2type(rettv, get_copyID(), &type_list, TRUE);
 
-           if (!equal_type(want_type, actual))
+           if (!equal_type(want_type, actual, 0))
            {
                if (want_type == &t_bool && actual != &t_bool
                                        && (actual->tt_flags & TTFLAG_BOOL_OK))
index 559eb5c146172ccc27ac9079a86abe53b4de87f0..6e8f486bc4d9215790dffe0f7af4e7f95fc1c2e0 100644 (file)
@@ -20,7 +20,7 @@ int check_type(type_T *expected, type_T *actual, int give_msg, where_T where);
 int check_argument_types(type_T *type, typval_T *argvars, int argcount, char_u *name);
 char_u *skip_type(char_u *start, int optional);
 type_T *parse_type(char_u **arg, garray_T *type_gap, int give_error);
-int equal_type(type_T *type1, type_T *type2);
+int equal_type(type_T *type1, type_T *type2, int flags);
 void common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap);
 type_T *get_member_type_from_stack(type_T **stack_top, int count, int skip, garray_T *type_gap);
 char *vartype_name(vartype_T type);
index d46299c70e52a851c1aefbaa402a6319393b9424..4b9e6f3065939420b0becfe627cbba768d0a7254 100644 (file)
@@ -1626,6 +1626,9 @@ def Test_vim9script_reload_noclear()
   var lines =<< trim END
     vim9script
     export var exported = 'thexport'
+
+    export def TheFunc(x = 0)
+    enddef
   END
   writefile(lines, 'XExportReload')
   lines =<< trim END
@@ -1638,6 +1641,9 @@ def Test_vim9script_reload_noclear()
       return 'again'
     enddef
 
+    import TheFunc from './XExportReload'
+    TheFunc()
+
     if exists('s:loaded') | finish | endif
     var s:loaded = true
 
index 95105699826603db6ca0cc69c2ff21f975822704..33f4196595a55f1dce8c94fb5d0255c2f8b7fefa 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3249,
 /**/
     3248,
 /**/
index 30cf284284014611f496493676e7bba4a861505b..54d507eefe9cd7b2e8f04744c06fbc9d015bf7c2 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -2736,4 +2736,7 @@ long elapsed(DWORD start_tick);
 // Maximum number of characters that can be fuzzy matched
 #define MAX_FUZZY_MATCHES      256
 
+// flags for equal_type()
+#define ETYPE_ARG_UNKNOWN 1
+
 #endif // VIM__H
index 5c59c5bfa71658cc4c5a8a821867dcd5db0d26d6..f453af7947224f2e9d3f7cbf4250a60d2d05fcd4 100644 (file)
@@ -1271,7 +1271,7 @@ get_script_svar(scriptref_T *sref, ectx_T *ectx)
        return NULL;
     }
     sv = ((svar_T *)si->sn_var_vals.ga_data) + sref->sref_idx;
-    if (!equal_type(sv->sv_type, sref->sref_type))
+    if (!equal_type(sv->sv_type, sref->sref_type, 0))
     {
        emsg(_(e_script_variable_type_changed));
        return NULL;
index 641b0dd88d3d6ca9ffab2b2edd7d1606f1d32432..40f857fe076908cc8b98048861a44d16d0087928 100644 (file)
@@ -623,9 +623,10 @@ handle_import(
                    && (imported->imp_flags & IMP_FLAGS_RELOAD)
                    && imported->imp_sid == sid
                    && (idx >= 0
-                       ? (equal_type(imported->imp_type, type)
+                       ? (equal_type(imported->imp_type, type, 0)
                            && imported->imp_var_vals_idx == idx)
-                       : (equal_type(imported->imp_type, ufunc->uf_func_type)
+                       : (equal_type(imported->imp_type, ufunc->uf_func_type,
+                                                            ETYPE_ARG_UNKNOWN)
                            && STRCMP(imported->imp_funcname,
                                                        ufunc->uf_name) == 0)))
            {
index ea50e890300d8cfbcaf04096cd508df307c58caa..f64089ad1cc6e6b32903771c758688a2d6373085 100644 (file)
@@ -954,9 +954,11 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
 
 /*
  * Check if "type1" and "type2" are exactly the same.
+ * "flags" can have ETYPE_ARG_UNKNOWN, which means that an unknown argument
+ * type in "type1" is accepted.
  */
     int
-equal_type(type_T *type1, type_T *type2)
+equal_type(type_T *type1, type_T *type2, int flags)
 {
     int i;
 
@@ -981,17 +983,19 @@ equal_type(type_T *type1, type_T *type2)
            break;  // not composite is always OK
        case VAR_LIST:
        case VAR_DICT:
-           return equal_type(type1->tt_member, type2->tt_member);
+           return equal_type(type1->tt_member, type2->tt_member, flags);
        case VAR_FUNC:
        case VAR_PARTIAL:
-           if (!equal_type(type1->tt_member, type2->tt_member)
+           if (!equal_type(type1->tt_member, type2->tt_member, flags)
                    || type1->tt_argcount != type2->tt_argcount)
                return FALSE;
            if (type1->tt_argcount < 0
                           || type1->tt_args == NULL || type2->tt_args == NULL)
                return TRUE;
            for (i = 0; i < type1->tt_argcount; ++i)
-               if (!equal_type(type1->tt_args[i], type2->tt_args[i]))
+               if ((flags & ETYPE_ARG_UNKNOWN) == 0
+                       && !equal_type(type1->tt_args[i], type2->tt_args[i],
+                                                                       flags))
                    return FALSE;
            return TRUE;
     }
@@ -1005,7 +1009,7 @@ equal_type(type_T *type1, type_T *type2)
     void
 common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap)
 {
-    if (equal_type(type1, type2))
+    if (equal_type(type1, type2, 0))
     {
        *dest = type1;
        return;