mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.2.3005: Vim9: using a void value does not give a proper error message
Problem: Vim9: using a void value does not give a proper error message. Solution: Give a clear error message. (clodes #8387)
This commit is contained in:
@@ -117,7 +117,7 @@ def Test_disassemble_exec_expr()
|
||||
'\d 2STRING stack\[-1\]\_s*' ..
|
||||
'\d\+ PUSHS ".txt"\_s*' ..
|
||||
'\d\+ EXECCONCAT 4\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -133,7 +133,7 @@ EOF
|
||||
assert_match('<SNR>\d*_PyHeredoc.*' ..
|
||||
" python3 << EOF^@ print('hello')^@EOF\\_s*" ..
|
||||
'\d EXEC_SPLIT python3 << EOF^@ print(''hello'')^@EOF\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
endif
|
||||
@@ -153,7 +153,7 @@ def Test_disassemble_substitute()
|
||||
'\d SUBSTITUTE :%s/a/\\=expr/&g#c\_s*' ..
|
||||
' 0 LOAD $0\_s*' ..
|
||||
' -------------\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -181,7 +181,7 @@ def Test_disassemble_seachpair()
|
||||
' -------------\_s*' ..
|
||||
'\d BCALL searchpair(argc 5)\_s*' ..
|
||||
'\d DROP\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -209,7 +209,7 @@ def Test_disassemble_redir_var()
|
||||
'\d REDIR END\_s*' ..
|
||||
'\d CONCAT\_s*' ..
|
||||
'\d STORE $0\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -228,7 +228,7 @@ def Test_disassemble_cexpr()
|
||||
'\d CEXPR pre cexpr\_s*' ..
|
||||
'\d LOAD $0\_s*' ..
|
||||
'\d CEXPR core cexpr "cexpr errors"\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -244,7 +244,7 @@ def Test_disassemble_yank_range()
|
||||
'\d EXEC norm! m\[jjm\]\_s*' ..
|
||||
' :''\[,''\]yank\_s*' ..
|
||||
'\d EXEC :''\[,''\]yank\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -258,7 +258,7 @@ def Test_disassemble_put_expr()
|
||||
' :3put ="text"\_s*' ..
|
||||
'\d PUSHS "text"\_s*' ..
|
||||
'\d PUT = 3\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -272,7 +272,7 @@ def Test_disassemble_put_range()
|
||||
' :$-2put a\_s*' ..
|
||||
'\d RANGE $-2\_s*' ..
|
||||
'\d PUT a range\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -390,7 +390,7 @@ def Test_disassemble_store_member()
|
||||
'\d\+ PUSHNR 1\_s*' ..
|
||||
'\d\+ LOAD $2\_s*' ..
|
||||
'\d\+ STOREINDEX blob\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -413,7 +413,7 @@ def Test_disassemble_store_index()
|
||||
'\d LOAD $0\_s*' ..
|
||||
'\d MEMBER dd\_s*' ..
|
||||
'\d STOREINDEX any\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -448,7 +448,7 @@ def Test_disassemble_list_assign()
|
||||
'\d\+ STORE $1\_s*' ..
|
||||
'\d\+ SLICE 2\_s*' ..
|
||||
'\d\+ STORE $2\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -476,7 +476,7 @@ def Test_disassemble_list_add()
|
||||
'\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
|
||||
'\d\+ LISTAPPEND\_s*' ..
|
||||
'\d\+ DROP\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -503,7 +503,7 @@ def Test_disassemble_blob_add()
|
||||
'\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
|
||||
'\d\+ BLOBAPPEND\_s*' ..
|
||||
'\d\+ DROP\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -530,7 +530,7 @@ def Test_disassemble_blob_index_slice()
|
||||
'\d\+ PUSHNR 2\_s*' ..
|
||||
'\d\+ BLOBSLICE\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -720,7 +720,7 @@ def Test_disassemble_closure()
|
||||
'\d LOAD arg\[-1\]\_s*' ..
|
||||
'\d CONCAT\_s*' ..
|
||||
'\d STOREOUTER level 1 $0\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
|
||||
res = execute('disass g:Get')
|
||||
@@ -754,7 +754,7 @@ def Test_disassemble_pcall()
|
||||
'\d PCALL top (argc 1)\_s*' ..
|
||||
'\d PCALL end\_s*' ..
|
||||
'\d DROP\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -1012,7 +1012,7 @@ def Test_disassemble_function()
|
||||
'\d PUSHS "UserFunc"\_s*' ..
|
||||
'\d BCALL funcref(argc 1)\_s*' ..
|
||||
'\d STORE $2\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1039,7 +1039,7 @@ def Test_disassemble_channel()
|
||||
'var chan1: channel\_s*' ..
|
||||
'\d PUSHCHANNEL 0\_s*' ..
|
||||
'\d STORE $2\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1111,7 +1111,7 @@ def Test_disassemble_nested_func()
|
||||
'echomsg "inner"\_s*' ..
|
||||
'enddef\_s*' ..
|
||||
'\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1133,7 +1133,7 @@ def Test_disassemble_nested_def_list()
|
||||
'\d DEF /Info\_s*' ..
|
||||
'def /Info/\_s*' ..
|
||||
'\d DEF /Info/\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1264,7 +1264,7 @@ def Test_disassemble_for_loop_unpack()
|
||||
'endfor\_s*' ..
|
||||
'\d\+ JUMP -> 8\_s*' ..
|
||||
'\d\+ DROP\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1321,7 +1321,7 @@ def Test_disassemble_for_loop_continue()
|
||||
'endfor\_s*' ..
|
||||
'21 JUMP -> 4\_s*' ..
|
||||
'\d\+ DROP\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1341,7 +1341,7 @@ def Test_disassemble_typecast()
|
||||
'\d NEWLIST size 2\_s*' ..
|
||||
'\d SETTYPE list<number>\_s*' ..
|
||||
'\d STORE $0\_s*' ..
|
||||
'\d RETURN 0\_s*',
|
||||
'\d RETURN void\_s*',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1828,7 +1828,7 @@ def Test_dsassemble_falsy_op()
|
||||
'echo "" ?? "empty string"\_s*' ..
|
||||
'\d\+ PUSHS "empty string"\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -1855,7 +1855,7 @@ def Test_disassemble_compare_const()
|
||||
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
|
||||
'\d PUSHNR 42.*' ..
|
||||
'\d ECHO 1.*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
else
|
||||
# condition false, function just returns
|
||||
@@ -1863,7 +1863,7 @@ def Test_disassemble_compare_const()
|
||||
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
|
||||
'echo 42[ \n]*' ..
|
||||
'endif[ \n]*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
endif
|
||||
|
||||
@@ -1901,7 +1901,7 @@ def Test_disassemble_execute()
|
||||
'\d\+ LOAD $1\_s*' ..
|
||||
'\d\+ CONCAT\_s*' ..
|
||||
'\d\+ EXECUTE 1\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -1920,7 +1920,7 @@ def Test_disassemble_echomsg()
|
||||
"echoerr 'went' .. 'wrong'\\_s*" ..
|
||||
'\d PUSHS "wentwrong"\_s*' ..
|
||||
'\d ECHOERR 1\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -2029,7 +2029,7 @@ def Test_shuffle()
|
||||
'\d SHUFFLE 2 up 1\_s*' ..
|
||||
'\d BCALL append(argc 2)\_s*' ..
|
||||
'\d DROP\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -2052,7 +2052,7 @@ def Test_silent()
|
||||
'\d PUSHS "error"\_s*' ..
|
||||
'\d ECHOERR 1\_s*' ..
|
||||
'\d CMDMOD_REV\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -2081,7 +2081,7 @@ def Test_silent_if()
|
||||
'\d\+ CMDMOD_REV\_s*' ..
|
||||
'\d\+ JUMP_IF_FALSE -> \d\+\_s*' ..
|
||||
'endif\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -2104,7 +2104,7 @@ def Test_silent_for()
|
||||
'endfor\_s*' ..
|
||||
'\d JUMP -> 5\_s*' ..
|
||||
'8 DROP\_s*' ..
|
||||
'\d RETURN 0\_s*',
|
||||
'\d RETURN void\_s*',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -2125,7 +2125,7 @@ def Test_silent_while()
|
||||
|
||||
'endwhile\_s*' ..
|
||||
'\d JUMP -> 0\_s*' ..
|
||||
'6 RETURN 0\_s*',
|
||||
'6 RETURN void\_s*',
|
||||
res)
|
||||
enddef
|
||||
|
||||
|
@@ -2967,6 +2967,20 @@ def Test_expr7_method_call()
|
||||
assert_equal([1, 2, 3], sorted)
|
||||
END
|
||||
CheckDefAndScriptSuccess(lines)
|
||||
|
||||
lines =<< trim END
|
||||
def RetVoid()
|
||||
enddef
|
||||
RetVoid()->byte2line()
|
||||
END
|
||||
CheckDefExecAndScriptFailure(lines, 'E1031:')
|
||||
|
||||
lines =<< trim END
|
||||
def RetVoid()
|
||||
enddef
|
||||
RetVoid()->byteidx(3)
|
||||
END
|
||||
CheckDefExecAndScriptFailure(lines, 'E1031:')
|
||||
enddef
|
||||
|
||||
|
||||
|
16
src/typval.c
16
src/typval.c
@@ -238,9 +238,11 @@ tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool)
|
||||
case VAR_BLOB:
|
||||
emsg(_("E974: Using a Blob as a Number"));
|
||||
break;
|
||||
case VAR_VOID:
|
||||
emsg(_(e_cannot_use_void_value));
|
||||
break;
|
||||
case VAR_UNKNOWN:
|
||||
case VAR_ANY:
|
||||
case VAR_VOID:
|
||||
case VAR_INSTR:
|
||||
internal_error_no_abort("tv_get_number(UNKNOWN)");
|
||||
break;
|
||||
@@ -294,7 +296,7 @@ tv_get_bool_chk(typval_T *varp, int *denote)
|
||||
return tv_get_bool_or_number_chk(varp, denote, TRUE);
|
||||
}
|
||||
|
||||
#ifdef FEAT_FLOAT
|
||||
#if defined(FEAT_FLOAT) || defined(PROTO)
|
||||
float_T
|
||||
tv_get_float(typval_T *varp)
|
||||
{
|
||||
@@ -336,9 +338,11 @@ tv_get_float(typval_T *varp)
|
||||
case VAR_BLOB:
|
||||
emsg(_("E975: Using a Blob as a Float"));
|
||||
break;
|
||||
case VAR_VOID:
|
||||
emsg(_(e_cannot_use_void_value));
|
||||
break;
|
||||
case VAR_UNKNOWN:
|
||||
case VAR_ANY:
|
||||
case VAR_VOID:
|
||||
case VAR_INSTR:
|
||||
internal_error_no_abort("tv_get_float(UNKNOWN)");
|
||||
break;
|
||||
@@ -501,9 +505,11 @@ tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
|
||||
return channel_to_string_buf(varp, buf);
|
||||
#endif
|
||||
break;
|
||||
case VAR_VOID:
|
||||
emsg(_(e_cannot_use_void_value));
|
||||
break;
|
||||
case VAR_UNKNOWN:
|
||||
case VAR_ANY:
|
||||
case VAR_VOID:
|
||||
case VAR_INSTR:
|
||||
semsg(_(e_using_invalid_value_as_string_str),
|
||||
vartype_name(varp->v_type));
|
||||
@@ -585,6 +591,7 @@ copy_tv(typval_T *from, typval_T *to)
|
||||
case VAR_NUMBER:
|
||||
case VAR_BOOL:
|
||||
case VAR_SPECIAL:
|
||||
case VAR_VOID:
|
||||
to->vval.v_number = from->vval.v_number;
|
||||
break;
|
||||
case VAR_FLOAT:
|
||||
@@ -659,7 +666,6 @@ copy_tv(typval_T *from, typval_T *to)
|
||||
break;
|
||||
case VAR_UNKNOWN:
|
||||
case VAR_ANY:
|
||||
case VAR_VOID:
|
||||
internal_error_no_abort("copy_tv(UNKNOWN)");
|
||||
break;
|
||||
}
|
||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
3005,
|
||||
/**/
|
||||
3004,
|
||||
/**/
|
||||
|
@@ -91,7 +91,7 @@ typedef enum {
|
||||
ISN_PCALL, // call partial, use isn_arg.pfunc
|
||||
ISN_PCALL_END, // cleanup after ISN_PCALL with cpf_top set
|
||||
ISN_RETURN, // return, result is on top of stack
|
||||
ISN_RETURN_ZERO, // Push zero, then return
|
||||
ISN_RETURN_VOID, // Push void, then return
|
||||
ISN_FUNCREF, // push a function ref to dfunc isn_arg.funcref
|
||||
ISN_NEWFUNC, // create a global function from a lambda function
|
||||
ISN_DEF, // list functions
|
||||
|
@@ -9679,8 +9679,8 @@ nextline:
|
||||
goto erret;
|
||||
}
|
||||
|
||||
// Return zero if there is no return at the end.
|
||||
generate_instr(&cctx, ISN_RETURN_ZERO);
|
||||
// Return void if there is no return at the end.
|
||||
generate_instr(&cctx, ISN_RETURN_VOID);
|
||||
}
|
||||
|
||||
// When compiled with ":silent!" and there was an error don't consider the
|
||||
@@ -10047,7 +10047,7 @@ delete_instr(isn_T *isn)
|
||||
case ISN_REDIREND:
|
||||
case ISN_REDIRSTART:
|
||||
case ISN_RETURN:
|
||||
case ISN_RETURN_ZERO:
|
||||
case ISN_RETURN_VOID:
|
||||
case ISN_SHUFFLE:
|
||||
case ISN_SLICE:
|
||||
case ISN_STORE:
|
||||
|
@@ -2815,17 +2815,18 @@ exec_instructions(ectx_T *ectx)
|
||||
}
|
||||
break;
|
||||
|
||||
// return from a :def function call
|
||||
case ISN_RETURN_ZERO:
|
||||
// return from a :def function call without a value
|
||||
case ISN_RETURN_VOID:
|
||||
if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
|
||||
goto theend;
|
||||
tv = STACK_TV_BOT(0);
|
||||
++ectx->ec_stack.ga_len;
|
||||
tv->v_type = VAR_NUMBER;
|
||||
tv->v_type = VAR_VOID;
|
||||
tv->vval.v_number = 0;
|
||||
tv->v_lock = 0;
|
||||
// FALLTHROUGH
|
||||
|
||||
// return from a :def function call with what is on the stack
|
||||
case ISN_RETURN:
|
||||
{
|
||||
garray_T *trystack = &ectx->ec_trystack;
|
||||
@@ -5076,8 +5077,8 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
|
||||
case ISN_RETURN:
|
||||
smsg("%s%4d RETURN", pfx, current);
|
||||
break;
|
||||
case ISN_RETURN_ZERO:
|
||||
smsg("%s%4d RETURN 0", pfx, current);
|
||||
case ISN_RETURN_VOID:
|
||||
smsg("%s%4d RETURN void", pfx, current);
|
||||
break;
|
||||
case ISN_FUNCREF:
|
||||
{
|
||||
|
Reference in New Issue
Block a user