[Git][ghc/ghc][wip/dcoutts/signals-cleanup] 135 commits: Add regression test for #7803
Duncan Coutts pushed to branch wip/dcoutts/signals-cleanup at Glasgow Haskell Compiler / GHC Commits: 234bab08 by Vladislav Zavialov at 2026-09-29T17:22:54-04:00 Add regression test for #7803 Commit 2effe18ab5, first shipped with GHC 8.2.1, fixed #7803 "Superclass methods are left unspecialized". This change turns the example from the ticket description into a regression test, checking that foo1 is fully specialised at Double, with no calls to the overloaded exp5Tail. Closes #7803 Assisted-by: Claude Opus 5 - - - - - c406135c by Andreas Klebinger at 2026-10-01T06:57:28-04:00 RTS: Update flag parsing/handling: Using 0 as argument to any of these flags now resets the flags setting to default: - ``-n0`` disables nursery chunking. - ``-K0`` (or a bare ``-K``) removes the stack size limit. - ``-M0`` removes the heap size limit. - ``-H0`` resets the suggested heap size, including the nursery scaling set by ``-H``. - ``-AL0`` makes the large object allocation limit follow ``-A`` again. GC Generations are now limited to 64. -n larger than -A now emits a warning and disables chunking. Fixes #27830 #27829 - - - - - 984ee82b by Andreas Klebinger at 2026-10-01T06:58:10-04:00 Fix MultiLayerModules timeout multiplier. We accidentally used the compile multiplier for ghci commands which use the run timeout setting to set the timeout. Fixes #26263 and #27796. - - - - - 50a9cf26 by Andreas Klebinger at 2026-10-01T06:58:10-04:00 testsuite: Include runtime in JUnit report. - - - - - e358619f by Alan Zimmerman at 2026-10-01T06:59:01-04:00 EPA: Use EpaLocation in EpVirtualBraces Haddock processing uses EpLayout.EpVirtualBraces to record the current layout column, for allocating haddock comments correctly. For exact printing, we need the line as well as the col, so we know how many lines to skip when the indented code block starts. This commit updates EpLayout.EpVirtualBraces so that it carries an EpaLocation instead of just the Int column, to allow it to be used for both purposes. It is a simple mechanical change, with no other impact, but it allows us to use EpLayout instead of AnnListLayout in AnnList, in the next commit in this series. - - - - - 1d2a26ee by Andrew Lelechenko at 2026-10-01T20:22:04-04:00 Remove bitSize from MINIMAL pragma of class Bits Cf. https://github.com/haskell/core-libraries-committee/issues/441 The function is deprecated for 12 years and has a default implementation, yet it was never removed from the MINIMAL pragma, putting library authors in a very awkward position. Let's finally remove bitSize from MINIMAL. - - - - - 3cc21e4c by Hannes Siebenhandl at 2026-10-01T20:22:59-04:00 Add regression test for #27641 - - - - - c35096f5 by Hannes Siebenhandl at 2026-10-01T20:23:00-04:00 Don't `:add` modules the loader will reject Only home modules can be actually added to the loader context, thus we only accept the module if it belongs to a home unit. - - - - - a563cb27 by Simon Jakobi at 2026-10-02T17:37:36-04:00 ci: accept modified changelog.d entries in lint-changelog The changelog guide says to extend an existing entry rather than add a new one when the feature is already documented. lint_changelog only counted added files, so such MRs failed before the validator ran. Fixes #27779. Assisted-by: Claude Fable 5.1 - - - - - 03082cd4 by Simon Jakobi at 2026-10-02T17:38:17-04:00 changelog.d: Fix warning flag name in the semaphore-v2 entry The entry refers to -Wsemaphore-version-mismatch, which does not exist. The warning GHC emits when it cannot use a -jsem semaphore, including on a protocol version mismatch, is -Wsemaphore-open-failure. Context: !15729, #25087 Assisted-by: Claude Fable 5.1 - - - - - a93705ee by Simon Jakobi at 2026-10-02T17:38:17-04:00 changelog.d: Fix the CLC proposal link in the T27455 entry The entry used the Sphinx :ref: role with a URL as its target. :ref: resolves only internal labels, so the generated release notes would show the proposal name without a link. Use the plain hyperlink form like the other entries. Context: !16274, #27455 Assisted-by: Claude Fable 5.1 - - - - - 54381079 by Hannes Siebenhandl at 2026-10-02T17:39:01-04:00 Extend the `TrustOverlay` for wired-in units The TrustOverlay only contained the `UnitId` of all on-disk units. However, wired-in units are referred to by their wired-in unit id, which is not the same as the on-disk unit id. Thus, trust checks for wired-in units failed because the lookup was using the wired-in unit, which wasn't present in the `TrustOverlay`. We fix #27834, by copying the trust info for wired-in unit ids. - - - - - f8cfb1a5 by Hécate Kleidukos at 2026-10-04T19:36:39+02:00 [CLC 341] Strict variants of mutable types This commit is the implementation of CLC Proposal 341 https://github.com/haskell/core-libraries-committee/issues/341 - - - - - 575c4bc6 by Rodrigo Mesquita at 2026-10-05T12:32:02-04:00 ttg: HsModuleName in the AST, ModuleName in GHC This commit makes the AST fully independent from GHC by parsing a "module name" as an `HsModuleName (= HText)` rather than constructing an `ModuleName (= FastString)` straight away. In the GHC side, everything remains as a `ModuleName`. We turn AST `HsModuleName`s into fast strings with the cheap `mkFastStringShortText` when we process the AST for manipulation within the compiler. There are no performance regressions introduced by this approach. This is the final piece of #21592 Alternative plans were discussed in gitlab.haskell.org/ghc/ghc/-/merge_requests/16546#note_694647, but the Simon suggested one won in simplicity and performance when compared against my attempt at implementing my original plan of having a family `ModuleNameP`. - - - - - b3b89d32 by mangoiv at 2026-10-05T22:03:32-04:00 hadrian: Persist the used flavour name in the build root (#20650) This executes the idea proposed in #20650, teaching Hadrian to persist the flavour used to build a build root. This both makes use of multiple build roots more ergonomic (as the user no longer needs to repeat themselves) and avoids a tiresome foot-gun (forgetting to specify a flavour, often wholly invalidating a build root). Closes #20650. Co-authored-by: Sylvain Henry <sylvain@haskus.fr> - - - - - f977837b by mangoiv at 2026-10-05T22:04:21-04:00 configure: fix sed script and subst tooldir script Fixes #27672 Adds sanity checking for SUBST_TOOLDIR Metric Decrease: LinkableUsage01 MultiLayerModulesTH_OneShot T10547 T12234 T12425 T13035 T13820 T18140 T18730 T18923 T9198 TcPlugin_RewritePerf mhu-perf - - - - - f1cb08be by Hannes Siebenhandl at 2026-10-05T22:05:03-04:00 Prepend in-memory unit database for backpack The packageDbFlags are stored in reverse order. Thus, prepending will ensure that the in-memory unit database is the last item on the unit database stack. Further, the in-memory unit database needs to be able to shadow units from earlier unit databases in the unit database stack. Moreover, a `-clear-package-db` would remove the in-memory database if it weren't the last item on the stack. Closes #27835 - - - - - 8d49ed42 by Kazu Yamamoto at 2026-10-06T19:37:25-04:00 Do not leave standard file descriptors free at startup (#24450) A process may be started with stdout closed -- `prog >&-` from a shell does exactly that. Nothing then reserves descriptor 1, and open(), pipe() and socket() hand out the lowest free descriptor, so the next descriptor the runtime creates for itself takes it: the ticker's pipe, or a capability's IO manager control pipe. 'GHC.Internal.IO.StdHandles.stdout' is a CAF, built the first time the program writes to stdout, which is long after that has happened. It builds a 'Handle' over descriptor 1, which now belongs to the runtime, and nothing reports an error because the descriptor is perfectly good. The program then writes its output into the runtime's own plumbing. What that looks like from the outside is a hang. The descriptor the Handle has taken over is the read end of a pipe, so poll() for POLLOUT on it never says yes and epoll_ctl() accepts a registration for it; the thread waiting to write blocks for ever. Closing the Handle at exit closes the runtime's descriptor, which is worse: the ticker then fails on every tick. 'hs_init_ghc' now opens /dev/null onto whichever of descriptors 0, 1 and 2 are closed, before the runtime creates any descriptor of its own. Each is opened for the access that descriptor would normally have, read-only for 0 and write-only for 1 and 2, so that writing to 'stdin' or reading from 'stdout' still fails rather than quietly succeeding against /dev/null. See Note [Standard file descriptors must be open]. Moving only the descriptors the runtime opens would not do: the first file the program itself opened would land on the free number instead. The fix has to leave no free number. A program run this way therefore finds stdout connected to /dev/null rather than failing with EBADF on the first write, which is what such a program would get from most other language runtimes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> - - - - - 65bcf9e9 by Simon Jakobi at 2026-10-06T19:38:09-04:00 changelog: Repair the sentence describing #27477 The description read "programs using could crash", the object of "using" having been lost. The synopsis already says which programs are affected, so drop the dangling word. Assisted-by: Claude Fable 5.1 - - - - - 15ece296 by mangoiv at 2026-10-08T15:14:56-04:00 ci: move hadrian/ghci into the lint category so it can be picked up by more runners Fixes #27817 - - - - - c0823135 by mangoiv at 2026-10-08T15:14:56-04:00 ci: make lint-adjacent jobs into platform independent - move lint jobs into lint-anyarch tag - unify lint jobs under the same platform independent container - - - - - f76464cf by Zubin Duggal at 2026-10-08T15:15:39-04:00 DmdAnal: Make AbsDmd neutral in maxDmd fixes #27845 - - - - - ffa56ae4 by sheaf at 2026-10-09T17:15:59+02:00 Preserve sign of zero when parsing -0.0# This commit leverages the recently added GHC.Types.Literal.Floating module in order to preserve the sign of negative zero from source-written floating-point literals. Fixes #27545 - - - - - d538cac9 by Facundo Domínguez at 2026-10-09T20:26:38-04:00 Propagate annotations to simple interfaces This allows annotations to be visible to plugins when run by haddock. The LiquidHaskell plugin needs the annotations, in particular. Fixes #26761 - - - - - 32c4f4ab by meooow25 at 2026-10-09T20:27:28-04:00 Bump containers submodule to 0.8.1 And fix affected tests. * T4086a: containers depends on template-haskell-lift now instead of template-haskell. * T22611: Updated to be less dependent on containers internals. - - - - - c786065e by sheaf at 2026-10-09T20:28:20-04:00 Use an explicit pattern match in toIfaceIdDetails The old wildcard pattern let this code bit rot: it did not properly account for recently added 'IdDetails' such as 'RepPolyId', which resulted in spurious 'pprTrace' messages that could even pollute HLS sessions. Fixes #23785 - - - - - e7cacf59 by sheaf at 2026-10-09T20:29:09-04:00 Take into account ifKind in freeNamesIfDecl Commit 3c2f4bb4 added the 'ifKind' field to various constructors of 'IfaceDecl', which preserves the original kind (before type synonym expansion) for better error messages. However, that commit forgot to update 'freeNamesIfDecl' correspondingly. This could result in a "urk! lookup local fingerpring" crash when e.g. a type's kind uses a type synonym defined later, as we failed to add a dependency on the type synonym during dependency analysis. Fixes #27916 - - - - - 41e80f41 by Simon Peyton Jones at 2026-10-11T14:38:51-04:00 Simplify the error-suppression mechanism in GHC.Tc.Errors In `GHC.Tc.Errors.reportWanteds` we suppress some errors in favour of others. But the mechanism had grown crufty, and #27331 exposed a bug. This MR makes it simpler and more uniform, by doing everything via the `ei_suppress` field of the ErrorItem. Claude then found another closely-related bug (see the review linked on !16564). That bug is immortalised in new test T18851d. I'm still not happy with `ignoreConstraint` but we can worry about that another day; I have not touched it. Main changes * Instead of /predicting/ when an error will be reported, we set `cec_error_reported` when an error is /actually/ reported. (I renamed it from `cec_suppress` to reflect this change.) Now errors are suppressed only when a preceding error has actually been reported. Simpler and more robust. See `Note [cec_error_reported: suppressing less-serious errors]` The big changes are in `reportWanteds` which looks very different. * New `Note [ei_suppress: suppressing confusing errors]` describes the (quite separate) `ei_suppress` mechanism for suppressing confusing errors, mainly arising from non-empty rewriter sets * In `tryTypeClassDefaulting`, instead of switching off type-class defaulting if there is an insoluble /anywhere/, we just switch it off locally when we find an insoluble sub-tree. See Note [When to do type-class defaulting] and (W5) in Note [ApproximateWC] * Greatly simplify `insolubleWantedCt`. * I made type-class-defaulting be a bit more eager, only switched off when a peer or ancestor (but not child) constraint is insoluble. See Note [When to do type-class defaulting]. Small refactorings * Rename `askNoErrs` to `askErrsFound` and flip its polarity * The code for "check if ei_suppress is true of all items" code is moved to `mkErrorItems` rather than in the large `reportWanteds`. * Code for `has_gadt_match` moves to `mkGivenErrorReporter`, rather than polluting the large `reportWanteds`. * Many tests with `-fdefer-type-errors` get more warnings, especially about ambiguous (Num a) constraints. This is by-design: see Note [Always warn with -fdefer-type-errors]. Previously GHC was not honouring this Note but now it is, hence the extra errors. - - - - - f217fc31 by Cheng Shao at 2026-10-11T14:39:33-04:00 compiler: ensure cross ghc --info output target unit ids Previously, for cross ghcs, the base/ghc/ghc-internal unit ids in --info output do not match the target unit ids reported by ghc-pkg, breaking cross ghc release builds with hash-unit-ids when being used with cabal 3.18. This patch fixes it by making --info output target unit ids. Fixes #27919. Co-authored-by: Codex <codex@openai.com> - - - - - d07a5176 by Simon Peyton Jones at 2026-10-13T18:10:39-04:00 Remove the Eq and Ord instances for ForAllTyFlag In Note [Comparing visibility] in GHC.Core.TyCo.Compare we read that "we always compare ForAllTyFlags with `eqForAllVis` or `cmpForAllVis`" But alas there was an Eq and Ord instance for ForAllTyFlag, which made it impossible to check this claim. So I made these changes: * Move the definition of ForAllTyFlag and its related functions from L.H.S.Specificity (where it did not belong, since L.H.S didn't use it) into GHC.Types.Var. * Remove the Eq and Ord instances for ForAllTyFlag * Deal with the fallout, by using `eqForAllVis` or related functions. * In interface files we use IfaceType as a key for a de-deduplication map See Note [Deduplication during iface binary serialisation] in GHC.Iface.Binary. For this we need /exact/ comparison, so we use a newtype wrapper for IfaceForAllTyFlag, and give use `cmpForAllTyFlagExactly` to implement its Ord instance. Tiresome but easy. * Rename `toIfaceForAllBndrs` to `toIfaceForAllTyBndrs` - - - - - ea5c054d by Simon Peyton Jones at 2026-10-13T18:10:39-04:00 Refactor type and coercion substitution This MR refactors type and coercion substitution so that they use TyCoMapper, rather than hand-rolled code. Fundamentally it's a simple idea, but I had to do quite a bit of refactoring to make it fly. I got Claude to help me this this refactoring, but I paid careful attention to every line of code. Main changes: * New module GHC.Core.TyCo.Make which defines TyCoMapper, and a bunch of other simple "smart constructors" for types and coercions. See GHC.Core.TyCo.Rep Note [The Type-related module hierarchy], esp (TRM1) * The new TyCoMapper has new fields `tcm_tcapp_ty` and `tcm_tcapp_co` to handle type-constructor applications. These replace `tcm_tycon`. * Rewrite GHC.Core.TyCo.Subst to use TyCoMapper * Rewrite GHC.Core.Type.expandTypeSynonyms to use TyCoMapper. * Implement `seqType` and `seqCo` with TyCoFolder. To to this I had to add a `tcf_lit` field to TyCoFolder. * A new module GHC.Utils.StrictIdentity to define a strict identity monad, which itself is used for substTyCoMapper :: TyCoMapper Subst StrictIdentity * I removed an apparently-unused instance for Binary Levity Refactoring `seq` functions * In GHC.Core.Seq, redefine `seqOneShot`, `seqRuleInfo`, and friends to return `SeqResult`, a new type defined in GHC.Types.Baseic, rather than `()`. We can define a Monoid instance for `SeqResult` that does the right thing. * This has knock-on effects across the compiler. - - - - - 34165e23 by Simon Peyton Jones at 2026-10-13T18:10:39-04:00 Refactor TyCoMapper to take a single monad; add StrictReaderT TyCoMapper used to be parameterised over both an environment and a monad, with fields like tcm_tyvar :: env -> TyVar -> m Type Now it is parameterised over just the monad: tcm_tyvar :: TyVar -> m Type If the mapping needs an environment, `m` is a reader monad over that environment. Many uses (e.g. zonkTcTypeMapper, swizzleMapper) need no environment at all, and used to pass a dummy (). The binder field becomes tcm_tycobinder :: forall r. TyCoVar -> ForAllTyFlag -> (TyCoVar -> m r) -> m r and runs the continuation in the extended environment. mapTyCoX is gone; only mapTyCo remains. To make this efficient, the reader monad must use the one-shot trick and be strict in the environment. So: * New module GHC.Utils.Monad.StrictReader defines newtype StrictReaderT r m a with hand-written instances. The builder of the pattern synonym `StrictReaderT` is a smart constructor that adds both `oneShot` and a bang on the environment, so every StrictReaderT computation is strict in the environment. See Note [Instances for StrictReaderT]. * ZonkT becomes type ZonkT = StrictReaderT ZonkEnv ZonkM becomes type ZonkM = StrictReaderT ZonkGblEnv IO replacing their own hand-written instances. * Substitution uses type SubstM = StrictReaderT Subst StrictIdentity substTyCoMapper :: TyCoMapper SubstM and similarly expandTypeSynonymMapper. * zonk_tycomapper :: TyCoMapper (ZonkT TcM) is now much simpler. * swizzleMapper uses StrictIdentity rather than Identity. * Module renaming, so that the strict monads are all peers in GHC.Utils.Monad: GHC.Utils.StrictIdentity ==> GHC.Utils.Monad.StrictIdentity GHC.Utils.Monad.State.Strict ==> GHC.Utils.Monad.StrictState alongside the new GHC.Utils.Monad.StrictReader. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> - - - - - c0299e15 by Simon Jakobi at 2026-10-13T18:11:23-04:00 testsuite: Line-buffer the driver's stdout Python block-buffers stdout when it is a pipe. This is the case for example in CI. As a result there is often no indication of progress at all until the run ends. To fix this, we configure it explicitly to use line buffering instead. stderr is reconfigured too, for consistency: Python line-buffers it by default since 3.9. The type-ignores are for mypy, which types these handles as TextIO — an interface without reconfigure. Fixes #12934. Assisted-by: Claude Fable 5 - - - - - 9b5beaa2 by Florian Ragwitz at 2026-10-13T18:12:05-04:00 hpc: Improve coverage semantics for instance methods and instances Users care about which of their explicitly written methods are or aren't covered, not whether all of the inherited methods are covered as well. Those should be covered where they are implemented. We therefore skip generating top-level boxes for inherited methods which will appear as uncovered with no clear indication as to why, and no way to fix other than exercising code the user has not written. Previously, top-level boxes for those inherited methods would use the instance head as their source span. Now that those boxes are gone, we can use that source span for another purpose: We introduce a new top-level box for each class instance with its instance head as the source span, and use that to indicate whether or not an instance has been covered at all. We do this by making any method of the instance, inherited/generated or otherwise, tick the box for the instance head. Excluded from this are methodless classes, which could never be covered using the current mechanism. This could be improved upon further. These changes apply to ticking for program coverage only, and don't affect source notes. Additionally, we update the scope of record selector ticking to be limited to program coverage as well, as the oversight to also extend it to source notes has previously caused bugs and because record selector ticking is coverage-specific. Fixes #17155, #15932. - - - - - 836ec50a by Simon Peyton Jones at 2026-10-13T18:12:54-04:00 Refactor fundeps again This MR fixes #27828; there was a bad scoping error in `trim_qtvs`. The main changes are * Refactor `trim_qtvs` completely to eliminate the bug. * Remove a redundant `apartnessCheck` from `mkTopOpenFamEqFDs`. * Lots of improvements to the Notes in FunDeps.hs I also did a couple of pure refactors: * I realised that we were carefully caching `cab_incomps` in each `CoAxBranch`, to make it more efficient to reduce a type family application, but we were not doing the same thing when computing relevance for functional dependencies; see Note [Relevance] in GHC.Tc.Solver.FunDeps. So I added `cab_overlaps`, which is now used in `noEarlierMatch`. * Use a proper data types, `AmIUnifying` and `OuterKindsFlag`, for two previously-Boolean arguments to `tc_unify_tys`. This is a pure refactor. - - - - - 889ef371 by Simon Peyton Jones at 2026-10-13T18:13:36-04:00 Refactor and simplify solver's unification code Ticket #27844 showed that GHC's constraint solver could miss an occurs check, and thereby build an infinite type. This patch significantly simplifes the code in GHC.Tc.Solver.Equality.canEqCanLHSFinish_try_unification GHC.Tc.Solver.Equality.canEqCanLHSFinish_no_unification It is now significantly simpler, and requires much less subtle reasoning to understand. Main changes * If `canEqCanLHSFinish_try_unification` fails to unify, it now /always/ calls `canEqCanLHSFinish_no_unification` rather than trying to finish the job itself. * `GHC.Tc.Solver.Monad.checkTypeEq` is moved from Monad into Equality, and renamed to `GHC.Tc.Solver.Equality.checkTypeEqNoUnification`. * `canEqCanLHSFinish_no_unification` calls `checkTypeEqNoUnification` to test the invariants for an inert equality. Before this MR there was a special case for `do_not_prevent_rewriting`, but that has gone; instead it's just a consequence of the flags passed to `checkTyEqRhs`, documented in the `PuOK` case of `canEqCanLHSFinish_no_unification`. * There is only one bit of "swap back" code, in `finish_no_unify` in `canEqCanLHSFinish_try_unification. Previously this code was duplicated. * `kickOutAfterFillingCoercionHole` should account for equalities with a TyFamLHS. See (KOC5) in Note [Kick out after filling a coercion hole] * No need to gather coercion holes in the `PuOK` case of `canEqCanLHSFinish_no_unification`. See documentation with that code. - - - - - f9193e53 by Simon Peyton Jones at 2026-10-13T18:13:37-04:00 One line fix to fallout from ...#27731, !16564, simplifying Tc.Errors machinery There was an over-eager assert! - - - - - cdd56b7a by Florian Ragwitz at 2026-10-13T18:14:19-04:00 Fix several sphinx errors and warnings from rendering the release notes The extension references which are removed here are for extension which were already previously undocumented, so just removing them seems fine for now. - - - - - 4f00da25 by Florian Ragwitz at 2026-10-13T18:14:19-04:00 Link to QualifiedStrings documentation - - - - - 97adaf89 by Simon Peyton Jones at 2026-10-14T00:07:27+01:00 Line up simpleUnifyCheck and check_ty_eq_rhs Even after #26543 was allegedly fixed, the original repo case in the Description continued to fail. The reason was that the QuickLook unifier, `qlUnify`, used `simpleUnifyCheck` for checking unification invariants; and `simpleUnifyCheck` conservatively rejected any RHS with a coercion hole in it. The upshot was that QuickLook was not as clever as it should be, wrongly failing to do an impredicative instantiation. Interestingly `check_ty_eq_rhs`, which does the same job during constraint solving, was more liberal: it just looked at the free vars of the coercion, and allowed coercion holes. This MR lines them up, adding some careful notes. See Note [simpleUnifyCheck] Note [Occurs check and coercions] Note [Unification preconditions] esp (COERCIONS) Things are better than before, but I am still uncomfortable about the possibilty that a hole might be filled with a coercion that mentions the LHS type variable; for now I have left this discomfort documented in Note [Occurs check and coercions]. Main changes * `qlUnify` now only unifies /instantiation variables/ not regular unification variables. This makes QuickLook more predictable. See (UQL6) in Note [QuickLook unification]. * `qlUnify` no longer needs to call `simpleUnifyCheck`, so we can get rid of `UC_QuickLook` and its code in `simpleUnifyCheck`. * I found I could get rid of `mkOccFolders` in favour of `anyFreeVarsOfType`. Hooray. * Improve documentation of CycleBreakerTv, and rename it to GivenCycleBreakerTv because they are only uesd for Givens! * I accepted a 9% worsening in compile time allocation on T5030 because the newly-consistent story triggered #27934. Other changes * I refactored `atvFolder` so that it pairs the "interesting-var" function with the in-scope set, to avoid building a closure with a free variable. Now we get nice tight loops for `anyFreeVarsOfType` and friends. See Note [Any-free-var folder]. Metric Increase: T5030 - - - - - 5f7b3047 by Simon Peyton Jones at 2026-10-14T00:07:27+01:00 Fix order-dependence in QuickLook Ticket #27917 pointed out that QuickLook was order-dependent -- very bad! The solution is in `qlUnify`: spot when we are unifying a type with a definite monotype, and then monomorphise any free instantiation variables of that type. See (UQL8) and (UQL9) in Note [QuickLook unification]. - - - - - c391c70c by Simon Peyton Jones at 2026-10-14T00:07:28+01:00 Add some comments about RuntimeUnk This commit just adds comments explaining why we don't need to worry about RuntimeUnkTv in the constraint solver. It also tightens up docmentation of earlier (overlapping) commits in this MR. - - - - - 7df3ba2f by Andrea Vezzosi at 2026-10-14T06:15:48-04:00 add runGhcWithSignalHandlers and remove handling from runGhc[T] it only ever makes sense to call `withSignalHandlers` from `main`, otherwise signals can be too easily swallowed without notification to the rest of your process. This commit takes withSignalHandlers out of `runGhc/runGhcT` and provides `runGhcWithSignalHandlers` for the old behaviour. - - - - - 3a72b8a2 by Hannes Siebenhandl at 2026-10-14T13:48:32-04:00 Fix #27836, normalise unit database path in ExternalUnitDatabases Add a regression test, proofing that all variations: - local-unit-db/my-test.conf - ./local-unit-db/my-test.conf - ./local-unit-db/my-test.conf/ are parsed only once. - - - - - 8ddbc6f9 by Florian Ragwitz at 2026-10-14T13:49:28-04:00 Remove obsolete HPC types Fixes #27946. - - - - - f34c79ee by Alan Zimmerman at 2026-10-15T04:54:47-04:00 EPA: Start using vocurly as basis for AnnListLayout For the existing cases that populate AnnList. This uses AnnListBraces when braces are explicitly supplied, and AnnListLayout when vocurly is used The change also shows up AnnList usages that can never capture layout, these are cleared up later. - - - - - 033ba59c by sheaf at 2026-10-15T04:55:44-04:00 Make exprFreeVars deep exprFreeVars used to be a shallow free-variable finder (it didn't look into kinds), but most callers wanted it to be deep. In particular, 'exprFreeVars' is often used to seed an 'InScopeSet', and that must contain the /deep/ free variables. This commit makes it deep, which allows us to get rid of calls to 'closeOverKinds' or other workarounds for shallowness in: - 'GHC.Core.Opt.Simplify.Utils.abstractFloats' - 'GHC.HsToCore.Binds.dsSpec_help' - 'GHC.Core.Opt.Arity.etaBodyForJoinPoint' - 'GHC.Core.FVs.freeVars' - 'GHC.Core.Lint.lintCoreRule' We also remove 'deepExprsFreeVarsDSet' and 'closeOverKindsDSet'. Other places needed a little bit more care, in particular to properly handle coercion variables free in kinds: - 'GHC.Core.Opt.Specialise.specHeader' quantifies over the binder of an unspecialised argument directly, instead of computing the free Ids of the argument. - 'GHC.HsToCore.dsWarnRuleShadowing' filters out 'CoVar's. - 'GHC.Core.Opt.SpecConstr.callToPat' had some ad-hoc logic to compute argument pattern types and a workaround with 'expandTypeSynonyms'. That logic is removed in favour of a new 'argsToPats' function which directly computes the argument pattern types by instantiating the type of the head of the call pattern. Fixes #27936 - - - - - f93d523c by Luite Stegeman at 2026-10-15T04:56:34-04:00 testsuite: Use mkWeakMVar in memo001/memo002 mkWeakPtr in the memo001/memo001 tests created weak pointers with the MVar box as the key, which is fragile in the presence of optimization. The fix is using mkWeakMVar, keying on the primitive MVar# instead. Fixes #27924 and #27396 - - - - - 8c947573 by Simon Peyton Jones at 2026-10-16T13:11:53+01:00 Improve exprOkForSpeculation Fixes #27910, which exposed an infelicity in exprOkForSpeculation The new story is carefully described in new Note [exprOkForSpeculation], esp (a-c) and (EOKS1). - - - - - 7dedcf13 by Alan Zimmerman at 2026-10-16T19:03:17-04:00 EPA: Add TTG fields to FamilyInfo This commit is a simple add, with unused extension fields. It lays the groundwork for using them for exact print annotations - - - - - 26b9a8a0 by Arkissa at 2026-10-17T16:04:10+00:00 ghci: Prefer exact source spans in :type-at Prefer expression types for identical source spans. Fixes #27412. - - - - - 70dc4e61 by sheaf at 2026-10-18T18:15:15-04:00 Carefully implement coercion zapping This commit implements coercion zapping in the rewriter, controlled by the -fzap-coercions flag (on by default). This significantly reduces the size of coercions produced when rewriting type family applications, resulting in much faster compilation. See Note [Coercion zapping] in GHC.Tc.Solver.Rewrite for an explanation and further details. The rewriter now keeps track of the `CoVar`s and `CoercionHole`s it uses when rewriting, which allows computing the dependencies of a zapped coercion without traversing the coercion the rewriter produced, as explained in Note [Computing coercion dependencies] in GHC.Tc.Solver.Rewrite. Accompanying changes: - Rework how dependencies of 'UnivCo's are tracked, purely for performance reasons. We now use the 'UnivCoDeps' datatype instead of '[Coercion]', and we now insist that 'uco_deps' also contains the CoVars that appear in the LHS and RHS types of the UnivCo (as a caching mechanism). - Several performance improvements to the rewriter (e.g. increased strictness). - Improvements to the family application cache, including: - Better documentation. - Only cache a whole chain of reduction steps. - Don't put coercion holes in the cache, fixing #27518. - Allow Core Lint to be called from within the typechecker (and from within the coercion optimiser). - Move out "annotation linting" from Core Lint into the general Core pipeline, to avoid the dependency GHC.Core.Coercion.Opt->GHC.Core.Lint causing a regression in CountDepsParser due to transitive dependencies of GHC.Core.Opt.Monad and GHC.Unit.Module.ModGuts. Fixes #8095 #27336 #27518 Summary of performance numbers Compile-time byte allocated in GHC's testsuite (0 regressions) CoOpt_Singletons(normal) ghc/alloc 634,040,332 595,448,728 -6.1% GOOD FamAppCachePerf(normal) ghc/alloc 495,629,812 191,612,920 -61.3% GOOD LargeRecord(normal) ghc/alloc 1,226,806,434 966,260,976 -21.2% GOOD SimplCastPerf(normal) ghc/alloc 160,505,678 148,112,688 -7.7% GOOD T12227(normal) ghc/alloc 244,668,982 233,037,216 -4.8% GOOD T12545(normal) ghc/alloc 697,804,842 424,705,152 -39.1% GOOD T13386(normal) ghc/alloc 422,871,076 35,213,656 -91.7% GOOD T15703(normal) ghc/alloc 288,402,364 273,692,560 -5.1% GOOD T26426(normal) ghc/alloc 86,002,052 78,152,104 -9.1% GOOD T27336(normal) ghc/alloc 498,932,268 35,886,016 -92.8% GOOD T5030(normal) ghc/alloc 117,057,706 88,785,648 -24.2% GOOD T5321Fun(normal) ghc/alloc 252,552,628 243,820,176 -3.5% GOOD T8095(normal) ghc/alloc 768,198,564 127,779,520 -83.4% GOOD T9872a(normal) ghc/alloc 1,655,675,020 1,406,017,008 -15.1% GOOD T9872b(normal) ghc/alloc 1,864,180,628 1,644,706,696 -11.8% GOOD T9872b_defer(normal) ghc/alloc 2,834,585,468 1,657,729,760 -41.5% GOOD T9872c(normal) ghc/alloc 1,572,573,116 1,354,055,424 -13.9% GOOD T9872d(normal) ghc/alloc 351,516,004 331,071,424 -5.8% GOOD TcPlugin_RewritePerf(normal) ghc/alloc 2,063,065,680 1,847,464,272 -10.5% GOOD Chesskell (github.com/Proxymoron461/chesskell/issues) Typechecking that the first N plies of kholmovVsBronsteinShort are a valid chess game: Plies | GHC 9.14 time/alloc | This commit time/alloc | -----:|---------------------|------------------------| 2 | 41s/20GB | 0.2s/19MB | 4 | 95s/49GB | 0.3s/25MB | 6 | timed out | 0.6s/522MB | 8 | timed out | 7s/673MB | 10 | timed out | timed out | Compilation of singletons-base: compile time -28%, allocations -25% ------------------------- Metric Decrease: CoOpt_Singletons FamAppCachePerf LargeRecord SimplCastPerf T12227 T12545 T13386 T15703 T24984 T26426 T27336 T5030 T5321Fun T8095 T9872a T9872b T9872b_defer T9872c T9872d TcPlugin_RewritePerf ------------------------- Co-Authored-By: Sylvain Henry <sylvain@haskus.fr> - - - - - 3d326d7d by Sylvain Henry at 2026-10-18T18:16:09-04:00 JS: fix stack corruption in h$ap_gen_fast's pushAllRegs (#27624) The loop added in 9e46990976 ("JS: support more than 128 registers (#26558)") pushed register N to stack[sp - N - 2] while the switch it falls through into, and every reader of the h$ap_gen frame, uses stack[sp - (N - 2)]. Registers >= R32 were therefore written 4 slots too low: the slots the readers consult were left stale and the frame below was silently corrupted. Fix the loop to use the same slot formula as the switch, and add a regression test: an unknown call to a thunk with 35 argument register slots, which goes through the generic apply. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> - - - - - 6bbca569 by Andreas Klebinger at 2026-10-21T10:01:10+00:00 Fix a few tag inference bugs. * Treat bottoming functions and nullary join points as functions. * When generating bytecode don't rely on imported tag sigs. Fixes #27831, #27841 and #27842. - - - - - 71808e29 by Sylvain Henry at 2026-10-22T04:50:24-04:00 Add GHC.Internal.Unboxed.Do: do-notation for unboxed values (#27944) QualifiedDo operators can be representation-polymorphic: a do-block is expanded into ordinary applications before typechecking, and the only check on a bound variable is the deferred fixed-runtime-rep check. A representation-polymorphic (>>=) cannot be defined directly, though, because its body would bind a variable of unknown representation. The new module provides such operators for State#-passing code as methods of a class indexed by RuntimeRep, with one instance per representation. With optimisation the dictionaries disappear and a block compiles to the usual nested case expressions: Ubx.do { x <- readWordArray# mba 0# -- x :: Word# ; writeWordArray# mba 1# x -- unit actions are statements ; Ubx.pure x } Also add users guide documentation and tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> - - - - - 33247780 by Sylvain Henry at 2026-10-22T04:50:24-04:00 Bignum: use Ubx.do for State#-passing code (#27944) Rewrite the State#-passing code of the GHC.Internal.Bignum modules (Primitives, WordArray, BigNat, Natural, Integer, Backend.Native, Backend.GMP) with the qualified do-notation of GHC.Internal.Unboxed.Do. Nested case chains such as case newWordArray# sz s of { (# s, mwa #) -> case act mwa s of { s -> unsafeFreezeByteArray# mwa s }} become Ubx.do mwa <- newWordArray# sz act mwa unsafeFreezeByteArray# mwa The optimised Core is unchanged (compared per top-level binding). BigNat now enables MonoLocalBinds: local loops written with Ubx.do must stay monomorphic in the state type, otherwise GHC does not turn them into join points. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> - - - - - 593f5f5b by Sylvain Henry at 2026-10-22T04:51:16-04:00 JS: remove archive padding after wasm objects (#25665) On Darwin hosts, emar (llvm-ar) writes archives in the Darwin format when the first member is not a known object file, which is the case for the archives of the JS backend. This format pads each member to 8 bytes with '\n' and includes the padding in the member size. Wasm objects do not accept trailing bytes: wasm-ld failed with "section too large". The JS linker now removes this padding when it extracts a wasm object from an archive. In addition, Hadrian passes --format=gnu to emar for the JS target. See Note [Wasm objects in Darwin archives]. Also document the format of Cc (wasm) objects in Note [Cc object format]. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> - - - - - 13dff5d0 by L0neGamer at 2026-10-22T21:37:31-04:00 add options for resizing bytearrays (#27244) add five mutable bytearray resizing operations for various kinds of pinnedness and aligning. - prefer unpinned when allocating new array (``resizeMutableByteArrayPreferUnpinned#``; the ``resizeMutableByteArray#`` default) - prefer pinned when allocating new array (``resizeMutableByteArrayPreferPinned#``) - prefer aligned and pinned when allocating new array (``resizeMutableByteArrayPreferAlignedPinned#``) - prefer same as input bytearray when allocating new array (``resizeMutableByteArrayKeepPinnedness#``) - ensure the output array is aligned and pinned after operation (``resizeMutableByteArrayMakeAlignedPinned#``) - - - - - 0c17201c by Sylvain Henry at 2026-10-22T21:38:23-04:00 JS: implement performMinorGC and performBlockingMajorGC (#28012) GHC.Internal.System.Mem imports three C entry points: performMajorGC, performGC (for performMinorGC) and performBlockingMajorGC. The JS RTS only defined h$performMajorGC, so calling performMinorGC or performBlockingMajorGC threw "ReferenceError: h$performGC is not defined" at runtime. The JS RTS has a single non-generational collector, so both missing entry points are now aliases of h$performMajorGC. Add a test that calls every GC entry point of System.Mem. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> - - - - - 7a631ff2 by L0neGamer at 2026-10-23T09:11:39-04:00 Mon(a|oi)d of No (Return|Mappend) progress (!15795) Make non-canonical definitions of return and mappend non-suppressible errors, and make canonical definitions of those methods warnings. CLC proposal: https://github.com/haskell/core-libraries-committee/issues/328 - - - - - 14656fd4 by Simon Jakobi at 2026-10-23T09:12:27-04:00 Cmm: keep the CBE substitution idempotent When blocks are merged over multiple rounds during common block elimination, a block that won a merge in an earlier round can still lose a merge in a later round. The substitution map (Subst) used to record this as a chain: the earlier loser mapped to a block that was itself eliminated. In PLT terminology, the substitution became *non-idempotent*. Applying such a substitution with a single lookup left edges to unreachable blocks in the Cmm graph, eventually leading to a setInfoTableStackMap panic (#27368). With this patch, each round's fresh substitutions are applied to the old ones as they are added (extendSubst), so every eliminated block maps directly to its final replacement and the substitution stays idempotent. Fixes #27368. Assisted-by: Claude Fable 5.1 - - - - - 92848e61 by Evgeny Malyshev at 2026-10-23T20:26:04-04:00 hadrian: Include transitive dependencies in Haddock builds Haddock needs indirect dependency interfaces to resolve references to definitions outside a package's direct dependencies. Expose Cabal's configured dependency closure through ContextData and use it alongside the direct list, preserving direct-interface precedence. Bump Shake's cache version for the serialized oracle change. Add a Hadrian selftest requiring template-haskell's indirect ghc-prim interface. Fixes #25850. Fixes #27786. Assisted-By: OpenAI Codex Metric Increase: haddock.Cabal - - - - - 5e8ae81b by Zubin Duggal at 2026-10-23T20:26:47-04:00 WinIO: Don't confuse Win32 errors and NTSTATUS codes WinIO misinterpreted NTSTATUS codes as Win32 errors, and had some ad hoc logic to deal with this. However, this logic was incomplete and resulted in the mishandling of results of certain I/O operations (see testcase). Now the `ErrCode` argument in `CompletionCallback` is always the Win32 error code, and we convert the NTSTATUS using RtlNtStatusToDosError. Also when an overlapped/async operation such as ReadFile fails immediately, with a Win32 error such as ERROR_BROKEN_PIPE, we don't get a further completion notification, so we never recorded the failure. This worked by coincidence earlier, because `STATUS_PENDING` happened to have the same numerical code as `ERROR_NO_MORE_ITEMS`, but it doesn't now that we translate `STATUS_PENDING` into the correct Win32 error code (`ERROR_IO_PENDING`). Fix this by using the Win32 error value we obtained when an operation returns `STATUS_PENDING`. Fixes #27971 - - - - - c42ed66a by Martijn Bastiaan at 2026-10-24T16:00:42+02:00 Add single-threaded test for #27526 + #27123 Issue #27526 is a duplicate of #27123, which has already been fixed in HEAD. The proposed patch in the former carries a "nicer" regression test in that it doesn't rely on multi-threading to trigger. Closes #27526 - - - - - 7f73f515 by Simon Peyton Jones at 2026-10-24T17:29:19-04:00 Refactor QuickLook a bit This MR simply refactors QuickLook a bit. In particular, it simplifies `tcApp`, and moves shared code into `finishApp`. It also adds `Note [QuickLook: arguments before result]` responding to #26599. There should be no user-visible changes, except perhaps in error messages, which improve marginally. For some reason T24984 compiles 8% faster. I'll take the win! Metric Decrease: T24984 - - - - - a4a3a964 by Alan Zimmerman at 2026-10-24T17:30:03-04:00 EPA: Use AnnList for XClosedTypeFamily We now have TTG annotations for FamilyInfo. Make use of it to store the AnnList annotations for a closed type family. - - - - - 953e4c7f by sheaf at 2026-10-26T18:19:10-04:00 Rework LogQueue to be a proper queue Now 'LogQueue' uses a 'TQueue' with a separate 'TVar' to indicate whether the log queue is finished logging, instead of the previous weird data representation using a reverse-order '[Maybe Msg]' with 'Nothing' denoting the end of the queue. - - - - - ec29c5fa by Rodrigo Mesquita at 2026-10-26T18:19:10-04:00 Refactor GHC.Driver.MakeAction Pull out of 'runParPipelines' the logic for creating a 'MakeEnv' ready to be used by multiple threads, as that will be useful for downsweep as well (which doesn't fit the 'runPipelines' flow), rather than being just for upsweep. The code is moved and re-structured to match the export list, simplify the sequentiality checks previously both in 'runPipelines' and 'runAllPipelines', which were weirdly similar and confusing; into the two part step where we need these checks: (1) to construct the MakeEnv, (2) to run the MakeActions in parallel. These two steps are separate and used to be too mixed up. Some additional little simplifications or clean ups here and there. - - - - - 3fb22073 by Rodrigo Mesquita at 2026-10-26T18:19:11-04:00 Refactor GHC.Driver.Downsweep in preparation for parallel downsweep Pure refactor to improve the code to facilitate implementing parallel downsweep in the next commit. This commit puts a MakeEnv into the DownsweepEnv, gives the fields proper names and uses RecordWildcards to simplify, rather than passing around all diagnostic wrappers, driver-message-things and using 10s of positional fields. No behavior changes here! - - - - - 52f385a7 by sheaf at 2026-10-26T18:19:11-04:00 Driver: enableCodeGenForTH in load', not downsweep enableCodeGenForTH modifies the module graph for planning, creating fresh temporary paths. So it should only be run when we are about to execute a build plan (e.g. in load'), so that consumers that want to know facts about the module graph don't go looking for files that don't exist yet (in particular 'haddock --no-compilation'). - - - - - 82402d14 by sheaf at 2026-10-26T18:19:11-04:00 2-phase Cache/Search Finder monad This commit restructures the finder abstraction by introducing the 'FinderM' monad, which splits module lookup operations into two phases: - a cache-only phase, performing no filesystem access, - from the first cache miss onwards, a search action which may access the filesystem. This allows consumers to distinguish between quick cached results versus more expensive filesystem search operations. - - - - - 5c302b40 by sheaf at 2026-10-26T18:19:11-04:00 Separate Home/External finder caches The caches for home modules and modules from external units have different lifetimes, needing to be invalidated at different points. This commit moves the cache for modules from external units into the 'UnitState' type, which keeps the cache correct whenever package flags or package databases change (setSessionDynFlags, :set -package ..., Backpack's addUnit). This also makes it easier to clear the cache of home modules, as they are now stored separately (obviating the 'isUnitEnvInstalledModule' check we used to perform). - - - - - 605fbb96 by sheaf at 2026-10-26T18:19:11-04:00 Add known home modules to the finder cache The finder looks in the file system for the on-disk source that corresponds to a Haskell module name. There are two kinds of modules where we need to bypass this search: - a file passed directly in the command line, which may not be in any search path and whose module name may differ from the file name; - Backpack signatures and modules, which do not exist as files at all. This commit handles these two situations by adding an immutable 'KnownHomeModules' in the finder cache, which is always consulted first before doing any search. This removes the ad-hoc imperative logic which relied on mutating the finder cache at careful points. 'setModuleGraph' now also takes the known home modules, so that the module graph and the known home modules are always set consistently. See Note [Known home modules] in GHC.Unit.Finder.Types. - - - - - 82718f44 by sheaf at 2026-10-26T18:19:11-04:00 Make 'UnresolvedImport' into a suitable cache key The goal of this commit is to make 'UnresolvedImport' suitable for use as a cache key. Specifically, during downsweep we want to be able to cache module resolution queries. We want to do this using some kind of map, e.g. (roughly speaking): Map UnresolvedImport ResolvedImport For this to work, 'UnresolvedImport' must contain **precisely** the input data to each resolution computation. In other words: 1. If something changes that materially affects resolution, it must be stored in the cache key. 2. If changing some input does not materially affect the outcome, then it must not be stored in the cache key. To satisfy (1), we change 'UnitNode' to also keep track of the home unit in whose unit state the unit's dependencies were looked up. For (2), 'ImportResolution' now stores a 'ModuleLookupScope' instead of an 'UnresolvedImportOrigin'. Plugin imports are expressed with a new 'LookupPlugin' scope. The source location of an import, which is immaterial to the resolution, is stored out of band outside 'UnresolvedImport', in 'ModSummary'. - - - - - d4635c7c by sheaf at 2026-10-26T18:19:11-04:00 Add GHC.Data.Dependent This commit adds a minimal implementation of dependent sums ('Some', 'DSum') and dependent maps ('DMap'). The implementation is not entirely performance optimal, as there are a few extraneous allocations compared to the full-blown implementation in the 'dependent-map' package. For our use case (caching downsweep computations), this does not matter much. See GHC.Data.Dependent. - - - - - 6759533e by sheaf at 2026-10-26T18:19:11-04:00 Driver: structured concurrent worker abstraction This commit introduces a structured concurrency framework in the style of the 'ki' library: a collection of threads within a scope. We implement two kinds of concurrent workers on top of this framework: - Independent workers cannot wait for one another at all. The only scheduling operation is to wait for quiescence. - Coordinating workers declare an STM readiness condition (waiting on other workers to complete) which gates their start. See Note [Deterministic concurrent workers] in GHC.Driver.Concurrency. This commit ports upsweep to this new framework, with downsweep being left as subsequent work. Further changes along the way: - Refactoring of how concurrency is acquired to avoid the footgun of trying to use a no-op 'AbstractSem' as a lock in the serial case. - The "re-run with -j1" logic for semaphore opening errors no longer triggers on late semaphore failures (part-way through a lengthy computation). - Logger threads are properly cleaned up on exception, with each concurrent worker's log queue and local TmpFs properly bracketed. - The 'GhcMessage -> AnyGhcDiagnostic' and 'Maybe Messager' arguments of 'depanalE', 'depanalPartial' and 'downsweep', which were all dead in practice, have been dropped. - Concurrent logging has been completely overhauled. Each worker has its own log queue. Workers whose logs are printed as we go are spawned in the order in which their logs must be printed, now using a TQueue instead of the old complicated LogQueueQueue mechanism. 'logThread' is replaced by 'withLogPrinter', which runs the thread that prints the log queues within a concurrent worker scope. These changes allow us to fix issues with the exception handling: we now always flush remaining log queues before exiting (even when the action throws an exception), and exceptions that arise while printing are properly rethrown. This fixes #28009. - - - - - 38a99006 by sheaf at 2026-10-26T18:19:11-04:00 Rule-based deterministic concurrent downsweep This commit rewrites downsweep as a single query-answering rule (see 'DownsweepRule') that can be executed by concurrent worker threads. The design allows every expensive operation (preprocessing files with CPP, parsing headers, reading interfaces) to be performed concurrently according to the -j<N>/-jsem flags. See Note [Rules-based downsweep] in GHC.Driver.Downsweep. The rules are run by "GHC.Driver.Concurrency.runRules" in a demand-driven way: each worker can demand other workers to run, but never wait on another worker. Every piece of work is done at most once. Fixes #27514 Memory usage can increase due to doing more work concurrently: ------------------------- Metric Increase: MultiComponentModulesRecomp MultiComponentModulesRecomp100 mhu-perf ------------------------- - - - - - 9fa7b7be by sheaf at 2026-10-26T18:19:11-04:00 Acquire/release semaphore tokens more readily This commit reworks GHC.Driver.MakeSem to use the scoped worker abstraction of GHC.Utils.Concurrent.Scope. This allows us to get rid of a lot of the tricky logic in GHC.Driver.MakeSem involving manual exception handling, thread spawning and lifetime management, etc. The main user-visible change is that token acquisition is no longer rate limited (due to a bug, there previously was a 1s rate limit on acquisition of semaphore tokens), with the release debounce period shortened from 1s to 10ms. Other changes: - With -jsem, the number of capabilities is now capped at the number of processors, bringing it in line with the -jN behaviour. - Pending jobs whose wait for a token is interrupted by an exception are now withdrawn from the jobserver, instead of acquiring a token that it hung onto without doing useful work. Fixes #27763 - - - - - c83c6733 by Alan Zimmerman at 2026-10-26T18:19:55-04:00 EPA: Update AnnClsInstDecl to contain AnnList It was already separately tracking the '{', '}' and leading ';' values. This aligns it with layout-introducing parser productions ('vocurly'), so the layout processing can be handled uniformly - - - - - ac870ad5 by Simon Jakobi at 2026-10-28T04:40:42-04:00 X86 NCG: use 32-bit POPCNT for sub-word popcounts A 32-bit write zero-extends the result to the full register, so we don't need to emit additional code for this. We also skip emitting zero-extension instructions for the argument when it is already visibly zero-extended. For the byte-wise popcount loop from #24813, this shrinks the popcount sequence from 5 instructions to 3. Assisted-by: Claude Fable 5.1 - - - - - 53087373 by Facundo Domínguez at 2026-10-28T04:41:32-04:00 Use a ShortByteString in Serialized instead of [Word8] This makes the in-memory representation 40x more compact for all values stored in annotations. A test is added to measure the representation size of annotations specified in the compiler input. The GHC API is modified. All functions that previously handled annotations in [Word8] form now use ShortByteString. The following definitions have modified types: * GHC.findGlobalAnns * GHC.Tc.Gen.Splice.getAnnotationsByTypeRep * GHC.Core.Opt.Monad.getAnnotations * GHC.Core.Opt.Monad.getFirstAnnotations * GHC.Types.Annotations.deserializeAnns * GHC.Types.Annotations.findAnns * GHC.Types.Annotations.findAnnsByTypeRep * GHC.Serialized.Serialized * GHC.Serialized.toSerialized * GHC.Serialized.fromSerialized * GHC.Serialized.serializeWithData * GHC.Serialized.deserializeWithData * GHCi.Message.ReifyAnnotations Fixes #28002. - - - - - 65fd0e31 by Duncan Coutts at 2026-10-29T12:10:21+00:00 Move idle GC tracking to its own file, step 1 of 2 Add a new IdleGC.{c,h} module. Move the RecentActivity type, recent_activity variable and {get,set}RecentActivity wrappers. - - - - - 6e3916bc by Duncan Coutts at 2026-10-29T12:10:21+00:00 Move idle GC functionality to its own file, step 2 of 2 We can now fully encapsulate the recent_activity state, exposing just three hooks, and one query used in the scheduler and timer tick. This is a prelude to making changes to the implementation of tracking when to perform an idle gc. - - - - - c455f7cd by Duncan Coutts at 2026-10-29T12:10:21+00:00 Correct comments in idle GC code The comments still referred to stopTimer/startTimer. These were replaced recently by pauseTimer/unpauseTimer, but the comment was not updated. - - - - - e5fe6cc3 by Duncan Coutts at 2026-10-29T12:10:21+00:00 Make signal handling be a responsibility of the I/O manager(s) Previously it was scattered between I/O managers and the scheduler, and especially the scheduler's deadlock detection. Previously the scheduler would poll for pending signals each iteration of the scheduler loop. The scheduler also had some hairy signal functionality in the deadlock detection: in the non-threaded RTS (only) if there were still no threads running after deadlock detection then it would block waiting for signals. But signals can and (in my opinion) should be thought of as just a funny kind of I/O, and thus should be a responsibility of the I/O manager. So now we have the I/O managers poll for signals when they are polling for I/O completion (and removing the separate poll in the scheduler). And when I/O managers block waiting for I/O then they now also start signal handlers if they get interrupted by a signal. Crucially, if there is no pending I/O or timers, the awaitCompletedTimeoutsOrIO will still block waiting for signals. This patch puts us into an intermediate state: it temporarily breaks deadlock detection in the non-threaded RTS. The waiting on I/O currently happens before deadlock detection. This means we'll now wait forever on signals before doing deadlock detection. We need to move waiting after deadlock detection. We'll do that in a later patch. - - - - - 46dc27d5 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Clean up the RTS internal signal handling API Now that the I/O manager is responsible for signals, we can simplify the API we present for signal handling. We now just need startPendingSignalHandlers, which is called from the I/O managers. We can get rid of awaitUserSignals. We also don't need RtsSignals.h to re-export the platform-specific posix/Signals.h or win32/ConsoleHandler.h We can also hide more of the implementation of signals. Less has to be exposed in posix/Signals.h or win32/ConsoleHandler.h. Indeed, posix/Signals.h becomes empty and we remove it. Partly this is because we don't need inline functions (or macros) in the interface. Also remove signal_handlers from RTS ABI exported symbols list. It does not appear to have any users in the core libs, and its really an internal implementation detail. It should not be exposed unless it's really necessary. - - - - - 5e427309 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Narrow the window in which signals might be missed before poll/select Any signals delivered just before poll/select block will be missed until they are woken later by unrelated events. This arbitrarily delays the delivery of signals. This is not a complete solution. It is a cheap way to narrow but not close the window. A full solution will have to come later. This issue existed already, and is documented in issue #27540. - - - - - 6be332e2 by Duncan Coutts at 2026-10-29T12:10:22+00:00 In the scheduler, move I/O blocking after deadlock detection To make deadlock detection effective in the non-threaded RTS when there are deadlocked threads and other unrelated threads waiting on I/O, we need to arrange to do deadlock detection before we block in scheduler to wait on I/O. The solution is to: 1. adjust scheduleFindWork, which runs before deadlock detection, to only poll for I/O and not block; and 2. add a step after deadlock detection to wait on I/O if there are still no threads to run (and there's any I/O or timeouts outstanding) The scheduleCheckBlockedThreads is now so simple that it made more sense to inline it into scheduleFindWork. - - - - - 1d6868b2 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Remove bogus anyPendingTimeoutsOrIO guard from scheduleDetectDeadlock The deadlock detection was only invoked if both of these conditions hold: 1. the run queue is empty 2. there is no pending I/O or timeouts The second condition is unnecessary. The deadlock detection mechanism can find deadlocks even if there are other threads waiting on I/O or timers. Having this extra condition means that we fail to detect blocked threads if there are any threads waiting on I/O or timers. Part of fixing issue #26408 - - - - - 62e73546 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Don't consider pending I/O for early context switch optimisation Context switches are normally initiated by the timer signal. If however the user specifies "context switch as often as possible", with +RTS -C0 then the scheduler arranges for an early context switch (when it's just about to run a Haskell thread). Context switching very often is expensive, so as an optimisation there cases where we do not arrange an early context switch: 1. if there's no other threads to run 2. if there is no pending I/O or timers This patch eliminates case 2, leaving only case 1. The rationale is as follows. The use of this was inconsistent across platforms and threaded/non-threaded RTS ways. It only worked on the non-threaded RTS and on Windows only worked for the win32-legacy I/O manager. On all other combinations anyPendingTimeoutsOrIO would always return false. The fact that nobody noticed and complained about this inconsistency suggests that the feature is not relied upon. If however it turns out that applications do rely on this, then the proper thing to do is not to restore this check, but to add a new I/O manager hint function that returns if there is any pending events that are likely to happen *soon*: for example timeouts expiring within one timeslice, or I/O waits on things likely to complete soon like disk I/O, but not for example socket/pipe I/O. The motivation to avoid this use of anyPendingTimeoutsOrIO is to allow us to eliminate anyPendingTimeoutsOrIO entirely. All other uses of this are just guards on {await,poll}CompletedTimeoutsOrIO and the guards can safely be folded into those functions. This will better cope with some I/O managers having no proper implementation of anyPendingTimeoutsOrIO. Ultimately this will let us simplify the scheduler which currently has to have special #ifdef mingw32_HOST_OS cases to cope with the lack of a working anyPendingTimeoutsOrIO for some Windows I/O managers - - - - - 4b4f7787 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Remove anyPendingTimeoutsOrIO guarding {poll,await}CompletedTimeoutsOrIO Previously the API of the I/O manager used a two step process: check anyPendingTimeoutsOrIO and then call {poll,await}CompletedTimeoutsOrIO. This was primarily there as a performance thing, to cheaply check if we need to do anything. And then because anyPendingTimeoutsOrIO existed, it was used for other things too. We have now eliminated the other uses, and are just left with the performance pattern. But this was problematic because not all I/O managers correctly implement anyPendingTimeoutsOrIO (specifically the win32 ones), and now that we also make I/O managers responsible for signals then we need to poll/await even if there is no pending I/O or timeouts. If there is no pending I/O or timeouts then await needs to degenerate to just waiting forever for any signals. - - - - - 50d2a1a8 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Remove anyPendingTimeoutsOrIO, it is no longer used And this avoids the problems arising from the win32 I/O managers having had a bogus implementation. - - - - - 2fc5cbe7 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Remove second scheduler call to awaitCompletedTimeoutsOrIO Previously awaitCompletedTimeoutsOrIO was called both before and after deadlock detection in the scheduler. The reason for that was that the win32 I/O managers had a bogus implementation of anyPendingTimeoutsOrIO and this was used to guard the call of awaitCompletedTimeoutsOrIO prior to deadlock detection. This meant the first call site was never actually called when using the win32 I/O managers. This was the reason for the second call: the first one was never used. What a mess. So now we have a simple design in the scheduler: 1. poll for completed I/O, timers or signals 2. if no runnable threads: do deadlock detection 3. if still no runnable threads: block waiting for I/O, timers or signals. - - - - - fc139a41 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Lift emptyRunQueue guard out of scheduleDetectDeadlock this improved the clarity of the logic when reading the scheduler code. And improve the comment about scheduleDoGC that was rather unclear. - - - - - f9f21372 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Make interruptIOManager work for WinIO (non-threaded) Fixes #27403 The idle GC scheme now fundamentally relies on interruptIOManager working, so it's no longer acceptable for it to be missing for WinIO. Not having it would cause lock ups. - - - - - 625e2a8e by Duncan Coutts at 2026-10-29T12:10:22+00:00 Make non-threaded deadlock detection also rely on idle GC Only do deadlock detection GC when idle GC kicks in. This also relies on using wakeUpRts, so now do this unconditionally. Previously wakeUpRts was for the threaded rts only. - - - - - 1ca6ce4f by Duncan Coutts at 2026-10-29T12:10:22+00:00 Enable idle GC by default on non-threaded RTS The behaviour is now uniform between the threaded and non-threaded RTS ways. The deadlock detection now relies on idle GC for both threaded and non-threaded ways. Previously deadlock detection did not rely on idle GC for the non-threaded way. Also tweak test T7275 to account for idle GC. This test's output is sensitive to the number of major GCs run. Since this commit enables idle GC for the non-threaded RTS, for this test that increases the number of major GCs, since the test program is frequently idle for more than 300ms. - - - - - c8266428 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Fix state of idle GC control vars with +RTS -V0 Currently when the user uses +RTS -I0, then doIdleGC is set to false. But if the master tick interval -V is set to 0 then the idleGCDelayTime was being set to 0 but doIdleGC was not being set to false, which is inconsistent, and almost certainly buggy. - - - - - 5e4f730b by Duncan Coutts at 2026-10-29T12:10:22+00:00 Add a long Note [Deadlock detection] It describes the historical and modern designs and their trade-offs. The point is we've now unified the code for deadlock detection between the threaded and non-threaded ways, by changing the non-threaded to follow the same design as the threaded. - - - - - 8140608d by Duncan Coutts at 2026-10-29T12:10:22+00:00 Refactor the utils providing the I/O timeout for different system APIs We have to provide a timeout in three different time formats (int milliseconds, struct timeval *, and struct timespec *). These are for platform APIs including poll, select, ppoll, pselect, epoll_wait, epoll_wait2 and in future kevent and io_uring. Previously we had one util for each format that both worked out what the timeout should be and converted it into the particular format. This duplicates some logic and it also makes it awkward to modify the timeout value (since there's no common format). Modifying the timeout value is exactly what we want to do, in a subsequent commit, where we want to adjust the timeout to take account of idle GC. - - - - - e2c997dc by Duncan Coutts at 2026-10-29T12:10:22+00:00 Update the old select I/O manager to use the new timeout utils This will make it much easier to adjust the timeout to take account of idle GC. - - - - - eb3b8276 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Add opportunistic deadlock detection without idle GC Our general design is now that comprehensive deadlock detection relies on idle GC. This allows us to detect partial deadlocks that are not system deadlocks. But it's not prompt. It's a nice to have feature to be able to promptly detect the cases that are system deadlocks. There's no hope to do this in the threaded RTS with -N > 1, but it can be done for the non-threaded RTS and _could_ be done for the threaded RTS with -N1. We can integrate this feature into the general design without too many contortions. We just need the I/O managers to check before sleeping if they would be about to sleep indefinately with no I/O and no registered signal handlers. If so, they can notify the idle GC that we're deadlocked and we schedule and idle GC. - - - - - edee0d4d by Duncan Coutts at 2026-10-29T12:10:22+00:00 Add idle GC mode for !HAVE_PREEMPTION We have to do idle GC (and thus deadlock detection) differently when we do not have the ticker and the ability to interrupt the I/O manager when it's blocking. - - - - - f913d1ed by Duncan Coutts at 2026-10-29T12:10:22+00:00 Add and use USED_IF_PREEMPTION to avoid warnings - - - - - 103573c7 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Add performDeadlockDetection and export via ghc-experimental When documenting the idle GC and deadlock detection behaviour in the user guide, it becomes obiovus that in some cases one would want manual control over deadlock detection. In particular, for applications that disable idle GC, for debugging or robustness, they may want to invoke deadlock detecting GC manually. Bind it in ghc-internal GHC.Internal.System.Mem and re-export via ghc-experimental in System.Mem.Experimental. It is clearly implementation specific behaviour, especially since in GHC the deadlock detection is tied to doing a major GC. - - - - - 983464a1 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Add tests for deadlock detection, issue #26408 We have three tests: T26408a: make sure that we can detect a /partial deadlock/ that is not also a /system deadlock/ T26408b: make sure that we can detect a /system deadlock/ promptly without relying on idle GC T26408c: make sure that we do not falsely detect a deadlock when there is nothing to do except wait on signals T26408d: make sure that we can detect a system deadlock with idle GC disabled, after the idle GC timeout has elapsed. - - - - - 5ebd91a9 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Update the user guide with the revised idle GC behaviour It's now not just for the threaded RTS, but general. Add a new section in the RTS chapter: Idle GC and deadlock detection. Provide general documentation on both topics. In particular, document the behaviour of deadlock detection and how it depends on idle GC. Move the existing entries for -I and -Iw to this section. Add a changelog entry. - - - - - 6e163e72 by Duncan Coutts at 2026-10-29T12:10:22+00:00 Remove variable n_haskell_handlers which has become write-only - - - - - 6489cce6 by Duncan Coutts at 2026-10-29T12:11:55+00:00 Remove use of (un)blockUserSignals in GC Once upon a time, prior to 7ed3f7556f46b957f7efb97ed7ebdc92db2f8ab7 in 2009, the signal handlers were stored within the RTS as a table of StablePtrs. This meant that the table could be accessed concurrently by the C signal handler (picking out a Haskell signal handler when the signal was delivered) and by the GC when it looks at the stable pointers. To avoid problems, the relevant signals were masked around this critical section in the GC. The use of blockUserSignals/unblockUserSignals in the GC was missed when the scheme was rewritten. We can safely remove it now. The GC no longer has anything to do with the data structures within the RTS used for signals. - - - - - a6c8f18d by Duncan Coutts at 2026-10-29T12:11:55+00:00 Change sigprocmask to pthread_sigmask in a couple places in the rts This is part of a series of changes to fix or remove uses of sigprocmask. See issue #27968. According to Posix:
The use of the sigprocmask() function is unspecified in a multi-threaded process.
and indeed it does different things on different platforms. In particular on macOS the behaviour is to change the signal mask for every thread in the process (there is no per-process mask, it changes the per-thread mask for every thread). This obviously does not mix well with other concurrent changes to signal masks in other threads. The use of sigprocmask in exitBySignal just needs to unmask a signal in the current OS thread so that it can send a signal to itself. This purpose only requires changing the signal mask of the calling thread, which is exactly what pthread_sigmask is specified to do. In resetTerminalSettings, sigprocmask (now pthread_sigmask) is used in an attempt to mask a signal. It is unclear if this is effective. It depends on whether there are any remaining threads running by the time the function is called during shutdown. Add a Note [pthread_sigmask and the ineffectiveness of masking signals] and refer to it. - - - - - e4882f24 by Duncan Coutts at 2026-10-29T12:11:55+00:00 Change (un)blockUserSignals to use pthread_sigmask, not sigprocmask These functions are exported from the RTS (on posix platforms). They are used in the process library to temporarily mask signals during a fork(). This is only needed to ensure the new process has the signals masked initially. So in particular for this use case we want it to only affect the signal mask of the calling thread. Thus pthread_sigmask is appropriate. - - - - - 78d39d02 by Duncan Coutts at 2026-10-29T12:11:56+00:00 Make (un)blockUserSignals local functions in win32 console handling These functions were defined for all platforms in the RTS public headers but only exported from the RTS on non-win32 platforms. They are only used externally (by the process library) on posix platforms. So for win32, break the link with the exported names and use local only C static functions. They do serve a local purpose, but are now unrelated to the posix ones. - - - - - 503820fa by Duncan Coutts at 2026-10-29T12:11:56+00:00 In System.Posix.Internals, change import of sigprocmask to pthread_sigmask and refer to the Note. It's still pretty dubious! - - - - - 5c1c6bdd by Duncan Coutts at 2026-10-29T12:11:56+00:00 Drop use of sigprocmask in stg_sig_install It is somewhat unclear what the signal masking was trying to protect in stg_sig_install. The comment said // Block the signal until we figure out what to do There are no shared data structured between stg_sig_install and the generic_handler that it installs. In any case, masking signals does not in general work, so whatever it was doing was a false sense of security. - - - - - e19bc4b9 by Duncan Coutts at 2026-10-29T12:11:56+00:00 Make startPendingSignalHandlers a per-platform, not common, API The direction of travel is that user-signal handling should be managed by the I/O manager(s). This is because signals (& win32 console events) are (a funny kind of) I/O, and also because they have to be involved in noticing signals and starting signal handlers. And how we communicate between the low level signal handler and starting the Haskell signal handler threads is also speific to the I/O manager implementation. There is no need for a common API here. These are just utilities shared between some I/O manager implementations. - - - - - be0745e1 by Duncan Coutts at 2026-10-29T12:11:56+00:00 Unify freeSignalHandlers and finiUserSignals in RTS shutdown They were called at different stages of shutdown. Historically this might have made sense when the handler mechanism used stable pointers. Now there appears to be no good reason. On win32, freeSignalHandlers did nothing. On posix, finiUserSignals did nothing. There appears to be no dependency on the stage of shutdown. It is all local resources. - - - - - 3d511298 by Duncan Coutts at 2026-10-29T12:11:56+00:00 Push checks on install_signal_handlers flag into signal functions Also, change the logic slightly. The docs for --install-signal-handlers say that it installs handlers for ctl-c etc. It does _not_ say that it disables the API for Haskell code to install signal handerls. Previously however the RTS startup code would guard initUserSignals behind the flag install_signal_handlers. All that code does is initalise variables properly. This meant that when user code installs a handler, it would be working with ill-defined userSignals value and an un-initialised mutex! Similarly, in the win32 console handling, it would skip initialising the hConsoleEvent, which certainly cannot lead to good outcomes. So now we only guard initDefaultHandlers and resetDefaultHandlers behind the install_signal_handlers flag. - - - - - df1aec3a by Duncan Coutts at 2026-10-29T12:11:56+00:00 Fix user guide reference to --install-signal-handlers While reviewing --install-signal-handlers docs, noticed a typo in the --generate-crash-dumps docs that referred to --install-signal-handlers when it means --install-seh-handlers. Yes I double-checked the code. - - - - - 8f6b6039 by Duncan Coutts at 2026-10-29T12:11:56+00:00 Split user signal functions out of posix/Signals into new file The direction of travel is that user-signal handling should be managed by the I/O manager(s). The user signal functions (i.e. to allow Haskell code to set signal handlers) should stop being first class functions called by the rest of the RTS and become utilities used by the I/O managers. Start here by splitting them out. - - - - - 90274421 by Duncan Coutts at 2026-10-29T12:11:56+00:00 Make stg_sig_install part of the IOManager API This is the external entry point for user code to install signal handlers. So it becomes part of the I/O manager API. Eventually it will dispatch to the I/O manager implementations (which will do different things), but for now it dispatches to the same old implementation, under a new name. - - - - - 5e1c7abe by Duncan Coutts at 2026-10-29T12:11:56+00:00 Document that nocldstop is a totally mad implicit parameter and it's part of our public API! - - - - - d33d38a3 by Duncan Coutts at 2026-10-29T12:11:56+00:00 Move user signal init and fini into the I/O manager Initially just moved into start/stopIOManager, but a later step will be to make that be part of the initialisation of each I/O manager. Why? Because they cannot have a common init if they have different data structures that need initialisation. In fact they already do have different code and data (threaded/non-threaded, windows/other), but this is fudged using CPP. - - - - - 4ddd7b11 by Duncan Coutts at 2026-10-29T12:11:56+00:00 Push {init,fini}{UserSignals,ConsoleEvents} down into I/O managers So they become part of individual I/O managers, which will allow us to start specialising them more sanely. Rename the Win32 ones to {init,fini}ConsoleEvents. - - - - - 57fcddf4 by Duncan Coutts at 2026-10-29T12:11:56+00:00 Push installUserSignalHandler down into individual I/O managers This will allow us to specialise them. Initally they all use the same (existing) generic_handler. - - - - - 866a4590 by Duncan Coutts at 2026-10-29T12:11:56+00:00 Specialise MIO's installing of signals It already used a separate implementation, but using cpp via the signal "generic_handler". Now it is much more direct and local. MIO writes signals into a pipe and reads and dispatches them at the other end (in Haskell). - - - - - b9e8ebbb by Duncan Coutts at 2026-10-29T12:11:56+00:00 Introduce an I/O manager data structure shared between all caps Accessed via iomgr->shared, but it points to the same struct for all capabilities. We initialise and free this with cap 0. We will use it initially for signal handling, since only one capability needs to dispatch signals. This is a fairly general mechanism, so I/O managers may be able to make use of it for other purposes, especially once in-RTS ones are adapted to work in the threaded RTS with multiple capabilities. - - - - - fedfb7b7 by Duncan Coutts at 2026-10-29T12:11:56+00:00 Use the shared I/O manager data structure for MIO for signals Move the MIO I/O manager's timer manager control fd from a global variable into the shared I/O manager struct. Soon we will use the same mechanism for the same purpose of signal handling for the other posix I/O managers. - - - - - 8791c6cf by Duncan Coutts at 2026-10-29T12:11:56+00:00 Extract and add more utility functions for the signal self-pipe trick Extract a utility function writeSignalInfoToPipe from the MIO I/O manager so we can use it in other I/O managers too. Also add related utility functions readSignalInfoFromPipe, newNonBlockingPipe and startSignalHandler. We will use these in the poll and selectbis I/O managers. - - - - - 6064c323 by Duncan Coutts at 2026-10-29T12:12:44+00:00 Redo the scheme for special fds in the poll and selectbis I/O managers At the moment we only have one special fd for these I/O managers: the pipe (or eventfd) for interrupting them when they're sleeping. We're about to gain a second for signal handling. The existing scheme was rather ad-hoc and hard to extend. It was already complicated by the fact that the interrupt fd is optional. The signal fd will also be optional in the sense that cap 0 will have it but cap >0 will not. So the new scheme is that we add special aiop entries into the aiop_table, and for the most part we can treat these uniformly with other aiops. But the action we take for them if/when they are ready is handled specially. This seems much cleaner and will be easy to extend for signals. - - - - - 738f37d7 by Duncan Coutts at 2026-10-29T12:13:11+00:00 Use the signal self-pipe trick for the poll and selectbis I/O managers So now the low level signal handler delivers signals into a pipe that is monitored by the I/O manager (on cap 0). The I/O manager then dispatches the handler (starting a Haskell thread). There are two important reasons for this change: 1. This method does not have any windows of time where signals can be missed for arbitrary periods of time. The previous method has a race where a signal delivered just before the I/O manager calls poll/select will not notice the signal until some unrelated event causes poll/select to return. See issue #27540. The new method ensures that a fd is ready and so poll/select will notice immediately (if the signal was delivered prior to the call to poll/select) or later. 2. The existing method relies on temporarily masking signals for concurrency safety which cannot work reliably in a multi-threaded process. Fixing this is a necessary pre-requisite to enable these in-RTS I/O managers to work in the threaded RTS. The issue is that startPendingSignalHandlers and the low level signal handler share the pending_handler_buf data structure, and so startPendingSignalHandlers has to mask delivery of signals to avoid the shared data being mutated concurrently. But masking signals in a multi-threaded process is not generally effective because the signal can still be delivered in any thread Document the self-pipe trick in a Note. This fixes issue #27540. - - - - - 05f27242 by Duncan Coutts at 2026-10-29T12:13:11+00:00 Move the legacy user signal handler into legacy select I/O manager We do not convert the legacy select I/O manager to use the self-pipe trick. It keeps the existing code, but since it is now the only user of it, then that code can move from being a shared utility to live with the select I/O manager. There are some minor modifications to the code moved so that it is not entangled with other remaining shared signal utils. - - - - - 0092d26b by Duncan Coutts at 2026-10-29T12:13:11+00:00 Deprecate (un)blockUserSignals for external RTS users Encourage external users to stop using these actions. - - - - - ceb691c9 by Duncan Coutts at 2026-11-02T11:04:26+00:00 FIXUP Use the signal self-pipe trick for the poll and selectbis I/O managers - - - - - b7532c37 by Duncan Coutts at 2026-11-02T17:07:14+00:00 Split interruptStgRts and remove wakeUpRtsViaTicker. Split the two uses of interruptStgRts into their posix and win32 cases, and move them to their use sites. Make the posix case not rely on wakeUpRts or wakeUpRtsViaTicker. The use of wakeUpRtsViaTicker while it seemed to cleverly solve overly-close coupling in one area, causes overly-close coupling in another area: ticker(s). And we want to start improving the ticker(s) but the existence of wakeUpRtsViaTicker holds that back. Delete wakeUpRtsViaTicker and its related implementation pieces. In the posix case, we add interruptIOManagerFromSignal, which is specific for the circumstance of use within a signal handler. The implementation of this for the in-RTS I/O managers is just interruptIOManager but for MIO it has to wake up the timer manager thread. All of this seems pretty unnecessary since it is all to support a ctl-c handler that is almost never used since it is duplicated and overridden by a ctl-c handler installed by runMainIO. See issue #28066. - - - - - a50e2a4a by Duncan Coutts at 2026-11-02T17:09:21+00:00 Simplify execution of signal handlers We make a few related changes: 1. Don't use malloc/free for passing siginfo_t from C to Haskell, use heap allocated byte arrays indead. The Haskell side already uses ForeignPtr which can use byte array directly. 2. Don't redundantly fork IO threads for signal handlers, when invoked from in-RTS I/O managers. The I/O manager already creates a new IO thread, but the existing runHandlers would then redundantly forkIO again. This is a waste of resources but also means signal handlers end up getting scheduled last. 3. Schedule signal handler threads first. This should fix #28067. Introduce new runHandler/runHandlerPtr to replace the existing runHandlers/runHandlersPtr. Conveniently the old ones have a weird name (they only invoke one handler!) so we can use a sensible name, and leave the old ones (which are exported via base!) alone. Add deprecation warnings though, since nobody should be using them via base. Update the caller in ghc-internal: the MIO timer manager. This one does need to use forkIO, but it's clearer if that forkIO is done there. - - - - - 758 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/hello.hs - + changelog.d/24450 - + changelog.d/25665 - + changelog.d/25850 - changelog.d/26616 - + changelog.d/26761 - + changelog.d/27368 - + changelog.d/27624 - + changelog.d/27641 - + changelog.d/27845 - + changelog.d/27936 - + changelog.d/27971 - + changelog.d/28012 - + changelog.d/T23785 - + changelog.d/T26543 - changelog.d/T27329 - + changelog.d/T27412 - changelog.d/T27455 - + changelog.d/T27545 - + changelog.d/T27731 - + changelog.d/T27763 - + changelog.d/T27828 - + changelog.d/T27830-rts-flag-bounds - + changelog.d/T27831-bottoming-strict-field - + changelog.d/T27842-bytecode-imported-tags - + changelog.d/T27844 - + changelog.d/T27916 - + changelog.d/T28002 - + changelog.d/T28002-api - + changelog.d/T4162 - changelog.d/boxing-family - + changelog.d/clc-341-strict-mutable-data-types - + changelog.d/fix-cross-ghc-info-unit-id - changelog.d/fix-parallel-gc-selector-race-27477 - + changelog.d/hadrian-persist-flavour - + changelog.d/hpc-classinsts - + changelog.d/hpc-cleanup - + changelog.d/idle-gc-and-deadlock-detection - + changelog.d/monad-of-no-return-canonical - + changelog.d/ncg-x86-subword-popcnt - + changelog.d/parallel-downsweep - + changelog.d/resizeMutableByteArray-pinnedness - changelog.d/semaphore-v2 - changelog.d/tcplugin_init.md - + changelog.d/unboxed-do - changelog.d/unit-index - + changelog.d/zap-coercions - compiler/GHC.hs - compiler/GHC/Builtin.hs - compiler/GHC/Builtin/Modules.hs - compiler/GHC/Builtin/WiredIn/Ids.hs - compiler/GHC/Builtin/WiredIn/Prim.hs - compiler/GHC/Builtin/WiredIn/Types/Box.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Show.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/GenericOpt.hs - compiler/GHC/Cmm/UniqueRenamer.hs - compiler/GHC/CmmToAsm/CFG/Dominators.hs - compiler/GHC/CmmToAsm/Dwarf/Types.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/Reg/Graph/Spill.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillCost.hs - compiler/GHC/CmmToAsm/Reg/Graph/Stats.hs - compiler/GHC/CmmToAsm/Reg/Linear/State.hs - compiler/GHC/CmmToAsm/Reg/Linear/Stats.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/Wasm/Asm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion.hs-boot - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - + compiler/GHC/Core/Lint.hs-boot - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CallerCC.hs - compiler/GHC/Core/Opt/CallerCC/Types.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Reduction.hs - compiler/GHC/Core/Seq.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/Compare.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/FVs.hs-boot - + compiler/GHC/Core/TyCo/Make.hs - + compiler/GHC/Core/TyCo/Make.hs-boot - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Rep.hs-boot - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToIface.hs-boot - compiler/GHC/CoreToStg.hs - + compiler/GHC/Data/Dependent.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/OrdList.hs - compiler/GHC/Data/OsPath.hs - compiler/GHC/Data/Pair.hs - compiler/GHC/Data/Word64Map/Internal.hs - compiler/GHC/Data/Word64Set/Internal.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CmdLine.hs - + compiler/GHC/Driver/Concurrency.hs - compiler/GHC/Driver/Config.hs - + compiler/GHC/Driver/Config/Concurrency.hs - compiler/GHC/Driver/Config/Core/Lint.hs - compiler/GHC/Driver/Downsweep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main/Compile.hs - compiler/GHC/Driver/Main/Passes.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeAction.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/MakeSem.hs - compiler/GHC/Driver/Pipeline.hs-boot - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/LogQueue.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Doc.hs - compiler/GHC/Hs/Dump.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Match/Literal.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Errors/Types.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/Type.hs-boot - compiler/GHC/IfaceToCore.hs - compiler/GHC/JS/Opt/Simple.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Header.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Parser/String.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Runtime/Eval/Types.hs - compiler/GHC/Runtime/Heap/Inspect.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/Settings.hs - compiler/GHC/Settings/IO.hs - compiler/GHC/Stg/BcPrep.hs - compiler/GHC/Stg/Debug.hs - compiler/GHC/Stg/EnforceEpt.hs - compiler/GHC/Stg/EnforceEpt/Rewrite.hs - compiler/GHC/Stg/EnforceEpt/TagSig.hs - compiler/GHC/Stg/EnforceEpt/Types.hs - compiler/GHC/Stg/Subst.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Apply.hs - compiler/GHC/StgToJS/ExprCtx.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Deriv/Generics.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Export.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Instance/FunDeps.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Plugin.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/FunDeps.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Rewrite.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/Types.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/ErrCtxt.hs - compiler/GHC/Tc/Utils/Backpack.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Zonk/Env.hs - compiler/GHC/Tc/Zonk/Monad.hs - compiler/GHC/Tc/Zonk/TcType.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Annotations.hs - compiler/GHC/Types/Arity.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Cpr.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Name/Env.hs - compiler/GHC/Types/Name/Occurrence.hs - compiler/GHC/Types/Unique.hs - compiler/GHC/Types/Unique/DSM.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Map.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Unique/Supply.hs - compiler/GHC/Types/UnresolvedImport.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Types/Var.hs-boot - compiler/GHC/Types/Var/FV.hs - compiler/GHC/Types/Var/Set.hs - compiler/GHC/Unit/External/Database.hs - compiler/GHC/Unit/External/ModuleOrigin.hs - compiler/GHC/Unit/External/Visibility.hs - compiler/GHC/Unit/External/Wired.hs - compiler/GHC/Unit/Finder.hs - + compiler/GHC/Unit/Finder/Cache.hs - compiler/GHC/Unit/Finder/Types.hs - compiler/GHC/Unit/Home.hs - compiler/GHC/Unit/Module.hs - compiler/GHC/Unit/Module/Env.hs - compiler/GHC/Unit/Module/Graph.hs - compiler/GHC/Unit/Module/ModSummary.hs - + compiler/GHC/Unit/Module/Name.hs - compiler/GHC/Unit/Module/WholeCoreBindings.hs - compiler/GHC/Unit/Parser.hs - compiler/GHC/Unit/State.hs - compiler/GHC/Unit/Types.hs - compiler/GHC/Unit/Types.hs-boot - compiler/GHC/Utils/Binary.hs - + compiler/GHC/Utils/Concurrent/Scope.hs - compiler/GHC/Utils/Monad/Codensity.hs - + compiler/GHC/Utils/Monad/StrictIdentity.hs - + compiler/GHC/Utils/Monad/StrictReader.hs - compiler/GHC/Utils/Monad/State/Strict.hs → compiler/GHC/Utils/Monad/StrictState.hs - compiler/GHC/Utils/Outputable.hs - compiler/GHC/Utils/Panic.hs - compiler/GHC/Utils/Ppr/Colour.hs - compiler/GHC/Utils/TmpFs.hs - compiler/Language/Haskell/Syntax.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Expr.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/ImpExp.hs - compiler/Language/Haskell/Syntax/Lit.hs - compiler/Language/Haskell/Syntax/Module/Name.hs - compiler/Language/Haskell/Syntax/Specificity.hs - compiler/Language/Haskell/Syntax/Text.hs - compiler/ghc.cabal.in - distrib/configure.ac.in - docs/users_guide/extending_ghc.rst - docs/users_guide/exts/literals.rst - docs/users_guide/exts/qualified_do.rst - docs/users_guide/exts/type_families.rst - docs/users_guide/profiling.rst - docs/users_guide/runtime_control.rst - docs/users_guide/using-warnings.rst - ghc/GHCi/UI.hs - ghc/GHCi/UI/Info.hs - ghc/Main.hs - ghc/ghc-bin.cabal.in - hadrian/bindist/Makefile - hadrian/bindist/config.mk.in - hadrian/doc/flavours.md - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - hadrian/src/Hadrian/Haskell/Cabal/Type.hs - hadrian/src/Main.hs - hadrian/src/Rules.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/Documentation.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/Selftest.hs - hadrian/src/Settings.hs - hadrian/src/Settings/Builders/Ar.hs - hadrian/src/Settings/Warnings.hs - libraries/base/base.cabal.in - libraries/base/changelog.md - libraries/base/src/Control/Concurrent/Chan.hs - + libraries/base/src/Control/Concurrent/Chan/Strict.hs - libraries/base/src/Control/Concurrent/MVar.hs - + libraries/base/src/Control/Concurrent/MVar/Strict.hs - libraries/base/src/Data/IORef.hs - + libraries/base/src/Data/IORef/Strict.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - + libraries/base/tests/IO/T27971.hs - + libraries/base/tests/IO/T27971.stdout - libraries/base/tests/IO/all.T - libraries/base/tests/Memo1.lhs - libraries/base/tests/Memo2.lhs - libraries/base/tests/all.T - libraries/containers - libraries/ghc-boot/GHC/Serialized.hs - libraries/ghc-experimental/src/System/Mem/Experimental.hs - libraries/ghc-internal/CHANGELOG.md - libraries/ghc-internal/ghc-internal.cabal.in - libraries/ghc-internal/include/RtsIfaceSymbols.h - libraries/ghc-internal/src/GHC/Internal/Base.hs - libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/GMP.hs - libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Native.hs - libraries/ghc-internal/src/GHC/Internal/Bignum/BigNat.hs - libraries/ghc-internal/src/GHC/Internal/Bignum/Integer.hs - libraries/ghc-internal/src/GHC/Internal/Bignum/Natural.hs - libraries/ghc-internal/src/GHC/Internal/Bignum/Primitives.hs - libraries/ghc-internal/src/GHC/Internal/Bignum/WordArray.hs - libraries/ghc-internal/src/GHC/Internal/Bits.hs - libraries/ghc-internal/src/GHC/Internal/Conc/Signal.hs - libraries/ghc-internal/src/GHC/Internal/Event/Control.hs - libraries/ghc-internal/src/GHC/Internal/Event/TimerManager.hs - libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc - libraries/ghc-internal/src/GHC/Internal/Event/Windows/FFI.hsc - libraries/ghc-internal/src/GHC/Internal/IO/Windows/Handle.hsc - libraries/ghc-internal/src/GHC/Internal/System/Mem.hs - libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs - + libraries/ghc-internal/src/GHC/Internal/Unboxed/Do.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/TH.hs - libraries/ghci/GHCi/TH/Binary.hs - linters/lint-codes/LintCodes/Static.hs - m4/subst_tooldir.m4 - rts/Capability.c - rts/IOManager.c - rts/IOManager.h - rts/IOManagerInternals.h - + rts/IdleGC.c - + rts/IdleGC.h - rts/Linker.c - rts/Prelude.h - rts/PrimOps.cmm - rts/RtsFlags.c - rts/RtsSignals.h - rts/RtsStartup.c - rts/RtsSymbols.c - rts/Schedule.c - rts/Schedule.h - rts/Ticker.h - rts/Timer.c - rts/configure.ac - rts/include/Rts.h - rts/include/rts/BlockSignals.h - rts/include/rts/Flags.h - rts/include/rts/IOInterface.h - rts/include/rts/OSThreads.h - rts/include/rts/RtsToHsIface.h - rts/include/rts/storage/Closures.h - rts/include/rts/storage/GC.h - rts/include/stg/MiscClosures.h - rts/js/environment.js - + rts/posix/IOManSignals.c - + rts/posix/IOManSignals.h - rts/posix/MIO.c - rts/posix/MIO.h - rts/posix/Poll.c - rts/posix/Poll.h - rts/posix/Select.c - rts/posix/Select.h - rts/posix/SelectBis.c - rts/posix/SelectBis.h - rts/posix/Signals.c - − rts/posix/Signals.h - rts/posix/TTY.c - rts/posix/Ticker.c - rts/posix/Timeout.c - rts/posix/Timeout.h - rts/rts.cabal - rts/sm/GC.c - rts/sm/Storage.c - rts/win32/AsyncMIO.c - rts/win32/AsyncMIO.h - rts/win32/AsyncWinIO.c - rts/win32/AsyncWinIO.h - rts/win32/AwaitEvent.c - rts/win32/ConsoleHandler.c - rts/win32/ConsoleHandler.h - testsuite/driver/junit.py - testsuite/driver/runtests.py - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/ado/ado-optimal.hs - testsuite/tests/ado/ado001.hs - testsuite/tests/annotations/should_run/Makefile - + testsuite/tests/annotations/should_run/T16841.hs - + testsuite/tests/annotations/should_run/T16841.stdout - testsuite/tests/annotations/should_run/all.T - + testsuite/tests/backpack/should_compile/T27835.bkp - + testsuite/tests/backpack/should_compile/T27835.stderr - testsuite/tests/backpack/should_compile/all.T - + testsuite/tests/bytecode/T27842.hs - + testsuite/tests/bytecode/T27842.stdout - + testsuite/tests/bytecode/T27842A.hs - + testsuite/tests/bytecode/T27842N.hs - testsuite/tests/bytecode/all.T - + testsuite/tests/codeGen/should_compile/T27368.hs - testsuite/tests/codeGen/should_compile/all.T - + testsuite/tests/codeGen/should_gen_asm/T24813.asm - + testsuite/tests/codeGen/should_gen_asm/T24813.cmm - testsuite/tests/codeGen/should_gen_asm/all.T - + testsuite/tests/codeGen/should_run/T27624.hs - + testsuite/tests/codeGen/should_run/T27624.stdout - testsuite/tests/codeGen/should_run/all.T - testsuite/tests/concurrent/T13615/Parallel.hs - testsuite/tests/concurrent/should_run/T21651.hs - testsuite/tests/concurrent/should_run/setnumcapabilities001.hs - testsuite/tests/corelint/T27374.hs - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/cpranal/should_run/T20598a.hs - testsuite/tests/default/default-fail05.stderr - testsuite/tests/dependent/should_compile/T14729.stderr - testsuite/tests/deriving/should_compile/T13758.hs - testsuite/tests/deriving/should_run/all.T - + testsuite/tests/deriving/should_run/drvrun-canonical-methods.hs - + testsuite/tests/deriving/should_run/drvrun-canonical-methods.stderr - + testsuite/tests/deriving/should_run/drvrun-canonical-methods.stdout - testsuite/tests/determinism/determ017/A.hs - testsuite/tests/diagnostic-codes/codes.stdout - testsuite/tests/dmdanal/should_compile/T9208.hs - + testsuite/tests/dmdanal/should_run/T27845.hs - + testsuite/tests/dmdanal/should_run/T27845.stdout - + testsuite/tests/dmdanal/should_run/T27845_Lib.hs - + testsuite/tests/dmdanal/should_run/T27845b.hs - + testsuite/tests/dmdanal/should_run/T27845b.stdout - + testsuite/tests/dmdanal/should_run/T27845b_Lib.hs - testsuite/tests/dmdanal/should_run/all.T - testsuite/tests/driver/Makefile - testsuite/tests/driver/T27461/Makefile - + testsuite/tests/driver/T27461/T27461c.stderr - testsuite/tests/driver/T27461/all.T - + testsuite/tests/driver/T27461/src/Wrong.hs - + testsuite/tests/driver/T27836/A.hs - + testsuite/tests/driver/T27836/B.hs - + testsuite/tests/driver/T27836/C.hs - + testsuite/tests/driver/T27836/Makefile - + testsuite/tests/driver/T27836/T27836.stdout - + testsuite/tests/driver/T27836/all.T - + testsuite/tests/driver/T27836/unitA - + testsuite/tests/driver/T27836/unitB - + testsuite/tests/driver/T27836/unitC - + testsuite/tests/driver/T28009.hs - testsuite/tests/driver/all.T - testsuite/tests/generics/T27245.hs - testsuite/tests/generics/T27245.stdout - + testsuite/tests/ghc-api/T4162.hs - + testsuite/tests/ghc-api/T4162.stdout - testsuite/tests/ghc-api/all.T - testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.hs - testsuite/tests/ghc-api/downsweep/OldModLocation.hs - testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr - testsuite/tests/ghc-api/fixed-nodes/FixedNodes.hs - testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs - testsuite/tests/ghc-api/fixed-nodes/ModuleGraphInvariants.hs - testsuite/tests/ghci.debugger/scripts/T14628.stderr - testsuite/tests/ghci/prog-mhu001/prog-mhu001c.stdout - testsuite/tests/ghci/prog-mhu002/prog-mhu002d.stdout - testsuite/tests/ghci/prog020/ghci.prog020a.stderr - testsuite/tests/ghci/prog020/ghci.prog020b.stderr - testsuite/tests/ghci/prog021/prog021a.stderr - testsuite/tests/ghci/prog021/prog021b.stderr - testsuite/tests/ghci/prog022/ghci.prog022a.stderr - testsuite/tests/ghci/prog022/ghci.prog022b.stderr - testsuite/tests/ghci/prog022/ghci.prog022c.stderr - testsuite/tests/ghci/prog022/ghci.prog022d.stderr - testsuite/tests/ghci/prog022/ghci.prog022e.stderr - testsuite/tests/ghci/prog022/ghci.prog022f.stderr - testsuite/tests/ghci/scripts/Defer02.stderr - testsuite/tests/ghci/scripts/T16575.script - testsuite/tests/ghci/scripts/T16575.stdout - testsuite/tests/ghci/scripts/T16804.stdout - testsuite/tests/ghci/scripts/T20150.stdout - + testsuite/tests/ghci/scripts/T27412.hs - + testsuite/tests/ghci/scripts/T27412.script - + testsuite/tests/ghci/scripts/T27412.stdout - + testsuite/tests/ghci/scripts/T27641.script - + testsuite/tests/ghci/scripts/T27641.stderr - + testsuite/tests/ghci/scripts/T27641.stdout - + testsuite/tests/ghci/scripts/T27834.hs - + testsuite/tests/ghci/scripts/T27834.script - + testsuite/tests/ghci/scripts/T27834.stdout - testsuite/tests/ghci/scripts/all.T - testsuite/tests/haddock/perf/Fold.hs - testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/hiefile/should_compile/hie002.hs - testsuite/tests/hiefile/should_run/T24544.hs - + testsuite/tests/hpc/instmeths/instmeths.hs - + testsuite/tests/hpc/instmeths/instmeths.stdout - + testsuite/tests/hpc/instmeths/test.T - testsuite/tests/hpc/raytrace/Eval.hs - + testsuite/tests/impredicative/T27917.hs - testsuite/tests/impredicative/all.T - + testsuite/tests/indexed-types/should_compile/T27828.hs - + testsuite/tests/indexed-types/should_compile/T27828a.hs - + testsuite/tests/indexed-types/should_compile/T27828b.hs - testsuite/tests/indexed-types/should_compile/T3787.hs - + testsuite/tests/indexed-types/should_compile/ZapDeps.hs - testsuite/tests/indexed-types/should_compile/all.T - testsuite/tests/indexed-types/should_fail/T1897b.stderr - testsuite/tests/indexed-types/should_fail/T7729.hs - testsuite/tests/indexed-types/should_fail/T7729a.hs - testsuite/tests/indexed-types/should_fail/T9662.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/ghc-experimental-exports.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 - testsuite/tests/interface-stability/ghc-prim-exports.stdout - testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32 - testsuite/tests/javascript/Makefile - + testsuite/tests/javascript/T25665.hs - + testsuite/tests/javascript/T25665.pkg - + testsuite/tests/javascript/T25665.stdout - + testsuite/tests/javascript/T25665Lib.hs - + testsuite/tests/javascript/T25665_c.c - + testsuite/tests/javascript/T25665_js.js - testsuite/tests/javascript/all.T - testsuite/tests/module/mod130.stderr - testsuite/tests/module/mod133.hs - testsuite/tests/module/mod185.stderr - + testsuite/tests/numeric/should_run/T27545.hs - + testsuite/tests/numeric/should_run/T27545.stdout - testsuite/tests/numeric/should_run/all.T - testsuite/tests/overloadedstrings/should_fail/T25926.stderr - testsuite/tests/overloadedstrings/should_fail/T27124.stderr - testsuite/tests/package/T4806a.stderr - testsuite/tests/package/all.T - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr - testsuite/tests/parser/should_compile/DumpSemis.stderr - testsuite/tests/parser/should_compile/KindSigs.stderr - testsuite/tests/parser/should_compile/T14189.stderr - testsuite/tests/parser/should_compile/T15323.stderr - testsuite/tests/parser/should_compile/T20452.stderr - testsuite/tests/parser/should_compile/T20718.stderr - testsuite/tests/parser/should_compile/T20718b.stderr - testsuite/tests/parser/should_compile/T20846.stderr - testsuite/tests/parser/should_compile/T23315/T23315.stderr - testsuite/tests/patsyn/should_fail/records-nofieldselectors.stderr - testsuite/tests/perf/compiler/T13253.hs - testsuite/tests/perf/compiler/T14683.hs - testsuite/tests/perf/compiler/T16473.hs - testsuite/tests/perf/compiler/T18730_A.hs - testsuite/tests/perf/compiler/T25723.hs - testsuite/tests/perf/compiler/all.T - + testsuite/tests/plugins/T26761.hs - + testsuite/tests/plugins/T26761.stderr - + testsuite/tests/plugins/T26761Plugin.hs - + testsuite/tests/plugins/T26761a.hs - testsuite/tests/plugins/all.T - testsuite/tests/plugins/defaulting-plugin/DefaultLifted.hs - testsuite/tests/pmcheck/should_compile/T11276.hs - + testsuite/tests/primops/should_run/ResizeByteArrayPinnedness.hs - + testsuite/tests/primops/should_run/ResizeByteArrayPinnedness.stdout - testsuite/tests/primops/should_run/all.T - testsuite/tests/printer/AnnotationNoListTuplePuns.stdout - testsuite/tests/printer/T17697.stderr - testsuite/tests/printer/T18791.stderr - testsuite/tests/printer/Test20297.stdout - testsuite/tests/printer/Test24533.stdout - testsuite/tests/profiling/should_compile/T19894/StreamK.hs - testsuite/tests/profiling/should_run/Makefile - testsuite/tests/profiling/should_run/T3001-2.hs - testsuite/tests/profiling/should_run/caller-cc/CallerCcParser.hs - testsuite/tests/programs/galois_raytrace/Eval.hs - testsuite/tests/qualifieddo/should_compile/all.T - + testsuite/tests/qualifieddo/should_compile/qdocompile003.hs - + testsuite/tests/qualifieddo/should_compile/qdocompile003.stderr - testsuite/tests/qualifieddo/should_fail/all.T - + testsuite/tests/qualifieddo/should_fail/qdofail006.hs - + testsuite/tests/qualifieddo/should_fail/qdofail006.stderr - testsuite/tests/qualifieddo/should_run/all.T - + testsuite/tests/qualifieddo/should_run/qdorun008.hs - + testsuite/tests/qualifieddo/should_run/qdorun008.stdout - testsuite/tests/rebindable/rebindable2.hs - + testsuite/tests/rename/should_fail/Noncanonical.hs - + testsuite/tests/rename/should_fail/Noncanonical.stderr - testsuite/tests/rename/should_fail/T15607.stderr - testsuite/tests/rename/should_fail/T19843b.stderr - testsuite/tests/rename/should_fail/all.T - testsuite/tests/rename/should_fail/rnfail026.hs - testsuite/tests/rep-poly/RepPolyRule3.stderr - testsuite/tests/rts/Makefile - + testsuite/tests/rts/T24450.hs - + testsuite/tests/rts/T24450.stderr - + testsuite/tests/rts/T26408a.hs - + testsuite/tests/rts/T26408a.stderr - + testsuite/tests/rts/T26408b.hs - + testsuite/tests/rts/T26408b.stderr - + testsuite/tests/rts/T26408c.hs - + testsuite/tests/rts/T26408c.stdout - + testsuite/tests/rts/T26408d.hs - + testsuite/tests/rts/T26408d.stderr - + testsuite/tests/rts/T27526.hs - + testsuite/tests/rts/T27526.stdout - + testsuite/tests/rts/T28012.hs - + testsuite/tests/rts/T28012.stdout - testsuite/tests/rts/all.T - testsuite/tests/rts/ipe/IpeStats/Fold.hs - testsuite/tests/rts/rtsflags001.stderr-ws-32 - testsuite/tests/rts/rtsflags001.stderr-ws-64 - testsuite/tests/safeHaskell/ghci/p4.stderr - testsuite/tests/safeHaskell/ghci/p6.stderr - testsuite/tests/simplCore/should_compile/T14908_Deps.hs - testsuite/tests/simplCore/should_compile/T22375.stderr - testsuite/tests/simplCore/should_compile/T22375DataFamily.stderr - testsuite/tests/simplCore/should_compile/T22611.hs - testsuite/tests/simplCore/should_compile/T22611.stderr - + testsuite/tests/simplCore/should_compile/T22611a.hs - testsuite/tests/simplCore/should_compile/T26051.stderr - + testsuite/tests/simplCore/should_compile/T27910.hs - + testsuite/tests/simplCore/should_compile/T27910.stderr - + testsuite/tests/simplCore/should_compile/T27936.hs - + testsuite/tests/simplCore/should_compile/T7803.hs - + testsuite/tests/simplCore/should_compile/T7803.stderr - + testsuite/tests/simplCore/should_compile/T7803a.hs - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/simplCore/should_compile/simpl017.hs - testsuite/tests/simplStg/should_compile/all.T - + testsuite/tests/simplStg/should_compile/inferTags005.hs - + testsuite/tests/simplStg/should_compile/inferTags005.stderr - + testsuite/tests/simplStg/should_compile/inferTags006.hs - + testsuite/tests/simplStg/should_compile/inferTags006.stderr - + testsuite/tests/simplStg/should_run/InferTags007_A.hs - + testsuite/tests/simplStg/should_run/T27831.hs - + testsuite/tests/simplStg/should_run/T27831.stdout - + testsuite/tests/simplStg/should_run/T27857.hs - + testsuite/tests/simplStg/should_run/T27857.stdout - testsuite/tests/simplStg/should_run/all.T - + testsuite/tests/simplStg/should_run/inferTags007.hs - + testsuite/tests/simplStg/should_run/inferTags007.stdout - testsuite/tests/splice-imports/SI35.hs - testsuite/tests/typecheck/should_compile/DeepSubsumption02.hs - testsuite/tests/typecheck/should_compile/LocalGivenEqs.hs - testsuite/tests/typecheck/should_compile/T11254.stderr - testsuite/tests/typecheck/should_compile/T15370.stderr - + testsuite/tests/typecheck/should_compile/T26543_orig.hs - + testsuite/tests/typecheck/should_compile/T27916.hs - testsuite/tests/typecheck/should_compile/T4524.hs - testsuite/tests/typecheck/should_compile/T4969.hs - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_compile/valid_hole_fits.stderr - testsuite/tests/typecheck/should_fail/ClassOperator.stderr - testsuite/tests/typecheck/should_fail/DoExpansion2.stderr - testsuite/tests/typecheck/should_fail/DoExpansion3.stderr - testsuite/tests/typecheck/should_fail/FunDepOrigin1b.hs - testsuite/tests/typecheck/should_fail/T12785b.stderr - testsuite/tests/typecheck/should_fail/T18851.stderr - + testsuite/tests/typecheck/should_fail/T18851e.hs - + testsuite/tests/typecheck/should_fail/T18851e.stderr - + testsuite/tests/typecheck/should_fail/T18851f.hs - + testsuite/tests/typecheck/should_fail/T18851f.stderr - testsuite/tests/typecheck/should_fail/T22707.hs - testsuite/tests/typecheck/should_fail/T22940.stderr - testsuite/tests/typecheck/should_fail/T25950.stderr - + testsuite/tests/typecheck/should_fail/T26543a.hs - + testsuite/tests/typecheck/should_fail/T26543a.stderr - testsuite/tests/typecheck/should_fail/T26823.stderr - + testsuite/tests/typecheck/should_fail/T27731.hs - + testsuite/tests/typecheck/should_fail/T27731.stderr - + testsuite/tests/typecheck/should_fail/T27844.hs - + testsuite/tests/typecheck/should_fail/T27844.stderr - testsuite/tests/typecheck/should_fail/T5691.stderr - testsuite/tests/typecheck/should_fail/T7019.hs - testsuite/tests/typecheck/should_fail/T7437.stderr - testsuite/tests/typecheck/should_fail/T8450.stderr - testsuite/tests/typecheck/should_fail/T8603.hs - testsuite/tests/typecheck/should_fail/all.T - testsuite/tests/typecheck/should_fail/mc24.stderr - testsuite/tests/typecheck/should_fail/tcfail019.stderr - testsuite/tests/typecheck/should_fail/tcfail189.stderr - + testsuite/tests/warnings/should_compile/RedundantCanonicalMethods.hs - + testsuite/tests/warnings/should_compile/RedundantCanonicalMethods.stderr - testsuite/tests/warnings/should_compile/WarnNoncanonical.hs - testsuite/tests/warnings/should_compile/WarnNoncanonical.stderr - testsuite/tests/warnings/should_compile/all.T - utils/check-exact/ExactPrint.hs - utils/check-exact/Parsers.hs - utils/check-exact/Utils.hs - utils/check-ppr/Main.hs - utils/count-deps/Main.hs - utils/dump-decls/Main.hs - utils/haddock/haddock-api/haddock-api.cabal - utils/haddock/haddock-api/src/Haddock.hs - utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs - utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Renderer.hs - utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Utils.hs - utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs - utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs - utils/haddock/haddock-api/src/Haddock/Convert.hs - utils/haddock/haddock-api/src/Haddock/Interface.hs - utils/haddock/haddock-api/src/Haddock/Interface/ParseModuleHeader.hs - utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs - utils/haddock/haddock-api/src/Haddock/Types.hs - utils/haddock/haddock-api/src/Haddock/Utils/Json.hs - utils/haddock/haddock-api/test/Haddock/Backends/Hyperlinker/ParserSpec.hs - utils/haddock/haddock-library/haddock-library.cabal - utils/haddock/haddock.cabal - utils/runghc/Main.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/06de1e3c2c884985c05344883f4f383... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/06de1e3c2c884985c05344883f4f383... You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
participants (1)
-
Duncan Coutts (@dcoutts)