diff --git a/Cabal.cabal b/Cabal.cabal
--- a/Cabal.cabal
+++ b/Cabal.cabal
@@ -1,6 +1,6 @@
 cabal-version: >=1.10
 name:          Cabal
-version:       3.6.0.0
+version:       3.6.1.0
 copyright:     2003-2021, Cabal Development Team (see AUTHORS file)
 license:       BSD3
 license-file:  LICENSE
diff --git a/src/Distribution/Simple.hs b/src/Distribution/Simple.hs
--- a/src/Distribution/Simple.hs
+++ b/src/Distribution/Simple.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE LambdaCase #-}
@@ -715,6 +716,11 @@
       pathEnv = maybe (intercalate spSep extraPath)
                 ((intercalate spSep extraPath ++ spSep)++) $ lookup "PATH" env
       overEnv = ("CFLAGS", Just cflagsEnv) :
+-- TODO: Move to either Cabal/src/Distribution/Compat/Environment.hs
+-- or Cabal/src/Distribution/Compat/FilePath.hs:
+#ifdef mingw32_HOST_OS
+                ("PATH_SEPARATOR", Just ";") :
+#endif
                 [("PATH", Just pathEnv) | not (null extraPath)]
       hp = hostPlatform lbi
       maybeHostFlag = if hp == buildPlatform then [] else ["--host=" ++ show (pretty hp)]
diff --git a/src/Distribution/Simple/Build/PathsModule.hs b/src/Distribution/Simple/Build/PathsModule.hs
--- a/src/Distribution/Simple/Build/PathsModule.hs
+++ b/src/Distribution/Simple/Build/PathsModule.hs
@@ -41,7 +41,6 @@
     , Z.zVersionDigits              = show $ versionNumbers $ packageVersion pkg_descr
     , Z.zSupportsCpp                = supports_cpp
     , Z.zSupportsNoRebindableSyntax = supports_rebindable_syntax
-    , Z.zSupportsNoMissingSafeHaskellMode = supports_missing_safehaskell
     , Z.zAbsolute                   = absolute
     , Z.zRelocatable                = relocatable lbi
     , Z.zIsWindows                  = isWindows
@@ -62,7 +61,6 @@
     supports_cpp                 = supports_language_pragma
     supports_rebindable_syntax   = ghc_newer_than (mkVersion [7,0,1])
     supports_language_pragma     = ghc_newer_than (mkVersion [6,6,1])
-    supports_missing_safehaskell = ghc_newer_than (mkVersion [8,10,1])
 
     ghc_newer_than minVersion =
         case compilerCompatVersion GHC (compiler lbi) of
diff --git a/src/Distribution/Simple/Build/PathsModule/Z.hs b/src/Distribution/Simple/Build/PathsModule/Z.hs
--- a/src/Distribution/Simple/Build/PathsModule/Z.hs
+++ b/src/Distribution/Simple/Build/PathsModule/Z.hs
@@ -6,7 +6,6 @@
          zVersionDigits :: String,
          zSupportsCpp :: Bool,
          zSupportsNoRebindableSyntax :: Bool,
-         zSupportsNoMissingSafeHaskellMode :: Bool,
          zAbsolute :: Bool,
          zRelocatable :: Bool,
          zIsWindows :: Bool,
@@ -43,12 +42,7 @@
   else do
     return ()
   tell "{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}\n"
-  if (zSupportsNoMissingSafeHaskellMode z_root)
-  then do
-    tell "{-# OPTIONS_GHC -Wno-missing-safe-haskell-mode #-}\n"
-    return ()
-  else do
-    return ()
+  tell "{-# OPTIONS_GHC -w #-}\n"
   tell "module Paths_"
   tell (zManglePkgName z_root (zPackageName z_root))
   tell " (\n"
diff --git a/src/Distribution/Simple/GHC.hs b/src/Distribution/Simple/GHC.hs
--- a/src/Distribution/Simple/GHC.hs
+++ b/src/Distribution/Simple/GHC.hs
@@ -240,10 +240,11 @@
                              | otherwise = [guessGhcVersioned dir suf,
                                             guessVersioned dir suf,
                                             guessNormal dir]
-           guesses = mkGuesses given_dir given_suf ++
-                            if real_path == given_path
-                                then []
-                                else mkGuesses real_dir real_suf
+           -- order matters here, see https://github.com/haskell/cabal/issues/7390
+           guesses = (if real_path == given_path
+                        then []
+                        else mkGuesses real_dir real_suf)
+                     ++ mkGuesses given_dir given_suf
        info verbosity $ "looking for tool " ++ toolname
          ++ " near compiler in " ++ given_dir
        debug verbosity $ "candidate locations: " ++ show guesses
diff --git a/src/Distribution/Simple/Hpc.hs b/src/Distribution/Simple/Hpc.hs
--- a/src/Distribution/Simple/Hpc.hs
+++ b/src/Distribution/Simple/Hpc.hs
@@ -68,7 +68,29 @@
        -> Way
        -> FilePath  -- ^ Component name
        -> FilePath  -- ^ Directory containing test suite's .mix files
-mixDir distPref way name = hpcDir distPref way </> "mix" </> name
+mixDir distPref way name = hpcDir distPrefBuild way </> "mix" </> name
+ where
+  -- This is a hack for HPC over test suites, needed to match the directory
+  -- where HPC saves and reads .mix files when the main library of the same
+  -- package is being processed, perhaps in a previous cabal run (#5213).
+  -- E.g., @distPref@ may be
+  -- @./dist-newstyle/build/x86_64-linux/ghc-9.0.1/cabal-gh5213-0.1/t/tests@
+  -- but the path where library mix files reside has two less components
+  -- at the end (@t/tests@) and this reduced path needs to be passed to
+  -- both @hpc@ and @ghc@. For non-default optimization levels, the path
+  -- suffix is one element longer and the extra path element needs
+  -- to be preserved.
+  distPrefElements = splitDirectories distPref
+  distPrefBuild = case drop (length distPrefElements - 3) distPrefElements of
+    ["t", _, "noopt"] ->
+      joinPath $ take (length distPrefElements - 3) distPrefElements
+                 ++ ["noopt"]
+    ["t", _, "opt"] ->
+      joinPath $ take (length distPrefElements - 3) distPrefElements
+                 ++ ["opt"]
+    [_, "t", _] ->
+      joinPath $ take (length distPrefElements - 2) distPrefElements
+    _ -> distPref
 
 tixDir :: FilePath  -- ^ \"dist/\" prefix
        -> Way
diff --git a/src/Distribution/Utils/Path.hs b/src/Distribution/Utils/Path.hs
--- a/src/Distribution/Utils/Path.hs
+++ b/src/Distribution/Utils/Path.hs
@@ -35,7 +35,7 @@
 -- until we interpret them.
 --
 newtype SymbolicPath from to = SymbolicPath FilePath
-  deriving (Generic, Show, Read, Eq, Typeable, Data)
+  deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Binary (SymbolicPath from to)
 instance (Typeable from, Typeable to) => Structured (SymbolicPath from to)
diff --git a/src/Distribution/Utils/Structured.hs b/src/Distribution/Utils/Structured.hs
--- a/src/Distribution/Utils/Structured.hs
+++ b/src/Distribution/Utils/Structured.hs
@@ -64,6 +64,7 @@
     containerStructure,
     -- * Structure type
     Structure (..),
+    Tag (..),
     TypeName,
     ConstructorName,
     TypeVersion,
@@ -207,7 +208,7 @@
             Nothing -> return $ mconcat [ Builder.word8 0, Builder.stringUtf8 (show t) ]
             Just acc' -> do
                 State.put acc'
-                k 
+                k
 
     goSop :: SopStructure -> State.State (Map.Map String (NonEmpty TypeRep)) Builder.Builder
     goSop sop = do
