[Git][ghc/ghc][wip/T25647] 35 commits: base: Label threads forked by IO operations

Patrick (@soulomoon) gitlab at gitlab.haskell.org
Sat Feb 8 20:37:07 UTC 2025



Patrick pushed to branch wip/T25647 at Glasgow Haskell Compiler / GHC


Commits:
8f8d3a90 by Ben Gamari at 2025-02-08T01:17:28-05:00
base: Label threads forked by IO operations

Addresses part of #25452.

Addresses core-libraries-committee#305.

- - - - -
28600825 by Ben Gamari at 2025-02-08T01:17:28-05:00
base: Label threads forked by System.Timeout

Addresses part of #25452.

Addresses core-libraries-committee#305.

- - - - -
8a249827 by Ben Gamari at 2025-02-08T01:17:28-05:00
base: Label signal handling threads

Addresses part of #25452.

Addresses core-libraries-committee#305.

- - - - -
26af26f0 by Ben Gamari at 2025-02-08T01:17:28-05:00
base: Label Windows console event handling threads

Addresses part of #25452.

Addresses core-libraries-committee#305.

- - - - -
bf9c3d4f by Ben Gamari at 2025-02-08T01:17:28-05:00
ghci: Label evaluation sandbox thread

Addresses part of #25452.

Addresses core-libraries-committee#305.

- - - - -
38f78ce5 by Ben Gamari at 2025-02-08T01:17:28-05:00
base: Add changelog entry for addition of thread labels

Addresses #25452.

Addresses core-libraries-committee#305.

- - - - -
c100deb5 by Ben Gamari at 2025-02-08T01:18:05-05:00
gen-ci: Clean up style

This cleans up a number of stylistic inconsistencies although it's still
far from perfect.

- - - - -
c4a7680a by Ben Gamari at 2025-02-08T01:18:05-05:00
gen-ci: Properly encapsulate GitLab predicates

- - - - -
72d14be7 by Simon Peyton Jones at 2025-02-08T20:36:39+00:00
WIP towards #25267

- - - - -
e71a4fb6 by Simon Peyton Jones at 2025-02-08T20:36:39+00:00
Wibbles

- - - - -
5755d1b5 by Simon Peyton Jones at 2025-02-08T20:36:39+00:00
Default tyvars in data/newtype insnstances

This is what fixes #25647

- - - - -
94962fe9 by Simon Peyton Jones at 2025-02-08T20:36:39+00:00
wibbles

Including fix for #25725

- - - - -
1a1ac919 by Simon Peyton Jones at 2025-02-08T20:36:39+00:00
Wibble

- - - - -
632c88ce by Patrick at 2025-02-08T20:36:39+00:00
add more tests

- - - - -
899f7590 by Patrick at 2025-02-08T20:36:39+00:00
Fix up T25611d with explicit kind annotation

- - - - -
57746293 by Patrick at 2025-02-08T20:36:39+00:00
fix up T25647_fail

- - - - -
c24c7bd5 by Patrick at 2025-02-08T20:36:39+00:00
cleanup whitespace

- - - - -
b005ce2a by Patrick at 2025-02-08T20:36:39+00:00
fix up T23512a

- - - - -
2ff9e2c8 by Patrick at 2025-02-08T20:36:39+00:00
add more examples to T25647b

- - - - -
56d57a2a by Patrick at 2025-02-08T20:36:39+00:00
add Dix6 to T25647_fail

- - - - -
0431d5b0 by Patrick at 2025-02-08T20:36:39+00:00
add Dix7 for T25647a

- - - - -
dabcbc77 by Patrick at 2025-02-08T20:36:39+00:00
change DefaultingStrategy of tcTyFamInstEqnGuts as well

- - - - -
73ec0074 by Patrick at 2025-02-08T20:36:39+00:00
align wildcard with named typevar on wether it is skolem

- - - - -
42452076 by Patrick at 2025-02-08T20:36:39+00:00
fix T17536c

- - - - -
cfa92439 by Patrick at 2025-02-08T20:36:39+00:00
Fix T9357

- - - - -
49161a84 by Patrick at 2025-02-08T20:36:39+00:00
remove wildcard usage

- - - - -
5d6aec85 by Patrick at 2025-02-08T20:36:39+00:00
Revert "align wildcard with named typevar on wether it is skolem"

This reverts commit d1f61858328cc190de9b34c9a24e8d6b28ee5fa9.

- - - - -
d2aa8e86 by Patrick at 2025-02-08T20:36:39+00:00
add WildCardTv to forbid wildcard from defaulting

- - - - -
cb661de1 by Patrick at 2025-02-08T20:36:39+00:00
Fix wildcard related tests

- - - - -
c54624db by Patrick at 2025-02-08T20:36:39+00:00
add wildcards testcase for T25647a

- - - - -
5d234718 by Patrick at 2025-02-08T20:36:39+00:00
Fix T25647a

- - - - -
f5abbf3a by Patrick at 2025-02-08T20:36:39+00:00
Revert "Fix wildcard related tests"

This reverts commit 8756ab87f4e3d74968d3937f84f811f78a861852.

- - - - -
1ff3327f by Patrick at 2025-02-08T20:36:39+00:00
limit WildCardTv to only HM_FamPat

- - - - -
28528ae1 by Patrick at 2025-02-08T20:36:39+00:00
fix

- - - - -
88dfabaa by Patrick at 2025-02-08T20:36:39+00:00
Revert "remove wildcard usage"

This reverts commit ccc9152f23177ab7a542852ffedf626edcdcef95.

- - - - -


30 changed files:

- .gitlab/generate-ci/gen_ci.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- libraries/base/changelog.md
- libraries/base/src/Control/Concurrent.hs
- libraries/base/src/System/Timeout.hs
- libraries/ghc-internal/src/GHC/Internal/Conc/Signal.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/ConsoleEvent.hsc
- libraries/ghci/GHCi/Run.hs
- + testsuite/tests/indexed-types/should_compile/T11450a.hs
- testsuite/tests/indexed-types/should_compile/T25611d.hs
- testsuite/tests/indexed-types/should_compile/all.T
- testsuite/tests/indexed-types/should_fail/T9357.stderr
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/rename/should_fail/T23512a.stderr
- + testsuite/tests/typecheck/should_compile/T25647_fail.hs
- + testsuite/tests/typecheck/should_compile/T25647_fail.stderr
- + testsuite/tests/typecheck/should_compile/T25647a.hs
- + testsuite/tests/typecheck/should_compile/T25647b.hs
- + testsuite/tests/typecheck/should_compile/T25725.hs
- testsuite/tests/typecheck/should_compile/all.T


Changes:

=====================================
.gitlab/generate-ci/gen_ci.hs
=====================================
@@ -5,6 +5,12 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE ViewPatterns #-}
 
+{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
+
+{-# HLINT ignore "Use newtype instead of data" #-}
+{-# HLINT ignore "Use camelCase" #-}
+{-# LANGUAGE DerivingStrategies #-}
+
 import Data.Aeson as A
 import qualified Data.Map as Map
 import Data.Map (Map)
@@ -199,7 +205,7 @@ data FlavourTrans =
 data BaseFlavour = Release | Validate | SlowValidate deriving Eq
 
 -----------------------------------------------------------------------------
--- Build Configs
+-- Build Configurations
 -----------------------------------------------------------------------------
 
 -- | A standard build config
@@ -244,7 +250,7 @@ releaseConfig = vanilla { buildFlavour = Release }
 debug :: BuildConfig
 debug = vanilla { buildFlavour = SlowValidate
                 , withAssertions = True
-                -- WithNuma so at least one job tests Numa
+                  -- WithNuma so at least one job tests Numa
                 , withNuma = True
                 }
 
@@ -280,21 +286,21 @@ usePerfProfilingTestsuite :: BuildConfig -> BuildConfig
 usePerfProfilingTestsuite bc = bc { testsuiteUsePerf = True }
 
 -----------------------------------------------------------------------------
--- Platform specific variables
+-- Identifying Platforms
 -----------------------------------------------------------------------------
 
 -- | These tags have to match what we call the runners on gitlab
 runnerTag :: Arch -> Opsys -> String
 runnerTag arch (Linux _) =
   case arch of
-    Amd64   -> "x86_64-linux"
-    AArch64 -> "aarch64-linux"
-    I386    -> "x86_64-linux"
-runnerTag AArch64 Darwin = "aarch64-darwin"
-runnerTag Amd64 Darwin = "x86_64-darwin-m1"
-runnerTag Amd64 Windows = "new-x86_64-windows"
+    Amd64                -> "x86_64-linux"
+    AArch64              -> "aarch64-linux"
+    I386                 -> "x86_64-linux"
+runnerTag AArch64 Darwin  = "aarch64-darwin"
+runnerTag Amd64 Darwin    = "x86_64-darwin-m1"
+runnerTag Amd64 Windows   = "new-x86_64-windows"
 runnerTag Amd64 FreeBSD14 = "x86_64-freebsd14"
-runnerTag _ _ = error "Invalid arch/opsys"
+runnerTag _ _             = error "Invalid arch/opsys"
 
 tags :: Arch -> Opsys -> BuildConfig -> [String]
 tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use
@@ -305,34 +311,34 @@ runnerPerfTag arch sys = runnerTag arch sys ++ "-perf"
 -- These names are used to find the docker image so they have to match what is
 -- in the docker registry.
 distroName :: LinuxDistro -> String
-distroName Debian12   = "deb12"
-distroName Debian11   = "deb11"
-distroName Debian11Js = "deb11-emsdk-closure"
+distroName Debian12      = "deb12"
+distroName Debian11      = "deb11"
+distroName Debian11Js    = "deb11-emsdk-closure"
 distroName Debian12Riscv = "deb12-riscv"
-distroName Debian10   = "deb10"
-distroName Debian9    = "deb9"
-distroName Fedora33   = "fedora33"
-distroName Fedora38   = "fedora38"
-distroName Ubuntu1804 = "ubuntu18_04"
-distroName Ubuntu2004 = "ubuntu20_04"
-distroName Ubuntu2204 = "ubuntu22_04"
-distroName Centos7    = "centos7"
-distroName Alpine312  = "alpine3_12"
-distroName Alpine318  = "alpine3_18"
-distroName Alpine320  = "alpine3_20"
-distroName AlpineWasm = "alpine3_20-wasm"
-distroName Rocky8     = "rocky8"
+distroName Debian10      = "deb10"
+distroName Debian9       = "deb9"
+distroName Fedora33      = "fedora33"
+distroName Fedora38      = "fedora38"
+distroName Ubuntu1804    = "ubuntu18_04"
+distroName Ubuntu2004    = "ubuntu20_04"
+distroName Ubuntu2204    = "ubuntu22_04"
+distroName Centos7       = "centos7"
+distroName Alpine312     = "alpine3_12"
+distroName Alpine318     = "alpine3_18"
+distroName Alpine320     = "alpine3_20"
+distroName AlpineWasm    = "alpine3_20-wasm"
+distroName Rocky8        = "rocky8"
 
 opsysName :: Opsys -> String
 opsysName (Linux distro) = "linux-" ++ distroName distro
-opsysName Darwin = "darwin"
-opsysName FreeBSD14 = "freebsd14"
-opsysName Windows = "windows"
+opsysName Darwin         = "darwin"
+opsysName FreeBSD14      = "freebsd14"
+opsysName Windows        = "windows"
 
 archName :: Arch -> String
-archName Amd64 = "x86_64"
+archName Amd64   = "x86_64"
 archName AArch64 = "aarch64"
-archName I386  = "i386"
+archName I386    = "i386"
 
 binDistName :: Arch -> Opsys -> BuildConfig -> String
 binDistName arch opsys bc = "ghc-" ++ testEnv arch opsys bc
@@ -341,16 +347,18 @@ binDistName arch opsys bc = "ghc-" ++ testEnv arch opsys bc
 -- Either the change is reflected by modifying the flavourString or directly (as is
 -- the case for settings which affect environment variables)
 testEnv :: Arch -> Opsys -> BuildConfig -> String
-testEnv arch opsys bc = intercalate "-" $
-                        [ archName arch
-                        , opsysName opsys ]
-                        ++ ["int_" ++ bignumString (bignumBackend bc) | bignumBackend bc /= Gmp]
-                        ++ ["unreg" | unregisterised bc ]
-                        ++ ["numa"  | withNuma bc ]
-                        ++ ["zstd"  | withZstd bc ]
-                        ++ ["no_tntc"  | not (tablesNextToCode bc) ]
-                        ++ ["cross_"++triple  | Just triple <- pure $ crossTarget bc ]
-                        ++ [flavourString (mkJobFlavour bc)]
+testEnv arch opsys bc =
+  intercalate "-" $ concat
+    [ [ archName arch
+      , opsysName opsys ]
+    , ["int_" ++ bignumString (bignumBackend bc) | bignumBackend bc /= Gmp]
+    , ["unreg" | unregisterised bc ]
+    , ["numa"  | withNuma bc ]
+    , ["zstd"  | withZstd bc ]
+    , ["no_tntc"  | not (tablesNextToCode bc) ]
+    , ["cross_"++triple  | Just triple <- pure $ crossTarget bc ]
+    , [flavourString (mkJobFlavour bc)]
+    ]
 
 -- | The hadrian flavour string we are going to use for this build
 flavourString :: Flavour -> String
@@ -384,7 +392,7 @@ dockerImage arch (Linux distro) =
 dockerImage _ _ = Nothing
 
 -----------------------------------------------------------------------------
--- Platform specific variables
+-- Platform-specific variables
 -----------------------------------------------------------------------------
 
 -- The variables map is a monoidal map so that we don't ever accidentally lose
@@ -438,35 +446,36 @@ opsysVariables _ FreeBSD14 = mconcat
   , "CABAL_INSTALL_VERSION" =: "3.10.3.0"
   ]
 opsysVariables arch (Linux distro) = distroVariables arch distro
-opsysVariables AArch64 (Darwin {}) =
-  mconcat [ "NIX_SYSTEM" =: "aarch64-darwin"
-          , "MACOSX_DEPLOYMENT_TARGET" =: "11.0"
-          , "LANG" =: "en_US.UTF-8"
-          , "CONFIGURE_ARGS" =: "--with-intree-gmp --with-system-libffi"
-          -- Fonts can't be installed on darwin
-          , "HADRIAN_ARGS" =: "--docs=no-sphinx-pdfs"
-          ]
-opsysVariables Amd64 (Darwin {}) =
-  mconcat [ "NIX_SYSTEM" =: "x86_64-darwin"
-          , "MACOSX_DEPLOYMENT_TARGET" =: "11.0"
-          -- "# Only Sierra and onwards supports clock_gettime. See #12858"
-          , "ac_cv_func_clock_gettime" =: "no"
-          -- # Only newer OS Xs support utimensat. See #17895
-          , "ac_cv_func_utimensat" =: "no"
-          -- # Only newer OS Xs support futimens. See #22938
-          , "ac_cv_func_futimens" =: "no"
-          , "LANG" =: "en_US.UTF-8"
-          , "CONFIGURE_ARGS" =: "--with-intree-gmp --with-system-libffi"
-          -- Fonts can't be installed on darwin
-          , "HADRIAN_ARGS" =: "--docs=no-sphinx-pdfs"
+opsysVariables AArch64 (Darwin {}) = mconcat
+  [ "NIX_SYSTEM" =: "aarch64-darwin"
+  , "MACOSX_DEPLOYMENT_TARGET" =: "11.0"
+  , "LANG" =: "en_US.UTF-8"
+  , "CONFIGURE_ARGS" =: "--with-intree-gmp --with-system-libffi"
+    -- Fonts can't be installed on darwin
+  , "HADRIAN_ARGS" =: "--docs=no-sphinx-pdfs"
+  ]
+opsysVariables Amd64 (Darwin {}) = mconcat
+  [ "NIX_SYSTEM" =: "x86_64-darwin"
+  , "MACOSX_DEPLOYMENT_TARGET" =: "11.0"
+    -- Only Sierra and onwards supports clock_gettime. See #12858
+  , "ac_cv_func_clock_gettime" =: "no"
+    -- Only newer OS Xs support utimensat. See #17895
+  , "ac_cv_func_utimensat" =: "no"
+    -- Only newer OS Xs support futimens. See #22938
+  , "ac_cv_func_futimens" =: "no"
+  , "LANG" =: "en_US.UTF-8"
+  , "CONFIGURE_ARGS" =: "--with-intree-gmp --with-system-libffi"
+    -- Fonts can't be installed on darwin
+  , "HADRIAN_ARGS" =: "--docs=no-sphinx-pdfs"
 
-          ]
-opsysVariables _ (Windows {}) =
-  mconcat [ "MSYSTEM" =: "CLANG64"
-          , "LANG" =: "en_US.UTF-8"
-          , "CABAL_INSTALL_VERSION" =: "3.10.2.0"
-          , "HADRIAN_ARGS" =: "--docs=no-sphinx-pdfs"
-          , "GHC_VERSION" =: "9.6.4" ]
+  ]
+opsysVariables _ (Windows {}) = mconcat
+  [ "MSYSTEM" =: "CLANG64"
+  , "LANG" =: "en_US.UTF-8"
+  , "CABAL_INSTALL_VERSION" =: "3.10.2.0"
+  , "HADRIAN_ARGS" =: "--docs=no-sphinx-pdfs"
+  , "GHC_VERSION" =: "9.6.4"
+  ]
 opsysVariables _ _ = mempty
 
 alpineVariables :: Arch -> Variables
@@ -481,7 +490,7 @@ alpineVariables arch = mconcat $
   | I386 <- [arch]
   ] ++
   [ brokenTest "T22033" "#25497" | I386 <- [arch] ] ++
-  [-- Bootstrap compiler has incorrectly configured target triple #25200
+  [ -- Bootstrap compiler has incorrectly configured target triple #25200
     "CONFIGURE_ARGS" =: "--enable-ignore-build-platform-mismatch --build=aarch64-unknown-linux --host=aarch64-unknown-linux --target=aarch64-unknown-linux"
   | AArch64 <- [arch]
   ]
@@ -491,15 +500,14 @@ distroVariables :: Arch -> LinuxDistro -> Variables
 distroVariables arch Alpine312 = alpineVariables arch
 distroVariables arch Alpine318 = alpineVariables arch
 distroVariables arch Alpine320 = alpineVariables arch
-distroVariables _ Centos7 = mconcat [
-    "HADRIAN_ARGS" =: "--docs=no-sphinx"
-  , brokenTest "T22012" "#23979"
-  ]
-distroVariables _ Fedora33 = mconcat
+distroVariables _    Centos7   = mconcat [ "HADRIAN_ARGS" =: "--docs=no-sphinx"
+                                         , brokenTest "T22012" "#23979"
+                                         ]
+distroVariables _    Fedora33  = mconcat
   -- LLC/OPT do not work for some reason in our fedora images
   -- These tests fail with this error: T11649 T5681 T7571 T8131b
   -- +/opt/llvm/bin/opt: /lib64/libtinfo.so.5: no version information available (required by /opt/llvm/bin/opt)
--- +/opt/llvm/bin/llc: /lib64/libtinfo.so.5: no version information available (required by /opt/llvm/bin/llc)
+  -- +/opt/llvm/bin/llc: /lib64/libtinfo.so.5: no version information available (required by /opt/llvm/bin/llc)
   [ "LLC" =: "/bin/false"
   , "OPT" =: "/bin/false"
   ]
@@ -510,7 +518,7 @@ distroVariables _ _ = mempty
 -----------------------------------------------------------------------------
 
 data Cache
-  = Cache { cacheKey :: String
+  = Cache { cacheKey   :: String
           , cachePaths :: [String]
           }
 
@@ -550,25 +558,27 @@ data ArtifactsWhen = ArtifactsOnSuccess | ArtifactsOnFailure | ArtifactsAlways
 instance ToJSON ArtifactsWhen where
   toJSON ArtifactsOnSuccess = "on_success"
   toJSON ArtifactsOnFailure = "on_failure"
-  toJSON ArtifactsAlways = "always"
+  toJSON ArtifactsAlways    = "always"
 
------------------------------------------------------------------------------
+---------------------------------------------------------------------
 -- Rules, when do we run a job
------------------------------------------------------------------------------
+---------------------------------------------------------------------
 
--- Data structure which records the condition when a job is run.
-data OnOffRules = OnOffRules { rule_set :: Rule -- ^ The enabled rules
-                             , when :: ManualFlag   -- ^ The additional condition about when to run this job.
-                             }
+-- | Data structure which records the condition when a job is run.
+data OnOffRules
+  = OnOffRules { rule_set :: Rule -- ^ The enabled rules
+               , when     :: ManualFlag   -- ^ The additional condition about when to run this job.
+               }
 
 -- The initial set of rules, which assumes a Validate pipeline which is run with FullCI.
 emptyRules :: String -> OnOffRules
 emptyRules jobName = OnOffRules (ValidateOnly jobName (S.fromList [FullCI])) OnSuccess
 
 -- When to run the job
-data ManualFlag = Manual -- ^ Only run the job when explicitly triggered by a user
-                | OnSuccess -- ^ Always run it, if the rules pass (the default)
-                deriving Eq
+data ManualFlag
+  = Manual -- ^ Only run the job when explicitly triggered by a user
+  | OnSuccess -- ^ Always run it, if the rules pass (the default)
+  deriving Eq
 
 setRule :: Rule -> OnOffRules -> OnOffRules
 setRule r (OnOffRules _ m) = OnOffRules r m
@@ -595,18 +605,23 @@ manualRule rules = rules { when = Manual }
 enumRules :: OnOffRules -> [OnOffRule]
 enumRules (OnOffRules r _) = rulesList
   where
-    rulesList = case r of
-                  ValidateOnly s rs -> [OnOffRule On (ValidateOnly s rs)
-                                    , OnOffRule Off ReleaseOnly
-                                    , OnOffRule Off Nightly ]
-                  Nightly -> [ OnOffRule Off (ValidateOnly "" S.empty)
-                             , OnOffRule Off ReleaseOnly
-                             , OnOffRule On Nightly ]
-                  ReleaseOnly -> [ OnOffRule Off (ValidateOnly "" S.empty)
-                                 , OnOffRule On ReleaseOnly
-                                 , OnOffRule Off Nightly ]
-
-
+    rulesList =
+      case r of
+        ValidateOnly s rs ->
+          [ OnOffRule On (ValidateOnly s rs)
+          , OnOffRule Off ReleaseOnly
+          , OnOffRule Off Nightly
+          ]
+        Nightly ->
+          [ OnOffRule Off (ValidateOnly "" S.empty)
+          , OnOffRule Off ReleaseOnly
+          , OnOffRule On Nightly
+          ]
+        ReleaseOnly ->
+          [ OnOffRule Off (ValidateOnly "" S.empty)
+          , OnOffRule On ReleaseOnly
+          , OnOffRule Off Nightly
+          ]
 
 data OnOffRule = OnOffRule OnOff Rule
 
@@ -617,102 +632,135 @@ instance ToJSON ManualFlag where
   toJSON OnSuccess = "on_success"
 
 instance ToJSON OnOffRules where
-  toJSON rules = toJSON [object ([
-    "if" A..= and_all (map one_rule (enumRules rules))
-    , "when" A..= toJSON (when rules)]
-    -- Necessary to stop manual jobs stopping pipeline progress
-    -- https://docs.gitlab.com/ee/ci/yaml/#rulesallow_failure
-    ++
-    ["allow_failure" A..= True | when rules == Manual ])]
-
+  toJSON rules = toJSON
+      [object $
+        [ "if" A..= and_all (map one_rule (enumRules rules))
+        , "when" A..= toJSON (when rules)
+        ] ++
+        -- Necessary to stop manual jobs stopping pipeline progress
+        -- https://docs.gitlab.com/ee/ci/yaml/#rulesallow_failure
+        [ "allow_failure" A..= True | when rules == Manual ]
+      ]
     where
-      one_rule (OnOffRule onoff r) = ruleString onoff r
+      one_rule (OnOffRule onoff r) = ruleToCond onoff r
 
+---------------------------------------------------------------------
+-- Rule conditions
+---------------------------------------------------------------------
 
-parens :: [Char] -> [Char]
-parens s = "(" ++ s ++ ")"
-and_all :: [[Char]] -> [Char]
-and_all rs = intercalate " && " (map parens rs)
-or_all :: [[Char]] -> [Char]
-or_all rs = intercalate " || " (map parens rs)
+-- | A predicate in GitLab's rules language.
+newtype Cond = Cond { getCond :: String }
+  deriving newtype (ToJSON)
 
--- | A Rule corresponds to some condition which must be satisifed in order to
--- run the job.
-data Rule = ReleaseOnly  -- ^ Only run this job in a release pipeline
-          | Nightly      -- ^ Only run this job in the nightly pipeline
-          | ValidateOnly String (S.Set ValidateRule) -- ^ Only run this job in a validate pipeline, when any of these rules are enabled.
-          deriving (Show, Ord, Eq)
-
-data ValidateRule =
-            FullCI       -- ^ Run this job when the "full-ci" label is present.
-          | FastCI       -- ^ Run this job on every validation pipeline
-          | LLVMBackend  -- ^ Run this job when the "LLVM backend" label is present
-          | JSBackend    -- ^ Run this job when the "javascript" label is present
-          | RiscV        -- ^ Run this job when the "RISC-V" label is present
-          | WasmBackend  -- ^ Run this job when the "wasm" label is present
-          | FreeBSDLabel -- ^ Run this job when the "FreeBSD" label is set.
-          | NonmovingGc  -- ^ Run this job when the "non-moving GC" label is set.
-          | IpeData      -- ^ Run this job when the "IPE" label is set
-          | TestPrimops  -- ^ Run this job when "test-primops" label is set
-          | I386Backend  -- ^ Run this job when the "i386" label is set
-          deriving (Show, Ord, Eq)
-
--- A constant evaluating to True because gitlab doesn't support "true" in the
+parens :: Cond -> Cond
+parens (Cond s) = Cond $ "(" ++ s ++ ")"
+
+and_all :: [Cond] -> Cond
+and_all =
+  Cond . intercalate " && " . map (getCond . parens)
+
+or_all :: [Cond] -> Cond
+or_all =
+  Cond . intercalate " || " . map (getCond . parens)
+
+type Var = String
+
+varIsSet :: Var -> Cond
+varIsSet var =
+  Cond $ "$" <> var
+
+-- | A constant evaluating to True because gitlab doesn't support "true" in the
 -- expression language.
-true :: String
-true =  "\"true\" == \"true\""
--- A constant evaluating to False because gitlab doesn't support "true" in the
+true :: Cond
+true = Cond "\"true\" == \"true\""
+
+-- | A constant evaluating to False because gitlab doesn't support "true" in the
 -- expression language.
-_false :: String
-_false = "\"disabled\" != \"disabled\""
-
--- Convert the state of the rule into a string that gitlab understand.
-ruleString :: OnOff -> Rule -> String
-ruleString On (ValidateOnly only_job_name vs) =
-  let conds = S.toList vs
-      empty_only_job = envVarNull "ONLY_JOBS"
-      run_cond = case conds of
-                  [] -> _false
-                  cs -> or_all (map validateRuleString conds)
-      escape :: String -> String
-      escape = concatMap (\c -> if c == '+' then "\\+" else [c])
-
-  in
-    or_all  [
-    -- 1. Case when ONLY_JOBS is set
-      and_all [ "$ONLY_JOBS", "$ONLY_JOBS =~ /.*\\b" ++  escape only_job_name ++ "(\\s|$).*/" ]
-    -- 2. Case when ONLY_JOBS is null
-    , and_all [ empty_only_job, run_cond ]
-    ]
-ruleString Off (ValidateOnly {}) = true
-ruleString On ReleaseOnly = "$RELEASE_JOB == \"yes\""
-ruleString Off ReleaseOnly = "$RELEASE_JOB != \"yes\""
-ruleString On Nightly = "$NIGHTLY"
-ruleString Off Nightly = envVarNull "NIGHTLY"
+_false :: Cond
+_false = Cond "\"disabled\" != \"disabled\""
+
+labelString :: String -> Cond
+labelString s =
+  Cond $ "$CI_MERGE_REQUEST_LABELS =~ /.*" ++ s ++ ".*/"
 
-labelString :: String -> String
-labelString s =  "$CI_MERGE_REQUEST_LABELS =~ /.*" ++ s ++ ".*/"
+branchStringExact :: String -> Cond
+branchStringExact =
+  varEqString "CI_COMMIT_BRANCH"
 
-branchStringExact :: String -> String
-branchStringExact s = envVarString "CI_COMMIT_BRANCH" s
+branchStringLike :: String -> Cond
+branchStringLike s =
+  Cond $ "$CI_COMMIT_BRANCH =~ /" ++ s ++ "/"
 
-branchStringLike :: String -> String
-branchStringLike s = "$CI_COMMIT_BRANCH =~ /" ++ s ++ "/"
+varEqString :: String -> String -> Cond
+varEqString var s =
+  Cond $ "$" ++ var ++ " == \"" ++ s ++ "\""
 
-envVarString :: String -> String -> String
-envVarString var s = "$" ++ var ++ " == \"" ++ s ++ "\""
+varNeString :: String -> String -> Cond
+varNeString var s =
+  Cond $ "$" ++ var ++ " != \"" ++ s ++ "\""
 
-envVarNull :: String ->  String
-envVarNull var = "$" ++ var ++ " == null"
+varIsNull :: String -> Cond
+varIsNull var =
+  Cond $ "$" ++ var ++ " == null"
 
+---------------------------------------------------------------------
+-- Our Rules
+---------------------------------------------------------------------
 
-validateRuleString :: ValidateRule -> String
-validateRuleString FullCI = or_all ([ labelString "full-ci"
-                                    , labelString "marge_bot_batch_merge_job"
-                                    , branchStringExact "master"
-                                    , branchStringLike "ghc-[0-9]+\\.[0-9]+"
-                                    ])
-validateRuleString FastCI = true
+-- | A Rule corresponds to some condition which must be satisifed in order to
+-- run the job.
+data Rule
+  = ReleaseOnly  -- ^ Only run this job in a release pipeline
+  | Nightly      -- ^ Only run this job in the nightly pipeline
+  | ValidateOnly String (S.Set ValidateRule) -- ^ Only run this job in a validate pipeline, when any of these rules are enabled.
+  deriving (Show, Ord, Eq)
+
+data ValidateRule
+  = FullCI       -- ^ Run this job when the "full-ci" label is present.
+  | FastCI       -- ^ Run this job on every validation pipeline
+  | LLVMBackend  -- ^ Run this job when the "LLVM backend" label is present
+  | JSBackend    -- ^ Run this job when the "javascript" label is present
+  | RiscV        -- ^ Run this job when the "RISC-V" label is present
+  | WasmBackend  -- ^ Run this job when the "wasm" label is present
+  | FreeBSDLabel -- ^ Run this job when the "FreeBSD" label is set.
+  | NonmovingGc  -- ^ Run this job when the "non-moving GC" label is set.
+  | IpeData      -- ^ Run this job when the "IPE" label is set
+  | TestPrimops  -- ^ Run this job when "test-primops" label is set
+  | I386Backend  -- ^ Run this job when the "i386" label is set
+  deriving (Show, Ord, Eq)
+
+-- | Convert the state of the rule into a string that gitlab understand.
+ruleToCond :: OnOff -> Rule -> Cond
+ruleToCond On (ValidateOnly only_job_name vs) =
+    or_all
+    [ -- 1. Case when ONLY_JOBS is set
+      and_all [ varIsSet "ONLY_JOBS"
+              , Cond $ "$ONLY_JOBS =~ /.*\\b" ++ escape only_job_name ++ "(\\s|$).*/"
+              ]
+      -- 2. Case when ONLY_JOBS is null
+    , and_all [ varIsNull "ONLY_JOBS"
+              , case S.toList vs of
+                  [] -> _false
+                  cs -> or_all (map validateRuleString cs)
+              ]
+    ]
+  where
+    escape :: String -> String
+    escape = concatMap (\c -> if c == '+' then "\\+" else [c])
+ruleToCond Off (ValidateOnly {}) = true
+ruleToCond On  ReleaseOnly       = "RELEASE_JOB" `varEqString` "yes"
+ruleToCond Off ReleaseOnly       = "RELEASE_JOB" `varNeString` "yes"
+ruleToCond On  Nightly           = varIsSet "NIGHTLY"
+ruleToCond Off Nightly           = varIsNull "NIGHTLY"
+
+
+validateRuleString :: ValidateRule -> Cond
+validateRuleString FullCI       = or_all [ labelString "full-ci"
+                                         , labelString "marge_bot_batch_merge_job"
+                                         , branchStringExact "master"
+                                         , branchStringLike "ghc-[0-9]+\\.[0-9]+"
+                                         ]
+validateRuleString FastCI       = true
 
 validateRuleString LLVMBackend  = labelString "LLVM backend"
 validateRuleString JSBackend    = labelString "javascript"
@@ -724,6 +772,10 @@ validateRuleString IpeData      = labelString "IPE"
 validateRuleString TestPrimops  = labelString "test-primops"
 validateRuleString I386Backend  = labelString "i386"
 
+---------------------------------------------------------------------
+-- The Job type
+---------------------------------------------------------------------
+
 -- | A 'Job' is the description of a single job in a gitlab pipeline. The
 -- job contains all the information about how to do the build but can be further
 -- modified with information about when to run jobs, which variables to set for
@@ -747,15 +799,15 @@ data Job
 instance ToJSON Job where
   toJSON Job{..} = object
     [ "stage" A..= jobStage
-    -- Convoluted to avoid download artifacts from ghci job
-    -- https://docs.gitlab.com/ee/ci/yaml/#needsartifacts
+      -- Convoluted to avoid download artifacts from ghci job
+      -- https://docs.gitlab.com/ee/ci/yaml/#needsartifacts
     , "needs" A..= map (\j -> object [ "job" A..= j, "artifacts" A..= False ]) jobNeeds
     , "dependencies" A..= jobDependencies
     , "image" A..= jobDockerImage
     , "tags" A..= jobTags
     , "allow_failure" A..= jobAllowFailure
-    -- Joining up variables like this may well be the wrong thing to do but
-    -- at least it doesn't lose information silently by overriding.
+      -- Joining up variables like this may well be the wrong thing to do but
+      -- at least it doesn't lose information silently by overriding.
     , "variables" A..= fmap unwords jobVariables
     , "artifacts" A..= jobArtifacts
     , "cache" A..= jobCache
@@ -783,7 +835,8 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
       = [ "bash .gitlab/ci.sh setup"
         , "bash .gitlab/ci.sh configure"
         , "bash .gitlab/ci.sh build_hadrian"
-        , "bash .gitlab/ci.sh test_hadrian" ]
+        , "bash .gitlab/ci.sh test_hadrian"
+        ]
       | otherwise
       = [ "find libraries -name config.sub -exec cp config.sub {} \\;" | Darwin == opsys ] ++
         [ "sudo chown ghc:ghc -R ." | Linux {} <- [opsys]] ++
@@ -803,7 +856,8 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
       [ ".gitlab/ci.sh save_cache"
       , ".gitlab/ci.sh save_test_output"
       , ".gitlab/ci.sh clean"
-      , "cat ci_timings" ]
+      , "cat ci_timings"
+      ]
 
     jobFlavour = mkJobFlavour buildConfig
 
@@ -819,9 +873,11 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
       , maybe mempty ("CONFIGURE_WRAPPER" =:) (configureWrapper buildConfig)
       , maybe mempty ("CROSS_TARGET" =:) (crossTarget buildConfig)
       , case crossEmulator buildConfig of
-          NoEmulator       -> case crossTarget buildConfig of
-            Nothing -> mempty
-            Just _  -> "CROSS_EMULATOR" =: "NOT_SET" -- we need an emulator but it isn't set. Won't run the testsuite
+          NoEmulator
+            -- we need an emulator but it isn't set. Won't run the testsuite
+            | Just _ <- crossTarget buildConfig
+                           -> "CROSS_EMULATOR" =: "NOT_SET"
+            | otherwise    -> mempty
           Emulator s       -> "CROSS_EMULATOR" =: s
           NoEmulatorNeeded -> mempty
       , if withNuma buildConfig then "ENABLE_NUMA" =: "1" else mempty
@@ -901,8 +957,10 @@ setVariable k v j = j { jobVariables = MonoidalMap $ Map.insert k [v] $ unMonoid
 delVariable :: String -> Job -> Job
 delVariable k j = j { jobVariables = MonoidalMap $ Map.delete k $ unMonoidalMap $ jobVariables j }
 
+---------------------------------------------------------------------
 -- Building the standard jobs
---
+---------------------------------------------------------------------
+
 -- | Make a normal validate CI job
 validate :: Arch -> Opsys -> BuildConfig -> NamedJob Job
 validate = job
@@ -919,15 +977,27 @@ releaseRule = setJobRule ReleaseOnly
 nightly :: Arch -> Opsys -> BuildConfig -> NamedJob Job
 nightly arch opsys bc =
   let NamedJob n j = job arch opsys bc
-  in NamedJob { name = "nightly-" ++ n, jobInfo = nightlyRule . keepArtifacts "8 weeks" . highCompression $ j}
+  in NamedJob { name = "nightly-" ++ n
+              , jobInfo = nightlyRule
+                        . keepArtifacts "8 weeks"
+                        . highCompression $ j
+              }
 
 -- | Make a normal release CI job
 release :: Arch -> Opsys -> BuildConfig -> NamedJob Job
 release arch opsys bc =
   let NamedJob n j = job arch opsys (bc { buildFlavour = Release })
-  in NamedJob { name = "release-" ++ n, jobInfo = releaseRule . keepArtifacts "1 year" . ignorePerfFailures . useHashUnitIds . highCompression $ j}
+  in NamedJob { name = "release-" ++ n
+              , jobInfo = releaseRule
+                        . keepArtifacts "1 year"
+                        . ignorePerfFailures
+                        . useHashUnitIds
+                        . highCompression $ j
+              }
 
+---------------------------------------------------------------------
 -- Specific job modification functions
+---------------------------------------------------------------------
 
 -- | Mark a job as requiring a manual trigger.
 manual :: Job -> Job
@@ -984,6 +1054,10 @@ onlyRule t = modifyValidateJobs (onlyValidateJobRule t)
 disableValidate :: JobGroup Job -> JobGroup Job
 disableValidate = modifyValidateJobs (removeValidateJobRule FastCI . removeValidateJobRule FullCI)
 
+---------------------------------------------------------------------
+-- NamedJob
+---------------------------------------------------------------------
+
 data NamedJob a = NamedJob { name :: String, jobInfo :: a } deriving (Show, Functor)
 
 renameJob :: (String -> String) -> NamedJob a -> NamedJob a
@@ -994,14 +1068,18 @@ instance ToJSON a => ToJSON (NamedJob a) where
     [ "name" A..= name nj
     , "jobInfo" A..= jobInfo nj ]
 
-
---data NamedJobGroup a = NamedJobGroup { platform :: String, jg :: JobGroup a }
+---------------------------------------------------------------------
+-- JobGroup
+---------------------------------------------------------------------
 
 -- Jobs are grouped into either triples or pairs depending on whether the
 -- job is just validate and nightly, or also release.
-data JobGroup a = StandardTriple { v :: Maybe (NamedJob a)
-                                 , n :: Maybe (NamedJob a)
-                                 , r :: Maybe (NamedJob a) } deriving (Functor, Show)
+data JobGroup a
+  = StandardTriple { v :: Maybe (NamedJob a)
+                   , n :: Maybe (NamedJob a)
+                   , r :: Maybe (NamedJob a)
+                   }
+  deriving (Functor, Show)
 
 instance ToJSON a => ToJSON (JobGroup a) where
   toJSON StandardTriple{..} = object
@@ -1039,16 +1117,19 @@ flattenJobGroup (StandardTriple a b c) = map flattenNamedJob (catMaybes [a,b,c])
 flattenNamedJob :: NamedJob a -> (String, a)
 flattenNamedJob (NamedJob n i) = (n, i)
 
-
 -- | Specification for all the jobs we want to build.
 jobs :: Map String Job
-jobs = Map.fromList $ concatMap (flattenJobGroup) job_groups
+jobs = Map.fromList $ concatMap flattenJobGroup job_groups
+
+---------------------------------------------------------------------
+-- Job definitions
+---------------------------------------------------------------------
 
 debian_x86 :: [JobGroup Job]
 debian_x86 =
   [ -- Release configurations
-  -- We still build Deb9 bindists for now due to Ubuntu 18 and Linux Mint 19
-  -- not being at EOL until April 2023 and they still need tinfo5.
+    -- We still build Deb9 bindists for now due to Ubuntu 18 and Linux Mint 19
+    -- not being at EOL until April 2023 and they still need tinfo5.
     disableValidate (standardBuildsWithConfig Amd64 (Linux Debian9) (splitSectionsBroken vanilla))
   , disableValidate (standardBuilds Amd64 (Linux Debian10))
   , disableValidate (standardBuildsWithConfig Amd64 (Linux Debian10) dwarf)
@@ -1056,15 +1137,15 @@ debian_x86 =
   , disableValidate (standardBuilds Amd64 (Linux Debian12))
 
 
-  -- Validate only builds
+    -- Validate only builds
   , fastCI (validateBuilds Amd64 (Linux validate_debian) debug)
   , validateBuilds Amd64 (Linux validate_debian) nativeInt
   , validateBuilds Amd64 (Linux validate_debian) unreg
-   -- More work is needed to address TSAN failures: #22520
+    -- More work is needed to address TSAN failures: #22520
   , modifyNightlyJobs allowFailure (modifyValidateJobs (allowFailure . manual) tsan_jobs)
   , -- Nightly allowed to fail: #22343
     modifyNightlyJobs allowFailure (modifyValidateJobs manual (validateBuilds Amd64 (Linux validate_debian) noTntc))
-  -- Run the 'perf' profiling nightly job in the release config.
+    -- Run the 'perf' profiling nightly job in the release config.
   , perfProfilingJob Amd64 (Linux Debian12) releaseConfig
 
   , onlyRule LLVMBackend (validateBuilds Amd64 (Linux validate_debian) llvm)
@@ -1095,7 +1176,7 @@ debian_aarch64 =
   [
      disableValidate (standardBuildsWithConfig AArch64 (Linux Debian10) (splitSectionsBroken vanilla))
    , fastCI (standardBuildsWithConfig AArch64 (Linux Debian12) (splitSectionsBroken vanilla))
-   -- LLVM backend bootstrap
+     -- LLVM backend bootstrap
    , onlyRule LLVMBackend (validateBuilds AArch64 (Linux Debian12) llvm)
   ]
 
@@ -1120,11 +1201,10 @@ rhel_x86 =
 
 fedora_x86 :: [JobGroup Job]
 fedora_x86 =
-  [
-  -- Fedora33 job is always built with perf so there's one job in the normal
-  -- validate pipeline which is built with perf.
+  [ -- Fedora33 job is always built with perf so there's one job in the normal
+    -- validate pipeline which is built with perf.
     fastCI (standardBuildsWithConfig Amd64 (Linux Fedora33) releaseConfig)
-  -- This job is only for generating head.hackage docs
+    -- This job is only for generating head.hackage docs
   , hackage_doc_job (disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora33) releaseConfig))
   , disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora33) dwarf)
   , disableValidate (standardBuilds Amd64 (Linux Fedora38))
@@ -1154,7 +1234,7 @@ alpine_x86 =
   [ -- Fully static build, in theory usable on any linux distribution.
     fullyStaticBrokenTests (standardBuildsWithConfig Amd64 (Linux Alpine312) (splitSectionsBroken static))
   , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt)))
-  -- Dynamically linked build, suitable for building your own static executables on alpine
+    -- Dynamically linked build, suitable for building your own static executables on alpine
   , disableValidate (standardBuildsWithConfig Amd64 (Linux Alpine312) (splitSectionsBroken vanilla))
   , disableValidate (standardBuildsWithConfig Amd64 (Linux Alpine320) (splitSectionsBroken vanilla))
   , allowFailureGroup (standardBuildsWithConfig I386 (Linux Alpine320) (splitSectionsBroken vanilla))
@@ -1173,16 +1253,16 @@ alpine_aarch64 = [
 
 cross_jobs :: [JobGroup Job]
 cross_jobs = [
-  -- x86 -> aarch64
+    -- x86 -> aarch64
     validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing)
 
-  -- x86_64 -> riscv
+    -- x86_64 -> riscv
   , addValidateRule RiscV (validateBuilds Amd64 (Linux Debian12Riscv) (crossConfig "riscv64-linux-gnu" (Emulator "qemu-riscv64 -L /usr/riscv64-linux-gnu") Nothing))
 
-  -- Javascript
+    -- Javascript
   , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig)
 
-  -- Wasm
+    -- Wasm
   , make_wasm_jobs wasm_build_config
   , modifyValidateJobs manual $
       make_wasm_jobs wasm_build_config {bignumBackend = Native}
@@ -1203,10 +1283,9 @@ cross_jobs = [
 
     wasm_build_config =
       (crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing)
-        {
-          hostFullyStatic = True
-          , buildFlavour     = Release -- TODO: This needs to be validate but wasm backend doesn't pass yet
-          , textWithSIMDUTF = True
+        { hostFullyStatic = True
+        , buildFlavour    = Release -- TODO: This needs to be validate but wasm backend doesn't pass yet
+        , textWithSIMDUTF = True
         }
 
 job_groups :: [JobGroup Job]
@@ -1224,6 +1303,9 @@ job_groups =
   ++ cross_jobs
   ++ freebsd_jobs
 
+---------------------------------------------------------------------
+-- Platform mapping for GHCup metadata
+---------------------------------------------------------------------
 
 mkPlatform :: Arch -> Opsys -> String
 mkPlatform arch opsys = archName arch <> "-" <> opsysName opsys
@@ -1267,7 +1349,11 @@ platform_mapping = Map.map go combined_result
                 , "release-x86_64-windows-release"
                 ]
 
-    process sel = Map.fromListWith combine [ (uncurry mkPlatform (jobPlatform (jobInfo $ j)), j) | (sel -> Just j) <- job_groups  ]
+    process sel =
+      Map.fromListWith combine
+      [ (uncurry mkPlatform (jobPlatform (jobInfo j)), j)
+      | (sel -> Just j) <- job_groups
+      ]
 
     vs = process v
     ns = process n
@@ -1275,10 +1361,13 @@ platform_mapping = Map.map go combined_result
 
     all_platforms = Map.keysSet vs <> Map.keysSet ns <> Map.keysSet rs
 
-    combined_result = Map.fromList [ (p, StandardTriple { v = Map.lookup p vs
-                                                        , n = Map.lookup p ns
-                                                        , r = Map.lookup p rs })
-                                   | p <- S.toList all_platforms ]
+    combined_result =
+      Map.fromList
+      [ (p, StandardTriple { v = Map.lookup p vs
+                           , n = Map.lookup p ns
+                           , r = Map.lookup p rs })
+      | p <- S.toList all_platforms
+      ]
 
     combine a b
       | name a `elem` whitelist = a -- Explicitly selected
@@ -1293,6 +1382,9 @@ data BindistInfo = BindistInfo { bindistName :: String } deriving Show
 instance ToJSON BindistInfo where
   toJSON (BindistInfo n) = object [ "bindistName" A..= n ]
 
+---------------------------------------------------------------------
+-- Main entrypoint
+---------------------------------------------------------------------
 
 main :: IO ()
 main = do


=====================================
compiler/GHC/Rename/Module.hs
=====================================
@@ -659,6 +659,7 @@ rnClsInstDecl (ClsInstDecl { cid_ext = (inst_warn_ps, _, _)
 rnFamEqn :: HsDocContext
          -> AssocTyFamInfo
          -> FamEqn GhcPs rhs
+         -> FreeKiTyVars     -- Implicit binders of the rhs payload
          -> (HsDocContext -> rhs -> RnM (rhs', FreeVars))
          -> RnM (FamEqn GhcRn rhs', FreeVars)
 rnFamEqn doc atfi
@@ -666,7 +667,7 @@ rnFamEqn doc atfi
             , feqn_bndrs  = outer_bndrs
             , feqn_pats   = pats
             , feqn_fixity = fixity
-            , feqn_rhs    = payload }) rn_payload
+            , feqn_rhs    = payload }) payload_kvs rn_payload
   = do { tycon' <- lookupFamInstName mb_cls tycon
 
          -- all_imp_vars represent the implicitly bound type variables. This is
@@ -697,7 +698,7 @@ rnFamEqn doc atfi
          --
          -- For associated type family instances, exclude the type variables
          -- bound by the instance head with filterInScopeM (#19649).
-       ; all_imp_vars <- filterInScopeM $ pat_kity_vars
+       ; all_imp_vars <- filterInScopeM $ (pat_kity_vars ++ payload_kvs)
 
        ; bindHsOuterTyVarBndrs doc mb_cls all_imp_vars outer_bndrs $ \rn_outer_bndrs ->
     do { (pats', pat_fvs) <- rnLHsTypeArgs (FamPatCtx tycon) pats
@@ -788,7 +789,7 @@ rnFamEqn doc atfi
     --   type instance F a b c = Either a b
     --                   ^^^^^
     lhs_loc = case map lhsTypeArgSrcSpan pats of
-      []         -> panic "rnFamEqn.lhs_loc"
+      []         -> getLocA tycon
       [loc]      -> loc
       (loc:locs) -> loc `combineSrcSpans` last locs
 
@@ -847,8 +848,9 @@ rnTyFamInstEqn :: AssocTyFamInfo
                -> TyFamInstEqn GhcPs
                -> RnM (TyFamInstEqn GhcRn, FreeVars)
 rnTyFamInstEqn atfi eqn@(FamEqn { feqn_tycon = tycon })
-  = rnFamEqn (TySynCtx tycon) atfi eqn rnTySyn
-
+  = rnFamEqn (TySynCtx tycon) atfi eqn
+       [{- No implicit vars on RHS of a type instance -}]
+       rnTySyn
 
 rnTyFamDefltDecl :: Name
                  -> TyFamDefltDecl GhcPs
@@ -859,9 +861,9 @@ rnDataFamInstDecl :: AssocTyFamInfo
                   -> DataFamInstDecl GhcPs
                   -> RnM (DataFamInstDecl GhcRn, FreeVars)
 rnDataFamInstDecl atfi (DataFamInstDecl { dfid_eqn =
-                    eqn@(FamEqn { feqn_tycon = tycon })})
-  = do { (eqn', fvs) <-
-           rnFamEqn (TyDataCtx tycon) atfi eqn rnDataDefn
+                    eqn@(FamEqn { feqn_tycon = tycon, feqn_rhs = defn })})
+  = do { let implicit_kvs = extractDataDefnKindVars defn
+       ; (eqn', fvs) <- rnFamEqn (TyDataCtx tycon) atfi eqn implicit_kvs rnDataDefn
        ; return (DataFamInstDecl { dfid_eqn = eqn' }, fvs) }
 
 -- Renaming of the associated types in instances.


=====================================
compiler/GHC/Tc/Gen/HsType.hs
=====================================
@@ -2212,7 +2212,7 @@ tcAnonWildCardOcc is_extra (TcTyMode { mode_holes = Just (hole_lvl, hole_mode) }
     --           esp the bullet on nested forall types
   = do { kv_details <- newTauTvDetailsAtLevel hole_lvl
        ; kv_name    <- newMetaTyVarName (fsLit "k")
-       ; wc_details <- newTauTvDetailsAtLevel hole_lvl
+       ; wc_details <- mk_wc_details hole_lvl
        ; wc_name    <- newMetaTyVarName wc_nm
        ; let kv      = mkTcTyVar kv_name liftedTypeKind kv_details
              wc_kind = mkTyVarTy kv
@@ -2231,11 +2231,11 @@ tcAnonWildCardOcc is_extra (TcTyMode { mode_holes = Just (hole_lvl, hole_mode) }
        ; checkExpectedKind ty (mkTyVarTy wc_tv) wc_kind exp_kind }
   where
      -- See Note [Wildcard names]
-     wc_nm = case hole_mode of
-               HM_Sig      -> fsLit "w"
-               HM_FamPat   -> fsLit "_"
-               HM_VTA      -> fsLit "w"
-               HM_TyAppPat -> fsLit "_"
+     (wc_nm, mk_wc_details) = case hole_mode of
+               HM_Sig      -> (fsLit "w", newTauTvDetailsAtLevel)
+               HM_FamPat   -> (fsLit "_", newWildCardTvDetailsAtLevel)
+               HM_VTA      -> (fsLit "w", newTauTvDetailsAtLevel)
+               HM_TyAppPat -> (fsLit "_", newTauTvDetailsAtLevel)
 
      emit_holes = case hole_mode of
                      HM_Sig     -> True


=====================================
compiler/GHC/Tc/TyCl.hs
=====================================
@@ -3141,7 +3141,7 @@ tcDataDefn err_ctxt roles_info tc_name
                                                -- via inferInitialKinds
                        , dd_cons = cons
                        , dd_derivs = derivs })
-  = bindTyClTyVars tc_name $ \ tc_bndrs res_kind ->
+  = bindTyClTyVars tc_name $ \ tc_bndrs tc_res_kind ->
        -- The TyCon tyvars must scope over
        --    - the stupid theta (dd_ctxt)
        --    - for H98 constructors only, the ConDecl
@@ -3152,18 +3152,18 @@ tcDataDefn err_ctxt roles_info tc_name
        ; tcg_env <- getGblEnv
        ; let hsc_src = tcg_src tcg_env
        ; unless (mk_permissive_kind hsc_src cons) $
-         checkDataKindSig (DataDeclSort (dataDefnConsNewOrData cons)) res_kind
+         checkDataKindSig (DataDeclSort (dataDefnConsNewOrData cons)) tc_res_kind
 
-       ; stupid_tc_theta <- pushLevelAndSolveEqualities skol_info tc_bndrs $
+       ; tc_stupid_theta <- pushLevelAndSolveEqualities skol_info tc_bndrs $
                             tcHsContext ctxt
 
        -- See Note [Error on unconstrained meta-variables] in GHC.Tc.Utils.TcMType
        -- Example: (typecheck/should_fail/T17567StupidTheta)
        --   data (forall a. a b ~ a c) => T b c
        -- The kind of 'a' is unconstrained.
-       ; dvs <- candidateQTyVarsOfTypes stupid_tc_theta
+       ; dvs <- candidateQTyVarsOfTypes tc_stupid_theta
        ; let err_ctx tidy_env
-               = do { (tidy_env2, theta) <- zonkTidyTcTypes tidy_env stupid_tc_theta
+               = do { (tidy_env2, theta) <- zonkTidyTcTypes tidy_env tc_stupid_theta
                     ; return (tidy_env2, UninfTyCtx_DataContext theta) }
        ; doNotQuantifyTyVars dvs err_ctx
 
@@ -3177,12 +3177,12 @@ tcDataDefn err_ctxt roles_info tc_name
 
        ; (bndrs, stupid_theta, res_kind) <- initZonkEnv NoFlexi $
          runZonkBndrT (zonkTyVarBindersX tc_bndrs) $ \ bndrs ->
-           do { stupid_theta   <- zonkTcTypesToTypesX stupid_tc_theta
-              ; res_kind       <- zonkTcTypeToTypeX   res_kind
+           do { stupid_theta   <- zonkTcTypesToTypesX tc_stupid_theta
+              ; res_kind       <- zonkTcTypeToTypeX   tc_res_kind
               ; return (bndrs, stupid_theta, res_kind) }
 
        ; tycon <- fixM $ \ rec_tycon -> do
-             { data_cons <- tcConDecls DDataType rec_tycon tc_bndrs res_kind cons
+             { data_cons <- tcConDecls DDataType rec_tycon tc_bndrs tc_res_kind cons
              ; tc_rhs    <- mk_tc_rhs hsc_src rec_tycon data_cons
              ; tc_rep_nm <- newTyConRepName tc_name
 
@@ -3360,24 +3360,52 @@ So, we use bindOuterFamEqnTKBndrs (which does not create an implication for
 the telescope), and generalise over /all/ the variables in the LHS,
 without treating the explicitly-quantified ones specially. Wrinkles:
 
- - When generalising, include the explicit user-specified forall'd
+(GT1) When generalising, include the explicit user-specified forall'd
    variables, so that we get an error from Validity.checkFamPatBinders
    if a forall'd variable is not bound on the LHS
 
- - We still want to complain about a bad telescope among the user-specified
+(GT2) We still want to complain about a bad telescope among the user-specified
    variables.  So in checkFamTelescope we emit an implication constraint
    quantifying only over them, purely so that we get a good telescope error.
 
-  - Note that, unlike a type signature like
+(GT3) Note that, unlike a type signature like
        f :: forall (a::k). blah
     we do /not/ care about the Inferred/Specified designation or order for
     the final quantified tyvars.  Type-family instances are not invoked
     directly in Haskell source code, so visible type application etc plays
     no role.
 
-See also Note [Re-quantify type variables in rules] in
-GHC.Tc.Gen.Rule, which explains a /very/ similar design when
-generalising over the type of a rewrite rule.
+(GT4) Consider #25647 (with UnliftedNewtypes)
+         type N :: forall r. (TYPE r -> TYPE r) -> TYPE r
+         newtype N f where { MkN :: ff (N ff) -> N ff }
+    When kind-checking the type signature for MkN we'll start wtih
+           ff :: TYPE kappa -> TYPE kappa
+           MkN :: ff (N @kappa) ff -> N @kappa ff
+    Then we generalise /and default the RuntimeRep variable kappa/
+    (via `kindGeneralizeAll` in `tcConDecl`), thus kappa := LiftedRep
+
+    But now the newtype looks like a GADT and we get an error
+         A newtype must not be a GADT
+
+    This seems OK.  We are just following the rules.
+
+    But this variant (the original report in #25647)
+       data family Fix2 :: (k -> Type) -> k
+       newtype instance Fix2 f where { In2 :: f (Fix2 f) -> Fix2 f }
+    At the `newtype instance`, we first
+       1. Find the kind of the newtype instance in `tcDataFamInstHeader`
+       2. Typecheck the newtype definitition itself in `tcConDecl`
+    In step 1 we do /not/ want to get
+       newtype instance forall r .  Fix2 (f :: TYPE r -> TYPE r) :: TYPE r where
+    If we do, we'll get that same "newtype must not be GADT" error as for N above.
+    Rather, we want to default the RuntimeRep variable r := LiftedRep. Hence
+    the use of `DefaultNonStandardTyVars` in `tcDataFamInstHeader`.  The key thing
+    is that we must make the /same/ choice here as we do in kind-checking the data
+    constructor's type.
+
+See also Note [Re-quantify type variables in rules] in GHC.Tc.Gen.Rule, which
+explains a /very/ similar design when generalising over the type of a rewrite
+rule.
 
 -}
 
@@ -3423,7 +3451,7 @@ tcTyFamInstEqnGuts fam_tc mb_clsinfo outer_hs_bndrs hs_pats hs_rhs_ty
 
        -- See Note [Generalising in tcTyFamInstEqnGuts]
        ; dvs  <- candidateQTyVarsWithBinders outer_tvs lhs_ty
-       ; qtvs <- quantifyTyVars skol_info TryNotToDefaultNonStandardTyVars dvs
+       ; qtvs <- quantifyTyVars skol_info DefaultNonStandardTyVars dvs
        ; let final_tvs = scopedSort (qtvs ++ outer_tvs)
              -- This scopedSort is important: the qtvs may be /interleaved/ with
              -- the outer_tvs.  See Note [Generalising in tcTyFamInstEqnGuts]
@@ -3753,23 +3781,30 @@ tcConDecl new_or_data dd_info rep_tycon tc_bndrs res_kind tag_map
 
        ; return (NE.singleton dc) }
 
-tcConDecl new_or_data dd_info rep_tycon tc_bndrs _res_kind tag_map
-  -- NB: don't use res_kind here, as it's ill-scoped. Instead,
+tcConDecl new_or_data dd_info rep_tycon tc_bndrs _tc_res_kind tag_map
+  -- NB: don't use _tc_res_kind here, as it's ill-scoped. Instead,
   -- we get the res_kind by typechecking the result type.
           (ConDeclGADT { con_names = names
                        , con_bndrs = L _ outer_hs_bndrs
                        , con_mb_cxt = cxt, con_g_args = hs_args
                        , con_res_ty = hs_res_ty })
   = addErrCtxt (DataConDefCtxt names) $
-    do { traceTc "tcConDecl 1 gadt" (ppr names)
+    do { traceTc "tcConDecl 1 gadt" (ppr names $$ ppr _tc_res_kind)
        ; let L _ name :| _ = names
        ; skol_info <- mkSkolemInfo (DataConSkol name)
-       ; (tclvl, wanted, (outer_bndrs, (ctxt, arg_tys, res_ty, field_lbls, stricts)))
+       ; (tclvl, wanted, (outer_bndrs, (ctxt, arg_tys, res_ty, field_lbls, stricts, res_kind)))
            <- pushLevelAndSolveEqualitiesX "tcConDecl:GADT" $
               tcOuterTKBndrs skol_info outer_hs_bndrs       $
               do { ctxt <- tcHsContext cxt
+
                  ; (res_ty, res_kind) <- tcInferLHsTypeKind hs_res_ty
-                         -- See Note [GADT return kinds]
+                              -- See Note [GADT return kinds]
+
+                   -- See Note [Datatype return kinds]
+                 ; let exp_kind = getArgExpKind new_or_data res_kind
+                 ; btys <- tcConGADTArgs exp_kind hs_args
+
+                 ; traceTc "tcConDecl 1a gadt" (ppr res_ty <+> dcolon <+> ppr res_kind)
 
                  -- For data instances (only), ensure that the return type,
                  -- res_ty, is a substitution instance of the header.
@@ -3784,13 +3819,9 @@ tcConDecl new_or_data dd_info rep_tycon tc_bndrs _res_kind tag_map
                              addErrCtxt (DataConResTyCtxt names) $
                              unifyType Nothing res_ty head_shape }
 
-                   -- See Note [Datatype return kinds]
-                 ; let exp_kind = getArgExpKind new_or_data res_kind
-                 ; btys <- tcConGADTArgs exp_kind hs_args
-
                  ; let (arg_tys, stricts) = unzip btys
                  ; field_lbls <- lookupConstructorFields name
-                 ; return (ctxt, arg_tys, res_ty, field_lbls, stricts)
+                 ; return (ctxt, arg_tys, res_ty, field_lbls, stricts, res_kind)
                  }
 
        ; outer_bndrs <- scopedSortOuter outer_bndrs
@@ -3801,7 +3832,10 @@ tcConDecl new_or_data dd_info rep_tycon tc_bndrs _res_kind tag_map
                      tcMkPhiTy ctxt                  $
                      tcMkScaledFunTys arg_tys        $
                      res_ty)
-       ; traceTc "tcConDecl:GADT" (ppr names $$ ppr res_ty $$ ppr tkvs)
+       ; traceTc "tcConDecl:GADT" (vcat [ text "names:" <+> ppr names
+                                        , text "tkvs:" <+> ppr tkvs
+                                        , text "res_ty:" <+> ppr res_ty
+                                        , text "res_kind:" <+> ppr res_kind ])
        ; reportUnsolvedEqualities skol_info tkvs tclvl wanted
 
        ; let tvbndrs =  mkTyVarBinders InferredSpec tkvs ++ outer_tv_bndrs


=====================================
compiler/GHC/Tc/TyCl/Instance.hs
=====================================
@@ -790,10 +790,10 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env
               , text "eta_tcbs" <+> ppr eta_tcbs ]
        ; (rep_tc, (axiom, ax_rhs)) <- fixM $ \ ~(rec_rep_tc, _) ->
            do { data_cons <- tcExtendTyVarEnv (binderVars tc_ty_binders) $
-                  -- For H98 decls, the tyvars scope
-                  -- over the data constructors
-                  tcConDecls (DDataInstance orig_res_ty) rec_rep_tc tc_ty_binders tc_res_kind
-                      hs_cons
+                             -- tcExtendTyVarEnv: for H98 decls, the tyvars
+                             -- scope over the data constructors
+                             tcConDecls (DDataInstance orig_res_ty) rec_rep_tc
+                                        tc_ty_binders tc_res_kind hs_cons
 
               ; rep_tc_name <- newFamInstTyConName lfam_name pats
               ; axiom_name  <- newFamInstAxiomName lfam_name [pats]
@@ -943,11 +943,6 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity
                   -- with its parent class
                   ; addConsistencyConstraints mb_clsinfo lhs_ty
 
-                  -- Add constraints from the data constructors
-                  -- Fix #25611
-                  -- See DESIGN CHOICE in Note [Kind inference for data family instances]
-                  ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons
-
                   -- Check that the result kind of the TyCon applied to its args
                   -- is compatible with the explicit signature (or Type, if there
                   -- is none)
@@ -956,6 +951,11 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity
                   ; res_kind <- tc_kind_sig m_ksig
                   ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind
 
+                  -- Add constraints from the data constructors
+                  -- Fix #25611
+                  -- See DESIGN CHOICE in Note [Kind inference for data family instances]
+                  ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons
+
                   ; traceTc "tcDataFamInstHeader" $
                     vcat [ ppr fam_tc, ppr m_ksig, ppr lhs_applied_kind, ppr res_kind, ppr m_ksig]
                   ; return ( stupid_theta
@@ -975,7 +975,10 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity
 
        -- See GHC.Tc.TyCl Note [Generalising in tcTyFamInstEqnGuts]
        ; dvs  <- candidateQTyVarsWithBinders outer_tvs lhs_ty
-       ; qtvs <- quantifyTyVars skol_info TryNotToDefaultNonStandardTyVars dvs
+       ; qtvs <- quantifyTyVars skol_info DefaultNonStandardTyVars dvs
+                 -- DefaultNonStandardTyVars: see (GT4) in
+                 -- GHC.Tc.TyCl Note [Generalising in tcTyFamInstEqnGuts]
+
        ; let final_tvs = scopedSort (qtvs ++ outer_tvs)
              -- This scopedSort is important: the qtvs may be /interleaved/ with
              -- the outer_tvs.  See Note [Generalising in tcTyFamInstEqnGuts]
@@ -999,7 +1002,7 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity
 
        -- Split up the LHS type to get the type patterns
        -- For the scopedSort see Note [Generalising in tcTyFamInstEqnGuts]
-       ; let pats      = unravelFamInstPats lhs_ty
+       ; let pats = unravelFamInstPats lhs_ty
 
        ; return (final_tvs, mkVarSet non_user_tvs, pats, master_res_kind, stupid_theta) }
   where


=====================================
compiler/GHC/Tc/Utils/TcMType.hs
=====================================
@@ -34,7 +34,8 @@ module GHC.Tc.Utils.TcMType (
 
   newMultiplicityVar,
   readMetaTyVar, writeMetaTyVar, writeMetaTyVarRef,
-  newTauTvDetailsAtLevel, newMetaDetails, newMetaTyVarName,
+  newWildCardTvDetailsAtLevel, newTauTvDetailsAtLevel,
+  newMetaDetails, newMetaTyVarName,
   isFilledMetaTyVar_maybe, isFilledMetaTyVar, isUnfilledMetaTyVar,
 
   --------------------------------
@@ -692,6 +693,16 @@ the thinking.
 *                                                                      *
 ********************************************************************* -}
 
+{- Note [WildCardTv]
+~~~~~~~~~~~~~~~~~
+A WildCardTv behaves like a TauTv, except that it can not be defaulted.
+
+It is used for a anonymous wildcard in a type signature, e.g.
+  f :: _ -> Int
+  f = ...
+
+-}
+
 {- Note [TyVarTv]
 ~~~~~~~~~~~~~~~~~
 A TyVarTv can unify with type *variables* only, including other TyVarTvs and
@@ -740,6 +751,7 @@ metaInfoToTyVarName :: MetaInfo -> FastString
 metaInfoToTyVarName  meta_info =
   case meta_info of
        TauTv          -> fsLit "t"
+       WildCardTv     -> fsLit "_"
        TyVarTv        -> fsLit "a"
        RuntimeUnkTv   -> fsLit "r"
        CycleBreakerTv -> fsLit "b"
@@ -853,6 +865,13 @@ newTauTvDetailsAtLevel tclvl
                         , mtv_ref   = ref
                         , mtv_tclvl = tclvl }) }
 
+newWildCardTvDetailsAtLevel :: TcLevel -> TcM TcTyVarDetails
+newWildCardTvDetailsAtLevel tclvl
+  = do { ref <- newMutVar Flexi
+       ; return (MetaTv { mtv_info  = WildCardTv
+                        , mtv_ref   = ref
+                        , mtv_tclvl = tclvl }) }
+
 newConcreteTvDetailsAtLevel :: ConcreteTvOrigin -> TcLevel -> TcM TcTyVarDetails
 newConcreteTvDetailsAtLevel conc_orig tclvl
   = do { ref <- newMutVar Flexi
@@ -1841,7 +1860,10 @@ defaultTyVar :: DefaultingStrategy
              -> TcTyVar    -- If it's a MetaTyVar then it is unbound
              -> TcM Bool   -- True <=> defaulted away altogether
 defaultTyVar def_strat tv
-  | not (isMetaTyVar tv)
+  | not (isMetaTyVar tv )
+  || isWildCardMetaTyVar tv
+    -- do not default WildcardTvs, wildcardTvs are are only meant to be unified
+    -- or be on its own but never defaulted.
   || isTyVarTyVar tv
     -- Do not default TyVarTvs. Doing so would violate the invariants
     -- on TyVarTvs; see Note [TyVarTv] in GHC.Tc.Utils.TcMType.


=====================================
compiler/GHC/Tc/Utils/TcType.hs
=====================================
@@ -51,7 +51,8 @@ module GHC.Tc.Utils.TcType (
   TcTyVarDetails(..), pprTcTyVarDetails, vanillaSkolemTvUnk,
   MetaDetails(Flexi, Indirect), MetaInfo(..), skolemSkolInfo,
   isImmutableTyVar, isSkolemTyVar, isMetaTyVar,  isMetaTyVarTy, isTyVarTy,
-  tcIsTcTyVar, isTyVarTyVar, isOverlappableTyVar,  isTyConableTyVar,
+  isWildCardMetaTyVar, tcIsTcTyVar, isTyVarTyVar, isOverlappableTyVar,
+  isTyConableTyVar,
   ConcreteTvOrigin(..), isConcreteTyVar_maybe, isConcreteTyVar,
   isConcreteTyVarTy, isConcreteTyVarTy_maybe, concreteInfo_maybe,
   ConcreteTyVars, noConcreteTyVars,
@@ -640,7 +641,8 @@ data MetaInfo
    = TauTv         -- ^ This MetaTv is an ordinary unification variable
                    -- A TauTv is always filled in with a tau-type, which
                    -- never contains any ForAlls.
-
+   | WildCardTv    -- ^ A variant of TauTv, except that it should not be
+                   -- defaulted.
    | TyVarTv       -- ^ A variant of TauTv, except that it should not be
                    --   unified with a type, only with a type variable
                    -- See Note [TyVarTv] in GHC.Tc.Utils.TcMType
@@ -670,6 +672,8 @@ instance Outputable MetaInfo where
   ppr RuntimeUnkTv    = text "rutv"
   ppr CycleBreakerTv  = text "cbv"
   ppr (ConcreteTv {}) = text "conc"
+  ppr (WildCardTv)    = text "wc"
+
 
 -- | What caused us to create a 'ConcreteTv' metavariable?
 -- See Note [ConcreteTv] in GHC.Tc.Utils.Concrete.
@@ -1179,7 +1183,7 @@ isImmutableTyVar :: TyVar -> Bool
 isImmutableTyVar tv = isSkolemTyVar tv
 
 isTyConableTyVar, isSkolemTyVar, isOverlappableTyVar,
-  isMetaTyVar, isAmbiguousTyVar, isCycleBreakerTyVar :: TcTyVar -> Bool
+  isMetaTyVar, isAmbiguousTyVar, isCycleBreakerTyVar, isWildCardMetaTyVar :: TcTyVar -> Bool
 
 isTyConableTyVar tv
         -- True of a meta-type variable that can be filled in
@@ -1220,6 +1224,13 @@ isMetaTyVar tv
         _         -> False
   | otherwise = False
 
+isWildCardMetaTyVar tv
+  | isTyVar tv -- See Note [Coercion variables in free variable lists]
+  = case tcTyVarDetails tv of
+        MetaTv { mtv_info = WildCardTv } -> True
+        _                                 -> False
+  | otherwise = False
+
 -- isAmbiguousTyVar is used only when reporting type errors
 -- It picks out variables that are unbound, namely meta
 -- type variables and the RuntimeUnk variables created by


=====================================
compiler/GHC/Tc/Utils/Unify.hs
=====================================
@@ -2574,8 +2574,9 @@ lhsPriority tv
              CycleBreakerTv -> 0
              TyVarTv        -> 1
              ConcreteTv {}  -> 2
-             TauTv          -> 3
-             RuntimeUnkTv   -> 4
+             WildCardTv     -> 3
+             TauTv          -> 4
+             RuntimeUnkTv   -> 5
 
 {- Note [Unification preconditions]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


=====================================
compiler/Language/Haskell/Syntax/Decls.hs
=====================================
@@ -809,9 +809,11 @@ data HsDataDefn pass   -- The payload of a data type defn
                        --       *and* for data family instances
   = -- | Declares a data type or newtype, giving its constructors
     -- @
-    --  data/newtype T a = <constrs>
-    --  data/newtype instance T [a] = <constrs>
+    --  data/newtype T a :: ksig = <constrs>
+    --  data/newtype instance T [a] :: ksig = <constrs>
     -- @
+    -- The HsDataDefn describes the (optional) kind signature and the <constrs>
+    -- but not the `data T a` or `newtype T [a]` headers
     HsDataDefn { dd_ext    :: XCHsDataDefn pass,
                  dd_ctxt   :: Maybe (LHsContext pass), -- ^ Context
                  dd_cType  :: Maybe (XRec pass CType),


=====================================
libraries/base/changelog.md
=====================================
@@ -10,6 +10,13 @@
   * `Data.List.NonEmpty` functions now have the same laziness as their `Data.List` counterparts (i.e. make them more strict than they currently are) ([CLC proposal #107](https://github.com/haskell/core-libraries-committee/issues/107))
   * `instance Functor NonEmpty` is now specified using `map` (rather than duplicating code). ([CLC proposal #300](https://github.com/haskell/core-libraries-committee/issues/300))
   * The `Data.Enum.enumerate` function was introduced ([CLC #306](https://github.com/haskell/core-libraries-committee/issues/306))
+  * Worker threads used by various `base` facilities are now labelled with descriptive thread labels ([CLC proposal #305](https://github.com/haskell/core-libraries-committee/issues/305), [GHC #25452](https://gitlab.haskell.org/ghc/ghc/-/issues/25452)). Specifically, these include:
+    * `Control.Concurrent.threadWaitRead`
+    * `Control.Concurrent.threadWaitWrite`
+    * `Control.Concurrent.threadWaitReadSTM`
+    * `Control.Concurrent.threadWaitWriteSTM`
+    * `System.Timeout.timeout`
+    * `GHC.Conc.Signal.runHandlers`
 
 ## 4.21.0.0 *TBA*
   * Change `SrcLoc` to be a strict and unboxed (finishing [CLC proposal #55](https://github.com/haskell/core-libraries-committee/issues/55))


=====================================
libraries/base/src/Control/Concurrent.hs
=====================================
@@ -265,7 +265,7 @@ threadWaitRead fd
   -- fdReady does the right thing, but we have to call it in a
   -- separate thread, otherwise threadWaitRead won't be interruptible,
   -- and this only works with -threaded.
-  | threaded  = withThread (waitFd fd False)
+  | threaded  = withThread "threadWaitRead worker" (waitFd fd False)
   | otherwise = case fd of
                   0 -> do _ <- hWaitForInput stdin (-1)
                           return ()
@@ -286,7 +286,7 @@ threadWaitRead fd
 threadWaitWrite :: Fd -> IO ()
 threadWaitWrite fd
 #if defined(mingw32_HOST_OS)
-  | threaded  = withThread (waitFd fd True)
+  | threaded  = withThread "threadWaitWrite worker" (waitFd fd True)
   | otherwise = errorWithoutStackTrace "threadWaitWrite requires -threaded on Windows"
 #else
   = Conc.threadWaitWrite fd
@@ -302,8 +302,11 @@ threadWaitReadSTM :: Fd -> IO (STM (), IO ())
 threadWaitReadSTM fd
 #if defined(mingw32_HOST_OS)
   | threaded = do v <- newTVarIO Nothing
-                  mask_ $ void $ forkIO $ do result <- try (waitFd fd False)
-                                             atomically (writeTVar v $ Just result)
+                  mask_ $ void $ forkIO $ do
+                    tid <- myThreadId
+                    labelThread tid "threadWaitReadSTM worker"
+                    result <- try (waitFd fd False)
+                    atomically (writeTVar v $ Just result)
                   let waitAction = do result <- readTVar v
                                       case result of
                                         Nothing         -> retry
@@ -326,8 +329,11 @@ threadWaitWriteSTM :: Fd -> IO (STM (), IO ())
 threadWaitWriteSTM fd
 #if defined(mingw32_HOST_OS)
   | threaded = do v <- newTVarIO Nothing
-                  mask_ $ void $ forkIO $ do result <- try (waitFd fd True)
-                                             atomically (writeTVar v $ Just result)
+                  mask_ $ void $ forkIO $ do
+                    tid <- myThreadId
+                    labelThread tid "threadWaitWriteSTM worker"
+                    result <- try (waitFd fd True)
+                    atomically (writeTVar v $ Just result)
                   let waitAction = do result <- readTVar v
                                       case result of
                                         Nothing         -> retry
@@ -343,10 +349,14 @@ threadWaitWriteSTM fd
 #if defined(mingw32_HOST_OS)
 foreign import ccall unsafe "rtsSupportsBoundThreads" threaded :: Bool
 
-withThread :: IO a -> IO a
-withThread io = do
+withThread :: String -> IO a -> IO a
+withThread label io = do
   m <- newEmptyMVar
-  _ <- mask_ $ forkIO $ try io >>= putMVar m
+  _ <- mask_ $ forkIO $ do
+    tid <- myThreadId
+    labelThread tid label
+    result <- try io
+    putMVar m result
   x <- takeMVar m
   case x of
     Right a -> return a


=====================================
libraries/base/src/System/Timeout.hs
=====================================
@@ -1,5 +1,5 @@
 {-# LANGUAGE CPP #-}
-{-# LANGUAGE Safe #-}
+{-# LANGUAGE Trustworthy #-}
 
 -------------------------------------------------------------------------------
 -- |
@@ -29,6 +29,7 @@ import GHC.Internal.Control.Exception   (Exception(..), handleJust, bracket,
                             asyncExceptionToException,
                             asyncExceptionFromException)
 import GHC.Internal.Data.Unique         (Unique, newUnique)
+import GHC.Conc (labelThread)
 import Prelude
 
 -- $setup
@@ -119,7 +120,9 @@ timeout n f
         let handleTimeout = do
                 v <- isEmptyMVar lock
                 when v $ void $ forkIOWithUnmask $ \unmask -> unmask $ do
-                    v2 <- tryPutMVar lock =<< myThreadId
+                    tid <- myThreadId
+                    labelThread tid "timeout worker"
+                    v2 <- tryPutMVar lock tid
                     when v2 $ throwTo pid ex
             cleanupTimeout key = uninterruptibleMask_ $ do
                 v <- tryPutMVar lock undefined
@@ -136,7 +139,9 @@ timeout n f
         ex  <- fmap Timeout newUnique
         handleJust (\e -> if e == ex then Just () else Nothing)
                    (\_ -> return Nothing)
-                   (bracket (forkIOWithUnmask $ \unmask ->
+                   (bracket (forkIOWithUnmask $ \unmask -> do
+                                 tid <- myThreadId
+                                 labelThread tid "timeout worker"
                                  unmask $ threadDelay n >> throwTo pid ex)
                             (uninterruptibleMask_ . killThread)
                             (\_ -> fmap Just f))


=====================================
libraries/ghc-internal/src/GHC/Internal/Conc/Signal.hs
=====================================
@@ -19,7 +19,7 @@ import GHC.Internal.Foreign.Ptr (Ptr, castPtr)
 import GHC.Internal.Foreign.Marshal.Alloc (finalizerFree)
 import GHC.Internal.Arr (inRange)
 import GHC.Internal.Base
-import GHC.Internal.Conc.Sync (forkIO)
+import GHC.Internal.Conc.Sync (myThreadId, labelThread, forkIO)
 import GHC.Internal.IO (mask_, unsafePerformIO)
 import GHC.Internal.IOArray (IOArray, boundsIOArray, newIOArray,
                     unsafeReadIOArray, unsafeWriteIOArray)
@@ -69,7 +69,10 @@ runHandlers p_info sig = do
       else do handler <- unsafeReadIOArray arr int
               case handler of
                 Nothing -> return ()
-                Just (f,_)  -> do _ <- forkIO (f p_info)
+                Just (f,_)  -> do _ <- forkIO $ do
+                                    tid <- myThreadId
+                                    labelThread tid "signal handler"
+                                    f p_info
                                   return ()
 
 -- It is our responsibility to free the memory buffer, so we create a


=====================================
libraries/ghc-internal/src/GHC/Internal/Event/Windows/ConsoleEvent.hsc
=====================================
@@ -53,7 +53,10 @@ start_console_handler :: Word32 -> IO ()
 start_console_handler r =
   case toWin32ConsoleEvent r of
     Just x  -> withMVar win32ConsoleHandler $ \handler -> do
-                 _ <- forkIO (handler x)
+                 _ <- forkIO $ do
+                     tid <- myThreadId
+                     labelThread tid "console event handler"
+                     handler x
                  return ()
     Nothing -> return ()
 


=====================================
libraries/ghci/GHCi/Run.hs
=====================================
@@ -226,7 +226,10 @@ sandboxIO opts io = do
     let runIt = measureAlloc $ tryEval $ rethrow opts $ clearCCS io
     if useSandboxThread opts
        then do
-         tid <- forkIO $ do unsafeUnmask runIt >>= putMVar statusMVar
+         tid <- forkIO $ do
+           tid <- myThreadId
+           labelThread tid "GHCi sandbox"
+           unsafeUnmask runIt >>= putMVar statusMVar
                                 -- empty: can't block
          redirectInterrupts tid $ unsafeUnmask $ takeMVar statusMVar
        else


=====================================
testsuite/tests/indexed-types/should_compile/T11450a.hs
=====================================
@@ -0,0 +1,9 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module T11450a where
+
+class C x where
+  type T x
+
+instance C (Either a b) where
+  type T (Either _ b) = b -> b


=====================================
testsuite/tests/indexed-types/should_compile/T25611d.hs
=====================================
@@ -20,7 +20,7 @@ data instance T p q where
       MkkV :: forall l. l Int# -> T l Int#
 
 type N :: TYPE r -> TYPE r
-newtype N a = MkN a
+newtype N (a::TYPE r) = MkN a
 
 f :: Int# -> N Int#
 f x = MkN x
@@ -29,7 +29,7 @@ g :: Int -> N Int
 g x = MkN x
 
 data family D :: Type -> k -> k
-newtype instance D Int a = MkD a
+newtype instance D Int (a::TYPE r) = MkD a
 
 f1 :: Int# -> D Int Int#
 f1 x = MkD x


=====================================
testsuite/tests/indexed-types/should_compile/all.T
=====================================
@@ -315,3 +315,4 @@ test('T25611a', normal, compile, [''])
 test('T25611b', normal, compile, [''])
 test('T25611c', normal, compile, [''])
 test('T25611d', normal, compile, [''])
+test('T11450a', normal, compile, [''])


=====================================
testsuite/tests/indexed-types/should_fail/T9357.stderr
=====================================
@@ -1,4 +1,4 @@
 T9357.hs:12:15: error: [GHC-91510]
-    • Illegal polymorphic type: forall (a :: TYPE t). a -> a
+     Illegal polymorphic type: forall a. a -> a
     • In the type family instance declaration for ‘F’
 


=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -10619,7 +10619,7 @@ module System.Posix.Types where
 
 
 module System.Timeout where
-  -- Safety: Safe
+  -- Safety: Trustworthy
   type Timeout :: *
   newtype Timeout = ...
   timeout :: forall a. GHC.Internal.Types.Int -> GHC.Internal.Types.IO a -> GHC.Internal.Types.IO (GHC.Internal.Maybe.Maybe a)
@@ -11736,7 +11736,7 @@ instance forall (c :: GHC.Internal.Types.Char). GHC.Internal.Classes.Eq (GHC.Int
 instance forall (s :: GHC.Internal.Types.Symbol). GHC.Internal.Classes.Eq (GHC.Internal.TypeLits.SSymbol s) -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Classes.Eq GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Classes.Eq GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
-instance [safe] GHC.Internal.Classes.Eq System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Classes.Eq System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance GHC.Internal.Classes.Eq GHC.Internal.Text.Read.Lex.Lexeme -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance GHC.Internal.Classes.Eq GHC.Internal.Text.Read.Lex.Number -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance forall a. GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Base’
@@ -12349,7 +12349,7 @@ instance GHC.Internal.Exception.Type.Exception GHC.Internal.Control.Exception.Ba
 instance GHC.Internal.Exception.Type.Exception GHC.Internal.Data.Dynamic.Dynamic -- Defined in ‘GHC.Internal.Data.Dynamic’
 instance [safe] GHC.Internal.Exception.Type.Exception ghc-internal-9.1300.0:GHC.Internal.IO.Handle.Lock.Common.FileLockingNotSupported -- Defined in ‘ghc-internal-9.1300.0:GHC.Internal.IO.Handle.Lock.Common’
 instance GHC.Internal.Exception.Type.Exception GHC.Internal.IOPort.IOPortException -- Defined in ‘GHC.Internal.IOPort’
-instance [safe] GHC.Internal.Exception.Type.Exception System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Exception.Type.Exception System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance forall a k (b :: k). GHC.Internal.Float.Floating a => GHC.Internal.Float.Floating (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’
 instance forall a. GHC.Internal.Float.RealFloat a => GHC.Internal.Float.Floating (Data.Complex.Complex a) -- Defined in ‘Data.Complex’
 instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Internal.Float.Floating (f (g a)) => GHC.Internal.Float.Floating (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’
@@ -13204,7 +13204,7 @@ instance forall (c :: GHC.Internal.Types.Char). GHC.Internal.Show.Show (GHC.Inte
 instance forall (s :: GHC.Internal.Types.Symbol). GHC.Internal.Show.Show (GHC.Internal.TypeLits.SSymbol s) -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Show.Show GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Show.Show GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
-instance [safe] GHC.Internal.Show.Show System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Show.Show System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance GHC.Internal.Show.Show GHC.Internal.Text.Read.Lex.Lexeme -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance GHC.Internal.Show.Show GHC.Internal.Text.Read.Lex.Number -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance [safe] forall a b. GHC.Internal.Show.Show (a -> b) -- Defined in ‘Text.Show.Functions’


=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -13664,7 +13664,7 @@ module System.Posix.Types where
 
 
 module System.Timeout where
-  -- Safety: Safe
+  -- Safety: Trustworthy
   type Timeout :: *
   newtype Timeout = ...
   timeout :: forall a. GHC.Internal.Types.Int -> GHC.Internal.Types.IO a -> GHC.Internal.Types.IO (GHC.Internal.Maybe.Maybe a)
@@ -14770,7 +14770,7 @@ instance forall (c :: GHC.Internal.Types.Char). GHC.Internal.Classes.Eq (GHC.Int
 instance forall (s :: GHC.Internal.Types.Symbol). GHC.Internal.Classes.Eq (GHC.Internal.TypeLits.SSymbol s) -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Classes.Eq GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Classes.Eq GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
-instance [safe] GHC.Internal.Classes.Eq System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Classes.Eq System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance GHC.Internal.Classes.Eq GHC.Internal.Text.Read.Lex.Lexeme -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance GHC.Internal.Classes.Eq GHC.Internal.Text.Read.Lex.Number -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance forall a. GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Base’
@@ -15385,7 +15385,7 @@ instance [safe] GHC.Internal.Exception.Type.Exception ghc-internal-9.1300.0:GHC.
 instance GHC.Internal.Exception.Type.Exception GHC.Internal.IOPort.IOPortException -- Defined in ‘GHC.Internal.IOPort’
 instance GHC.Internal.Exception.Type.Exception GHC.Internal.JS.Prim.JSException -- Defined in ‘GHC.Internal.JS.Prim’
 instance GHC.Internal.Exception.Type.Exception GHC.Internal.JS.Prim.WouldBlockException -- Defined in ‘GHC.Internal.JS.Prim’
-instance [safe] GHC.Internal.Exception.Type.Exception System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Exception.Type.Exception System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance forall a k (b :: k). GHC.Internal.Float.Floating a => GHC.Internal.Float.Floating (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’
 instance forall a. GHC.Internal.Float.RealFloat a => GHC.Internal.Float.Floating (Data.Complex.Complex a) -- Defined in ‘Data.Complex’
 instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Internal.Float.Floating (f (g a)) => GHC.Internal.Float.Floating (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’
@@ -16235,7 +16235,7 @@ instance forall (c :: GHC.Internal.Types.Char). GHC.Internal.Show.Show (GHC.Inte
 instance forall (s :: GHC.Internal.Types.Symbol). GHC.Internal.Show.Show (GHC.Internal.TypeLits.SSymbol s) -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Show.Show GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Show.Show GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
-instance [safe] GHC.Internal.Show.Show System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Show.Show System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance GHC.Internal.Show.Show GHC.Internal.Text.Read.Lex.Lexeme -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance GHC.Internal.Show.Show GHC.Internal.Text.Read.Lex.Number -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance [safe] forall a b. GHC.Internal.Show.Show (a -> b) -- Defined in ‘Text.Show.Functions’


=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -10881,7 +10881,7 @@ module System.Posix.Types where
 
 
 module System.Timeout where
-  -- Safety: Safe
+  -- Safety: Trustworthy
   type Timeout :: *
   newtype Timeout = ...
   timeout :: forall a. GHC.Internal.Types.Int -> GHC.Internal.Types.IO a -> GHC.Internal.Types.IO (GHC.Internal.Maybe.Maybe a)
@@ -11992,7 +11992,7 @@ instance forall (c :: GHC.Internal.Types.Char). GHC.Internal.Classes.Eq (GHC.Int
 instance forall (s :: GHC.Internal.Types.Symbol). GHC.Internal.Classes.Eq (GHC.Internal.TypeLits.SSymbol s) -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Classes.Eq GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Classes.Eq GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
-instance [safe] GHC.Internal.Classes.Eq System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Classes.Eq System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance GHC.Internal.Classes.Eq GHC.Internal.Text.Read.Lex.Lexeme -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance GHC.Internal.Classes.Eq GHC.Internal.Text.Read.Lex.Number -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance forall a. GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Base’
@@ -12608,7 +12608,7 @@ instance GHC.Internal.Exception.Type.Exception GHC.Internal.Control.Exception.Ba
 instance GHC.Internal.Exception.Type.Exception GHC.Internal.Data.Dynamic.Dynamic -- Defined in ‘GHC.Internal.Data.Dynamic’
 instance [safe] GHC.Internal.Exception.Type.Exception ghc-internal-9.1300.0:GHC.Internal.IO.Handle.Lock.Common.FileLockingNotSupported -- Defined in ‘ghc-internal-9.1300.0:GHC.Internal.IO.Handle.Lock.Common’
 instance GHC.Internal.Exception.Type.Exception GHC.Internal.IOPort.IOPortException -- Defined in ‘GHC.Internal.IOPort’
-instance [safe] GHC.Internal.Exception.Type.Exception System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Exception.Type.Exception System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance forall a k (b :: k). GHC.Internal.Float.Floating a => GHC.Internal.Float.Floating (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’
 instance forall a. GHC.Internal.Float.RealFloat a => GHC.Internal.Float.Floating (Data.Complex.Complex a) -- Defined in ‘Data.Complex’
 instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Internal.Float.Floating (f (g a)) => GHC.Internal.Float.Floating (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’
@@ -13476,7 +13476,7 @@ instance forall (c :: GHC.Internal.Types.Char). GHC.Internal.Show.Show (GHC.Inte
 instance forall (s :: GHC.Internal.Types.Symbol). GHC.Internal.Show.Show (GHC.Internal.TypeLits.SSymbol s) -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Show.Show GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Show.Show GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
-instance [safe] GHC.Internal.Show.Show System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Show.Show System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance GHC.Internal.Show.Show GHC.Internal.Text.Read.Lex.Lexeme -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance GHC.Internal.Show.Show GHC.Internal.Text.Read.Lex.Number -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance [safe] forall a b. GHC.Internal.Show.Show (a -> b) -- Defined in ‘Text.Show.Functions’


=====================================
testsuite/tests/interface-stability/base-exports.stdout-ws-32
=====================================
@@ -10619,7 +10619,7 @@ module System.Posix.Types where
 
 
 module System.Timeout where
-  -- Safety: Safe
+  -- Safety: Trustworthy
   type Timeout :: *
   newtype Timeout = ...
   timeout :: forall a. GHC.Internal.Types.Int -> GHC.Internal.Types.IO a -> GHC.Internal.Types.IO (GHC.Internal.Maybe.Maybe a)
@@ -11736,7 +11736,7 @@ instance forall (c :: GHC.Internal.Types.Char). GHC.Internal.Classes.Eq (GHC.Int
 instance forall (s :: GHC.Internal.Types.Symbol). GHC.Internal.Classes.Eq (GHC.Internal.TypeLits.SSymbol s) -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Classes.Eq GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Classes.Eq GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
-instance [safe] GHC.Internal.Classes.Eq System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Classes.Eq System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance GHC.Internal.Classes.Eq GHC.Internal.Text.Read.Lex.Lexeme -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance GHC.Internal.Classes.Eq GHC.Internal.Text.Read.Lex.Number -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance forall a. GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Base’
@@ -12349,7 +12349,7 @@ instance GHC.Internal.Exception.Type.Exception GHC.Internal.Control.Exception.Ba
 instance GHC.Internal.Exception.Type.Exception GHC.Internal.Data.Dynamic.Dynamic -- Defined in ‘GHC.Internal.Data.Dynamic’
 instance [safe] GHC.Internal.Exception.Type.Exception ghc-internal-9.1300.0:GHC.Internal.IO.Handle.Lock.Common.FileLockingNotSupported -- Defined in ‘ghc-internal-9.1300.0:GHC.Internal.IO.Handle.Lock.Common’
 instance GHC.Internal.Exception.Type.Exception GHC.Internal.IOPort.IOPortException -- Defined in ‘GHC.Internal.IOPort’
-instance [safe] GHC.Internal.Exception.Type.Exception System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Exception.Type.Exception System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance forall a k (b :: k). GHC.Internal.Float.Floating a => GHC.Internal.Float.Floating (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’
 instance forall a. GHC.Internal.Float.RealFloat a => GHC.Internal.Float.Floating (Data.Complex.Complex a) -- Defined in ‘Data.Complex’
 instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Internal.Float.Floating (f (g a)) => GHC.Internal.Float.Floating (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’
@@ -13204,7 +13204,7 @@ instance forall (c :: GHC.Internal.Types.Char). GHC.Internal.Show.Show (GHC.Inte
 instance forall (s :: GHC.Internal.Types.Symbol). GHC.Internal.Show.Show (GHC.Internal.TypeLits.SSymbol s) -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Show.Show GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
 instance GHC.Internal.Show.Show GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
-instance [safe] GHC.Internal.Show.Show System.Timeout.Timeout -- Defined in ‘System.Timeout’
+instance GHC.Internal.Show.Show System.Timeout.Timeout -- Defined in ‘System.Timeout’
 instance GHC.Internal.Show.Show GHC.Internal.Text.Read.Lex.Lexeme -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance GHC.Internal.Show.Show GHC.Internal.Text.Read.Lex.Number -- Defined in ‘GHC.Internal.Text.Read.Lex’
 instance [safe] forall a b. GHC.Internal.Show.Show (a -> b) -- Defined in ‘Text.Show.Functions’


=====================================
testsuite/tests/rename/should_fail/T23512a.stderr
=====================================
@@ -1,6 +1,3 @@
-
 T23512a.hs:6:31: error: [GHC-76037] Not in scope: type variable ‘j’
 
 T23512a.hs:6:36: error: [GHC-76037] Not in scope: type variable ‘j’
-
-T23512a.hs:9:20: error: [GHC-76037] Not in scope: type variable ‘k’


=====================================
testsuite/tests/typecheck/should_compile/T25647_fail.hs
=====================================
@@ -0,0 +1,21 @@
+{-# LANGUAGE DataKinds, UnliftedNewtypes, TypeFamilies, PolyKinds, MagicHash #-}
+
+module T25647_fail where
+
+import GHC.Exts
+import Data.Kind
+
+-- Rejected because in the type signature for In2 we default
+-- the runtime-rep variable to LiftedRep, and that makes In2
+-- into a GADT
+newtype Fix2 f :: TYPE r where
+   In2 :: forall ff. ff (Fix2 ff) -> Fix2 ff
+
+-- Rejected for the same reason
+type Fix4a :: forall r. (TYPE r -> TYPE r) -> TYPE r
+newtype Fix4a f where
+  In4a :: ff (Fix4a ff) -> Fix4a ff
+
+data family Dix6 :: (k -> TYPE 'IntRep) -> k
+newtype instance Dix6 f where
+  DIn6 :: forall ff. ff (Dix6 ff) -> Dix6 ff


=====================================
testsuite/tests/typecheck/should_compile/T25647_fail.stderr
=====================================
@@ -0,0 +1,23 @@
+T25647_fail.hs:12:4: [GHC-89498]
+     A newtype must not be a GADT
+      In2 :: forall (ff :: * -> *).
+             ff (Fix2 @LiftedRep ff) -> Fix2 @LiftedRep ff
+     In the definition of data constructor ‘In2’
+      In the newtype declaration for ‘Fix2’
+
+T25647_fail.hs:17:3: [GHC-89498]
+     A newtype must not be a GADT
+      In4a :: forall (ff :: * -> *).
+              ff (Fix4a @LiftedRep ff) -> Fix4a @LiftedRep ff
+     In the definition of data constructor ‘In4a’
+      In the newtype declaration for ‘Fix4a’
+
+T25647_fail.hs:21:3: [GHC-18872]
+     Couldn't match a lifted type with an unlifted type
+      When matching types
+        ff :: TYPE IntRep -> TYPE IntRep
+        f0 :: * -> TYPE IntRep
+      Expected: Dix6 f0
+        Actual: Dix6 ff
+     In the result type of data constructor ‘DIn6’
+      In the newtype family instance declaration for ‘Dix6’
\ No newline at end of file


=====================================
testsuite/tests/typecheck/should_compile/T25647a.hs
=====================================
@@ -0,0 +1,92 @@
+{-# LANGUAGE DataKinds, UnliftedNewtypes, TypeFamilies, PolyKinds, MagicHash #-}
+
+module T25647a where
+
+import GHC.Exts
+import Data.Kind
+
+-------------------- Plain newtypes -----------------
+
+-- A plain newtype, H98
+-- Defaulting happens; infers Fix1 :: forall k. (k -> Type) -> Type
+newtype Fix1a f = In1a (f (Fix1a f))
+
+-- A plain newtype, GADT syntax
+-- Defaulting happens; infers Fix1 :: forall k. (k -> Type) -> Type
+newtype Fix1b f where
+    In1b :: forall ff. ff (Fix1b ff) -> Fix1b ff
+
+-- A plain newtype, GADT syntax, with a return kind signature,
+-- and runtime-rep quantification in the data constructor
+-- Should infer Fix2 :: forall r k. (k -> TYPE r) -> TYPE r
+newtype Fix2 f :: TYPE r where
+   In2 :: forall r (ff :: TYPE r -> TYPE r). ff (Fix2 ff) -> Fix2 ff
+
+-- Plain newtype, H98 syntax, standalone kind signature
+-- Should get In3 :: forall r (f :: TYPE r -> TYPE r). Fix3 @r f -> Fix3 @r f
+type Fix3 :: forall r. (TYPE r -> TYPE r) -> TYPE r
+newtype Fix3 f = In3 (f (Fix3 f))
+
+-- Plain newtype, H98 syntax, standalone kind signature
+-- Should get In4 :: forall r k (f :: k -> TYPE r). Fix4 @r @k f -> Fix4 @r @k f
+type Fix4 :: forall r. (TYPE r -> TYPE r) -> TYPE r
+newtype Fix4 f where
+  In4 :: forall rr (ff :: TYPE rr -> TYPE rr).
+         ff (Fix4 ff) -> Fix4 @rr ff
+
+-------------------- Data families with newtype instance -----------------
+
+-- data instance in GADT sytntax
+data family Dix1 :: (k -> Type) -> k
+data instance Dix1 f where
+  DIn1 :: forall ff. ff (Dix1 ff) -> Dix1 ff
+
+-- newtype instance in GADT syntax
+data family Dix2 :: (k -> Type) -> k
+newtype instance Dix2 f where
+  DIn2 :: forall ff. ff (Dix2 ff) -> Dix2 ff
+
+data family Dix2a :: (k -> Type) -> k
+newtype instance Dix2a f :: Type where
+  DIn2a :: forall ff. ff (Dix2a ff) -> Dix2a ff
+
+-- newtype instance in H98 syntax
+data family Dix3 :: (k -> Type) -> k
+newtype instance Dix3 f = DIn3 (f (Dix3 f))
+
+-- newtype instance in GADT syntax
+-- The newtype instance defaults to LiftedRep
+data family Dix4 :: (k -> TYPE r) -> k
+newtype instance Dix4 f where
+  DIn4 :: forall ff. ff (Dix4 ff) -> Dix4 ff
+
+-- newtype instance in H98 syntax
+data family Dix5 :: (k -> TYPE r) -> k
+newtype instance Dix5 f = DIn5 (f (Dix5 f))
+
+-- -- newtype instance that is not TYPE 'LiftedRep
+-- data family Dix6 :: (k -> TYPE 'IntRep) -> k
+-- newtype instance Dix6 f where
+--   DIn6 :: forall ff. ff (Dix6 ff) -> Dix6 ff
+
+data family Dix7 :: (k -> TYPE 'IntRep) -> k
+newtype instance Dix7 f = DIn7 (f (Dix7 f))
+
+
+
+-- anonymous wildcards
+type Dix8 :: RuntimeRep -> Type
+data family Dix8 r
+newtype instance Dix8 _ = Dix8 Int
+
+dix8 :: Dix8 FloatRep -> Int
+dix8 (Dix8 x) = x
+
+
+-- named wildcards
+type Dix9 :: RuntimeRep -> Type
+data family Dix9 r
+newtype instance Dix9 _r = Dix9 Int
+
+dix9 :: Dix9 FloatRep -> Int
+dix9 (Dix9 x) = x


=====================================
testsuite/tests/typecheck/should_compile/T25647b.hs
=====================================
@@ -0,0 +1,65 @@
+{-# LANGUAGE DataKinds, TypeFamilies, PolyKinds, MagicHash #-}
+
+module T25647b where
+
+import GHC.Exts
+import Data.Kind
+
+---------------------------
+-- without UnliftedNewtypes
+---------------------------
+
+-------------------- Plain newtypes -----------------
+
+-- A plain newtype, H98
+-- Defaulting happens; infers Fix1 :: forall k. (k -> Type) -> Type
+newtype Fix1a f = In1a (f (Fix1a f))
+
+-- A plain newtype, GADT syntax
+-- Defaulting happens; infers Fix1 :: forall k. (k -> Type) -> Type
+newtype Fix1b f where
+    In1b :: forall ff. ff (Fix1b ff) -> Fix1b ff
+
+-- A plain newtype, GADT syntax, with a return kind signature,
+-- and runtime-rep quantification in the data constructor
+-- Should infer Fix2 :: (Type -> Type) -> Type
+newtype Fix2 f where
+   In2 :: forall (ff :: Type -> Type). ff (Fix2 ff) -> Fix2 ff
+
+-- Plain newtype, H98 syntax, standalone kind signature
+type Fix3 :: (Type -> Type) -> Type
+newtype Fix3 f = In3 (f (Fix3 f))
+
+-- Plain newtype, H98 syntax, standalone kind signature
+type Fix4 :: (Type -> Type) -> Type
+newtype Fix4 f where
+  In4 :: forall (ff :: Type -> Type).
+         ff (Fix4 ff) -> Fix4 ff
+
+-------------------- Data families with newtype instance -----------------
+
+-- data instance in GADT sytntax
+data family Dix1 :: (k -> Type) -> k
+data instance Dix1 f where
+  DIn1 :: forall ff. ff (Dix1 ff) -> Dix1 ff
+
+-- newtype instance in GADT syntax
+data family Dix2 :: (k -> Type) -> k
+newtype instance Dix2 f where
+  DIn2 :: forall ff. ff (Dix2 ff) -> Dix2 ff
+
+data family Dix2a :: (k -> Type) -> k
+newtype instance Dix2a f :: Type where
+  DIn2a :: forall ff. ff (Dix2a ff) -> Dix2a ff
+
+-- newtype instance in H98 syntax
+data family Dix3 :: (k -> Type) -> k
+newtype instance Dix3 f = DIn3 (f (Dix3 f))
+
+-- newtype instance in H98 syntax
+data family Dix5 :: (k -> TYPE r) -> k
+newtype instance Dix5 f = DIn5 (f (Dix5 f))
+
+-- data family Dix6 :: (k -> TYPE 'IntRep) -> k
+-- newtype instance Dix6 f where
+--   DIn6 :: forall ff. ff (Dix6 ff) -> Dix6 ff


=====================================
testsuite/tests/typecheck/should_compile/T25725.hs
=====================================
@@ -0,0 +1,17 @@
+{-# LANGUAGE TypeFamilies, PolyKinds #-}
+
+module T25725 where
+
+import Data.Kind
+import GHC.Exts
+
+--This one was OK
+data D :: TYPE r -> Type where
+  MkD :: p -> D p
+
+-- now this is OK too
+data family Dix4 :: Type -> k
+data instance Dix4 Int :: TYPE r -> Type where
+  DIn4 :: p -> Dix4 Int p
+
+


=====================================
testsuite/tests/typecheck/should_compile/all.T
=====================================
@@ -933,3 +933,7 @@ test('T25266', normal, compile, [''])
 test('T25266a', normal, compile_fail, [''])
 test('T25266b', normal, compile, [''])
 test('T25597', normal, compile, [''])
+test('T25647a', normal, compile, [''])
+test('T25647b', normal, compile, [''])
+test('T25647_fail', normal, compile_fail, [''])
+test('T25725', normal, compile, [''])



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bfdbaffc3bdab06e453c4e067e6deeb89bdd28ad...88dfabaae0cf0492fbc23e9ddc352d47dc78f17d

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bfdbaffc3bdab06e453c4e067e6deeb89bdd28ad...88dfabaae0cf0492fbc23e9ddc352d47dc78f17d
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20250208/658a459e/attachment-0001.html>


More information about the ghc-commits mailing list