]> granicus.if.org Git - vim/commitdiff
patch 8.2.1469: Vim9: cannot assign string to string option v8.2.1469
authorBram Moolenaar <Bram@vim.org>
Sun, 16 Aug 2020 19:29:05 +0000 (21:29 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 16 Aug 2020 19:29:05 +0000 (21:29 +0200)
Problem:    Vim9: cannot assign string to string option.
Solution:   Change checks for option value. (closes #6720)

src/evalvars.c
src/testdir/test_vim9_script.vim
src/version.c

index 0562b4ce22e0c1e2a670fbf3fb44bfc6c1b6f4f8..2f4a11b2cc7320a20d7b11294f74c2fde50995ad 100644 (file)
@@ -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);
index 905deb6debba498cfd543602e8e316adbdb43863..af86815132ab21f9125e2bf2fd5421cd97e0f82a 100644 (file)
@@ -96,22 +96,36 @@ def Test_assignment()
     &ts += 3
     assert_equal(9, &ts)
   END
-  call CheckScriptSuccess(lines)
+  CheckScriptSuccess(lines)
 
-  call CheckDefFailure(['&notex += 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:')
+  CheckDefFailure(['&notex += 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
index 19a870468834f5eeeb08fd98cff8bbdad31e375b..10c659ebebae5dd56832df3a78c952f56c118aa1 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1469,
 /**/
     1468,
 /**/