# HG changeset patch # User Bram Moolenaar # Date 1623788103 -7200 # Node ID 345619f35112834067c9e0188dde5c76f528fa64 # Parent 68f1020e0c69344ce38854ff4b00739bb2d95ae6 patch 8.2.3005: Vim9: using a void value does not give a proper error message Commit: https://github.com/vim/vim/commit/f57b43c230c23117650c956c1f62546a34500fb6 Author: Bram Moolenaar Date: Tue Jun 15 22:13:27 2021 +0200 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 https://github.com/vim/vim/issues/8387) diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -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('\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 \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\_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 diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -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 diff --git a/src/typval.c b/src/typval.c --- a/src/typval.c +++ b/src/typval.c @@ -238,9 +238,11 @@ tv_get_bool_or_number_chk(typval_T *varp 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 *den 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 *v 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; } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3005, +/**/ 3004, /**/ 3003, diff --git a/src/vim9.h b/src/vim9.h --- a/src/vim9.h +++ b/src/vim9.h @@ -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 diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -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: diff --git a/src/vim9execute.c b/src/vim9execute.c --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -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 *inst 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: {