diff --git a/compiler/GHC/Builtin/Types/Prim.hs b/compiler/GHC/Builtin/Types/Prim.hs
--- a/compiler/GHC/Builtin/Types/Prim.hs
+++ b/compiler/GHC/Builtin/Types/Prim.hs
@@ -13,7 +13,8 @@
 module GHC.Builtin.Types.Prim(
         mkPrimTyConName, -- For implicit parameters in GHC.Builtin.Types only
 
-        mkTemplateKindVars, mkTemplateTyVars, mkTemplateTyVarsFrom,
+        mkTemplateKindVar, mkTemplateKindVars,
+        mkTemplateTyVars, mkTemplateTyVarsFrom,
         mkTemplateKiTyVars, mkTemplateKiTyVar,
 
         mkTemplateTyConBinders, mkTemplateKindTyConBinders,
diff --git a/compiler/GHC/Core/Make.hs b/compiler/GHC/Core/Make.hs
--- a/compiler/GHC/Core/Make.hs
+++ b/compiler/GHC/Core/Make.hs
@@ -13,6 +13,7 @@
         sortQuantVars, castBottomExpr,
 
         -- * Constructing boxed literals
+        mkLitRubbish,
         mkWordExpr,
         mkIntExpr, mkIntExprInt, mkUncheckedIntExpr,
         mkIntegerExpr, mkNaturalExpr,
@@ -246,6 +247,23 @@
   | otherwise            = Case e (mkWildValBinder One e_ty) res_ty []
   where
     e_ty = exprType e
+
+mkLitRubbish :: Type -> Maybe CoreExpr
+-- Make a rubbish-literal CoreExpr of the given type.
+-- Fail (returning Nothing) if
+--    * the RuntimeRep of the Type is not monomorphic;
+--    * the type is (a ~# b), the type of coercion
+-- See INVARIANT 1 and 2 of item (2) in Note [Rubbish literals]
+-- in GHC.Types.Literal
+mkLitRubbish ty
+  | not (noFreeVarsOfType rep)
+  = Nothing   -- Satisfy INVARIANT 1
+  | isCoVarType ty
+  = Nothing   -- Satisfy INVARIANT 2
+  | otherwise
+  = Just (Lit (LitRubbish rep) `mkTyApps` [ty])
+  where
+    rep  = getRuntimeRep ty
 
 {-
 ************************************************************************
diff --git a/compiler/GHC/Core/TyCon.hs b/compiler/GHC/Core/TyCon.hs
--- a/compiler/GHC/Core/TyCon.hs
+++ b/compiler/GHC/Core/TyCon.hs
@@ -1403,7 +1403,7 @@
 ************************************************************************
 
 Note [rep swamp]
-
+~~~~~~~~~~~~~~~~
 GHC has a rich selection of types that represent "primitive types" of
 one kind or another.  Each of them makes a different set of
 distinctions, and mostly the differences are for good reasons,
diff --git a/compiler/GHC/CoreToIface.hs b/compiler/GHC/CoreToIface.hs
--- a/compiler/GHC/CoreToIface.hs
+++ b/compiler/GHC/CoreToIface.hs
@@ -52,6 +52,7 @@
 import GHC.Iface.Syntax
 import GHC.Core.DataCon
 import GHC.Types.Id
+import GHC.Types.Literal
 import GHC.Types.Id.Info
 import GHC.StgToCmm.Types
 import GHC.Core
@@ -541,6 +542,7 @@
 
 toIfaceExpr :: CoreExpr -> IfaceExpr
 toIfaceExpr (Var v)         = toIfaceVar v
+toIfaceExpr (Lit (LitRubbish r)) = IfaceLitRubbish (toIfaceType r)
 toIfaceExpr (Lit l)         = IfaceLit l
 toIfaceExpr (Type ty)       = IfaceType (toIfaceType ty)
 toIfaceExpr (Coercion co)   = IfaceCo   (toIfaceCoercion co)
@@ -583,7 +585,9 @@
 ---------------------
 toIfaceCon :: AltCon -> IfaceConAlt
 toIfaceCon (DataAlt dc) = IfaceDataAlt (getName dc)
-toIfaceCon (LitAlt l)   = IfaceLitAlt l
+toIfaceCon (LitAlt l)   = ASSERT2( (not (isLitRubbish l)) , ppr l )
+                          -- assert: see Note [Rubbish literals] wrinkle (b)
+                          (IfaceLitAlt l)
 toIfaceCon DEFAULT      = IfaceDefault
 
 ---------------------
diff --git a/compiler/GHC/Iface/Syntax.hs b/compiler/GHC/Iface/Syntax.hs
--- a/compiler/GHC/Iface/Syntax.hs
+++ b/compiler/GHC/Iface/Syntax.hs
@@ -558,6 +558,8 @@
   | IfaceLet    IfaceBinding  IfaceExpr
   | IfaceCast   IfaceExpr IfaceCoercion
   | IfaceLit    Literal
+  | IfaceLitRubbish IfaceType -- See GHC.Types.Literal
+                              --   Note [Rubbish literals] item (6)
   | IfaceFCall  ForeignCall IfaceType
   | IfaceTick   IfaceTickish IfaceExpr    -- from Tick tickish E
 
@@ -1363,6 +1365,7 @@
 pprIfaceExpr _       (IfaceLcl v)       = ppr v
 pprIfaceExpr _       (IfaceExt v)       = ppr v
 pprIfaceExpr _       (IfaceLit l)       = ppr l
+pprIfaceExpr _       (IfaceLitRubbish r) = text "RUBBISH" <> parens (ppr r)
 pprIfaceExpr _       (IfaceFCall cc ty) = braces (ppr cc <+> ppr ty)
 pprIfaceExpr _       (IfaceType ty)     = char '@' <> pprParendIfaceType ty
 pprIfaceExpr _       (IfaceCo co)       = text "@~" <> pprParendIfaceCoercion co
@@ -2347,6 +2350,9 @@
         putByte bh 13
         put_ bh a
         put_ bh b
+    put_ bh (IfaceLitRubbish r) = do
+        putByte bh 14
+        put_ bh r
     get bh = do
         h <- getByte bh
         case h of
@@ -2389,6 +2395,8 @@
             13 -> do a <- get bh
                      b <- get bh
                      return (IfaceECase a b)
+            14 -> do r <- get bh
+                     return (IfaceLitRubbish r)
             _ -> panic ("get IfaceExpr " ++ show h)
 
 instance Binary IfaceTickish where
@@ -2613,6 +2621,7 @@
     IfaceLet bind e -> rnf bind `seq` rnf e
     IfaceCast e co -> rnf e `seq` rnf co
     IfaceLit l -> l `seq` () -- FIXME
+    IfaceLitRubbish r -> rnf r `seq` ()
     IfaceFCall fc ty -> fc `seq` rnf ty
     IfaceTick tick e -> rnf tick `seq` rnf e
 
diff --git a/compiler/GHC/Types/Literal.hs b/compiler/GHC/Types/Literal.hs
--- a/compiler/GHC/Types/Literal.hs
+++ b/compiler/GHC/Types/Literal.hs
@@ -33,7 +33,6 @@
         , mkLitChar, mkLitString
         , mkLitInteger, mkLitNatural
         , mkLitNumber, mkLitNumberWrap
-        , mkLitRubbish
 
         -- ** Operations on Literals
         , literalType
@@ -53,7 +52,7 @@
         , isZeroLit, isOneLit
         , litFitsInChar
         , litValue, mapLitValue
-        , isLitValue_maybe
+        , isLitValue_maybe, isLitRubbish
 
         -- ** Coercions
         , narrowInt8Lit, narrowInt16Lit, narrowInt32Lit, narrowInt64Lit
@@ -71,7 +70,6 @@
 import GHC.Builtin.Types.Prim
 import {-# SOURCE #-} GHC.Builtin.Types
 import GHC.Core.Type
-import GHC.Core.TyCon
 import GHC.Utils.Outputable
 import GHC.Data.FastString
 import GHC.Types.Basic
@@ -135,13 +133,15 @@
                                 -- that can be represented as a Literal. Create
                                 -- with 'nullAddrLit'
 
-  | LitRubbish [PrimRep]        -- ^ A nonsense value of the given
-                                -- representation. See Note [Rubbish values].
+  | LitRubbish Type             -- ^ A nonsense value of the given
+                                -- representation. See Note [Rubbish literals].
                                 --
-                                -- The @[PrimRep]@ of a 'Type' can be obtained
-                                -- from 'typeMonoPrimRep_maybe'. The field
-                                -- becomes empty or singleton post-unarisation,
-                                -- see Note [Post-unarisation invariants].
+                                -- The Type argument, rr, is of kind RuntimeRep.
+                                -- The type of the literal is forall (a:TYPE rr). a
+                                --
+                                -- INVARIANT: the Type has no free variables
+                                --    and so substitution etc can ignore it
+                                --
 
   | LitFloat   Rational         -- ^ @Float#@. Create with 'mkLitFloat'
   | LitDouble  Rational         -- ^ @Double#@. Create with 'mkLitDouble'
@@ -219,7 +219,6 @@
 {-
 Note [BigNum literals]
 ~~~~~~~~~~~~~~~~~~~~~~
-
 GHC supports 2 kinds of arbitrary precision integers (a.k.a BigNum):
 
    * Natural: natural represented as a Word# or as a BigNat
@@ -233,7 +232,6 @@
 
 Note [String literals]
 ~~~~~~~~~~~~~~~~~~~~~~
-
 String literals are UTF-8 encoded and stored into ByteStrings in the following
 ASTs: Haskell, Core, Stg, Cmm. TH can also emit ByteString based string literals
 with the BytesPrimL constructor (see #14741).
@@ -262,7 +260,9 @@
         = do putByte bh 6
              put_ bh nt
              put_ bh i
-    put_ bh (LitRubbish b) = do putByte bh 7; put_ bh b
+    put_ _ (LitRubbish b) = pprPanic "Binary LitRubbish" (ppr b)
+     -- We use IfaceLitRubbish; see Note [Rubbish literals], item (6)
+
     get bh = do
             h <- getByte bh
             case h of
@@ -288,9 +288,6 @@
                     nt <- get bh
                     i  <- get bh
                     return (LitNumber nt i)
-              7 -> do
-                    b <- get bh
-                    return (LitRubbish b)
               _ -> pprPanic "Binary:Literal" (int (fromIntegral h))
 
 instance Outputable Literal where
@@ -572,11 +569,9 @@
 mkLitNatural x = ASSERT2( inNaturalRange x,  integer x )
                     (LitNumber LitNumNatural x)
 
--- | Create a rubbish literal of the given representation.
--- The representation of a 'Type' can be obtained via 'typeMonoPrimRep_maybe'.
--- See Note [Rubbish values].
-mkLitRubbish :: [PrimRep] -> Literal
-mkLitRubbish = LitRubbish
+isLitRubbish :: Literal -> Bool
+isLitRubbish (LitRubbish {}) = True
+isLitRubbish _               = False
 
 inNaturalRange :: Integer -> Bool
 inNaturalRange x = x >= 0
@@ -844,10 +839,12 @@
    LitNumWord16  -> word16PrimTy
    LitNumWord32  -> word32PrimTy
    LitNumWord64  -> word64PrimTy
-literalType (LitRubbish preps) = mkForAllTy a Inferred (mkTyVarTy a)
+
+-- LitRubbish: see Note [Rubbish literals]
+literalType (LitRubbish rep)
+  = mkForAllTy a Inferred (mkTyVarTy a)
   where
-    -- See Note [Rubbish values]
-    a = head $ mkTemplateTyVars [tYPE (primRepsToRuntimeRep preps)]
+    a = mkTemplateKindVar (tYPE rep)
 
 {-
         Comparison
@@ -863,7 +860,7 @@
 cmpLit (LitLabel     a _ _) (LitLabel      b _ _) = a `lexicalCompareFS` b
 cmpLit (LitNumber nt1 a)    (LitNumber nt2  b)
   = (nt1 `compare` nt2) `mappend` (a `compare` b)
-cmpLit (LitRubbish b1)      (LitRubbish b2)       = b1 `compare` b2
+cmpLit (LitRubbish b1)      (LitRubbish b2)       = b1 `nonDetCmpType` b2
 cmpLit lit1 lit2
   | isTrue# (dataToTag# lit1 <# dataToTag# lit2) = LT
   | otherwise                                    = GT
@@ -899,8 +896,8 @@
     where b = case mb of
               Nothing -> pprHsString l
               Just x  -> doubleQuotes (text (unpackFS l ++ '@':show x))
-pprLiteral _       (LitRubbish reps)
-  = text "RUBBISH" <> ppr reps
+pprLiteral _       (LitRubbish rep)
+  = text "RUBBISH" <> parens (ppr rep)
 
 pprIntegerVal :: (SDoc -> SDoc) -> Integer -> SDoc
 -- See Note [Printing of literals in Core].
@@ -944,75 +941,159 @@
 LitLabel        "__label" ...      ("__label" ...)
 LitRubbish      "RUBBISH[...]"
 
-Note [Rubbish values]
-~~~~~~~~~~~~~~~~~~~~~
+Note [Rubbish literals]
+~~~~~~~~~~~~~~~~~~~~~~~
 Sometimes, we need to cough up a rubbish value of a certain type that is used
 in place of dead code we thus aim to eliminate. The value of a dead occurrence
 has no effect on the dynamic semantics of the program, so we can pick any value
 of the same representation.
+
 Exploiting the results of absence analysis in worker/wrapper is a scenario where
-we need such a rubbish value, see Note [Absent fillers] for examples.
+we need such a rubbish value, see examples in Note [Absent fillers] in
+GHC.Core.Opt.WorkWrap.Utils.
 
 It's completely undefined what the *value* of a rubbish value is, e.g., we could
 pick @0#@ for @Int#@ or @42#@; it mustn't matter where it's inserted into a Core
 program. We embed these rubbish values in the 'LitRubbish' case of the 'Literal'
 data type. Here are the moving parts:
 
-  1. Source Haskell: No way to produce rubbish lits in source syntax. Purely
-     an IR feature.
+1. Source Haskell: No way to produce rubbish lits in source syntax. Purely
+   an IR feature.
 
-  2. Core: 'LitRubbish' carries a @[PrimRep]@ which represents the monomorphic
-     'RuntimeRep' of the type it is substituting for.
-     We have it that @RUBBISH[IntRep]@ has type @forall (a :: TYPE IntRep). a@,
-     and the type application @RUBBISH[IntRep] \@Int# :: Int#@ represents
-     a rubbish value of type @Int#@. Rubbish lits are completely opaque in Core.
-     In general, @RUBBISH[preps] :: forall (a :: TYPE rep). a@, where @rep@
-     is the 'RuntimeRep' corresponding to @preps :: [PrimRep]@
-     (via 'primRepsToRuntimeRep'). See 'literalType'.
-     Why not encode a 'RuntimeRep' via a @Type@? Thus
-     > data Literal = ... | LitRubbish Type | ...
-     Because
-       * We have to provide an Eq and Ord instance and @Type@ has none
-       * The encoded @Type@ might be polymorphic and we can only emit code for
-         monomorphic 'RuntimeRep's anyway.
+2. Core: 'LitRubbish' carries a `Type` of kind RuntimeRep,
+   describing the runtime representaion of the literal (is it a
+   pointer, an unboxed Double#, or whatever).
 
-  3. STG: The type app in @RUBBISH[IntRep] \@Int# :: Int#@ is erased and we get
-     the (untyped) 'StgLit' @RUBBISH[IntRep] :: Int#@ in STG.
-     It's treated mostly opaque, with the exception of the Unariser, where we
-     take apart a case scrutinisation on, or arg occurrence of, e.g.,
-     @RUBBISH[IntRep,DoubleRep]@ (which may stand in for @(# Int#, Double# #)@)
-     into its sub-parts @RUBBISH[IntRep]@ and @RUBBISH[DoubleRep]@, similar to
-     unboxed tuples. @RUBBISH[VoidRep]@ is erased.
-     See 'unariseRubbish_maybe' and also Note [Post-unarisation invariants].
+   We have it that `RUBBISH[rr]` has type `forall (a :: TYPE rr). a`.
+   See the `LitRubbish` case of `literalType`.
 
-  4. Cmm: We translate 'LitRubbish' to their actual rubbish value in 'cgLit'.
-     The particulars are boring, and only matter when debugging illicit use of
-     a rubbish value; see Modes of failure below.
+   The function GHC.Core.Make.mkLitRubbish makes a Core rubbish literal of
+   a given type.  It obeys the following invariants:
 
-  5. Bytecode: In GHC.ByteCode.Asm we just lower it as a 0 literal, because it's
-     all boxed to the host GC anyway.
+   INVARIANT 1: 'rr' has no free variables. Main reason: we don't need to run
+   substitutions and free variable finders over Literal. The rules around
+   levity/runtime-rep polymorphism naturally uphold this invariant.
 
-Why not lower LitRubbish in CoreToStg? Because it enables us to use RubbishLit
-when unarising unboxed sums in the future, and it allows rubbish values of e.g.
-VecRep, for which we can't cough up dummy values in STG.
+   INVARIANT 2: we never make a rubbish literal of type (a ~# b). Reason:
+   see Note [Core type and coercion invariant] in GHC.Core.  We can't substitute
+   a LitRubbish inside a coercion, so it's best not to make one. They are zero
+   width anyway, so passing absent ones around costs nothing.  If we wanted
+   an absent filler of type (a ~# b) we should use (Coercion (UnivCo ...)),
+   but it doesn't seem worth making a new UnivCoProvenance for this purpose.
 
+   This is sad, though: see #18983.
+
+3. STG: The type app in `RUBBISH[IntRep] @Int# :: Int#` is erased and we get
+   the (untyped) 'StgLit' `RUBBISH[IntRep] :: Int#` in STG.
+
+   It's treated mostly opaque, with the exception of the Unariser, where we
+   take apart a case scrutinisation on, or arg occurrence of, e.g.,
+   `RUBBISH[TupleRep[IntRep,DoubleRep]]` (which may stand in for `(# Int#, Double# #)`)
+   into its sub-parts `RUBBISH[IntRep]` and `RUBBISH[DoubleRep]`, similar to
+   unboxed tuples. `RUBBISH[VoidRep]` is erased.
+   See 'unariseRubbish_maybe' and also Note [Post-unarisation invariants].
+
+4. Cmm: We translate 'LitRubbish' to their actual rubbish value in 'cgLit'.
+   The particulars are boring, and only matter when debugging illicit use of
+   a rubbish value; see Modes of failure below.
+
+5. Bytecode: In GHC.ByteCode.Asm we just lower it as a 0 literal, because it's
+   all boxed to the host GC anyway.
+
+6. IfaceSyn: `Literal` is part of `IfaceSyn`, but `Type` really isn't.  So in
+   the passage from Core to Iface I put LitRubbish into its owns IfaceExpr data
+   constructor, IfaceLitRubbish. The remaining constructors of Literal are
+   fine as IfaceSyn.
+
+Wrinkles
+
+a) Why do we put the `Type` (of kind RuntimeRep) inside the literal?  Could
+   we not instead /apply/ the literal to that RuntimeRep?  Alas no, becuase
+   then LitRubbish :: forall (rr::RuntimeRep) (a::TYPE rr). a
+   and that's am ill-formed type because its kind is `TYPE rr`, which escapes
+   the binding site of `rr`. Annoying.
+
+b) A rubbish literal is not bottom, and replies True to exprOkForSpeculation.
+   For unboxed types there is no bottom anyway.  If we have
+       let (x::Int#) = RUBBISH[IntRep] @Int#
+   we want to convert that to a case!  We want to leave it as a let, and
+   probably discard it as dead code soon after because x is unused.
+
+c) We can see a rubbish literal at the head of an application chain.
+   Most obviously, pretty much every rubbish literal is the head of a
+   type application e.g. `RUBBISH[IntRep] @Int#`.  But see also
+   Note [How a rubbish literal can be the head of an application]
+
+c) Literal is in Ord, because (and only because) we use Ord on AltCon when
+   building a TypeMap. Annoying.  We use `nonDetCmpType` here; the
+   non-determinism won't matter because it's only used in TrieMap.
+   Moreover, rubbish literals should not appear in patterns anyway.
+
+d) Why not lower LitRubbish in CoreToStg? Because it enables us to use
+   RubbishLit when unarising unboxed sums in the future, and it allows
+   rubbish values of e.g.  VecRep, for which we can't cough up dummy
+   values in STG.
+
 Modes of failure
 ----------------
 Suppose there is a bug in GHC, and a rubbish value is used after all. That is
 undefined behavior, of course, but let us list a few examples for failure modes:
 
- a) For an value of unboxed numeric type like @Int#@, we just use a silly
+ a) For an value of unboxed numeric type like `Int#`, we just use a silly
     value like 42#. The error might propoagate indefinitely, hence we better
     pick a rather unique literal. Same for Word, Floats, Char and VecRep.
  b) For AddrRep (like String lits), we mit a null pointer, resulting in a
     definitive segfault when accessed.
  c) For boxed values, unlifted or not, we use a pointer to a fixed closure,
-    like @()@, so that the GC has a pointer to follow.
+    like `()`, so that the GC has a pointer to follow.
     If we use that pointer as an 'Array#', we will likely access fields of the
     array that don't exist, and a seg-fault is likely, but not guaranteed.
-    If we use that pointer as @Either Int Bool@, we might try to access the
+    If we use that pointer as `Either Int Bool`, we might try to access the
     'Int' field of the 'Left' constructor (which has the same ConTag as '()'),
     which doesn't exists. In the best case, we'll find an invalid pointer in its
     position and get a seg-fault, in the worst case the error manifests only one
     or two indirections later.
- -}
+
+Note [How a rubbish literal can be the head of an application]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider this (#19824):
+
+    h :: T3 -> Int -> blah
+    h _ (I# n) = ...
+
+    f :: (T1 -> T2 -> T3) -> T4 -> blah
+    f g x = ....(h (g n s) x)...
+
+Demand analysis finds that h does not use its first argument, and w/w's h to
+
+    {-# INLINE h #-}
+    h a b = case b of I# n -> $wh n
+
+Demand analysis also finds that f does not use its first arg,
+so the worker for f look like
+
+    $wf x = let g = RUBBISH in
+            ....(h (g n s) x)...
+
+Now we inline g to get:
+
+    $wf x = ....(h (RUBBISH n s) x)...
+
+And lo, until we inline `h`, we have that application of
+RUBBISH in $wf's RHS.  But surely `h` will inline? Not if the
+arguments look boring.  Well, RUBBISH doesn't look boring.  But it
+could be a bit more complicated like
+   f g x = let t = ...(g n s)...
+           in ...(h t x)...
+
+and now the call looks more boring.  Anyway, the point is that we
+might reasonably see RUBBISH at the head of an application chain.
+
+It would be fine to rewrite
+  RUBBISH @(ta->tb->tr) a b  --->   RUBBISH @tr
+but we don't currently do so.
+
+It is NOT ok to discard the entire continuation:
+  case RUBBISH @ty of DEFAULT -> blah
+does not return RUBBISH!
+-}
diff --git a/compiler/GHC/Types/RepType.hs b/compiler/GHC/Types/RepType.hs
--- a/compiler/GHC/Types/RepType.hs
+++ b/compiler/GHC/Types/RepType.hs
@@ -338,7 +338,7 @@
 enumerates all the possibilities.
 
 data PrimRep
-  = VoidRep
+  = VoidRep       -- See Note [VoidRep]
   | LiftedRep     -- ^ Lifted pointer
   | UnliftedRep   -- ^ Unlifted pointer
   | Int8Rep       -- ^ Signed, 8-bit value
@@ -549,6 +549,7 @@
 
 -- | Take a type of kind RuntimeRep and extract the list of 'PrimRep' that
 -- it encodes. See also Note [Getting from RuntimeRep to PrimRep]
+-- The [PrimRep] is the final runtime representation /after/ unarisation
 runtimeRepPrimRep :: HasDebugCallStack => SDoc -> Type -> [PrimRep]
 runtimeRepPrimRep doc rr_ty
   | Just rr_ty' <- coreView rr_ty
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: 2.0
 build-type: Simple
 name: ghc-lib-parser
-version: 9.2.6.20230211
+version: 9.2.7.20230228
 license: BSD3
 license-file: LICENSE
 category: Development
@@ -37,9 +37,9 @@
     ghc-lib/stage0/compiler/build/primop-vector-uniques.hs-incl
     ghc-lib/stage0/compiler/build/primop-docs.hs-incl
     ghc-lib/stage0/compiler/build/GHC/Platform/Constants.hs
+    ghc-lib/stage0/compiler/build/GHC/Settings/Config.hs
     ghc-lib/stage0/libraries/ghc-boot/build/GHC/Version.hs
     ghc-lib/stage0/libraries/ghc-boot/build/GHC/Platform/Host.hs
-    ghc-lib/stage0/compiler/build/GHC/Settings/Config.hs
     compiler/GHC/Parser.y
     compiler/GHC/Parser/Lexer.x
     includes/MachDeps.h
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   = "5383016c78fe4b2555e0aae9248bea5b42f67a78"
+cProjectGitCommitId   = "b81cd709df8054b8b98ac05d3b9affcee9a8b840"
 
 cProjectVersion       :: String
-cProjectVersion       = "9.2.6"
+cProjectVersion       = "9.2.7"
 
 cProjectVersionInt    :: String
 cProjectVersionInt    = "902"
 
 cProjectPatchLevel    :: String
-cProjectPatchLevel    = "6"
+cProjectPatchLevel    = "7"
 
 cProjectPatchLevel1   :: String
-cProjectPatchLevel1   = "6"
+cProjectPatchLevel1   = "7"
 
 cProjectPatchLevel2   :: String
 cProjectPatchLevel2   = ""
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
@@ -462,7 +462,7 @@
 #define MIN_VERSION_ghc_heap(major1,major2,minor) (\
   (major1) <  9 || \
   (major1) == 9 && (major2) <  2 || \
-  (major1) == 9 && (major2) == 2 && (minor) <= 6)
+  (major1) == 9 && (major2) == 2 && (minor) <= 7)
 #endif /* MIN_VERSION_ghc_heap */
 #if MIN_VERSION_ghc_heap(8,11,0)
 instance Binary Heap.StgTSOProfInfo
