Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi-repl: Support module renaming for ghc-9.12 onwards #10880

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Cabal/src/Distribution/Simple/Compiler.hs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ module Distribution.Simple.Compiler
, libraryDynDirSupported
, libraryVisibilitySupported
, jsemSupported
, reexportedAsSupported

-- * Support for profiling detail levels
, ProfDetailLevel (..)
Expand Down Expand Up @@ -432,6 +433,14 @@ jsemSupported comp = case compilerFlavor comp of
where
v = compilerVersion comp

-- | Does the compiler support the -reexported-modules "A as B" syntax
reexportedAsSupported :: Compiler -> Bool
reexportedAsSupported comp = case compilerFlavor comp of
GHC -> v >= mkVersion [9, 12]
_ -> False
where
v = compilerVersion comp

-- | Does this compiler support a package database entry with:
-- "dynamic-library-dirs"?
libraryDynDirSupported :: Compiler -> Bool
Expand Down
9 changes: 9 additions & 0 deletions Cabal/src/Distribution/Simple/Errors.hs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ data CabalException
| UnknownVersionDb String VersionRange FilePath
| MissingCoveredInstalledLibrary UnitId
| SetupHooksException SetupHooksException
| MultiReplDoesNotSupportComplexReexportedModules PackageName ComponentName
deriving (Show)

exceptionCode :: CabalException -> Int
Expand Down Expand Up @@ -304,6 +305,7 @@ exceptionCode e = case e of
MissingCoveredInstalledLibrary{} -> 9341
SetupHooksException err ->
setupHooksExceptionCode err
MultiReplDoesNotSupportComplexReexportedModules{} -> 9355

versionRequirement :: VersionRange -> String
versionRequirement range
Expand Down Expand Up @@ -799,3 +801,10 @@ exceptionMessage e = case e of
++ "' in package database stack."
SetupHooksException err ->
setupHooksExceptionMessage err
MultiReplDoesNotSupportComplexReexportedModules pname cname ->
"When attempting start the repl for "
++ showComponentName cname
++ " from package "
++ prettyShow pname
++ " a module renaming was found.\n"
++ "Multi-repl does not work with complicated reexported-modules until GHC-9.12."
40 changes: 28 additions & 12 deletions Cabal/src/Distribution/Simple/GHC/Build/Link.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ module Distribution.Simple.GHC.Build.Link where
import Distribution.Compat.Prelude
import Prelude ()

import Control.Monad
import Control.Monad.IO.Class
import qualified Data.ByteString.Lazy.Char8 as BS
import qualified Data.Set as Set
import Distribution.Backpack
import Distribution.Compat.Binary (encode)
import Distribution.Compat.ResponseFile
import Distribution.InstalledPackageInfo (InstalledPackageInfo)
Expand All @@ -23,6 +25,7 @@ import Distribution.Pretty
import Distribution.Simple.Build.Inputs
import Distribution.Simple.BuildPaths
import Distribution.Simple.Compiler
import Distribution.Simple.Errors
import Distribution.Simple.GHC.Build.Modules
import Distribution.Simple.GHC.Build.Utils (exeTargetName, flibBuildName, flibTargetName, withDynFLib)
import Distribution.Simple.GHC.ImplInfo
Expand Down Expand Up @@ -740,6 +743,7 @@ runReplOrWriteFlags
runReplOrWriteFlags ghcProg lbi rflags ghcOpts pkg_name target =
let bi = componentBuildInfo $ targetComponent target
clbi = targetCLBI target
cname = componentName (targetComponent target)
comp = compiler lbi
platform = hostPlatform lbi
common = configCommonFlags $ configFlags lbi
Expand All @@ -761,28 +765,40 @@ runReplOrWriteFlags ghcProg lbi rflags ghcOpts pkg_name target =
Flag out_dir -> do
let uid = componentUnitId clbi
this_unit = prettyShow uid
getOpenModName (OpenModule _ mn) = Just mn
getOpenModName (OpenModuleVar{}) = Nothing
reexported_modules =
[ mn | LibComponentLocalBuildInfo{componentExposedModules = exposed_mods} <- [clbi], IPI.ExposedModule mn (Just{}) <- exposed_mods
[ (from_mn, to_mn) | LibComponentLocalBuildInfo{componentExposedModules = exposed_mods} <- [clbi], IPI.ExposedModule to_mn (Just m) <- exposed_mods, Just from_mn <- [getOpenModName m]
]
renderReexportedModule (from_mn, to_mn)
| reexportedAsSupported comp =
pure $ prettyShow from_mn ++ " as " ++ prettyShow to_mn
| otherwise =
if from_mn == to_mn
then pure $ prettyShow to_mn
else dieWithException verbosity (MultiReplDoesNotSupportComplexReexportedModules pkg_name cname)
hidden_modules = otherModules bi
extra_opts =
concat $
[ ["-this-package-name", prettyShow pkg_name]
, case mbWorkDir of
Nothing -> []
Just wd -> ["-working-dir", getSymbolicPath wd]
]
++ [ ["-reexported-module", prettyShow m] | m <- reexported_modules
]
++ [ ["-hidden-module", prettyShow m] | m <- hidden_modules
]
render_extra_opts = do
rexp_mods <- mapM renderReexportedModule reexported_modules
pure $
concat $
[ ["-this-package-name", prettyShow pkg_name]
, case mbWorkDir of
Nothing -> []
Just wd -> ["-working-dir", getSymbolicPath wd]
]
++ [ ["-reexported-module", m] | m <- rexp_mods
]
++ [ ["-hidden-module", prettyShow m] | m <- hidden_modules
]
-- Create "paths" subdirectory if it doesn't exist. This is where we write
-- information about how the PATH was augmented.
createDirectoryIfMissing False (out_dir </> "paths")
-- Write out the PATH information into `paths` subdirectory.
writeFileAtomic (out_dir </> "paths" </> this_unit) (encode ghcProg)
-- Write out options for this component into a file ready for loading into
-- the multi-repl
extra_opts <- render_extra_opts
writeFileAtomic (out_dir </> this_unit) $
BS.pack $
escapeArgs $
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
packages: package-a package-b
multi-repl: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Test.Cabal.Prelude

main = cabalTest $ recordMode DoNotRecord $ do
-- For the multi-repl command
good_ver <- isGhcVersion ">= 9.12"
skipUnlessGhcVersion ">= 9.4"
skipUnlessAnyCabalVersion ">= 3.15"
if good_ver
then do
res <- cabalWithStdin "v2-repl" ["all"] ""
assertOutputContains "Ok, two" res
else do
res <- fails $ cabalWithStdin "v2-repl" ["all"] ""
assertOutputContains "Multi-repl does not work with complicated" res

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Revision history for package-a

## 0.1.0.0 -- YYYY-mm-dd

* First version. Released on an unsuspecting world.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cabal-version: 3.14
name: package-a
version: 0.1.0.0
license: NONE
author: Matthew Pickering
maintainer: [email protected]
build-type: Simple
extra-doc-files: CHANGELOG.md

common warnings
ghc-options: -Wall

library
import: warnings
exposed-modules: PackageA
reexported-modules: Prelude as PreludeA
build-depends: base
hs-source-dirs: src
default-language: Haskell2010
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module PackageA () where

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Revision history for package-b

## 0.1.0.0 -- YYYY-mm-dd

* First version. Released on an unsuspecting world.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
cabal-version: 3.14
name: package-b
version: 0.1.0.0
license: NONE
author: Matthew Pickering
maintainer: [email protected]
build-type: Simple
extra-doc-files: CHANGELOG.md

common warnings
ghc-options: -Wall

library
import: warnings
exposed-modules: PackageB
build-depends: package-a
hs-source-dirs: src
default-language: Haskell2010
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{-# LANGUAGE NoImplicitPrelude #-}
module PackageB (someFunc) where

-- reexport from package-a
import PreludeA
-- Normal import from package-a
import PackageA ()

someFunc :: IO ()
someFunc = putStrLn "someFunc"
12 changes: 12 additions & 0 deletions changelog.d/pr-10880.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
synopsis: 'Fix multi-repl when using reexported-modules with renaming for GHC >= 9.12'
packages: [cabal-install, Cabal]
prs: 10880
issues: 10181
---

Since GHC 9.12, the `-reexported-module` flag has supported module renaming. Therefore
we now use that functionality when starting the multi-repl if it is needed. A new
error message is added to catch the case where you attempt to load a project which
uses this complicated export form but are using < 9.12.

Loading