From b79efe0f40c177fa80262dd9aab9ff7c64a4f8fb Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Tue, 20 Oct 2026 15:23:02 +0000 Subject: [PATCH] patch 9.2.1217: Vim9: varargs type of generic function not in function type Problem: Vim9: when a generic function with variable arguments is used with type arguments, the type variable in the variable arguments type is not replaced in the function type, e.g. it is "func(...list)" instead of "func(...list)". Solution: Also replace the type variable in the function type (Yegappan Lakshmanan). fixes: #21568 closes: #21507 Assisted-by: Claude Signed-off-by: Yegappan Lakshmanan Signed-off-by: Christian Brabandt --- src/testdir/test_vim9_generics.vim | 23 +++++++++++++++++++++++ src/version.c | 2 ++ src/vim9generics.c | 11 +++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/testdir/test_vim9_generics.vim b/src/testdir/test_vim9_generics.vim index f9718d1092..8af93ae86b 100644 --- a/src/testdir/test_vim9_generics.vim +++ b/src/testdir/test_vim9_generics.vim @@ -3988,6 +3988,29 @@ def Test_generic_type_var_name_prefix() v9.CheckSourceFailure(lines, 'E1010: Type not recognized: T', 2) enddef +" Test for the function type of a generic function with variable arguments +def Test_generic_func_varargs_type() + var lines =<< trim END + vim9script + def Fn(...l: list): list + return l + enddef + assert_equal('func(...list): list', typename(Fn)) + var F: func(...list): list = Fn + assert_equal([1, 2], F(1, 2)) + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + def Fn(...l: list): list + return l + enddef + var F: func(...list): list = Fn + END + v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(...list): list but got func(...list): list', 5) +enddef + " Test for using a generic method to initialize an object member variable def Test_generic_method_in_object_member_init_expr() var lines =<< trim END diff --git a/src/version.c b/src/version.c index 118d103121..dc53470469 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1217, /**/ 1216, /**/ diff --git a/src/vim9generics.c b/src/vim9generics.c index d9ac5a621b..1a04029d9b 100644 --- a/src/vim9generics.c +++ b/src/vim9generics.c @@ -918,10 +918,17 @@ generic_func_copy_types(ufunc_T *fp, ufunc_T *new_fp) && ft->tt_argcount > i ? &ft->tt_args[i] : NULL); - // Update the vararg type if it uses generic types + // Update the vararg type if it uses generic types. It is the last + // argument of the function type. if (fp->uf_va_type != NULL) + { + int va_idx = fp->uf_args.ga_len; + update_generic_type(fp, new_fp, fp->uf_va_type, &new_fp->uf_va_type, - NULL); + ft != NULL && ft->tt_args != NULL + && ft->tt_argcount > va_idx + ? &ft->tt_args[va_idx] : NULL); + } // Update the return type if it is a generic type if (fp->uf_ret_type != NULL)