-
08cc4abd
by Ben Gamari at 2026-09-03T12:23:52+05:30
base: Don't drop exception context in SomeException(toException)
For reasons that are lost to time, the implementation of [CLC #200]
that was merged inappropriately dropped `ExceptionContext` in the
`toException` implementation given to `SomeException`.
Fix this infelicity.
[CLC #200]: https://github.com/haskell/core-libraries-committee/issues/200
(cherry picked from commit 2ab02c579a9625438f5281a258051cb32ba40004)
-
c37cb584
by Vladislav Zavialov at 2026-09-03T12:24:15+05:30
Discard type arguments in tcPatToExpr (#27440, #27583)
The builder expression of an implicitly bidirectional pattern synonym must not
mention types written in the RHS:
* Invisible type arguments led to a panic (#27440)
* Required type arguments failed with out-of-scope variables (#27583)
Both are now discarded, following the precedent established by pattern
signatures (#9867).
Discarding type arguments takes some care: a type pattern cannot be told from a
value pattern by syntax alone, as the `type` keyword may be omitted. Consider:
data T a b c where
MkT :: forall a. forall b c -> a -> T a b c
pattern P :: x -> T x y z
pattern P x = MkT @a (type b) c x
In P's right-hand side, `@a` and `type b` are clearly type arguments, but what
about `c` and `x`? We can only tell by matching the patterns against MkT's
type. So tcPatToExpr now runs in TcM and matches the arguments against the
constructor's TyVarBinders using zipPatsBndrs, which is made public for this
purpose. The resulting builder is $bP x = MkT _ _ x.
See Note [Discarding types in the builder expression].
Test cases: T27440a T27440b T27440c T27440d T27440e
T27583a T27583b T27583c T27583d T27583e T27583f T27583g
Metric Increase: LinkableUsage02
Metric Decrease: T27336
Assisted-by: Claude Opus 5
(cherry picked from commit 4f98510802423dcd98fa62af77997189ee97a111)
-
768a7203
by sheaf at 2026-09-03T12:24:43+05:30
mkWpFun_FRR: fix ordering of coercion composition
When the subsumption machinery generates an eta-expansion, we must
perform a representation polymorphism check to ensure the lambda binder
it introduces has a fixed runtime representation.
This is done in GHC.Tc.Utils.mkWpFun_FRR.
This check involves composing quite a few coercions, arising from
representation-polymorphism checks on both the actual and expected
argument types. These coercions are then chained using HsWrapper
composition, <.>. The ordering of composition was incorrect, leading to
the Core Lint failure reported in #27639. This commit fixes that.
Fixes #27639
(cherry picked from commit eb1dcd4d98548b7bc64c323dc352ddbf149a91ec)
-
3df33eca
by Vladislav Zavialov at 2026-09-03T12:25:11+05:30
Fix tcLookupId panic with RequiredTypeArguments and PatternSynonyms (#27586)
The arguments declared on the left-hand side of a pattern synonym are looked up
as term variables bound by its right-hand side. Prior to this patch, that lookup
panicked with RequiredTypeArguments:
data T a where
MkT :: forall a -> T a
pattern P :: Int -> T Int
pattern P x = MkT x
On the RHS, `x` looks like a term argument, so the renamer binds it in the term
namespace. Only during type checking does it turn out to be a type variable, so
the lookup on the LHS finds an ATyVar rather than an ATcId. As the lookup was
done with tcLookupId, it resulted in a panic.
Now the arguments are looked up with tcLookupPatSynArg, which reports an illegal
term-level use of `x`, just as an ordinary function definition `f (MkT x) = x`
does.
Test cases: T27586a T27586b T27586c
Assisted-by: Claude Opus 5
(cherry picked from commit b757727a78613e7437a713058c24b94e10697f47)
-
d8eb75ae
by Zubin Duggal at 2026-09-03T12:27:35+05:30
ghc-internal: annotateSTM should use catchSTM# rather than catch#
A catch# frame inside a transaction breaks retry and async exception
delivery.
Fixes #27657
(cherry picked from commit fd22f71ee92595f4634206455d8eab111488d836)
-
21670d7a
by fendor at 2026-09-03T12:28:40+05:30
GHCi: Fix order of `PackageDBFlag`s for interactive home unit
`PackageDBFlag`s are stored in reverse order of cli specification.
When sorting the `PackageDBFlag`s by longest common prefix, we need thus
to reverse the package db stacks before calculating the prefix.
We make sure to reverse the package db stack for the interactive home
unit to uphold that later specified package dbs overwrite earlier ones.
Resolved and adds regression test for #27640
(cherry picked from commit 06fde293f2e8c80db11f4d01fcdfc482c1128db5)
-
aaff8ff7
by Simon Peyton Jones at 2026-09-03T12:29:56+05:30
Never make an absent filler for a constraint type
mkAbsentFiller used isTerminatingType to decide, but that is not enough.
Consider
class Eq a => UC a where {}
let u :: UC Int -- UC Int is a "non-terminating type"
u = error "Absent"
let e :: Eq Int -- Eq Int is a "terminating type"
e = $p1UC u
We clearly must not make a filler for `e`, because we speculatively
evaluate it. But speculatively evaluating `e` forces `u`, so we must not
make one for `u` either.
Asking isDictTy instead is not enough either, because it does not catch a
constraint hidden behind an unreduced type family application:
type family F a :: Constraint
type instance F W = TC W
a :: F W => Int -> Int -- (F W) argument is absent
Oops! Entered absent arg Arg: irred
Type: F W
So play safe and use isPredTy: never make an absent filler for any
constraint-kinded type.
Fixes #27627
(cherry picked from commit 7bf546fc423e23cb649580016ee494efbfe144ab)
-
bc85dcac
by Zubin Duggal at 2026-09-03T12:29:57+05:30
Add tests for absent fillers at dictionary types
T27627 a unary class whose superclass is a non-unary class
T27627a ...whose superclass is a Constraint-kinded type family
T27627b ...whose superclass is a quantified constraint
T27627c a unary class applied to itself, (UC (UC (TC a)))
T27627e a (forall b. P b) dictionary that loops
(cherry picked from commit 5f474953d1880232b5e6c5741f08746e28cd25ab)
-
8e59b385
by Zubin Duggal at 2026-09-03T12:29:57+05:30
An abstract TyCon may hide a unary class
A class declared in an hs-boot file is an AbstractTyCon inside the
module loop, and compiling the real declaration may reveal it to be a
UnaryClassTyCon.
- isTerminatingType returned True for such AbstractTyCons
- IfaceToCore set the unary flag to False in the DFunId
So we could end up speculating bottom dictionaries because inside a module
loop we see an UnaryClassTyCon as an AbstractTyCon
Use isTerminatingTyCon, which returns False for an abstract TyCon.
The Bool in DFunId is now a cache for isTerminatingTyCon, set in
mkDFunIdDetails.
Fixes #27704
(cherry picked from commit cd5c6bcc0a59c7b4dc4627fdc7471dc7938d07c2)
-
0a73317b
by Zubin Duggal at 2026-09-03T12:30:29+05:30
Specialise: don't replace dead args with absent fillers
specHeader decides an argument is dead by calling isDeadBinder on a binder of
the /optimised RHS/, then applies the filler to the /stable unfolding/
template instead. The two may differ, so the argument can be dead in
the RHS and not in the template.
The specialised function's unfolding then has an absent filler, and any call
site that inlines it evaluates the error thunk.
Dropping dead args in the specialiser is rarely worth it, to quote Simon,
"The later worker/wrapper pass will pick up the dead arg later if it is really dead. Keeps the specialiser simpler."
So instead of trying to check if the arg really is dead in the stable unfolding,
just drop the logic for dropping dead args in the specialiser altogeher.
Fixes #27703
(cherry picked from commit abfc224a27cf499390efc5fe1348301fefebb910)
-
07fc3695
by Zubin Duggal at 2026-09-03T12:30:29+05:30
CorePrep: don't speculate a call across an hs-boot edge
We take care not to evaluate things that might be bottom, like a
looping dictionary group, but our analysis is defeated by boot files.
We only track recursion within a module, so two dictionaries that
depend on each other across a module loop each look non-recursive, and
we might speculate them.
Any recursion we cannot see must cross an hs-boot edge, so refuse to
speculate calls that cross one.
Fixes #27717
(cherry picked from commit 1557fd1cfb802d2608cb5b138eab664564f57fb7)
-
60441138
by Cheng Shao at 2026-09-03T12:31:17+05:30
configure: bump LlvmMaxVersion to 23
This patch bumps `LlvmMaxVersion` to 23 to support LLVM 22.x releases.
(cherry picked from commit cc9cc6d5df7fb3845b1409fe708e1097896252a7)
-
b6c4fbea
by Cheng Shao at 2026-09-03T12:31:38+05:30
autoconf/ghc-toolchain: bump llvm upper bound to support llvm 23
This commit bumps llvm upper bound to support llvm 23.
(cherry picked from commit 56291fc550ec00784e46ec0c89ee65081090ae9f)
-
c0329e1d
by Cheng Shao at 2026-09-03T12:31:38+05:30
rts: fix compilation issues with clang 23
clang 23 has broadened `-Wall`/`-Wextra` ranges, exposing some minor
issues in the rts when building with validate flavours:
- Unused locals
- `#pragma GCC diagnostic pop` mismatch
This commit fixes those.
(cherry picked from commit 20eb3f415f9e04a003322d1a49d95e0aaf1029f2)
-
fca9490e
by Zubin Duggal at 2026-09-03T12:42:47+05:30
fixup! base: Don't drop exception context in SomeException(toException)
-
7a4a0c45
by Cheng Shao at 2026-09-03T12:43:23+05:30
libffi: update to 3.7.1
Bumps libffi submodule.
(cherry picked from commit d7e36a486b224908b1e1f6e5d9eb04084819c805)
-
c8afb3f2
by Andreas Klebinger at 2026-09-03T12:56:15+05:30
cmm dumps: Add machop width info with -dppr-debug for infix ops.
(cherry picked from commit e9bbe8f924ec0b9d0772cf3d4f20aa6a25f28345)
-
b7115dbb
by Andreas Klebinger at 2026-09-03T12:56:22+05:30
CmmLint: Check for unsupported MachOp widths
machOpArgReps now maps MachOp + Width to a list of supported
argument widths or Nothing if the given operation is not supported
at the given width.
This allows us to check for nonsensical combinations like FloatToInt
at Word16.
Similarly we now check that every address is actually wordwidth.
(cherry picked from commit 86e3a9d8d0a85b5c80dad212cf3ec8fbf1ba72e6)
-
6298575d
by Andreas Klebinger at 2026-09-03T12:59:38+05:30
arm64 ncg: The big subword truncation fix.
A set of slightly related fixes to arm subword handling:
Bitmask immediates:
Don't produce overflowing assembly literals.
There is still another bug here that causes us to miss some valid
literals but we will fix that later.
Improve subword truncation handling:
We now use a small set of helpers to truncate `Register` values rather
than truncating immediate `Reg` values which greatly simplifies the code
structure. This fixes a great many bugs to do with sign/zero extending subwords
or the lack thereof.
We now establish the invariant that subword values are zero-extended at
every site at which they come into "scope" of the ncg, and rely on the
invariant throughout rather than pessimistically inserting redundant
extensions in a hodgepodge manner at the use sites of these values.
This fixes at least the bugs described in issues #27533, #27430
#27537, #27538, #27539, and #27550. But likely more bugs yet not
found.
Subword ffi results:
Apply truncations when calling functions returning
subword values.
genCondJump:
Don't sign extend signed values in the input register as
it might map to a local variable, corrupting the value stored within.
Fix subword store/load instructions.:
We used to read those at 32bit width even for smaller values possibly
resulting in invalid memory access. Now we construct the suffix for
subword variants based on the instruction format for these.
(cherry picked from commit 13781cca5c24c2671d651fd2b13a561c7386fe3a)
-
bfe79214
by Andreas Klebinger at 2026-09-03T13:04:08+05:30
Add some test cases covering bugs in the arm ncg.
* Test for #27430 (subword ffi results)
* #27537 - subword conversions
* #27538 - subwords used in conditional
* #27533 - single byte read
(cherry picked from commit 94822c951c2a6f77c7766720e0d4ff7d4afb7290)
-
96224bce
by Andreas Klebinger at 2026-09-03T13:04:12+05:30
cmmLint: Lint against MO_FS_Truncate subword use.
(cherry picked from commit dd1ba88a70f47bead722e9dae8e91f9a617258aa)
-
c7df4cfc
by Zubin Duggal at 2026-09-03T13:06:38+05:30
fixup! Add a deprecation warning for static forms
-
604c6824
by Zubin Duggal at 2026-09-03T13:56:37+05:30
fixup! base: Don't drop exception context in SomeException(toException)
-
b414e021
by fendor at 2026-09-03T14:07:32+05:30
Drop `preloadClosure` from `UnitState`
It is always hard-coded to the same value.
Backpack Unit instantiation isn't using it any more.
Allows us to simplify the API and get rid of `improveUnit`.
(cherry picked from commit fb5246adb7e10bd9ef07de314eaf98fbcfb729a1)
-
811da397
by fendor at 2026-09-03T14:07:53+05:30
Introduce global unit database cache
As a first step for better sharing of `UnitInfo` across `UnitEnv`,
we introduce a new datatype called `ExternalUnitDatabases`.
It primarily serves as an in-memory representation of *all*
`UnitDatabase`s across `UnitEnv`. This means, if multiple `HomeUnitEnv`s
depend on the same database, one way or another, we make sure that we
don't parse from disk every time.
Instead, we store the in-memory representation in `ExternalUnitDatabases`.
`ExternalUnitDatabaseCache` is the equivalent of `ExternalUnitState` in
the `UnitEnv`. It is a mutable variable wrapping `ExternalUnitDatabases`.
The mutable `ExternalUnitDatabaseCache` is used in `initUnits` to make
sure we don't parse the same unit database multiple times.
Almost by accident, we change the semantics of `initUnits` to honour
modifications to `packageDBFlags`.
The inability to change `packageDBFlags` while also reusing the already
parsed `UnitDatabase`s was reported in #26423 as a bug.
Hence, we think this behaviour change is warranted and acceptable,
especially since it comes with a breaking change to the `initUnits` API.
Add regression test for #26423
Closes #26423
(cherry picked from commit 5d0ab71ac1d01c2ef19bf3146adb7dac8733dca5)
-
9fa88e7b
by fendor at 2026-09-03T14:29:45+05:30
Introduce UnitIndex for global external unit caching
`UnitInfo`s have been observed to cause a lot of memory usage in #27500.
Especially with multiple home units, as the same (external) units are
processed from scratch, even though most of the time we end up with
exactly the same `UnitInfo`.
We introduce a `UnitEnv` global cache that allows us to store external
unit information that is used across all `HomeUnitEnv`s.
The most important change in this commit is the introduction of the `UnitIndex`.
It stores a global mapping of `UnitId` -> `UnitInfo`, and `initUnits`
always uses the cached `UnitInfo` entry to populate each
`HomeUnitEnv`'s `UnitState`.
This allows us to ensure the following property:
> Each `UnitInfo` should be alive exactly once in GHC.
All `UnitState`s should reference 'UnitInfo's stored in the 'UnitIndex'.
This ensured by calling 'initUnits' with the 'UnitIndex'.
In addition, the `ExternalUnitDatabases` may also hold a reference
to each on-disk representation of `UnitInfo`.
This means, we impose an hard upper bound on the number of `UnitInfo`s
alive in the GHC session:
> The number of alive `UnitInfo`s closure objects must be the
> sum of all loaded unit database times two.
We add performance regression tests that make sure the number of live
`UnitInfo` cannot exceed this threshold.
Closes #27500
-------------------------
Metric Decrease:
MultiComponentModules
MultiComponentModulesRecomp
MultiComponentModulesRecomp100
mhu-perf
LinkableUsage02
-------------------------
These metrics increases are especially notable, as we are not even
sharing anything big but merely the global package database with 50
entries.
It shows how careful sharing of `UnitInfo` can improve memory usage.
We expect this to be much more notable when the whole cabal package
database is shared across multiple home units.
`LinkableUsage02` metric decreases on unreg and i386 platform, only.
---
Technical details
To share the `UnitInfo`s correctly, it is important that we extract
the `WireMap` into the `UnitIndex`. At the moment of writing, `WireMap`
must be globally the same for all `HomeUnitEnv`s.
This is important, as we could otherwise not cache the "fully-resolved"
`UnitInfo`, as we don't change the `UnitId` or `unitAbiHash` when
resolving wired-in units. Thus, there could be ambiguities, when the
`WireMap` is not the same for all `UnitState`s across the `UnitEnv`.
We consider a `UnitInfo` fully-resolved, if wired-in units have been
updated, the `UnitInfo` has been validated and variables in the unit
config, such as `${pkgroot}` have been resolved.
Updating the wired-in units requires the `WireMap` to be globally the
same.
(cherry picked from commit 6cce494a7ec43953c7a949e0d8ce712abfe73da7)
-
481dc5ce
by fendor at 2026-09-03T14:30:47+05:30
Reuse the UnitIndexCache after initialising multiple home units
(cherry picked from commit 024c4d04a98f7e27b3dcb93f9b038f9b6b5a1ad9)
-
9fc20ad3
by Andreas Klebinger at 2026-09-03T14:30:52+05:30
Specialise: Stop looping on recursive dictionaries in interestingDict
interestingDict now doesn't look through loopbreaker unfoldings.
Doing so would cause infinite loops on certain dictionaries.
Fixes #27705.
(cherry picked from commit 578bd18509f0d2aeb004231a197f7f3898f86a2a)
-
a764f8ce
by Zubin Duggal at 2026-09-03T15:14:37+05:30
hadrian: constrain splitmix to keep building on Debian 9
-
f37ae7a6
by Zubin Duggal at 2026-09-03T15:14:37+05:30
Bump file-io submodule to 0.1.6
-
0aa35678
by Zubin Duggal at 2026-09-03T15:14:37+05:30
Bump haskeline submodule to 0.8.5.0
-
1e794061
by Zubin Duggal at 2026-09-03T15:14:37+05:30
Bump os-string submodule to 2.0.10
-
cd61daa7
by Zubin Duggal at 2026-09-03T15:14:37+05:30
Bump directory submodule to 1.3.11.0
-
08f58e96
by Zubin Duggal at 2026-09-03T15:15:01+05:30
Prepare 9.14.2-rc2