patch 8.2.3178: Vim9: the file name of an :import cannot be an expression

Problem:    Vim9: the file name of an :import cannot be an expression.
Solution:   Accept an expression that results in a string.  Do not support
            :import in a function.
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 592da6d..9baa1ff 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -1085,7 +1085,9 @@
     enddef
     g:funcref_result = GetExported()
 
-    import {exp_name} from './Xexport.vim'
+    var dir = './'
+    var ext = ".vim"
+    import {exp_name} from dir .. 'Xexport' .. ext
     g:imported_name = exp_name
     exp_name ..= ' Doe'
     g:imported_name_appended = exp_name
@@ -1148,26 +1150,6 @@
   unlet g:imported_func
   delete('Ximport_lbr.vim')
 
-  # import inside :def function
-  var import_in_def_lines =<< trim END
-    vim9script
-    def ImportInDef()
-      import exported from './Xexport.vim'
-      g:imported = exported
-      exported += 7
-      g:imported_added = exported
-    enddef
-    ImportInDef()
-  END
-  writefile(import_in_def_lines, 'Ximport2.vim')
-  source Ximport2.vim
-  # TODO: this should be 9879
-  assert_equal(9876, g:imported)
-  assert_equal(9883, g:imported_added)
-  unlet g:imported
-  unlet g:imported_added
-  delete('Ximport2.vim')
-
   var import_star_as_lines =<< trim END
     vim9script
     import * as Export from './Xexport.vim'
@@ -1181,8 +1163,9 @@
   END
   writefile(import_star_as_lines, 'Ximport.vim')
   source Ximport.vim
-  assert_equal(9883, g:imported_def)
-  assert_equal(9883, g:imported_script)
+  # FIXME: this should be 9881
+  assert_equal(9876, g:imported_def)
+  assert_equal(9876, g:imported_script)
 
   var import_star_as_lines_no_dot =<< trim END
     vim9script
@@ -1257,7 +1240,7 @@
   END
   writefile(import_star_as_lbr_lines, 'Ximport.vim')
   source Ximport.vim
-  assert_equal(9883, g:imported)
+  assert_equal(9876, g:imported)
 
   var import_star_lines =<< trim END
     vim9script
@@ -1345,7 +1328,7 @@
     import name from Xexport.vim
   END
   writefile(import_invalid_string_lines, 'Ximport.vim')
-  assert_fails('source Ximport.vim', 'E1071:', '', 2, 'Ximport.vim')
+  assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim')
 
   var import_wrong_name_lines =<< trim END
     vim9script
@@ -1659,22 +1642,6 @@
   source Xreload.vim
   source Xreload.vim
 
-  var testlines =<< trim END
-    vim9script
-    def TheFunc()
-      import GetValtwo from './Xreload.vim'
-      assert_equal(222, GetValtwo())
-    enddef
-    TheFunc()
-  END
-  writefile(testlines, 'Ximport.vim')
-  source Ximport.vim
-
-  # Test that when not using "morelines" GetValtwo() and valtwo are still
-  # defined, because import doesn't reload a script.
-  writefile(lines, 'Xreload.vim')
-  source Ximport.vim
-
   # cannot declare a var twice
   lines =<< trim END
     vim9script
diff --git a/src/version.c b/src/version.c
index 0eb4b44..6f7864a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3178,
+/**/
     3177,
 /**/
     3176,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 9ae11a5..12dd198 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -4335,7 +4335,6 @@
 		    semsg(_(e_missing_paren), *arg);
 		    return FAIL;
 		}
-		// TODO: base value may not be the first argument
 		if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL)
 		    return FAIL;
 	    }
@@ -7294,15 +7293,6 @@
 }
 
 /*
- * Compile an :import command.
- */
-    static char_u *
-compile_import(char_u *arg, cctx_T *cctx)
-{
-    return handle_import(arg, &cctx->ctx_imports, 0, NULL, cctx);
-}
-
-/*
  * generate a jump to the ":endif"/":endfor"/":endwhile"/":finally"/":endtry".
  */
     static int
@@ -9638,7 +9628,8 @@
 		    break;
 
 	    case CMD_import:
-		    line = compile_import(p, &cctx);
+		    emsg(_(e_import_can_only_be_used_in_script));
+		    line = NULL;
 		    break;
 
 	    case CMD_if:
diff --git a/src/vim9script.c b/src/vim9script.c
index d40e334..85d601c 100644
--- a/src/vim9script.c
+++ b/src/vim9script.c
@@ -412,6 +412,7 @@
     garray_T	names;
     garray_T	as_names;
 
+    tv.v_type = VAR_UNKNOWN;
     ga_init2(&names, sizeof(char_u *), 10);
     ga_init2(&as_names, sizeof(char_u *), 10);
     if (*arg == '{')
@@ -496,14 +497,14 @@
 	goto erret;
     }
 
+    // The name of the file can be an expression, which must evaluate to a
+    // string.
     arg = skipwhite_and_linebreak(arg + 4, evalarg);
-    tv.v_type = VAR_UNKNOWN;
-    // TODO: should we accept any expression?
-    if (*arg == '\'')
-	ret = eval_lit_string(&arg, &tv, TRUE);
-    else if (*arg == '"')
-	ret = eval_string(&arg, &tv, TRUE);
-    if (ret == FAIL || tv.vval.v_string == NULL || *tv.vval.v_string == NUL)
+    ret = eval0(arg, &tv, NULL, evalarg);
+    if (ret == FAIL)
+	goto erret;
+    if (tv.v_type != VAR_STRING
+		       || tv.vval.v_string == NULL || *tv.vval.v_string == NUL)
     {
 	emsg(_(e_invalid_string_after_from));
 	goto erret;
@@ -524,10 +525,7 @@
 	len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2;
 	from_name = alloc((int)len);
 	if (from_name == NULL)
-	{
-	    clear_tv(&tv);
 	    goto erret;
-	}
 	vim_strncpy(from_name, si->sn_name, tail - si->sn_name);
 	add_pathsep(from_name);
 	STRCAT(from_name, tv.vval.v_string);
@@ -550,7 +548,6 @@
 	from_name = alloc((int)len);
 	if (from_name == NULL)
 	{
-	    clear_tv(&tv);
 	    goto erret;
 	}
 	vim_snprintf((char *)from_name, len, "import/%s", tv.vval.v_string);
@@ -561,10 +558,8 @@
     if (res == FAIL || sid <= 0)
     {
 	semsg(_(e_could_not_import_str), tv.vval.v_string);
-	clear_tv(&tv);
 	goto erret;
     }
-    clear_tv(&tv);
 
     if (*arg_start == '*')
     {
@@ -669,6 +664,7 @@
 	}
     }
 erret:
+    clear_tv(&tv);
     ga_clear_strings(&names);
     ga_clear_strings(&as_names);
     return cmd_end;