# HG changeset patch # User Bram Moolenaar # Date 1597606203 -7200 # Node ID c7699985db0069d893a7b34af6f6ee940d7048ff # Parent 3e44fb5274725105ed6eaf90978ef1d00780b15b patch 8.2.1469: Vim9: cannot assign string to string option Commit: https://github.com/vim/vim/commit/0aae4809fd52b445531766411a9c963dc6274a04 Author: Bram Moolenaar Date: Sun Aug 16 21:29:05 2020 +0200 patch 8.2.1469: Vim9: cannot assign string to string option Problem: Vim9: cannot assign string to string option. Solution: Change checks for option value. (closes https://github.com/vim/vim/issues/6720) diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -1294,28 +1294,36 @@ ex_let_one( emsg(_(e_letunexp)); else { - long n; + long n = 0; int opt_type; long numval; char_u *stringval = NULL; char_u *s = NULL; + int failed = FALSE; c1 = *p; *p = NUL; - n = (long)tv_get_number(tv); - // avoid setting a string option to the text "v:false" or similar. - if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL) - s = tv_get_string_chk(tv); // != NULL if number or string - if (s != NULL && op != NULL && *op != '=') + opt_type = get_option_value(arg, &numval, &stringval, opt_flags); + if ((opt_type == 1 || opt_type == -1) + && (tv->v_type != VAR_STRING || !in_vim9script())) + // number, possibly hidden + n = (long)tv_get_number(tv); + + // Avoid setting a string option to the text "v:false" or similar. + // In Vim9 script also don't convert a number to string. + if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL + && (!in_vim9script() || tv->v_type != VAR_NUMBER)) + s = tv_get_string_chk(tv); + + if (op != NULL && *op != '=') { - opt_type = get_option_value(arg, &numval, - &stringval, opt_flags); if ((opt_type == 1 && *op == '.') || (opt_type == 0 && *op != '.')) { semsg(_(e_letwrong), op); - s = NULL; // don't set the value + failed = TRUE; // don't set the value + } else { @@ -1330,19 +1338,25 @@ ex_let_one( case '%': n = (long)num_modulus(numval, n); break; } } - else if (opt_type == 0 && stringval != NULL) // string + else if (opt_type == 0 && stringval != NULL && s != NULL) { + // string s = concat_str(stringval, s); vim_free(stringval); stringval = s; } } } - if (s != NULL || tv->v_type == VAR_BOOL - || tv->v_type == VAR_SPECIAL) + + if (!failed) { - set_option_value(arg, n, s, opt_flags); - arg_end = p; + if (opt_type != 0 || s != NULL) + { + set_option_value(arg, n, s, opt_flags); + arg_end = p; + } + else + emsg(_(e_stringreq)); } *p = c1; vim_free(stringval); 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 @@ -96,22 +96,36 @@ def Test_assignment() &ts += 3 assert_equal(9, &ts) END - call CheckScriptSuccess(lines) - - call CheckDefFailure(['¬ex += 3'], 'E113:') - call CheckDefFailure(['&ts ..= "xxx"'], 'E1019:') - call CheckDefFailure(['&ts = [7]'], 'E1012:') - call CheckDefExecFailure(['&ts = g:alist'], 'E1029: Expected number but got list') - call CheckDefFailure(['&ts = "xx"'], 'E1012:') - call CheckDefExecFailure(['&ts = g:astring'], 'E1029: Expected number but got string') - call CheckDefFailure(['&path += 3'], 'E1012:') - call CheckDefExecFailure(['&bs = "asdf"'], 'E474:') + CheckScriptSuccess(lines) + + CheckDefFailure(['¬ex += 3'], 'E113:') + CheckDefFailure(['&ts ..= "xxx"'], 'E1019:') + CheckDefFailure(['&ts = [7]'], 'E1012:') + CheckDefExecFailure(['&ts = g:alist'], 'E1029: Expected number but got list') + CheckDefFailure(['&ts = "xx"'], 'E1012:') + CheckDefExecFailure(['&ts = g:astring'], 'E1029: Expected number but got string') + CheckDefFailure(['&path += 3'], 'E1012:') + CheckDefExecFailure(['&bs = "asdf"'], 'E474:') # test freeing ISN_STOREOPT - call CheckDefFailure(['&ts = 3', 'let asdf'], 'E1022:') + CheckDefFailure(['&ts = 3', 'let asdf'], 'E1022:') &ts = 8 - call CheckDefFailure(['let s:var = 123'], 'E1101:') - call CheckDefFailure(['let s:var: number'], 'E1101:') + lines =<< trim END + let save_TI = &t_TI + &t_TI = '' + assert_equal('', &t_TI) + &t_TI = 'xxx' + assert_equal('xxx', &t_TI) + &t_TI = save_TI + END + CheckDefSuccess(lines) + CheckScriptSuccess(['vim9script'] + lines) + + CheckDefFailure(['&t_TI = 123'], 'E1012:') + CheckScriptFailure(['vim9script', '&t_TI = 123'], 'E928:') + + CheckDefFailure(['let s:var = 123'], 'E1101:') + CheckDefFailure(['let s:var: number'], 'E1101:') lines =<< trim END vim9script 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 */ /**/ + 1469, +/**/ 1468, /**/ 1467,