From 3f335420f33bb55bb3d7be857677cb5d87558d62 Mon Sep 17 00:00:00 2001 From: Alexey Khudyakov Date: Mon, 15 Sep 2025 13:27:32 +0300 Subject: [PATCH 1/2] Drop support for GHC<8.8 It's already 6 years old, it's version shipped by Debian oldoldstable so it provides quite generous supported version range. - Drop old GHC from CI build matrix - Bump dependency on deepseq to >=1.4.3 (version shipped with GHC 8.2) - Drop outdated conditional compilation and cabal checks. At this point we have only #if MIN_VERSION cabal checks! --- .github/workflows/ci.yml | 8 -------- vector-stream/src/Data/Stream/Monadic.hs | 13 ------------ vector-stream/vector-stream.cabal | 6 +----- vector/src/Data/Vector.hs | 16 +-------------- .../src/Data/Vector/Fusion/Bundle/Monadic.hs | 12 ----------- vector/src/Data/Vector/Primitive.hs | 8 +------- vector/src/Data/Vector/Primitive/Mutable.hs | 8 +------- vector/src/Data/Vector/Storable.hs | 8 +------- vector/src/Data/Vector/Storable/Mutable.hs | 8 +------- vector/src/Data/Vector/Strict.hs | 16 +-------------- vector/src/Data/Vector/Unboxed/Base.hs | 10 ++-------- vector/tests-inspect/main.hs | 5 ----- vector/tests/Tests/Deriving.hs | 5 ----- vector/vector.cabal | 20 +++++-------------- 14 files changed, 14 insertions(+), 129 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cc0cc7f6..fc7681ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,10 +18,6 @@ jobs: matrix: include: # Linux - - { cabal: "3.14", os: ubuntu-24.04, ghc: "8.0.2" } - - { cabal: "3.14", os: ubuntu-24.04, ghc: "8.2.2" } - - { cabal: "3.14", os: ubuntu-24.04, ghc: "8.4.4" } - - { cabal: "3.14", os: ubuntu-24.04, ghc: "8.6.5" } - { cabal: "3.14", os: ubuntu-24.04, ghc: "8.8.4" } - { cabal: "3.14", os: ubuntu-24.04, ghc: "8.10.7" } - { cabal: "3.14", os: ubuntu-24.04, ghc: "9.0.2" } @@ -34,15 +30,11 @@ jobs: - { cabal: "3.14", os: ubuntu-24.04, ghc: "9.10.2" } - { cabal: "3.14", os: ubuntu-24.04, ghc: "9.12.2" } # Win - - { cabal: "3.14", os: windows-latest, ghc: "8.4.4" } - { cabal: "3.14", os: windows-latest, ghc: "9.6.7" } - { cabal: "3.14", os: windows-latest, ghc: "9.8.4" } - { cabal: "3.14", os: windows-latest, ghc: "9.10.2" } - { cabal: "3.14", os: windows-latest, ghc: "9.12.2" } - # Too flaky: - # - { cabal: "3.6", os: windows-latest, ghc: "9.0.1" } # MacOS - - { cabal: "3.14", os: macOS-13, ghc: "8.4.4" } # Fails with linker errors # > ld: warning: -single_module is obsolete # > : can't load framework: Security (not found) diff --git a/vector-stream/src/Data/Stream/Monadic.hs b/vector-stream/src/Data/Stream/Monadic.hs index 6c86ee64..33867919 100644 --- a/vector-stream/src/Data/Stream/Monadic.hs +++ b/vector-stream/src/Data/Stream/Monadic.hs @@ -1555,24 +1555,11 @@ enumFromTo_double :: (Monad m, Ord a, RealFrac a) => a -> a -> Stream m a enumFromTo_double n m = n `seq` m `seq` Stream step ini where lim = m + 1/2 -- important to float out - --- GHC changed definition of Enum for Double in GHC8.6 so we have to --- accommodate both definitions in order to preserve validity of --- rewrite rule --- --- ISSUE: https://gitlab.haskell.org/ghc/ghc/issues/15081 --- COMMIT: https://gitlab.haskell.org/ghc/ghc/commit/4ffaf4b67773af4c72d92bb8b6c87b1a7d34ac0f -#if MIN_VERSION_base(4,12,0) ini = 0 step x | x' <= lim = return $ Yield x' (x+1) | otherwise = return $ Done where x' = x + n -#else - ini = n - step x | x <= lim = return $ Yield x (x+1) - | otherwise = return $ Done -#endif {-# RULES diff --git a/vector-stream/vector-stream.cabal b/vector-stream/vector-stream.cabal index 26a9fbc5..4000172f 100644 --- a/vector-stream/vector-stream.cabal +++ b/vector-stream/vector-stream.cabal @@ -22,10 +22,6 @@ Description: as a backbone for vector package fusion functionality. Tested-With: - GHC == 8.0.2 - GHC == 8.2.2 - GHC == 8.4.4 - GHC == 8.6.5 GHC == 8.8.4 GHC == 8.10.7 GHC == 9.0.2 @@ -51,7 +47,7 @@ Library Hs-Source-Dirs: src - Build-Depends: base >= 4.9 && < 4.23 + Build-Depends: base >= 4.13 && < 4.23 , ghc-prim >= 0.2 && < 0.14 source-repository head diff --git a/vector/src/Data/Vector.hs b/vector/src/Data/Vector.hs index cf204731..9ce30de8 100644 --- a/vector/src/Data/Vector.hs +++ b/vector/src/Data/Vector.hs @@ -184,16 +184,9 @@ import Data.Primitive.Array import qualified Data.Vector.Fusion.Bundle as Bundle import qualified Data.Vector.Generic as G -import Control.DeepSeq ( NFData(rnf) -#if MIN_VERSION_deepseq(1,4,3) - , NFData1(liftRnf) -#endif - ) +import Control.DeepSeq ( NFData(rnf), NFData1(liftRnf)) import Control.Monad ( MonadPlus(..), liftM, ap ) -#if !MIN_VERSION_base(4,13,0) -import Control.Monad (fail) -#endif import Control.Monad.ST ( ST, runST ) import Control.Monad.Primitive import qualified Control.Monad.Fail as Fail @@ -230,12 +223,10 @@ instance NFData a => NFData (Vector a) where rnf = liftRnfV rnf {-# INLINEABLE rnf #-} -#if MIN_VERSION_deepseq(1,4,3) -- | @since 0.12.1.0 instance NFData1 Vector where liftRnf = liftRnfV {-# INLINEABLE liftRnf #-} -#endif instance Show a => Show (Vector a) where showsPrec = G.showsPrec @@ -348,11 +339,6 @@ instance Monad Vector where {-# INLINE (>>=) #-} (>>=) = flip concatMap -#if !(MIN_VERSION_base(4,13,0)) - {-# INLINE fail #-} - fail = Fail.fail -- == \ _str -> empty -#endif - -- | @since 0.12.1.0 instance Fail.MonadFail Vector where {-# INLINE fail #-} diff --git a/vector/src/Data/Vector/Fusion/Bundle/Monadic.hs b/vector/src/Data/Vector/Fusion/Bundle/Monadic.hs index 99a3bdea..6e51532f 100644 --- a/vector/src/Data/Vector/Fusion/Bundle/Monadic.hs +++ b/vector/src/Data/Vector/Fusion/Bundle/Monadic.hs @@ -1018,23 +1018,11 @@ enumFromTo_double n m = n `seq` m `seq` fromStream (Stream step ini) (Max (len n l = truncate (y-x)+2 {-# INLINE_INNER step #-} --- GHC changed definition of Enum for Double in GHC8.6 so we have to --- accommodate both definitions in order to preserve validity of --- rewrite rule --- --- ISSUE: https://gitlab.haskell.org/ghc/ghc/issues/15081 --- COMMIT: https://gitlab.haskell.org/ghc/ghc/commit/4ffaf4b67773af4c72d92bb8b6c87b1a7d34ac0f -#if MIN_VERSION_base(4,12,0) ini = 0 step x | x' <= lim = return $ Yield x' (x+1) | otherwise = return $ Done where x' = x + n -#else - ini = n - step x | x <= lim = return $ Yield x (x+1) - | otherwise = return $ Done -#endif {-# RULES diff --git a/vector/src/Data/Vector/Primitive.hs b/vector/src/Data/Vector/Primitive.hs index 16c0a2a5..dade073f 100644 --- a/vector/src/Data/Vector/Primitive.hs +++ b/vector/src/Data/Vector/Primitive.hs @@ -169,11 +169,7 @@ import qualified Data.Vector.Fusion.Bundle as Bundle import Data.Primitive.ByteArray import Data.Primitive ( Prim, sizeOf ) -import Control.DeepSeq ( NFData(rnf) -#if MIN_VERSION_deepseq(1,4,3) - , NFData1(liftRnf) -#endif - ) +import Control.DeepSeq ( NFData(rnf), NFData1(liftRnf)) import Control.Monad ( liftM ) import Control.Monad.ST ( ST ) @@ -213,11 +209,9 @@ data Vector a = Vector {-# UNPACK #-} !Int -- ^ offset instance NFData (Vector a) where rnf (Vector _ _ _) = () -#if MIN_VERSION_deepseq(1,4,3) -- | @since 0.12.1.0 instance NFData1 Vector where liftRnf _ (Vector _ _ _) = () -#endif instance (Show a, Prim a) => Show (Vector a) where showsPrec = G.showsPrec diff --git a/vector/src/Data/Vector/Primitive/Mutable.hs b/vector/src/Data/Vector/Primitive/Mutable.hs index 627a2350..6c8dd884 100644 --- a/vector/src/Data/Vector/Primitive/Mutable.hs +++ b/vector/src/Data/Vector/Primitive/Mutable.hs @@ -77,11 +77,7 @@ import Data.Word ( Word8 ) import Control.Monad.Primitive import Control.Monad ( liftM ) -import Control.DeepSeq ( NFData(rnf) -#if MIN_VERSION_deepseq(1,4,3) - , NFData1(liftRnf) -#endif - ) +import Control.DeepSeq ( NFData(rnf), NFData1(liftRnf)) import Prelude ( Ord, Bool, Int, Maybe, Ordering(..) @@ -116,10 +112,8 @@ type STVector s = MVector s instance NFData (MVector s a) where rnf (MVector _ _ _) = () -#if MIN_VERSION_deepseq(1,4,3) instance NFData1 (MVector s) where liftRnf _ (MVector _ _ _) = () -#endif instance Prim a => G.MVector MVector a where basicLength (MVector _ n _) = n diff --git a/vector/src/Data/Vector/Storable.hs b/vector/src/Data/Vector/Storable.hs index aa1a8c29..fb32941a 100644 --- a/vector/src/Data/Vector/Storable.hs +++ b/vector/src/Data/Vector/Storable.hs @@ -178,11 +178,7 @@ import Foreign.ForeignPtr import Foreign.Ptr import Foreign.Marshal.Array ( advancePtr, copyArray ) -import Control.DeepSeq ( NFData(rnf) -#if MIN_VERSION_deepseq(1,4,3) - , NFData1(liftRnf) -#endif - ) +import Control.DeepSeq ( NFData(rnf), NFData1(liftRnf)) import Control.Monad.ST ( ST ) import Control.Monad.Primitive @@ -221,11 +217,9 @@ data Vector a = Vector {-# UNPACK #-} !Int instance NFData (Vector a) where rnf (Vector _ _) = () -#if MIN_VERSION_deepseq(1,4,3) -- | @since 0.12.1.0 instance NFData1 Vector where liftRnf _ (Vector _ _) = () -#endif instance (Show a, Storable a) => Show (Vector a) where showsPrec = G.showsPrec diff --git a/vector/src/Data/Vector/Storable/Mutable.hs b/vector/src/Data/Vector/Storable/Mutable.hs index 524bd691..2e3c3cd2 100644 --- a/vector/src/Data/Vector/Storable/Mutable.hs +++ b/vector/src/Data/Vector/Storable/Mutable.hs @@ -76,11 +76,7 @@ module Data.Vector.Storable.Mutable( Storable, PrimMonad, PrimState, RealWorld ) where -import Control.DeepSeq ( NFData(rnf) -#if MIN_VERSION_deepseq(1,4,3) - , NFData1(liftRnf) -#endif - ) +import Control.DeepSeq ( NFData(rnf), NFData1(liftRnf)) import qualified Data.Vector.Generic.Mutable as G import Data.Vector.Storable.Internal @@ -134,10 +130,8 @@ type STVector s = MVector s instance NFData (MVector s a) where rnf (MVector _ _) = () -#if MIN_VERSION_deepseq(1,4,3) instance NFData1 (MVector s) where liftRnf _ (MVector _ _) = () -#endif instance Storable a => G.MVector MVector a where {-# INLINE basicLength #-} diff --git a/vector/src/Data/Vector/Strict.hs b/vector/src/Data/Vector/Strict.hs index 3019679b..a7f0a565 100644 --- a/vector/src/Data/Vector/Strict.hs +++ b/vector/src/Data/Vector/Strict.hs @@ -184,16 +184,9 @@ import Data.Primitive.Array import qualified Data.Vector.Generic as G import qualified Data.Vector as V -import Control.DeepSeq ( NFData(rnf) -#if MIN_VERSION_deepseq(1,4,3) - , NFData1(liftRnf) -#endif - ) +import Control.DeepSeq ( NFData(rnf), NFData1(liftRnf)) import Control.Monad ( MonadPlus(..), ap ) -#if !MIN_VERSION_base(4,13,0) -import Control.Monad (fail) -#endif import Control.Monad.ST ( ST, runST ) import Control.Monad.Primitive import qualified Control.Monad.Fail as Fail @@ -241,12 +234,10 @@ instance NFData a => NFData (Vector a) where rnf = liftRnfV rnf {-# INLINEABLE rnf #-} -#if MIN_VERSION_deepseq(1,4,3) -- | @since 0.13.2.0 instance NFData1 Vector where liftRnf = liftRnfV {-# INLINEABLE liftRnf #-} -#endif instance Show a => Show (Vector a) where showsPrec = G.showsPrec @@ -335,11 +326,6 @@ instance Monad Vector where {-# INLINE (>>=) #-} (>>=) = flip concatMap -#if !(MIN_VERSION_base(4,13,0)) - {-# INLINE fail #-} - fail = Fail.fail -- == \ _str -> empty -#endif - -- | @since 0.13.2.0 instance Fail.MonadFail Vector where {-# INLINE fail #-} diff --git a/vector/src/Data/Vector/Unboxed/Base.hs b/vector/src/Data/Vector/Unboxed/Base.hs index 50062af7..da0db7c2 100644 --- a/vector/src/Data/Vector/Unboxed/Base.hs +++ b/vector/src/Data/Vector/Unboxed/Base.hs @@ -40,12 +40,7 @@ import qualified Data.Vector.Primitive as P import Control.Applicative (Const(..)) -import Control.DeepSeq ( NFData(rnf) -#if MIN_VERSION_deepseq(1,4,3) - , NFData1(liftRnf) -#endif - , force - ) +import Control.DeepSeq ( NFData(rnf), NFData1(liftRnf), force) import Control.Monad.Primitive import Control.Monad ( liftM ) @@ -79,14 +74,13 @@ class (G.Vector Vector a, M.MVector MVector a) => Unbox a instance NFData (Vector a) where rnf !_ = () instance NFData (MVector s a) where rnf !_ = () -#if MIN_VERSION_deepseq(1,4,3) -- | @since 0.12.1.0 instance NFData1 Vector where liftRnf _ !_ = () -- | @since 0.12.1.0 instance NFData1 (MVector s) where liftRnf _ !_ = () -#endif + instance (Data a, Unbox a) => Data (Vector a) where gfoldl = G.gfoldl diff --git a/vector/tests-inspect/main.hs b/vector/tests-inspect/main.hs index b6eda69d..52dd6db0 100644 --- a/vector/tests-inspect/main.hs +++ b/vector/tests-inspect/main.hs @@ -1,16 +1,11 @@ -{-# LANGUAGE CPP #-} module Main (main) where import qualified Inspect -#if MIN_VERSION_base(4,12,0) import qualified Inspect.DerivingVia -#endif import Test.Tasty (defaultMain,testGroup) main :: IO () main = defaultMain $ testGroup "tests" [ Inspect.tests -#if MIN_VERSION_base(4,12,0) , Inspect.DerivingVia.tests -#endif ] diff --git a/vector/tests/Tests/Deriving.hs b/vector/tests/Tests/Deriving.hs index fa7dc87f..ce884dfd 100644 --- a/vector/tests/Tests/Deriving.hs +++ b/vector/tests/Tests/Deriving.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} @@ -10,9 +9,7 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UnboxedTuples #-} -#if MIN_VERSION_base(4,12,0) {-# LANGUAGE DerivingVia #-} -#endif -- | -- These tests make sure that derived Unbox instances actually works. -- It's distressingly easy to forget to export some constructor and @@ -31,7 +28,6 @@ import qualified Data.Vector.Storable as VS import qualified Data.Vector.Primitive as VP import qualified Data.Vector.Unboxed as VU -#if MIN_VERSION_base(4,12,0) ---------------------------------------------------------------- -- Primitive @@ -183,4 +179,3 @@ deriving via (FooAs a `VU.As` (Int, a)) instance VU.Unbox a => VGM.MVector VU.MV deriving via (FooAs a `VU.As` (Int, a)) instance VU.Unbox a => VG.Vector VU.Vector (FooAs a) instance VU.Unbox a => VU.Unbox (FooAs a) -#endif diff --git a/vector/vector.cabal b/vector/vector.cabal index f4f38417..62a4369b 100644 --- a/vector/vector.cabal +++ b/vector/vector.cabal @@ -44,10 +44,6 @@ Description: * Tested-With: - GHC == 8.0.2 - GHC == 8.2.2 - GHC == 8.4.4 - GHC == 8.6.5 GHC == 8.8.4 GHC == 8.10.7 GHC == 9.0.2 @@ -98,8 +94,6 @@ common flag-Wall Ghc-Options: -Wall if !flag(Wall) Ghc-Options: -fno-warn-orphans - if impl(ghc >= 8.0) && impl(ghc < 8.1) - Ghc-Options: -Wno-redundant-constraints Library import: flag-Wall @@ -161,9 +155,9 @@ Library Install-Includes: vector.h - Build-Depends: base >= 4.9 && < 4.23 + Build-Depends: base >= 4.13 && < 4.23 , primitive >= 0.6.4.0 && < 0.10 - , deepseq >= 1.1 && < 1.6 + , deepseq >= 1.4.3 && < 1.6 , vector-stream >= 0.1 && < 0.2 Ghc-Options: -O2 @@ -188,7 +182,7 @@ common tests-common Ghc-Options: -Wno-x-partial Ghc-Options: -fno-warn-missing-signatures hs-source-dirs: tests - Build-Depends: base >= 4.5 && < 5 + Build-Depends: base >= 4.13 && < 5 , template-haskell , base-orphans >= 0.6 , vector @@ -241,9 +235,6 @@ test-suite vector-doctest main-is: doctests.hs hs-source-dirs: tests default-language: Haskell2010 - -- Older GHC don't support DerivingVia and doctests use them - if impl(ghc < 8.6) - buildable: False -- Attempts to run doctests on macos on GHC8.10 and 9.0 cause linker errors: -- > ld: warning: -undefined dynamic_lookup may not work with chained fixups if os(darwin) && impl(ghc >= 8.10) && impl(ghc < 9.2) @@ -261,8 +252,7 @@ test-suite vector-inspection main-is: main.hs default-language: Haskell2010 Other-modules: Inspect - if impl(ghc >= 8.6) - Other-modules: Inspect.DerivingVia + Inspect.DerivingVia Inspect.DerivingVia.OtherFoo build-depends: base -any @@ -305,7 +295,7 @@ benchmark algorithms default-language: Haskell2010 build-depends: - base >= 2 && < 5 + base >= 4.13 && < 5 , random >= 1.2 , tasty , tasty-bench >= 0.2.1 From 40e01736dbee31842ce668bdf251a28a18268243 Mon Sep 17 00:00:00 2001 From: Alexey Khudyakov Date: Mon, 15 Sep 2025 13:33:49 +0300 Subject: [PATCH 2/2] Drop liftRnfV function We can use method from NFData1 --- vector/src/Data/Vector.hs | 7 ++----- vector/src/Data/Vector/Strict.hs | 13 +++++-------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/vector/src/Data/Vector.hs b/vector/src/Data/Vector.hs index 9ce30de8..6c373bba 100644 --- a/vector/src/Data/Vector.hs +++ b/vector/src/Data/Vector.hs @@ -216,16 +216,13 @@ data Vector a = Vector {-# UNPACK #-} !Int {-# UNPACK #-} !Int {-# UNPACK #-} !(Array a) -liftRnfV :: (a -> ()) -> Vector a -> () -liftRnfV elemRnf = foldl' (\_ -> elemRnf) () - instance NFData a => NFData (Vector a) where - rnf = liftRnfV rnf + rnf = liftRnf rnf {-# INLINEABLE rnf #-} -- | @since 0.12.1.0 instance NFData1 Vector where - liftRnf = liftRnfV + liftRnf elemRnf = foldl' (\_ -> elemRnf) () {-# INLINEABLE liftRnf #-} instance Show a => Show (Vector a) where diff --git a/vector/src/Data/Vector/Strict.hs b/vector/src/Data/Vector/Strict.hs index a7f0a565..58db6d3f 100644 --- a/vector/src/Data/Vector/Strict.hs +++ b/vector/src/Data/Vector/Strict.hs @@ -227,16 +227,13 @@ newtype Vector a = Vector (V.Vector a) -- parameters (e.g. Eq, Ord) and not OK to derive ones where new -- vector is created (e.g. Read, Functor) -liftRnfV :: (a -> ()) -> Vector a -> () -liftRnfV elemRnf = foldl' (\_ -> elemRnf) () - instance NFData a => NFData (Vector a) where - rnf = liftRnfV rnf + rnf = liftRnf rnf {-# INLINEABLE rnf #-} -- | @since 0.13.2.0 instance NFData1 Vector where - liftRnf = liftRnfV + liftRnf elemRnf = foldl' (\_ -> elemRnf) () {-# INLINEABLE liftRnf #-} instance Show a => Show (Vector a) where @@ -2562,7 +2559,7 @@ toLazy (Vector v) = v -- | /O(n)/ Convert lazy array to strict array. This function reduces -- each element of vector to WHNF. fromLazy :: V.Vector a -> Vector a -fromLazy vec = liftRnfV (`seq` ()) v `seq` v where v = Vector vec +fromLazy vec = liftRnf (`seq` ()) v `seq` v where v = Vector vec -- Conversions - Arrays @@ -2573,7 +2570,7 @@ fromLazy vec = liftRnfV (`seq` ()) v `seq` v where v = Vector vec -- @since 0.13.2.0 fromArray :: Array a -> Vector a {-# INLINE fromArray #-} -fromArray arr = liftRnfV (`seq` ()) vec `seq` vec +fromArray arr = liftRnf (`seq` ()) vec `seq` vec where vec = Vector $ V.fromArray arr @@ -2611,7 +2608,7 @@ unsafeFromArraySlice :: -> Int -- ^ Length -> Vector a {-# INLINE unsafeFromArraySlice #-} -unsafeFromArraySlice arr offset len = liftRnfV (`seq` ()) vec `seq` vec +unsafeFromArraySlice arr offset len = liftRnf (`seq` ()) vec `seq` vec where vec = Vector (V.unsafeFromArraySlice arr offset len)