[Git][ghc/ghc][wip/dcoutts/signals-cleanup] 135 commits: Add regression test for #7803
by Duncan Coutts (@dcoutts) 02 Nov '26
by Duncan Coutts (@dcoutts) 02 Nov '26
02 Nov '26
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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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/06de1e3c2c884985c05344883f4f38…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/06de1e3c2c884985c05344883f4f38…
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
1
0
[Git][ghc/ghc][wip/ani/T27156] add reSynBindsE in GHC.Essentials. Remove ReSynBindsTc as we should not need...
by Apoorv Ingle (@ani) 02 Nov '26
by Apoorv Ingle (@ani) 02 Nov '26
02 Nov '26
Apoorv Ingle pushed to branch wip/ani/T27156 at Glasgow Haskell Compiler / GHC
Commits:
e01782f2 by Apoorv Ingle at 2026-11-02T12:20:52-06:00
add reSynBindsE in GHC.Essentials. Remove ReSynBindsTc as we should not need it. Add a tcExpand stub for ReSynBindsRn that should expand to the appropriate expression
- - - - -
10 changed files:
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Tc/Gen/Expand.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Zonk/Type.hs
- libraries/base/src/GHC/Essentials.hs
Changes:
=====================================
compiler/GHC/Hs/Expr.hs
=====================================
@@ -715,7 +715,6 @@ data XXExprGhcTc
| HsRecSelTc (FieldOcc GhcTc) -- ^ Variable pointing to record selector
-- See Note [Non-overloaded record field selectors] and
-- Note [Record selectors in the AST]
- | ReSynBindsTc HsModuleName (HsExpr GhcTc)
{- *********************************************************************
* *
@@ -1091,8 +1090,6 @@ instance Outputable XXExprGhcTc where
ppr exp, text ")"]
ppr (HsRecSelTc f) = pprPrefixOcc f
- ppr (ReSynBindsTc m e) = text "{{" <+> ppr m <+> text "}}" <+> ppr e
-
ppr_infix_expr :: forall p. (OutputableBndrId p) => HsExpr (GhcPass p) -> Maybe SDoc
ppr_infix_expr (HsVar _ (L _ v)) = Just (pprInfixOcc v)
ppr_infix_expr (HsHole x) = Just $ pprInfixOcc $ case (ghcPass @p, x) of
@@ -1121,7 +1118,6 @@ ppr_infix_expr_tc (ConLikeTc con) = Just (pprInfixOcc (conLikeName co
ppr_infix_expr_tc (HsTick {}) = Nothing
ppr_infix_expr_tc (HsBinTick {}) = Nothing
ppr_infix_expr_tc (HsRecSelTc f) = Just (pprInfixOcc f)
-ppr_infix_expr_tc (ReSynBindsTc _ e) = ppr_infix_expr e
ppr_infix_hs_expansion :: HsCtxt -> Maybe SDoc
ppr_infix_hs_expansion (ExprCtxt e) = ppr_infix_expr e
@@ -1215,7 +1211,6 @@ hsExprNeedsParens prec = go
go_x_tc (HsTick _ (L _ e)) = hsExprNeedsParens prec e
go_x_tc (HsBinTick _ _ (L _ e)) = hsExprNeedsParens prec e
go_x_tc (HsRecSelTc{}) = False
- go_x_tc (ReSynBindsTc _ e) = hsExprNeedsParens prec e
go_x_rn :: XXExprGhcRn -> Bool
go_x_rn (ExpandedThingRn (HSE thing _)) = hsExpandedNeedsParens thing
@@ -1269,7 +1264,6 @@ isAtomicHsExpr (XExpr x)
go_x_tc (HsTick {}) = False
go_x_tc (HsBinTick {}) = False
go_x_tc (HsRecSelTc{}) = True
- go_x_tc (ReSynBindsTc _ e) = isAtomicHsExpr e
go_x_rn :: XXExprGhcRn -> Bool
go_x_rn (ExpandedThingRn (HSE thing _)) = isAtomicExpandedThingRn thing
=====================================
compiler/GHC/Hs/Syn/Type.hs
=====================================
@@ -170,7 +170,6 @@ hsExprType (XExpr (ConLikeTc con)) = conLikeType con
hsExprType (XExpr (HsTick _ e)) = lhsExprType e
hsExprType (XExpr (HsBinTick _ _ e)) = lhsExprType e
hsExprType (XExpr (HsRecSelTc (FieldOcc _ id))) = idType (unLoc id)
-hsExprType (XExpr (ReSynBindsTc _ e)) = hsExprType e
arithSeqInfoType :: ArithSeqInfo GhcTc -> Type
arithSeqInfoType asi = mkListTy $ case asi of
=====================================
compiler/GHC/HsToCore/Expr.hs
=====================================
@@ -310,10 +310,6 @@ dsExpr e@(XExpr ext_expr_tc)
ConLikeTc {} -> dsApp e
ExpandedThingTc (HSE _ e) -> dsLExpr e
- ReSynBindsTc m e ->
- do
- tracePm "dsExpr XExpr" (ppr m)
- dsExpr e --TODO ANI: This should never happen?
-- Hpc Support
HsTick tickish e -> do
=====================================
compiler/GHC/HsToCore/Ticks.hs
=====================================
@@ -708,9 +708,6 @@ addTickHsExpr (XExpr (HsBinTick t0 t1 e)) =
liftM (XExpr . HsBinTick t0 t1) (addTickLHsExprNever e)
addTickHsExpr e@(XExpr (HsRecSelTc (FieldOcc _ id))) = do freeVar (unLoc id); return e
-addTickHsExpr (XExpr (ReSynBindsTc m e)) =
- liftM (XExpr . ReSynBindsTc m) (addTickHsExpr e)
-
addTickHsExpr (HsDo srcloc cxt (L l stmts))
= do { (stmts', _) <- addTickLStmts' forQual stmts (return ())
=====================================
compiler/GHC/Iface/Ext/Ast.hs
=====================================
@@ -1377,8 +1377,6 @@ instance HiePass p => ToHie (LocatedA (HsExpr (GhcPass p))) where
HsBinTick _ _ expr
-> [ toHie expr
]
- ReSynBindsTc _ _
- -> []
HsRecSelTc fld
-> [ toHie $ RFC RecFieldOcc Nothing (L mspan fld)
]
=====================================
compiler/GHC/Rename/Expr.hs
=====================================
@@ -610,7 +610,7 @@ rnExpr (HsFunArr _ mult arg res)
rnExpr (XExpr (ReSynBindsPs m e))
= do { traceRn "XExpr ReSynBinds" (text "module:" <+> ppr m)
; (e', fvs) <- rnExpr e
- ; return (e', fvs)
+ ; return (XExpr (ReSynBindsRn m e'), fvs)
}
{-
=====================================
compiler/GHC/Tc/Gen/Expand.hs
=====================================
@@ -288,10 +288,31 @@ tcExpand e@(HsUntypedSplice splice_res _)
------------------------
-- XExpr
+tcExpand e@(XExpr (ReSynBindsRn _ inner_e))
+ = do { -- set environment variable to be in rebindable syntax
+ -- add the required rebindable syntax binding names into the environment
+ -- try expanding inner_e
+ traceTc "tcExpand: ReSynBindsRn" (ppr e)
+ ; e' <- tcExpand inner_e
+ ; let expr = case e' of
+ Just (HSE {hse_exp = expanded_e}) ->
+ expanded_e
+ Nothing ->
+ -- likely that inner_e does not contain anything expandable
+ -- so we just return inner_e
+ wrapGenSpan inner_e
+ ; return $ Just $
+ HSE { hse_ctxt = ExprCtxt e
+ , hse_exp = expr }
+ }
+
+
-- Expansions are idempotent, XExprs do not expand again
tcExpand (XExpr (ExpandedThingRn hse))
= return $ Just hse
+
+
tcExpand _ = return $ Nothing
=====================================
compiler/GHC/Tc/Gen/Expr.hs
=====================================
@@ -767,11 +767,6 @@ tcExprNoExpand (ArithSeq _ witness seq) res_ty
tcExprNoExpand (HsTypedSplice ext splice) res_ty = tcTypedSplice ext splice res_ty
tcExprNoExpand e@(HsTypedBracket _ext body) res_ty = tcTypedBracket e body res_ty
tcExprNoExpand e@(HsUntypedBracket ps body) res_ty = tcUntypedBracket e body ps res_ty
-tcExprNoExpand (XExpr (ReSynBindsRn m e)) res_ty
- = do { traceTc "XExpr ReSynBinds" (text "module:" <+> ppr m)
- ; e' <- tcExpr e res_ty
- ; return $ XExpr (ReSynBindsTc m e')
- }
{-
************************************************************************
=====================================
compiler/GHC/Tc/Zonk/Type.hs
=====================================
@@ -1096,10 +1096,6 @@ zonkExpr (XExpr (HsRecSelTc (FieldOcc occ (L l v))))
= do { v' <- zonkIdOcc v
; return (XExpr (HsRecSelTc (FieldOcc occ (L l v')))) }
-zonkExpr (XExpr (ReSynBindsTc m e))
- = do e' <- zonkExpr e
- return $ (XExpr (ReSynBindsTc m e'))
-
zonkExpr (RecordUpd x _ _) = dataConCantHappen x
zonkExpr (HsGetField x _ _) = dataConCantHappen x
zonkExpr (HsProjection x _) = dataConCantHappen x
=====================================
libraries/base/src/GHC/Essentials.hs
=====================================
@@ -227,7 +227,7 @@ module GHC.Essentials
, lamE, lamCaseE, lamCasesE, tupE, unboxedTupE, unboxedSumE, condE, multiIfE
, letE, caseE, doE, mdoE, compE, fromE, fromThenE, fromToE, fromThenToE
, listE, sigE, recConE, recUpdE, staticE, unboundVarE, labelE, implicitParamVarE
- , getFieldE, projectionE, typeE, forallE, forallVisE, constrainedE
+ , getFieldE, projectionE, typeE, forallE, forallVisE, constrainedE, reSynBindsE
, TH.cxt
, TH.noSourceUnpackedness, TH.sourceNoUnpack, TH.sourceUnpack
, TH.noSourceStrictness, TH.sourceLazy, TH.sourceStrict
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e01782f263bf75628574d508bbeb331…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e01782f263bf75628574d508bbeb331…
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
1
0
[Git][ghc/ghc][wip/ani/T27156] 40 commits: Add single-threaded test for #27526 + #27123
by Apoorv Ingle (@ani) 02 Nov '26
by Apoorv Ingle (@ani) 02 Nov '26
02 Nov '26
Apoorv Ingle pushed to branch wip/ani/T27156 at Glasgow Haskell Compiler / GHC
Commits:
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.
- - - - -
cc533b66 by Sasha Bogicevic at 2026-10-31T09:18:15-04:00
Don't report -XStrict-generated bangs under -Wredundant-bang-patterns
The -XStrict flag causes the desugarer to insert bang patterns.
These are not user-written, so -Wredundant-bang-patterns must not
report them.
To achieve this, the desugarer now tracks whether it is desugaring
compiler-generated code (similar to the typechecker's 'tcl_in_gen_code').
Bangs inserted by -XStrict are given generated spans, which suppresses
the "redundant bang" warnings without otherwise affecting pattern-match
warnings.
Fixes #27323
- - - - -
13d38047 by Luite Stegeman at 2026-10-31T09:19:11-04:00
rts: tombstone Weak# copies that lose an evacuation race (#23160)
Mark the losing copy of a Weak# during an evacuation race in parallel
GC with stg_DEAD_WEAK_info. This ensures that the nonmoving GC
doesn't follow dangling pointers, leading to crashes.
Fixes #23160
- - - - -
63347328 by Zubin Duggal at 2026-10-31T09:19:52-04:00
ghci: Drop GHCi's exception context when rethrowing in ghc -e
Fixes #27847.
- - - - -
a85fef3f by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context in modifyIOError
Fixes #27851.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/446
- - - - -
1d60b591 by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context in mapException
Fixes #27851.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/446
- - - - -
3c029a1b by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context when rethrowing exceptions in Handle reads
Fixes #27875.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/447
- - - - -
ab2b317a by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context when rethrowing exceptions in hClose
Fixes #27875.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/447
- - - - -
f5abf277 by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context when rethrowing exceptions in Windows openFile
Fixes #27875.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/447
- - - - -
d842c672 by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context when rethrowing exceptions in executablePath
Fixes #27875.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/447
- - - - -
c5a8bb9f by Simon Peyton Jones at 2026-10-31T09:20:34-04:00
Simplify a tc-trace which could crash the compiler
The trace formatted an error message, which prematurely
read the ExpType in a FunResCtxt.
Solution: don't put call the error message formatting
when tc-tracing.
- - - - -
ab49b1d2 by Simon Peyton Jones at 2026-10-31T09:20:34-04:00
Tiny comment change to uniqAway
- - - - -
6efe4ba3 by Simon Peyton Jones at 2026-10-31T09:20:34-04:00
Make niFixSubst idempotent
I discovered (when fixing #27994) that `niFixSubst` didn't actually
generate an idempotent subsitution despite its claims. It could
return a substitution that mentions domain variables on in its range,
when those variables are hidden inside the kind of a type variable
occurrence. As a result it can generate ill-kinded types. Boo!
The fix is simple, and uses deep substitution.
See Note [Finding the substitution fixpoint]
I don't think it actually /caused/ any bugs, so there is no
regression test.
- - - - -
3b60ae7e by Simon Peyton Jones at 2026-10-31T09:20:34-04:00
Fix a nasty bug in fundeps
This MR fixes #27994, which turned out to be very tricky.
See Note [Exploiting closed type famililes], especially (CF7). I was
ending up with TyVars (not TcTyVars) in the solver, because the
substitution computed in `getRelevantBranches` mixed the two.
The code was just too clever. I ended up simplifying it quite a bit.
For /closed/ families we no longer call `trimQtvs` (was `trim_qtvs`).
Open families still do use `trimQtvs`. See Note [trimQTvs]
This patch also fixes one other buglet in the same code.
* Over-saturated type families were being mis-handled.
See the new use of `saturatedFamApp_maybe`.
- - - - -
e4610f2d by Facundo Domínguez at 2026-10-31T09:21:24-04:00
Have haddock --incremental look for the module in -this-unit-id
- - - - -
bc6c0db6 by sheaf at 2026-10-31T09:22:20-04:00
mightBeFunTy: hotfix for #27979
ce01ccb6 refactored 'GHC.Types.RepType.mightBeFunTy' to look through
unary classes. That change introduced the helper function 'unwrap_type'
which was supposed to always return an unwrapped type, but its fallback
equation mistakenly returned the original type. This caused the
subsequent 'tyConAppTyCon_maybe' to fail in cases where it should
succeed (e.g. looking through foralls).
In this commit, we move all the unary class unwrapping logic into
'unwrapType' where it belonged from the start, and update the
documentation of 'unwrapType' to better explain what it should be used
for (#26695).
Fixes #27979 #26695
-------------------------
Metric Increase:
T5642
-------------------------
- - - - -
233cce46 by Alan Zimmerman at 2026-10-31T09:23:01-04:00
EPA: Tidy up ExactPrint.markAnnListA'
It takes an action which can modify the AnnList, but this
is never used. So remove it.
- - - - -
3594a908 by Sylvain Henry at 2026-10-31T09:23:51-04:00
gitmodules: ignore dirty libffi-clib submodule (#26785)
`./boot` runs autoreconf in libraries/libffi-clib, which leaves
`configure~` behind and rewrites the tracked `aclocal.m4` whenever the
local automake version differs from the one that generated it. Every
checkout then looks dirty. Ignore working-tree changes in the submodule
(`ignore = dirty`); a changed submodule commit is still reported.
Co-Authored-By: Claude Fable 5.1 <noreply(a)anthropic.com>
- - - - -
341223c0 by Rodrigo Mesquita at 2026-10-31T09:24:33-04:00
refactor: Keep the interactive Ids directly rather than Name
Removes things like
names <- map idName ids
map (\i -> let id = find (\x -> i==idName x) names) idso
and is more straightforward because there's less state going around (no
more updating HscEnv as an output)
It also kills `printTypeOfNames` completely, since now we just have the
Ids. No longer `lookupName` names to get back the ids...
```
printTypeOfName :: GHC.GhcMonad m => Name -> m ()
printTypeOfName n
= do maybe_tything <- GHC.lookupName n
case maybe_tything of
Nothing -> return ()
Just thing -> printTyThing thing
```
now is just `printTyThing . AnId`
Also:
```diff
- tythings <- catMaybes `liftM` mapM GHC.lookupName namesSorted
- docs <- mapM pprTypeAndContents [i | AnId i <- tythings]
+ docs <- mapM pprTypeAndContents idsSorted
```
(and yes, in ExecBreaks there are only Ids, no TyThings, bc they are
only constructed by the interpreter execution which can only bind ids.
for TyThings use runDecls which doesn't return execBreaks.)
There's some care to be had to make sure we use the "most refined" Ids,
whereas when using `Name`s we'd always fetch the most refined Id from
scratch.
Fixes #28052
- - - - -
df3558b6 by Apoorv Ingle at 2026-11-02T11:54:55-06:00
Work on #27156
- Add `RebindableSyntaxTable` to store function/operator names while renaming in the XBlah fields
- Expand the following expressions right before typechecking instead of in the renamer
* OverloadedLabel
* RecordDotSyntax: HsGetField and HsProjection
* ExplicitList
* RecordUpd
* HsIf
* HsDo (Vanilla cases)
- - - - -
4604dfea by Apoorv Ingle at 2026-11-02T11:54:55-06:00
make a new ReSynBinds to store the module name
- - - - -
0ff6e353 by Apoorv Ingle at 2026-11-02T11:54:55-06:00
add ReSynBindsE, ReSynBindsRn and ReSynBindsTc
- - - - -
d1a01e4c by Apoorv Ingle at 2026-11-02T11:54:55-06:00
add reSynBindsE in GHC.Essentials. Remove ReSynBindsTc as we should not need it. Add a tcExpand stub for ReSynBindsRn that should expand to the appropriate expression
- - - - -
205 changed files:
- .gitmodules
- + changelog.d/T27156
- + changelog.d/T27323
- + changelog.d/T27763
- + changelog.d/T27847
- + changelog.d/T27979
- + changelog.d/T27994
- + changelog.d/T28002
- + changelog.d/T28002-api
- + changelog.d/clc-446
- + changelog.d/clc-447
- + changelog.d/fix-nonmoving-weak-evacuation-race-23160
- + changelog.d/ghc-api-interactive-ids
- + changelog.d/ncg-x86-subword-popcnt
- + changelog.d/parallel-downsweep
- compiler/GHC.hs
- compiler/GHC/Builtin.hs
- compiler/GHC/Builtin/TH.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/Core/Coercion/Axiom.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unify.hs
- + compiler/GHC/Data/Dependent.hs
- compiler/GHC/Driver/Backpack.hs
- + compiler/GHC/Driver/Concurrency.hs
- + compiler/GHC/Driver/Config/Concurrency.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Errors/Types.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/Execute.hs
- compiler/GHC/Driver/Pipeline/LogQueue.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Types.hs
- compiler/GHC/HsToCore/Utils.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Header.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Runtime/Context.hs
- compiler/GHC/Runtime/Debugger.hs
- compiler/GHC/Runtime/Eval.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/StgToJS/Linker/Linker.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Do.hs
- compiler/GHC/Tc/Gen/Expand.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Instance/Family.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Plugin.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Backpack.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Annotations.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Types/UnresolvedImport.hs
- compiler/GHC/Types/Var/Env.hs
- compiler/GHC/Unit/Finder.hs
- + compiler/GHC/Unit/Finder/Cache.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- + compiler/GHC/Utils/Concurrent/Scope.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/GHC/Utils/TmpFs.hs
- compiler/ghc.cabal.in
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Monad.hs
- ghc/Main.hs
- libraries/base/changelog.md
- libraries/base/src/GHC/Essentials.hs
- libraries/ghc-boot-th/GHC/Boot/TH/Ppr.hs
- libraries/ghc-boot/GHC/Serialized.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Exception/Base.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Internals.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Text.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Windows.hs
- libraries/ghc-internal/src/GHC/Internal/System/Environment/ExecutablePath.hsc
- libraries/ghc-internal/src/GHC/Internal/System/IO/Error.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/TH.hs
- libraries/ghci/GHCi/TH/Binary.hs
- linters/lint-codes/LintCodes/Static.hs
- rts/sm/Evac.c
- 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/codeGen/should_compile/T27979.hs
- + testsuite/tests/codeGen/should_compile/T27979.stderr
- 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/count-deps/CountDepsParser.stdout
- testsuite/tests/diagnostic-codes/codes.stdout
- 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/T28009.hs
- testsuite/tests/driver/all.T
- + testsuite/tests/exceptions/T27851.hs
- + testsuite/tests/exceptions/T27851.stderr
- + testsuite/tests/exceptions/T27851b.hs
- + testsuite/tests/exceptions/T27851b.stderr
- + testsuite/tests/exceptions/T27851c.hs
- + testsuite/tests/exceptions/T27851c.stdout
- + testsuite/tests/exceptions/T27851d.hs
- + testsuite/tests/exceptions/T27851d.stdout
- + testsuite/tests/exceptions/T27851d.stdout-javascript-unknown-ghcjs
- testsuite/tests/exceptions/all.T
- testsuite/tests/ghc-api/T25121_status.stdout
- 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/fixed-nodes/FixedNodes.hs
- testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs
- testsuite/tests/ghc-api/fixed-nodes/ModuleGraphInvariants.hs
- testsuite/tests/ghc-e/should_fail/T18441fail7.stderr
- testsuite/tests/ghc-e/should_run/ghc-e005.stderr
- + testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.hs
- + testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.script
- + testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.stdout
- testsuite/tests/ghci.debugger/scripts/T14628.stderr
- testsuite/tests/ghci.debugger/scripts/all.T
- + testsuite/tests/haddock/haddock_testsuite/IncrementalUnitId.hs
- testsuite/tests/haddock/haddock_testsuite/Makefile
- testsuite/tests/haddock/haddock_testsuite/all.T
- + testsuite/tests/haddock/haddock_testsuite/haddockIncrementalUnitId.stdout
- testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/KindSigs.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail9.stderr
- testsuite/tests/plugins/T26761Plugin.hs
- testsuite/tests/plugins/all.T
- testsuite/tests/plugins/defaulting-plugin/DefaultLifted.hs
- + testsuite/tests/pmcheck/should_compile/T27323.hs
- + testsuite/tests/pmcheck/should_compile/T27323b.hs
- testsuite/tests/pmcheck/should_compile/all.T
- testsuite/tests/printer/Test24533.stdout
- testsuite/tests/rebindable/T19918.stdout
- + testsuite/tests/rts/T23160.hs
- + testsuite/tests/rts/T23160.stdout
- + testsuite/tests/rts/T27526.hs
- + testsuite/tests/rts/T27526.stdout
- testsuite/tests/rts/all.T
- testsuite/tests/splice-imports/SI35.hs
- testsuite/tests/th/T18102b.stdout
- + testsuite/tests/typecheck/should_compile/T27994.hs
- + testsuite/tests/typecheck/should_compile/T27994a.hs
- + testsuite/tests/typecheck/should_compile/T27994b.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T22707.stderr
- testsuite/tests/typecheck/should_fail/T25950.stderr
- testsuite/tests/typecheck/should_fail/T8450.stderr
- testsuite/tests/warnings/should_compile/Overflow.stderr-ws-32
- testsuite/tests/warnings/should_compile/Overflow.stderr-ws-64
- testsuite/tests/warnings/should_compile/T13256.stderr-ws-32
- testsuite/tests/warnings/should_compile/T13256.stderr-ws-64
- utils/check-exact/ExactPrint.hs
- utils/check-ppr/Main.hs
- utils/haddock/CHANGES.md
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/Interface.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c08de6ddecb5f2170a4148b0213f11…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c08de6ddecb5f2170a4148b0213f11…
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
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Consolidate all CPU feature handling
by Marge Bot (@marge-bot) 02 Nov '26
by Marge Bot (@marge-bot) 02 Nov '26
02 Nov '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
ecd2b759 by sheaf at 2026-11-02T12:49:00-05:00
Consolidate all CPU feature handling
This commit introduces GHC.Platform.CpuFeatures which consolidates all
of the logic for implications between CPU feature flags (mainly X86):
- DynFlags now only records the set of -m<feature> flags that were
passed, as an EnumSet CpuFeature. That keeps it a simple record of
the flags the user passed, with no post-processing.
- GHC.Platform.CpuFeatures.initCpuFeatures turns this set into a
CpuFeatures value, applying all implications and the per-architecture
baseline. This is the single home for all of the feature implication
logic.
Some datatypes were reworked to better reflect the implication
structure in the types, e.g. SseAvxVersion has a strategically
placed 'FMA' boolean.
- The NCG, LLVM backend, StgToCmm, CPP defines and LLVM -mattr
flags all consult CpuFeatures, via targetCpuFeatures.
See Note [CPU features], which replaces
Note [Implications between X86 CPU feature flags].
Behaviour changes:
- x86 feature flags (-msse3, -mavx, -mavx512*, -mgfni, ...) passed
when targeting a non-x86 architecture no longer cause x86 CPP
macros (__SSE3__, __AVX512BW__, __GFNI__, ...) to be defined, nor
x86 attributes to be passed to LLVM.
- Error messages reported when required CPU features are not enabled
now print out the minimal set of flags required
(e.g. "-mavx512vl" rather than "-mavx512f -mavx512vl").
- - - - -
cc7b5276 by Luite Stegeman at 2026-11-02T12:49:15-05:00
rts: move stack check to the start of the stg_unpack_cstring thunks
fixes a deadlock
see #27272
- - - - -
afa31101 by Simon Jakobi at 2026-11-02T12:49:16-05:00
Cmm: exclude the entry block from common block elimination
a1d8139054c had fixed #27722 only partially, because it didn't prevent
elimination of the entry block in later rounds, where the entry block is
no longer guaranteed to come first.
To close this loophole, we exclude the entry block from the CBE merge
logic. See Note [Retain entry block during common block elimination] for
details.
This also deletes a misleading comment regarding unreachable blocks: the
control-flow optimiser doesn't actually guarantee that no unreachable
blocks reach CBE.
Fixes #27722.
Assisted-by: Claude Fable 5.1
- - - - -
f70da46a by Alan Zimmerman at 2026-11-02T12:49:16-05:00
EPA: Use AnnList for GADT declarations
Continuing the process of using AnnList to capture parser layout
- - - - -
44 changed files:
- changelog.d/T27722-cbe-entry-block.md
- + changelog.d/caf-deadlock-27272
- compiler/GHC/Cmm/CallConv.hs
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/CmmToAsm/Config.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/CmmToLlvm/Config.hs
- compiler/GHC/Driver/Config/CmmToAsm.hs
- compiler/GHC/Driver/Config/CmmToLlvm.hs
- compiler/GHC/Driver/Config/StgToCmm.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Platform.hs
- + compiler/GHC/Platform/CpuFeatures.hs
- compiler/GHC/StgToCmm/Config.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/ghc.cabal.in
- rts/StgStdThunks.cmm
- + testsuite/tests/cmm/should_run/T27722.hs
- + testsuite/tests/cmm/should_run/T27722_cmm.cmm
- testsuite/tests/cmm/should_run/all.T
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/ghc-api/exactprint/Test20239.stderr
- 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/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T15323.stderr
- testsuite/tests/parser/should_compile/T20452.stderr
- testsuite/tests/printer/T18791.stderr
- + testsuite/tests/rts/T27272.hs
- + testsuite/tests/rts/T27272_gen.py
- testsuite/tests/rts/all.T
- utils/check-exact/ExactPrint.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1130173e2fb27864061e1b211912fe…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1130173e2fb27864061e1b211912fe…
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
1
0
[Git][ghc/ghc][wip/T27212] 21 commits: Don't report -XStrict-generated bangs under -Wredundant-bang-patterns
by Simon Peyton Jones (@simonpj) 02 Nov '26
by Simon Peyton Jones (@simonpj) 02 Nov '26
02 Nov '26
Simon Peyton Jones pushed to branch wip/T27212 at Glasgow Haskell Compiler / GHC
Commits:
cc533b66 by Sasha Bogicevic at 2026-10-31T09:18:15-04:00
Don't report -XStrict-generated bangs under -Wredundant-bang-patterns
The -XStrict flag causes the desugarer to insert bang patterns.
These are not user-written, so -Wredundant-bang-patterns must not
report them.
To achieve this, the desugarer now tracks whether it is desugaring
compiler-generated code (similar to the typechecker's 'tcl_in_gen_code').
Bangs inserted by -XStrict are given generated spans, which suppresses
the "redundant bang" warnings without otherwise affecting pattern-match
warnings.
Fixes #27323
- - - - -
13d38047 by Luite Stegeman at 2026-10-31T09:19:11-04:00
rts: tombstone Weak# copies that lose an evacuation race (#23160)
Mark the losing copy of a Weak# during an evacuation race in parallel
GC with stg_DEAD_WEAK_info. This ensures that the nonmoving GC
doesn't follow dangling pointers, leading to crashes.
Fixes #23160
- - - - -
63347328 by Zubin Duggal at 2026-10-31T09:19:52-04:00
ghci: Drop GHCi's exception context when rethrowing in ghc -e
Fixes #27847.
- - - - -
a85fef3f by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context in modifyIOError
Fixes #27851.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/446
- - - - -
1d60b591 by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context in mapException
Fixes #27851.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/446
- - - - -
3c029a1b by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context when rethrowing exceptions in Handle reads
Fixes #27875.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/447
- - - - -
ab2b317a by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context when rethrowing exceptions in hClose
Fixes #27875.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/447
- - - - -
f5abf277 by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context when rethrowing exceptions in Windows openFile
Fixes #27875.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/447
- - - - -
d842c672 by Zubin Duggal at 2026-10-31T09:19:52-04:00
base: Preserve exception context when rethrowing exceptions in executablePath
Fixes #27875.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/447
- - - - -
c5a8bb9f by Simon Peyton Jones at 2026-10-31T09:20:34-04:00
Simplify a tc-trace which could crash the compiler
The trace formatted an error message, which prematurely
read the ExpType in a FunResCtxt.
Solution: don't put call the error message formatting
when tc-tracing.
- - - - -
ab49b1d2 by Simon Peyton Jones at 2026-10-31T09:20:34-04:00
Tiny comment change to uniqAway
- - - - -
6efe4ba3 by Simon Peyton Jones at 2026-10-31T09:20:34-04:00
Make niFixSubst idempotent
I discovered (when fixing #27994) that `niFixSubst` didn't actually
generate an idempotent subsitution despite its claims. It could
return a substitution that mentions domain variables on in its range,
when those variables are hidden inside the kind of a type variable
occurrence. As a result it can generate ill-kinded types. Boo!
The fix is simple, and uses deep substitution.
See Note [Finding the substitution fixpoint]
I don't think it actually /caused/ any bugs, so there is no
regression test.
- - - - -
3b60ae7e by Simon Peyton Jones at 2026-10-31T09:20:34-04:00
Fix a nasty bug in fundeps
This MR fixes #27994, which turned out to be very tricky.
See Note [Exploiting closed type famililes], especially (CF7). I was
ending up with TyVars (not TcTyVars) in the solver, because the
substitution computed in `getRelevantBranches` mixed the two.
The code was just too clever. I ended up simplifying it quite a bit.
For /closed/ families we no longer call `trimQtvs` (was `trim_qtvs`).
Open families still do use `trimQtvs`. See Note [trimQTvs]
This patch also fixes one other buglet in the same code.
* Over-saturated type families were being mis-handled.
See the new use of `saturatedFamApp_maybe`.
- - - - -
e4610f2d by Facundo Domínguez at 2026-10-31T09:21:24-04:00
Have haddock --incremental look for the module in -this-unit-id
- - - - -
bc6c0db6 by sheaf at 2026-10-31T09:22:20-04:00
mightBeFunTy: hotfix for #27979
ce01ccb6 refactored 'GHC.Types.RepType.mightBeFunTy' to look through
unary classes. That change introduced the helper function 'unwrap_type'
which was supposed to always return an unwrapped type, but its fallback
equation mistakenly returned the original type. This caused the
subsequent 'tyConAppTyCon_maybe' to fail in cases where it should
succeed (e.g. looking through foralls).
In this commit, we move all the unary class unwrapping logic into
'unwrapType' where it belonged from the start, and update the
documentation of 'unwrapType' to better explain what it should be used
for (#26695).
Fixes #27979 #26695
-------------------------
Metric Increase:
T5642
-------------------------
- - - - -
233cce46 by Alan Zimmerman at 2026-10-31T09:23:01-04:00
EPA: Tidy up ExactPrint.markAnnListA'
It takes an action which can modify the AnnList, but this
is never used. So remove it.
- - - - -
3594a908 by Sylvain Henry at 2026-10-31T09:23:51-04:00
gitmodules: ignore dirty libffi-clib submodule (#26785)
`./boot` runs autoreconf in libraries/libffi-clib, which leaves
`configure~` behind and rewrites the tracked `aclocal.m4` whenever the
local automake version differs from the one that generated it. Every
checkout then looks dirty. Ignore working-tree changes in the submodule
(`ignore = dirty`); a changed submodule commit is still reported.
Co-Authored-By: Claude Fable 5.1 <noreply(a)anthropic.com>
- - - - -
341223c0 by Rodrigo Mesquita at 2026-10-31T09:24:33-04:00
refactor: Keep the interactive Ids directly rather than Name
Removes things like
names <- map idName ids
map (\i -> let id = find (\x -> i==idName x) names) idso
and is more straightforward because there's less state going around (no
more updating HscEnv as an output)
It also kills `printTypeOfNames` completely, since now we just have the
Ids. No longer `lookupName` names to get back the ids...
```
printTypeOfName :: GHC.GhcMonad m => Name -> m ()
printTypeOfName n
= do maybe_tything <- GHC.lookupName n
case maybe_tything of
Nothing -> return ()
Just thing -> printTyThing thing
```
now is just `printTyThing . AnId`
Also:
```diff
- tythings <- catMaybes `liftM` mapM GHC.lookupName namesSorted
- docs <- mapM pprTypeAndContents [i | AnId i <- tythings]
+ docs <- mapM pprTypeAndContents idsSorted
```
(and yes, in ExecBreaks there are only Ids, no TyThings, bc they are
only constructed by the interpreter execution which can only bind ids.
for TyThings use runDecls which doesn't return execBreaks.)
There's some care to be had to make sure we use the "most refined" Ids,
whereas when using `Name`s we'd always fetch the most refined Id from
scratch.
Fixes #28052
- - - - -
a255b982 by Simon Peyton Jones at 2026-11-02T17:10:50+00:00
Use a different herald for -ddump-simpl-trace
... so that we can more easily skip the high-volume ones
- - - - -
dfe2c433 by Simon Peyton Jones at 2026-11-02T17:15:02+00:00
Update eta-reduction documentation; ignore multiplicities
Triggered by #27212, this patch does several related things:
* Update documentation about eta expansion and reduction, especially
* Make it clear in `findRhsArity` that we eta expand only to increase
`exprArity`, not `manifestArity`. (The latter was a misconception of
#27212.)
* Relabel the criteria in Note [Eta reduction soundness] as (EtaA),
(EtaS), (EtaR), (EtaE), (EtaT), (EtaJ), (EtaB), (EtaW), fix references
to them (including stale references to a non-existent
Note [Eta reduction makes sense]), and add historical notes (EtaMult)
and (EtaBot).
* Refactor GHC.Core.Opt.Arity.tryEtaReduce, which was hard
to understand. New code is simpler and more efficient.
* As part of this refactor I dropped the tricky checks on multiplicity,
which sometimes disabled eta-reduction. Note [Linting linearity]
in GHC.Core.Lint already said that we don't try to preserve linearity
when doing eta-reduction, so the change here just executs that claim.
- - - - -
ea6c76cd by Simon Peyton Jones at 2026-11-02T17:15:02+00:00
Update comments and user manual
This commit addresses the comment-related suggestions in #27973
- - - - -
102 changed files:
- .gitmodules
- + changelog.d/T27323
- + changelog.d/T27847
- + changelog.d/T27979
- + changelog.d/T27994
- + changelog.d/clc-446
- + changelog.d/clc-447
- + changelog.d/fix-nonmoving-weak-evacuation-race-23160
- + changelog.d/ghc-api-interactive-ids
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Coercion/Axiom.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Inline.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Make.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Driver/Config/Core/Opt/Simplify.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Types.hs
- compiler/GHC/HsToCore/Utils.hs
- compiler/GHC/Runtime/Context.hs
- compiler/GHC/Runtime/Debugger.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Eval/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Tc/Instance/Family.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Types/Var/Env.hs
- compiler/GHC/Utils/Logger.hs
- compiler/Language/Haskell/Syntax/Binds/InlinePragma.hs
- docs/users_guide/debug-info.rst
- docs/users_guide/using-optimisation.rst
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Monad.hs
- libraries/base/changelog.md
- libraries/containers
- libraries/ghc-internal/src/GHC/Internal/Control/Exception/Base.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Internals.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Text.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Windows.hs
- libraries/ghc-internal/src/GHC/Internal/System/Environment/ExecutablePath.hsc
- libraries/ghc-internal/src/GHC/Internal/System/IO/Error.hs
- rts/sm/Evac.c
- + testsuite/tests/codeGen/should_compile/T27979.hs
- + testsuite/tests/codeGen/should_compile/T27979.stderr
- testsuite/tests/codeGen/should_compile/all.T
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/exceptions/T27851.hs
- + testsuite/tests/exceptions/T27851.stderr
- + testsuite/tests/exceptions/T27851b.hs
- + testsuite/tests/exceptions/T27851b.stderr
- + testsuite/tests/exceptions/T27851c.hs
- + testsuite/tests/exceptions/T27851c.stdout
- + testsuite/tests/exceptions/T27851d.hs
- + testsuite/tests/exceptions/T27851d.stdout
- + testsuite/tests/exceptions/T27851d.stdout-javascript-unknown-ghcjs
- testsuite/tests/exceptions/all.T
- testsuite/tests/ghc-e/should_fail/T18441fail7.stderr
- testsuite/tests/ghc-e/should_run/ghc-e005.stderr
- + testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.hs
- + testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.script
- + testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.stdout
- testsuite/tests/ghci.debugger/scripts/all.T
- + testsuite/tests/haddock/haddock_testsuite/IncrementalUnitId.hs
- testsuite/tests/haddock/haddock_testsuite/Makefile
- testsuite/tests/haddock/haddock_testsuite/all.T
- + testsuite/tests/haddock/haddock_testsuite/haddockIncrementalUnitId.stdout
- + testsuite/tests/pmcheck/should_compile/T27323.hs
- + testsuite/tests/pmcheck/should_compile/T27323b.hs
- testsuite/tests/pmcheck/should_compile/all.T
- + testsuite/tests/rts/T23160.hs
- + testsuite/tests/rts/T23160.stdout
- testsuite/tests/rts/all.T
- testsuite/tests/simplCore/should_compile/T24726.stderr
- + testsuite/tests/typecheck/should_compile/T27994.hs
- + testsuite/tests/typecheck/should_compile/T27994a.hs
- + testsuite/tests/typecheck/should_compile/T27994b.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/warnings/should_compile/Overflow.stderr-ws-32
- testsuite/tests/warnings/should_compile/Overflow.stderr-ws-64
- testsuite/tests/warnings/should_compile/T13256.stderr-ws-32
- testsuite/tests/warnings/should_compile/T13256.stderr-ws-64
- utils/check-exact/ExactPrint.hs
- utils/haddock/CHANGES.md
- utils/haddock/haddock-api/src/Haddock/Interface.hs
- utils/hsc2hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2d0357fbe9a5b1086bc5826950d927…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2d0357fbe9a5b1086bc5826950d927…
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
1
0
[Git][ghc/ghc][wip/romes/multi-threaded-debugger] 24 commits: X86 NCG: use 32-bit POPCNT for sub-word popcounts
by Rodrigo Mesquita (@alt-romes) 02 Nov '26
by Rodrigo Mesquita (@alt-romes) 02 Nov '26
02 Nov '26
Rodrigo Mesquita pushed to branch wip/romes/multi-threaded-debugger at Glasgow Haskell Compiler / GHC
Commits:
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.
- - - - -
e4e3bb3c by Rodrigo Mesquita at 2026-10-28T15:21:12+00:00
refactor: Keep the interactive Ids directly rather than Name
Removes things like
names <- map idName ids
map (\i -> let id = find (\x -> i==idName x) names) idso
and is more straightforward because there's less state going around (no
more updating HscEnv as an output)
It also kills `printTypeOfNames` completely, since now we just have the
Ids. No longer `lookupName` names to get back the ids...
```
printTypeOfName :: GHC.GhcMonad m => Name -> m ()
printTypeOfName n
= do maybe_tything <- GHC.lookupName n
case maybe_tything of
Nothing -> return ()
Just thing -> printTyThing thing
```
now is just `printTyThing . AnId`
Also:
```diff
- tythings <- catMaybes `liftM` mapM GHC.lookupName namesSorted
- docs <- mapM pprTypeAndContents [i | AnId i <- tythings]
+ docs <- mapM pprTypeAndContents idsSorted
```
(and yes, in ExecBreaks there are only Ids, no TyThings, bc they are
only constructed by the interpreter execution which can only bind ids.
for TyThings use runDecls which doesn't return execBreaks.)
There's some care to be had to make sure we use the "most refined" Ids,
whereas when using `Name`s we'd always fetch the most refined Id from
scratch.
Fixes #28052
- - - - -
7a0c80db by Rodrigo Mesquita at 2026-11-02T17:10:26+00:00
interp: Make resumeExec and ExecBreak use `Resume` directly
Previously, `Resume` contexts were just put directly in the global
interactive environment state, so they were only accessible through it.
However, in the context of multi-threaded debugging, in that many
threads may hit breakpoints, it no longer suffices to have a global
linear list of breakpoints hit. We need a per-breakpoint Resume context
and need to be able to wield it directly rather than going through a
global context.
The driving changes of this commit are:
- Put the Resume data in ExecBreak
- Make resumeExec receive a Resume as an argument
This also simplifies the interpreter in that we no longer necessarily
rely on the global interactive state to resume a thread. We can do it
directly from the ExecBreak.
The interactive context still maintains a stack of resumes, but
`resumeExec` can no longer pop the resume it resumes off of the
breakpoints stack, since it is no longer guaranteed to be resuming the
first in that list. Hence, callers of `resumeExec` must update ic_resume
on their own.
Fixes #28058
- - - - -
55ce2ade by Rodrigo Mesquita at 2026-11-02T17:10:29+00:00
Per-thread break-on exception (TSO_STOP_ON_EXCEPTION)
The `-fbreak-on-exception` flag allows the interactive interpreter to stop
when a synchronous exception is raised.
However, this is a global toggle backed by a global variable in the RTS
(rts_stop_on_exception) which is not compatible with a multi-threaded
debugger where we may want to stop if some threads raise a synchronous
exception but not other.
This commit makes -break-on-exception similar to step-next and step-out
where there is a per-thread toggle on each TSO (TSO_STOP_ON_EXCEPTION),
and that break-on-exception set in EvalOpts when resuming a statement
only affect the thread being resumed.
Fixes #28068
- - - - -
eee86f8d by Rodrigo Mesquita at 2026-11-02T17:10:29+00:00
Asynchronous RPC with external interpreter
There's a single pipe to connect the host compiler to the external
interpreter. On this pipe, we have historically done synchronous
request/reply communication to invoke methods on the external
interpreter.
However, with the advent of multi-threaded debugging, it has become
necessary to do asynchronous calls on the external interpreter, where we
may block on the host waiting for a reply, but the external interpreter
should handle the request asynchronously and reply when ready. For
instance, we want to start the evaluation of the debuggee but not block
the interpreter waiting for it to finish or hit a breakpoint. Or e.g. we
want to resume two threads of the debuggee simulatenously instead of
blocking waiting for the resume result of each one sequentially.
And it turns out, we were already doing some ad-hoc asynchronous
communication to evaluate Template Haskell on the external interpreter.
It used to go as an ad-hoc "send request without expecting reply",
followed by handling on the host a set of 'THMessage's sent by the
interpreter, followed by "expect a response to arrive now". It worked
because there was still a fixed order of messages, but it fits an async
model in a non-ad-hoc way.
Asynchronous communication that unblocks the external interpreter main
thread will also make it possible to resolve issues such as #18852
(exceptions leaving the external interpreter in an unrecoverrable state)
The new design
--------------
The new invariant: every single request should receive a matching reply.
The pipe is bidirectional (the ext. interpreter can receive requests,
but it can also send requests for TH evaluation; the host can send
requests, but it can also receive TH requests from the interpreter).
When a request is sent in whichever direction, it always contains a
correlation-id header. The Sender places an empty MVar on a
pending-reply map keyed by id and waits on it for a response.
See 'remoteCall' and 'remoteTHCall'.
The pipe is associated to a thread which drains the read end. Because
it's bidirectional, two things may be read off the pipe:
- A Reply, with a correlation-id header, which we match against the
pending requests map to unblock the corresponding pending-reply MVar
- A Request, which is queued to the pending-request queue.
To handle a message, we take a Request from the pending-request queue
and run a handler that produces a Reply. Currently, the handler is run
synchronously in the thread, but it is trivial to make the handler run
in a forked thread for certain ("interruptible") messages in an upcoming
patch (when it is necessary for the multi-threaded debugger).
See 'handleRemoteCall' and 'handleRemoteTHCall'.
The old interp lock now just protect the pipe writing (reads don't lock
bc they are done exclusively by drainPipe), it doesn't need nor should
lock the full remote procedure call.
Fixes #27960
- - - - -
533ff7d9 by Rodrigo Mesquita at 2026-11-02T17:10:29+00:00
interp: Add separate mailboxes for TH async RPC
When the host sends a `RunTH` command to the interpreter, it expects a
few "reverse requests" from the interpreter (e.g. `NewName`) which must
be run in the same context that initiated the `RunTH`.
When the host is evaluating many splices at once, it will send many
`RunTH` commands to the interpreter and start listening for reverse
requests in the meantime. However, a received request previously had no
way to be associated to the scope of a particular `RunTH` invocation, so
the reverse commands could get replied to from incorrect contexts, or
e.g. a `RunTHDone` from the interp. could terminate early the wrong
`RunTH` computation.
In this commit we add independent mailboxes to the interpreter
asynchronous RPC infrastructure, allowing a RunTH to announce a
particular `InboxId` that all reverse requests for that RunTH should
use. On the host, we create that mailbox id and have
`handleRemoteTHCall` listen on that specific mailbox rather than for
requests without a specific mailbox address.
- - - - -
7c78175f by Rodrigo Mesquita at 2026-11-02T17:10:29+00:00
refactor: Move Async RPC abstraction into GHCi.Message.Async
Carves out the Async RPC over the Pipe abstraction to a new module,
making the GHCi.Message more about the specific interpreter messages
rather than about the IPC protocol.
- - - - -
2346f2da by Rodrigo Mesquita at 2026-11-02T17:10:29+00:00
interp: If we have pending reads in the queue we can deliver them
We may still be able to reply even if the read end was closed.
As long as we have pending messages we should try to deliver them.
- - - - -
a2284cc8 by Andrea Vezzosi at 2026-11-02T17:10:30+00:00
interp: close Handles when done with Pipe
Ensures we close the pipe handles (if created using 'mkPipeFromHandles')
on `closePipe`, and do `closePipe` on `Shutdown`.
The thread draining the read end always `'finally'` closes the read end.
And `closePipe` kills the draining thread and closes the write end.
When `remoteAsyncReq`, we throw PipeReadClosedException if the pipe read is
closed, since we wouldn't be able to receive the reply.
It's fine for the drain thread not to close the write end, even if it
dies without `closePipe` (which does close the write end), because:
- requests pending a reply will get PipeClosedException (we'll not be
able to read any further "real" reply)
- new calls to `remoteAsyncReq` will throw PipeReadClosedException
- pending pipe writes, in response to an already read request, might still succeed
And the clean up code should call close pipe to ensure the write end is
closed as well.
So, if the drain thread dies naturally and the read end is closed, may
still be attempted to be used, but it will throw accordingly. The user
likely wants to catch this to close the write end as well.
- - - - -
abd1c98a by Zubin Duggal at 2026-11-02T17:10:30+00:00
interp: fix external interpreter shutdown deadlock on Windows
On shutdown both GHC and iserv call `closePipe`, which stopped the drain
thread before closing the write end. On Windows the drain thread reads
with a safe foreign call to _read, which `throwTo' can't interrupt, so
the two sides were stuck in the deadlock deadlock.
Closing the write end first is not enough on its own. On Windows a read
on a pipe only unblocks once all write handles to it are closed [1].
However, all all four pipe ends were inheritable and we didn't close the
child's ends in the parent. This means a close on any one side wouldn't
unblock any reads, becuase the other side had another copy open.
* runWithPipes now uses System.Process.CommunicationHandle [2], which is
built for passing pipes to a child process: only the child's ends are
inheritable, and it simplifies our mess of CPP. Additionally, it is
important to close our copy of the endpoints passed to the child so
each side only keeps open copies it needs to allow a close to unblock
reads.
* readGhcHandle makes the handle non-inheritable so we don't have
additional references floating around that stop reads from unblocking
on close.
* In closePipe the ordering is subtle and important. We first fail any
requests still waiting for a reply, then close the write end so the
other side sees EOF. We take the write lock to close it, so we never
close under a concurrent write [3]. Only then do we stop the drain
thread, which closes the read end itself once its read has finished.
Bump bound to process >= 1.6.20 as this is the version with
System.Process.CommunicationHandle
[1] https://learn.microsoft.com/en-us/windows/win32/ipc/anonymous-pipe-operatio…
[2] https://github.com/haskell/process/pull/308
[3] https://gitlab.haskell.org/ghc/ghc/-/work_items/27801
- - - - -
16a07999 by Andrea Vezzosi at 2026-11-02T17:10:30+00:00
GHCi.Server: handle RunTH and RunModFinalizers in forked thread
This commit makes the external interpreter able to many interpret
template haskell splices in parallel without blocking the main server
thread. Simply: fork off a thread to handle a RunTH request. The handler
will issue the reverse-requests on the given RunTH mailbox, to keep each
RunTH isolated from the others.
`handleRemoteCall` was generalised slightly by allowing `WriteReply` to
be used linearly in the handler directly, so that the caller of
`handleRemoteCall` may `WriteReply` in the forked thread rather than in
the main thread.
The only question is how can we guarantee `WriteReply` is used linearly
if we want to use it inside a forked thread? We need two guarantees:
1. `WriteReply` is used in the forked thread regardless of whether an
exception is thrown to that thread.
2. The forked thread is always awaited for, so that the main program
doesn't exit before the thread has a chance to actually use
`WriteReply`.
We introduced a small `ThreadManager` which provides a `spawnFinally`
that provides these two guarantees:
1. is guaranteed by `forkFinally`, which always runs the clean up action
exactly once.
2. is guaranteed by `ThreadManager` being abstract and the only exposed
function that introduces `ThreadManager` being `withThreadManager`,
which always awaits for all spawned threads.
Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita(a)gmail.com>
- - - - -
32f3e510 by Andrea Vezzosi at 2026-11-02T17:10:30+00:00
interp: spawn fillPipe thread, writePipe now safely interruptible
Previously an async exception during a call to `writePipe` could have caused a
partial write, making any further write impossible to parse from the other end.
Now `writePipe` merely pushes the message onto a queue, and the actual write
happens in a separate `fillPipe` thread. As a result of this and previous
changes, `interpCmd` no longer needs `interruptibleMask` to preserve the state
of the protocol.
`writePipe` waits for the actual write to complete, and rethrows exceptions
raised in the write attempt, if any.
- - - - -
2d2a2fe9 by Andrea Vezzosi at 2026-11-02T17:10:30+00:00
Follow `Note [Exceptions in TH]` in `qReport` implementation
`qReport b msg` should use `seqList msg` to trigger any exceptions in the
`String`, as explained in the note.
Through refactors the `seqList msg` call followed the bulk of the implementation
in `GHC.Tc.Gen.Splice.report`, but the call should be in `qReport` itself, so
that, even with -fexternal-interpreter, `msg` gets forced right away and any
exceptions get reported as a compilation error.
Follow up to 'interp: spawn fillPipe thread, writePipe now safely
interruptible'.
- - - - -
7949cc15 by Rodrigo Mesquita at 2026-11-02T17:10:30+00:00
test: make T3171 not fragile and add version for ext interp too
- actually test the sleep of the user-given expression gets interrupted
- the ext interp version tests two things:
- Requests can be cancelled without terminating the ext interp (#18852)
- The stmt being evaluated gets interrupted in the ext interp (that
is, ^C gets sent to the thread running the user-given expression
and doesn't affect the ext interp main thread)
- testing ext interp requires sending ^C to whole process group
Fixes #15383
- - - - -
7aa73b46 by Andrea Vezzosi at 2026-11-02T17:10:30+00:00
interp: cancel requests if async exceptions while waiting for reply.
- - - - -
a46421a3 by Andrea Vezzosi at 2026-11-02T17:10:30+00:00
interp: do not terminate ext. interp. process on exception
`sendMessage` throwing an exception does not warrant terminating the external
interpreter process anymore, because communication can keep going no matter what.
`stopInterp` now resets the whole `Interp` state, so that a new
ExtInterpInstance can be later created and work correctly.
`withExtInterp` now calls `stopInterp` on a `PipeClosedException` and rethrows.
Fixes #18852
- - - - -
348c4cd5 by Rodrigo Mesquita at 2026-11-02T17:19:05+00:00
add break033 checks continue after unsetting break on exception works
- - - - -
6630f5d4 by Rodrigo Mesquita at 2026-11-02T17:19:05+00:00
Add test checking we don't stop at breakpoints in TH
- - - - -
ff887d8b by Rodrigo Mesquita at 2026-11-02T17:19:05+00:00
Test that :abandon doesn't hang when -fbreak-on-error
- - - - -
e17dfb2c by Rodrigo Mesquita at 2026-11-02T17:19:05+00:00
run conc033 in ghci too
- - - - -
6e0b4e0a by Rodrigo Mesquita at 2026-11-02T17:19:05+00:00
Add test checking a ^C interrupt of a :force interrupts the expression
- - - - -
2bbbb5ba by Rodrigo Mesquita at 2026-11-02T17:19:05+00:00
test T3171 with -fno-ghci-sandbox too
- - - - -
602c4111 by Rodrigo Mesquita at 2026-11-02T17:20:50+00:00
Global break action which uses shared thread map
the status Var must actually be global across all threads, otherwise all
of them will block trying to write some Status Var no one is looking at
at all
Build EvalOpts once per exec rather than per breakpoint stop
in interpreter_steplocal the allocations increased because now we're
updating `eval_opts` after constructing them in `handleRunStatus` (which
is run many times since in step-local most often we don't stop, just
check).
So drop the update to the eval_opts, and, in fact, pull their
construction out. the loop always uses the same eval_opts, so no point
in constructing them inside from scratch every time.
-3.6% from this branch which had the regressions in
interpreter_steplocal
Look up a thread's ResumeContext without taking a lock
modifyMVar is unnecessarily expensive and blocking when most often we
just care about reading without modifying. optimize for default case
(thread context already exists). It is called every single time a
breakpoint is hit (regardless of whether we stop there, e.g. in
interpreter_steplocal we do not stop there often)
-3.3% improvement over original regression
Every thread resume-context keeps a var for its EvalStatus
Kill the global mapping from thread id to EvalStatus
Instead, keep the EvalStatus in the ResumeContext associated to a thread
in the threadContextVar (where entries are created on breakpoints being
hit and when writing an EvalComplete result)
Before, every breakpoint hit meant reading the global map TVar and
deleting a map entry which did a lot of allocations. Now, we have a
Nothing variable which we overwrite to "take" rather than deleting from
a Map and allocating the GlobalDbgMap too. Note that for every
breakpoint hit we'd have to insert the ThreadId entry in the map again
(because we deleted it last time we resumed), again allocating
unnecessarily. Now it's only a look up on the map and an update on the
variable directly.
And a LOT of breakpoints were hit on interpreter_steplocal, stress
testing the cost of hitting a breakpoint
The isolated threads move to their own top-level TVar Set.
-4.4% improvement over the regression
Move whether a thread is isolated to the same global map
Stops us from reconstructing the set every time this changed instead to
being a per thread variable just toggled on/off, by default non-isolated
like before (before it was Set.empty, Set.insert for True, Set.delete
for FALSE). This is more straightforward -- there's always an isolation
mode per thread and we can toggle it directly
reduces slightly allocations, but the main advantage is killing a second
global map and making it more uniform with just one thread map and no
membership check for toggledness.
Prefer foldl' in readAnyThreadEvalBreak txn
retry 'orElse' next is just next, so we might as well use a strict fold
TODO comment on breakOnException being global rather than per-thread
Set global breakpoint action in sandboxIO rather than withBreakAction
WIP: Asynchronous eval/resume
Fix commentary
clean up some comments in GHCi.Signals
unmask runIt only
Move cmmtn
internal interp: redirect interrupts on waits to the thread we're waiting for
Do redirectInterrupts to ext interp too
get rid of installSignalHandlers and discardCtrlC and uninterruptibleMask
fixes
Manage thread status stopped vs running and allow many threads to read the same result off of a stoped thread
abstracrt resumeStoppedThread
and use it in abandonStmt too.
fix redirect todo on seq/resumeseq
Add inline TODO about improving efficiency of readyAnyThreadBreak
It is currently O(N) in number of threads that have hit breakpoints
It should be number of *live* threads that have hit breaks, bc we still need to find a way to evacuate threads from the map
setBreakAction should also unset if flag is off.
(e.g. we don't want a :continue to keep flags if the :continue resume
request has unset things)
Fix writeCtxEvalStatus can overwrite existing breakpoint because of exceptions
kill EvalStatus_ for EvalStatus
resume :abandon until complete
Don't hang if we try to resume an already finished thread (and test it)
catch exception thrown while stopped at breakpoint
- - - - -
93 changed files:
- + changelog.d/T27960
- + changelog.d/T28002
- + changelog.d/T28002-api
- + changelog.d/ghc-api-exec-break-resume
- + changelog.d/ghc-api-interactive-ids
- + changelog.d/ncg-x86-subword-popcnt
- compiler/GHC.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Driver/Config.hs
- compiler/GHC/Runtime/Context.hs
- compiler/GHC/Runtime/Debugger.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Eval/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/Runtime/Interpreter/JS.hs
- compiler/GHC/Runtime/Interpreter/Process.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- compiler/GHC/Runtime/Interpreter/Wasm.hs
- compiler/GHC/Runtime/Utils.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Types/Annotations.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/ghc.cabal.in
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Monad.hs
- libraries/ghc-boot/GHC/Serialized.hs
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingDisabled.hsc
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc
- libraries/ghc-heap/tests/parse_tso_flags.hs
- libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghci/GHCi/Debugger.hs
- libraries/ghci/GHCi/Message.hs
- + libraries/ghci/GHCi/Message/Async.hs
- libraries/ghci/GHCi/Run.hs
- + libraries/ghci/GHCi/Run/Breakpoints.hs
- libraries/ghci/GHCi/Server.hs
- + libraries/ghci/GHCi/Server/Threads.hs
- libraries/ghci/GHCi/Signals.hs
- libraries/ghci/GHCi/TH.hs
- libraries/ghci/GHCi/TH/Binary.hs
- libraries/ghci/GHCi/Utils.hsc
- libraries/ghci/ghci.cabal.in
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- rts/Exception.cmm
- rts/Interpreter.c
- rts/Interpreter.h
- rts/RtsSymbols.c
- rts/include/rts/Constants.h
- 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/codeGen/should_gen_asm/T24813.asm
- + testsuite/tests/codeGen/should_gen_asm/T24813.cmm
- testsuite/tests/codeGen/should_gen_asm/all.T
- testsuite/tests/concurrent/should_run/all.T
- testsuite/tests/ghc-api/T8628.hs
- testsuite/tests/ghc-api/T8639_api.hs
- testsuite/tests/ghc-api/apirecomp001/myghc.hs
- + testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.hs
- + testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.script
- + testsuite/tests/ghci.debugger/scripts/RttiSharedTyVar.stdout
- testsuite/tests/ghci.debugger/scripts/all.T
- + testsuite/tests/ghci.debugger/scripts/break032.hs
- + testsuite/tests/ghci.debugger/scripts/break032.script
- + testsuite/tests/ghci.debugger/scripts/break032.stdout
- + testsuite/tests/ghci.debugger/scripts/break033.hs
- + testsuite/tests/ghci.debugger/scripts/break033.script
- + testsuite/tests/ghci.debugger/scripts/break033.stdout
- + testsuite/tests/ghci.debugger/scripts/break034.hs
- + testsuite/tests/ghci.debugger/scripts/break034.script
- + testsuite/tests/ghci.debugger/scripts/break034.stdout
- + testsuite/tests/ghci.debugger/scripts/break035.hs
- + testsuite/tests/ghci.debugger/scripts/break035.script
- + testsuite/tests/ghci.debugger/scripts/break035.stdout
- testsuite/tests/ghci/custom-external-interpreter-commands/Main.hs
- + testsuite/tests/ghci/should_run/ForceInterrupt.script
- + testsuite/tests/ghci/should_run/ForceInterrupt.stdout
- + testsuite/tests/ghci/should_run/ForceInterruptExt.stdout
- testsuite/tests/ghci/should_run/Makefile
- testsuite/tests/ghci/should_run/T3171.stdout
- + testsuite/tests/ghci/should_run/T3171ext.stdout
- + testsuite/tests/ghci/should_run/T3171extnosandbox.stdout
- + testsuite/tests/ghci/should_run/T3171nosandbox.stdout
- testsuite/tests/ghci/should_run/all.T
- testsuite/tests/plugins/T26761Plugin.hs
- testsuite/tests/plugins/all.T
- + testsuite/tests/th/T8987b.hs
- + testsuite/tests/th/T8987b.stderr
- testsuite/tests/th/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bfd992fee69bbb18a03e271d6fdd82…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bfd992fee69bbb18a03e271d6fdd82…
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
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Consolidate all CPU feature handling
by Marge Bot (@marge-bot) 02 Nov '26
by Marge Bot (@marge-bot) 02 Nov '26
02 Nov '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
e37299bd by sheaf at 2026-11-02T12:23:39-05:00
Consolidate all CPU feature handling
This commit introduces GHC.Platform.CpuFeatures which consolidates all
of the logic for implications between CPU feature flags (mainly X86):
- DynFlags now only records the set of -m<feature> flags that were
passed, as an EnumSet CpuFeature. That keeps it a simple record of
the flags the user passed, with no post-processing.
- GHC.Platform.CpuFeatures.initCpuFeatures turns this set into a
CpuFeatures value, applying all implications and the per-architecture
baseline. This is the single home for all of the feature implication
logic.
Some datatypes were reworked to better reflect the implication
structure in the types, e.g. SseAvxVersion has a strategically
placed 'FMA' boolean.
- The NCG, LLVM backend, StgToCmm, CPP defines and LLVM -mattr
flags all consult CpuFeatures, via targetCpuFeatures.
See Note [CPU features], which replaces
Note [Implications between X86 CPU feature flags].
Behaviour changes:
- x86 feature flags (-msse3, -mavx, -mavx512*, -mgfni, ...) passed
when targeting a non-x86 architecture no longer cause x86 CPP
macros (__SSE3__, __AVX512BW__, __GFNI__, ...) to be defined, nor
x86 attributes to be passed to LLVM.
- Error messages reported when required CPU features are not enabled
now print out the minimal set of flags required
(e.g. "-mavx512vl" rather than "-mavx512f -mavx512vl").
- - - - -
29360b8e by Luite Stegeman at 2026-11-02T12:23:52-05:00
rts: move stack check to the start of the stg_unpack_cstring thunks
fixes a deadlock
see #27272
- - - - -
efa6e379 by Simon Jakobi at 2026-11-02T12:23:53-05:00
Cmm: exclude the entry block from common block elimination
a1d8139054c had fixed #27722 only partially, because it didn't prevent
elimination of the entry block in later rounds, where the entry block is
no longer guaranteed to come first.
To close this loophole, we exclude the entry block from the CBE merge
logic. See Note [Retain entry block during common block elimination] for
details.
This also deletes a misleading comment regarding unreachable blocks: the
control-flow optimiser doesn't actually guarantee that no unreachable
blocks reach CBE.
Fixes #27722.
Assisted-by: Claude Fable 5.1
- - - - -
1130173e by Alan Zimmerman at 2026-11-02T12:23:53-05:00
EPA: Use AnnList for GADT declarations
Continuing the process of using AnnList to capture parser layout
- - - - -
44 changed files:
- changelog.d/T27722-cbe-entry-block.md
- + changelog.d/caf-deadlock-27272
- compiler/GHC/Cmm/CallConv.hs
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/CmmToAsm/Config.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/CmmToLlvm/Config.hs
- compiler/GHC/Driver/Config/CmmToAsm.hs
- compiler/GHC/Driver/Config/CmmToLlvm.hs
- compiler/GHC/Driver/Config/StgToCmm.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Platform.hs
- + compiler/GHC/Platform/CpuFeatures.hs
- compiler/GHC/StgToCmm/Config.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/ghc.cabal.in
- rts/StgStdThunks.cmm
- + testsuite/tests/cmm/should_run/T27722.hs
- + testsuite/tests/cmm/should_run/T27722_cmm.cmm
- testsuite/tests/cmm/should_run/all.T
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/ghc-api/exactprint/Test20239.stderr
- 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/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T15323.stderr
- testsuite/tests/parser/should_compile/T20452.stderr
- testsuite/tests/printer/T18791.stderr
- + testsuite/tests/rts/T27272.hs
- + testsuite/tests/rts/T27272_gen.py
- testsuite/tests/rts/all.T
- utils/check-exact/ExactPrint.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b50bf52aa0a59a74cc922ffec9ebc8…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b50bf52aa0a59a74cc922ffec9ebc8…
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
1
0
[Git][ghc/ghc][wip/romes/per-thread-break-on-exception] Per-thread break-on exception (TSO_STOP_ON_EXCEPTION)
by Rodrigo Mesquita (@alt-romes) 02 Nov '26
by Rodrigo Mesquita (@alt-romes) 02 Nov '26
02 Nov '26
Rodrigo Mesquita pushed to branch wip/romes/per-thread-break-on-exception at Glasgow Haskell Compiler / GHC
Commits:
fa298c0c by Rodrigo Mesquita at 2026-11-02T16:36:39+00:00
Per-thread break-on exception (TSO_STOP_ON_EXCEPTION)
The `-fbreak-on-exception` flag allows the interactive interpreter to stop
when a synchronous exception is raised.
However, this is a global toggle backed by a global variable in the RTS
(rts_stop_on_exception) which is not compatible with a multi-threaded
debugger where we may want to stop if some threads raise a synchronous
exception but not other.
This commit makes -break-on-exception similar to step-next and step-out
where there is a per-thread toggle on each TSO (TSO_STOP_ON_EXCEPTION),
and that break-on-exception set in EvalOpts when resuming a statement
only affect the thread being resumed.
Fixes #28068
- - - - -
11 changed files:
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingDisabled.hsc
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc
- libraries/ghc-heap/tests/parse_tso_flags.hs
- libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghci/GHCi/Debugger.hs
- libraries/ghci/GHCi/Run.hs
- rts/Exception.cmm
- rts/Interpreter.c
- rts/Interpreter.h
- rts/RtsSymbols.c
- rts/include/rts/Constants.h
Changes:
=====================================
libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingDisabled.hsc
=====================================
@@ -93,6 +93,7 @@ parseTsoFlags w | isSet (#const TSO_LOCKED) w = TsoLocked : parseTsoFlags (unset
#if __GLASGOW_HASKELL__ >= 913
| isSet (#const TSO_STOP_NEXT_BREAKPOINT) w = TsoStopNextBreakpoint : parseTsoFlags (unset (#const TSO_STOP_NEXT_BREAKPOINT) w)
| isSet (#const TSO_STOP_AFTER_RETURN) w = TsoStopAfterReturn : parseTsoFlags (unset (#const TSO_STOP_AFTER_RETURN) w)
+ | isSet (#const TSO_STOP_ON_EXCEPTION) w = TsoStopOnException : parseTsoFlags (unset (#const TSO_STOP_ON_EXCEPTION) w)
#endif
parseTsoFlags 0 = []
parseTsoFlags w = [TsoFlagsUnknownValue w]
=====================================
libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc
=====================================
@@ -93,6 +93,7 @@ parseTsoFlags w | isSet (#const TSO_LOCKED) w = TsoLocked : parseTsoFlags (unset
#if __GLASGOW_HASKELL__ >= 913
| isSet (#const TSO_STOP_NEXT_BREAKPOINT) w = TsoStopNextBreakpoint : parseTsoFlags (unset (#const TSO_STOP_NEXT_BREAKPOINT) w)
| isSet (#const TSO_STOP_AFTER_RETURN) w = TsoStopAfterReturn : parseTsoFlags (unset (#const TSO_STOP_AFTER_RETURN) w)
+ | isSet (#const TSO_STOP_ON_EXCEPTION) w = TsoStopOnException : parseTsoFlags (unset (#const TSO_STOP_ON_EXCEPTION) w)
#endif
parseTsoFlags 0 = []
parseTsoFlags w = [TsoFlagsUnknownValue w]
=====================================
libraries/ghc-heap/tests/parse_tso_flags.hs
=====================================
@@ -15,5 +15,6 @@ main = do
assertEqual (parseTsoFlags 256) [TsoAllocLimit]
assertEqual (parseTsoFlags 512) [TsoStopNextBreakpoint]
assertEqual (parseTsoFlags 1024) [TsoStopAfterReturn]
+ assertEqual (parseTsoFlags 2048) [TsoStopOnException]
assertEqual (parseTsoFlags 6) [TsoLocked, TsoBlockx]
=====================================
libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
=====================================
@@ -632,6 +632,7 @@ data TsoFlags
| TsoAllocLimit
| TsoStopNextBreakpoint
| TsoStopAfterReturn
+ | TsoStopOnException
| TsoFlagsUnknownValue Word32 -- ^ Please report this as a bug
deriving (Eq, Show, Generic, Ord)
=====================================
libraries/ghci/GHCi/Debugger.hs
=====================================
@@ -13,7 +13,10 @@ module GHCi.Debugger
, rts_disableStopAfterReturn
-- * Stop on exception
- , exceptionFlag
+ , rts_enableStopOnException
+ , rts_disableStopOnException
+ , rts_enableStopOnExceptionAll
+ , rts_disableStopOnExceptionAll
-- * Breakpoint Callback
, BreakpointCallback
@@ -23,7 +26,6 @@ module GHCi.Debugger
import Prelude -- See note [Why do we import Prelude here?]
import GHC.Base (ThreadId#, Addr#, Int#)
-import Foreign.C (CInt)
import Foreign (StablePtr, Ptr)
import GHCi.RemoteTypes (HValue)
@@ -60,7 +62,19 @@ foreign import ccall unsafe "rts_disableStopAfterReturn"
--------------------------------------------------------------------------------
-foreign import ccall "&rts_stop_on_exception" exceptionFlag :: Ptr CInt
+-- | Make this thread break when an exception is hit
+foreign import ccall unsafe "rts_enableStopOnException" rts_enableStopOnException :: ThreadId# -> IO ()
+
+-- | No longer have this thread break when an exception is hit
+foreign import ccall unsafe "rts_disableStopOnException" rts_disableStopOnException :: ThreadId# -> IO ()
+
+-- | Enables global break-on-exception for all threads
+foreign import ccall unsafe "rts_enableStopOnExceptionAll" rts_enableStopOnExceptionAll :: IO ()
+
+-- | Disables the global break-on-exception for all threads. Individual threads
+-- with break-on-exception will still break on exception if the global flag is
+-- disabled.
+foreign import ccall unsafe "rts_disableStopOnExceptionAll" rts_disableStopOnExceptionAll :: IO ()
--------------------------------------------------------------------------------
=====================================
libraries/ghci/GHCi/Run.hs
=====================================
@@ -269,14 +269,17 @@ rethrow EvalOpts{..} io =
catchNoPropagate io $ \(ExceptionWithContext cx se) -> do
-- If -fbreak-on-error, we break unconditionally,
-- but with care of not breaking twice
+ ThreadId mytid <- myThreadId
if breakOnError && not breakOnException
- then poke exceptionFlag 1
+ then rts_enableStopOnException mytid
else case fromException se of
-- If it is a "UserInterrupt" exception, we allow
-- a possible break by way of -fbreak-on-exception
Just UserInterrupt -> return ()
-- In any other case, we don't want to break
- _ -> poke exceptionFlag 0
+ _ -> do
+ rts_disableStopOnException mytid
+ rts_disableStopOnExceptionAll
rethrowIO (ExceptionWithContext cx se)
--
@@ -338,7 +341,11 @@ withBreakAction opts breakMVar statusMVar mtid act
setBreakAction = do
stablePtr <- newStablePtr onBreak
poke breakPointIOAction stablePtr
- when (breakOnException opts) $ poke exceptionFlag 1
+ when (breakOnException opts) $ do
+ case mtid of
+ Nothing -> rts_enableStopOnExceptionAll
+ Just (ThreadId tid) -> do
+ rts_enableStopOnException tid
when (singleStep opts) rts_enableStopNextBreakpointAll
when (stepOut opts) $ do
case mtid of
@@ -380,7 +387,9 @@ withBreakAction opts breakMVar statusMVar mtid act
resetBreakAction stablePtr = do
poke breakPointIOAction noBreakStablePtr
- poke exceptionFlag 0
+ case mtid of
+ Just (ThreadId tid) -> rts_disableStopOnException tid
+ _ -> rts_disableStopOnExceptionAll
rts_disableStopNextBreakpointAll
case mtid of
Just (ThreadId tid) -> rts_disableStopAfterReturn tid
=====================================
rts/Exception.cmm
=====================================
@@ -523,14 +523,16 @@ retry_pop_stack:
if (W_[no_break_on_exception] != 0) {
W_[no_break_on_exception] = 0;
} else {
- if (TO_W_(CInt[rts_stop_on_exception]) != 0) {
+ if (TO_W_(CInt[rts_stop_on_exception]) != 0 ||
+ (TO_W_(StgTSO_flags(CurrentTSO)) & TSO_STOP_ON_EXCEPTION) != 0) {
W_ ioAction;
// we don't want any further exceptions to be caught,
// until GHCi is ready to handle them. This prevents
// deadlock if an exception is raised in InteractiveUI,
- // for example. Perhaps the stop_on_exception flag should
- // be per-thread.
+ // for example.
CInt[rts_stop_on_exception] = 0;
+ StgTSO_flags(CurrentTSO) = %lobits32(
+ TO_W_(StgTSO_flags(CurrentTSO)) & ~TSO_STOP_ON_EXCEPTION);
("ptr" ioAction) = ccall deRefStablePtr (W_[rts_breakpoint_io_action] "ptr");
Sp = Sp - WDS(11);
Sp(10) = exception;
=====================================
rts/Interpreter.c
=====================================
@@ -388,8 +388,6 @@ is_ret_bco_frame(const StgPtr frame_head) {
);
}
-int rts_stop_on_exception = 0;
-
/* ---------------------------------------------------------------------------
* Enabling and disabling global single step mode
* ------------------------------------------------------------------------ */
@@ -473,7 +471,40 @@ A limitation of this approach is that stepping-out of a function that was
tail-called will skip its caller since no stack frame is pushed for a tail
call (i.e. a tail call returns directly to its caller's first non-tail caller).
*/
-/* -------------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------------
+ * Enabling and disabling global break-on-exception
+ * ------------------------------------------------------------------------ */
+
+int rts_stop_on_exception = 0;
+
+void rts_enableStopOnExceptionAll(void)
+{
+ rts_stop_on_exception = 1;
+}
+
+void rts_disableStopOnExceptionAll(void)
+{
+ rts_stop_on_exception = 0;
+}
+
+/* ---------------------------------------------------------------------------
+ * Enabling and disabling per-thread break-on-exception
+ * ------------------------------------------------------------------------ */
+
+void rts_enableStopOnException(StgTSO* tso)
+{
+ Capability* cap = rts_unsafeGetMyCapability();
+ setThreadFlag(cap, tso, TSO_STOP_ON_EXCEPTION);
+}
+
+void rts_disableStopOnException(StgTSO* tso)
+{
+ Capability* cap = rts_unsafeGetMyCapability();
+ unsetThreadFlag(cap, tso, TSO_STOP_ON_EXCEPTION);
+}
+
+/* ------------------------------------------------------------------------ */
#if defined(INTERP_STATS)
=====================================
rts/Interpreter.h
=====================================
@@ -21,3 +21,9 @@ void rts_disableStopNextBreakpoint ( StgTSO* );
// Debugger step out
void rts_enableStopAfterReturn ( StgTSO* );
void rts_disableStopAfterReturn ( StgTSO* );
+
+// Debugger stop on exception
+void rts_enableStopOnException ( StgTSO* );
+void rts_disableStopOnException ( StgTSO* );
+void rts_enableStopOnExceptionAll ( void );
+void rts_disableStopOnExceptionAll ( void );
=====================================
rts/RtsSymbols.c
=====================================
@@ -950,6 +950,10 @@ extern char **environ;
SymI_NeedsProto(rts_disableStopNextBreakpoint) \
SymI_NeedsProto(rts_enableStopAfterReturn) \
SymI_NeedsProto(rts_disableStopAfterReturn) \
+ SymI_NeedsProto(rts_enableStopOnException) \
+ SymI_NeedsProto(rts_disableStopOnException) \
+ SymI_NeedsProto(rts_enableStopOnExceptionAll) \
+ SymI_NeedsProto(rts_disableStopOnExceptionAll) \
SymI_HasProto(stopTimer) \
SymI_HasDataProto(n_capabilities) \
SymI_HasDataProto(max_n_capabilities) \
=====================================
rts/include/rts/Constants.h
=====================================
@@ -394,6 +394,11 @@
*/
#define TSO_STOP_AFTER_RETURN 1024
+/*
+ * Enables break-on-exception mode for this thread
+ */
+#define TSO_STOP_ON_EXCEPTION 2048
+
/*
* The number of times we spin in a spin lock before yielding (see
* #3758). To tune this value, use the benchmark in #3758: run the
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fa298c0ca441d1f8da164fac051a70a…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fa298c0ca441d1f8da164fac051a70a…
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
1
0
[Git][ghc/ghc][wip/romes/per-thread-break-on-exception] Per-thread break-on exception (TSO_STOP_ON_EXCEPTION)
by Rodrigo Mesquita (@alt-romes) 02 Nov '26
by Rodrigo Mesquita (@alt-romes) 02 Nov '26
02 Nov '26
Rodrigo Mesquita pushed to branch wip/romes/per-thread-break-on-exception at Glasgow Haskell Compiler / GHC
Commits:
d7da0b79 by Rodrigo Mesquita at 2026-11-02T16:36:08+00:00
Per-thread break-on exception (TSO_STOP_ON_EXCEPTION)
The `-fbreak-on-exception` flag allows the interactive interpreter to stop
when a synchronous exception is raised.
However, this is a global toggle backed by a global variable in the RTS
(rts_stop_on_exception) which is not compatible with a multi-threaded
debugger where we may want to stop if some threads raise a synchronous
exception but not other.
This commit makes -break-on-exception similar to step-next and step-out
where there is a per-thread toggle on each TSO (TSO_STOP_ON_EXCEPTION),
and that break-on-exception set in EvalOpts when resuming a statement
only affect the thread being resumed.
Fixes #28068
- - - - -
11 changed files:
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingDisabled.hsc
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc
- libraries/ghc-heap/tests/parse_tso_flags.hs
- libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghci/GHCi/Debugger.hs
- libraries/ghci/GHCi/Run.hs
- rts/Exception.cmm
- rts/Interpreter.c
- rts/Interpreter.h
- rts/RtsSymbols.c
- rts/include/rts/Constants.h
Changes:
=====================================
libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingDisabled.hsc
=====================================
@@ -93,6 +93,7 @@ parseTsoFlags w | isSet (#const TSO_LOCKED) w = TsoLocked : parseTsoFlags (unset
#if __GLASGOW_HASKELL__ >= 913
| isSet (#const TSO_STOP_NEXT_BREAKPOINT) w = TsoStopNextBreakpoint : parseTsoFlags (unset (#const TSO_STOP_NEXT_BREAKPOINT) w)
| isSet (#const TSO_STOP_AFTER_RETURN) w = TsoStopAfterReturn : parseTsoFlags (unset (#const TSO_STOP_AFTER_RETURN) w)
+ | isSet (#const TSO_STOP_ON_EXCEPTION) w = TsoStopOnException : parseTsoFlags (unset (#const TSO_STOP_ON_EXCEPTION) w)
#endif
parseTsoFlags 0 = []
parseTsoFlags w = [TsoFlagsUnknownValue w]
=====================================
libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc
=====================================
@@ -93,6 +93,7 @@ parseTsoFlags w | isSet (#const TSO_LOCKED) w = TsoLocked : parseTsoFlags (unset
#if __GLASGOW_HASKELL__ >= 913
| isSet (#const TSO_STOP_NEXT_BREAKPOINT) w = TsoStopNextBreakpoint : parseTsoFlags (unset (#const TSO_STOP_NEXT_BREAKPOINT) w)
| isSet (#const TSO_STOP_AFTER_RETURN) w = TsoStopAfterReturn : parseTsoFlags (unset (#const TSO_STOP_AFTER_RETURN) w)
+ | isSet (#const TSO_STOP_ON_EXCEPTION) w = TsoStopOnException : parseTsoFlags (unset (#const TSO_STOP_ON_EXCEPTION) w)
#endif
parseTsoFlags 0 = []
parseTsoFlags w = [TsoFlagsUnknownValue w]
=====================================
libraries/ghc-heap/tests/parse_tso_flags.hs
=====================================
@@ -15,5 +15,6 @@ main = do
assertEqual (parseTsoFlags 256) [TsoAllocLimit]
assertEqual (parseTsoFlags 512) [TsoStopNextBreakpoint]
assertEqual (parseTsoFlags 1024) [TsoStopAfterReturn]
+ assertEqual (parseTsoFlags 2048) [TsoStopOnException]
assertEqual (parseTsoFlags 6) [TsoLocked, TsoBlockx]
=====================================
libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
=====================================
@@ -632,6 +632,7 @@ data TsoFlags
| TsoAllocLimit
| TsoStopNextBreakpoint
| TsoStopAfterReturn
+ | TsoStopOnException
| TsoFlagsUnknownValue Word32 -- ^ Please report this as a bug
deriving (Eq, Show, Generic, Ord)
=====================================
libraries/ghci/GHCi/Debugger.hs
=====================================
@@ -13,7 +13,10 @@ module GHCi.Debugger
, rts_disableStopAfterReturn
-- * Stop on exception
- , exceptionFlag
+ , rts_enableStopOnException
+ , rts_disableStopOnException
+ , rts_enableStopOnExceptionAll
+ , rts_disableStopOnExceptionAll
-- * Breakpoint Callback
, BreakpointCallback
@@ -23,7 +26,6 @@ module GHCi.Debugger
import Prelude -- See note [Why do we import Prelude here?]
import GHC.Base (ThreadId#, Addr#, Int#)
-import Foreign.C (CInt)
import Foreign (StablePtr, Ptr)
import GHCi.RemoteTypes (HValue)
@@ -60,7 +62,19 @@ foreign import ccall unsafe "rts_disableStopAfterReturn"
--------------------------------------------------------------------------------
-foreign import ccall "&rts_stop_on_exception" exceptionFlag :: Ptr CInt
+-- | Make this thread break when an exception is hit
+foreign import ccall unsafe "rts_enableStopOnException" rts_enableStopOnException :: ThreadId# -> IO ()
+
+-- | No longer have this thread break when an exception is hit
+foreign import ccall unsafe "rts_disableStopOnException" rts_disableStopOnException :: ThreadId# -> IO ()
+
+-- | Enables global break-on-exception for all threads
+foreign import ccall unsafe "rts_enableStopOnExceptionAll" rts_enableStopOnExceptionAll :: IO ()
+
+-- | Disables the global break-on-exception for all threads. Individual threads
+-- with break-on-exception will still break on exception if the global flag is
+-- disabled.
+foreign import ccall unsafe "rts_disableStopOnExceptionAll" rts_disableStopOnExceptionAll :: IO ()
--------------------------------------------------------------------------------
=====================================
libraries/ghci/GHCi/Run.hs
=====================================
@@ -269,14 +269,17 @@ rethrow EvalOpts{..} io =
catchNoPropagate io $ \(ExceptionWithContext cx se) -> do
-- If -fbreak-on-error, we break unconditionally,
-- but with care of not breaking twice
+ ThreadId mytid <- myThreadId
if breakOnError && not breakOnException
- then poke exceptionFlag 1
+ then rts_enableStopOnException mytid
else case fromException se of
-- If it is a "UserInterrupt" exception, we allow
-- a possible break by way of -fbreak-on-exception
Just UserInterrupt -> return ()
-- In any other case, we don't want to break
- _ -> poke exceptionFlag 0
+ _ -> do
+ rts_disableStopOnException mytid
+ rts_disableStopOnExceptionAll
rethrowIO (ExceptionWithContext cx se)
--
@@ -338,7 +341,11 @@ withBreakAction opts breakMVar statusMVar mtid act
setBreakAction = do
stablePtr <- newStablePtr onBreak
poke breakPointIOAction stablePtr
- when (breakOnException opts) $ poke exceptionFlag 1
+ when (breakOnException opts) $ do
+ case mtid of
+ Nothing -> rts_enableStopOnExceptionAll
+ Just (ThreadId tid) -> do
+ rts_enableStopOnException tid
when (singleStep opts) rts_enableStopNextBreakpointAll
when (stepOut opts) $ do
case mtid of
@@ -380,7 +387,9 @@ withBreakAction opts breakMVar statusMVar mtid act
resetBreakAction stablePtr = do
poke breakPointIOAction noBreakStablePtr
- poke exceptionFlag 0
+ case mtid of
+ Just (ThreadId tid) -> rts_disableStopOnException tid
+ _ -> rts_disableStopOnExceptionAll
rts_disableStopNextBreakpointAll
case mtid of
Just (ThreadId tid) -> rts_disableStopAfterReturn tid
=====================================
rts/Exception.cmm
=====================================
@@ -523,14 +523,16 @@ retry_pop_stack:
if (W_[no_break_on_exception] != 0) {
W_[no_break_on_exception] = 0;
} else {
- if (TO_W_(CInt[rts_stop_on_exception]) != 0) {
+ if (TO_W_(CInt[rts_stop_on_exception]) != 0 ||
+ (TO_W_(StgTSO_flags(CurrentTSO)) & TSO_STOP_ON_EXCEPTION) != 0) {
W_ ioAction;
// we don't want any further exceptions to be caught,
// until GHCi is ready to handle them. This prevents
// deadlock if an exception is raised in InteractiveUI,
- // for example. Perhaps the stop_on_exception flag should
- // be per-thread.
+ // for example.
CInt[rts_stop_on_exception] = 0;
+ StgTSO_flags(CurrentTSO) = %lobits32(
+ TO_W_(StgTSO_flags(CurrentTSO)) & ~TSO_STOP_ON_EXCEPTION);
("ptr" ioAction) = ccall deRefStablePtr (W_[rts_breakpoint_io_action] "ptr");
Sp = Sp - WDS(11);
Sp(10) = exception;
=====================================
rts/Interpreter.c
=====================================
@@ -388,8 +388,6 @@ is_ret_bco_frame(const StgPtr frame_head) {
);
}
-int rts_stop_on_exception = 0;
-
/* ---------------------------------------------------------------------------
* Enabling and disabling global single step mode
* ------------------------------------------------------------------------ */
@@ -473,7 +471,40 @@ A limitation of this approach is that stepping-out of a function that was
tail-called will skip its caller since no stack frame is pushed for a tail
call (i.e. a tail call returns directly to its caller's first non-tail caller).
*/
-/* -------------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------------
+ * Enabling and disabling global break-on-exception
+ * ------------------------------------------------------------------------ */
+
+int rts_stop_on_exception = 0;
+
+void rts_enableStopOnExceptionAll(void)
+{
+ rts_stop_on_exception = 1;
+}
+
+void rts_disableStopOnExceptionAll(void)
+{
+ rts_stop_on_exception = 0;
+}
+
+/* ---------------------------------------------------------------------------
+ * Enabling and disabling per-thread break-on-exception
+ * ------------------------------------------------------------------------ */
+
+void rts_enableStopOnException(StgTSO* tso)
+{
+ Capability* cap = rts_unsafeGetMyCapability();
+ setThreadFlag(cap, tso, TSO_STOP_ON_EXCEPTION);
+}
+
+void rts_disableStopOnException(StgTSO* tso)
+{
+ Capability* cap = rts_unsafeGetMyCapability();
+ unsetThreadFlag(cap, tso, TSO_STOP_ON_EXCEPTION);
+}
+
+/* ------------------------------------------------------------------------ */
#if defined(INTERP_STATS)
=====================================
rts/Interpreter.h
=====================================
@@ -21,3 +21,9 @@ void rts_disableStopNextBreakpoint ( StgTSO* );
// Debugger step out
void rts_enableStopAfterReturn ( StgTSO* );
void rts_disableStopAfterReturn ( StgTSO* );
+
+// Debugger stop on exception
+void rts_enableStopOnException ( StgTSO* );
+void rts_disableStopOnException ( StgTSO* );
+void rts_enableStopOnExceptionAll ( void );
+void rts_disableStopOnExceptionAll ( void );
=====================================
rts/RtsSymbols.c
=====================================
@@ -950,6 +950,10 @@ extern char **environ;
SymI_NeedsProto(rts_disableStopNextBreakpoint) \
SymI_NeedsProto(rts_enableStopAfterReturn) \
SymI_NeedsProto(rts_disableStopAfterReturn) \
+ SymI_NeedsProto(rts_enableStopOnException) \
+ SymI_NeedsProto(rts_disableStopOnException) \
+ SymI_NeedsProto(rts_enableStopOnExceptionAll) \
+ SymI_NeedsProto(rts_disableStopOnExceptionAll) \
SymI_HasProto(stopTimer) \
SymI_HasDataProto(n_capabilities) \
SymI_HasDataProto(max_n_capabilities) \
=====================================
rts/include/rts/Constants.h
=====================================
@@ -394,6 +394,11 @@
*/
#define TSO_STOP_AFTER_RETURN 1024
+/*
+ * Enables break-on-exception mode for this thread
+ */
+#define TSO_STOP_ON_EXCEPTION 2048
+
/*
* The number of times we spin in a spin lock before yielding (see
* #3758). To tune this value, use the benchmark in #3758: run the
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7da0b79bdf97e95da3f343ff202df9…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7da0b79bdf97e95da3f343ff202df9…
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
1
0
[Git][ghc/ghc] Pushed new branch wip/romes/per-thread-break-on-exception
by Rodrigo Mesquita (@alt-romes) 02 Nov '26
by Rodrigo Mesquita (@alt-romes) 02 Nov '26
02 Nov '26
Rodrigo Mesquita pushed new branch wip/romes/per-thread-break-on-exception at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/romes/per-thread-break-on-exc…
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
1
0