]> granicus.if.org Git - vim/commitdiff
patch 8.2.3005: Vim9: using a void value does not give a proper error message v8.2.3005
authorBram Moolenaar <Bram@vim.org>
Tue, 15 Jun 2021 20:13:27 +0000 (22:13 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 15 Jun 2021 20:13:27 +0000 (22:13 +0200)
Problem:    Vim9: using a void value does not give a proper error message.
Solution:   Give a clear error message. (clodes #8387)

src/testdir/test_vim9_disassemble.vim
src/testdir/test_vim9_expr.vim
src/typval.c
src/version.c
src/vim9.h
src/vim9compile.c
src/vim9execute.c

index f09cb1ddda8d9cf8085393345c4707816c93d28b..9d2f697d8a50144a4195d67f86303969c9bedbd1 100644 (file)
@@ -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
 
index 6b51bc78a509a30dc98e408f5a0be8ee2d7a84f6..d7fb1df825c1f7c6593f5ec1e9b4a6b4f0ae95df 100644 (file)
@@ -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
 
 
index a17dbef7efaa8cc40f4af334dc461f195564df9b..b19140d445d4d6581a6fad9d59a217da640c5c94 100644 (file)
@@ -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;
     }
index e8b0ddcf0b8e03123e87b305f3175d19c252f989..21f5b53734800746a975cec29af591369132744a 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3005,
 /**/
     3004,
 /**/
index 04972dcecf9c1b40da42d578c04c5dfd85978519..b8c713358633cd65c85a2c42ce09870ee8ca00b8 100644 (file)
@@ -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
index 83893992131dcaca89771cda62d5fbd897843e79..663a52dc7b5bd5c8f6fcd8e190fab371df6d881f 100644 (file)
@@ -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:
index 96bd24509367bc2ad5a17a294c40eddb643fcbdb..e464732dda8da2b359e4fbd303a0fa60aab93063 100644 (file)
@@ -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:
                {