1
0
forked from aniani/vim

patch 8.2.4287: cannot assign empty list with type to variable with list type

Problem:    Cannot assign empty list with any list type to variable with
            specific list type.
Solution:   Use unknown list type for empty list if the specified type is any.
This commit is contained in:
Bram Moolenaar
2022-02-03 12:34:05 +00:00
parent 381692b6f1
commit 2d3ac2e030
4 changed files with 19 additions and 4 deletions

View File

@@ -1249,6 +1249,15 @@ def Test_assignment_var_list()
v9.CheckScriptSuccess(lines) v9.CheckScriptSuccess(lines)
enddef enddef
def Test_assignment_empty_list()
var lines =<< trim END
var l2: list<any> = []
var l: list<string>
l = l2
END
v9.CheckDefAndScriptSuccess(lines)
enddef
def Test_assignment_vim9script() def Test_assignment_vim9script()
var lines =<< trim END var lines =<< trim END
vim9script vim9script

View File

@@ -3461,11 +3461,11 @@ def Test_list_any_type_checked()
enddef enddef
Foo() Foo()
END END
# "any" could be "dict<any>", thus OK
lines[2] = 'var l: list<any>' lines[2] = 'var l: list<any>'
v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<any>', 2) v9.CheckScriptSuccess(lines)
lines[2] = 'var l: list<any> = []' lines[2] = 'var l: list<any> = []'
v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<any>', 2) v9.CheckScriptSuccess(lines)
lines[2] = 'var l: list<any> = [11]' lines[2] = 'var l: list<any> = [11]'
v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2) v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)

View File

@@ -746,6 +746,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
4287,
/**/ /**/
4286, 4286,
/**/ /**/

View File

@@ -344,7 +344,11 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int flags)
list_T *l = tv->vval.v_list; list_T *l = tv->vval.v_list;
listitem_T *li; listitem_T *li;
if (l == NULL || (l->lv_first == NULL && l->lv_type == NULL)) // An empty list has type list<unknown>, unless the type was specified
// and is not list<any>. This matters when assigning to a variable
// with a specific list type.
if (l == NULL || (l->lv_first == NULL
&& (l->lv_type == NULL || l->lv_type->tt_member == &t_any)))
return &t_list_empty; return &t_list_empty;
if ((flags & TVTT_DO_MEMBER) == 0) if ((flags & TVTT_DO_MEMBER) == 0)
return &t_list_any; return &t_list_any;