# HG changeset patch # User Bram Moolenaar # Date 1594499407 -7200 # Node ID 6a4806e326ddc4a2066ac1046a48b2d36bc14935 # Parent f3bdfe1d93598b4c3c7e0c1b8b9d8d8b7dd7d719 patch 8.2.1183: assert_fails() checks the last error message Commit: https://github.com/vim/vim/commit/9b7bf9e98f06ece595fed7a3ff53ecce89797a53 Author: Bram Moolenaar Date: Sat Jul 11 22:14:59 2020 +0200 patch 8.2.1183: assert_fails() checks the last error message Problem: assert_fails() checks the last error message. Solution: Check the first error, it is more relevant. Fix all the tests that rely on the old behavior. diff --git a/runtime/doc/testing.txt b/runtime/doc/testing.txt --- a/runtime/doc/testing.txt +++ b/runtime/doc/testing.txt @@ -295,8 +295,23 @@ assert_exception({error} [, {msg}]) *a assert_fails({cmd} [, {error} [, {msg}]]) *assert_fails()* Run {cmd} and add an error message to |v:errors| if it does - NOT produce an error. Also see |assert-return|. - When {error} is given it must match in |v:errmsg|. + NOT produce an error or when {error} is not found in the + error message. Also see |assert-return|. + + When {error} is a string it must be found literally in the + first reported error. Most often this will be the error code, + including the colon, e.g. "E123:". > + assert_fails('bad cmd', 'E987:') +< + When {error} is a |List| with one or two strings, these are + used as patterns. The first pattern is matched against the + first reported error: > + assert_fails('cmd', ['E987:.*expected bool']) +< The second pattern, if present, is matched against the last + reported error. To only match the last error use an empty + string for the first error: > + assert_fails('cmd', ['', 'E987:']) +< Note that beeping is not considered an error, and some failing commands only beep. Use |assert_beeps()| for those. diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -3388,7 +3388,7 @@ static char_u *redir_varname = NULL; int var_redir_start(char_u *name, int append) { - int save_emsg; + int called_emsg_before; int err; typval_T tv; @@ -3432,8 +3432,7 @@ var_redir_start(char_u *name, int append // check if we can write to the variable: set it to or append an empty // string - save_emsg = did_emsg; - did_emsg = FALSE; + called_emsg_before = called_emsg; tv.v_type = VAR_STRING; tv.vval.v_string = (char_u *)""; if (append) @@ -3441,9 +3440,7 @@ var_redir_start(char_u *name, int append else set_var_lval(redir_lval, redir_endp, &tv, TRUE, 0, (char_u *)"="); clear_lval(redir_lval); - err = did_emsg; - did_emsg |= save_emsg; - if (err) + if (called_emsg > called_emsg_before) { redir_endp = NULL; // don't store a value, only cleanup var_redir_stop(); diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -220,6 +220,10 @@ EXTERN int emsg_skip INIT(= 0); // d // expression that is skipped EXTERN int emsg_severe INIT(= FALSE); // use message of next of several // emsg() calls for throw +// used by assert_fails() +EXTERN int emsg_assert_fails_used INIT(= FALSE); +EXTERN char_u *emsg_assert_fails_msg INIT(= NULL); + EXTERN int did_endif INIT(= FALSE); // just had ":endif" #endif EXTERN int did_emsg; // set by emsg() when the message diff --git a/src/if_cscope.c b/src/if_cscope.c --- a/src/if_cscope.c +++ b/src/if_cscope.c @@ -2152,7 +2152,6 @@ cs_read_prompt(int i) ch = getc(csinfo[i].fr_fp); if (ch == EOF) { - PERROR("cs_read_prompt EOF"); if (buf != NULL && buf[0] != NUL) (void)semsg(cs_emsg, buf); else if (p_csverbose) diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -654,6 +654,9 @@ emsg_core(char_u *s) return TRUE; } + if (emsg_assert_fails_used && emsg_assert_fails_msg == NULL) + emsg_assert_fails_msg = vim_strsave(s); + // set "v:errmsg", also when using ":silent! cmd" set_vim_var_string(VV_ERRMSG, s, -1); #endif diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -168,9 +168,7 @@ func Test_autocmd_bufunload_avoiding_SEG exe 'autocmd BufUnload ' . (lastbuf + 1) . 'bwipeout!' augroup END - " Todo: check for E937 generated first - " call assert_fails('edit bb.txt', 'E937:') - call assert_fails('edit bb.txt', 'E517:') + call assert_fails('edit bb.txt', ['E937:', 'E517:']) autocmd! test_autocmd_bufunload augroup! test_autocmd_bufunload @@ -1745,9 +1743,7 @@ endfunc func Test_nocatch_wipe_all_buffers() " Real nasty autocommand: wipe all buffers on any event. au * * bwipe * - " Get E93 first? - " call assert_fails('next x', 'E93:') - call assert_fails('next x', 'E517:') + call assert_fails('next x', ['E94:', 'E517:']) bwipe au! endfunc @@ -1756,7 +1752,7 @@ func Test_nocatch_wipe_dummy_buffer() if has('quickfix') " Nasty autocommand: wipe buffer on any event. au * x bwipe - call assert_fails('lv½ /x', 'E480') + call assert_fails('lv½ /x', 'E937') au! endif endfunc @@ -2570,7 +2566,7 @@ func Test_BufDelete_changebuf() augroup END let save_cpo = &cpo set cpo+=f - call assert_fails('r Xfile', 'E484:') + call assert_fails('r Xfile', ['E812:', 'E484:']) call assert_equal('somefile', @%) let &cpo = save_cpo augroup TestAuCmd diff --git a/src/testdir/test_buffer.vim b/src/testdir/test_buffer.vim --- a/src/testdir/test_buffer.vim +++ b/src/testdir/test_buffer.vim @@ -76,7 +76,7 @@ func Test_bunload_with_offset() let caught_E90 = 1 endtry call assert_equal(1, caught_E90) - call assert_fails('$bunload', 'E515:') + call assert_fails('$bunload', 'E90:') endfunc " Test for :buffer, :bnext, :bprevious, :brewind, :blast and :bmodified @@ -278,7 +278,7 @@ func Test_goto_buf_with_confirm() call assert_equal(1, &modified) call assert_equal('', @%) call feedkeys('y', 'L') - call assert_fails('confirm b Xfile', 'E37:') + call assert_fails('confirm b Xfile', ['', 'E37:']) call assert_equal(1, &modified) call assert_equal('', @%) call feedkeys('n', 'L') diff --git a/src/testdir/test_cd.vim b/src/testdir/test_cd.vim --- a/src/testdir/test_cd.vim +++ b/src/testdir/test_cd.vim @@ -4,7 +4,7 @@ source shared.vim func Test_cd_large_path() " This used to crash with a heap write overflow. - call assert_fails('cd ' . repeat('x', 5000), 'E472:') + call assert_fails('cd ' . repeat('x', 5000), 'E344:') endfunc func Test_cd_up_and_down() @@ -93,7 +93,7 @@ func Test_chdir_func() call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t')) " Error case - call assert_fails("call chdir('dir-abcd')", 'E472:') + call assert_fails("call chdir('dir-abcd')", 'E344:') silent! let d = chdir("dir_abcd") call assert_equal("", d) " Should not crash diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -559,7 +559,7 @@ func Test_raw_pipe() call assert_equal(1, found) call assert_fails("call job_stop('abc')", 'E475:') - call assert_fails("call job_stop(job, [])", 'E474:') + call assert_fails("call job_stop(job, [])", 'E730:') call assert_fails("call job_stop(test_null_job())", 'E916:') " Try to use the job and channel where a number is expected. This is not @@ -1641,15 +1641,15 @@ func Test_job_start_fails() call assert_fails("call job_start('ls', {'in_top' : -1})", 'E475:') call assert_fails("call job_start('ls', {'in_bot' : -1})", 'E475:') call assert_fails("call job_start('ls', {'channel' : -1})", 'E475:') - call assert_fails("call job_start('ls', {'callback' : -1})", 'E475:') - call assert_fails("call job_start('ls', {'out_cb' : -1})", 'E475:') - call assert_fails("call job_start('ls', {'err_cb' : -1})", 'E475:') - call assert_fails("call job_start('ls', {'close_cb' : -1})", 'E475:') - call assert_fails("call job_start('ls', {'exit_cb' : -1})", 'E475:') + call assert_fails("call job_start('ls', {'callback' : -1})", 'E921:') + call assert_fails("call job_start('ls', {'out_cb' : -1})", 'E921:') + call assert_fails("call job_start('ls', {'err_cb' : -1})", 'E921:') + call assert_fails("call job_start('ls', {'close_cb' : -1})", 'E921:') + call assert_fails("call job_start('ls', {'exit_cb' : -1})", 'E921:') call assert_fails("call job_start('ls', {'term_name' : []})", 'E475:') call assert_fails("call job_start('ls', {'term_finish' : 'run'})", 'E475:') call assert_fails("call job_start('ls', {'term_api' : []})", 'E475:') - call assert_fails("call job_start('ls', {'stoponexit' : []})", 'E475:') + call assert_fails("call job_start('ls', {'stoponexit' : []})", 'E730:') call assert_fails("call job_start('ls', {'in_io' : 'file'})", 'E920:') call assert_fails("call job_start('ls', {'out_io' : 'file'})", 'E920:') call assert_fails("call job_start('ls', {'err_io' : 'file'})", 'E920:') diff --git a/src/testdir/test_clientserver.vim b/src/testdir/test_clientserver.vim --- a/src/testdir/test_clientserver.vim +++ b/src/testdir/test_clientserver.vim @@ -84,7 +84,7 @@ func Test_client_server() call remote_send(v:servername, ":let g:testvar2 = 75\") call feedkeys('', 'x') call assert_equal(75, g:testvar2) - call assert_fails('let v = remote_expr(v:servername, "/2")', 'E449:') + call assert_fails('let v = remote_expr(v:servername, "/2")', ['E15:.*/2']) call remote_send(name, ":call server2client(expand(''), 'got it')\", 'g:myserverid') call assert_equal('got it', g:myserverid->remote_read(2)) @@ -166,8 +166,8 @@ func Test_client_server() call assert_fails('call remote_startserver([])', 'E730:') call assert_fails("let x = remote_peek([])", 'E730:') - call assert_fails("let x = remote_read('vim10')", 'E277:') - call assert_fails("call server2client('abc', 'xyz')", 'E258:') + call assert_fails("let x = remote_read('vim10')", ['E573:.*vim10']) + call assert_fails("call server2client('abc', 'xyz')", ['E573:.*abc']) endfunc " Uncomment this line to get a debugging log diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -855,7 +855,7 @@ func Test_cmdline_search_range() call assert_equal('B', getline(2)) let @/ = 'apple' - call assert_fails('\/print', 'E486:') + call assert_fails('\/print', ['E486:.*apple']) bwipe! endfunc @@ -972,7 +972,7 @@ func Test_verbosefile() call assert_match("foo\nbar", join(log, "\n")) call delete('Xlog') call mkdir('Xdir') - call assert_fails('set verbosefile=Xdir', 'E474:') + call assert_fails('set verbosefile=Xdir', ['E484:.*Xdir', 'E474:']) call delete('Xdir', 'd') endfunc @@ -1208,7 +1208,7 @@ func Test_cmdwin_jump_to_win() call assert_fails('call feedkeys("q:\\\", "xt")', 'E11:') new set modified - call assert_fails('call feedkeys("q/:qall\", "xt")', 'E162:') + call assert_fails('call feedkeys("q/:qall\", "xt")', ['E37:', 'E162:']) close! call feedkeys("q/:close\", "xt") call assert_equal(1, winnr('$')) diff --git a/src/testdir/test_cpoptions.vim b/src/testdir/test_cpoptions.vim --- a/src/testdir/test_cpoptions.vim +++ b/src/testdir/test_cpoptions.vim @@ -104,7 +104,7 @@ func Test_cpo_C() source Xfile call assert_equal([1, 2], g:l) set cpo+=C - call assert_fails('source Xfile', 'E10:') + call assert_fails('source Xfile', ['E697:', 'E10:']) call delete('Xfile') let &cpo = save_cpo endfunc diff --git a/src/testdir/test_cscope.vim b/src/testdir/test_cscope.vim --- a/src/testdir/test_cscope.vim +++ b/src/testdir/test_cscope.vim @@ -189,7 +189,7 @@ func Test_cscopeWithCscopeConnections() " Test: 'cst' option set nocst - call assert_fails('tag TEST_COUNT', 'E426:') + call assert_fails('tag TEST_COUNT', 'E433:') set cst let a = execute('tag TEST_COUNT') call assert_match('(1 of 1): <> #define TEST_COUNT 50000', a) diff --git a/src/testdir/test_excmd.vim b/src/testdir/test_excmd.vim --- a/src/testdir/test_excmd.vim +++ b/src/testdir/test_excmd.vim @@ -335,8 +335,8 @@ func Test_redir_cmd() call assert_fails('redir abc', 'E475:') call assert_fails('redir => 1abc', 'E474:') call assert_fails('redir => a b', 'E488:') - call assert_fails('redir => abc[1]', 'E474:') - let b=0zFF + call assert_fails('redir => abc[1]', 'E121:') + let b = 0zFF call assert_fails('redir =>> b', 'E734:') unlet b diff --git a/src/testdir/test_expr.vim b/src/testdir/test_expr.vim --- a/src/testdir/test_expr.vim +++ b/src/testdir/test_expr.vim @@ -478,7 +478,7 @@ func Test_setmatches() endif eval set->setmatches() call assert_equal(exp, getmatches()) - call assert_fails('let m = setmatches([], [])', 'E957:') + call assert_fails('let m = setmatches([], [])', 'E745:') endfunc func Test_empty_concatenate() diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -224,7 +224,7 @@ func Test_str2nr() if has('float') call assert_fails('call str2nr(1.2)', 'E806:') endif - call assert_fails('call str2nr(10, [])', 'E474:') + call assert_fails('call str2nr(10, [])', 'E745:') endfunc func Test_strftime() @@ -1702,11 +1702,11 @@ func Test_libcall_libcallnr() call assert_equal(4, 'abcd'->libcallnr(libc, 'strlen')) call assert_equal(char2nr('A'), char2nr('a')->libcallnr(libc, 'toupper')) - call assert_fails("call libcall(libc, 'Xdoesnotexist_', '')", 'E364:') - call assert_fails("call libcallnr(libc, 'Xdoesnotexist_', '')", 'E364:') + call assert_fails("call libcall(libc, 'Xdoesnotexist_', '')", ['', 'E364:']) + call assert_fails("call libcallnr(libc, 'Xdoesnotexist_', '')", ['', 'E364:']) - call assert_fails("call libcall('Xdoesnotexist_', 'getenv', 'HOME')", 'E364:') - call assert_fails("call libcallnr('Xdoesnotexist_', 'strlen', 'abcd')", 'E364:') + call assert_fails("call libcall('Xdoesnotexist_', 'getenv', 'HOME')", ['', 'E364:']) + call assert_fails("call libcallnr('Xdoesnotexist_', 'strlen', 'abcd')", ['', 'E364:']) endfunc sandbox function Fsandbox() diff --git a/src/testdir/test_global.vim b/src/testdir/test_global.vim --- a/src/testdir/test_global.vim +++ b/src/testdir/test_global.vim @@ -36,7 +36,7 @@ endfunc func Test_global_error() call assert_fails('g\\a', 'E10:') call assert_fails('g', 'E148:') - call assert_fails('g/\(/y', 'E476:') + call assert_fails('g/\(/y', 'E54:') endfunc " Test for printing lines using :g with different search patterns diff --git a/src/testdir/test_json.vim b/src/testdir/test_json.vim --- a/src/testdir/test_json.vim +++ b/src/testdir/test_json.vim @@ -181,7 +181,7 @@ func Test_json_decode() call assert_fails('call json_decode("{\"n\",1}")', "E491:") call assert_fails('call json_decode("{-}")', "E491:") if has('float') - call assert_fails('call json_decode("{3.14:1}")', "E474:") + call assert_fails('call json_decode("{3.14:1}")', "E806:") endif call assert_fails('call json_decode("[foobar]")', "E491:") @@ -292,25 +292,25 @@ func Test_js_decode() call assert_equal({'n': 1}, js_decode('{"n":1,}')) call assert_equal({'n': '1'}, js_decode("{'n':'1',}")) - call assert_fails('call js_decode("\"")', "E474:") - call assert_fails('call js_decode("blah")', "E474:") - call assert_fails('call js_decode("true blah")', "E474:") - call assert_fails('call js_decode("")', "E474:") + call assert_fails('call js_decode("\"")', "E491:") + call assert_fails('call js_decode("blah")', "E491:") + call assert_fails('call js_decode("true blah")', "E488:") + call assert_fails('call js_decode("")', "E491:") - call assert_fails('call js_decode("{")', "E474:") - call assert_fails('call js_decode("{foobar}")', "E474:") - call assert_fails('call js_decode("{\"n\",")', "E474:") - call assert_fails('call js_decode("{\"n\":")', "E474:") - call assert_fails('call js_decode("{\"n\":1")', "E474:") - call assert_fails('call js_decode("{\"n\":1,")', "E474:") - call assert_fails('call js_decode("{\"n\",1}")', "E474:") - call assert_fails('call js_decode("{-}")', "E474:") + call assert_fails('call js_decode("{")', "E491:") + call assert_fails('call js_decode("{foobar}")', "E491:") + call assert_fails('call js_decode("{\"n\",")', "E491:") + call assert_fails('call js_decode("{\"n\":")', "E491:") + call assert_fails('call js_decode("{\"n\":1")', "E491:") + call assert_fails('call js_decode("{\"n\":1,")', "E491:") + call assert_fails('call js_decode("{\"n\",1}")', "E491:") + call assert_fails('call js_decode("{-}")', "E491:") - call assert_fails('call js_decode("[foobar]")', "E474:") - call assert_fails('call js_decode("[")', "E474:") - call assert_fails('call js_decode("[1")', "E474:") - call assert_fails('call js_decode("[1,")', "E474:") - call assert_fails('call js_decode("[1 2]")', "E474:") + call assert_fails('call js_decode("[foobar]")', "E491:") + call assert_fails('call js_decode("[")', "E491:") + call assert_fails('call js_decode("[1")', "E491:") + call assert_fails('call js_decode("[1,")', "E491:") + call assert_fails('call js_decode("[1 2]")', "E491:") call assert_equal(s:varl5, js_decode(s:jsl5)) endfunc diff --git a/src/testdir/test_let.vim b/src/testdir/test_let.vim --- a/src/testdir/test_let.vim +++ b/src/testdir/test_let.vim @@ -279,7 +279,7 @@ func Test_let_errors() let l = [1, 2, 3] call assert_fails('let l[:] = 5', 'E709:') - call assert_fails('let x:lnum=5', 'E488:') + call assert_fails('let x:lnum=5', ['E121:', 'E488:']) call assert_fails('let v:=5', 'E461:') call assert_fails('let [a]', 'E474:') call assert_fails('let [a, b] = [', 'E697:') diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim --- a/src/testdir/test_listdict.vim +++ b/src/testdir/test_listdict.vim @@ -674,10 +674,10 @@ func Test_reverse_sort_uniq() endif call assert_fails('call reverse("")', 'E899:') - call assert_fails('call uniq([1, 2], {x, y -> []})', 'E882:') + call assert_fails('call uniq([1, 2], {x, y -> []})', 'E745:') call assert_fails("call sort([1, 2], function('min'), 1)", "E715:") call assert_fails("call sort([1, 2], function('invalid_func'))", "E700:") - call assert_fails("call sort([1, 2], function('min'))", "E702:") + call assert_fails("call sort([1, 2], function('min'))", "E118:") endfunc " reduce a list or a blob @@ -960,7 +960,7 @@ func Test_listdict_index() call assert_fails('echo d[1:2]', 'E719:') call assert_fails("let v = [4, 6][{-> 1}]", 'E729:') call assert_fails("let v = range(5)[2:[]]", 'E730:') - call assert_fails("let v = range(5)[2:{-> 2}(]", 'E116:') + call assert_fails("let v = range(5)[2:{-> 2}(]", ['E15:', 'E116:']) call assert_fails("let v = range(5)[2:3", 'E111:') call assert_fails("let l = insert([1,2,3], 4, 10)", 'E684:') call assert_fails("let l = insert([1,2,3], 4, -10)", 'E684:') diff --git a/src/testdir/test_listener.vim b/src/testdir/test_listener.vim --- a/src/testdir/test_listener.vim +++ b/src/testdir/test_listener.vim @@ -210,8 +210,8 @@ func Test_listener_args() " Invalid arguments call assert_fails('call listener_add([])', 'E921:') - call assert_fails('call listener_add("s:StoreListArgs", [])', 'E158:') - call assert_fails('call listener_flush([])', 'E158:') + call assert_fails('call listener_add("s:StoreListArgs", [])', 'E730:') + call assert_fails('call listener_flush([])', 'E730:') endfunc func s:StoreBufList(buf, start, end, added, list) diff --git a/src/testdir/test_match.vim b/src/testdir/test_match.vim --- a/src/testdir/test_match.vim +++ b/src/testdir/test_match.vim @@ -160,7 +160,7 @@ endfunc func Test_matchadd_error() call assert_fails("call matchadd('GroupDoesNotExist', 'X')", 'E28:') - call assert_fails("call matchadd('Search', '\\(')", 'E475:') + call assert_fails("call matchadd('Search', '\\(')", 'E54:') call assert_fails("call matchadd('Search', 'XXX', 1, 123, 1)", 'E715:') call assert_fails("call matchadd('Error', 'XXX', 1, 3)", 'E798:') call assert_fails("call matchadd('Error', 'XXX', 1, 0)", 'E799:') diff --git a/src/testdir/test_menu.vim b/src/testdir/test_menu.vim --- a/src/testdir/test_menu.vim +++ b/src/testdir/test_menu.vim @@ -153,7 +153,7 @@ func Test_menu_errors() call assert_fails('menu Test.Foo.Bar', 'E327:') call assert_fails('cmenu Test.Foo', 'E328:') call assert_fails('emenu x Test.Foo', 'E475:') - call assert_fails('emenu Test.Foo.Bar', 'E334:') + call assert_fails('emenu Test.Foo.Bar', 'E327:') call assert_fails('menutranslate Test', 'E474:') silent! unmenu Foo diff --git a/src/testdir/test_method.vim b/src/testdir/test_method.vim --- a/src/testdir/test_method.vim +++ b/src/testdir/test_method.vim @@ -131,9 +131,9 @@ func Test_method_syntax() eval [1, 2, 3] \ ->sort( \ ) - call assert_fails('eval [1, 2, 3]-> sort()', 'E260:') + call assert_fails('eval [1, 2, 3]-> sort()', 'E15:') call assert_fails('eval [1, 2, 3]->sort ()', 'E274:') - call assert_fails('eval [1, 2, 3]-> sort ()', 'E260:') + call assert_fails('eval [1, 2, 3]-> sort ()', 'E15:') endfunc func Test_method_lambda() diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim --- a/src/testdir/test_normal.vim +++ b/src/testdir/test_normal.vim @@ -1384,7 +1384,7 @@ func Test_normal23_K() call setline(1, '---') call assert_fails('normal! ggv2lK', 'E349:') call setline(1, ['abc', 'xyz']) - call assert_fails("normal! gg2lv2h\", 'E426:') + call assert_fails("normal! gg2lv2h\", 'E433:') call assert_beeps("normal! ggVjK") " clean up diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim --- a/src/testdir/test_popup.vim +++ b/src/testdir/test_popup.vim @@ -367,7 +367,7 @@ func Test_completefunc_opens_new_window_ setlocal completefunc=DummyCompleteTwo call setline(1, 'two') /^two - call assert_fails('call feedkeys("A\\\\", "x")', 'E764:') + call assert_fails('call feedkeys("A\\\\", "x")', 'E839:') call assert_notequal(winid, win_getid()) q! call assert_equal(winid, win_getid()) diff --git a/src/testdir/test_python2.vim b/src/testdir/test_python2.vim --- a/src/testdir/test_python2.vim +++ b/src/testdir/test_python2.vim @@ -73,7 +73,7 @@ func Test_pydo() " Try modifying a buffer with 'nomodifiable' set set nomodifiable - call assert_fails('pydo toupper(line)', 'cannot save undo information') + call assert_fails('pydo toupper(line)', 'E21:') set modifiable " Invalid command diff --git a/src/testdir/test_python3.vim b/src/testdir/test_python3.vim --- a/src/testdir/test_python3.vim +++ b/src/testdir/test_python3.vim @@ -90,7 +90,7 @@ func Test_py3do() " Try modifying a buffer with 'nomodifiable' set set nomodifiable - call assert_fails('py3do toupper(line)', 'cannot save undo information') + call assert_fails('py3do toupper(line)', 'E21:') set modifiable " Invalid command @@ -290,7 +290,7 @@ func Test_python3_vim_val() call assert_equal("\nNone", execute('py3 print(vim.eval("v:none"))')) call assert_equal("\nb'\\xab\\x12'", execute('py3 print(vim.eval("0zab12"))')) - call assert_fails('py3 vim.eval("1+")', 'vim.error: invalid expression') + call assert_fails('py3 vim.eval("1+")', 'E15: Invalid expression') endfunc " Test range objects, see :help python-range @@ -305,10 +305,10 @@ func Test_python3_range() call assert_equal('3', py3eval('b[2]')) call assert_equal('4', py3eval('r[2]')) - call assert_fails('py3 r[3] = "x"', 'IndexError: line number out of range') - call assert_fails('py3 x = r[3]', 'IndexError: line number out of range') - call assert_fails('py3 r["a"] = "x"', 'TypeError: index must be int or slice, not str') - call assert_fails('py3 x = r["a"]', 'TypeError: index must be int or slice, not str') + call assert_fails('py3 r[3] = "x"', ['Traceback', 'IndexError: line number out of range']) + call assert_fails('py3 x = r[3]', ['Traceback', 'IndexError: line number out of range']) + call assert_fails('py3 r["a"] = "x"', ['Traceback', 'TypeError: index must be int or slice, not str']) + call assert_fails('py3 x = r["a"]', ['Traceback', 'TypeError: index must be int or slice, not str']) py3 del r[:] call assert_equal(['1', '5', '6'], getline(1, '$')) diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -693,7 +693,7 @@ func s:test_xhelpgrep(cchar) " Search for non existing help string call assert_fails('Xhelpgrep a1b2c3', 'E480:') " Invalid regular expression - call assert_fails('Xhelpgrep \@"', 'E33:') call assert_fails('exe "normal ?~\"', 'E33:') set regexpengine=2 - call assert_fails('exe "normal /~\"', 'E383:') - call assert_fails('exe "normal ?~\"', 'E383:') + call assert_fails('exe "normal /~\"', ['E33:', 'E383:']) + call assert_fails('exe "normal ?~\"', ['E33:', 'E383:']) set regexpengine& call writefile(v:errors, 'Xresult') qall! diff --git a/src/testdir/test_signs.vim b/src/testdir/test_signs.vim --- a/src/testdir/test_signs.vim +++ b/src/testdir/test_signs.vim @@ -458,13 +458,13 @@ func Test_sign_funcs() call assert_fails('call sign_place(5, "", "sign1", "@", {"lnum" : 10})', \ 'E158:') call assert_fails('call sign_place(5, "", "sign1", [], {"lnum" : 10})', - \ 'E158:') + \ 'E730:') call assert_fails('call sign_place(21, "", "sign1", "Xsign", \ {"lnum" : -1})', 'E474:') call assert_fails('call sign_place(22, "", "sign1", "Xsign", \ {"lnum" : 0})', 'E474:') call assert_fails('call sign_place(22, "", "sign1", "Xsign", - \ {"lnum" : []})', 'E474:') + \ {"lnum" : []})', 'E745:') call assert_equal(-1, sign_place(1, "*", "sign1", "Xsign", {"lnum" : 10})) " Tests for sign_getplaced() @@ -1724,7 +1724,7 @@ func Test_sign_jump_func() call assert_fails("call sign_jump(5, 'g5', 'foo')", 'E157:') call assert_fails('call sign_jump([], "", "foo")', 'E745:') call assert_fails('call sign_jump(2, [], "foo")', 'E730:') - call assert_fails('call sign_jump(2, "", {})', 'E158:') + call assert_fails('call sign_jump(2, "", {})', 'E731:') call assert_fails('call sign_jump(2, "", "baz")', 'E158:') sign unplace * group=* diff --git a/src/testdir/test_spell.vim b/src/testdir/test_spell.vim --- a/src/testdir/test_spell.vim +++ b/src/testdir/test_spell.vim @@ -334,7 +334,7 @@ func Test_spellsuggest_expr_errors() return [[{}, {}]] endfunc set spellsuggest=expr:MySuggest3() - call assert_fails("call spellsuggest('baord')", 'E728:') + call assert_fails("call spellsuggest('baord')", 'E731:') set nospell spellsuggest& delfunc MySuggest diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim --- a/src/testdir/test_substitute.vim +++ b/src/testdir/test_substitute.vim @@ -235,7 +235,7 @@ func Test_substitute_errors() call assert_fails('s/FOO/bar/', 'E486:') call assert_fails('s/foo/bar/@', 'E488:') - call assert_fails('s/\(/bar/', 'E476:') + call assert_fails('s/\(/bar/', 'E54:') call assert_fails('s afooabara', 'E146:') call assert_fails('s\\a', 'E10:') @@ -817,9 +817,9 @@ endfunc func Test_sub_with_no_last_pat() let lines =<< trim [SCRIPT] call assert_fails('~', 'E33:') - call assert_fails('s//abc/g', 'E476:') - call assert_fails('s\/bar', 'E476:') - call assert_fails('s\&bar&', 'E476:') + call assert_fails('s//abc/g', 'E35:') + call assert_fails('s\/bar', 'E35:') + call assert_fails('s\&bar&', 'E33:') call writefile(v:errors, 'Xresult') qall! [SCRIPT] diff --git a/src/testdir/test_syntax.vim b/src/testdir/test_syntax.vim --- a/src/testdir/test_syntax.vim +++ b/src/testdir/test_syntax.vim @@ -348,7 +348,7 @@ func Test_syntax_invalid_arg() call assert_fails('syntax sync x', 'E404:') call assert_fails('syntax keyword Abc a[', 'E789:') call assert_fails('syntax keyword Abc a[bc]d', 'E890:') - call assert_fails('syntax cluster Abc add=A add=', 'E475:') + call assert_fails('syntax cluster Abc add=A add=', 'E406:') " Test for too many \z\( and unmatched \z\( " Not able to use assert_fails() here because both E50:/E879: and E475: diff --git a/src/testdir/test_tagfunc.vim b/src/testdir/test_tagfunc.vim --- a/src/testdir/test_tagfunc.vim +++ b/src/testdir/test_tagfunc.vim @@ -73,7 +73,7 @@ func Test_tagfunc() return v:null endfunc set tags= tfu=NullTagFunc - call assert_fails('tag nothing', 'E426') + call assert_fails('tag nothing', 'E433') delf NullTagFunc bwipe! diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim --- a/src/testdir/test_tagjump.vim +++ b/src/testdir/test_tagjump.vim @@ -8,7 +8,7 @@ func Test_ptag_with_notagstack() CheckFeature quickfix set notagstack - call assert_fails('ptag does_not_exist_tag_name', 'E426') + call assert_fails('ptag does_not_exist_tag_name', 'E433') set tagstack&vim endfunc @@ -345,7 +345,7 @@ func Test_tagjump_etags() \ "Xmain.c,64", \ ";;;;\x7f1,0", \ ], 'Xtags') - call assert_fails('tag foo', 'E426:') + call assert_fails('tag foo', 'E431:') call delete('Xtags') call delete('Xtags2') diff --git a/src/testdir/test_taglist.vim b/src/testdir/test_taglist.vim --- a/src/testdir/test_taglist.vim +++ b/src/testdir/test_taglist.vim @@ -84,7 +84,7 @@ func Test_taglist_ctags_etags() endfunc func Test_tags_too_long() - call assert_fails('tag ' . repeat('x', 1020), 'E426') + call assert_fails('tag ' . repeat('x', 1020), ['E433', 'E426']) tags endfunc diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -65,7 +65,7 @@ func Test_terminal_make_change() setlocal modifiable exe "normal Axxx\" - call assert_fails(buf . 'bwipe', 'E517') + call assert_fails(buf . 'bwipe', ['E89:', 'E517']) undo exe buf . 'bwipe' @@ -89,7 +89,7 @@ endfunc func Test_terminal_wipe_buffer() let buf = Run_shell_in_terminal({}) - call assert_fails(buf . 'bwipe', 'E517') + call assert_fails(buf . 'bwipe', ['E89', 'E517']) exe buf . 'bwipe!' call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) call assert_equal("", bufname(buf)) @@ -635,7 +635,7 @@ endfunc func Test_terminal_list_args() let buf = term_start([&shell, &shellcmdflag, 'echo "123"']) - call assert_fails(buf . 'bwipe', 'E517') + call assert_fails(buf . 'bwipe', ['E89', 'E517']) exe buf . 'bwipe!' call assert_equal("", bufname(buf)) endfunction @@ -981,19 +981,19 @@ func Test_terminal_term_start_empty_comm let cmd = "call term_start(0, {'curwin' : 1, 'term_finish' : 'close'})" call assert_fails(cmd, 'E474') let cmd = "call term_start('', {'term_name' : []})" - call assert_fails(cmd, 'E475') + call assert_fails(cmd, 'E730') let cmd = "call term_start('', {'term_finish' : 'axby'})" call assert_fails(cmd, 'E475') let cmd = "call term_start('', {'eof_chars' : []})" - call assert_fails(cmd, 'E475:') + call assert_fails(cmd, 'E730:') let cmd = "call term_start('', {'term_kill' : []})" - call assert_fails(cmd, 'E475:') + call assert_fails(cmd, 'E730:') let cmd = "call term_start('', {'tty_type' : []})" - call assert_fails(cmd, 'E475:') + call assert_fails(cmd, 'E730:') let cmd = "call term_start('', {'tty_type' : 'abc'})" call assert_fails(cmd, 'E475:') let cmd = "call term_start('', {'term_highlight' : []})" - call assert_fails(cmd, 'E475:') + call assert_fails(cmd, 'E730:') if has('gui') || has('termguicolors') let cmd = "call term_start('', {'ansi_colors' : 'abc'})" call assert_fails(cmd, 'E475:') @@ -1242,7 +1242,7 @@ func Test_terminal_dumpload() let closedbuf = winbufnr('') quit call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': closedbuf})", 'E475:') - call assert_fails('call term_dumpload([])', 'E474:') + call assert_fails('call term_dumpload([])', 'E730:') call assert_fails('call term_dumpload("xabcy.dump")', 'E485:') quit @@ -1272,7 +1272,7 @@ func Test_terminal_dumpdiff() call assert_equal(' bbbbbbbbbbbbbbbbbb ', getline(26)[0:29]) quit - call assert_fails('call term_dumpdiff("X1.dump", [])', 'E474:') + call assert_fails('call term_dumpdiff("X1.dump", [])', 'E730:') call assert_fails('call term_dumpdiff("X1.dump", "X2.dump")', 'E485:') call writefile([], 'X1.dump') call assert_fails('call term_dumpdiff("X1.dump", "X2.dump")', 'E485:') @@ -1555,7 +1555,7 @@ func Test_terminal_api_call() call assert_equal(['hello', 123], g:called_arg2) call StopVimInTerminal(buf) - call assert_fails("call term_start('ls', {'term_api' : []})", 'E475:') + call assert_fails("call term_start('ls', {'term_api' : []})", 'E730:') unlet! g:called_bufnum2 unlet! g:called_arg2 @@ -1761,7 +1761,7 @@ func Test_terminal_ansicolors_func() eval buf->term_setansicolors(colors) let colors[4] = 'Invalid' - call assert_fails('call term_setansicolors(buf, colors)', 'E474:') + call assert_fails('call term_setansicolors(buf, colors)', 'E254:') call assert_fails('call term_setansicolors(buf, {})', 'E714:') call StopShellInTerminal(buf) diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -1214,7 +1214,7 @@ func Test_prop_func_invalid_args() call assert_fails('call prop_clear(1, 2, [])', 'E715:') call assert_fails('call prop_clear(-1, 2)', 'E16:') call assert_fails('call prop_find(test_null_dict())', 'E474:') - call assert_fails('call prop_find({"bufnr" : []})', 'E158:') + call assert_fails('call prop_find({"bufnr" : []})', 'E730:') call assert_fails('call prop_find({})', 'E968:') call assert_fails('call prop_find({}, "x")', 'E474:') call assert_fails('call prop_find({"lnum" : -2})', 'E16:') @@ -1223,11 +1223,11 @@ func Test_prop_func_invalid_args() call assert_fails('call prop_remove([])', 'E474:') call assert_fails('call prop_remove({}, -2)', 'E16:') call assert_fails('call prop_remove({})', 'E968:') - call assert_fails('call prop_type_add([], {})', 'E474:') + call assert_fails('call prop_type_add([], {})', 'E730:') call assert_fails("call prop_type_change('long', {'xyz' : 10})", 'E971:') - call assert_fails("call prop_type_delete([])", 'E474:') + call assert_fails("call prop_type_delete([])", 'E730:') call assert_fails("call prop_type_delete('xyz', [])", 'E715:') - call assert_fails("call prop_type_get([])", 'E474:') + call assert_fails("call prop_type_get([])", 'E730:') call assert_fails("call prop_type_get('', [])", 'E474:') call assert_fails("call prop_type_list([])", 'E715:') endfunc diff --git a/src/testdir/test_trycatch.vim b/src/testdir/test_trycatch.vim --- a/src/testdir/test_trycatch.vim +++ b/src/testdir/test_trycatch.vim @@ -2000,7 +2000,7 @@ endfunc func Test_try_catch_errors() call assert_fails('throw |', 'E471:') call assert_fails("throw \n ", 'E471:') - call assert_fails('catch abc', 'E603:') + call assert_fails('catch abc', 'E654:') call assert_fails('try | let i = 1| finally | catch | endtry', 'E604:') call assert_fails('finally', 'E606:') call assert_fails('try | finally | finally | endtry', 'E607:') diff --git a/src/testdir/test_utf8.vim b/src/testdir/test_utf8.vim --- a/src/testdir/test_utf8.vim +++ b/src/testdir/test_utf8.vim @@ -20,7 +20,7 @@ func Test_strchars() call assert_equal(exp[i][1], inp[i]->strchars(0)) call assert_equal(exp[i][2], strchars(inp[i], 1)) endfor - call assert_fails("let v=strchars('abc', [])", 'E474:') + call assert_fails("let v=strchars('abc', [])", 'E745:') call assert_fails("let v=strchars('abc', 2)", 'E474:') endfunc 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 @@ -34,8 +34,8 @@ def Test_disassemble_load() assert_fails('disass NotCompiled', 'E1062:') assert_fails('disass', 'E471:') assert_fails('disass [', 'E475:') - assert_fails('disass 234', 'E475:') - assert_fails('disass foo', 'E475:') + assert_fails('disass 234', 'E129:') + assert_fails('disass foo', 'E129:') let res = execute('disass s:ScriptFuncLoad') assert_match('\d*_ScriptFuncLoad.*' .. diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -746,7 +746,7 @@ enddef def Test_unknown_function() CheckDefExecFailure([ 'let Ref: func = function("NotExist")', - 'delfunc g:NotExist'], 'E130:') + 'delfunc g:NotExist'], 'E700:') enddef def RefFunc(Ref: func(string): string): string diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -305,7 +305,7 @@ def Test_assignment_failure() call CheckDefFailure(['let true = 1'], 'E1034:') call CheckDefFailure(['let false = 1'], 'E1034:') - call CheckDefFailure(['[a; b; c] = g:list'], 'E1001:') + call CheckDefFailure(['[a; b; c] = g:list'], 'E452:') call CheckDefExecFailure(['let a: number', '[a] = test_null_list()'], 'E1093:') call CheckDefExecFailure(['let a: number', @@ -897,7 +897,7 @@ def Test_vim9script_fails() CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:') CheckScriptFailure(['export let some = 123'], 'E1042:') CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1048:') - CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:') + CheckScriptFailure(['vim9script', 'export let g:some'], 'E1022:') CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:') CheckScriptFailure(['vim9script', 'let str: string', 'str = 1234'], 'E1013:') @@ -1723,7 +1723,7 @@ def Test_vim9_comment() ' echo "yes"', 'catch', 'endtry# comment', - ], 'E600:') + ], 'E488:') CheckScriptSuccess([ 'vim9script', diff --git a/src/testdir/test_viminfo.vim b/src/testdir/test_viminfo.vim --- a/src/testdir/test_viminfo.vim +++ b/src/testdir/test_viminfo.vim @@ -705,13 +705,13 @@ func Test_viminfo_error() " Too many errors in viminfo file call writefile(repeat(["a 123"], 15), 'Xviminfo') - call assert_fails('rv Xviminfo', 'E136:') + call assert_fails('rv Xviminfo', 'E575:') call writefile(['>'] + repeat(['@'], 10), 'Xviminfo') - call assert_fails('rv Xviminfo', 'E136:') + call assert_fails('rv Xviminfo', 'E576:') call writefile(repeat(['"@'], 15), 'Xviminfo') - call assert_fails('rv Xviminfo', 'E136:') + call assert_fails('rv Xviminfo', 'E577:') call delete('Xviminfo') endfunc diff --git a/src/testdir/test_winbuf_close.vim b/src/testdir/test_winbuf_close.vim --- a/src/testdir/test_winbuf_close.vim +++ b/src/testdir/test_winbuf_close.vim @@ -115,7 +115,7 @@ func Test_winbuf_close() call assert_equal('Xtest2', bufname('%')) quit! call assert_equal('Xtest3', bufname('%')) - call assert_fails('silent! quit!', 'E162') + call assert_fails('silent! quit!', 'E37') call assert_equal('Xtest1', bufname('%')) call delete('Xtest1') diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim --- a/src/testdir/test_window_cmd.vim +++ b/src/testdir/test_window_cmd.vim @@ -569,7 +569,7 @@ func Test_access_freed_mem() au * 0 vs xxx arg 0 argadd - call assert_fails("all", "E249:") + call assert_fails("all", "E242:") au! bwipe xxx call assert_equal(&columns, winwidth(0)) diff --git a/src/testdir/test_writefile.vim b/src/testdir/test_writefile.vim --- a/src/testdir/test_writefile.vim +++ b/src/testdir/test_writefile.vim @@ -310,7 +310,7 @@ func Test_write_autocmd_unloadbuf_lockma autocmd BufWritePre Xfile enew | write augroup END e Xfile - call assert_fails('lockmarks write', 'E203:') + call assert_fails('lockmarks write', ['E32', 'E203:']) augroup WriteTest au! augroup END diff --git a/src/testing.c b/src/testing.c --- a/src/testing.c +++ b/src/testing.c @@ -546,11 +546,13 @@ f_assert_fails(typval_T *argvars, typval garray_T ga; int save_trylevel = trylevel; int called_emsg_before = called_emsg; + int wrong_arg = FALSE; // trylevel must be zero for a ":throw" command to be considered failed trylevel = 0; suppress_errthrow = TRUE; emsg_silent = TRUE; + emsg_assert_fails_used = TRUE; do_cmdline_cmd(cmd); if (called_emsg == called_emsg_before) @@ -565,14 +567,58 @@ f_assert_fails(typval_T *argvars, typval else if (argvars[1].v_type != VAR_UNKNOWN) { char_u buf[NUMBUFLEN]; - char *error = (char *)tv_get_string_buf_chk(&argvars[1], buf); + char_u *expected; + int error_found = FALSE; + char_u *actual = emsg_assert_fails_msg == NULL ? (char_u *)"[unknown]" + : emsg_assert_fails_msg; + + if (argvars[1].v_type == VAR_STRING) + { + expected = tv_get_string_buf_chk(&argvars[1], buf); + error_found = expected == NULL + || strstr((char *)actual, (char *)expected) == NULL; + } + else if (argvars[1].v_type == VAR_LIST) + { + list_T *list = argvars[1].vval.v_list; + typval_T *tv; - if (error == NULL - || strstr((char *)get_vim_var_str(VV_ERRMSG), error) == NULL) + if (list == NULL || list->lv_len < 1 || list->lv_len > 2) + { + wrong_arg = TRUE; + goto theend; + } + CHECK_LIST_MATERIALIZE(list); + tv = &list->lv_first->li_tv; + expected = tv_get_string_buf_chk(tv, buf); + if (!pattern_match(expected, actual, FALSE)) + { + error_found = TRUE; + } + else if (list->lv_len == 2) + { + tv = &list->lv_u.mat.lv_last->li_tv; + actual = get_vim_var_str(VV_ERRMSG); + expected = tv_get_string_buf_chk(tv, buf); + if (!pattern_match(expected, actual, FALSE)) + error_found = TRUE; + } + } + else { + wrong_arg = TRUE; + goto theend; + } + + if (error_found) + { + typval_T actual_tv; + prepare_assert_error(&ga); + actual_tv.v_type = VAR_STRING; + actual_tv.vval.v_string = actual; fill_assert_error(&ga, &argvars[2], NULL, &argvars[1], - get_vim_var_tv(VV_ERRMSG), ASSERT_OTHER); + &actual_tv, ASSERT_OTHER); ga_concat(&ga, (char_u *)": "); assert_append_cmd_or_arg(&ga, argvars, cmd); assert_error(&ga); @@ -581,11 +627,16 @@ f_assert_fails(typval_T *argvars, typval } } +theend: trylevel = save_trylevel; suppress_errthrow = FALSE; emsg_silent = FALSE; emsg_on_display = FALSE; + emsg_assert_fails_used = FALSE; + VIM_CLEAR(emsg_assert_fails_msg); set_vim_var_string(VV_ERRMSG, NULL, 0); + if (wrong_arg) + emsg(_("E856: assert_fails() second argument must be a string or a list with one or two strings")); } /* diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1183, +/**/ 1182, /**/ 1181, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -912,7 +912,12 @@ generate_TYPECHECK(cctx_T *cctx, type_T * - return FAIL. */ static int -need_type(type_T *actual, type_T *expected, int offset, cctx_T *cctx) +need_type( + type_T *actual, + type_T *expected, + int offset, + cctx_T *cctx, + int silent) { if (check_type(expected, actual, FALSE) == OK) return OK; @@ -921,7 +926,8 @@ need_type(type_T *actual, type_T *expect && !(actual->tt_type == VAR_FUNC && (actual->tt_member == &t_any || actual->tt_argcount < 0))) { - type_mismatch(expected, actual); + if (!silent) + type_mismatch(expected, actual); return FAIL; } generate_TYPECHECK(cctx, expected, offset); @@ -1538,7 +1544,7 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufu else expected = ufunc->uf_va_type->tt_member; actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i]; - if (need_type(actual, expected, -argcount + i, cctx) == FAIL) + if (need_type(actual, expected, -argcount + i, cctx, TRUE) == FAIL) { arg_type_mismatch(expected, actual, i + 1); return FAIL; @@ -4640,8 +4646,8 @@ compile_return(char_u *arg, int set_retu emsg(_("E1096: Returning a value in a function without a return type")); return NULL; } - if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1, cctx) - == FAIL) + if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1, + cctx, FALSE) == FAIL) return NULL; } } @@ -4942,7 +4948,7 @@ compile_assignment(char_u *arg, exarg_T emsg(_(e_cannot_use_void)); goto theend; } - if (need_type(stacktype, &t_list_any, -1, cctx) == FAIL) + if (need_type(stacktype, &t_list_any, -1, cctx, FALSE) == FAIL) goto theend; generate_CHECKLEN(cctx, semicolon ? var_count - 1 : var_count, semicolon); @@ -5356,13 +5362,13 @@ compile_assignment(char_u *arg, exarg_T if (use_type == NULL) use_type = &t_void; } - if (need_type(stacktype, use_type, -1, cctx) + if (need_type(stacktype, use_type, -1, cctx, FALSE) == FAIL) goto theend; } } else if (*p != '=' && need_type(stacktype, member_type, -1, - cctx) == FAIL) + cctx, FALSE) == FAIL) goto theend; } else if (cmdidx == CMD_const) @@ -5439,7 +5445,7 @@ compile_assignment(char_u *arg, exarg_T if (*op == '.') expected = &t_string; stacktype = ((type_T **)stack->ga_data)[stack->ga_len - 1]; - if (need_type(stacktype, expected, -1, cctx) == FAIL) + if (need_type(stacktype, expected, -1, cctx, FALSE) == FAIL) goto theend; if (*op == '.') @@ -6128,7 +6134,7 @@ compile_for(char_u *arg, cctx_T *cctx) // Now that we know the type of "var", check that it is a list, now or at // runtime. vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1]; - if (need_type(vartype, &t_list_any, -1, cctx) == FAIL) + if (need_type(vartype, &t_list_any, -1, cctx, FALSE) == FAIL) { drop_scope(cctx); return NULL;