Patch 8.2.3005
Problem: Vim9: using a void value does not give a proper error message.
Solution: Give a clear error message. (clodes #8387)
Files: src/typval.c, src/vim9compile.c, src/vim9.h, src/vim9execute.c,
src/testdir/test_vim9_expr.vim,
src/testdir/test_vim9_disassemble.vim
*** ../vim-8.2.3004/src/typval.c 2021-06-06 12:33:44.478933711 +0200
--- src/typval.c 2021-06-15 22:02:25.787468663 +0200
***************
*** 238,246 ****
case VAR_BLOB:
emsg(_("E974: Using a Blob as a Number"));
break;
case VAR_UNKNOWN:
case VAR_ANY:
- case VAR_VOID:
case VAR_INSTR:
internal_error_no_abort("tv_get_number(UNKNOWN)");
break;
--- 238,248 ----
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_INSTR:
internal_error_no_abort("tv_get_number(UNKNOWN)");
break;
***************
*** 294,300 ****
return tv_get_bool_or_number_chk(varp, denote, TRUE);
}
! #ifdef FEAT_FLOAT
float_T
tv_get_float(typval_T *varp)
{
--- 296,302 ----
return tv_get_bool_or_number_chk(varp, denote, TRUE);
}
! #if defined(FEAT_FLOAT) || defined(PROTO)
float_T
tv_get_float(typval_T *varp)
{
***************
*** 336,344 ****
case VAR_BLOB:
emsg(_("E975: Using a Blob as a Float"));
break;
case VAR_UNKNOWN:
case VAR_ANY:
- case VAR_VOID:
case VAR_INSTR:
internal_error_no_abort("tv_get_float(UNKNOWN)");
break;
--- 338,348 ----
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_INSTR:
internal_error_no_abort("tv_get_float(UNKNOWN)");
break;
***************
*** 501,509 ****
return channel_to_string_buf(varp, buf);
#endif
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));
--- 505,515 ----
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_INSTR:
semsg(_(e_using_invalid_value_as_string_str),
vartype_name(varp->v_type));
***************
*** 585,590 ****
--- 591,597 ----
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,665 ****
break;
case VAR_UNKNOWN:
case VAR_ANY:
- case VAR_VOID:
internal_error_no_abort("copy_tv(UNKNOWN)");
break;
}
--- 666,671 ----
*** ../vim-8.2.3004/src/vim9compile.c 2021-06-15 11:27:17.713718186 +0200
--- src/vim9compile.c 2021-06-15 22:07:05.490685639 +0200
***************
*** 9679,9686 ****
goto erret;
}
! // Return zero if there is no return at the end.
! generate_instr(&cctx, ISN_RETURN_ZERO);
}
// When compiled with ":silent!" and there was an error don't consider the
--- 9679,9686 ----
goto erret;
}
! // 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,10053 ****
case ISN_REDIREND:
case ISN_REDIRSTART:
case ISN_RETURN:
! case ISN_RETURN_ZERO:
case ISN_SHUFFLE:
case ISN_SLICE:
case ISN_STORE:
--- 10047,10053 ----
case ISN_REDIREND:
case ISN_REDIRSTART:
case ISN_RETURN:
! case ISN_RETURN_VOID:
case ISN_SHUFFLE:
case ISN_SLICE:
case ISN_STORE:
*** ../vim-8.2.3004/src/vim9.h 2021-06-14 20:40:33.590233925 +0200
--- src/vim9.h 2021-06-15 22:07:38.198593822 +0200
***************
*** 91,97 ****
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_FUNCREF, // push a function ref to dfunc isn_arg.funcref
ISN_NEWFUNC, // create a global function from a lambda function
ISN_DEF, // list functions
--- 91,97 ----
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_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
*** ../vim-8.2.3004/src/vim9execute.c 2021-06-15 19:32:35.638516519 +0200
--- src/vim9execute.c 2021-06-15 22:07:29.418618467 +0200
***************
*** 2815,2831 ****
}
break;
! // return from a :def function call
! case ISN_RETURN_ZERO:
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->vval.v_number = 0;
tv->v_lock = 0;
// FALLTHROUGH
case ISN_RETURN:
{
garray_T *trystack = &ectx->ec_trystack;
--- 2815,2832 ----
}
break;
! // 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_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,5083 ****
case ISN_RETURN:
smsg("%s%4d RETURN", pfx, current);
break;
! case ISN_RETURN_ZERO:
! smsg("%s%4d RETURN 0", pfx, current);
break;
case ISN_FUNCREF:
{
--- 5077,5084 ----
case ISN_RETURN:
smsg("%s%4d RETURN", pfx, current);
break;
! case ISN_RETURN_VOID:
! smsg("%s%4d RETURN void", pfx, current);
break;
case ISN_FUNCREF:
{
*** ../vim-8.2.3004/src/testdir/test_vim9_expr.vim 2021-06-08 20:46:42.130585681 +0200
--- src/testdir/test_vim9_expr.vim 2021-06-15 22:08:40.658418425 +0200
***************
*** 2967,2972 ****
--- 2967,2986 ----
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
*** ../vim-8.2.3004/src/testdir/test_vim9_disassemble.vim 2021-06-14 21:08:52.924309067 +0200
--- src/testdir/test_vim9_disassemble.vim 2021-06-15 22:10:19.478140533 +0200
***************
*** 117,123 ****
'\d 2STRING stack\[-1\]\_s*' ..
'\d\+ PUSHS ".txt"\_s*' ..
'\d\+ EXECCONCAT 4\_s*' ..
! '\d\+ RETURN 0',
res)
enddef
--- 117,123 ----
'\d 2STRING stack\[-1\]\_s*' ..
'\d\+ PUSHS ".txt"\_s*' ..
'\d\+ EXECCONCAT 4\_s*' ..
! '\d\+ RETURN void',
res)
enddef
***************
*** 133,139 ****
assert_match('<SNR>\d*_PyHeredoc.*' ..
" python3 << EOF^@ print('hello')^@EOF\\_s*" ..
'\d EXEC_SPLIT python3 << EOF^@ print(''hello'')^@EOF\_s*' ..
! '\d RETURN 0',
res)
enddef
endif
--- 133,139 ----
assert_match('<SNR>\d*_PyHeredoc.*' ..
" python3 << EOF^@ print('hello')^@EOF\\_s*" ..
'\d EXEC_SPLIT python3 << EOF^@ print(''hello'')^@EOF\_s*' ..
! '\d RETURN void',
res)
enddef
endif
***************
*** 153,159 ****
'\d SUBSTITUTE :%s/a/\\=expr/&g#c\_s*' ..
' 0 LOAD $0\_s*' ..
' -------------\_s*' ..
! '\d RETURN 0',
res)
enddef
--- 153,159 ----
'\d SUBSTITUTE :%s/a/\\=expr/&g#c\_s*' ..
' 0 LOAD $0\_s*' ..
' -------------\_s*' ..
! '\d RETURN void',
res)
enddef
***************
*** 181,187 ****
' -------------\_s*' ..
'\d BCALL searchpair(argc 5)\_s*' ..
'\d DROP\_s*' ..
! '\d RETURN 0',
res)
enddef
--- 181,187 ----
' -------------\_s*' ..
'\d BCALL searchpair(argc 5)\_s*' ..
'\d DROP\_s*' ..
! '\d RETURN void',
res)
enddef
***************
*** 209,215 ****
'\d REDIR END\_s*' ..
'\d CONCAT\_s*' ..
'\d STORE $0\_s*' ..
! '\d RETURN 0',
res)
enddef
--- 209,215 ----
'\d REDIR END\_s*' ..
'\d CONCAT\_s*' ..
'\d STORE $0\_s*' ..
! '\d RETURN void',
res)
enddef
***************
*** 228,234 ****
'\d CEXPR pre cexpr\_s*' ..
'\d LOAD $0\_s*' ..
'\d CEXPR core cexpr "cexpr errors"\_s*' ..
! '\d RETURN 0',
res)
enddef
--- 228,234 ----
'\d CEXPR pre cexpr\_s*' ..
'\d LOAD $0\_s*' ..
'\d CEXPR core cexpr "cexpr errors"\_s*' ..
! '\d RETURN void',
res)
enddef
***************
*** 244,250 ****
'\d EXEC norm! m\[jjm\]\_s*' ..
' :''\[,''\]yank\_s*' ..
'\d EXEC :''\[,''\]yank\_s*' ..
! '\d RETURN 0',
res)
enddef
--- 244,250 ----
'\d EXEC norm! m\[jjm\]\_s*' ..
' :''\[,''\]yank\_s*' ..
'\d EXEC :''\[,''\]yank\_s*' ..
! '\d RETURN void',
res)
enddef
***************
*** 258,264 ****
' :3put ="text"\_s*' ..
'\d PUSHS "text"\_s*' ..
'\d PUT = 3\_s*' ..
! '\d RETURN 0',
res)
enddef
--- 258,264 ----
' :3put ="text"\_s*' ..
'\d PUSHS "text"\_s*' ..
'\d PUT = 3\_s*' ..
! '\d RETURN void',
res)
enddef
***************
*** 272,278 ****
' :$-2put a\_s*' ..
'\d RANGE $-2\_s*' ..
'\d PUT a range\_s*' ..
! '\d RETURN 0',
res)
enddef
--- 272,278 ----
' :$-2put a\_s*' ..
'\d RANGE $-2\_s*' ..
'\d PUT a range\_s*' ..
! '\d RETURN void',
res)
enddef
***************
*** 390,396 ****
'\d\+ PUSHNR 1\_s*' ..
'\d\+ LOAD $2\_s*' ..
'\d\+ STOREINDEX blob\_s*' ..
! '\d\+ RETURN 0',
res)
enddef
--- 390,396 ----
'\d\+ PUSHNR 1\_s*' ..
'\d\+ LOAD $2\_s*' ..
'\d\+ STOREINDEX blob\_s*' ..
! '\d\+ RETURN void',
res)
enddef
***************
*** 413,419 ****
'\d LOAD $0\_s*' ..
'\d MEMBER dd\_s*' ..
'\d STOREINDEX any\_s*' ..
! '\d\+ RETURN 0',
res)
enddef
--- 413,419 ----
'\d LOAD $0\_s*' ..
'\d MEMBER dd\_s*' ..
'\d STOREINDEX any\_s*' ..
! '\d\+ RETURN void',
res)
enddef
***************
*** 448,454 ****
'\d\+ STORE $1\_s*' ..
'\d\+ SLICE 2\_s*' ..
'\d\+ STORE $2\_s*' ..
! '\d\+ RETURN 0',
res)
enddef
--- 448,454 ----
'\d\+ STORE $1\_s*' ..
'\d\+ SLICE 2\_s*' ..
'\d\+ STORE $2\_s*' ..
! '\d\+ RETURN void',
res)
enddef
***************
*** 476,482 ****
'\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
'\d\+ LISTAPPEND\_s*' ..
'\d\+ DROP\_s*' ..
! '\d\+ RETURN 0',
res)
enddef
--- 476,482 ----
'\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
'\d\+ LISTAPPEND\_s*' ..
'\d\+ DROP\_s*' ..
! '\d\+ RETURN void',
res)
enddef
***************
*** 503,509 ****
'\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
'\d\+ BLOBAPPEND\_s*' ..
'\d\+ DROP\_s*' ..
! '\d\+ RETURN 0',
res)
enddef
--- 503,509 ----
'\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
'\d\+ BLOBAPPEND\_s*' ..
'\d\+ DROP\_s*' ..
! '\d\+ RETURN void',
res)
enddef
***************
*** 530,536 ****
'\d\+ PUSHNR 2\_s*' ..
'\d\+ BLOBSLICE\_s*' ..
'\d\+ ECHO 1\_s*' ..
! '\d\+ RETURN 0',
res)
enddef
--- 530,536 ----
'\d\+ PUSHNR 2\_s*' ..
'\d\+ BLOBSLICE\_s*' ..
'\d\+ ECHO 1\_s*' ..
! '\d\+ RETURN void',
res)
enddef
***************
*** 720,726 ****
'\d LOAD arg\[-1\]\_s*' ..
'\d CONCAT\_s*' ..
'\d STOREOUTER level 1 $0\_s*' ..
! '\d RETURN 0',
res)
res = execute('disass g:Get')
--- 720,726 ----
'\d LOAD arg\[-1\]\_s*' ..
'\d CONCAT\_s*' ..
'\d STOREOUTER level 1 $0\_s*' ..
! '\d RETURN void',
res)
res = execute('disass g:Get')
***************
*** 754,760 ****
'\d PCALL top (argc 1)\_s*' ..
'\d PCALL end\_s*' ..
'\d DROP\_s*' ..
! '\d RETURN 0',
res)
enddef
--- 754,760 ----
'\d PCALL top (argc 1)\_s*' ..
'\d PCALL end\_s*' ..
'\d DROP\_s*' ..
! '\d RETURN void',
res)
enddef
***************
*** 1012,1018 ****
'\d PUSHS "UserFunc"\_s*' ..
'\d BCALL funcref(argc 1)\_s*' ..
'\d STORE $2\_s*' ..
! '\d RETURN 0',
instr)
enddef
--- 1012,1018 ----
'\d PUSHS "UserFunc"\_s*' ..
'\d BCALL funcref(argc 1)\_s*' ..
'\d STORE $2\_s*' ..
! '\d RETURN void',
instr)
enddef
***************
*** 1039,1045 ****
'var chan1: channel\_s*' ..
'\d PUSHCHANNEL 0\_s*' ..
'\d STORE $2\_s*' ..
! '\d RETURN 0',
instr)
enddef
--- 1039,1045 ----
'var chan1: channel\_s*' ..
'\d PUSHCHANNEL 0\_s*' ..
'\d STORE $2\_s*' ..
! '\d RETURN void',
instr)
enddef
***************
*** 1111,1117 ****
'echomsg "inner"\_s*' ..
'enddef\_s*' ..
'\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
! '\d RETURN 0',
instr)
enddef
--- 1111,1117 ----
'echomsg "inner"\_s*' ..
'enddef\_s*' ..
'\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
! '\d RETURN void',
instr)
enddef
***************
*** 1133,1139 ****
'\d DEF /Info\_s*' ..
'def /Info/\_s*' ..
'\d DEF /Info/\_s*' ..
! '\d RETURN 0',
instr)
enddef
--- 1133,1139 ----
'\d DEF /Info\_s*' ..
'def /Info/\_s*' ..
'\d DEF /Info/\_s*' ..
! '\d RETURN void',
instr)
enddef
***************
*** 1264,1270 ****
'endfor\_s*' ..
'\d\+ JUMP -> 8\_s*' ..
'\d\+ DROP\_s*' ..
! '\d\+ RETURN 0',
instr)
enddef
--- 1264,1270 ----
'endfor\_s*' ..
'\d\+ JUMP -> 8\_s*' ..
'\d\+ DROP\_s*' ..
! '\d\+ RETURN void',
instr)
enddef
***************
*** 1321,1327 ****
'endfor\_s*' ..
'21 JUMP -> 4\_s*' ..
'\d\+ DROP\_s*' ..
! '\d\+ RETURN 0',
instr)
enddef
--- 1321,1327 ----
'endfor\_s*' ..
'21 JUMP -> 4\_s*' ..
'\d\+ DROP\_s*' ..
! '\d\+ RETURN void',
instr)
enddef
***************
*** 1341,1347 ****
'\d NEWLIST size 2\_s*' ..
'\d SETTYPE list<number>\_s*' ..
'\d STORE $0\_s*' ..
! '\d RETURN 0\_s*',
instr)
enddef
--- 1341,1347 ----
'\d NEWLIST size 2\_s*' ..
'\d SETTYPE list<number>\_s*' ..
'\d STORE $0\_s*' ..
! '\d RETURN void\_s*',
instr)
enddef
***************
*** 1828,1834 ****
'echo "" ?? "empty string"\_s*' ..
'\d\+ PUSHS "empty string"\_s*' ..
'\d\+ ECHO 1\_s*' ..
! '\d\+ RETURN 0',
res)
enddef
--- 1828,1834 ----
'echo "" ?? "empty string"\_s*' ..
'\d\+ PUSHS "empty string"\_s*' ..
'\d\+ ECHO 1\_s*' ..
! '\d\+ RETURN void',
res)
enddef
***************
*** 1855,1861 ****
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
'\d PUSHNR 42.*' ..
'\d ECHO 1.*' ..
! '\d RETURN 0',
instr)
else
# condition false, function just returns
--- 1855,1861 ----
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
'\d PUSHNR 42.*' ..
'\d ECHO 1.*' ..
! '\d RETURN void',
instr)
else
# condition false, function just returns
***************
*** 1863,1869 ****
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
'echo 42[ \n]*' ..
'endif[ \n]*' ..
! '\d RETURN 0',
instr)
endif
--- 1863,1869 ----
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
'echo 42[ \n]*' ..
'endif[ \n]*' ..
! '\d RETURN void',
instr)
endif
***************
*** 1901,1907 ****
'\d\+ LOAD $1\_s*' ..
'\d\+ CONCAT\_s*' ..
'\d\+ EXECUTE 1\_s*' ..
! '\d\+ RETURN 0',
res)
enddef
--- 1901,1907 ----
'\d\+ LOAD $1\_s*' ..
'\d\+ CONCAT\_s*' ..
'\d\+ EXECUTE 1\_s*' ..
! '\d\+ RETURN void',
res)
enddef
***************
*** 1920,1926 ****
"echoerr 'went' .. 'wrong'\\_s*" ..
'\d PUSHS "wentwrong"\_s*' ..
'\d ECHOERR 1\_s*' ..
! '\d RETURN 0',
res)
enddef
--- 1920,1926 ----
"echoerr 'went' .. 'wrong'\\_s*" ..
'\d PUSHS "wentwrong"\_s*' ..
'\d ECHOERR 1\_s*' ..
! '\d RETURN void',
res)
enddef
***************
*** 2029,2035 ****
'\d SHUFFLE 2 up 1\_s*' ..
'\d BCALL append(argc 2)\_s*' ..
'\d DROP\_s*' ..
! '\d RETURN 0',
res)
enddef
--- 2029,2035 ----
'\d SHUFFLE 2 up 1\_s*' ..
'\d BCALL append(argc 2)\_s*' ..
'\d DROP\_s*' ..
! '\d RETURN void',
res)
enddef
***************
*** 2052,2058 ****
'\d PUSHS "error"\_s*' ..
'\d ECHOERR 1\_s*' ..
'\d CMDMOD_REV\_s*' ..
! '\d\+ RETURN 0',
res)
enddef
--- 2052,2058 ----
'\d PUSHS "error"\_s*' ..
'\d ECHOERR 1\_s*' ..
'\d CMDMOD_REV\_s*' ..
! '\d\+ RETURN void',
res)
enddef
***************
*** 2081,2087 ****
'\d\+ CMDMOD_REV\_s*' ..
'\d\+ JUMP_IF_FALSE -> \d\+\_s*' ..
'endif\_s*' ..
! '\d\+ RETURN 0',
res)
enddef
--- 2081,2087 ----
'\d\+ CMDMOD_REV\_s*' ..
'\d\+ JUMP_IF_FALSE -> \d\+\_s*' ..
'endif\_s*' ..
! '\d\+ RETURN void',
res)
enddef
***************
*** 2104,2110 ****
'endfor\_s*' ..
'\d JUMP -> 5\_s*' ..
'8 DROP\_s*' ..
! '\d RETURN 0\_s*',
res)
enddef
--- 2104,2110 ----
'endfor\_s*' ..
'\d JUMP -> 5\_s*' ..
'8 DROP\_s*' ..
! '\d RETURN void\_s*',
res)
enddef
***************
*** 2125,2131 ****
'endwhile\_s*' ..
'\d JUMP -> 0\_s*' ..
! '6 RETURN 0\_s*',
res)
enddef
--- 2125,2131 ----
'endwhile\_s*' ..
'\d JUMP -> 0\_s*' ..
! '6 RETURN void\_s*',
res)
enddef
*** ../vim-8.2.3004/src/version.c 2021-06-15 20:06:30.646818721 +0200
--- src/version.c 2021-06-15 21:55:53.120557508 +0200
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 3005,
/**/
--
Article in the first Free Software Magazine: "Bram Moolenaar studied
electrical engineering at the Technical University of Delft and
graduated in 1985 on a multi-processor Unix architecture."
Response by "dimator": Could the school not afford a proper
stage for the ceremony?
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///