Handle :cd in external interpreter in a more robust way
authorZejun Wu <watashi@fb.com>
Mon, 17 Dec 2018 06:16:00 +0000 (01:16 -0500)
committerBen Gamari <ben@smart-cactus.org>
Mon, 17 Dec 2018 06:16:01 +0000 (01:16 -0500)
We used to enqueue another command to change directory in the external
interpreter subprocess, this is not as robust as:

* it can fail with -fno-implict-import-qualified;
* it doesn't work when we `setGHCiMonad` to something other than `IO`.

Neither of them works if `directory` package is hidden though.

Test Plan:
```
$ inplace/bin/ghc-stage2 --interactive # -fexternal-interpreter
GHCi, version 8.7.20181213: http://www.haskell.org/ghc/  :? for help
Prelude> :cd ..
Prelude> System.Directory.getCurrentDirectory
"/data/users/watashi"
Prelude> :!pwd
/data/users/watashi
Prelude>
Leaving GHCi.
```

  ./validate

Reviewers: simonmar, bgamari, RyanGlScott

Reviewed By: simonmar

Subscribers: rwbarton, carter

Differential Revision: https://phabricator.haskell.org/D5453

ghc/GHCi/UI.hs
ghc/GHCi/UI/Monad.hs

index 13275f8..105324f 100644 (file)
@@ -1430,8 +1430,11 @@ changeDirectory dir = do
   dflags <- getDynFlags
   -- With -fexternal-interpreter, we have to change the directory of the subprocess too.
   -- (this gives consistent behaviour with and without -fexternal-interpreter)
-  when (gopt Opt_ExternalInterpreter dflags) $
-    lift $ enqueueCommands ["System.Directory.setCurrentDirectory " ++ show dir']
+  when (gopt Opt_ExternalInterpreter dflags) $ do
+    hsc_env <- GHC.getSession
+    fhv <- compileGHCiExpr $
+      "System.Directory.setCurrentDirectory " ++ show dir'
+    liftIO $ evalIO hsc_env fhv
 
 trySuccess :: GHC.GhcMonad m => m SuccessFlag -> m SuccessFlag
 trySuccess act =
index 45a5271..a3c21d8 100644 (file)
@@ -24,6 +24,8 @@ module GHCi.UI.Monad (
 
         printForUserNeverQualify, printForUserModInfo,
         printForUser, printForUserPartWay, prettyLocations,
+
+        compileGHCiExpr,
         initInterpBuffering,
         turnOffBuffering, turnOffBuffering_,
         flushInterpBuffers,