diff --git a/derive-storable-plugin.cabal b/derive-storable-plugin.cabal
--- a/derive-storable-plugin.cabal
+++ b/derive-storable-plugin.cabal
@@ -1,8 +1,8 @@
--- Initial generic-storable-plugin.cabal generated by cabal init.  For 
+-- Initial generic-storable-plugin.cabal generated by cabal init.  For
 -- further documentation, see http://haskell.org/cabal/users-guide/
 
 name:                derive-storable-plugin
-version:             0.2.3.6
+version:             0.2.3.7
 synopsis:            GHC core plugin supporting the derive-storable package.
 description:         The package helps derive-storable package in forcing compile time evaluation of
                      sizes, alignments and offsets.
@@ -11,12 +11,12 @@
 license-file:        LICENSE
 author:              Mateusz Kłoczko
 maintainer:          mateusz.p.kloczko@gmail.com
--- copyright:           
+-- copyright:
 category:            Foreign
 build-type:          Simple
 extra-source-files:  ChangeLog.md README.md
 cabal-version:       >=1.10
-tested-with:         GHC==8.2.2, GHC==8.4.2, GHC==8.6.5, GHC==8.8.1, GHC==8.10.7, GHC==9.0.2, GHC==9.2.2, GHC==9.4.2
+tested-with:         GHC==8.2.2, GHC==8.4.2, GHC==8.6.5, GHC==8.8.1, GHC==8.10.7, GHC==9.0.2, GHC==9.2.2, GHC==9.4.2, GHC==9.6.1
 
 Flag sumtypes
   Description:   Use sumtypes within benchmark and tests.
@@ -32,7 +32,7 @@
                        , Foreign.Storable.Generic.Plugin.Internal.Predicates
                        , Foreign.Storable.Generic.Plugin.Internal.Types
   other-extensions:    DeriveGeneric, DeriveAnyClass, PatternGuards
-  build-depends:       base >=4.10 && <5, ghc >= 8.2 && < 9.5, ghci >= 8.2 && < 9.5, derive-storable >= 0.3 && < 0.4
+  build-depends:       base >=4.10 && <5, ghc >= 8.2 && < 9.7, ghci >= 8.2 && < 9.7, derive-storable >= 0.3 && < 0.4
   hs-source-dirs:      src
   default-language:    Haskell2010
 
@@ -53,16 +53,15 @@
 
 test-suite c_alignment
   type:                exitcode-stdio-1.0
-  
+
   hs-source-dirs:      test/Basic, test/Basic/cbits
-  c-sources:           test/Basic/cbits/TestCases.c 
+  c-sources:           test/Basic/cbits/TestCases.c
   main-is:             MemoryCSpec.hs
-  other-modules:       TestCases 
+  other-modules:       TestCases
   build-depends:       base >= 4.10 && < 5, derive-storable, derive-storable-plugin
                      , hspec >= 2.4, QuickCheck >= 2.10
-                     , ghc >= 8.2 && < 9.5, ghci >= 8.2 && < 9.5
-  
+                     , ghc >= 8.2 && < 9.7, ghci >= 8.2 && < 9.7
+
   default-language:    Haskell2010
   if flag(sumtypes)
     cpp-options: -DGSTORABLE_SUMTYPES
-
diff --git a/src/Foreign/Storable/Generic/Plugin.hs b/src/Foreign/Storable/Generic/Plugin.hs
--- a/src/Foreign/Storable/Generic/Plugin.hs
+++ b/src/Foreign/Storable/Generic/Plugin.hs
@@ -6,7 +6,7 @@
 Stability   : experimental
 Portability : GHC-only
 
-GHC Core plugin for optimising GStorable instances. 
+GHC Core plugin for optimising GStorable instances.
 For more information please refer to generic-storable package.
 
 How to enable:
@@ -18,7 +18,10 @@
 {-# LANGUAGE CPP #-}
 module Foreign.Storable.Generic.Plugin (plugin) where
 
-
+#if   MIN_VERSION_GLASGOW_HASKELL(9,6,1,0)
+import GHC.Core.Opt.Simplify.Env (SimplMode (sm_phase))
+import GHC.Core.Opt.Simplify (so_mode)
+#endif
 #if   MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
 import GHC.Plugins
 #else
@@ -46,33 +49,37 @@
 defFlags = Flags Some False
 
 orderingPass :: Flags -> IORef [[Type]] -> CoreToDo
-orderingPass flags io_ref = CoreDoPluginPass "GStorable - type ordering" 
+orderingPass flags io_ref = CoreDoPluginPass "GStorable - type ordering"
                                 (groupTypes flags io_ref)
 
 substitutionPass :: Flags -> IORef [[Type]] -> CoreToDo
-substitutionPass flags io_ref = CoreDoPluginPass "GStorable - substitution" 
+substitutionPass flags io_ref = CoreDoPluginPass "GStorable - substitution"
                                 (gstorableSubstitution flags io_ref)
 
 -- | Checks whether the core pass is a simplifier phase 0.
-isPhase0 :: CoreToDo 
+isPhase0 :: CoreToDo
          -> Bool
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+isPhase0 (CoreDoSimplify simpl_mode) = case sm_phase $ (so_mode simpl_mode) of
+#else
 isPhase0 (CoreDoSimplify iters simpl_mode) = case sm_phase $ simpl_mode of
+#endif
     Phase 0 -> True
-    _       -> False 
+    _       -> False
 isPhase0 _ = False
 
--- | Return the index of simplifier phase 0. 
+-- | Return the index of simplifier phase 0.
 afterPhase0 :: [CoreToDo] -> Maybe Int
-afterPhase0 todos = findIndex isPhase0 todos 
+afterPhase0 todos = findIndex isPhase0 todos
 
 -- | Checks whether the core pass is a specialising pass.
 isSpecialize :: CoreToDo -> Bool
 isSpecialize CoreDoSpecialising = True
 isSpecialize _                  = False
 
--- | Return the index of the specialising pass. 
+-- | Return the index of the specialising pass.
 afterSpecialize :: [CoreToDo] -> Maybe Int
-afterSpecialize todos = findIndex isSpecialize todos 
+afterSpecialize todos = findIndex isSpecialize todos
 
 -- | Set the verbosity and ToCrash flags based on supplied arguments.
 setOpts :: Flags -> String -> Flags
@@ -87,7 +94,7 @@
 parseOpts opts = foldl' setOpts defFlags opts
 
 
-putPasses :: Flags -> [CoreToDo] -> Int -> Int -> CoreM [CoreToDo] 
+putPasses :: Flags -> [CoreToDo] -> Int -> Int -> CoreM [CoreToDo]
 putPasses flags todos ph0 sp = do
     the_ioref <- liftIO $ newIORef []
     let (before_spec,after_spec)   = splitAt sp  todos
@@ -104,10 +111,10 @@
         printer = case verb of
             None  -> return ()
             other -> putMsg $ text "The GStorable plugin requires simplifier phases with inlining and rules on, as well as a specialiser phase."
-                          $$ text "Try to compile the code with -O1 or -O2 optimisation flags." 
+                          $$ text "Try to compile the code with -O1 or -O2 optimisation flags."
     printer
     when to_crash $ (return $ error "Crashing...")
-    
+
 
 
 install :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo]
diff --git a/src/Foreign/Storable/Generic/Plugin/Internal.hs b/src/Foreign/Storable/Generic/Plugin/Internal.hs
--- a/src/Foreign/Storable/Generic/Plugin/Internal.hs
+++ b/src/Foreign/Storable/Generic/Plugin/Internal.hs
@@ -11,7 +11,7 @@
 -}
 {-#LANGUAGE CPP #-}
 
-module Foreign.Storable.Generic.Plugin.Internal 
+module Foreign.Storable.Generic.Plugin.Internal
     ( groupTypes
     , gstorableSubstitution)
 where
@@ -38,21 +38,31 @@
 #else
 import GHC.Driver.Types (HscEnv,ModGuts(..))
 #endif
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+import GHC.Core.Opt.Pipeline.Types (CoreToDo(..))
+#else
+import GHC.Core.Opt.Monad (CoreToDo(..))
+#endif
 import GHC.Core.Opt.Monad
-    (CoreM, CoreToDo(..), 
-     getHscEnv, getDynFlags, putMsg, putMsgS)
+    (CoreM, getHscEnv, getDynFlags, putMsg, putMsgS)
 import GHC.Types.Basic (CompilerPhase(..))
 import GHC.Core.Type (isAlgType, splitTyConApp_maybe)
 import GHC.Core.TyCon (tyConKind, algTyConRhs, visibleDataCons)
-import GHC.Core.TyCo.Rep (Type(..), TyBinder(..))
+import GHC.Core.TyCo.Rep (Type(..))
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+import GHC.Types.Var (PiTyBinder(..))
+#define TyBinder PiTyBinder
+#else
+import GHC.Core.TyCo.Rep (TyBinder(..))
+#endif
 import GHC.Builtin.Types   (intDataCon)
-import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys) 
+import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys)
 import GHC.Core.Make       (mkWildValBinder)
-import GHC.Utils.Outputable 
+import GHC.Utils.Outputable
     (cat, ppr, SDoc, showSDocUnsafe,
-     ($$), ($+$), hsep, vcat, empty,text, 
-     (<>), (<+>), nest, int, colon,hcat, comma, 
-     punctuate, fsep) 
+     ($$), ($+$), hsep, vcat, empty,text,
+     (<>), (<+>), nest, int, colon,hcat, comma,
+     punctuate, fsep)
 import GHC.Core.Opt.Monad (putMsg, putMsgS)
 #elif MIN_VERSION_GLASGOW_HASKELL(8,2,1,0)
 import CoreSyn (Bind(..),Expr(..), CoreExpr, CoreBind, CoreProgram, Alt)
@@ -67,21 +77,21 @@
 import Unique (getUnique)
 import HscMain (hscCompileCoreExpr)
 import HscTypes (HscEnv,ModGuts(..))
-import CoreMonad 
-    (CoreM, CoreToDo(..), 
+import CoreMonad
+    (CoreM, CoreToDo(..),
      getHscEnv, getDynFlags, putMsg, putMsgS)
 import BasicTypes (CompilerPhase(..))
 import Type (isAlgType, splitTyConApp_maybe)
 import TyCon (tyConKind, algTyConRhs, visibleDataCons)
 import TyCoRep (Type(..), TyBinder(..))
 import TysWiredIn (intDataCon)
-import DataCon    (dataConWorkId,dataConOrigArgTys) 
+import DataCon    (dataConWorkId,dataConOrigArgTys)
 import MkCore (mkWildValBinder)
-import Outputable 
+import Outputable
     (cat, ppr, SDoc, showSDocUnsafe,
-     ($$), ($+$), hsep, vcat, empty,text, 
-     (<>), (<+>), nest, int, colon,hcat, comma, 
-     punctuate, fsep) 
+     ($$), ($+$), hsep, vcat, empty,text,
+     (<>), (<+>), nest, int, colon,hcat, comma,
+     punctuate, fsep)
 import CoreMonad (putMsg, putMsgS)
 #endif
 
@@ -93,7 +103,7 @@
 import Data.IORef
 import Debug.Trace
 import Control.Monad.IO.Class
-import Control.Monad 
+import Control.Monad
 
 import Foreign.Storable.Generic.Plugin.Internal.Error
 import Foreign.Storable.Generic.Plugin.Internal.Compile
@@ -127,7 +137,7 @@
             other           -> pprError verb other
         printer errs = case errs of
             [] -> return ()
-            ls ->  putMsg $ print_header (vcat (map print_err errs)) 
+            ls ->  putMsg $ print_header (vcat (map print_err errs))
     -- Do printing
     -- Eventually crash.
     printer errors
@@ -171,7 +181,7 @@
         bad_types_zip id m_t = case m_t of
             Nothing -> Just $ TypeNotFound id
             Just _  -> Nothing
-        bad_types     =    catMaybes $ zipWith bad_types_zip gstorable_ids m_gstorable_types 
+        bad_types     =    catMaybes $ zipWith bad_types_zip gstorable_ids m_gstorable_types
         -- type_list is used instead of type_set because Type has no uniquable instance.
         type_list = [ t | Just t <- m_gstorable_types]
         -- Calculate the type ordering.
@@ -179,7 +189,7 @@
 
     groupTypes_info flags type_order
     groupTypes_errors flags bad_types
-    
+
     liftIO $ writeIORef type_order_ref type_order
     return guts
 
@@ -192,7 +202,7 @@
 -- | Print errors related to CoreBind grouping.
 -- Return the badly grouped bindings, and perhaps crash
 -- the compiler.
-grouping_errors :: Flags            -- ^ Verbosity and ToCrash options 
+grouping_errors :: Flags            -- ^ Verbosity and ToCrash options
                 -> Maybe Error      -- ^ The error
                 -> CoreM [CoreBind] -- ^ Recovered bindings.
 grouping_errors flags m_err = do
@@ -204,10 +214,10 @@
        print_header txt = case verb of
            None  -> empty
            other ->    text "Errors while grouping bindings: "
-                    $$ nest 4 txt 
+                    $$ nest 4 txt
        printer m_err = case m_err of
            Nothing  -> return ()
-           Just err ->  putMsg $ print_header (pprError verb err) 
+           Just err ->  putMsg $ print_header (pprError verb err)
        ungroup m_e = case m_e of
            Just (OrderingFailedBinds _ rest) -> rest
            _                                 -> []
@@ -217,7 +227,7 @@
 
 
 -- | Print the information related to found GStorable ids.
-foundBinds_info :: Flags    -- ^ Verbosity and ToCrash options 
+foundBinds_info :: Flags    -- ^ Verbosity and ToCrash options
                 -> [Id]     -- ^ GStorable ids.
                 -> CoreM ()
 foundBinds_info flags ids = do
@@ -237,7 +247,7 @@
         -- Use eqType for maybes
         eqType_maybe (Just t1) (Just t2) = t1 `eqType` t2
         eqType_maybe _         _         = False
-        -- group and sort the bindings 
+        -- group and sort the bindings
         grouped = groupBy (\i1 i2 -> (getGStorableType $ varType i1) `eqType_maybe` (getGStorableType $ varType i2) ) ids
         sorting = sortBy (\i1 i2 -> varName i1 `compare` varName i2)
         sorted  = map sorting grouped
@@ -247,7 +257,7 @@
             (h:_) -> case getGStorableType $ varType h of
                 Just gtype ->     ppr  gtype
                               $+$ (fsep $ punctuate comma (map print_binding the_group))
-                Nothing    -> ppr "Could not get the type of a binding:" 
+                Nothing    -> text "Could not get the type of a binding:"
                               $+$ nest 4 (ppr h <+> text "::" <+> ppr (varType h))
     -- Print the ids
     printer sorted
@@ -257,8 +267,8 @@
                       -> IORef [[Type]] -- ^ Reference to grouped types.
                       -> ModGuts        -- ^ Information about compiled module.
                       -> CoreM ModGuts  -- ^ Information about compiled module, with GStorable optimisations.
-gstorableSubstitution flags type_order_ref guts = do 
-    type_hierarchy <- liftIO $ readIORef type_order_ref 
+gstorableSubstitution flags type_order_ref guts = do
+    type_hierarchy <- liftIO $ readIORef type_order_ref
     let binds  = mg_binds guts
         -- Get all GStorable binds.
         -- Check whether the type has no constraints.
@@ -267,18 +277,18 @@
             else getGStorableMethodType t
         -- predicate = toIsBind (withTypeCheck typeCheck isGStorableMethodId)
         predicate = toIsBind (isGStorableMethodId)
-        
+
         (gstorable_binds,rest) = partition predicate binds
         -- Check if there are any recursives somehow
         -- The plugin won't be able to handle them.
         (nonrecs, recs) = partition isNonRecBind gstorable_binds
         -- Group the gstorables by nestedness
         (grouped_binds, m_err_group) = groupBinds type_hierarchy nonrecs
-   
-    foundBinds_info flags $ concatMap getIdsBind $ concat grouped_binds 
+
+    foundBinds_info flags $ concatMap getIdsBind $ concat grouped_binds
     -- Check for errors
     not_grouped <- grouping_errors flags m_err_group
     -- Compile and replace gstorable bindings
     new_gstorables <- compileGroups flags grouped_binds rest -- perhaps return errors here ?
-    
+
     return $ guts {mg_binds = concat [new_gstorables, not_grouped,recs,rest]}
diff --git a/src/Foreign/Storable/Generic/Plugin/Internal/Compile.hs b/src/Foreign/Storable/Generic/Plugin/Internal/Compile.hs
--- a/src/Foreign/Storable/Generic/Plugin/Internal/Compile.hs
+++ b/src/Foreign/Storable/Generic/Plugin/Internal/Compile.hs
@@ -10,8 +10,8 @@
 
 -}
 {-#LANGUAGE CPP#-}
-module Foreign.Storable.Generic.Plugin.Internal.Compile 
-    ( 
+module Foreign.Storable.Generic.Plugin.Internal.Compile
+    (
     -- Compilation
       compileExpr
     , tryCompileExpr
@@ -60,16 +60,21 @@
 #else
 import GHC.Driver.Types (HscEnv,ModGuts(..))
 #endif
-import GHC.Core.Opt.Monad (CoreM,CoreToDo(..),getHscEnv,getDynFlags)
+import GHC.Core.Opt.Monad (CoreM,getHscEnv,getDynFlags)
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+import GHC.Core.Opt.Pipeline.Types (CoreToDo(..))
+#else
+import GHC.Core.Opt.Monad (CoreToDo(..))
+#endif
 import GHC.Core.Lint (lintExpr)
 import GHC.Types.Basic (CompilerPhase(..), Boxity(..))
 import GHC.Core.Type
 import GHC.Core.TyCon (algTyConRhs, visibleDataCons)
-import GHC.Builtin.Types   
-import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys) 
+import GHC.Builtin.Types
+import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys)
 import GHC.Core.Make       (mkWildValBinder)
 import GHC.Utils.Outputable (cat, ppr, SDoc, showSDocUnsafe)
-import GHC.Utils.Outputable (Outputable(..),($$), ($+$), vcat, empty,text, (<>), (<+>), nest, int, comma) 
+import GHC.Utils.Outputable (Outputable(..),($$), ($+$), vcat, empty,text, (<>), (<+>), nest, int, comma)
 import GHC.Core.Opt.Monad (putMsg, putMsgS)
 import GHC.Builtin.Names  (buildIdKey, augmentIdKey)
 import GHC.Builtin.Types.Prim (intPrimTy)
@@ -91,11 +96,11 @@
 import BasicTypes (CompilerPhase(..), Boxity(..))
 import Type (isAlgType, splitTyConApp_maybe)
 import TyCon (algTyConRhs, visibleDataCons)
-import TysWiredIn 
-import DataCon    (dataConWorkId,dataConOrigArgTys) 
+import TysWiredIn
+import DataCon    (dataConWorkId,dataConOrigArgTys)
 import MkCore (mkWildValBinder)
 import Outputable (cat, ppr, SDoc, showSDocUnsafe)
-import Outputable (Outputable(..),($$), ($+$), vcat, empty,text, (<>), (<+>), nest, int, comma) 
+import Outputable (Outputable(..),($$), ($+$), vcat, empty,text, (<>), (<+>), nest, int, comma)
 import CoreMonad (putMsg, putMsgS)
 import PrelNames (buildIdKey, augmentIdKey)
 import TysPrim (intPrimTy)
@@ -107,8 +112,14 @@
 import GHCi.RemoteTypes
 
 
-#if MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
 import GHC.Types.Var (TyVarBinder(..), VarBndr(..))
+import GHC.Core.TyCo.Rep (Type(..), scaledThing)
+import GHC.Types.Var
+import GHC.Driver.Config.Core.Lint (initLintConfig)
+#define Many ManyTy
+#elif MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
+import GHC.Types.Var (TyVarBinder(..), VarBndr(..))
 import GHC.Core.TyCo.Rep (Type(..), TyBinder(..), TyCoBinder(..),scaledThing)
 import GHC.Types.Var
 #elif MIN_VERSION_GLASGOW_HASKELL(8,8,1,0)
@@ -148,13 +159,13 @@
 -- import CoreMonad (CoreM,CoreToDo(..), getHscEnv, getDynFlags)
 -- import CoreLint (lintExpr)
 -- import BasicTypes (CompilerPhase(..))
--- -- Haskell types 
+-- -- Haskell types
 -- import Type (isAlgType, splitTyConApp_maybe)
 -- import TyCon (tyConName, algTyConRhs, visibleDataCons)
 -- import TyCoRep (Type(..), TyBinder(..), TyLit(..))
 -- import TysWiredIn
 -- import TysPrim (intPrimTy)
--- import DataCon    (dataConWorkId,dataConOrigArgTys) 
+-- import DataCon    (dataConWorkId,dataConOrigArgTys)
 
 
 import Unsafe.Coerce
@@ -174,12 +185,18 @@
 import Foreign.Storable.Generic.Plugin.Internal.Predicates
 import Foreign.Storable.Generic.Plugin.Internal.Types
 
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+-- See 778c6adca2c995cd8a1b84394d4d5ca26b915dac
+type TyBinder = PiTyBinder
+type TyCoVarBinder = ForAllTyBinder
+#endif
+
 ---------------------
 -- compile helpers --
 ---------------------
 
 -- | Compile an expression.
-compileExpr :: HscEnv -> CoreExpr -> SrcSpan -> IO a 
+compileExpr :: HscEnv -> CoreExpr -> SrcSpan -> IO a
 compileExpr hsc_env expr src_span = do
 #if MIN_VERSION_GLASGOW_HASKELL(9,4,0,0)
     (foreign_hval, _, _) <-
@@ -188,7 +205,7 @@
 #endif
       liftIO $ hscCompileCoreExpr hsc_env src_span expr
     hval         <- liftIO $ withForeignRef foreign_hval localRef
-    let val = unsafeCoerce hval :: a 
+    let val = unsafeCoerce hval :: a
     -- finalizeForeignRef foreign_hval  -- check whether that's the source of the error
     return val
 
@@ -196,7 +213,7 @@
 tryCompileExpr :: Id -> CoreExpr -> CoreM (Either Error a)
 tryCompileExpr id core_expr  = do
     hsc_env <- getHscEnv
-    e_compiled <- liftIO $ try $ 
+    e_compiled <- liftIO $ try $
                     compileExpr hsc_env core_expr (getSrcSpan id) :: CoreM (Either SomeException a)
     case e_compiled of
         Left  se  -> return $ Left $ CompilationError (NonRec id core_expr) [stringToPpr $ show se]
@@ -223,9 +240,9 @@
           -- arg = Lit $ MachInt $ fromIntegral i
           arg = intLiteral i
 #if MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
-          wild= mkWildValBinder Many t 
+          wild= mkWildValBinder Many t
 #else
-          wild= mkWildValBinder t 
+          wild= mkWildValBinder t
 #endif
 
 -- | For gsizeOf and galignment - calculate the variables.
@@ -239,10 +256,10 @@
     hsc_env     <- getHscEnv
     -- Try the subtitution.
     the_integer <- tryCompileExpr id expr :: CoreM (Either Error Int)
-    let m_t      = getGStorableType (varType id) 
+    let m_t      = getGStorableType (varType id)
     case m_t of
         Just t ->  return $ NonRec id <$> (Lam l1 <$> (Lam l2 <$> (intToExpr t <$> the_integer)))
-        Nothing -> 
+        Nothing ->
             return the_integer >> return $ Left $ CompilationError b [text "Type not found"]
 -- Without GSTORABLE_SUMPTYPES
 intSubstitution b@(NonRec id (Lam l1 expr)) = do
@@ -250,15 +267,15 @@
     hsc_env     <- getHscEnv
     -- Try the subtitution.
     the_integer <- tryCompileExpr id expr :: CoreM (Either Error Int)
-    let m_t      = getGStorableType (varType id) 
+    let m_t      = getGStorableType (varType id)
     case m_t of
         Just t ->  return $ NonRec id <$> (intToExpr t <$> the_integer)
-        Nothing -> 
+        Nothing ->
             return the_integer >> return $ Left $ CompilationError b [text "Type not found"]
 -- For GHC <= 8.6.5
 intSubstitution b@(NonRec id e@(App expr g)) = case expr of
      Lam _ (Lam _ (Lam _ e)) -> intSubstitution $ NonRec id expr
-     App e t                 -> do 
+     App e t                 -> do
         subs <- intSubstitution $ NonRec id e
         case subs of
             Right (NonRec i (Lam l1 (Lam l2 e)) ) -> return (Right $ NonRec i e)
@@ -274,11 +291,11 @@
     -- Try the subtitution.
     the_integer <- tryCompileExpr id expr :: CoreM (Either Error Int)
     -- Get the type.
-    let m_t      = getGStorableType (varType id) 
+    let m_t      = getGStorableType (varType id)
     case m_t of
         Just t ->  return $ NonRec id <$> (intToExpr t <$> the_integer)
         -- If the compilation error occured, first return it.
-        Nothing -> 
+        Nothing ->
             return the_integer >> return $ Left $ CompilationError (NonRec id expr) [text "Type not found"]
 -----------------------
 -- peek substitution --
@@ -291,10 +308,10 @@
     e_subs <- offsetSubstitutionTree [] expr
     let ne_subs = case e_subs of
              -- Add the text from other error.
-             Left (OtherError sdoc) 
+             Left (OtherError sdoc)
                  -> Left $ CompilationError b [sdoc]
              -- Add the information about uncompiled expr.
-             Left err@(CompilationError _ _) 
+             Left err@(CompilationError _ _)
                  -> Left $ CompilationError b [pprError Some err]
              a   -> a
 
@@ -312,8 +329,8 @@
 
 -- | Get 'CoreExpr' from 'OffsetScope'
 getScopeExpr :: OffsetScope -> CoreExpr
-getScopeExpr (IntList      _ expr) = expr 
-getScopeExpr (IntPrimVal   _ expr) = expr 
+getScopeExpr (IntList      _ expr) = expr
+getScopeExpr (IntPrimVal   _ expr) = expr
 
 instance Outputable OffsetScope where
     ppr (IntList    id expr) = ppr id <+> ppr (getUnique id) <+> comma <+> ppr expr
@@ -325,13 +342,13 @@
 
 -- | Create a list expression from Haskell list.
 intListExpr :: [Int] -> CoreExpr
-intListExpr list = intListExpr' (reverse list) empty_list 
+intListExpr list = intListExpr' (reverse list) empty_list
     where empty_list = App ( Var $ dataConWorkId nilDataCon) (Type intTy)
 
 intListExpr' :: [Int] -> CoreExpr -> CoreExpr
 intListExpr'  []    acc = acc
 intListExpr' (l:ls) acc = intListExpr' ls $ App int_cons acc
-    where int_t_cons = App (Var $ dataConWorkId consDataCon) (Type intTy) 
+    where int_t_cons = App (Var $ dataConWorkId consDataCon) (Type intTy)
           int_val    = App (Var $ dataConWorkId intDataCon ) (intLiteral l)
           int_cons   = App int_t_cons int_val
 
@@ -363,10 +380,10 @@
     = Just e
 isLitOrGlobal _ = Nothing
 
--- | Check whether the given CoreExpr is an id, 
+-- | Check whether the given CoreExpr is an id,
 -- and if yes - substitute it.
 inScopeAll :: [OffsetScope] -> CoreExpr -> Maybe CoreExpr
-inScopeAll (el:rest) e@(Var v_id) 
+inScopeAll (el:rest) e@(Var v_id)
     | id <- getScopeId el
     -- Thought uniques will be unique inside.
     , id == v_id
@@ -378,7 +395,7 @@
 
 
 -- | Is an "$w!!" identifier
-isIndexer :: Id   
+isIndexer :: Id
           -> Bool
 isIndexer id = getOccName (varName id) == mkOccName N.varName "$w!!"
 
@@ -386,7 +403,7 @@
 -- For !! @Int offsets val expressions.
 caseExprIndex :: [OffsetScope] -> CoreExpr -> Maybe CoreExpr
 caseExprIndex scope expr
-    -- A long list of what needs to be inside the expression. 
+    -- A long list of what needs to be inside the expression.
     | App beg lit <- expr
     -- Substitute or leave the literal be. Otherwise cancel.
     , Just lit_expr <- inScopeAll scope lit <|> isLitOrGlobal lit
@@ -401,37 +418,37 @@
     , isIntType intt
     , isIndexer ix_id
     -- New expression.
-    = Just $ App (App (App ix_var t_int) list_expr) lit_expr 
+    = Just $ App (App (App ix_var t_int) list_expr) lit_expr
     | otherwise = Nothing
 
 
 {- Note [Offset substitution]
  - ~~~~~~~~~~~~~~~~~~~~~~~~~~
  -
- - We would like for gpeekByteOff and gpokeByteOff methods to work as fast as 
+ - We would like for gpeekByteOff and gpokeByteOff methods to work as fast as
  - handwritten versions. This depends on whether the field's offsets are known
- - at compile time or not. 
+ - at compile time or not.
  -
  - To have offsets at compile time we have look for certain expressions to pop up.
  - We need to compile them, and later translate them back to Core expressions.
  - This approach relies on compiler optimisations of GStorable internals,
- - like inlining gpeekByteOff' methods and not inlining the calcOffsets functions. 
+ - like inlining gpeekByteOff' methods and not inlining the calcOffsets functions.
  - If these optimisations do not happen, a compilation error might occur.
- - If not, the resulting method might be not as fast as handwritten one. 
+ - If not, the resulting method might be not as fast as handwritten one.
  -
  -
  - We expect to deal with the following expressions:
  -
- - 
+ -
  - 1) let offsets = ... :: [Int] in expr
  -
  - Here we compile the offsets and put them for later use in expr.
  -
  -
  - 2) case $w!! @Int offsets 0# of _ I# x -> alt_expr
- - or case $w!! @Int ...     0# of _ I# x -> alt_expr   
- - 
- - Here we substitute the offsets if we can, and then we compile the 
+ - or case $w!! @Int ...     0# of _ I# x -> alt_expr
+ -
+ - Here we substitute the offsets if we can, and then we compile the
  - evaluated expression to later replace 'x' occurences in alt_expr.
  -
  -
@@ -471,14 +488,14 @@
     | Let    offset_bind in_expr     <- expr
     , NonRec offset_id   offset_expr <- offset_bind
     , isOffsetsId offset_id
-    = do 
+    = do
       e_new_s <- exprToIntList offset_id offset_expr
       case e_new_s of
           Left err       -> return $ Left err
           Right int_list -> offsetSubstitutionTree (int_list:scope) in_expr
-    -- Normal let bindings 
+    -- Normal let bindings
     | Let bind in_expr <- expr
-    = do 
+    = do
       subs <- offsetSubstitutionTree scope in_expr
       -- Substitution for the bindings
       let sub_idexpr (id,e) = do
@@ -486,7 +503,7 @@
               return $ (,) id <$> inner_subs
           sub_bind (NonRec id e) = do
               inner_subs <- offsetSubstitutionTree scope e
-              return $ NonRec id <$> inner_subs 
+              return $ NonRec id <$> inner_subs
           sub_bind (Rec bs) = do
               inner_subs <- mapM sub_idexpr bs
               case lefts inner_subs of
@@ -506,13 +523,13 @@
 #endif
     , i_prim_con == intDataCon
     , Just new_case_expr <- caseExprIndex scope case_expr
-    = do 
-      e_new_s <- exprToIntVal x_id new_case_expr 
+    = do
+      e_new_s <- exprToIntVal x_id new_case_expr
       case e_new_s of
           Left err       -> return $ Left err
-          Right int_val  -> offsetSubstitutionTree (int_val:scope) alt_expr 
-      
-    -- Normal case expressions. 
+          Right int_val  -> offsetSubstitutionTree (int_val:scope) alt_expr
+
+    -- Normal case expressions.
     | Case case_expr cb t alts <- expr
     = do
 #if MIN_VERSION_GLASGOW_HASKELL(9,2,0,0)
@@ -533,7 +550,7 @@
         -- Find the first error in alternative compilation
         let c_err = find (\(_,_,e) -> isLeft e) e_new_alts
         case c_err of
-            Nothing -> return $ Case <$> new_case_expr 
+            Nothing -> return $ Case <$> new_case_expr
                 <*> pure cb <*> pure t <*> pure [mkAlt a b ne | (a,b,Right ne)  <- e_new_alts]
             Just (_,_,err) -> return err
     -- Variable. Return it or try to replace it.
@@ -554,7 +571,7 @@
 
 
 -- | Compile the expression in Core Bind and replace it.
-compileGStorableBind :: CoreBind -> CoreM (Either Error CoreBind) 
+compileGStorableBind :: CoreBind -> CoreM (Either Error CoreBind)
 compileGStorableBind core_bind
     -- Substitute gsizeOf
     | (NonRec id expr) <- core_bind
@@ -586,15 +603,20 @@
     = NonRec (setIdInfo id $ setUnfoldingInfo id_info unfolding{uf_tmpl = expr} ) expr
     | otherwise
     = b
-    
 
+
 -- | Lint a binding
 lintBind :: CoreBind -- ^ Core binding to use when returning CompilationError
          -> CoreBind -- ^ Core binding to check
          -> CoreM (Either Error CoreBind) -- ^ Success or failure
 lintBind b_old b@(NonRec id expr) = do
     dyn_flags <- getDynFlags
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+    let lintConfig = initLintConfig dyn_flags []
+    case lintExpr lintConfig expr of
+#else
     case lintExpr dyn_flags [] expr of
+#endif
         Just sdoc -> do
 #if MIN_VERSION_GLASGOW_HASKELL(9,2,0,0)
             let err = bagToList sdoc
@@ -606,7 +628,12 @@
             return $ Right b
 lintBind b_old b@(Rec bs) = do
     dyn_flags <- getDynFlags
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+    let lintConfig = initLintConfig dyn_flags []
+    let errs = mapMaybe (\(_,expr) -> lintExpr lintConfig expr) bs
+#else
     let errs = mapMaybe (\(_,expr) -> lintExpr dyn_flags [] expr) bs
+#endif
 #if MIN_VERSION_GLASGOW_HASKELL(9,2,0,0)
     let convert = foldMap bagToList
 #else
@@ -639,11 +666,11 @@
     = replaceIds gstorable_bs other_bs expr
     -- For recs. The substituted component has to be removed.
     | isLocalId id
-    , ([id_here],rest) <- partition (\x -> id `elem` (map fst x)) $ [bs | Rec bs <- gstorable_bs] 
+    , ([id_here],rest) <- partition (\x -> id `elem` (map fst x)) $ [bs | Rec bs <- gstorable_bs]
     , Just (_,expr) <- find ((id==).fst) id_here
     = replaceIds (map Rec rest) other_bs expr
     | isLocalId id
-    , ([id_here],rest) <- partition (\x -> id `elem` (map fst x)) $ [bs | Rec bs <- other_bs] 
+    , ([id_here],rest) <- partition (\x -> id `elem` (map fst x)) $ [bs | Rec bs <- other_bs]
     , Just (_,expr) <- find ((id==).fst) id_here
     = replaceIds gstorable_bs (map Rec rest) expr
     -- If is a global id, or id was not found (local inside the expression) - leave it alone.
@@ -681,7 +708,7 @@
 -- | The insides of compileGroups method.
 compileGroups_rec :: Flags         -- ^ For error handling.
                   -> Int           -- ^ Depth, useful for debugging.
-                  -> [[CoreBind]]  -- ^ Ordered GStorable bindings. 
+                  -> [[CoreBind]]  -- ^ Ordered GStorable bindings.
                   -> [CoreBind]    -- ^ Other top-level bindings
                   -> [CoreBind]    -- ^ Succesfull substitutions.
                   -> [CoreBind]    -- ^ Unsuccesfull substitutions.
@@ -695,13 +722,13 @@
             -- Monad transformers would be nice here.
             case e_compiled of
                 Right bind' -> lintBind bind (replaceUnfoldingBind bind')
-                _           -> return e_compiled 
+                _           -> return e_compiled
     -- Compiled (or not) expressions
     e_compiled <- mapM compile_and_lint layer_replaced
     let errors = lefts e_compiled
-        compiled  = rights e_compiled 
-    
-    -- Handle errors    
+        compiled  = rights e_compiled
+
+    -- Handle errors
     not_compiled <- compileGroups_error flags d errors
     -- Next iteration.
     compileGroups_rec flags (d+1) bgs bind_rest (concat [compiled,subs]) (concat [not_compiled, not_subs])
@@ -720,13 +747,13 @@
        -- Print header for this type of errors
        print_header txt = case verb of
            None  -> empty
-           other ->    text "Errors while compiling and substituting bindings at depth " <+> int d <> text ":" 
-                    $$ nest 4 txt 
+           other ->    text "Errors while compiling and substituting bindings at depth " <+> int d <> text ":"
+                    $$ nest 4 txt
        -- Print errors themselves
        printer errs = case errs of
            [] -> return ()
            -- Print with header
-           ls ->  putMsg $ print_header (vcat (map (pprError verb) errs)) 
+           ls ->  putMsg $ print_header (vcat (map (pprError verb) errs))
        -- Get the bindings from errors.
        ungroup err = case err of
            (CompilationNotSupported bind)   -> Just bind
diff --git a/src/Foreign/Storable/Generic/Plugin/Internal/GroupTypes.hs b/src/Foreign/Storable/Generic/Plugin/Internal/GroupTypes.hs
--- a/src/Foreign/Storable/Generic/Plugin/Internal/GroupTypes.hs
+++ b/src/Foreign/Storable/Generic/Plugin/Internal/GroupTypes.hs
@@ -9,7 +9,7 @@
 Grouping methods, both for types and core bindings.
 -}
 {-# LANGUAGE CPP #-}
-module Foreign.Storable.Generic.Plugin.Internal.GroupTypes 
+module Foreign.Storable.Generic.Plugin.Internal.GroupTypes
     (
     -- Type ordering
       calcGroupOrder
@@ -38,12 +38,17 @@
 #else
 import GHC.Driver.Types (HscEnv,ModGuts(..))
 #endif
-import GHC.Core.Opt.Monad (CoreM,CoreToDo(..))
+import GHC.Core.Opt.Monad (CoreM)
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+import GHC.Core.Opt.Pipeline.Types (CoreToDo(..))
+#else
+import GHC.Core.Opt.Monad (CoreToDo(..))
+#endif
 import GHC.Types.Basic (CompilerPhase(..))
 import GHC.Core.Type hiding (eqType)
 import GHC.Core.TyCon
 import GHC.Builtin.Types   (intDataCon)
-import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys) 
+import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys)
 import GHC.Core.Make       (mkWildValBinder)
 import GHC.Utils.Outputable (cat, ppr, SDoc, showSDocUnsafe)
 import GHC.Utils.Outputable (text, (<+>), ($$), nest)
@@ -63,9 +68,9 @@
 import CoreMonad (CoreM,CoreToDo(..), getHscEnv)
 import BasicTypes (CompilerPhase(..))
 import Type hiding (eqType)
-import TyCon 
+import TyCon
 import TysWiredIn (intDataCon)
-import DataCon    (dataConWorkId,dataConOrigArgTys) 
+import DataCon    (dataConWorkId,dataConOrigArgTys)
 import MkCore (mkWildValBinder)
 import Outputable (cat, ppr, SDoc, showSDocUnsafe)
 import Outputable (text, (<+>), ($$), nest)
@@ -78,8 +83,12 @@
 import GHCi.RemoteTypes
 
 
-#if MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
 import GHC.Types.Var (TyVarBinder(..), VarBndr(..))
+import GHC.Core.TyCo.Rep (Type(..), scaledThing)
+import GHC.Types.Var
+#elif MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
+import GHC.Types.Var (TyVarBinder(..), VarBndr(..))
 import GHC.Core.TyCo.Rep (Type(..), TyBinder(..), TyCoBinder(..),scaledThing)
 import GHC.Types.Var
 #elif MIN_VERSION_GLASGOW_HASKELL(8,8,1,0)
@@ -105,8 +114,13 @@
 import Foreign.Storable.Generic.Plugin.Internal.Predicates
 import Foreign.Storable.Generic.Plugin.Internal.Types
 
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+-- See 778c6adca2c995cd8a1b84394d4d5ca26b915dac
+type TyBinder = PiTyBinder
+type TyCoVarBinder = ForAllTyBinder
+#endif
 
--- | Calculate the order of types. 
+-- | Calculate the order of types.
 calcGroupOrder :: [Type] -> ([[Type]], Maybe Error)
 calcGroupOrder types = calcGroupOrder_rec types []
 
@@ -121,9 +135,9 @@
         then (reverse acc, Just $ OrderingFailedTypes (length acc) rest)
         else calcGroupOrder_rec rest (layer':acc)
 
--- | This could be done more efficently if we'd 
+-- | This could be done more efficently if we'd
 -- represent the problem as a graph problem.
-calcGroupOrder_iteration :: [Type] -- ^ Type to check 
+calcGroupOrder_iteration :: [Type] -- ^ Type to check
                          -> [Type] -- ^ Type that are checked
                          -> [Type] -- ^ Type that are in this layer
                          -> [Type] -- ^ Type that are not.
@@ -138,19 +152,19 @@
         then calcGroupOrder_iteration ts (t:checked)  accepted    (t:rejected)
         else calcGroupOrder_iteration ts (t:checked) (t:accepted)  rejected
 
--- | Used for type substitution. 
+-- | Used for type substitution.
 -- Whether a TyVar appears, replace it with a Type.
 type TypeScope = (TyVar, Type)
 
 -- | Functions doing the type substitutions.
 
 -- Examples
--- 
+--
 -- substituteTyCon [(a,Int)]           a          = Int
 -- substituteTyCon [(a,Int),(b,Char)] (AType b a) = AType Char Int
 substituteTyCon :: [TypeScope] -> Type -> Type
 substituteTyCon []         tc_app             = tc_app
-substituteTyCon type_scope old@(TyVarTy  ty_var) 
+substituteTyCon type_scope old@(TyVarTy  ty_var)
 -- Substitute simple type variables
     = case find (\(av,_) -> av == ty_var) type_scope of
           Just (_, new_type) -> new_type
@@ -158,11 +172,11 @@
 substituteTyCon type_scope (TyConApp tc args)
 -- Substitute type constructors
     = TyConApp tc $ map (substituteTyCon type_scope) args
-substituteTyCon type_scope t = t 
+substituteTyCon type_scope t = t
 
 -- | Get data constructor arguments from an algebraic type.
 getDataConArgs :: Type -> [Type]
-getDataConArgs t 
+getDataConArgs t
     | isAlgType t
     , Just (tc, ty_args) <- splitTyConApp_maybe t
     , ty_vars <- tyConTyVars tc
@@ -172,9 +186,9 @@
     let type_scope = zip ty_vars ty_args
         data_cons  = concatMap dataConOrigArgTys $ (visibleDataCons.algTyConRhs) tc
 #if MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
-    map (substituteTyCon type_scope) (map scaledThing data_cons)  
+    map (substituteTyCon type_scope) (map scaledThing data_cons)
 #else
-    map (substituteTyCon type_scope) data_cons  
+    map (substituteTyCon type_scope) data_cons
 #endif
     | otherwise = []
 
@@ -182,10 +196,10 @@
 
 -- | Group bindings according to type groups.
 groupBinds :: [[Type]]   -- ^ Type groups.
-           -> [CoreBind] -- ^ Should be only NonRecs. 
+           -> [CoreBind] -- ^ Should be only NonRecs.
            -> ([[CoreBind]], Maybe Error)
 -- perhaps add some safety so non-recs won't get here.
-groupBinds type_groups binds = groupBinds_rec type_groups binds [] 
+groupBinds type_groups binds = groupBinds_rec type_groups binds []
 
 -- | Iteration for groupBinds
 groupBinds_rec :: [[Type]]      -- ^ Group of types
@@ -194,8 +208,8 @@
                -> ([[CoreBind]], Maybe Error) -- ^ Grouped bindings, and perhaps an error)
 groupBinds_rec []       []    acc = (reverse acc,Nothing)
 groupBinds_rec (a:as)   []    acc = (reverse acc,Just $ OtherError msg)
-    where msg =    text "Could not find any bindings." 
-                $$ text "Is the second pass placed after main simplifier phases ?" 
+    where msg =    text "Could not find any bindings."
+                $$ text "Is the second pass placed after main simplifier phases ?"
 groupBinds_rec []       binds acc = (reverse acc,Just $ OrderingFailedBinds (length acc) binds)
 groupBinds_rec (tg:tgs) binds acc = do
     let predicate (NonRec id _) = case getGStorableType $ varType id of
@@ -203,6 +217,6 @@
             Nothing -> False
         predicate (Rec _) = False
     let (layer, rest) = partition predicate binds
-    if length layer == 0 
+    if length layer == 0
         then (reverse acc, Just $ OrderingFailedBinds (length acc) rest)
         else groupBinds_rec tgs rest (reverse layer:acc)
diff --git a/src/Foreign/Storable/Generic/Plugin/Internal/Helpers.hs b/src/Foreign/Storable/Generic/Plugin/Internal/Helpers.hs
--- a/src/Foreign/Storable/Generic/Plugin/Internal/Helpers.hs
+++ b/src/Foreign/Storable/Generic/Plugin/Internal/Helpers.hs
@@ -29,12 +29,17 @@
 #else
 import GHC.Driver.Types (HscEnv,ModGuts(..))
 #endif
-import GHC.Core.Opt.Monad (CoreM,CoreToDo(..))
+import GHC.Core.Opt.Monad (CoreM)
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+import GHC.Core.Opt.Pipeline.Types (CoreToDo(..))
+#else
+import GHC.Core.Opt.Monad (CoreToDo(..))
+#endif
 import GHC.Types.Basic (CompilerPhase(..))
 import GHC.Core.Type (isAlgType, splitTyConApp_maybe)
 import GHC.Core.TyCon (algTyConRhs, visibleDataCons)
 import GHC.Builtin.Types   (intDataCon)
-import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys) 
+import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys)
 import GHC.Core.Make       (mkWildValBinder)
 import GHC.Utils.Outputable (cat, ppr, SDoc, showSDocUnsafe)
 import GHC.Core.Opt.Monad (putMsg, putMsgS)
@@ -55,7 +60,7 @@
 import Type (isAlgType, splitTyConApp_maybe)
 import TyCon (algTyConRhs, visibleDataCons)
 import TysWiredIn (intDataCon)
-import DataCon    (dataConWorkId,dataConOrigArgTys) 
+import DataCon    (dataConWorkId,dataConOrigArgTys)
 import MkCore (mkWildValBinder)
 import Outputable (cat, ppr, SDoc, showSDocUnsafe)
 import CoreMonad (putMsg, putMsgS)
@@ -66,9 +71,12 @@
 -- Used to get to compiled values
 import GHCi.RemoteTypes
 
-
-#if MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
 import GHC.Types.Var (TyVarBinder(..), VarBndr(..))
+import GHC.Core.TyCo.Rep (Type(..), scaledThing)
+import GHC.Types.Var
+#elif MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
+import GHC.Types.Var (TyVarBinder(..), VarBndr(..))
 import GHC.Core.TyCo.Rep (Type(..), TyBinder(..), TyCoBinder(..),scaledThing)
 import GHC.Types.Var
 #elif MIN_VERSION_GLASGOW_HASKELL(8,8,1,0)
@@ -90,6 +98,11 @@
 import Data.Either
 import Control.Monad.IO.Class
 
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+-- See 778c6adca2c995cd8a1b84394d4d5ca26b915dac
+type TyBinder = PiTyBinder
+type TyCoVarBinder = ForAllTyBinder
+#endif
 
 
 -- | Get ids from core bind.
@@ -160,7 +173,9 @@
 #else
 eqTyBind (Named t1 vis1) (Named t2 vis2) = t1 == t2 && vis1 == vis2
 #endif
-#if MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+eqTyBind (Anon t1 _) (Anon t2 _) = scaledThing t1 `eqType` scaledThing t2
+#elif MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
 eqTyBind (Anon _ t1) (Anon _ t2) = scaledThing t1 `eqType` scaledThing t2
 #elif MIN_VERSION_GLASGOW_HASKELL(8,10,0,0)
 eqTyBind (Anon _ t1) (Anon _ t2) = t1 `eqType` t2
@@ -171,11 +186,11 @@
 
 #if MIN_VERSION_GLASGOW_HASKELL(8,8,1,0)
 eqTyVarBind :: TyVarBinder -> TyVarBinder -> Bool
-eqTyVarBind (Bndr t1 arg1) (Bndr t2 arg2) = t1 == t2 
+eqTyVarBind (Bndr t1 arg1) (Bndr t2 arg2) = t1 == t2
 #elif MIN_VERSION_GLASGOW_HASKELL(8,2,1,0)
 -- | Equality for type variable binders
 eqTyVarBind :: TyVarBinder -> TyVarBinder -> Bool
-eqTyVarBind (TvBndr t1 arg1) (TvBndr t2 arg2) = t1 == t2 
+eqTyVarBind (TvBndr t1 arg1) (TvBndr t2 arg2) = t1 == t2
 #endif
 
 -- | 'elem' function for types
@@ -185,7 +200,7 @@
 
 #if MIN_VERSION_GLASGOW_HASKELL(8,8,1,0)
 isProxy :: TyCoVarBinder -> Bool
-isProxy (Bndr tycovar flag) 
+isProxy (Bndr tycovar flag)
 #elif MIN_VERSION_GLASGOW_HASKELL(8,2,1,0)
 isProxy :: TyVarBinder -> Bool
 isProxy (TvBndr tycovar flag)
@@ -201,7 +216,7 @@
     , FunTy _ bool star <- varType tycovar
 #elif MIN_VERSION_GLASGOW_HASKELL(8,2,1,0)
     , FunTy bool star <- varType tycovar
-#else 
+#else
     , ForAllTy bool   star <- varType tycovar
 #endif
     = True
@@ -218,7 +233,7 @@
     , FunTy _  ch   t2 <- t1
 #elif MIN_VERSION_GLASGOW_HASKELL(8,2,1,0)
     , FunTy    ch   t2 <- t1
-#else 
+#else
     , ForAllTy ch'   t2 <- t
     , Anon     ch       <- ch'
 #endif
@@ -235,7 +250,7 @@
     , FunTy _  ch   t2 <- t1
 #elif MIN_VERSION_GLASGOW_HASKELL(8,2,1,0)
     , FunTy    ch   t2 <- t1
-#else 
+#else
     , ForAllTy ch'   t2 <- t
     , Anon     ch       <- ch'
 #endif
@@ -252,7 +267,7 @@
     , FunTy _  ch   t2 <- t1
 #elif MIN_VERSION_GLASGOW_HASKELL(8,2,1,0)
     , FunTy    ch   t2 <- t1
-#else 
+#else
     , ForAllTy ch'  t2 <- t
     , Anon     ch      <- ch'
 #endif
diff --git a/src/Foreign/Storable/Generic/Plugin/Internal/Predicates.hs b/src/Foreign/Storable/Generic/Plugin/Internal/Predicates.hs
--- a/src/Foreign/Storable/Generic/Plugin/Internal/Predicates.hs
+++ b/src/Foreign/Storable/Generic/Plugin/Internal/Predicates.hs
@@ -10,7 +10,7 @@
 
 -}
 {-#LANGUAGE CPP#-}
-module Foreign.Storable.Generic.Plugin.Internal.Predicates 
+module Foreign.Storable.Generic.Plugin.Internal.Predicates
     (
     -- Predicates on identifiers
       isGStorableInstId
@@ -53,13 +53,13 @@
 -- import HscTypes (HscEnv,ModGuts(..))
 -- import CoreMonad (CoreM, CoreToDo(..), getHscEnv)
 -- import BasicTypes (CompilerPhase(..))
--- -- Types 
+-- -- Types
 -- import Type (isAlgType, splitTyConApp_maybe)
 -- import TyCon (TyCon,tyConName, algTyConRhs, visibleDataCons)
 -- import TyCoRep (Type(..), TyBinder(..))
 -- import TysWiredIn (intDataCon)
--- import DataCon    (dataConWorkId,dataConOrigArgTys) 
--- 
+-- import DataCon    (dataConWorkId,dataConOrigArgTys)
+--
 -- import MkCore (mkWildValBinder)
 -- -- Printing
 -- import Outputable (cat, ppr, SDoc, showSDocUnsafe)
@@ -82,12 +82,17 @@
 #else
 import GHC.Driver.Types (HscEnv,ModGuts(..))
 #endif
-import GHC.Core.Opt.Monad (CoreM,CoreToDo(..))
+import GHC.Core.Opt.Monad (CoreM)
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+import GHC.Core.Opt.Pipeline.Types (CoreToDo(..))
+#else
+import GHC.Core.Opt.Monad (CoreToDo(..))
+#endif
 import GHC.Types.Basic (CompilerPhase(..))
 import GHC.Core.Type (isAlgType, splitTyConApp_maybe)
 import GHC.Core.TyCon (algTyConRhs, visibleDataCons)
 import GHC.Builtin.Types   (intDataCon)
-import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys) 
+import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys)
 import GHC.Core.Make       (mkWildValBinder)
 import GHC.Utils.Outputable (cat, ppr, SDoc, showSDocUnsafe)
 import GHC.Core.Opt.Monad (putMsg, putMsgS)
@@ -109,17 +114,21 @@
 import Type (isAlgType, splitTyConApp_maybe)
 import TyCon (algTyConRhs, visibleDataCons)
 import TysWiredIn (intDataCon)
-import DataCon    (dataConWorkId,dataConOrigArgTys) 
+import DataCon    (dataConWorkId,dataConOrigArgTys)
 import MkCore (mkWildValBinder)
 import Outputable (cat, ppr, SDoc, showSDocUnsafe)
 import CoreMonad (putMsg, putMsgS)
 import Name (nameStableString)
 #endif
 
-#if MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
 import GHC.Types.Var (TyVarBinder(..), VarBndr(..))
-import GHC.Core.TyCo.Rep (Type(..), TyBinder(..), TyCoBinder(..),scaledThing)
+import GHC.Core.TyCo.Rep (Type(..), scaledThing)
 import GHC.Types.Var
+#elif MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
+import GHC.Types.Var (TyVarBinder(..), VarBndr(..))
+import GHC.Core.TyCo.Rep (Type(..), scaledThing)
+import GHC.Types.Var
 #elif MIN_VERSION_GLASGOW_HASKELL(8,8,1,0)
 import Var (TyVarBinder(..), VarBndr(..))
 import TyCoRep (Type(..), TyBinder(..), TyCoBinder(..))
@@ -130,14 +139,19 @@
 import Var
 #endif
 
-import Data.Maybe 
+import Data.Maybe
 
 import Foreign.Storable.Generic.Plugin.Internal.Helpers
 
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+-- See 778c6adca2c995cd8a1b84394d4d5ca26b915dac
+type TyBinder = PiTyBinder
+type TyCoVarBinder = ForAllTyBinder
+#endif
 
 -- | Predicate used to find GStorable instances identifiers.
 isGStorableInstId :: Id -> Bool
-isGStorableInstId id =    cutted_occ_name == gstorable_dict_name 
+isGStorableInstId id =    cutted_occ_name == gstorable_dict_name
                        && cutted_occ_name2 /= gstorable'_dict_name
     where cutted_occ_name = cutOccName 11 $ getOccName (varName id)
           cutted_occ_name2 = cutOccName 12 $ getOccName (varName id)
@@ -146,11 +160,11 @@
 
 -- | Predicate used to find gsizeOf identifiers
 isSizeOfId :: Id -> Bool
-isSizeOfId ident = getOccName (varName ident)    == mkOccName N.varName "$cgsizeOf" 
+isSizeOfId ident = getOccName (varName ident)    == mkOccName N.varName "$cgsizeOf"
 
 -- | Predicate used to find galignment identifiers
 isAlignmentId :: Id -> Bool
-isAlignmentId ident = getOccName (varName ident) == mkOccName N.varName "$cgalignment" 
+isAlignmentId ident = getOccName (varName ident) == mkOccName N.varName "$cgalignment"
 
 -- | Predicate used to find gpeekByteOff identifiers
 isPeekId :: Id -> Bool
@@ -174,7 +188,7 @@
     where occStr    = nameStableString $ varName id
           compared1 = "$_in$$s$fGStorableChoice'Falsea_$cchSizeOf"
           compared2 = "$_in$$s$fGStorableChoice'Truea_$cchSizeOf"
-          
+
 -- | Predicate used to find chAlignment identifiers
 isChoiceAlignmentId :: Id -> Bool
 isChoiceAlignmentId id = occStr == compared1 || occStr == compared2
@@ -212,19 +226,19 @@
 
 -- | Predicate used to find specialized gsizeOf identifiers
 isSpecSizeOfId :: Id -> Bool
-isSpecSizeOfId ident = getOccName (varName ident)    == mkOccName N.varName "$s$cgsizeOf" 
+isSpecSizeOfId ident = getOccName (varName ident)    == mkOccName N.varName "$s$cgsizeOf"
 
 -- | Predicate used to find specialized galignment identifiers
 isSpecAlignmentId :: Id -> Bool
-isSpecAlignmentId ident = getOccName (varName ident) == mkOccName N.varName "$s$cgalignment" 
+isSpecAlignmentId ident = getOccName (varName ident) == mkOccName N.varName "$s$cgalignment"
 
 -- | Predicate used to find specialized gpeekByteOff identifiers
 isSpecPeekId :: Id -> Bool
-isSpecPeekId ident = getOccName (varName ident) == mkOccName N.varName "$s$cgpeekByteOff" 
+isSpecPeekId ident = getOccName (varName ident) == mkOccName N.varName "$s$cgpeekByteOff"
 
 -- | Predicate used to find specialized gpokeByteOff identifiers
 isSpecPokeId :: Id -> Bool
-isSpecPokeId ident = getOccName (varName ident) == mkOccName N.varName "$s$cgpokeByteOff" 
+isSpecPokeId ident = getOccName (varName ident) == mkOccName N.varName "$s$cgpokeByteOff"
 
 
 ----------------------------
@@ -252,7 +266,7 @@
 #endif
                              ]
 -- | Is the id an GStorable method.
-isGStorableMethodId :: Id -> Bool 
+isGStorableMethodId :: Id -> Bool
 isGStorableMethodId id = any ($ id) [isSizeOfId, isAlignmentId
                                    , isPeekId, isPokeId
                                    , isSpecSizeOfId, isSpecAlignmentId
@@ -262,7 +276,7 @@
                                    , isChoicePeekId, isChoicePokeId
 #endif
                                    ]
-------------------                                   
+------------------
 -- Miscellanous --
 ------------------
 
diff --git a/src/Foreign/Storable/Generic/Plugin/Internal/Types.hs b/src/Foreign/Storable/Generic/Plugin/Internal/Types.hs
--- a/src/Foreign/Storable/Generic/Plugin/Internal/Types.hs
+++ b/src/Foreign/Storable/Generic/Plugin/Internal/Types.hs
@@ -57,12 +57,17 @@
 #else
 import GHC.Driver.Types (HscEnv,ModGuts(..))
 #endif
-import GHC.Core.Opt.Monad (CoreM,CoreToDo(..))
+import GHC.Core.Opt.Monad (CoreM)
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+import GHC.Core.Opt.Pipeline.Types (CoreToDo(..))
+#else
+import GHC.Core.Opt.Monad (CoreToDo(..))
+#endif
 import GHC.Types.Basic (CompilerPhase(..))
 import GHC.Core.Type (isAlgType, splitTyConApp_maybe)
 import GHC.Core.TyCon (TyCon(..),algTyConRhs, visibleDataCons)
 import GHC.Builtin.Types   (intDataCon)
-import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys) 
+import GHC.Core.DataCon    (dataConWorkId,dataConOrigArgTys)
 import GHC.Core.Make       (mkWildValBinder)
 import GHC.Utils.Outputable (cat, ppr, SDoc, showSDocUnsafe)
 import GHC.Core.Opt.Monad (putMsg, putMsgS)
@@ -83,7 +88,7 @@
 import Type (isAlgType, splitTyConApp_maybe)
 import TyCon (TyCon(..),algTyConRhs, visibleDataCons)
 import TysWiredIn (intDataCon)
-import DataCon    (dataConWorkId,dataConOrigArgTys) 
+import DataCon    (dataConWorkId,dataConOrigArgTys)
 import MkCore (mkWildValBinder)
 import Outputable (cat, ppr, SDoc, showSDocUnsafe)
 import CoreMonad (putMsg, putMsgS)
@@ -118,8 +123,12 @@
 #endif
 
 
-#if MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
 import GHC.Types.Var (TyVarBinder(..), VarBndr(..))
+import GHC.Core.TyCo.Rep (Type(..), scaledThing)
+import GHC.Types.Var
+#elif MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
+import GHC.Types.Var (TyVarBinder(..), VarBndr(..))
 import GHC.Core.TyCo.Rep (Type(..), TyBinder(..), TyCoBinder(..),scaledThing)
 import GHC.Types.Var
 #elif MIN_VERSION_GLASGOW_HASKELL(8,8,1,0)
@@ -132,6 +141,13 @@
 import Var
 #endif
 
+#if MIN_VERSION_GLASGOW_HASKELL(9,6,0,0)
+-- See 778c6adca2c995cd8a1b84394d4d5ca26b915dac
+type TyBinder = PiTyBinder
+type TyCoVarBinder = ForAllTyBinder
+#endif
+
+
 -- | Check whether the type is integer
 isIntType :: Type -> Bool
 isIntType (TyConApp int []) = int == intTyCon
@@ -177,11 +193,11 @@
 
 -- | Check whether the type constuctor is a GStorable
 isGStorableInstTyCon :: TyCon -> Bool
-isGStorableInstTyCon tc = getOccName (tyConName tc) == mkOccName N.tcClsName "GStorable" 
+isGStorableInstTyCon tc = getOccName (tyConName tc) == mkOccName N.tcClsName "GStorable"
 
 -- | Check whether the type is of kind * -> Constraint.
 hasConstraintKind :: Type -> Bool
-hasConstraintKind ty 
+hasConstraintKind ty
     | TyConApp tc   [a]     <- ty
     , ForAllTy star kind_ty <- tyConKind tc
     , TyConApp k_tc []      <- kind_ty
@@ -211,7 +227,7 @@
 getGStorableInstType :: Type -> Maybe Type
 getGStorableInstType t
     | hasConstraintKind t
-    , TyConApp gstorable [the_t] <- t 
+    , TyConApp gstorable [the_t] <- t
     = Just the_t
     -- Ignore forall a. a, GStorable a =>, etc..
     | ForAllTy _ some_t <- t  = getGStorableInstType some_t
@@ -283,11 +299,11 @@
 
 -- | Insides of getPeekType, which takes into the account
 -- the order of arguments.
-getPeekType' :: Type 
+getPeekType' :: Type
              -> Bool -- ^ Is after Ptr
              -> Bool -- ^ Is after Int
              -> Maybe Type -- ^ Returning
-getPeekType' t after_ptr after_int 
+getPeekType' t after_ptr after_int
     -- Last step: IO (TheType)
     | after_ptr, after_int
     , TyConApp io_tc [the_t] <- t
@@ -310,13 +326,13 @@
     -- Ptr b -> Int -> IO (TheType)
 #if   MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
     | ForAllTy ty_bind fun_t <- t
-    , FunTy _ _ ptr_t rest <- fun_t 
+    , FunTy _ _ ptr_t rest <- fun_t
 #elif MIN_VERSION_GLASGOW_HASKELL(8,10,0,0)
     | ForAllTy ty_bind fun_t <- t
-    , FunTy _ ptr_t rest <- fun_t 
+    , FunTy _ ptr_t rest <- fun_t
 #elif MIN_VERSION_GLASGOW_HASKELL(8,2,1,0)
     | ForAllTy ty_bind fun_t <- t
-    , FunTy ptr_t rest <- fun_t 
+    , FunTy ptr_t rest <- fun_t
 #else
     | ForAllTy ty_bind rest <- t
     , Anon ptr_t <- ty_bind
@@ -324,7 +340,7 @@
     , isPtrType ptr_t
     = getPeekType' rest True False
     -- Ignore other types
-    -- including constraints and 
+    -- including constraints and
     -- Named ty binders.
     | ForAllTy _ some_t <- t
     = getPeekType' some_t after_ptr after_int
@@ -332,17 +348,17 @@
 
 
 
---isUnboxedTuple2 is State# h 
+--isUnboxedTuple2 is State# h
 
 -- | Get the type from GStorable poke method
 getPokeType :: Type -> Maybe Type
 getPokeType t = getPokeType' t False False
 
-getPokeType' :: Type 
+getPokeType' :: Type
              -> Bool -- ^ Is after Ptr
              -> Bool -- ^ Is after Int
              -> Maybe Type -- ^ Returning
-getPokeType' t after_ptr after_int 
+getPokeType' t after_ptr after_int
     -- Last step: TheType -> IO ()
     | after_ptr, after_int
 #if MIN_VERSION_GLASGOW_HASKELL(9,0,1,0)
@@ -387,11 +403,11 @@
 #else
     | ForAllTy ty_bind rest <- t
     , Anon ptr_t <- ty_bind
-#endif 
+#endif
     , isPtrType ptr_t
     = getPokeType' rest True False
     -- Ignore other types
-    -- including constraints and 
+    -- including constraints and
     -- Named ty binders.
     | ForAllTy _ some_t <- t
     = getPokeType' some_t after_ptr after_int
