Skip to content

Commit c967d57

Browse files
committed
patch 8.2.3129: Vim9: imported uninitialized list does not get type checked
Problem: Vim9: imported uninitialized list does not get type checked. Solution: Get type from imported variable.
1 parent f055d45 commit c967d57

7 files changed

Lines changed: 29 additions & 20 deletions

File tree

src/eval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,7 @@ get_lval(
959959
&& lp->ll_tv == &v->di_tv
960960
&& ht != NULL && ht == get_script_local_ht())
961961
{
962-
svar_T *sv = find_typval_in_script(lp->ll_tv, TRUE);
962+
svar_T *sv = find_typval_in_script(lp->ll_tv);
963963

964964
// Vim9 script local variable: get the type
965965
if (sv != NULL)

src/evalvars.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2564,9 +2564,9 @@ eval_variable(
25642564
int ret = OK;
25652565
typval_T *tv = NULL;
25662566
int found = FALSE;
2567-
dictitem_T *v;
25682567
hashtab_T *ht = NULL;
25692568
int cc;
2569+
type_T *type = NULL;
25702570

25712571
// truncate the name, so that we can use strcmp()
25722572
cc = name[len];
@@ -2576,13 +2576,16 @@ eval_variable(
25762576
if ((tv = lookup_debug_var(name)) == NULL)
25772577
{
25782578
// Check for user-defined variables.
2579-
v = find_var(name, &ht, flags & EVAL_VAR_NOAUTOLOAD);
2579+
dictitem_T *v = find_var(name, &ht, flags & EVAL_VAR_NOAUTOLOAD);
2580+
25802581
if (v != NULL)
25812582
{
25822583
tv = &v->di_tv;
25832584
if (dip != NULL)
25842585
*dip = v;
25852586
}
2587+
else
2588+
ht = NULL;
25862589
}
25872590

25882591
if (tv == NULL && (in_vim9script() || STRNCMP(name, "s:", 2) == 0))
@@ -2628,6 +2631,7 @@ eval_variable(
26282631
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
26292632
+ import->imp_var_vals_idx;
26302633
tv = sv->sv_tv;
2634+
type = sv->sv_type;
26312635
}
26322636
}
26332637
else if (in_vim9script())
@@ -2656,13 +2660,10 @@ eval_variable(
26562660
}
26572661
else if (rettv != NULL)
26582662
{
2659-
type_T *type = NULL;
2660-
26612663
if (ht != NULL && ht == get_script_local_ht())
26622664
{
2663-
svar_T *sv = find_typval_in_script(tv, FALSE);
2665+
svar_T *sv = find_typval_in_script(tv);
26642666

2665-
// TODO: check imported variable
26662667
if (sv != NULL)
26672668
type = sv->sv_type;
26682669
}

src/proto/vim9script.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ char_u *vim9_declare_scriptvar(exarg_T *eap, char_u *arg);
1616
void update_vim9_script_var(int create, dictitem_T *di, int flags, typval_T *tv, type_T **type, int do_member);
1717
void hide_script_var(scriptitem_T *si, int idx, int func_defined);
1818
void free_all_script_vars(scriptitem_T *si);
19-
svar_T *find_typval_in_script(typval_T *dest, int give_error);
19+
svar_T *find_typval_in_script(typval_T *dest);
2020
int check_script_var_type(typval_T *dest, typval_T *value, char_u *name, where_T where);
2121
int check_reserved_name(char_u *name);
2222
/* vim: set ft=c : */

src/testdir/test_vim9_script.vim

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,7 @@ def Test_import_as()
13911391
vim9script
13921392
export var one = 1
13931393
export var yes = 'yes'
1394+
export var slist: list<string>
13941395
END
13951396
writefile(export_lines, 'XexportAs')
13961397

@@ -1415,6 +1416,13 @@ def Test_import_as()
14151416
END
14161417
CheckScriptSuccess(import_lines)
14171418

1419+
import_lines =<< trim END
1420+
vim9script
1421+
import {slist as impSlist} from './XexportAs'
1422+
impSlist->add(123)
1423+
END
1424+
CheckScriptFailure(import_lines, 'E1012: Type mismatch; expected string but got number')
1425+
14181426
delete('XexportAs')
14191427
enddef
14201428

@@ -1947,8 +1955,8 @@ def Test_import_rtp()
19471955
'g:imported_rtp = exported',
19481956
]
19491957
writefile(import_lines, 'Ximport_rtp.vim')
1950-
mkdir('import')
1951-
writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
1958+
mkdir('Ximport')
1959+
writefile(s:export_script_lines, 'Ximport/Xexport_rtp.vim')
19521960

19531961
var save_rtp = &rtp
19541962
&rtp = getcwd()
@@ -1960,7 +1968,7 @@ def Test_import_rtp()
19601968
Undo_export_script_lines()
19611969
unlet g:imported_rtp
19621970
delete('Ximport_rtp.vim')
1963-
delete('import', 'rf')
1971+
delete('Ximport', 'rf')
19641972
enddef
19651973

19661974
def Test_import_compile_error()

src/userfunc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,7 @@ deref_func_name(
15121512
{
15131513
if (type != NULL && ht == get_script_local_ht())
15141514
{
1515-
svar_T *sv = find_typval_in_script(&v->di_tv, TRUE);
1515+
svar_T *sv = find_typval_in_script(&v->di_tv);
15161516

15171517
if (sv != NULL)
15181518
*type = sv->sv_type;

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,8 @@ static char *(features[]) =
755755

756756
static int included_patches[] =
757757
{ /* Add new patch number below this line */
758+
/**/
759+
3129,
758760
/**/
759761
3128,
760762
/**/

src/vim9script.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ handle_import(
616616
if (idx < 0 && ufunc == NULL)
617617
goto erret;
618618

619-
// If already imported with the same propertis and the
619+
// If already imported with the same properties and the
620620
// IMP_FLAGS_RELOAD set then we keep that entry. Otherwise create
621621
// a new one (and give an error for an existing import).
622622
imported = find_imported(name, len, cctx);
@@ -806,7 +806,7 @@ update_vim9_script_var(
806806
}
807807
else
808808
{
809-
sv = find_typval_in_script(&di->di_tv, TRUE);
809+
sv = find_typval_in_script(&di->di_tv);
810810
}
811811
if (sv != NULL)
812812
{
@@ -922,11 +922,10 @@ free_all_script_vars(scriptitem_T *si)
922922

923923
/*
924924
* Find the script-local variable that links to "dest".
925-
* Returns NULL if not found and when "give_error" is TRUE this is considered
926-
* an internal error.
925+
* Returns NULL if not found and give an internal error.
927926
*/
928927
svar_T *
929-
find_typval_in_script(typval_T *dest, int give_error)
928+
find_typval_in_script(typval_T *dest)
930929
{
931930
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
932931
int idx;
@@ -945,8 +944,7 @@ find_typval_in_script(typval_T *dest, int give_error)
945944
if (sv->sv_name != NULL && sv->sv_tv == dest)
946945
return sv;
947946
}
948-
if (give_error)
949-
iemsg("find_typval_in_script(): not found");
947+
iemsg("find_typval_in_script(): not found");
950948
return NULL;
951949
}
952950

@@ -961,7 +959,7 @@ check_script_var_type(
961959
char_u *name,
962960
where_T where)
963961
{
964-
svar_T *sv = find_typval_in_script(dest, TRUE);
962+
svar_T *sv = find_typval_in_script(dest);
965963
int ret;
966964

967965
if (sv != NULL)

0 commit comments

Comments
 (0)