patch 8.2.3924: Vim9: no error if something follows :enddef

Problem:    Vim9: no error if something follows :enddef in a nested function.
Solution:   Give an error.  Move common code to a function.
diff --git a/src/errors.h b/src/errors.h
index 5ca74cc..692574b 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -717,8 +717,8 @@
 	INIT(= N_("E1171: Missing } after inline function"));
 EXTERN char e_cannot_use_default_values_in_lambda[]
 	INIT(= N_("E1172: Cannot use default values in a lambda"));
-EXTERN char e_text_found_after_enddef_str[]
-	INIT(= N_("E1173: Text found after enddef: %s"));
+EXTERN char e_text_found_after_str_str[]
+	INIT(= N_("E1173: Text found after %s: %s"));
 EXTERN char e_string_required_for_argument_nr[]
 	INIT(= N_("E1174: String required for argument %d"));
 EXTERN char e_non_empty_string_required_for_argument_nr[]
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index 88c0af8..7a5f0f1 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -1686,7 +1686,7 @@
       # Compile all functions
       defcompile
   END
-  CheckScriptFailure(lines, 'E476: Invalid command: AAAAA')
+  CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
 enddef
 
 def Test_nested_function_with_args_split()
@@ -1703,8 +1703,17 @@
       # Compile all functions
       defcompile
   END
-  # FIXME: this should fail on the BBBB
-  CheckScriptSuccess(lines)
+  CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
+
+  lines =<< trim END
+      vim9script
+      def FirstFunction()
+        func SecondFunction()
+        endfunc|BBBB
+      enddef
+      defcompile
+  END
+  CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
 enddef
 
 def Test_return_type_wrong()
diff --git a/src/userfunc.c b/src/userfunc.c
index a7cbac3..b87cded 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -166,6 +166,35 @@
 }
 
 /*
+ * Handle line continuation in function arguments or body.
+ * Get a next line, store it in "eap" if appropriate and use "line_to_free" to
+ * handle freeing the line later.
+ */
+    static char_u *
+get_function_line(
+	exarg_T		*eap,
+	char_u		**line_to_free,
+	getline_opt_T	getline_options,
+	int		indent)
+{
+    char_u *theline;
+
+    if (eap->getline == NULL)
+	theline = getcmdline(':', 0L, indent, getline_options);
+    else
+	theline = eap->getline(':', eap->cookie, indent, getline_options);
+    if (theline != NULL)
+    {
+	if (*eap->cmdlinep == *line_to_free)
+	    *eap->cmdlinep = theline;
+	vim_free(*line_to_free);
+	*line_to_free = theline;
+    }
+
+    return theline;
+}
+
+/*
  * Get function arguments.
  * "argp" should point to just after the "(", possibly to white space.
  * "argp" is advanced just after "endchar".
@@ -212,16 +241,11 @@
 	while (eap != NULL && eap->getline != NULL
 			 && (*p == NUL || (VIM_ISWHITE(*whitep) && *p == '#')))
 	{
-	    char_u *theline;
-
 	    // End of the line, get the next one.
-	    theline = eap->getline(':', eap->cookie, 0, TRUE);
+	    char_u *theline = get_function_line(eap, line_to_free, 0, TRUE);
+
 	    if (theline == NULL)
 		break;
-	    vim_free(*line_to_free);
-	    if (*eap->cmdlinep == *line_to_free)
-		*eap->cmdlinep = theline;
-	    *line_to_free = theline;
 	    whitep = (char_u *)" ";
 	    p = skipwhite(theline);
 	}
@@ -720,15 +744,8 @@
 	}
 	else
 	{
-	    if (eap->getline == NULL)
-		theline = getcmdline(':', 0L, indent, getline_options);
-	    else
-		theline = eap->getline(':', eap->cookie, indent,
+	    theline = get_function_line(eap, line_to_free, indent,
 							      getline_options);
-	    if (*eap->cmdlinep == *line_to_free)
-		*eap->cmdlinep = theline;
-	    vim_free(*line_to_free);
-	    *line_to_free = theline;
 	}
 	if (KeyTyped)
 	    lines_left = Rows - 1;
@@ -827,7 +844,7 @@
 			SOURCING_LNUM = sourcing_lnum_top
 							+ newlines->ga_len + 1;
 			if (eap->cmdidx == CMD_def)
-			    semsg(_(e_text_found_after_enddef_str), p);
+			    semsg(_(e_text_found_after_str_str), "enddef", p);
 			else
 			    give_warning2((char_u *)
 				   _("W22: Text found after :endfunction: %s"),
diff --git a/src/version.c b/src/version.c
index 5d22d98..90bd422 100644
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3924,
+/**/
     3923,
 /**/
     3922,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index b23145e..8882bfe 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -879,12 +879,18 @@
     }
 
     ufunc = define_function(eap, lambda_name, line_to_free);
-
     if (ufunc == NULL)
     {
 	r = eap->skip ? OK : FAIL;
 	goto theend;
     }
+    if (eap->nextcmd != NULL)
+    {
+	semsg(_(e_text_found_after_str_str),
+	      eap->cmdidx == CMD_def ? "enddef" : "endfunction", eap->nextcmd);
+	r = FAIL;
+	goto theend;
+    }
 
     // copy over the block scope IDs before compiling
     if (!is_global && cctx->ctx_ufunc->uf_block_depth > 0)