diff --git a/compiler/GHC/Core/Utils.hs b/compiler/GHC/Core/Utils.hs
--- a/compiler/GHC/Core/Utils.hs
+++ b/compiler/GHC/Core/Utils.hs
@@ -23,9 +23,9 @@
         -- * Properties of expressions
         exprType, coreAltType, coreAltsType, mkLamType, mkLamTypes,
         mkFunctionType,
-        exprIsDupable, exprIsTrivial, getIdFromTrivialExpr,
-        getIdFromTrivialExpr_maybe,
-        exprIsCheap, exprIsExpandable, exprIsCheapX, CheapAppFun,
+        exprIsTrivial, getIdFromTrivialExpr, getIdFromTrivialExpr_maybe,
+        trivial_expr_fold,
+        exprIsDupable, exprIsCheap, exprIsExpandable, exprIsCheapX, CheapAppFun,
         exprIsHNF, exprOkForSpeculation, exprOkForSideEffects, exprOkForSpecEval,
         exprIsWorkFree, exprIsConLike,
         isCheapApp, isExpandableApp, isSaturatedConApp,
@@ -1047,20 +1047,37 @@
 it off at source.
 -}
 
+{-# INLINE trivial_expr_fold #-}
+trivial_expr_fold :: (Id -> r) -> (Literal -> r) -> r -> r -> CoreExpr -> r
+-- ^ The worker function for Note [exprIsTrivial] and Note [getIdFromTrivialExpr]
+-- This is meant to have the code of both functions in one place and make it
+-- easy to derive custom predicates.
+--
+-- (trivial_expr_fold k_id k_triv k_not_triv e)
+-- * returns (k_id x) if `e` is a variable `x` (with trivial wrapping)
+-- * returns (k_lit x) if `e` is a trivial literal `l` (with trivial wrapping)
+-- * returns k_triv if `e` is a literal, type, or coercion (with trivial wrapping)
+-- * returns k_not_triv otherwise
+--
+-- where "trivial wrapping" is
+-- * Type application or abstraction
+-- * Ticks other than `tickishIsCode`
+-- * `case e of {}` an empty case
+trivial_expr_fold k_id k_lit k_triv k_not_triv = go
+  where
+    go (Var v)                            = k_id v  -- See Note [Variables are trivial]
+    go (Lit l)    | litIsTrivial l        = k_lit l
+    go (Type _)                           = k_triv
+    go (Coercion _)                       = k_triv
+    go (App f t)  | not (isRuntimeArg t)  = go f
+    go (Lam b e)  | not (isRuntimeVar b)  = go e
+    go (Tick t e) | not (tickishIsCode t) = go e              -- See Note [Tick trivial]
+    go (Cast e _)                         = go e
+    go (Case e _ _ [])                    = go e              -- See Note [Empty case is trivial]
+    go _                                  = k_not_triv
+
 exprIsTrivial :: CoreExpr -> Bool
--- If you modify this function, you may also
--- need to modify getIdFromTrivialExpr
-exprIsTrivial (Var _)          = True        -- See Note [Variables are trivial]
-exprIsTrivial (Type _)         = True
-exprIsTrivial (Coercion _)     = True
-exprIsTrivial (Lit lit)        = litIsTrivial lit
-exprIsTrivial (App e arg)      = not (isRuntimeArg arg) && exprIsTrivial e
-exprIsTrivial (Lam b e)        = not (isRuntimeVar b) && exprIsTrivial e
-exprIsTrivial (Tick t e)       = not (tickishIsCode t) && exprIsTrivial e
-                                 -- See Note [Tick trivial]
-exprIsTrivial (Cast e _)       = exprIsTrivial e
-exprIsTrivial (Case e _ _ [])  = exprIsTrivial e  -- See Note [Empty case is trivial]
-exprIsTrivial _                = False
+exprIsTrivial e = trivial_expr_fold (const True) (const True) True False e
 
 {-
 Note [getIdFromTrivialExpr]
@@ -1080,24 +1097,13 @@
 -}
 
 getIdFromTrivialExpr :: HasDebugCallStack => CoreExpr -> Id
-getIdFromTrivialExpr e
-    = fromMaybe (pprPanic "getIdFromTrivialExpr" (ppr e))
-                (getIdFromTrivialExpr_maybe e)
-
-getIdFromTrivialExpr_maybe :: CoreExpr -> Maybe Id
 -- See Note [getIdFromTrivialExpr]
--- Th equations for this should line up with those for exprIsTrivial
-getIdFromTrivialExpr_maybe e
-  = go e
+getIdFromTrivialExpr e = trivial_expr_fold id (const panic) panic panic e
   where
-    go (App f t) | not (isRuntimeArg t)   = go f
-    go (Tick t e) | not (tickishIsCode t) = go e
-    go (Cast e _)                         = go e
-    go (Lam b e) | not (isRuntimeVar b)   = go e
-    go (Case e _ _ [])                    = go e
-    go (Var v) = Just v
-    go _       = Nothing
+    panic = pprPanic "getIdFromTrivialExpr" (ppr e)
 
+getIdFromTrivialExpr_maybe :: CoreExpr -> Maybe Id
+getIdFromTrivialExpr_maybe e = trivial_expr_fold Just (const Nothing) Nothing Nothing e
 
 {- *********************************************************************
 *                                                                      *
diff --git a/compiler/ghc.cabal b/compiler/ghc.cabal
--- a/compiler/ghc.cabal
+++ b/compiler/ghc.cabal
@@ -3,7 +3,7 @@
 -- ./configure.  Make sure you are editing ghc.cabal.in, not ghc.cabal.
 
 Name: ghc
-Version: 9.6.5
+Version: 9.6.6
 License: BSD-3-Clause
 License-File: LICENSE
 Author: The GHC Team
@@ -86,9 +86,9 @@
                    transformers >= 0.5 && < 0.7,
                    exceptions == 0.10.*,
                    stm,
-                   ghc-boot   == 9.6.5,
-                   ghc-heap   == 9.6.5,
-                   ghci == 9.6.5
+                   ghc-boot   == 9.6.6,
+                   ghc-heap   == 9.6.6,
+                   ghci == 9.6.6
 
     if os(windows)
         Build-Depends: Win32  >= 2.3 && < 2.14
diff --git a/ghc-lib-parser.cabal b/ghc-lib-parser.cabal
--- a/ghc-lib-parser.cabal
+++ b/ghc-lib-parser.cabal
@@ -1,7 +1,7 @@
 cabal-version: 3.0
 build-type: Simple
 name: ghc-lib-parser
-version: 9.6.5.20240423
+version: 9.6.6.20240701
 license: BSD-3-Clause
 license-file: LICENSE
 category: Development
@@ -67,13 +67,14 @@
   manual: True
   description: Pass -DTHREADED_RTS to the C toolchain
 library
-    default-language:   Haskell2010
+    default-language: Haskell2010
     exposed: False
     include-dirs:
         rts/include
         ghc-lib/stage0/lib
         ghc-lib/stage0/compiler/build
         compiler
+    ghc-options: -fno-safe-haskell
     if flag(threaded-rts)
         ghc-options: -fobject-code -package=ghc-boot-th -optc-DTHREADED_RTS
         cc-options: -DTHREADED_RTS
@@ -101,6 +102,8 @@
         pretty == 1.1.*,
         transformers >= 0.5 && < 0.7,
         process >= 1 && < 1.7
+    if impl(ghc >= 9.10)
+      build-depends: ghc-internal
     build-tool-depends: alex:alex >= 3.1, happy:happy > 1.20
     other-extensions:
         BangPatterns
diff --git a/ghc-lib/stage0/compiler/build/GHC/Settings/Config.hs b/ghc-lib/stage0/compiler/build/GHC/Settings/Config.hs
--- a/ghc-lib/stage0/compiler/build/GHC/Settings/Config.hs
+++ b/ghc-lib/stage0/compiler/build/GHC/Settings/Config.hs
@@ -21,7 +21,7 @@
 cProjectName          = "The Glorious Glasgow Haskell Compilation System"
 
 cBooterVersion        :: String
-cBooterVersion        = "9.6.2"
+cBooterVersion        = "9.6.5"
 
 cStage                :: String
 cStage                = show (1 :: Int)
diff --git a/ghc-lib/stage0/libraries/ghc-boot/build/GHC/Version.hs b/ghc-lib/stage0/libraries/ghc-boot/build/GHC/Version.hs
--- a/ghc-lib/stage0/libraries/ghc-boot/build/GHC/Version.hs
+++ b/ghc-lib/stage0/libraries/ghc-boot/build/GHC/Version.hs
@@ -3,19 +3,19 @@
 import Prelude -- See Note [Why do we import Prelude here?]
 
 cProjectGitCommitId   :: String
-cProjectGitCommitId   = "650c34ab4e1cefb521209b143ecd75367ec03ee1"
+cProjectGitCommitId   = "3a18c0fa2edcd61b0c3b470661791b09501c4c2b"
 
 cProjectVersion       :: String
-cProjectVersion       = "9.6.5"
+cProjectVersion       = "9.6.6"
 
 cProjectVersionInt    :: String
 cProjectVersionInt    = "906"
 
 cProjectPatchLevel    :: String
-cProjectPatchLevel    = "5"
+cProjectPatchLevel    = "6"
 
 cProjectPatchLevel1   :: String
-cProjectPatchLevel1   = "5"
+cProjectPatchLevel1   = "6"
 
 cProjectPatchLevel2   :: String
 cProjectPatchLevel2   = "0"
diff --git a/ghc/ghc-bin.cabal b/ghc/ghc-bin.cabal
--- a/ghc/ghc-bin.cabal
+++ b/ghc/ghc-bin.cabal
@@ -2,7 +2,7 @@
 -- ./configure.  Make sure you are editing ghc-bin.cabal.in, not ghc-bin.cabal.
 
 Name: ghc-bin
-Version: 9.6.5
+Version: 9.6.6
 Copyright: XXX
 -- License: XXX
 -- License-File: XXX
@@ -39,8 +39,8 @@
                    filepath   >= 1   && < 1.5,
                    containers >= 0.5 && < 0.7,
                    transformers >= 0.5 && < 0.7,
-                   ghc-boot      == 9.6.5,
-                   ghc           == 9.6.5
+                   ghc-boot      == 9.6.6,
+                   ghc           == 9.6.6
 
     if os(windows)
         Build-Depends: Win32  >= 2.3 && < 2.14
@@ -58,7 +58,7 @@
         Build-depends:
             deepseq        == 1.4.*,
             ghc-prim       >= 0.5.0 && < 0.11,
-            ghci           == 9.6.5,
+            ghci           == 9.6.6,
             haskeline      == 0.8.*,
             exceptions     == 0.10.*,
             time           >= 1.8 && < 1.13
diff --git a/libraries/ghc-boot-th/ghc-boot-th.cabal b/libraries/ghc-boot-th/ghc-boot-th.cabal
--- a/libraries/ghc-boot-th/ghc-boot-th.cabal
+++ b/libraries/ghc-boot-th/ghc-boot-th.cabal
@@ -3,7 +3,7 @@
 -- ghc-boot-th.cabal.in, not ghc-boot-th.cabal.
 
 name:           ghc-boot-th
-version:        9.6.5
+version:        9.6.6
 license:        BSD3
 license-file:   LICENSE
 category:       GHC
diff --git a/libraries/ghc-boot/ghc-boot.cabal b/libraries/ghc-boot/ghc-boot.cabal
--- a/libraries/ghc-boot/ghc-boot.cabal
+++ b/libraries/ghc-boot/ghc-boot.cabal
@@ -5,7 +5,7 @@
 -- ghc-boot.cabal.
 
 name:           ghc-boot
-version:        9.6.5
+version:        9.6.6
 license:        BSD-3-Clause
 license-file:   LICENSE
 category:       GHC
@@ -77,7 +77,7 @@
                    directory  >= 1.2 && < 1.4,
                    filepath   >= 1.3 && < 1.5,
                    deepseq    >= 1.4 && < 1.5,
-                   ghc-boot-th == 9.6.5
+                   ghc-boot-th == 9.6.6
     if !os(windows)
         build-depends:
                    unix       >= 2.7 && < 2.9
diff --git a/libraries/ghc-heap/ghc-heap.cabal b/libraries/ghc-heap/ghc-heap.cabal
--- a/libraries/ghc-heap/ghc-heap.cabal
+++ b/libraries/ghc-heap/ghc-heap.cabal
@@ -1,6 +1,6 @@
 cabal-version:  3.0
 name:           ghc-heap
-version:        9.6.5
+version:        9.6.6
 license:        BSD-3-Clause
 license-file:   LICENSE
 maintainer:     libraries@haskell.org
diff --git a/libraries/ghci/GHCi/Message.hs b/libraries/ghci/GHCi/Message.hs
--- a/libraries/ghci/GHCi/Message.hs
+++ b/libraries/ghci/GHCi/Message.hs
@@ -465,7 +465,7 @@
 #define MIN_VERSION_ghc_heap(major1,major2,minor) (\
   (major1) <  9 || \
   (major1) == 9 && (major2) <  6 || \
-  (major1) == 9 && (major2) == 6 && (minor) <= 5)
+  (major1) == 9 && (major2) == 6 && (minor) <= 6)
 #endif /* MIN_VERSION_ghc_heap */
 #if MIN_VERSION_ghc_heap(8,11,0)
 instance Binary Heap.StgTSOProfInfo
diff --git a/libraries/ghci/ghci.cabal b/libraries/ghci/ghci.cabal
--- a/libraries/ghci/ghci.cabal
+++ b/libraries/ghci/ghci.cabal
@@ -2,7 +2,7 @@
 -- ../../configure.  Make sure you are editing ghci.cabal.in, not ghci.cabal.
 
 name:           ghci
-version:        9.6.5
+version:        9.6.6
 license:        BSD3
 license-file:   LICENSE
 category:       GHC
@@ -77,8 +77,8 @@
         containers       >= 0.5 && < 0.7,
         deepseq          == 1.4.*,
         filepath         == 1.4.*,
-        ghc-boot         == 9.6.5,
-        ghc-heap         == 9.6.5,
+        ghc-boot         == 9.6.6,
+        ghc-heap         == 9.6.6,
         template-haskell == 2.20.*,
         transformers     >= 0.5 && < 0.7
 
diff --git a/libraries/template-haskell/template-haskell.cabal b/libraries/template-haskell/template-haskell.cabal
--- a/libraries/template-haskell/template-haskell.cabal
+++ b/libraries/template-haskell/template-haskell.cabal
@@ -56,7 +56,7 @@
 
     build-depends:
         base        >= 4.11 && < 4.19,
-        ghc-boot-th == 9.6.5,
+        ghc-boot-th == 9.6.6,
         ghc-prim,
         pretty      == 1.1.*
 
