Skip to content

Commit 96952b2

Browse files
erraelchrisbra
authored andcommitted
patch 9.0.2043: Vim9: issue with funcref assignmentand varargs
Problem: Vim9: issue with funcref assignmentand varargs Solution: Fix funcref type checking closes: #13351 Signed-off-by: Christian Brabandt <[email protected]> Co-authored-by: Ernie Rael <[email protected]>
1 parent c290009 commit 96952b2

File tree

5 files changed

+127
-1
lines changed

5 files changed

+127
-1
lines changed

src/testdir/test_vim9_assign.vim

+56
Original file line numberDiff line numberDiff line change
@@ -1863,6 +1863,62 @@ def Test_assign_lambda()
18631863
v9.CheckDefAndScriptFailure(lines, 'E1051:')
18641864
enddef
18651865

1866+
def Test_assign_funcref_args()
1867+
# unspecified arguments match everything, including varargs
1868+
var lines =<< trim END
1869+
vim9script
1870+
1871+
var FuncUnknown: func: number
1872+
1873+
FuncUnknown = (v): number => v
1874+
assert_equal(5, FuncUnknown(5))
1875+
1876+
FuncUnknown = (v1, v2): number => v1 + v2
1877+
assert_equal(7, FuncUnknown(3, 4))
1878+
1879+
FuncUnknown = (...v1): number => v1[0] + v1[1] + len(v1) * 1000
1880+
assert_equal(4007, FuncUnknown(3, 4, 5, 6))
1881+
1882+
FuncUnknown = (v: list<any>): number => v[0] + v[1] + len(v) * 1000
1883+
assert_equal(5009, FuncUnknown([4, 5, 6, 7, 8]))
1884+
END
1885+
v9.CheckScriptSuccess(lines)
1886+
1887+
# varargs must match
1888+
lines =<< trim END
1889+
vim9script
1890+
var FuncAnyVA: func(...any): number
1891+
FuncAnyVA = (v): number => v
1892+
END
1893+
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(...any): number but got func(any): number')
1894+
1895+
# varargs must match
1896+
lines =<< trim END
1897+
vim9script
1898+
var FuncAnyVA: func(...any): number
1899+
FuncAnyVA = (v1, v2): number => v1 + v2
1900+
END
1901+
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(...any): number but got func(any, any): number')
1902+
1903+
# varargs must match
1904+
lines =<< trim END
1905+
vim9script
1906+
var FuncAnyVA: func(...any): number
1907+
FuncAnyVA = (v1: list<any>): number => 3
1908+
END
1909+
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(...any): number but got func(list<any>): number')
1910+
enddef
1911+
1912+
def Test_assign_funcref_arg_any()
1913+
var lines =<< trim END
1914+
vim9script
1915+
var FuncAnyVA: func(any): number
1916+
FuncAnyVA = (v): number => v
1917+
END
1918+
# TODO: Verify this should succeed.
1919+
v9.CheckScriptSuccess(lines)
1920+
enddef
1921+
18661922
def Test_heredoc()
18671923
# simple heredoc
18681924
var lines =<< trim END

src/testdir/test_vim9_class.vim

+63
Original file line numberDiff line numberDiff line change
@@ -6953,6 +6953,21 @@ def Test_extended_obj_method_type_check()
69536953
endclass
69546954
END
69556955
v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<B>): object<A>', 20)
6956+
6957+
# check varargs type mismatch
6958+
lines =<< trim END
6959+
vim9script
6960+
6961+
class B
6962+
def F(...xxx: list<any>)
6963+
enddef
6964+
endclass
6965+
class C extends B
6966+
def F(xxx: list<any>)
6967+
enddef
6968+
endclass
6969+
END
6970+
v9.CheckSourceFailure(lines, 'E1383: Method "F": type mismatch, expected func(...list<any>) but got func(list<any>)', 10)
69566971
enddef
69576972

69586973
" Test type checking for class variable in assignments
@@ -7431,6 +7446,54 @@ def Test_funcref_argtype_returntype_check()
74317446
v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
74327447
enddef
74337448

7449+
def Test_funcref_argtype_invariance_check()
7450+
var lines =<< trim END
7451+
vim9script
7452+
7453+
class A
7454+
endclass
7455+
class B extends A
7456+
endclass
7457+
class C extends B
7458+
endclass
7459+
7460+
var Func: func(B): number
7461+
Func = (o: B): number => 3
7462+
assert_equal(3, Func(B.new()))
7463+
END
7464+
v9.CheckSourceSuccess(lines)
7465+
7466+
lines =<< trim END
7467+
vim9script
7468+
7469+
class A
7470+
endclass
7471+
class B extends A
7472+
endclass
7473+
class C extends B
7474+
endclass
7475+
7476+
var Func: func(B): number
7477+
Func = (o: A): number => 3
7478+
END
7479+
v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7480+
7481+
lines =<< trim END
7482+
vim9script
7483+
7484+
class A
7485+
endclass
7486+
class B extends A
7487+
endclass
7488+
class C extends B
7489+
endclass
7490+
7491+
var Func: func(B): number
7492+
Func = (o: C): number => 3
7493+
END
7494+
v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7495+
enddef
7496+
74347497
" Test for using an operator (e.g. +) with an assignment
74357498
def Test_op_and_assignment()
74367499
# Using += with a class variable

src/testdir/test_vim9_func.vim

+1-1
Original file line numberDiff line numberDiff line change
@@ -1995,7 +1995,7 @@ def Test_varargs_mismatch()
19951995
var res = Map((v) => str2nr(v))
19961996
assert_equal(12, res)
19971997
END
1998-
v9.CheckScriptSuccess(lines)
1998+
v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected func(...any): number but got func(any): number')
19991999
enddef
20002000

20012001
def Test_using_var_as_arg()

src/version.c

+2
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@ static char *(features[]) =
704704

705705
static int included_patches[] =
706706
{ /* Add new patch number below this line */
707+
/**/
708+
2043,
707709
/**/
708710
2042,
709711
/**/

src/vim9type.c

+5
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,11 @@ check_type_maybe(
884884
else
885885
ret = MAYBE;
886886
}
887+
if (ret != FAIL
888+
&& ((expected->tt_flags & TTFLAG_VARARGS)
889+
!= (actual->tt_flags & TTFLAG_VARARGS))
890+
&& expected->tt_argcount != -1)
891+
ret = FAIL;
887892
if (ret != FAIL && expected->tt_argcount != -1
888893
&& actual->tt_min_argcount != -1
889894
&& (actual->tt_argcount == -1

0 commit comments

Comments
 (0)