patch 8.2.0650: Vim9: script function can be deleted

Problem:    Vim9: script function can be deleted.
Solution:   Disallow deleting script function.  Delete functions when sourcing
            a script again.
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index 42a9926..4632272 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -207,12 +207,12 @@
   assert_equal(true, g:adict == #{bbb: 8, aaa: 2})
   assert_equal(false, #{ccc: 9, aaa: 2} == g:adict)
 
-  assert_equal(true, function('Test_expr4_equal') == function('Test_expr4_equal'))
-  assert_equal(false, function('Test_expr4_equal') == function('Test_expr4_is'))
+  assert_equal(true, function('g:Test_expr4_equal') == function('g:Test_expr4_equal'))
+  assert_equal(false, function('g:Test_expr4_equal') == function('g:Test_expr4_is'))
 
-  assert_equal(true, function('Test_expr4_equal', [123]) == function('Test_expr4_equal', [123]))
-  assert_equal(false, function('Test_expr4_equal', [123]) == function('Test_expr4_is', [123]))
-  assert_equal(false, function('Test_expr4_equal', [123]) == function('Test_expr4_equal', [999]))
+  assert_equal(true, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_equal', [123]))
+  assert_equal(false, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_is', [123]))
+  assert_equal(false, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_equal', [999]))
 enddef
 
 " test != comperator
@@ -274,12 +274,12 @@
   assert_equal(false, g:adict != #{bbb: 8, aaa: 2})
   assert_equal(true, #{ccc: 9, aaa: 2} != g:adict)
 
-  assert_equal(false, function('Test_expr4_equal') != function('Test_expr4_equal'))
-  assert_equal(true, function('Test_expr4_equal') != function('Test_expr4_is'))
+  assert_equal(false, function('g:Test_expr4_equal') != function('g:Test_expr4_equal'))
+  assert_equal(true, function('g:Test_expr4_equal') != function('g:Test_expr4_is'))
 
-  assert_equal(false, function('Test_expr4_equal', [123]) != function('Test_expr4_equal', [123]))
-  assert_equal(true, function('Test_expr4_equal', [123]) != function('Test_expr4_is', [123]))
-  assert_equal(true, function('Test_expr4_equal', [123]) != function('Test_expr4_equal', [999]))
+  assert_equal(false, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_equal', [123]))
+  assert_equal(true, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_is', [123]))
+  assert_equal(true, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_equal', [999]))
 enddef
 
 " test > comperator
@@ -929,15 +929,15 @@
 
 def Test_expr7_trailing()
   " user function call
-  assert_equal(123, CallMe(123))
-  assert_equal(123, CallMe(  123))
-  assert_equal(123, CallMe(123  ))
-  assert_equal('yesno', CallMe2('yes', 'no'))
-  assert_equal('yesno', CallMe2( 'yes', 'no' ))
-  assert_equal('nothing', CallMe('nothing'))
+  assert_equal(123, g:CallMe(123))
+  assert_equal(123, g:CallMe(  123))
+  assert_equal(123, g:CallMe(123  ))
+  assert_equal('yesno', g:CallMe2('yes', 'no'))
+  assert_equal('yesno', g:CallMe2( 'yes', 'no' ))
+  assert_equal('nothing', g:CallMe('nothing'))
 
   " partial call
-  let Part = function('CallMe')
+  let Part = function('g:CallMe')
   assert_equal('yes', Part('yes'))
 
   " funcref call, using list index
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index f3721ba..2ee91f1 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -353,7 +353,7 @@
 def Test_delfunc()
   let lines =<< trim END
     vim9script
-    def GoneSoon()
+    def g:GoneSoon()
       echo 'hello'
     enddef
 
@@ -361,7 +361,7 @@
       GoneSoon()
     enddef
 
-    delfunc GoneSoon
+    delfunc g:GoneSoon
     CallGoneSoon()
   END
   writefile(lines, 'XToDelFunc')
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 218ef77..0ab170e 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -53,7 +53,7 @@
   endif
   let Funky1: func
   let Funky2: func = function('len')
-  let Party2: func = funcref('Test_syntax')
+  let Party2: func = funcref('g:Test_syntax')
 
   # type becomes list<any>
   let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
@@ -282,6 +282,49 @@
   assert_equal('', $ENVVAR)
 enddef
 
+def Test_delfunction()
+  " Check function is defined in script namespace
+  CheckScriptSuccess([
+      'vim9script',
+      'func CheckMe()',
+      '  return 123',
+      'endfunc',
+      'assert_equal(123, s:CheckMe())',
+      ])
+
+  " Check function in script namespace cannot be deleted
+  CheckScriptFailure([
+      'vim9script',
+      'func DeleteMe1()',
+      'endfunc',
+      'delfunction DeleteMe1',
+      ], 'E1084:')
+  CheckScriptFailure([
+      'vim9script',
+      'func DeleteMe2()',
+      'endfunc',
+      'def DoThat()',
+      '  delfunction DeleteMe2',
+      'enddef',
+      'DoThat()',
+      ], 'E1084:')
+  CheckScriptFailure([
+      'vim9script',
+      'def DeleteMe3()',
+      'enddef',
+      'delfunction DeleteMe3',
+      ], 'E1084:')
+  CheckScriptFailure([
+      'vim9script',
+      'def DeleteMe4()',
+      'enddef',
+      'def DoThat()',
+      '  delfunction DeleteMe4',
+      'enddef',
+      'DoThat()',
+      ], 'E1084:')
+enddef
+
 func Test_wrong_type()
   call CheckDefFailure(['let var: list<nothing>'], 'E1010:')
   call CheckDefFailure(['let var: list<list<nothing>>'], 'E1010:')
@@ -649,7 +692,7 @@
   assert_fails('export something', 'E1043')
 enddef
 
-def Test_vim9script_reload()
+def Test_vim9script_reload_import()
   let lines =<< trim END
     vim9script
     const var = ''
@@ -700,6 +743,47 @@
   delete('Ximport.vim')
 enddef
 
+def Test_vim9script_reload_delfunc()
+  let first_lines =<< trim END
+    vim9script
+    def FuncYes(): string
+      return 'yes'
+    enddef
+  END
+  let middle_lines =<< trim END
+    def FuncNo(): string
+      return 'no'
+    enddef
+  END
+  let final_lines =<< trim END
+    def g:DoCheck(no_exists: bool)
+      assert_equal('yes', FuncYes())
+      if no_exists
+        assert_equal('no', FuncNo())
+      else
+        assert_fails('call FuncNo()', 'E117:')
+      endif
+    enddef
+  END
+
+  # FuncNo() is defined
+  writefile(first_lines + middle_lines + final_lines, 'Xreloaded.vim')
+  source Xreloaded.vim
+  g:DoCheck(true)
+
+  # FuncNo() is not redefined
+  writefile(first_lines + final_lines, 'Xreloaded.vim')
+  source Xreloaded.vim
+  g:DoCheck(false)
+
+  # FuncNo() is back
+  writefile(first_lines + middle_lines + final_lines, 'Xreloaded.vim')
+  source Xreloaded.vim
+  g:DoCheck(true)
+
+  delete('Xreloaded.vim')
+enddef
+
 def Test_import_absolute()
   let import_lines = [
         'vim9script',
@@ -1445,15 +1529,15 @@
 
   CheckScriptSuccess([
       'vim9script',
-      'func DeleteMe()',
+      'func g:DeleteMeA()',
       'endfunc',
-      'delfunction DeleteMe # comment',
+      'delfunction g:DeleteMeA # comment',
       ])
   CheckScriptFailure([
       'vim9script',
-      'func DeleteMe()',
+      'func g:DeleteMeB()',
       'endfunc',
-      'delfunction DeleteMe# comment',
+      'delfunction g:DeleteMeB# comment',
       ], 'E488:')
 
   CheckScriptSuccess([