From b73ac1ed25c28b3e5098574144248533c1a6e3c5 Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Tue, 22 Sep 2026 10:20:57 -0400 Subject: [PATCH 1/7] Add bounds exceptions for ghc >= 10 --- Cabal-tree-diff/Cabal-tree-diff.cabal | 2 +- project-cabal/ghc-latest.config | 64 +++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/Cabal-tree-diff/Cabal-tree-diff.cabal b/Cabal-tree-diff/Cabal-tree-diff.cabal index 2285c97e66d..6c9b6c6b52b 100644 --- a/Cabal-tree-diff/Cabal-tree-diff.cabal +++ b/Cabal-tree-diff/Cabal-tree-diff.cabal @@ -13,7 +13,7 @@ library , base , Cabal-syntax ^>=3.19.0.0 , Cabal ^>=3.19.0.0 - , tree-diff ^>=0.1 || ^>=0.2 || ^>=0.3 + , tree-diff >=0.1 && < 0.5 exposed-modules: Data.TreeDiff.Instances.Cabal other-modules: diff --git a/project-cabal/ghc-latest.config b/project-cabal/ghc-latest.config index 5e4dd4e3a45..a8db4fdbb87 100644 --- a/project-cabal/ghc-latest.config +++ b/project-cabal/ghc-latest.config @@ -8,11 +8,67 @@ -- NOTE: don't forget to update the compiler version in the conditional -- when upgrading to a newer GHC -if impl(ghc >= 9.14.0) +if impl(ghc >= 10) allow-newer: - --windns:*, rere:*, tree-diff:*, uuid-types:*, these:*, assoc:*, semialign:*, indexed-traversable-instances:*, indexed-traversable:*, OneTuple:*, scientific:*, time-compat:*, text-short:*, integer-conversion:*, generically:*, data-fix:*, binary:* - -- Artem, 2024-04-21: I started and then gave up... - *:base, *:template-haskell, text-short, *:deepseq, *:bytestring, *:ghc-prim, *:ghc-bignum, *:containers + aeson:template-haskell + , aeson:time + , assoc:base + , async:base + , bifunctors:template-haskell + , Cabal-3.12.1.0:containers + , Cabal-3.12.1.0:time + , Cabal-syntax-3.12.1.0:containers + , Cabal-syntax-3.12.1.0:time + , cabal-testsuite:containers + , data-fix:base + , hackage-security:base + , hackage-security:ghc-prim + , hackage-security:template-haskell + , hackage-security:time + , hsc2hs:base + , HTTP:base + , HTTP:time + , indexed-traversable:base + , indexed-traversable-instances:base + , integer-conversion:base + , integer-logarithms:base + , nothunks:containers + , nothunks:time + , OneTuple:base + , parallel:base + , primitive:base + , scientific:base + , scientific:template-haskell + , semialign:base + , splitmix:base + , tagged:template-haskell + , tasty-bench:ghc-prim + , text-iso8601:time + , text-short:base + , text-short:ghc-prim + , text-short:template-haskell + , th-abstraction:template-haskell + , th-compat:template-haskell + , these:base + , time-compat:base + , time-compat:time + , tree-diff:base + , unordered-containers:template-haskell + , uuid-types:template-haskell + , vector:base + , vector-stream:base + , vector-stream:ghc-prim + , vector-th-unbox:template-haskell + , zinza:base + , zlib:base + source-repository-package + type: git + location: https://github.com/typechecker/hashable.git + tag: fb9badd5ae735c7be180242bdde7ea0f5a230cfd + source-repository-package + type: git + location: https://github.com/typechecker/vector-th-unbox.git + tag: 39832ca661766155d4dae6faa1275cdcabe516b8 -- repository head.hackage.ghc.haskell.org -- url: https://ghc.gitlab.haskell.org/head.hackage/ From 62f93d898a598efbb20b2b665b97f0da20c74d2e Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Tue, 22 Sep 2026 13:03:05 -0400 Subject: [PATCH 2/7] Avoid deepseq deprecation of NFData (a -> b) --- .../Client/ProjectConfig/Types.hs | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs index 852ae187ba3..ed4ca398269 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DerivingVia #-} +{-# LANGUAGE NamedFieldPuns #-} -- | Handling project configuration, types. module Distribution.Client.ProjectConfig.Types @@ -500,4 +501,53 @@ data BuildTimeSettings = BuildTimeSettings } deriving (Generic) -instance NFData BuildTimeSettings +-- | This instance avoids the deepseq deprecation of @NFData (a -> b)@ triggered +-- by buildSettingLogFile the alternative @instance NFData BuildTimeSettings@. +instance NFData BuildTimeSettings where + rnf + BuildTimeSettings + { buildSettingDryRun + , buildSettingOnlyDeps + , buildSettingOnlyDownload + , buildSettingSummaryFile + , buildSettingLogFile + , buildSettingLogVerbosity + , buildSettingBuildReports + , buildSettingReportPlanningFailure + , buildSettingSymlinkBinDir + , buildSettingNumJobs + , buildSettingKeepGoing + , buildSettingOfflineMode + , buildSettingKeepTempFiles + , buildSettingRemoteRepos + , buildSettingLocalNoIndexRepos + , buildSettingCacheDir + , buildSettingHttpTransport + , buildSettingIgnoreExpiry + , buildSettingProgPathExtra + , buildSettingHaddockOpen + , buildSettingBuildTimings + } = + rnf + [ rnf buildSettingDryRun + , rnf buildSettingOnlyDeps + , rnf buildSettingOnlyDownload + , rnf buildSettingSummaryFile + , maybe () (`seq` ()) buildSettingLogFile + , rnf buildSettingLogVerbosity + , rnf buildSettingBuildReports + , rnf buildSettingReportPlanningFailure + , rnf buildSettingSymlinkBinDir + , rnf buildSettingNumJobs + , rnf buildSettingKeepGoing + , rnf buildSettingOfflineMode + , rnf buildSettingKeepTempFiles + , rnf buildSettingRemoteRepos + , rnf buildSettingLocalNoIndexRepos + , rnf buildSettingCacheDir + , rnf buildSettingHttpTransport + , rnf buildSettingIgnoreExpiry + , rnf buildSettingProgPathExtra + , rnf buildSettingHaddockOpen + , rnf buildSettingBuildTimings + ] From 8ba2a53c436aa57d350c4b8eb0e575a6bb855b83 Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Tue, 22 Sep 2026 13:04:01 -0400 Subject: [PATCH 3/7] Avoid -Wx-partial about last --- .../src/Distribution/Client/Init/NonInteractive/Command.hs | 7 +++---- .../Distribution/Client/Init/NonInteractive/Heuristics.hs | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index e25d5293149..982d0cdc894 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -41,7 +41,6 @@ import Distribution.Client.Init.Types import Distribution.Client.Compat.Prelude hiding (getLine, head, last, putStr, putStrLn) import Prelude () -import Data.List (last) import qualified Data.List.NonEmpty as NEL import Distribution.CabalSpecVersion (CabalSpecVersion (..)) @@ -56,7 +55,7 @@ import Distribution.Simple.Setup (fromFlagOrDefault, pattern Flag, pattern NoFla import Distribution.Solver.Types.PackageIndex (elemByPackageName) import Distribution.Types.Dependency (Dependency (..)) import Distribution.Types.PackageName (PackageName, unPackageName) -import Distribution.Utils.Generic (safeHead) +import Distribution.Utils.Generic (safeHead, safeLast) import Distribution.Verbosity import Distribution.Version (Version) @@ -267,7 +266,7 @@ packageNameHeuristics sourcePkgDb flags = getPackageName flags $ do defName <- guessPackageName =<< case packageDir flags of Flag a -> return a - NoFlag -> last . splitDirectories <$> getCurrentDirectory + NoFlag -> fromMaybe "" . safeLast . splitDirectories <$> getCurrentDirectory when (isPkgRegistered defName) $ putStrLn (inUseMsg defName) @@ -413,7 +412,7 @@ libOtherModulesHeuristics flags = case otherModules flags of if exists then do otherModules' <- filter isHaskell <$> listFilesRecursive libDir - filter ((`elem` otherCandidates) . last . components) + filter (maybe False (`elem` otherCandidates) . safeLast . components) . catMaybes <$> traverse retrieveModuleName otherModules' else return [] diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs index 789bde1619e..10e400532d3 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs @@ -32,7 +32,6 @@ import Distribution.Client.Compat.Prelude hiding (many, readFile, (<|>)) import Distribution.Simple.Setup (fromFlagOrDefault) import Data.Functor ((<&>)) -import qualified Data.List as L import qualified Data.Set as Set import Distribution.CabalSpecVersion import Distribution.Client.Init.Defaults @@ -40,7 +39,7 @@ import Distribution.Client.Init.FlagExtractors (getCabalVersionNoPrompt) import Distribution.Client.Init.Types import Distribution.Client.Init.Utils import Distribution.FieldGrammar.Newtypes -import Distribution.Simple.Utils (ordNub) +import Distribution.Simple.Utils (ordNub, safeLast) import Distribution.Types.PackageName (PackageName) import Distribution.Version import System.FilePath @@ -101,7 +100,7 @@ guessPackageType flags = do if fromFlagOrDefault False (initializeTestSuite flags) then return TestSuite else do - let lastDir dirs = L.last . splitDirectories $ dirs + let lastDir dirs = fromMaybe "" . safeLast . splitDirectories $ dirs srcCandidates = [defaultSourceDir, "src", "source"] testCandidates = [defaultTestDir, "test", "tests"] From 935bbefa0902b6fda2b541a1fe11f6ac4e5be52b Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Tue, 22 Sep 2026 13:28:59 -0400 Subject: [PATCH 4/7] Fix integration test with allow-newer --- cabal-install/tests/IntegrationTests2.hs | 28 +++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index a3d9e20820a..f3ac0c6f57b 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PatternSynonyms #-} -- For the handy instance IsString PackageIdentifier @@ -30,10 +31,20 @@ import Distribution.Client.Targets , UserConstraintScope (UserAnyQualifier) ) import Distribution.Client.Types - ( PackageLocation (..) + ( AllowNewer (..) + , PackageLocation (..) , PackageSpecifier (..) , UnresolvedSourcePackage ) +#if MIN_VERSION_GLASGOW_HASKELL(10,0,0,0) && !MIN_VERSION_GLASGOW_HASKELL(10,0,1,0) +import Distribution.Client.Types + ( RelaxDepMod (..) + , RelaxDepScope (..) + , RelaxDepSubject (..) + , RelaxDeps (..) + , RelaxedDep (..) + ) +#endif import Distribution.Solver.Types.ConstraintSource ( ConstraintSource (ConstraintSourceUnknown) ) @@ -882,9 +893,24 @@ testTargetProblemsCommon config0 = do , ConstraintSourceUnknown ) ] + , projectConfigAllowNewer = filepathAllowNewer } } +-- | allow-newer: filepath:base only while we're using a pre-release of ghc-10 +filepathAllowNewer :: Maybe AllowNewer +#if MIN_VERSION_GLASGOW_HASKELL(10,0,0,0) && !MIN_VERSION_GLASGOW_HASKELL(10,0,1,0) +filepathAllowNewer = + Just . AllowNewer . RelaxDepsSome $ + [ RelaxedDep + (RelaxDepScopePackage "filepath") + RelaxDepModNone + (RelaxDepSubjectPkg "base") + ] +#else +filepathAllowNewer = Nothing +#endif + testTargetProblemsBuild :: ProjectConfig -> (String -> IO ()) -> Assertion testTargetProblemsBuild config reportSubCase = do reportSubCase "empty-pkg" From 278f4cd19a89b02c65471704a110f0211947902c Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Thu, 24 Sep 2026 15:49:29 -0400 Subject: [PATCH 5/7] Move allow-newer exception to the test project --- cabal-install/tests/IntegrationTests2.hs | 28 +------------------ .../targets/complex/cabal.project | 3 ++ 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index f3ac0c6f57b..a3d9e20820a 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PatternSynonyms #-} -- For the handy instance IsString PackageIdentifier @@ -31,20 +30,10 @@ import Distribution.Client.Targets , UserConstraintScope (UserAnyQualifier) ) import Distribution.Client.Types - ( AllowNewer (..) - , PackageLocation (..) + ( PackageLocation (..) , PackageSpecifier (..) , UnresolvedSourcePackage ) -#if MIN_VERSION_GLASGOW_HASKELL(10,0,0,0) && !MIN_VERSION_GLASGOW_HASKELL(10,0,1,0) -import Distribution.Client.Types - ( RelaxDepMod (..) - , RelaxDepScope (..) - , RelaxDepSubject (..) - , RelaxDeps (..) - , RelaxedDep (..) - ) -#endif import Distribution.Solver.Types.ConstraintSource ( ConstraintSource (ConstraintSourceUnknown) ) @@ -893,24 +882,9 @@ testTargetProblemsCommon config0 = do , ConstraintSourceUnknown ) ] - , projectConfigAllowNewer = filepathAllowNewer } } --- | allow-newer: filepath:base only while we're using a pre-release of ghc-10 -filepathAllowNewer :: Maybe AllowNewer -#if MIN_VERSION_GLASGOW_HASKELL(10,0,0,0) && !MIN_VERSION_GLASGOW_HASKELL(10,0,1,0) -filepathAllowNewer = - Just . AllowNewer . RelaxDepsSome $ - [ RelaxedDep - (RelaxDepScopePackage "filepath") - RelaxDepModNone - (RelaxDepSubjectPkg "base") - ] -#else -filepathAllowNewer = Nothing -#endif - testTargetProblemsBuild :: ProjectConfig -> (String -> IO ()) -> Assertion testTargetProblemsBuild config reportSubCase = do reportSubCase "empty-pkg" diff --git a/cabal-install/tests/IntegrationTests2/targets/complex/cabal.project b/cabal-install/tests/IntegrationTests2/targets/complex/cabal.project index c58dcdd9480..3694ffeeac5 100644 --- a/cabal-install/tests/IntegrationTests2/targets/complex/cabal.project +++ b/cabal-install/tests/IntegrationTests2/targets/complex/cabal.project @@ -1 +1,4 @@ packages: q/ + +if impl(ghc >= 10.0 && < 10.0.1) + allow-newer: filepath:base From 906fe96c8c6cdbbc465dc668d080939b4df67d56 Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Thu, 24 Sep 2026 16:03:26 -0400 Subject: [PATCH 6/7] Trigger a failure with ghc >= 10.0.1 --- .../tests/IntegrationTests2/targets/complex/cabal.project | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cabal-install/tests/IntegrationTests2/targets/complex/cabal.project b/cabal-install/tests/IntegrationTests2/targets/complex/cabal.project index 3694ffeeac5..29450c5f1b2 100644 --- a/cabal-install/tests/IntegrationTests2/targets/complex/cabal.project +++ b/cabal-install/tests/IntegrationTests2/targets/complex/cabal.project @@ -1,4 +1,9 @@ packages: q/ -if impl(ghc >= 10.0 && < 10.0.1) +if impl(ghc >= 10.0.1) + -- When ghc-10.0.1, or later, is released remove this conditional block and + -- the allow-newer exception. + packages: ghc-10.0.1-is-released-remove-this-workaround/ +elif impl(ghc >= 10.0) + -- When using a pre-release of ghc-10 allow-newer: filepath:base From 4fc590dc80935972e202dcc8ad3dc6775ae37baa Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Thu, 24 Sep 2026 16:10:20 -0400 Subject: [PATCH 7/7] Use getCurrentDirectory as-is --- .../src/Distribution/Client/Init/NonInteractive/Command.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index 982d0cdc894..ee4c670ac94 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -63,7 +63,7 @@ import Language.Haskell.Extension (Extension (..), Language (..)) import qualified Data.Set as Set import Distribution.FieldGrammar.Newtypes -import System.FilePath (splitDirectories, ()) +import System.FilePath (()) -- | Main driver for interactive prompt code. createProject @@ -266,7 +266,7 @@ packageNameHeuristics sourcePkgDb flags = getPackageName flags $ do defName <- guessPackageName =<< case packageDir flags of Flag a -> return a - NoFlag -> fromMaybe "" . safeLast . splitDirectories <$> getCurrentDirectory + NoFlag -> getCurrentDirectory when (isPkgRegistered defName) $ putStrLn (inUseMsg defName)