patch 8.2.3901: Vim9: Cannot set 'cpo' in main .vimrc if using Vim9 script

Problem:    Vim9: Cannot set 'cpo' in main .vimrc if using Vim9 script.
Solution:   Do not restore 'cpo' at the end of the main .vimrc.
diff --git a/src/scriptfile.c b/src/scriptfile.c
index 7ff9672..129d4d6 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -1372,6 +1372,9 @@
 	if (ret_sid != NULL)
 	    *ret_sid = current_sctx.sc_sid;
 
+	// Remember the "is_vimrc" flag for when the file is sourced again.
+	si->sn_is_vimrc = is_vimrc;
+
 	// Used to check script variable index is still valid.
 	si->sn_script_seq = current_sctx.sc_seq;
     }
@@ -1471,9 +1474,11 @@
 
 #ifdef FEAT_EVAL
 almosttheend:
+    // If "sn_save_cpo" is set that means we encountered "vim9script": restore
+    // 'cpoptions', unless in the main .vimrc file.
     // Get "si" again, "script_items" may have been reallocated.
     si = SCRIPT_ITEM(current_sctx.sc_sid);
-    if (si->sn_save_cpo != NULL)
+    if (si->sn_save_cpo != NULL && si->sn_is_vimrc == DOSO_NONE)
     {
 	if (STRCMP(p_cpo, CPO_VIM) != 0)
 	{
@@ -1503,8 +1508,8 @@
 		}
 	}
 	set_option_value((char_u *)"cpo", 0L, si->sn_save_cpo, OPT_NO_REDRAW);
-	VIM_CLEAR(si->sn_save_cpo);
     }
+    VIM_CLEAR(si->sn_save_cpo);
 
     restore_funccal();
 # ifdef FEAT_PROFILE
diff --git a/src/structs.h b/src/structs.h
index 4160453..4e770f1 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1866,6 +1866,7 @@
     int		sn_version;	// :scriptversion
     int		sn_state;	// SN_STATE_ values
     char_u	*sn_save_cpo;	// 'cpo' value when :vim9script found
+    char	sn_is_vimrc;	// .vimrc file, do not restore 'cpo'
 
 # ifdef FEAT_PROFILE
     int		sn_prof_on;	// TRUE when script is/was profiled
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 8975e1b..f79112e 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -4270,18 +4270,64 @@
   delete('Xclose')
   delete('Xdone')
 
-  writefile(['vim9script'], 'XanotherScript')
+  writefile(['vim9script', 'g:cpoval = &cpo'], 'XanotherScript')
   set cpo=aABceFsMny>
   edit XanotherScript
   so %
   assert_equal('aABceFsMny>', &cpo)
+  assert_equal('aABceFs', g:cpoval)
   :1del
+  setline(1, 'let g:cpoval = &cpo')
   w
   so %
   assert_equal('aABceFsMny>', &cpo)
+  assert_equal('aABceFsMny>', g:cpoval)
 
   delete('XanotherScript')
   set cpo&vim
+  unlet g:cpoval
+
+  if has('unix')
+    # 'cpo' is not restored in main vimrc
+    var save_HOME = $HOME
+    $HOME = getcwd() .. '/Xhome'
+    mkdir('Xhome')
+    var lines =<< trim END
+        vim9script
+        writefile(['before: ' .. &cpo], 'Xresult')
+        set cpo+=M
+        writefile(['after: ' .. &cpo], 'Xresult', 'a')
+    END
+    writefile(lines, 'Xhome/.vimrc')
+
+    lines =<< trim END
+        call writefile(['later: ' .. &cpo], 'Xresult', 'a')
+    END
+    writefile(lines, 'Xlegacy')
+
+    lines =<< trim END
+        vim9script
+        call writefile(['vim9: ' .. &cpo], 'Xresult', 'a')
+        qa
+    END
+    writefile(lines, 'Xvim9')
+
+    var cmd = GetVimCommand() .. " -S Xlegacy -S Xvim9"
+    cmd = substitute(cmd, '-u NONE', '', '')
+    exe "silent !" .. cmd
+
+    assert_equal([
+        'before: aABceFs',
+        'after: aABceFsM',
+        'later: aABceFsM',
+        'vim9: aABceFs'], readfile('Xresult'))
+
+    $HOME = save_HOME
+    delete('Xhome', 'rf')
+    delete('Xlegacy')
+    delete('Xvim9')
+    delete('Xresult')
+  endif
 enddef
 
 " Use :function so we can use Check commands
diff --git a/src/version.c b/src/version.c
index 1ada856..9a5ef2c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3901,
+/**/
     3900,
 /**/
     3899,