From 60dc8274e9f8c6a20d54efebc7a8752fe062eead Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 29 Jul 2021 22:48:54 +0200 Subject: patch 8.2.3249: Vim9: error for re-imported function with default argument 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 | 2 +- src/proto/vim9type.pro | 2 +- src/testdir/test_vim9_script.vim | 6 ++++++ src/version.c | 2 ++ src/vim.h | 3 +++ src/vim9execute.c | 2 +- src/vim9script.c | 5 +++-- src/vim9type.c | 14 +++++++++----- 8 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/eval.c b/src/eval.c index 0d41f1780..769816d2c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -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)) diff --git a/src/proto/vim9type.pro b/src/proto/vim9type.pro index 559eb5c14..6e8f486bc 100644 --- a/src/proto/vim9type.pro +++ b/src/proto/vim9type.pro @@ -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); diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index d46299c70..4b9e6f306 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -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 diff --git a/src/version.c b/src/version.c index 951056998..33f419659 100644 --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 3249, /**/ 3248, /**/ diff --git a/src/vim.h b/src/vim.h index 30cf28428..54d507eef 100644 --- 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 diff --git a/src/vim9execute.c b/src/vim9execute.c index 5c59c5bfa..f453af794 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -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; diff --git a/src/vim9script.c b/src/vim9script.c index 641b0dd88..40f857fe0 100644 --- a/src/vim9script.c +++ b/src/vim9script.c @@ -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))) { diff --git a/src/vim9type.c b/src/vim9type.c index ea50e8903..f64089ad1 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -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; -- cgit v1.2.1