Skip to content

Commit 4bf1ea0

Browse files
committed
multi-repl: Support module renaming for ghc-9.12 onwards
In ghc-9.12 the -rexported-module flag was extended to add support for module renaming. Therefore now if a module uses a module renaming, then the -reexported-module flag is passed the renaming. Fixes #10181
1 parent dc79523 commit 4bf1ea0

File tree

12 files changed

+133
-12
lines changed

12 files changed

+133
-12
lines changed

Cabal/src/Distribution/Simple/Compiler.hs

+9
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ module Distribution.Simple.Compiler
8484
, libraryDynDirSupported
8585
, libraryVisibilitySupported
8686
, jsemSupported
87+
, reexportedAsSupported
8788

8889
-- * Support for profiling detail levels
8990
, ProfDetailLevel (..)
@@ -432,6 +433,14 @@ jsemSupported comp = case compilerFlavor comp of
432433
where
433434
v = compilerVersion comp
434435

436+
-- | Does the compiler support the -reexported-modules "A as B" syntax
437+
reexportedAsSupported :: Compiler -> Bool
438+
reexportedAsSupported comp = case compilerFlavor comp of
439+
GHC -> v >= mkVersion [9, 12]
440+
_ -> False
441+
where
442+
v = compilerVersion comp
443+
435444
-- | Does this compiler support a package database entry with:
436445
-- "dynamic-library-dirs"?
437446
libraryDynDirSupported :: Compiler -> Bool

Cabal/src/Distribution/Simple/Errors.hs

+9
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ data CabalException
171171
| UnknownVersionDb String VersionRange FilePath
172172
| MissingCoveredInstalledLibrary UnitId
173173
| SetupHooksException SetupHooksException
174+
| MultiReplDoesNotSupportComplexReexportedModules PackageName ComponentName
174175
deriving (Show)
175176

176177
exceptionCode :: CabalException -> Int
@@ -304,6 +305,7 @@ exceptionCode e = case e of
304305
MissingCoveredInstalledLibrary{} -> 9341
305306
SetupHooksException err ->
306307
setupHooksExceptionCode err
308+
MultiReplDoesNotSupportComplexReexportedModules{} -> 9355
307309

308310
versionRequirement :: VersionRange -> String
309311
versionRequirement range
@@ -799,3 +801,10 @@ exceptionMessage e = case e of
799801
++ "' in package database stack."
800802
SetupHooksException err ->
801803
setupHooksExceptionMessage err
804+
MultiReplDoesNotSupportComplexReexportedModules pname cname ->
805+
"When attempting start the repl for "
806+
++ showComponentName cname
807+
++ " from package "
808+
++ prettyShow pname
809+
++ " a module renaming was found.\n"
810+
++ "Multi-repl does not work with complicated reexported-modules until GHC-9.12."

Cabal/src/Distribution/Simple/GHC/Build/Link.hs

+28-12
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ module Distribution.Simple.GHC.Build.Link where
77
import Distribution.Compat.Prelude
88
import Prelude ()
99

10+
import Control.Monad
1011
import Control.Monad.IO.Class
1112
import qualified Data.ByteString.Lazy.Char8 as BS
1213
import qualified Data.Set as Set
14+
import Distribution.Backpack
1315
import Distribution.Compat.Binary (encode)
1416
import Distribution.Compat.ResponseFile
1517
import Distribution.InstalledPackageInfo (InstalledPackageInfo)
@@ -23,6 +25,7 @@ import Distribution.Pretty
2325
import Distribution.Simple.Build.Inputs
2426
import Distribution.Simple.BuildPaths
2527
import Distribution.Simple.Compiler
28+
import Distribution.Simple.Errors
2629
import Distribution.Simple.GHC.Build.Modules
2730
import Distribution.Simple.GHC.Build.Utils (exeTargetName, flibBuildName, flibTargetName, withDynFLib)
2831
import Distribution.Simple.GHC.ImplInfo
@@ -740,6 +743,7 @@ runReplOrWriteFlags
740743
runReplOrWriteFlags ghcProg lbi rflags ghcOpts pkg_name target =
741744
let bi = componentBuildInfo $ targetComponent target
742745
clbi = targetCLBI target
746+
cname = componentName (targetComponent target)
743747
comp = compiler lbi
744748
platform = hostPlatform lbi
745749
common = configCommonFlags $ configFlags lbi
@@ -761,28 +765,40 @@ runReplOrWriteFlags ghcProg lbi rflags ghcOpts pkg_name target =
761765
Flag out_dir -> do
762766
let uid = componentUnitId clbi
763767
this_unit = prettyShow uid
768+
getOpenModName (OpenModule _ mn) = Just mn
769+
getOpenModName (OpenModuleVar{}) = Nothing
764770
reexported_modules =
765-
[ mn | LibComponentLocalBuildInfo{componentExposedModules = exposed_mods} <- [clbi], IPI.ExposedModule mn (Just{}) <- exposed_mods
771+
[ (from_mn, to_mn) | LibComponentLocalBuildInfo{componentExposedModules = exposed_mods} <- [clbi], IPI.ExposedModule to_mn (Just m) <- exposed_mods, Just from_mn <- [getOpenModName m]
766772
]
773+
renderReexportedModule (from_mn, to_mn) =
774+
if reexportedAsSupported comp
775+
then pure $ prettyShow from_mn ++ " as " ++ prettyShow to_mn
776+
else
777+
if from_mn == to_mn
778+
then pure $ prettyShow to_mn
779+
else dieWithException verbosity (MultiReplDoesNotSupportComplexReexportedModules pkg_name cname)
767780
hidden_modules = otherModules bi
768-
extra_opts =
769-
concat $
770-
[ ["-this-package-name", prettyShow pkg_name]
771-
, case mbWorkDir of
772-
Nothing -> []
773-
Just wd -> ["-working-dir", getSymbolicPath wd]
774-
]
775-
++ [ ["-reexported-module", prettyShow m] | m <- reexported_modules
776-
]
777-
++ [ ["-hidden-module", prettyShow m] | m <- hidden_modules
778-
]
781+
render_extra_opts = do
782+
rexp_mods <- mapM renderReexportedModule reexported_modules
783+
pure $
784+
concat $
785+
[ ["-this-package-name", prettyShow pkg_name]
786+
, case mbWorkDir of
787+
Nothing -> []
788+
Just wd -> ["-working-dir", getSymbolicPath wd]
789+
]
790+
++ [ ["-reexported-module", m] | m <- rexp_mods
791+
]
792+
++ [ ["-hidden-module", prettyShow m] | m <- hidden_modules
793+
]
779794
-- Create "paths" subdirectory if it doesn't exist. This is where we write
780795
-- information about how the PATH was augmented.
781796
createDirectoryIfMissing False (out_dir </> "paths")
782797
-- Write out the PATH information into `paths` subdirectory.
783798
writeFileAtomic (out_dir </> "paths" </> this_unit) (encode ghcProg)
784799
-- Write out options for this component into a file ready for loading into
785800
-- the multi-repl
801+
extra_opts <- render_extra_opts
786802
writeFileAtomic (out_dir </> this_unit) $
787803
BS.pack $
788804
escapeArgs $
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
packages: package-a package-b
2+
multi-repl: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Test.Cabal.Prelude
2+
3+
main = cabalTest $ recordMode DoNotRecord $ do
4+
-- For the multi-repl command
5+
good_ver <- isGhcVersion ">= 9.12"
6+
skipUnlessAnyCabalVersion ">= 3.15"
7+
if good_ver
8+
then do
9+
res <- cabalWithStdin "v2-repl" ["all"] ""
10+
assertOutputContains "Ok, two" res
11+
else do
12+
res <- fails $ cabalWithStdin "v2-repl" ["all"] ""
13+
assertOutputContains "Multi-repl does not work with complicated" res
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Revision history for package-a
2+
3+
## 0.1.0.0 -- YYYY-mm-dd
4+
5+
* First version. Released on an unsuspecting world.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
cabal-version: 3.14
2+
name: package-a
3+
version: 0.1.0.0
4+
license: NONE
5+
author: Matthew Pickering
6+
maintainer: [email protected]
7+
build-type: Simple
8+
extra-doc-files: CHANGELOG.md
9+
10+
common warnings
11+
ghc-options: -Wall
12+
13+
library
14+
import: warnings
15+
exposed-modules: PackageA
16+
reexported-modules: Prelude as PreludeA
17+
build-depends: base
18+
hs-source-dirs: src
19+
default-language: Haskell2010
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module PackageA () where
2+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Revision history for package-b
2+
3+
## 0.1.0.0 -- YYYY-mm-dd
4+
5+
* First version. Released on an unsuspecting world.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
cabal-version: 3.14
2+
name: package-b
3+
version: 0.1.0.0
4+
license: NONE
5+
author: Matthew Pickering
6+
maintainer: [email protected]
7+
build-type: Simple
8+
extra-doc-files: CHANGELOG.md
9+
10+
common warnings
11+
ghc-options: -Wall
12+
13+
library
14+
import: warnings
15+
exposed-modules: PackageB
16+
build-depends: package-a
17+
hs-source-dirs: src
18+
default-language: Haskell2010
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{-# LANGUAGE NoImplicitPrelude #-}
2+
module PackageB (someFunc) where
3+
4+
-- reexport from package-a
5+
import PreludeA
6+
-- Normal import from package-a
7+
import PackageA ()
8+
9+
someFunc :: IO ()
10+
someFunc = putStrLn "someFunc"

changelog.d/pr-10880.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
synopsis: 'Fix multi-repl when using reexported-modules with renaming for GHC >= 9.12'
3+
packages: [cabal-install, Cabal]
4+
prs: 10880
5+
issues: 10181
6+
---
7+
8+
Since GHC 9.12, the `-reexported-module` flag has supported module renaming. Therefore
9+
we now use that functionality when starting the multi-repl if it is needed. A new
10+
error message is added to catch the case where you attempt to load a project which
11+
uses this complicated export form but are using < 9.12.
12+

0 commit comments

Comments
 (0)