summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/users_guide/packages.rst4
-rw-r--r--ghc/GHCi/UI.hs8
-rw-r--r--testsuite/tests/ghci/scripts/Makefile4
-rw-r--r--testsuite/tests/ghci/scripts/T19650.script1
-rw-r--r--testsuite/tests/ghci/scripts/T19650.stdout1
-rwxr-xr-xtestsuite/tests/ghci/scripts/all.T8
6 files changed, 24 insertions, 2 deletions
diff --git a/docs/users_guide/packages.rst b/docs/users_guide/packages.rst
index 837a444a74..ff6953ac8c 100644
--- a/docs/users_guide/packages.rst
+++ b/docs/users_guide/packages.rst
@@ -536,6 +536,10 @@ or ``ghci`` that are local to a shell session or to some file system location.
They are intended to be managed by build/package tools, to enable ``ghc`` and
``ghci`` to automatically use an environment created by the tool.
+In the case of ``ghci``, the environment file will be read once, during
+initialisation. If the file changes then you have to restart GHCi to reflect
+the updated file.
+
The file contains package IDs and optionally package databases, one directive
per line:
diff --git a/ghc/GHCi/UI.hs b/ghc/GHCi/UI.hs
index edd473bba9..c707bd4ee7 100644
--- a/ghc/GHCi/UI.hs
+++ b/ghc/GHCi/UI.hs
@@ -3028,13 +3028,17 @@ setOptions wds =
-- then, dynamic flags
when (not (null minus_opts)) $ newDynFlags False minus_opts
+-- | newDynFlags will *not* read package environment files, therefore we
+-- use 'parseDynamicFlagsCmdLine' rather than 'parseDynamicFlags'. This
+-- function is called very often and results in repeatedly loading
+-- environment files (see #19650)
newDynFlags :: GhciMonad m => Bool -> [String] -> m ()
newDynFlags interactive_only minus_opts = do
let lopts = map noLoc minus_opts
logger <- getLogger
idflags0 <- GHC.getInteractiveDynFlags
- (idflags1, leftovers, warns) <- GHC.parseDynamicFlags logger idflags0 lopts
+ (idflags1, leftovers, warns) <- DynFlags.parseDynamicFlagsCmdLine idflags0 lopts
liftIO $ handleFlagWarnings logger idflags1 warns
when (not $ null leftovers)
@@ -3050,7 +3054,7 @@ newDynFlags interactive_only minus_opts = do
dflags0 <- getDynFlags
when (not interactive_only) $ do
- (dflags1, _, _) <- liftIO $ GHC.parseDynamicFlags logger dflags0 lopts
+ (dflags1, _, _) <- liftIO $ DynFlags.parseDynamicFlagsCmdLine dflags0 lopts
must_reload <- GHC.setProgramDynFlags dflags1
-- if the package flags changed, reset the context and link
diff --git a/testsuite/tests/ghci/scripts/Makefile b/testsuite/tests/ghci/scripts/Makefile
index 40ba561f69..a76b8c090c 100644
--- a/testsuite/tests/ghci/scripts/Makefile
+++ b/testsuite/tests/ghci/scripts/Makefile
@@ -66,3 +66,7 @@ T11389:
T12023:
-'$(TEST_HC)' $(TEST_HC_OPTS_INTERACTIVE) \
-ghci-script T12023.script < /dev/null | grep -c -E '(~#|~R#|~P#)'
+
+.PHONY: T19650_setup
+T19650_setup:
+ '$(GHC_PKG)' latest base > my_package_env
diff --git a/testsuite/tests/ghci/scripts/T19650.script b/testsuite/tests/ghci/scripts/T19650.script
new file mode 100644
index 0000000000..1426870840
--- /dev/null
+++ b/testsuite/tests/ghci/scripts/T19650.script
@@ -0,0 +1 @@
+:set -DMAGIC
diff --git a/testsuite/tests/ghci/scripts/T19650.stdout b/testsuite/tests/ghci/scripts/T19650.stdout
new file mode 100644
index 0000000000..4bca5be26b
--- /dev/null
+++ b/testsuite/tests/ghci/scripts/T19650.stdout
@@ -0,0 +1 @@
+Loaded package environment from my_package_env
diff --git a/testsuite/tests/ghci/scripts/all.T b/testsuite/tests/ghci/scripts/all.T
index f38a1738eb..8c5f34fb08 100755
--- a/testsuite/tests/ghci/scripts/all.T
+++ b/testsuite/tests/ghci/scripts/all.T
@@ -332,3 +332,11 @@ test('T19667Ghci', extra_files(['T19667Ghci.hs']), ghci_script, ['T19667Ghci.scr
test('T19688', normal, ghci_script, ['T19688.script'])
test('T20019', normal, ghci_script, ['T20019.script'])
test('T20101', normal, ghci_script, ['T20101.script'])
+test('T19650',
+ [ pre_cmd('$MAKE -s --no-print-directory T19650_setup'),
+ extra_hc_opts('-package-env my_package_env -v1'),
+ # Should only appear once
+ filter_stdout_lines(r'Loaded package env.*')
+ ],
+ ghci_script,
+ ['T19650.script'])