diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,10 @@
+0.4.1.0 (2021-11-14)
+====================
+
+-   Support GHC 9.2. (#45)
+
 0.4.0.0 (2021-01-14)
-================
+====================
 
 Breaking changes:
 
diff --git a/pinch.cabal b/pinch.cabal
--- a/pinch.cabal
+++ b/pinch.cabal
@@ -1,11 +1,11 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.34.2.
+-- This file has been generated from package.yaml by hpack version 0.34.4.
 --
 -- see: https://github.com/sol/hpack
 
 name:           pinch
-version:        0.4.0.0
+version:        0.4.1.0
 synopsis:       An alternative implementation of Thrift for Haskell.
 description:    This library provides machinery for types to specify how they can be
                 serialized and deserialized into/from Thrift payloads. It makes no
@@ -26,7 +26,8 @@
 maintainer:     mail@abhinavg.net
 license:        BSD3
 license-file:   LICENSE
-tested-with:    GHC == 8.10.2, GHC == 8.8.3, GHC == 8.6.5, GHC == 8.4.4
+tested-with:
+    GHC == 8.10.2, GHC == 8.8.3, GHC == 8.6.5, GHC == 8.4.4
 build-type:     Simple
 extra-source-files:
     README.md
@@ -74,16 +75,16 @@
   build-depends:
       array >=0.5
     , base >=4.7 && <5
-    , bytestring >=0.10 && <0.11
+    , bytestring >=0.10 && <0.12
     , cereal >=0.5.8.1 && <0.6
     , containers >=0.5 && <0.7
     , deepseq >=1.3 && <1.5
     , ghc-prim
     , hashable >=1.2 && <1.4
-    , network >=3.1 && <3.2
+    , network ==3.1.*
     , semigroups >=0.18 && <0.20
-    , text >=1.2 && <1.3
-    , unordered-containers >=0.2 && <0.3
+    , text ==1.2.*
+    , unordered-containers ==0.2.*
     , vector >=0.10 && <0.13
   default-language: Haskell2010
 
@@ -115,15 +116,15 @@
       QuickCheck >=2.5
     , async >=2.2.2 && <2.3
     , base >=4.7 && <5
-    , bytestring >=0.10 && <0.11
+    , bytestring >=0.10 && <0.12
     , cereal >=0.5.8.1 && <0.6
     , containers >=0.5 && <0.7
     , hspec >=2.0
-    , network >=3.1 && <3.2
+    , network ==3.1.*
     , network-run >=0.2.4 && <0.3
     , pinch
     , semigroups >=0.18 && <0.20
-    , text >=1.2 && <1.3
-    , unordered-containers >=0.2 && <0.3
+    , text ==1.2.*
+    , unordered-containers ==0.2.*
     , vector >=0.10 && <0.13
   default-language: Haskell2010
diff --git a/src/Pinch/Internal/Bits.hs b/src/Pinch/Internal/Bits.hs
--- a/src/Pinch/Internal/Bits.hs
+++ b/src/Pinch/Internal/Bits.hs
@@ -17,8 +17,15 @@
     ) where
 
 #if defined(__GLASGOW_HASKELL__) && !defined(__HADDOCK__)
-import GHC.Base (Int (..), uncheckedShiftL#)
-import GHC.Word (Word16 (..), Word32 (..), Word64 (..), uncheckedShiftL64#)
+import GHC.Base (
+    Int (..),
+#if MIN_VERSION_base(4,16,0)
+    uncheckedShiftLWord16#,
+    uncheckedShiftLWord32#,
+#endif
+    uncheckedShiftL#,
+    )
+import GHC.Word (Word16 (..), Word32 (..), Word64 (..))
 #else
 import Data.Bits (shiftL)
 import Data.Word (Word16, Word32, Word64)
@@ -36,9 +43,14 @@
 -- If we're not on GHC, the regular shiftL will be returned.
 
 #if defined(__GLASGOW_HASKELL__) && !defined(__HADDOCK__)
+#if MIN_VERSION_base(4,16,0)
+w16ShiftL (W16# w) (I# i) = W16# (w `uncheckedShiftLWord16#` i)
+w32ShiftL (W32# w) (I# i) = W32# (w `uncheckedShiftLWord32#` i)
+#else
 w16ShiftL (W16# w) (I# i) = W16# (w `uncheckedShiftL#` i)
 w32ShiftL (W32# w) (I# i) = W32# (w `uncheckedShiftL#` i)
-w64ShiftL (W64# w) (I# i) = W64# (w `uncheckedShiftL64#` i)
+#endif
+w64ShiftL (W64# w) (I# i) = W64# (w `uncheckedShiftL#` i)
 #else
 w16ShiftL = shiftL
 w32ShiftL = shiftL
diff --git a/src/Pinch/Internal/Builder.hs b/src/Pinch/Internal/Builder.hs
--- a/src/Pinch/Internal/Builder.hs
+++ b/src/Pinch/Internal/Builder.hs
@@ -63,12 +63,6 @@
     {-# INLINE mempty #-}
     mempty = B 0 (\_ -> return ())
 
-    {-# INLINE mappend #-}
-    mappend = append
-
-    {-# INLINE mconcat #-}
-    mconcat = foldr mappend mempty
-
 primFixed :: BP.FixedPrim a -> a -> Builder
 primFixed prim a = B (BPI.size prim) (BPI.runF prim a)
 {-# INLINE [1] primFixed #-}
diff --git a/src/Pinch/Internal/FoldList.hs b/src/Pinch/Internal/FoldList.hs
--- a/src/Pinch/Internal/FoldList.hs
+++ b/src/Pinch/Internal/FoldList.hs
@@ -121,6 +121,3 @@
 instance Monoid (FoldList a) where
     mempty = FoldList (\_ r -> r)
     {-# INLINE mempty #-}
-
-    FoldList f1 `mappend` FoldList f2 = FoldList $ \cons nil -> f2 cons (f1 cons nil)
-    {-# INLINE mappend #-}
diff --git a/src/Pinch/Internal/Pinchable.hs b/src/Pinch/Internal/Pinchable.hs
--- a/src/Pinch/Internal/Pinchable.hs
+++ b/src/Pinch/Internal/Pinchable.hs
@@ -44,6 +44,7 @@
 import Data.ByteString (ByteString)
 import Data.Hashable   (Hashable)
 import Data.Int        (Int16, Int32, Int64, Int8)
+import Data.Kind       (Type)
 import Data.List       (foldl')
 import Data.Text       (Text)
 import Data.Typeable   ((:~:) (..))
@@ -80,7 +81,7 @@
 
 -- | GPinchable is used to impelment support for automatically deriving
 -- instances of Pinchable via generics.
-class IsTType (GTag f) => GPinchable (f :: * -> *) where
+class IsTType (GTag f) => GPinchable (f :: Type -> Type) where
     -- | 'TType' tag to use for objects of this type.
     type GTag f
 
diff --git a/tests/Pinch/Arbitrary.hs b/tests/Pinch/Arbitrary.hs
--- a/tests/Pinch/Arbitrary.hs
+++ b/tests/Pinch/Arbitrary.hs
@@ -3,6 +3,7 @@
 {-# LANGUAGE FlexibleInstances          #-}
 {-# LANGUAGE GADTs                      #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE ScopedTypeVariables        #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Pinch.Arbitrary
@@ -138,8 +139,9 @@
         T.TBinary -> shrinkBinary
         T.TStruct ->
             \(V.VStruct xs) -> V.VStruct . M.fromList <$> shrink (M.toList xs)
-        T.TMap ->
-            \(V.VMap xs) -> V.VMap . FL.fromFoldable <$> shrink (FL.toList xs)
+        T.TMap -> \case
+            V.VMap xs -> V.VMap . FL.fromFoldable <$> shrink (FL.toList xs)
+            V.VNullMap -> []
         T.TSet ->
             \(V.VSet xs) -> V.VSet . FL.fromFoldable <$> shrink (FL.toList xs)
         T.TList ->
diff --git a/tests/Pinch/ClientServerSpec.hs b/tests/Pinch/ClientServerSpec.hs
--- a/tests/Pinch/ClientServerSpec.hs
+++ b/tests/Pinch/ClientServerSpec.hs
@@ -25,7 +25,8 @@
 
 import           Pinch
 import           Pinch.Arbitrary          ()
-import           Pinch.Client
+import           Pinch.Client             hiding (client)
+import qualified Pinch.Client             (client)
 import           Pinch.Server
 import           Pinch.Transport
 
@@ -34,9 +35,9 @@
   pure r
 
 data CalcRequest = CalcRequest
-  { inp1 :: Field 1 Int32
-  , inp2 :: Field 2 Int32
-  , op   :: Field 3 Op
+  { _inp1 :: Field 1 Int32
+  , _inp2 :: Field 2 Int32
+  , _op   :: Field 3 Op
   } deriving (Generic, Show)
 instance Pinchable CalcRequest
 
@@ -67,7 +68,7 @@
 
 errorServer :: ThriftServer
 errorServer = createServer $ \nm -> case nm of
-  "app_ex" -> Just $ CallHandler $ \_ (msg :: Value TStruct) ->
+  "app_ex" -> Just $ CallHandler $ \_ (_ :: Value TStruct) ->
     throwIO $ ApplicationException "Test" InternalError :: IO (Value TStruct)
   "hs_ex" -> Just $ CallHandler $ \_ (_ :: Value TStruct) -> error "nononono" :: IO (Value TStruct)
   _ -> Nothing
@@ -131,7 +132,7 @@
 
         _ <- call client (TCall "missing" val :: ThriftCall (Value TStruct)) `shouldThrow` \e ->
           case e of
-            ApplicationException msg ty -> ty == WrongMethodName
+            ApplicationException _ ty -> ty == WrongMethodName
         pure ()
 
   where
@@ -144,7 +145,7 @@
     bracketOnError (open addr) close (\sock ->
       withAsync (loop sock `finally` close sock) $ \_ ->
         runTCPClient "127.0.0.1" "54093" $ \s -> do
-          c <- client <$> createChannel s framedTransport binaryProtocol
+          c <- Pinch.Client.client <$> createChannel s framedTransport binaryProtocol
           cont c
       )
   where
diff --git a/tests/Pinch/Internal/BuilderParserSpec.hs b/tests/Pinch/Internal/BuilderParserSpec.hs
--- a/tests/Pinch/Internal/BuilderParserSpec.hs
+++ b/tests/Pinch/Internal/BuilderParserSpec.hs
@@ -5,7 +5,6 @@
 import Control.Applicative
 #endif
 
-import Data.Monoid
 import Test.Hspec
 import Test.Hspec.QuickCheck
 
diff --git a/tests/Pinch/Internal/BuilderSpec.hs b/tests/Pinch/Internal/BuilderSpec.hs
--- a/tests/Pinch/Internal/BuilderSpec.hs
+++ b/tests/Pinch/Internal/BuilderSpec.hs
@@ -2,7 +2,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Pinch.Internal.BuilderSpec (spec) where
 
-import Data.Monoid
 import Data.Word             (Word8)
 import Test.Hspec
 import Test.Hspec.QuickCheck
diff --git a/tests/Pinch/TransportSpec.hs b/tests/Pinch/TransportSpec.hs
--- a/tests/Pinch/TransportSpec.hs
+++ b/tests/Pinch/TransportSpec.hs
@@ -19,7 +19,7 @@
 
 data MemoryConnection = MemoryConnection
   { contents :: IORef ByteString
-  , maxChunkSize :: Int -- ^ how many bytes to maximally return for one cGetSome call
+  , _maxChunkSize :: Int -- ^ how many bytes to maximally return for one cGetSome call
   }
 
 newMemoryConnection :: Int -> IO MemoryConnection
