[Git][ghc/ghc][wip/T27629] Re-introduce the "weird SpecDict" case
by Simon Peyton Jones (@simonpj) 03 Sep '26
by Simon Peyton Jones (@simonpj) 03 Sep '26
03 Sep '26
Simon Peyton Jones pushed to branch wip/T27629 at Glasgow Haskell Compiler / GHC
Commits:
eed2f9cc by Simon Peyton Jones at 2026-09-03T11:17:07+01:00
Re-introduce the "weird SpecDict" case
In this commit
commit f80375dd4945350a1d784e436975b48b9c736eaf
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Sun Jun 29 15:26:58 2025 +0100
Refactor of Specialise.hs
I removed a test for a dictionary with unbound type variables. This
turned out to be wrong; see #27629.
So this MR re-introduces it.
- - - - -
6 changed files:
- compiler/GHC/Core/Opt/Specialise.hs
- testsuite/tests/simplCore/should_compile/Makefile
- + testsuite/tests/simplCore/should_compile/T27629.hs
- + testsuite/tests/simplCore/should_compile/T27629.stderr
- + testsuite/tests/simplCore/should_compile/T27629Plugin.hs
- testsuite/tests/simplCore/should_compile/all.T
Changes:
=====================================
compiler/GHC/Core/Opt/Specialise.hs
=====================================
@@ -1713,9 +1713,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
; let spec_rhs_bndrs = spec_bndrs ++ inner_rhs_bndrs'
(rhs_uds2, inner_dumped_dbs) = dumpUDs spec_rhs_bndrs $
dx_binds `consDictBinds` rhs_uds
- -- dx_binds comes from the arguments to the call,
- -- and so can mention poly_qvars but no other local binders
- spec_rhs = mkLams spec_rhs_bndrs $
+ spec_rhs = mkLams spec_rhs_bndrs $
wrapDictBindsE inner_dumped_dbs rhs_body'
rule_rhs_args = spec_bndrs
@@ -1784,8 +1782,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
, text "rule_act" <+> ppr rule_act
]
--- ; pprTrace "spec_call: rule" (vcat [ -- text "poly_qvars" <+> ppr poly_qvars
--- text "rule_bndrs" <+> ppr rule_bndrs
+-- ; pprTrace "spec_call: rule" (vcat [ text "rule_bndrs" <+> ppr rule_bndrs
-- , text "rule_lhs_args" <+> ppr rule_lhs_args
-- , text "all_call_args" <+> ppr all_call_args
-- , ppr spec_rule ]) $
@@ -2611,6 +2608,14 @@ specHeader subst (bndr:bndrs) (UnspecType : args)
-- a wildcard binder to match the dictionary (See Note [Specialising Calls] for
-- the nitty-gritty), as a LHS rule and unfolding details.
specHeader subst (bndr:bndrs) (SpecDict dict_arg : args)
+ | let in_scope = getInScopeVars (substInScopeSet subst)
+ bad_dict_fv v = isLocalVar v && not (v `elemVarSet` in_scope)
+ , not $ isEmptyVarSet $ exprSomeFreeVars bad_dict_fv dict_arg
+ = -- Do not specialise if `dict_arg` has any any free vars that are /not/ in scope
+ -- See Note [Weird special case for SpecDict]
+ specHeader mod subst (bndr:bndrs) (UnspecArg : args)
+
+ | otherwise
= do { -- Make up a fresh binder to use in the RULE
-- It might turn into a dict binding (via bindAuxiliaryDict) which we
-- then float, so we use cloneIdBndr to get a completely fresh binder
@@ -2886,13 +2891,15 @@ We could zap `k` to (Any @Type) and `a` to (Any @(Any @Type)), but that
is a lot of hard work for a very strange case.
So we simply refrain from specialising in this case; hence the guard
- allVarSet (`elemInScopeSet` in_scope) (exprFreeVars d)
-in the SpecDict cased of specHeader.
-
-How did this strange polymorphic mkD arise in the first place?
-From GHC.Core.Opt.Utils.abstractFloats, which was abstracting
-over too many type variables. But that too is now fixed;
-see Note [Which type variables to abstract over] in that module.
+ not $ isEmptyVarSet $ exprSomeFreeVars bad_dict_fv dict_arg
+in the SpecDict case of `specHeader`.
+
+How did this strange polymorphic mkD arise in the first place? From
+GHC.Core.Opt.Utils.abstractFloats, which was abstracting over too many type
+variables. But that too is now fixed; see Note [Which type variables to abstract
+over] in that module. So we don't actually have a Haskell source program that
+triggers it (see #27629) -- only test T27629 that uses a plugin to inject a strange
+definition.
-}
instance Outputable DictBind where
=====================================
testsuite/tests/simplCore/should_compile/Makefile
=====================================
@@ -3,6 +3,12 @@ include $(TOP)/mk/boilerplate.mk
include $(TOP)/mk/test.mk
+# T27629 runs a plugin that injects a Core binding
+# that made the specialiser crash
+T27629:
+ '$(TEST_HC)' $(TEST_HC_OPTS) --make -package ghc -dynamic-too -c T27629Plugin.hs
+ '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fpolymorphic-specialisation -dcore-lint T27629.hs
+
# T18815 should not have a non-recursive join-point for 'go'
# Previously we ended up with
# join {go_sPI w_sQ3 = case w_sQ3 of { GHC.Types.I# ww1_sQ6 ->
=====================================
testsuite/tests/simplCore/should_compile/T27629.hs
=====================================
@@ -0,0 +1,29 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# OPTIONS_GHC -fplugin=T27629Plugin #-}
+
+-- The plugin rewrites 'poly' to the example of
+-- Note [Weird special case for SpecDict]:
+--
+-- poly = /\x. \t. split @T (mkD @x MkT) [t]
+--
+-- where mkD :: forall a. T -> C T is a new top-level binding
+-- (mkD = /\a. \_. $fCT), so the tyvar x is free in the dictionary
+-- *expression* but not in its *type* (C T).
+module T27629 (poly, split, T (..), C (..)) where
+
+import Data.Kind (Type)
+
+data T = MkT
+
+class C b where
+ meth :: b -> b
+
+instance C T where
+ meth x = x
+
+split :: C b => [b] -> [b]
+split [] = []
+split (x : xs) = meth x : split xs
+
+poly :: forall (x :: Type). T -> [T]
+poly t = [t]
=====================================
testsuite/tests/simplCore/should_compile/T27629.stderr
=====================================
@@ -0,0 +1 @@
+ReproPlugin: injected weird SpecDict call into poly
=====================================
testsuite/tests/simplCore/should_compile/T27629Plugin.hs
=====================================
@@ -0,0 +1,94 @@
+-- Injects the example of Note [Weird special case for SpecDict] in
+-- GHC.Core.Opt.Specialise, which cannot be written in source Haskell:
+-- a call whose dictionary argument mentions a type variable that is
+-- free in the dictionary expression but not in its type.
+--
+-- Runs before the main Core pipeline (in particular before the
+-- Specialiser). It adds
+--
+-- mkD :: forall a. T -> C T {-# NOINLINE mkD #-}
+-- mkD = /\a. \_. $fCT
+--
+-- and rewrites poly = /\x. \t. [t]
+-- to poly = /\x. \t. split @T (mkD @x MkT) [t]
+{-# LANGUAGE CPP #-}
+module T27629Plugin (plugin) where
+
+import GHC.Core.Make (mkCoreApps, mkListExpr)
+import GHC.Core.Predicate (getClassPredTys_maybe)
+import GHC.Plugins
+#if __GLASGOW_HASKELL__ >= 1000
+import GHC.Types.InlinePragma (neverInlinePragma)
+#else
+import GHC.Types.Basic (neverInlinePragma)
+#endif
+
+plugin :: Plugin
+plugin =
+ defaultPlugin
+ { installCoreToDos = \_ todos ->
+ return (CoreDoPluginPass "inject-weird-specdict" pass : todos)
+ , pluginRecompile = purePlugin
+ }
+
+pass :: ModGuts -> CoreM ModGuts
+pass guts = do
+ let binds = mg_binds guts
+
+ dfun = case [b | b <- bindersOfBinds binds, isDFunId b] of
+ (b : _) -> b
+ [] -> panic "ReproPlugin: no dfun binding in module"
+
+ dictTy = idType dfun -- C T
+ tyT = case getClassPredTys_maybe dictTy of
+ Just (_cls, [t]) -> t
+ _ -> panic "ReproPlugin: dfun type is not C T"
+
+ mkTCon = case tyConDataCons (tyConAppTyCon tyT) of
+ (dc : _) -> dataConWorkId dc
+ [] -> panic "ReproPlugin: T has no data constructors"
+
+ findTopId nm =
+ case [b | b <- bindersOfBinds binds, occNameString (getOccName b) == nm] of
+ (b : _) -> b
+ [] -> panic ("ReproPlugin: no top-level binding " ++ nm)
+
+ splitId = findTopId "split"
+ polyId = findTopId "poly"
+
+ uMkD <- getUniqueM
+ uTv <- getUniqueM
+ uWild <- getUniqueM
+
+ let aTv = mkTyVar (mkSystemName uTv (mkTyVarOcc "a")) liftedTypeKind
+ mkDTy = mkSpecForAllTys [aTv] (mkFunctionType ManyTy tyT dictTy)
+ mkDId =
+ setInlinePragma
+ (mkExportedVanillaId (mkSystemName uMkD (mkVarOcc "mkD")) mkDTy)
+ neverInlinePragma
+ wild = mkSysLocal (fsLit "eta") uWild ManyTy tyT
+ mkDBind = NonRec mkDId (mkLams [aTv, wild] (Var dfun))
+
+ rewritePoly rhs
+ | (bndrs, _body) <- collectBinders rhs
+ , (x : _) <- reverse (filter isTyVar bndrs)
+ , (t : _) <- filter isId bndrs
+ = mkLams bndrs $
+ mkCoreApps
+ (Var splitId)
+ [ Type tyT
+ , mkCoreApps (Var mkDId) [Type (mkTyVarTy x), Var mkTCon]
+ , mkListExpr tyT [Var t]
+ ]
+ | otherwise =
+ pprPanic "ReproPlugin: unexpected shape of poly" (ppr rhs)
+
+ go (b, rhs)
+ | b == polyId = (b, rewritePoly rhs)
+ | otherwise = (b, rhs)
+
+ -- One top-level Rec, so bind order is irrelevant.
+ binds' = [Rec (map go (flattenBinds binds) ++ flattenBinds [mkDBind])]
+
+ putMsgS "ReproPlugin: injected weird SpecDict call into poly"
+ return guts {mg_binds = binds'}
=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -611,3 +611,4 @@ test('T27296', [], makefile_test, ['T27296'])
test('T27296b', [], makefile_test, ['T27296b'])
test('T27589', [grep_errmsg(r'wombat')], compile, ['-O -ddump-simpl -dno-typeable-binds -dsuppress-uniques'])
test('T27590', [grep_errmsg(r'wombat')], compile, ['-O -ddump-simpl -dno-typeable-binds -dsuppress-uniques'])
+test('T27629', only_ways(['optasm']), makefile_test, ['T27629'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eed2f9cccb80bddaa047bab6f754b49…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eed2f9cccb80bddaa047bab6f754b49…
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/9.14.2-rc2] 34 commits: base: Don't drop exception context in SomeException(toException)
by Zubin (@wz1000) 03 Sep '26
by Zubin (@wz1000) 03 Sep '26
03 Sep '26
Zubin pushed to branch wip/9.14.2-rc2 at Glasgow Haskell Compiler / GHC
Commits:
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
- - - - -
206 changed files:
- − changelog.d/27626
- − changelog.d/T26716
- compiler/GHC.hs
- compiler/GHC/Cmm/Expr.hs
- compiler/GHC/Cmm/Lint.hs
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/AArch64/Instr.hs
- compiler/GHC/CmmToAsm/AArch64/Ppr.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Types/Demand.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Literal.hs
- compiler/GHC/Types/Unique.hs
- compiler/GHC/Unit.hs
- compiler/GHC/Unit/Env.hs
- + compiler/GHC/Unit/External/Database.hs
- + compiler/GHC/Unit/External/Index.hs
- + compiler/GHC/Unit/External/ModuleOrigin.hs
- + compiler/GHC/Unit/External/Providers.hs
- + compiler/GHC/Unit/External/Query.hs
- + compiler/GHC/Unit/External/Substitution.hs
- + compiler/GHC/Unit/External/Validate.hs
- + compiler/GHC/Unit/External/Visibility.hs
- + compiler/GHC/Unit/External/Wired.hs
- compiler/GHC/Unit/Home/Graph.hs
- compiler/GHC/Unit/Info.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- compiler/ghc.cabal.in
- configure.ac
- docs/users_guide/9.14.2-notes.rst
- ghc/GHCi/UI.hs
- hadrian/cabal.project
- hadrian/src/Rules/Generate.hs
- libffi-tarballs
- libraries/base/changelog.md
- libraries/directory
- libraries/file-io
- libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- libraries/haskeline
- libraries/os-string
- rts/ProfHeap.c
- rts/eventlog/EventLog.c
- rts/prim/atomic.c
- + testsuite/tests/codeGen/should_run/T27430.hs
- + testsuite/tests/codeGen/should_run/T27430.stdout
- + testsuite/tests/codeGen/should_run/T27430_c.c
- + testsuite/tests/codeGen/should_run/T27533.hs
- + testsuite/tests/codeGen/should_run/T27533.stdout
- + testsuite/tests/codeGen/should_run/T27533_cmm.cmm
- + testsuite/tests/codeGen/should_run/T27537.hs
- + testsuite/tests/codeGen/should_run/T27537.stdout
- + testsuite/tests/codeGen/should_run/T27538.hs
- + testsuite/tests/codeGen/should_run/T27538.stdout
- testsuite/tests/codeGen/should_run/all.T
- + testsuite/tests/concurrent/should_run/T27657a.hs
- + testsuite/tests/concurrent/should_run/T27657a.stdout
- + testsuite/tests/concurrent/should_run/T27657b.hs
- + testsuite/tests/concurrent/should_run/T27657b.stdout
- testsuite/tests/concurrent/should_run/all.T
- + testsuite/tests/core-to-stg/T27627/Callee.hs
- + testsuite/tests/core-to-stg/T27627/Caller.hs
- + testsuite/tests/core-to-stg/T27627/Main.hs
- + testsuite/tests/core-to-stg/T27627/T27627.stdout
- + testsuite/tests/core-to-stg/T27627/all.T
- + testsuite/tests/core-to-stg/T27627a/Callee.hs
- + testsuite/tests/core-to-stg/T27627a/Caller.hs
- + testsuite/tests/core-to-stg/T27627a/Main.hs
- + testsuite/tests/core-to-stg/T27627a/T27627a.stdout
- + testsuite/tests/core-to-stg/T27627a/all.T
- + testsuite/tests/core-to-stg/T27627b/Callee.hs
- + testsuite/tests/core-to-stg/T27627b/Caller.hs
- + testsuite/tests/core-to-stg/T27627b/Main.hs
- + testsuite/tests/core-to-stg/T27627b/T27627b.stdout
- + testsuite/tests/core-to-stg/T27627b/all.T
- + testsuite/tests/core-to-stg/T27627c/Callee.hs
- + testsuite/tests/core-to-stg/T27627c/Caller.hs
- + testsuite/tests/core-to-stg/T27627c/Main.hs
- + testsuite/tests/core-to-stg/T27627c/T27627c.stdout
- + testsuite/tests/core-to-stg/T27627c/all.T
- + testsuite/tests/core-to-stg/T27627e.hs
- + testsuite/tests/core-to-stg/T27627e.stdout
- + testsuite/tests/core-to-stg/T27627f/Callee.hs
- + testsuite/tests/core-to-stg/T27627f/Caller.hs
- + testsuite/tests/core-to-stg/T27627f/Inst.hs
- + testsuite/tests/core-to-stg/T27627f/Main.hs
- + testsuite/tests/core-to-stg/T27627f/T27627f.stdout
- + testsuite/tests/core-to-stg/T27627f/all.T
- + testsuite/tests/core-to-stg/T27704/Callee.hs
- + testsuite/tests/core-to-stg/T27704/Callee.hs-boot
- + testsuite/tests/core-to-stg/T27704/Main.hs
- + testsuite/tests/core-to-stg/T27704/Mid.hs
- + testsuite/tests/core-to-stg/T27704/T27704.stdout
- + testsuite/tests/core-to-stg/T27704/all.T
- + testsuite/tests/core-to-stg/T27704a/Callee.hs
- + testsuite/tests/core-to-stg/T27704a/Callee.hs-boot
- + testsuite/tests/core-to-stg/T27704a/Main.hs
- + testsuite/tests/core-to-stg/T27704a/Mid.hs
- + testsuite/tests/core-to-stg/T27704a/T27704a.stdout
- + testsuite/tests/core-to-stg/T27704a/all.T
- + testsuite/tests/core-to-stg/T27717/Callee.hs
- + testsuite/tests/core-to-stg/T27717/Callee.hs-boot
- + testsuite/tests/core-to-stg/T27717/Main.hs
- + testsuite/tests/core-to-stg/T27717/Mid.hs
- + testsuite/tests/core-to-stg/T27717/T27717.stdout
- + testsuite/tests/core-to-stg/T27717/Ty.hs
- + testsuite/tests/core-to-stg/T27717/all.T
- testsuite/tests/core-to-stg/all.T
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/driver/T26423/Hello.hs
- + testsuite/tests/driver/T26423/Makefile
- + testsuite/tests/driver/T26423/T26423.hs
- + testsuite/tests/driver/T26423/T26423.stderr
- + testsuite/tests/driver/T26423/T26423.stdout
- + testsuite/tests/driver/T26423/all.T
- + testsuite/tests/driver/T26423/test/Test.hs
- + testsuite/tests/driver/T26423/test/test.pkg
- + testsuite/tests/driver/TUnitInfo/Foo.hs
- + testsuite/tests/driver/TUnitInfo/Makefile
- + testsuite/tests/driver/TUnitInfo/all.T
- + testsuite/tests/driver/TUnitInfo/genMhu.sh
- + testsuite/tests/driver/TUnitInfo/generic-unit-info-space-mhu.stdout
- + testsuite/tests/driver/TUnitInfo/generic-unit-info-space-single.stdout
- + testsuite/tests/driver/TUnitInfo/generic-unit-info-space.hs
- + testsuite/tests/driver/TUnitInfo/generic-unit-info-space.stdout
- testsuite/tests/ghc-e/should_fail/T9930fail.stderr
- testsuite/tests/ghc-e/should_run/ghc-e005.stderr
- + testsuite/tests/ghci/prog-mhu007/Makefile
- + testsuite/tests/ghci/prog-mhu007/a/A.hs
- + testsuite/tests/ghci/prog-mhu007/all.T
- + testsuite/tests/ghci/prog-mhu007/b/B.hs
- + testsuite/tests/ghci/prog-mhu007/prog-mhu007.script
- + testsuite/tests/ghci/prog-mhu007/prog-mhu007.stdout
- + testsuite/tests/ghci/prog-mhu007/testpkg-bar/Bar.hs
- + testsuite/tests/ghci/prog-mhu007/testpkg-bar/testpkg-bar.pkg
- + testsuite/tests/ghci/prog-mhu007/testpkg-foo/Foo.hs
- + testsuite/tests/ghci/prog-mhu007/testpkg-foo/testpkg-foo.pkg
- + testsuite/tests/ghci/prog-mhu007/unitA
- + testsuite/tests/ghci/prog-mhu007/unitB
- + testsuite/tests/patsyn/should_compile/T27440a.hs
- + testsuite/tests/patsyn/should_compile/T27440b.hs
- + testsuite/tests/patsyn/should_compile/T27440c.hs
- testsuite/tests/patsyn/should_compile/all.T
- + testsuite/tests/patsyn/should_fail/T27440d.hs
- + testsuite/tests/patsyn/should_fail/T27440d.stderr
- testsuite/tests/patsyn/should_fail/all.T
- + testsuite/tests/rep-poly/T27639.hs
- testsuite/tests/rep-poly/all.T
- testsuite/tests/simplCore/should_compile/T17966.stderr
- testsuite/tests/simplCore/should_compile/T7785.stderr
- testsuite/tests/simplCore/should_compile/spec004.hs
- testsuite/tests/simplCore/should_compile/spec004.stderr
- + testsuite/tests/simplCore/should_run/T27703/Lib.hs
- + testsuite/tests/simplCore/should_run/T27703/Main.hs
- + testsuite/tests/simplCore/should_run/T27703/T27703.stdout
- + testsuite/tests/simplCore/should_run/T27703/all.T
- + testsuite/tests/simplCore/should_run/T27705.hs
- + testsuite/tests/simplCore/should_run/T27705.stdout
- + testsuite/tests/simplCore/should_run/T27705_Inst.hs
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/typecheck/should_compile/T26718.stderr
- + testsuite/tests/typecheck/should_compile/T27664.hs
- testsuite/tests/typecheck/should_compile/all.T
- + testsuite/tests/vdq-rta/should_compile/T27583a.hs
- + testsuite/tests/vdq-rta/should_compile/T27583b.hs
- + testsuite/tests/vdq-rta/should_compile/T27583c.hs
- + testsuite/tests/vdq-rta/should_compile/T27583d.hs
- + testsuite/tests/vdq-rta/should_compile/T27583e.hs
- + testsuite/tests/vdq-rta/should_compile/T27583g.hs
- testsuite/tests/vdq-rta/should_compile/all.T
- + testsuite/tests/vdq-rta/should_fail/T27440e.hs
- + testsuite/tests/vdq-rta/should_fail/T27440e.stderr
- + testsuite/tests/vdq-rta/should_fail/T27583f.hs
- + testsuite/tests/vdq-rta/should_fail/T27583f.stderr
- + testsuite/tests/vdq-rta/should_fail/T27586a.hs
- + testsuite/tests/vdq-rta/should_fail/T27586a.stderr
- + testsuite/tests/vdq-rta/should_fail/T27586b.hs
- + testsuite/tests/vdq-rta/should_fail/T27586b.stderr
- + testsuite/tests/vdq-rta/should_fail/T27586c.hs
- + testsuite/tests/vdq-rta/should_fail/T27586c.stderr
- testsuite/tests/vdq-rta/should_fail/all.T
- utils/haddock/haddock-api/src/Haddock.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/03babb4526e14779588476693e7826…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/03babb4526e14779588476693e7826…
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/27323] Don't report -XStrict-generated bangs under -Wredundant-bang-patterns
by Sasha Bogicevic (@Bogicevic) 03 Sep '26
by Sasha Bogicevic (@Bogicevic) 03 Sep '26
03 Sep '26
Sasha Bogicevic pushed to branch wip/27323 at Glasgow Haskell Compiler / GHC
Commits:
f14b27ba by Sasha Bogicevic at 2026-09-03T11:28:23+02:00
Don't report -XStrict-generated bangs under -Wredundant-bang-patterns
With -XStrict, decideBangHood inserts bang patterns on binders. When
such a bang cannot force anything (e.g. on a binder of unlifted type),
-Wredundant-bang-patterns reported it, even though there is no bang in
the source to remove.
The desugarer now tracks whether it is desugaring compiler-generated
code, mirroring tcl_in_gen_code in the typechecker:
* decideBangHood places the bangs it inserts at a generatedSrcSpan.
* DsLclEnv gains a dsl_in_generated_code field, maintained solely by
putSrcSpanDs: a real span clears it, a generated span sets it.
* The pattern-match checker's desugaring (desugarLPat) pushes each
pattern's location, and on a bang in generated code emits a PmBang
with no SrcInfo: it is still divergence-checked (so inaccessible-RHS
warnings under -XStrict survive, #21761), but never reported as
redundant.
See Note [Desugaring -XStrict matches in Pmc] in GHC.HsToCore.Pmc.Desugar.
Making these bangs proper expanded patterns instead is tracked as #27677.
- - - - -
7 changed files:
- + changelog.d/T27323
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Types.hs
- compiler/GHC/HsToCore/Utils.hs
- + testsuite/tests/pmcheck/should_compile/T27323.hs
- testsuite/tests/pmcheck/should_compile/all.T
Changes:
=====================================
changelog.d/T27323
=====================================
@@ -0,0 +1,7 @@
+section: compiler
+synopsis: Don't report ``-XStrict``-generated bang patterns under ``-Wredundant-bang-patterns``
+description:
+ Bangs introduced by ``-XStrict`` are no longer reported as redundant under
+ ``-Wredundant-bang-patterns``, as they are not user-written.
+issues: #27323
+mrs: !16395
=====================================
compiler/GHC/HsToCore/Monad.hs
=====================================
@@ -15,7 +15,7 @@ module GHC.HsToCore.Monad (
duplicateLocalDs, newSysLocalDs, newSysLocalsDs,
newSysLocalMDs, newSysLocalsMDs, newFailLocalMDs,
newUniqueId, newPredVarDs, newStaticId,
- getSrcSpanDs, putSrcSpanDs, putSrcSpanDsA,
+ getSrcSpanDs, inGeneratedCodeDs, putSrcSpanDs, putSrcSpanDsA,
mkNamePprCtxDs,
newUnique,
UniqSupply, newUniqueSupply,
@@ -584,6 +584,7 @@ mkDsEnvs unit_env mod rdr_env type_env fam_inst_env tcm_plugins ptc msg_var
, dsl_loc = real_span
, dsl_nablas = Ldi initNablas
, dsl_unspecables = Just emptyVarSet
+ , dsl_in_generated_code = False
}
in (gbl_env, lcl_env)
@@ -676,13 +677,17 @@ getSrcSpanDs :: DsM SrcSpan
getSrcSpanDs = do { env <- getLclEnv
; return (RealSrcSpan (dsl_loc env) Strict.Nothing) }
+-- | See 'dsl_in_generated_code'
+inGeneratedCodeDs :: DsM Bool
+inGeneratedCodeDs = dsl_in_generated_code <$> getLclEnv
+
putSrcSpanDs :: SrcSpan -> DsM a -> DsM a
putSrcSpanDs (RealSrcSpan real_span _) thing_inside
- = updLclEnv (\ env -> env {dsl_loc = real_span}) thing_inside
+ = updLclEnv (\ env -> env {dsl_loc = real_span, dsl_in_generated_code = False}) thing_inside
putSrcSpanDs UnhelpfulSpan{} thing_inside
= thing_inside
putSrcSpanDs GeneratedSrcSpan{} thing_inside
- = thing_inside
+ = updLclEnv (\ env -> env {dsl_in_generated_code = True}) thing_inside
putSrcSpanDsA :: EpAnn ann -> DsM a -> DsM a
putSrcSpanDsA loc = putSrcSpanDs (locA loc)
=====================================
compiler/GHC/HsToCore/Pmc/Desugar.hs
=====================================
@@ -155,11 +155,15 @@ desugarPat x pat = case pat of
VarPat _ y -> pure (mkPmLetVar (unLoc y) x)
ParPat _ p -> desugarLPat x p
LazyPat _ _ -> pure GdEnd -- like a wildcard
- BangPat _ p@(L l p') ->
+ BangPat _ p@(L l p') -> do
-- Add the bang in front of the list, because it will happen before any
-- nested stuff.
+ in_gen <- inGeneratedCodeDs
+ -- A bang inserted by -XStrict (decideBangHood) has no SrcInfo: it is
+ -- divergence-checked but never reported as redundant (#27323).
+ let pm_loc | in_gen = Nothing
+ | otherwise = Just (SrcInfo (L (locA l) (ppr p')))
consGrdDag (PmBang x pm_loc) <$> desugarLPat x p
- where pm_loc = Just (SrcInfo (L (locA l) (ppr p')))
-- (x@pat) ==> Desugar pat with x as match var and handle impedance
-- mismatch with incoming match var
@@ -311,7 +315,7 @@ desugarPatV pat = do
pure (x, grds)
desugarLPat :: Id -> LPat GhcTc -> DsM GrdDag
-desugarLPat x = desugarPat x . unLoc
+desugarLPat x (L loc pat) = putSrcSpanDsA loc (desugarPat x pat)
-- | 'desugarLPat', but also select and return a new match var.
desugarLPatV :: LPat GhcTc -> DsM (Id, GrdDag)
@@ -650,4 +654,19 @@ user *had* written a bang:
+ In an equation for ‘idV’: idV !v = ...
So we live with the duplication.
+
+Note that 'decideBangHood' places the bangs it inserts at a 'generatedSrcSpan'.
+When 'desugarLPat' enters such a span, 'putSrcSpanDs' (GHC.HsToCore.Monad)
+records in 'dsl_in_generated_code' that we are desugaring compiler-generated
+code. For a bang in generated code, 'desugarPat' emits a 'PmBang' with no
+'SrcInfo': the checker still performs the divergence check (so the
+inaccessible-RHS warning above survives), but -Wredundant-bang-patterns only
+ever reports bangs the user actually wrote (#27323). See
+Note [Dead bang patterns] in GHC.HsToCore.Pmc.Check.
+
+Eventually the bangs inserted by -XStrict should become expanded patterns,
+following Note [Handling overloaded and rebindable constructs] in
+GHC.Rename.Expr. That would let warnings always display the original
+user-written code, making the decideBangHood duplication described above
+unnecessary. This is tracked as #27677.
-}
=====================================
compiler/GHC/HsToCore/Types.hs
=====================================
@@ -11,7 +11,7 @@ module GHC.HsToCore.Types (
DsMetaEnv, DsMetaVal(..), CompleteMatches
) where
-import GHC.Prelude (Int)
+import GHC.Prelude (Bool, Int)
import Data.IORef
@@ -125,6 +125,7 @@ data DsLclEnv
-- ^ See Note [Desugaring non-canonical evidence]
-- This field collects all un-specialisable evidence variables in scope.
-- Nothing <=> don't collect this info (used for the LHS of Rules)
+ , dsl_in_generated_code :: Bool -- Desugaring compiler-generated or user-written code
}
-- Inside [| |] brackets, the desugarer looks
=====================================
compiler/GHC/HsToCore/Utils.hs
=====================================
@@ -951,6 +951,9 @@ Specifically:
-- | Use -XStrict to add a ! or remove a ~
+-- The bang we insert is compiler-generated, so we put it at a generatedSrcSpan.
+-- The pattern-match checker uses this (via dsl_in_generated_code) to avoid reporting
+-- such bangs under -Wredundant-bang-patterns (#27323).
-- See Note [decideBangHood]
decideBangHood :: DynFlags
-> LPat GhcTc -- ^ Original pattern
@@ -966,7 +969,7 @@ decideBangHood dflags lpat
ParPat x p -> L l (ParPat x (go p))
LazyPat _ lp' -> lp'
BangPat _ _ -> lp
- _ -> L l (BangPat noExtField lp)
+ _ -> L (noAnnSrcSpan generatedSrcSpan) (BangPat noExtField lp)
isTrueLHsExpr :: LHsExpr GhcTc -> Maybe (CoreExpr -> DsM CoreExpr)
=====================================
testsuite/tests/pmcheck/should_compile/T27323.hs
=====================================
@@ -0,0 +1,9 @@
+{-# LANGUAGE MagicHash, Strict #-}
+{-# OPTIONS_GHC -Wredundant-bang-patterns #-}
+
+import GHC.Prim (Int#)
+
+idInt# :: Int# -> Int#
+idInt# x = x
+
+main = pure ()
=====================================
testsuite/tests/pmcheck/should_compile/all.T
=====================================
@@ -190,4 +190,5 @@ test('T24845', [], compile, [overlapping_incomplete])
test('T22652', [], compile, [overlapping_incomplete])
test('T22652a', [], compile, [overlapping_incomplete])
test('T24867', [], compile_fail, [overlapping_incomplete])
+test('T27323', normal, compile, ['-Wredundant-bang-patterns'])
test('T27360', normal, compile, [overlapping_incomplete + '-g3'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f14b27ba9cd7043cb32c00ad0e522e8…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f14b27ba9cd7043cb32c00ad0e522e8…
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/mangoiv/ci-stages] ci: clean up env before running tests even more
by Magnus (@MangoIV) 03 Sep '26
by Magnus (@MangoIV) 03 Sep '26
03 Sep '26
Magnus pushed to branch wip/mangoiv/ci-stages at Glasgow Haskell Compiler / GHC
Commits:
43337463 by mangoiv at 2026-09-03T11:13:40+02:00
ci: clean up env before running tests even more
- - - - -
1 changed file:
- .gitlab/ci.sh
Changes:
=====================================
.gitlab/ci.sh
=====================================
@@ -968,7 +968,7 @@ function run_hadrian() {
if [ -n "${VERBOSE:-}" ]; then args+=("-V"); fi
# Before running the compiler, unset variables gitlab env vars as these
# can destabilise the performance test (see #20341)
- (unset $(compgen -v | grep CI_*);
+ (unset $(compgen -v | grep -E '^(CI_|FF_|GITLAB_)');
# dump the env before running hdarian itself.
start_section run_hadrian_env "env for runnning hadrian"; env; end_section run_hadrian_env
run "${HADRIAN_PATH:-hadrian/build-cabal}" \
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4333746379de774b9727fdfea777ef1…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4333746379de774b9727fdfea777ef1…
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/T27664] 47 commits: testsuite: Use sigkill in process009.
by Simon Peyton Jones (@simonpj) 03 Sep '26
by Simon Peyton Jones (@simonpj) 03 Sep '26
03 Sep '26
Simon Peyton Jones pushed to branch wip/T27664 at Glasgow Haskell Compiler / GHC
Commits:
fed942ac by Andreas Klebinger at 2026-08-17T12:11:57-04:00
testsuite: Use sigkill in process009.
SIGHUB might have been blocked by a (grand)*parent of the test.
In such cases the test would fail as the python process would simply
exist gracefully instead of committing to a premature end.
By using SIGKILL we can rely on the signal not being blocked, fixing #27578
in the process.
- - - - -
574c875f by Andreas Klebinger at 2026-08-17T12:12:39-04:00
Simplify comparison in DFM.hs
Fixes #27669
- - - - -
d8f1a2a3 by Alan Zimmerman at 2026-08-17T12:13:18-04:00
TTG: Add extension points to BooleanFormula
They are currently unused, but will be used for exact print
annotations next, allowing us to get rid of LocatedBF / SrcSpanAnnBF
- - - - -
93a2b20f by Andreas Klebinger at 2026-08-18T04:31:04-04:00
Fix a number of incorrect module references:
Fix module reference in Note [DataCon wrappers are conlike].
Fix module reference in Note [Detailed InertCans Invariants].
Fix module reference in Note [GHC's data format representations].
Fix module reference in Note [Grand plan for static forms].
Fix module reference in Note [How tuples work].
Fix module reference in Note [Solved dictionaries].
Fix module reference in Note [Stacktraces from Info Table Provenance Entries (IPE based stack unwinding)].
Fix module reference in Note [The VarBndr type and its uses].
Found the incorrect references with a llm.
- - - - -
eb0dfb01 by Simon Jakobi at 2026-08-18T04:31:44-04:00
ci: Run stack-hadrian-build only in full-ci pipelines
The job exists to catch changes that break hadrian/build-stack (#18726),
but nothing in the pipeline depends on it, and it can only break when
hadrian's dependencies change. Restricting it to full-ci (like
hadrian-multi) still covers marge-bot merge batches, so such breakage
cannot reach master unnoticed, while ordinary validate pipelines skip
the job.
Assisted-by: Claude Fable 5
- - - - -
b9160962 by Simon Jakobi at 2026-08-20T14:57:52-04:00
testsuite: Show baseline sample count and range in perf failures
A perf baseline is the mean of all samples recorded for a commit, and
it prints as a single number, hiding how far the samples spread. When
the spread is wide, this can indicate an unstable metric that isn't
actually useful as a signal for the perf tests.
For example, in #27602, T27336's peak_megabytes_allocated baseline
showed as 757 when the underlying samples were 605 and 909.
When the baseline is averaged from more than one sample, say so in the
failure output: the one-line stat-failure reason shows the sample
range, and the detail block lists the raw samples. Single-sample
baselines print exactly as before.
Context: #27602
Assisted-by: Claude Fable 5
- - - - -
a4979877 by Simon Jakobi at 2026-08-20T14:57:52-04:00
testsuite: Fold Baseline into CommitMetric
A Baseline was just a CommitMetric plus the commit it came from, built
by copying fields across. Since get_commit_metric already knows that
commit, record it on CommitMetric itself and drop Baseline. This also
collapses both branches of find_baseline into plain returns.
Assisted-by: Claude Fable 5
- - - - -
99fb8d68 by Simon Jakobi at 2026-08-20T14:57:52-04:00
ci: Clarify comment on pushing perf notes after failures
Context: #27602
Assisted-by: Claude Fable 5
- - - - -
2ca87972 by Alan Zimmerman at 2026-08-20T14:58:36-04:00
EPA: Remove LocatedBC / SrcSpanBF
The custom annotations are now in the BooleanFormula TTG extension
points, so LBooleanFormula can now use the standard LocatedA.
- - - - -
d2bc32aa by Simon Peyton Jones at 2026-08-21T12:59:26-04:00
Better handling of serialisation of wired-in names
Fixes #27501
- - - - -
d2795ffc by Alan Zimmerman at 2026-08-21T13:00:05-04:00
EPA: Remove NoEpTok/NoEpUniTok, using an unhelpful SrcSpan instead
Also introduce helper functions noEpTok and noEpUniTok to serve
as simple replacements in code inserting an token annotation without
location information.
- - - - -
b5d29ab8 by Brandon Chinn at 2026-08-25T18:42:08-04:00
Add Data.RealFloat and Infinity/NegInfinity/NaN pattern synonyms (#26961)
- - - - -
e60eb3bc by Andreas Klebinger at 2026-08-25T18:42:59-04:00
rts linker: Fix pointer arithmetic issue in flushInstructionCacheRISCV64
We accidentally operated over `uint64_t*` when we should use `uint8_t`.
Fixes #27569
- - - - -
e9bbe8f9 by Andreas Klebinger at 2026-08-26T15:09:23-04:00
cmm dumps: Add machop width info with -dppr-debug for infix ops.
- - - - -
86e3a9d8 by Andreas Klebinger at 2026-08-26T15:09:24-04:00
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.
- - - - -
13781cca by Andreas Klebinger at 2026-08-26T15:09:24-04:00
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.
- - - - -
d8fa5d7c by Andreas Klebinger at 2026-08-26T15:09:24-04:00
arm64 ncg: Fix MO_V_Broadcast for non-literals.
We now use OpReg instead of OpScalarAsVec as required since we broadcast a gp register.
Also adds a test. Fixes #27565.
- - - - -
94822c95 by Andreas Klebinger at 2026-08-26T15:09:24-04:00
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
- - - - -
dd1ba88a by Andreas Klebinger at 2026-08-26T15:09:24-04:00
cmmLint: Lint against MO_FS_Truncate subword use.
- - - - -
fd22f71e by Zubin Duggal at 2026-08-26T15:10:20-04:00
ghc-internal: annotateSTM should use catchSTM# rather than catch#
A catch# frame inside a transaction breaks retry and async exception
delivery.
Fixes #27657
- - - - -
bb324171 by Rodrigo Mesquita at 2026-08-26T15:10:59-04:00
rts: refactor to reduce THREADED_RTS in MSG_UPD_TSO_FLAGS
- No behavior change in this commit (well, a small optimization here
makes us do less work if the target TSO owned by the curr. capability)
- Move all THREADED_RTS CPP needed into `updThreadFlag`
- Merge MSG_SET_TSO_FLAGS and MSG_UNSET_TSO_FLAGS into MSG_UPD_TSO_FLAGS
plus a `set` bool field in the MessageUpdTSOFlag struct
Towards #27729
- - - - -
ed99b7b7 by Rodrigo Mesquita at 2026-08-26T15:10:59-04:00
rts: Fix race condition in MSG_UPD_TSO_FLAGS execution
The code for processing the MSG_UPD_TSO_FLAGS message was not taking
into consideration that the TSO's owner might have moved in between that
capability receiving the message (since it was its previous owner) and
starting to process its inbox (a point at which it was no longer the
owner)
Added Note [TSO owner may change in between Msg being sent and received]
to explain this race and the pattern used to fix this, where we just
forward the message to the new owner.
Fixes #27729
- - - - -
cd653714 by Alan Zimmerman at 2026-08-26T15:11:49-04:00
EPA: Uses Parsers.parseModule for exactprint tests
Parsers.parseModule is the advertised way to parse for use for exact
printing in the ghc-exactprint library. This commit updates the GHC
exact print testing to use it.
This requires moving the comment balancing that was occurring
only in the test path into the advertising parser path, so it moves
from Transforms.hs to Utils.hs.
Also update the comment adding to honour trailing annotations
- - - - -
d1d01fa5 by Wolfgang Jeltsch at 2026-08-27T13:17:59+03:00
Add `rethrowSTM` and improve STM-related documentation
Adding `rethrowSTM` resolves #26758.
The implementation of `rethrowSTM` is completely analogous to the one of
`rethrowIO`.
The following is established for the documentation of `throwSTM` and
`catchSTM`:
* Both operations are directly described as analogs of their `IO`
counterparts.
* There is no reference to `throw` in the documentation of `throwSTM`,
because, although such a reference is great in the documentation of
`throwIO`, it is somewhat out of place in the documentation of
`throwSTM`.
* Instead of repeating part of `throwIO`’s documentation, the
documentation of `throwSTM` just recommends using `throwSTM` instead
of `throw` and references the corresponding arguments in the
documentation of `throwIO`.
- - - - -
06fde293 by fendor at 2026-08-28T06:06:44-04:00
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
- - - - -
024c4d04 by fendor at 2026-08-28T06:07:23-04:00
Reuse the UnitIndexCache after initialising multiple home units
- - - - -
55326fa0 by Alan Zimmerman at 2026-08-28T06:08:03-04:00
EPA: Some Haddock processing tweaks
These changes to the Haddock postprocessing should not change
behaviour, but just bring it more closely in line with the
original, changed at 44309cd377f
And add some haddock exactprint tests to show they work.
- - - - -
b3ddee95 by Andreas Klebinger at 2026-08-28T13:57:46-04:00
hadrian: Deprecate quickest flavour.
It was more of a trap for new users than actually beneficial so we
deprecate it and suggest quick+no_dynamic_libs to users instead.
- - - - -
a1d81390 by Andreas Klebinger at 2026-08-28T13:58:37-04:00
cmm: Always favour entry block during block deduplication.
We now always keep the first block in the CmmGraph. This way we avoid
the need to update the entry info table.
Failing to do so caused #27722.
Fixes #27722.
- - - - -
5bd65f00 by Andreas Klebinger at 2026-08-28T13:59:16-04:00
test: FamAppCachePerf - Only collect bytes allocated. Fixes 27747
- - - - -
ced53ce6 by mangoiv at 2026-08-29T07:15:24-04:00
nightlies: output yaml to file only
Previously we would just output the metadata to stdout
which risks that it's clobbered by incidental debugt output.
We now output to file only.
Fixes #27511
- - - - -
578bd185 by Andreas Klebinger at 2026-08-29T07:16:05-04:00
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.
- - - - -
7bf546fc by Simon Peyton Jones at 2026-08-31T23:48:53-04:00
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
- - - - -
5f474953 by Zubin Duggal at 2026-08-31T23:48:53-04:00
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
- - - - -
cd5c6bcc by Zubin Duggal at 2026-08-31T23:48:53-04:00
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
- - - - -
abfc224a by Zubin Duggal at 2026-08-31T23:48:53-04:00
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
- - - - -
1557fd1c by Zubin Duggal at 2026-08-31T23:48:53-04:00
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
- - - - -
4117e5ae by Wolfgang Jeltsch at 2026-08-31T23:49:35-04:00
Incorporate the `rethrowSTM` reexport into the `stm` submodule
- - - - -
4bfbf5c8 by ARATA Mizuki at 2026-09-01T18:55:08-04:00
testsuite: Fix out-of-bounds access in T3586
unsafeRead and unsafeWrite use 0-based index.
Looking at #3586, the expected output seems to be 2.8e8.
Addresses #27596
- - - - -
3f9db6d4 by ARATA Mizuki at 2026-09-01T18:55:08-04:00
testsuite: Fix out-of-bounds access in T21305
writeInt64Array# takes an index measured in units of Int64 elements.
Fixes #27596
- - - - -
44d7788f by Simon Peyton Jones at 2026-09-01T18:55:53-04:00
Fix buglet in INLINE-arity calculation for pattern synonyms
This fixes #27744.
The buglet was accidentally introduced by
commit 3a0f9a51c1dacc474c7fd128082edd8bf4081256
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Sat Aug 1 00:13:02 2026 +0100
Fix three bugs related to required type args and INLINE pragmas
I failed to find all the calls to `addInlinePragArity`!
- - - - -
df058f1d by Simon Jakobi at 2026-09-02T07:18:06-04:00
testsuite: Migrate perf tests off collect_compiler_stats('all')
The 'all' metric argument applies a single tolerance to bytes
allocated, max_bytes_used and peak_megabytes_allocated, although their
noise profiles are incompatible (#27653): allocations are nearly
deterministic, residency needs 10-20%, and peak is quantized to 1 MB.
Any single tolerance is too tight for one metric or too slack for
another. This migrates the remaining users of 'all' (and of the 'all'
default) to explicit per-metric collection, ahead of removing 'all'
from the driver.
peak_megabytes_allocated is dropped everywhere: its 1 MB granularity
makes tight relative windows meaningless (#27613), and it is sensitive
to GC timing. In #27489 it drifted by -5.3% while max_bytes_used moved
by less than 0.1%. Where a test guards a memory property,
max_bytes_used covers it at byte granularity.
Where the motivating ticket was about compile-time memory
(T11545, T15304, T26425), residency remains gated via max_bytes_used,
now with a residency-appropriate tolerance.
max_bytes_used is dropped where residency was only ever an accident of
'all':
* T15630, T15630a, T20261: the underlying tickets (#15630, #20261)
contain no memory data at all. One is a simplifier-ticks blowup and
the other is stated entirely in allocation numbers, so the 20%
window never had teeth.
* T21839c: #21839's measurements show residency essentially flat
(+0.16%) while allocations moved +7%, so allocations are the
discriminating metric. They are already gated at 1% via
collect_compiler_runtime. The ghc/max gate had previously broken CI
spuriously (9fd11585eb widened it from 1% to 10% for that reason).
Allocation tolerances are tightened to the testsuite's conventional 2%
where 'all' previously left them at 10-20%.
Assisted-by: Claude Fable 5
- - - - -
72dd2432 by Simon Jakobi at 2026-09-02T07:18:06-04:00
testsuite: Remove the 'all' metric argument of collect_stats
'all' gated bytes allocated, max_bytes_used and peak_megabytes_allocated
at a single tolerance, although their noise profiles are incompatible,
making such tests either flaky or toothless (#27653).
Closes #27653.
Assisted-by: Claude Fable 5
- - - - -
2228cb30 by Simon Jakobi at 2026-09-02T07:18:06-04:00
testsuite: Make the deviation argument of collect_stats mandatory
Almost every caller passes an explicit tolerance matched to the
metric's noise profile, and the silent 20% default is far slacker than
'bytes allocated' merits. Only two tests relied on it. They now state
their tolerance explicitly:
large-project gets 10%, in line with other large compile-time tests.
T9848 gets 2%: its metric is byte-for-byte deterministic across CI
jobs and platforms of a given test_env, has drifted only about 2.5%
since 2015, and the fusion failure it guards against would show up as
a roughly +30000% jump.
Assisted-by: Claude Fable 5
- - - - -
56291fc5 by Cheng Shao at 2026-09-02T07:18:45-04:00
autoconf/ghc-toolchain: bump llvm upper bound to support llvm 23
This commit bumps llvm upper bound to support llvm 23.
- - - - -
20eb3f41 by Cheng Shao at 2026-09-02T07:18:45-04:00
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.
- - - - -
421ef3f6 by Simon Peyton Jones at 2026-09-03T10:09:12+01:00
Move HsStatic free-var test to typechecker
A `static` form should have no free *term* variables, but it
can have free *type* variables. Alas, the renamer does not really know what
is a term variable and what is a type variable, because of required type
arguments. This patch moves the test to the typechecker, which does know.
Addresses #27664
- - - - -
255 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- + changelog.d/27627
- + changelog.d/27703
- + changelog.d/27704
- + changelog.d/27717
- changelog.d/T27202
- + changelog.d/T27657
- + changelog.d/T27705
- + changelog.d/T27722-cbe-entry-block.md
- + changelog.d/T27744
- + changelog.d/T27764
- + changelog.d/arm_ncg_fixes_T27430
- + changelog.d/llvm-23
- + changelog.d/rethrow-stm
- changelog.d/unit-index
- compiler/GHC/Builtin.hs
- compiler/GHC/Builtin/WiredIn/Types.hs
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/Cmm/Expr.hs
- compiler/GHC/Cmm/Lint.hs
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/AArch64/Instr.hs
- compiler/GHC/CmmToAsm/AArch64/Ppr.hs
- compiler/GHC/CmmToAsm/Format.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Class.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Data/BooleanFormula.hs
- compiler/GHC/Data/Word64Map/Internal.hs
- compiler/GHC/Data/Word64Map/Lazy.hs
- compiler/GHC/Data/Word64Map/Strict.hs
- compiler/GHC/Data/Word64Map/Strict/Internal.hs
- compiler/GHC/Driver/GenerateCgIPEStub.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Hs.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/Iface/Binary.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/TyCl/Class.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Types/Demand.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Literal.hs
- compiler/GHC/Types/Unique/DFM.hs
- compiler/GHC/Types/Var.hs
- compiler/Language/Haskell/Syntax/BooleanFormula.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- configure.ac
- ghc/GHCi/UI.hs
- hadrian/README.md
- hadrian/doc/cross-compile.md
- hadrian/doc/flavours.md
- hadrian/doc/make.md
- hadrian/doc/windows.md
- hadrian/hadrian.cabal
- hadrian/src/CommandLine.hs
- hadrian/src/Flavour.hs
- hadrian/src/Settings.hs
- − hadrian/src/Settings/Flavours/Quickest.hs
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- + libraries/base/src/Data/RealFloat.hs
- libraries/base/src/GHC/Conc.hs
- libraries/base/tests/all.T
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- libraries/stm
- rts/CloneStack.c
- rts/Interpreter.c
- rts/Messages.c
- rts/ProfHeap.c
- rts/StgMiscClosures.cmm
- rts/Threads.c
- rts/Threads.h
- rts/eventlog/EventLog.c
- rts/include/rts/storage/Closures.h
- rts/include/stg/MiscClosures.h
- rts/linker/elf_reloc_riscv64.c
- rts/prim/atomic.c
- testsuite/driver/README.md
- testsuite/driver/perf_notes.py
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/cmm/should_compile/Makefile
- + testsuite/tests/cmm/should_compile/T27368-ppr-debug.stderr
- − testsuite/tests/cmm/should_compile/T27368-ppr-debug.stdout
- testsuite/tests/cmm/should_compile/all.T
- + testsuite/tests/codeGen/should_run/T27430.hs
- + testsuite/tests/codeGen/should_run/T27430.stdout
- + testsuite/tests/codeGen/should_run/T27430_c.c
- + testsuite/tests/codeGen/should_run/T27533.hs
- + testsuite/tests/codeGen/should_run/T27533.stdout
- + testsuite/tests/codeGen/should_run/T27533_cmm.cmm
- + testsuite/tests/codeGen/should_run/T27537.hs
- + testsuite/tests/codeGen/should_run/T27537.stdout
- + testsuite/tests/codeGen/should_run/T27538.hs
- + testsuite/tests/codeGen/should_run/T27538.stdout
- testsuite/tests/codeGen/should_run/all.T
- + testsuite/tests/concurrent/should_run/T27657a.hs
- + testsuite/tests/concurrent/should_run/T27657a.stdout
- + testsuite/tests/concurrent/should_run/T27657b.hs
- + testsuite/tests/concurrent/should_run/T27657b.stdout
- testsuite/tests/concurrent/should_run/all.T
- + testsuite/tests/core-to-stg/T27627/Callee.hs
- + testsuite/tests/core-to-stg/T27627/Caller.hs
- + testsuite/tests/core-to-stg/T27627/Main.hs
- + testsuite/tests/core-to-stg/T27627/T27627.stdout
- + testsuite/tests/core-to-stg/T27627/all.T
- + testsuite/tests/core-to-stg/T27627a/Callee.hs
- + testsuite/tests/core-to-stg/T27627a/Caller.hs
- + testsuite/tests/core-to-stg/T27627a/Main.hs
- + testsuite/tests/core-to-stg/T27627a/T27627a.stdout
- + testsuite/tests/core-to-stg/T27627a/all.T
- + testsuite/tests/core-to-stg/T27627b/Callee.hs
- + testsuite/tests/core-to-stg/T27627b/Caller.hs
- + testsuite/tests/core-to-stg/T27627b/Main.hs
- + testsuite/tests/core-to-stg/T27627b/T27627b.stdout
- + testsuite/tests/core-to-stg/T27627b/all.T
- + testsuite/tests/core-to-stg/T27627c/Callee.hs
- + testsuite/tests/core-to-stg/T27627c/Caller.hs
- + testsuite/tests/core-to-stg/T27627c/Main.hs
- + testsuite/tests/core-to-stg/T27627c/T27627c.stdout
- + testsuite/tests/core-to-stg/T27627c/all.T
- + testsuite/tests/core-to-stg/T27627e.hs
- + testsuite/tests/core-to-stg/T27627e.stdout
- + testsuite/tests/core-to-stg/T27627f/Callee.hs
- + testsuite/tests/core-to-stg/T27627f/Caller.hs
- + testsuite/tests/core-to-stg/T27627f/Inst.hs
- + testsuite/tests/core-to-stg/T27627f/Main.hs
- + testsuite/tests/core-to-stg/T27627f/T27627f.stdout
- + testsuite/tests/core-to-stg/T27627f/all.T
- + testsuite/tests/core-to-stg/T27704/Callee.hs
- + testsuite/tests/core-to-stg/T27704/Callee.hs-boot
- + testsuite/tests/core-to-stg/T27704/Main.hs
- + testsuite/tests/core-to-stg/T27704/Mid.hs
- + testsuite/tests/core-to-stg/T27704/T27704.stdout
- + testsuite/tests/core-to-stg/T27704/all.T
- + testsuite/tests/core-to-stg/T27704a/Callee.hs
- + testsuite/tests/core-to-stg/T27704a/Callee.hs-boot
- + testsuite/tests/core-to-stg/T27704a/Main.hs
- + testsuite/tests/core-to-stg/T27704a/Mid.hs
- + testsuite/tests/core-to-stg/T27704a/T27704a.stdout
- + testsuite/tests/core-to-stg/T27704a/all.T
- + testsuite/tests/core-to-stg/T27717/Callee.hs
- + testsuite/tests/core-to-stg/T27717/Callee.hs-boot
- + testsuite/tests/core-to-stg/T27717/Main.hs
- + testsuite/tests/core-to-stg/T27717/Mid.hs
- + testsuite/tests/core-to-stg/T27717/T27717.stdout
- + testsuite/tests/core-to-stg/T27717/Ty.hs
- + testsuite/tests/core-to-stg/T27717/all.T
- testsuite/tests/core-to-stg/all.T
- testsuite/tests/ffi/should_run/T21305.hs
- testsuite/tests/ghc-api/exactprint/T22919.stderr
- testsuite/tests/ghc-api/exactprint/Test20239.stderr
- testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr
- + testsuite/tests/ghci/prog-mhu007/Makefile
- + testsuite/tests/ghci/prog-mhu007/a/A.hs
- + testsuite/tests/ghci/prog-mhu007/all.T
- + testsuite/tests/ghci/prog-mhu007/b/B.hs
- + testsuite/tests/ghci/prog-mhu007/prog-mhu007.script
- + testsuite/tests/ghci/prog-mhu007/prog-mhu007.stdout
- + testsuite/tests/ghci/prog-mhu007/testpkg-bar/Bar.hs
- + testsuite/tests/ghci/prog-mhu007/testpkg-bar/testpkg-bar.pkg
- + testsuite/tests/ghci/prog-mhu007/testpkg-foo/Foo.hs
- + testsuite/tests/ghci/prog-mhu007/testpkg-foo/testpkg-foo.pkg
- + testsuite/tests/ghci/prog-mhu007/unitA
- + testsuite/tests/ghci/prog-mhu007/unitB
- 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/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/module/mod185.stderr
- 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/DumpTypecheckedAst.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_compile/T27744.hs
- testsuite/tests/patsyn/should_compile/all.T
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/perf/compiler/large-project/all.T
- testsuite/tests/perf/should_run/T3586.hs
- testsuite/tests/perf/should_run/T3586.stdout
- testsuite/tests/perf/space_leaks/all.T
- testsuite/tests/printer/AnnotationNoListTuplePuns.stdout
- + testsuite/tests/printer/Haddock1.hs
- testsuite/tests/printer/Makefile
- testsuite/tests/printer/T18791.stderr
- testsuite/tests/printer/Test20297.stdout
- testsuite/tests/printer/Test24533.stdout
- testsuite/tests/printer/all.T
- testsuite/tests/process/process009.hs
- testsuite/tests/process/process009.stdout
- testsuite/tests/rename/should_fail/RnStaticPointersFail01.stderr
- testsuite/tests/rename/should_fail/RnStaticPointersFail03.stderr
- testsuite/tests/rename/should_fail/T26545.stderr
- + testsuite/tests/simd/should_run/T27565.hs
- + testsuite/tests/simd/should_run/T27565.stdout
- testsuite/tests/simd/should_run/all.T
- testsuite/tests/simplCore/should_compile/T17966.stderr
- testsuite/tests/simplCore/should_compile/T7785.stderr
- testsuite/tests/simplCore/should_compile/spec004.hs
- testsuite/tests/simplCore/should_compile/spec004.stderr
- + testsuite/tests/simplCore/should_run/T27703/Lib.hs
- + testsuite/tests/simplCore/should_run/T27703/Main.hs
- + testsuite/tests/simplCore/should_run/T27703/T27703.stdout
- + testsuite/tests/simplCore/should_run/T27703/all.T
- + testsuite/tests/simplCore/should_run/T27705.hs
- + testsuite/tests/simplCore/should_run/T27705.stdout
- + testsuite/tests/simplCore/should_run/T27705_Inst.hs
- testsuite/tests/simplCore/should_run/all.T
- + testsuite/tests/typecheck/should_compile/T27664.hs
- testsuite/tests/typecheck/should_compile/all.T
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Main.hs
- utils/check-exact/Parsers.hs
- utils/check-exact/Transform.hs
- utils/check-exact/Utils.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Program.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Target.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.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/16157a5dbd87a605534ddb19bcbb63…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/16157a5dbd87a605534ddb19bcbb63…
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/T27731] Simplify the error-suppression mechanism in GHC.Tc.Errors
by Simon Peyton Jones (@simonpj) 03 Sep '26
by Simon Peyton Jones (@simonpj) 03 Sep '26
03 Sep '26
Simon Peyton Jones pushed to branch wip/T27731 at Glasgow Haskell Compiler / GHC
Commits:
2aaebe8b by Simon Peyton Jones at 2026-09-03T10:00:13+01: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.
- - - - -
7 changed files:
- + changelog.d/T27731
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Types/Constraint.hs
- + testsuite/tests/typecheck/should_fail/T18851d.hs
- + testsuite/tests/typecheck/should_fail/T27731.hs
- + testsuite/tests/typecheck/should_fail/T27731.stderr
- testsuite/tests/typecheck/should_fail/all.T
Changes:
=====================================
changelog.d/T27731
=====================================
@@ -0,0 +1,11 @@
+section: compiler
+synopsis: Fix a compiler crash after typechecking
+issues: #27731
+mrs: !16564
+description: {
+ The type checker was failing to report an error, even though it had found one,
+ due to over-zealous error suppression. That led to subsequent chaos. This
+ MR fixes it *and* simplifies the code.
+
+ Claude found a second, closely-related bug, now immortalised as test ``T18851d``.
+}
=====================================
compiler/GHC/Tc/Errors.hs
=====================================
@@ -263,11 +263,11 @@ report_unsolved type_errors expr_holes
, cec_type_holes = type_holes
, cec_out_of_scope_holes = out_of_scope_holes
, cec_suppress = insolubleWC wanted
- -- See Note [Suppressing error messages]
- -- Suppress low-priority errors if there
- -- are insoluble errors anywhere;
- -- See #15539 and c.f. setting ic_status
- -- in GHC.Tc.Solver.setImplicationStatus
+ -- See (SLIE1) in
+ -- Note [cec_suppress: suppressing less-important error messages]
+ -- Suppress low-priority errors if there are insoluble errors
+ -- anywhere in the treee. See #15539 and c.f. setting ic_status
+ -- in GHC.Tc.Solver.setImplicationStatus
, cec_warn_redundant = warn_redundant
, cec_expand_syns = exp_syns
, cec_binds = binds_var }
@@ -322,30 +322,123 @@ we just switch off deferred type errors altogether. See #14605.
This is done by maybeSwitchOffDefer. It's also useful in one other
place: see Note [Wrapping failing kind equalities] in GHC.Tc.Solver.
-Note [Suppressing error messages]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The cec_suppress flag says "don't report any errors". Instead, just create
-evidence bindings (as usual). It's used when more important errors have occurred.
-
-Specifically (see reportWanteds)
- * If there are insoluble Givens, then we are in unreachable code and all bets
- are off. So don't report any further errors.
- * If there are any insolubles (eg Int~Bool), here or in a nested implication,
- then suppress errors from the simple constraints here. Sometimes the
- simple-constraint errors are a knock-on effect of the insolubles.
-
-This suppression behaviour is controlled by the Bool flag in
-ReportErrorSpec, as used in reportWanteds.
-
-But we need to take care: flags can turn errors into warnings, and we
-don't want those warnings to suppress subsequent errors (including
-suppressing the essential addTcEvBind for them: #15152). So in
-tryReporter we use askNoErrs to see if any error messages were
-/actually/ produced; if not, we don't switch on suppression.
-
-A consequence is that warnings never suppress warnings, so turning an
-error into a warning may allow subsequent warnings to appear that were
-previously suppressed. (e.g. partial-sigs/should_fail/T14584)
+Note [cec_suppress: suppressing less-important error messages]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The cec_suppress flag says "don't report any less-important errors". Instead, just create
+evidence bindings (as usual). It's used when more important errors have occurred
+(or will occur) eleswhere.
+
+(SLIE0)
+ * Note that `cec_suppress` does not affect more-important errors, namely the `report1`
+ group in `reportWanteds`
+ * But `cec_suppress` /does/ affect the less-important errors, namely the `report2` group.
+ To see this, look at the plumbing of cec suppress in `reportWanteds`
+
+(SLIE1) When we begin `reportAllUnsolved` we set `cec_suppress` if there are insoluble
+ wanteds /anywhere/ in the tree, via `insolubleWC`. That means we'll suppress all
+ less-important errors in favour of the more important (insolbule) ones
+
+(SLIE2) But we need to take care: flags can turn errors into warnings, and we
+ don't want those warnings to suppress subsequent errors (including
+ suppressing the essential addTcEvBind for them: #15152). So in
+ tryReporter we use askNoErrs to see if any error messages were
+ /actually/ produced; if not, we don't switch on suppression.
+
+ A consequence is that warnings never suppress warnings, so turning an
+ error into a warning may allow subsequent warnings to appear that were
+ previously suppressed. (e.g. partial-sigs/should_fail/T14584)
+
+(SLIE3) There is a tricky interaction between
+ * `cec_suppress` (a global flag) and
+ * `ei_suppress` (a local, per-error-item flag),
+ see Note [ei_suppresss: suppressing confusing errors]
+ Suppose cec_suppress is True because of an insoluble constraint arising from a
+ superclass constraint -- this constraint will have ei_suppress=True.
+
+
+
+Note [ei_suppresss: suppressing confusing errors]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Certain errors we might encounter are potentially confusing to users.
+If there are any other errors to report, at all, we want to suppress these.
+We achieve this by setting the `ei_suppress` flag in the `ErrorItem`.
+
+Which errors should be suppressed?
+
+(SCE1) Non-empty rewriter sets. See Note [Wanteds rewrite Wanteds: rewriter-sets]
+ in GHC.Tc.Types.Constraint
+
+(SCE2) Superclasses of Wanteds. These are generated only in case they trigger functional
+ dependencies. If such a constraint is unsolved, then its "parent" constraint must
+ also be unsolved, and is much more informative to the user. Example (#26255):
+ class (MinVersion <= F era) => Era era where { ... }
+ f :: forall era. EraFamily era -> IO ()
+ f = ..blah... -- [W] Era era
+ Here we have simply omitted "Era era =>" from f's type. But we'll end up with
+ /two/ Wanted constraints:
+ [W] d1 : Era era
+ [W] d2 : MinVersion <= F era -- Superclass of d1
+ We definitely want to report d1 and not d2! Happily it's easy to filter out those
+ superclass-Wanteds, becuase their Origin betrays them.
+
+There are wrinkles
+
+(SCE3) In rare cases we may suppress /all/ errors. That is catastrophic: GHC proceeds
+ to desugar and optimise the program, even though it is full of type errors (#22702,
+ #22793), and/or we fail to bind evidence (#27731).
+
+ If this happens, unless we are sure that an error will be reported some other way
+ (details in the defn of `tidy_items` in `reportWanteds), we just un-suppress the lot,
+ which is brutal but safe. It's a rare case.
+
+ How can it happen that there are /all/ errors are suppressed?
+ * See test T18851 for an example of how it is (just, barely) possible for the
+ /only/ errors to be superclass-of-Wanted constraints.
+ * Similarly #27731, which also involves a superclass-of-Wanted:
+ class (a ~ F b) => Ren a b
+ If we have a [W] Ren a b, we'll emit the superclass [W] a ~ F b, which will
+ rewrite the original class constraint to [W] Ren (F b) b. Now we have two
+ constraints: one has a non-empty rewriter set (SEC1) and one is a superclass of
+ a Wanted (SEC2).
+ * Also see Wrinkle (PER2) in Note [Prioritise Wanteds with empty
+ CoHoleSet] in GHC.Tc.Types.Constraint.
+
+Historical note. We used to suppress errors arising from the interaction of two
+ fundep constraints. But nowadays fundep constraints never "escape" into the main
+ solver and so never show up in error messages. See (SOLVE-FD) in Note [Overview
+ of functional dependencies in type inference] in GHC.Tc.Solver.FunDeps. So this
+ wrinkle is now just a historical note.
+
+ Errors which arise from the interaction of two Wanted fun-dep constraints.
+ Example:
+
+ class C a b | a -> b where
+ op :: a -> b -> b
+
+ foo _ = op True Nothing
+
+ bar _ = op False []
+
+ Here, we could infer
+ foo :: C Bool (Maybe a) => p -> Maybe a
+ bar :: C Bool [a] => p -> [a]
+
+ (The unused arguments suppress the monomorphism restriction.) The problem
+ is that these types can't both be correct, as they violate the functional
+ dependency. Yet reporting an error here is awkward: we must
+ non-deterministically choose either foo or bar to reject. We thus want
+ to report this problem only when there is nothing else to report.
+ See typecheck/should_fail/T13506 for an example of when to suppress
+ the error. The case above is actually accepted, because foo and bar
+ are checked separately, and thus the two fundep constraints never
+ encounter each other. It is test case typecheck/should_compile/FunDepOrigin1.
+
+ This case applies only when both fundeps are *Wanted* fundeps; when
+ both are givens, the error represents unreachable code. For
+ a Given/Wanted case, see #9612.
+
+ End of historical note
+
-}
reportImplic :: SolverReportErrCtxt -> Implication -> TcM ()
@@ -452,16 +545,6 @@ reportBadTelescope ctxt env (ForAllSkol telescope) skols
reportBadTelescope _ _ skol_info skols
= pprPanic "reportBadTelescope" (ppr skol_info $$ ppr skols)
--- | Should we completely ignore this constraint in error reporting?
--- It *must* be the case that any constraint for which this returns True
--- somehow causes an error to be reported elsewhere.
--- See Note [Constraints to ignore].
-ignoreConstraint :: Ct -> Bool
-ignoreConstraint ct
- = case ctOrigin ct of
- AssocFamPatOrigin -> True -- See (CIG1)
- _ -> False
-
-- | Makes an error item from a constraint, calculating whether or not the item
-- should be suppressed. See Note [Wanteds rewrite Wanteds: rewriter-sets]
-- in GHC.Tc.Types.Constraint. Returns Nothing if we should just ignore
@@ -473,56 +556,105 @@ mkErrorItem ct
; return Nothing } -- See Note [Constraints to ignore]
| otherwise
- = do { let loc = ctLoc ct
- flav = ctFlavour ct
+ = do { let ev = ctEvidence ct
+
+ m_evdest = case ev of
+ CtGiven {} -> Nothing
+ CtWanted (WantedCt { ctev_dest = dest }) -> Just dest
- -- For this `suppress` stuff see
- -- Note [Wanteds rewrite Wanteds: rewriter-sets] in GHC.Tc.Types.Constraint
- (suppress, m_evdest) = case ctEvidence ct of
- CtGiven {} -> (False, Nothing)
- CtWanted (WantedCt { ctev_rewriters = rws, ctev_dest = dest })
- -> (not (isEmptyCoHoleSet rws), Just dest)
- ; let m_reason = case ct of
+ m_reason = case ct of
CIrredCan (IrredCt { ir_reason = reason }) -> Just reason
_ -> Nothing
- insoluble_ct = insolubleCt ct
-
; return $ Just $ EI { ei_pred = ctPred ct
, ei_evdest = m_evdest
- , ei_flavour = flav
- , ei_loc = loc
+ , ei_flavour = ctFlavour ct
+ , ei_loc = ctLoc ct
, ei_m_reason = m_reason
- , ei_insoluble = insoluble_ct
- , ei_suppress = suppress }}
+ , ei_insoluble = insolubleCt ct
+ , ei_suppress = suppressCtError ev }}
-- | Actually report this 'ErrorItem'.
unsuppressErrorItem :: ErrorItem -> ErrorItem
unsuppressErrorItem ei = ei { ei_suppress = False }
+-- | Should we completely ignore this constraint in error reporting?
+-- It *must* be the case that any constraint for which this returns True
+-- somehow causes an error to be reported elsewhere.
+-- See Note [Constraints to ignore].
+ignoreConstraint :: Ct -> Bool
+ignoreConstraint ct
+ = case ctOrigin ct of
+ AssocFamPatOrigin -> True -- See (CIG1)
+ _ -> False
+
+suppressCtError :: CtEvidence -> Bool
+-- See Note [ei_suppress: suppressing confusing errors]
+suppressCtError (CtGiven {})
+ = False
+suppressCtError (CtWanted (WantedCt { ctev_rewriters = rws, ctev_loc = loc }))
+ | not (isEmptyCoHoleSet rws)
+ = True -- See (SCE1)
+
+ | isWantedSuperclassOrigin (ctLocOrigin loc)
+ = True -- See (SCE2)
+
+ | otherwise
+ = False
+
+{- Note [Constraints to ignore]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Some constraints are meant only to aid the solver by unification; a failure
+to solve them is not necessarily an error to report to the user. It is critical
+that compilation is aborted elsewhere if there are any ignored constraints here;
+they will remain unfilled, and might have been used to rewrite another constraint.
+
+Currently, the constraints to ignore are:
+
+(CIG1) Constraints generated in order to unify associated type instance parameters
+ with class parameters. Here are two illustrative examples:
+
+ class C (a :: k) where
+ type F (b :: k)
+
+ instance C True where
+ type F a = Int
+
+ instance C Left where
+ type F (Left :: a -> Either a b) = Bool
+
+ In the first instance, we want to infer that `a` has type Bool. So we emit
+ a constraint unifying kappa (the guessed type of `a`) with Bool. All is well.
+
+ In the second instance, we process the associated type instance only
+ after fixing the quantified type variables of the class instance. We thus
+ have skolems a1 and b1 such that the class instance is for (Left :: a1 -> Either a1 b1).
+ Unifying a1 and b1 with a and b in the type instance will fail, but harmlessly so.
+ checkConsistentFamInst checks for this, and will fail if anything has gone
+ awry. Really the equality constraints emitted are just meant as an aid, not
+ a requirement. This is test case T13972.
+
+ We detect this case by looking for an origin of AssocFamPatOrigin; constraints
+ with this origin are dropped entirely during error message reporting.
+
+ If there is any trouble, checkValidFamInst bleats, aborting compilation.
+
+(Note: Aug 25: this seems a rather tricky corner;
+ c.f. Note [ei_suppress: suppressing confusing errors])
+-}
+
----------------------------------------------------------------
reportWanteds :: SolverReportErrCtxt -> TcLevel -> WantedConstraints -> TcM ()
reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics
, wc_errors = errs })
- | isEmptyWC wc = traceTc "reportWanteds empty WC" empty
+ | isEmptyWC wc
+ = traceTc "reportWanteds empty WC" empty
| otherwise
= do { tidy_items1 <- mapMaybeM mkErrorItem tidy_cts
- ; traceTc "reportWanteds 1" (vcat [ text "Simples =" <+> ppr simples
- , text "Suppress =" <+> ppr (cec_suppress ctxt)
- , text "tidy_cts =" <+> ppr tidy_cts
- , text "tidy_items1 =" <+> ppr tidy_items1
- , text "tidy_errs =" <+> ppr tidy_errs ])
-- Catch an awkward (and probably rare) case in which /all/ errors are
- -- suppressed: see Wrinkle (PER2) in Note [Prioritise Wanteds with empty
- -- CoHoleSet] in GHC.Tc.Types.Constraint.
- --
- -- Unless we are sure that an error will be reported some other way
- -- (details in the defn of tidy_items) un-suppress the lot. This makes
- -- sure we don't forget to report an error at all, which is
- -- catastrophic: GHC proceeds to desguar and optimise the program, even
- -- though it is full of type errors (#22702, #22793)
+ -- suppressed: see (SCE3) in Note [ie_suppress: suppressing confusing errors]
; errs_already <- ifErrsM (return True) (return False)
; let tidy_items
| not errs_already -- Have not already reported an error (perhaps
@@ -530,43 +662,54 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics
, not (any ignoreConstraint simples) -- No error is ignorable (is reported elsewhere)
, all ei_suppress tidy_items1 -- All errors are suppressed
= map unsuppressErrorItem tidy_items1
+
| otherwise
= tidy_items1
+ ; traceTc "reportWanteds 1" (vcat [ text "Simples =" <+> ppr simples
+ , text "Suppress =" <+> ppr (cec_suppress ctxt)
+ , text "tidy_cts =" <+> ppr tidy_cts
+ , text "tidy_items1 =" <+> ppr tidy_items1
+ , text "tidy_errs =" <+> ppr tidy_errs ])
+
-- First, deal with any out-of-scope errors:
; let (out_of_scope, other_holes, not_conc_errs, mult_co_errs) = partition_errors tidy_errs
- -- don't suppress out-of-scope errors
+ -- Don't suppress out-of-scope errors
+ -- See (SLIE0) in Note [cec_suppress: suppressing less-important error messages]
ctxt_for_scope_errs = ctxt { cec_suppress = False }
; (_, no_out_of_scope) <- askNoErrs $
reportHoles tidy_items ctxt_for_scope_errs out_of_scope
-- Next, deal with things that are utterly wrong
- -- Like Int ~ Bool (incl nullary TyCons)
- -- or Int ~ t a (AppTy on one side)
- -- These /ones/ are not suppressed by the incoming context
- -- (but will be by out-of-scope errors)
+ -- These should not be suppressed by the incoming context
+ -- (but should be suppressed by out-of-scope errors)
+ -- See (SLIE0) in Note [cec_suppress: suppressing less-important error messages]
; let ctxt_for_insols = ctxt { cec_suppress = not no_out_of_scope }
- ; reportHoles tidy_items ctxt_for_insols other_holes
- -- holes never suppress
+ -- Don't suppress holes or concreteness errors unless we have scope errors
+ ; reportHoles tidy_items ctxt_for_insols other_holes
; reportNotConcreteErrs ctxt_for_insols not_conc_errs
-- We only want to report multiplicity coercion errors for multiplicity
-- constraints which are /solved/ with a non-reflexivity coercion. We
-- over approximate here: we only report multiplicity coercion errors
- -- when /all/ constraints are solved.
+ -- when /all/ other constraints are solved.
-- See wrinkle (DME1) in Note [Coercion errors in tcSubMult] in GHC.Tc.Utils.Unify.
- ; when (null simples) $ reportMultiplicityCoercionErrs ctxt_for_insols mult_co_errs
+ ; when (null simples) $
+ reportMultiplicityCoercionErrs ctxt_for_insols mult_co_errs
- -- See Note [Suppressing confusing errors]
- ; let (suppressed_items, reportable_items) = partition suppressItem tidy_items
- ; traceTc "reportWanteds suppressed:" (ppr suppressed_items)
- ; (ctxt1, items1) <- tryReporters ctxt_for_insols report1 reportable_items
+ -- Now the main batch of utterly-wrong things
+ -- Like Int ~ Bool (incl nullary TyCons)
+ -- or Int ~ t a (AppTy on one side)
+ ; (ctxt1, items1) <- tryReporters ctxt_for_insols report1 tidy_items
-- Now all the other constraints. We suppress errors here if
- -- any of the first batch failed, or if the enclosing context
- -- says to suppress
- ; let ctxt2 = ctxt1 { cec_suppress = cec_suppress ctxt || cec_suppress ctxt1 }
+ -- any of the first batch failed (ctxt1), or if the enclosing context
+ -- says to suppress AND there are no local insolubles
+ -- Why the AND part? In case all those local insolubles are suppressed.
+ -- See (SLIE3) in Note [cec_suppress: suppressing less-important error messages]
+ ; let ctxt2 = ctxt1 { cec_suppress = cec_suppress ctxt1
+ || (cec_suppress ctxt && not (any ei_insoluble tidy_items)) }
; (_, leftovers) <- tryReporters ctxt2 report2 items1
; massertPpr (null leftovers)
(text "The following unsolved Wanted constraints \
@@ -577,21 +720,10 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics
-- NB ctxt2: don't suppress inner insolubles if there's only a
-- wanted insoluble here; but do suppress inner insolubles
-- if there's a *given* insoluble here (= inaccessible code)
-
- -- If there are no other errors to report, report suppressed errors.
- -- See (SCE3) in Note [Suppressing confusing errors].
- -- NB: with -fdefer-type-errors we might have reported warnings only from
- -- reportable_items`, but we still want to suppress the `suppressed_items`.
- ; when (null reportable_items) $
- do { (_, more_leftovers) <- tryReporters ctxt_for_insols (report1++report2)
- suppressed_items
- -- ctxt_for_insols: the suppressed errors can be Int~Bool, which
- -- will have made the incoming `ctxt` be True; don't make that
- -- suppress the Int~Bool error!
- ; massertPpr (null more_leftovers) (ppr more_leftovers) } }
+ }
where
env = cec_tidy ctxt
- tidy_cts = bagToList (mapBag (tidyCt env) simples)
+ tidy_cts = bagToList (mapBag (tidyCt env) simples)
tidy_errs = bagToList (mapBag (tidyDelayedError env) errs)
partition_errors :: [DelayedError] -> ([Hole], [Hole], [NotConcreteError], [(TcCoercion, CtLoc)])
@@ -610,8 +742,8 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics
DE_Multiplicity mult_co loc
-> (es1, es2, es3, (mult_co, loc):es4)
- -- report1: ones that should *not* be suppressed by
- -- an insoluble somewhere else in the tree
+ -- report1: ones that should *not* be suppressed by cec_suppress,
+ -- (i.e. by an insoluble somewhere else in the tree)
-- It's crucial that anything that is considered insoluble
-- (see GHC.Tc.Utils.insolublWantedCt) is caught here, otherwise
-- we might suppress its error message, and proceed on past
@@ -752,15 +884,6 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics
= has_gadt_match implics
---------------
-suppressItem :: ErrorItem -> Bool
- -- See Note [Suppressing confusing errors]
-suppressItem item
- | Wanted <- ei_flavour item
- , let orig = errorItemOrigin item
- = isWantedSuperclassOrigin orig -- See (SCE1)
- | otherwise
- = False
-
isSkolemTy :: TcLevel -> Type -> Bool
-- The type is a skolem tyvar
isSkolemTy tc_lvl ty
@@ -778,113 +901,8 @@ isTyFun_maybe ty = case tcSplitTyConApp_maybe ty of
Just (tc,_) | isTypeFamilyTyCon tc -> Just tc
_ -> Nothing
-{- Note [Suppressing confusing errors]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Certain errors we might encounter are potentially confusing to users.
-If there are any other errors to report, at all, we want to suppress these.
-
-Which errors should be suppressed?
-
-(SCE1) Superclasses of Wanteds. These are generated only in case they trigger functional
- dependencies. If such a constraint is unsolved, then its "parent" constraint must
- also be unsolved, and is much more informative to the user. Example (#26255):
- class (MinVersion <= F era) => Era era where { ... }
- f :: forall era. EraFamily era -> IO ()
- f = ..blah... -- [W] Era era
- Here we have simply omitted "Era era =>" from f's type. But we'll end up with
- /two/ Wanted constraints:
- [W] d1 : Era era
- [W] d2 : MinVersion <= F era -- Superclass of d1
- We definitely want to report d1 and not d2! Happily it's easy to filter out those
- superclass-Wanteds, becuase their Origin betrays them.
-
-Historical (SCE2). Fundep constraints never "escape" into the
- main solver and so never show up in error messages.
- See (SOLVE-FD) in Note [Overview of functional dependencies in type inference]
- in GHC.Tc.Solver.FunDeps. So this wrinkle is now just a historical note.
-
- Errors which arise from the interaction of two Wanted fun-dep constraints.
- Example:
-
- class C a b | a -> b where
- op :: a -> b -> b
-
- foo _ = op True Nothing
-
- bar _ = op False []
-
- Here, we could infer
- foo :: C Bool (Maybe a) => p -> Maybe a
- bar :: C Bool [a] => p -> [a]
-
- (The unused arguments suppress the monomorphism restriction.) The problem
- is that these types can't both be correct, as they violate the functional
- dependency. Yet reporting an error here is awkward: we must
- non-deterministically choose either foo or bar to reject. We thus want
- to report this problem only when there is nothing else to report.
- See typecheck/should_fail/T13506 for an example of when to suppress
- the error. The case above is actually accepted, because foo and bar
- are checked separately, and thus the two fundep constraints never
- encounter each other. It is test case typecheck/should_compile/FunDepOrigin1.
-
- This case applies only when both fundeps are *Wanted* fundeps; when
- both are givens, the error represents unreachable code. For
- a Given/Wanted case, see #9612.
-
- End of historical (SCE2)
-
-(SCE3) How can it happen that there are /only/ suppressed errors? See test T18851
- for an example of how it is (just, barely) possible for the /only/ errors to
- be superclass-of-Wanted constraints.
-
-Mechanism:
-
-We use the `suppress` function within reportWanteds to filter out these
-"suppress" cases, then report all other errors. After doing so, we return to these
-suppressed ones and report them only if there have been no errors so far.
-
-Note [Constraints to ignore]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Some constraints are meant only to aid the solver by unification; a failure
-to solve them is not necessarily an error to report to the user. It is critical
-that compilation is aborted elsewhere if there are any ignored constraints here;
-they will remain unfilled, and might have been used to rewrite another constraint.
-
-Currently, the constraints to ignore are:
-
-(CIG1) Constraints generated in order to unify associated type instance parameters
- with class parameters. Here are two illustrative examples:
-
- class C (a :: k) where
- type F (b :: k)
-
- instance C True where
- type F a = Int
-
- instance C Left where
- type F (Left :: a -> Either a b) = Bool
-
- In the first instance, we want to infer that `a` has type Bool. So we emit
- a constraint unifying kappa (the guessed type of `a`) with Bool. All is well.
-
- In the second instance, we process the associated type instance only
- after fixing the quantified type variables of the class instance. We thus
- have skolems a1 and b1 such that the class instance is for (Left :: a1 -> Either a1 b1).
- Unifying a1 and b1 with a and b in the type instance will fail, but harmlessly so.
- checkConsistentFamInst checks for this, and will fail if anything has gone
- awry. Really the equality constraints emitted are just meant as an aid, not
- a requirement. This is test case T13972.
-
- We detect this case by looking for an origin of AssocFamPatOrigin; constraints
- with this origin are dropped entirely during error message reporting.
-
- If there is any trouble, checkValidFamInst bleats, aborting compilation.
-
-(Note: Aug 25: this seems a rather tricky corner;
- c.f. Note [Suppressing confusing errors])
-
-Note [Implementation of Unsatisfiable constraints]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+{- Note [Implementation of Unsatisfiable constraints]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Unsatisfiable constraint was introduced in GHC proposal #433 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0433-u…)
See Note [The Unsatisfiable constraint] in GHC.TypeError.
@@ -1317,9 +1335,15 @@ maybeReportError :: SolverReportErrCtxt
maybeReportError ctxt items@(item1:|_) (SolverReport { sr_important_msg = important
, sr_supplementary = supp
, sr_hints = hints })
- | suppress_group = return ()
- | otherwise = do { msg <- mkErrorReport loc_env diag (Just ctxt) supp hints
- ; reportDiagnostic msg }
+ | suppress_group
+ = -- Suppress the report entirely
+ -- But NB we still create the evidence binding; see `reportGroup`.
+ return ()
+
+ | otherwise
+ = -- Spit out an error or warning
+ do { msg <- mkErrorReport loc_env diag (Just ctxt) supp hints
+ ; reportDiagnostic msg }
where
reason | any (nonDeferrableOrigin . errorItemOrigin) items = ErrorWithoutFlag
| otherwise = cec_defer_type_errors ctxt
@@ -1328,11 +1352,6 @@ maybeReportError ctxt items@(item1:|_) (SolverReport { sr_important_msg = import
loc_env = ctLocEnv (errorItemCtLoc item1)
suppress_group
- | all ei_suppress items
- = True -- If they are all suppressed (notably, have been rewritten by another unsolved wanted)
- -- report nothing. (If at least one is not suppressed, do report: the function that
- -- generates the error message should look for an unsuppressed error item.)
-
-- It is tempting to say that we always want to see all insoluble errors
-- But then we get a bit more than we want. Examples:
-- a ~ t a occurs check errors (T2534, mc25)
@@ -1344,6 +1363,12 @@ maybeReportError ctxt items@(item1:|_) (SolverReport { sr_important_msg = import
| cec_suppress ctxt
= True -- Some earlier error has occurred, so suppress this diagnostic
+ | all ei_suppress items
+ = True -- If they are all suppressed (notably, have been rewritten by another unsolved
+ -- wanted) report nothing. (If at least one is not suppressed, do report:
+ -- the function that generates the error message should look for an
+ -- unsuppressed error item.)
+
| otherwise
= False
@@ -1402,11 +1427,11 @@ mkErrorTerm ct_loc ty ctxt msg supp hints
; return $ evDelayedError ty err_str }
-tryReporters :: SolverReportErrCtxt -> [ReporterSpec] -> [ErrorItem] -> TcM (SolverReportErrCtxt, [ErrorItem])
+tryReporters :: SolverReportErrCtxt -> [ReporterSpec] -> [ErrorItem]
+ -> TcM (SolverReportErrCtxt, [ErrorItem])
-- Use the first reporter in the list whose predicate says True
tryReporters ctxt reporters items
- = do { let (vis_items, invis_items)
- = partition (isVisibleOrigin . errorItemOrigin) items
+ = do { let (vis_items, invis_items) = partition (isVisibleOrigin . errorItemOrigin) items
; traceTc "tryReporters {" (ppr vis_items $$ ppr invis_items)
; (ctxt', items') <- go ctxt reporters vis_items invis_items
; traceTc "tryReporters }" (ppr items')
@@ -1416,9 +1441,9 @@ tryReporters ctxt reporters items
= return (ctxt, vis_items ++ invis_items)
go ctxt (r : rs) vis_items invis_items
- -- always look at *visible* Origins before invisible ones
+ -- Always look at *visible* Origins before invisible ones
-- this is the whole point of isVisibleOrigin
- = do { (ctxt', vis_items') <- tryReporter ctxt r vis_items
+ = do { (ctxt', vis_items') <- tryReporter ctxt r vis_items
; (ctxt'', invis_items') <- tryReporter ctxt' r invis_items
; go ctxt'' rs vis_items' invis_items' }
-- Carry on with the rest, because we must make
@@ -1432,7 +1457,7 @@ tryReporter ctxt (str, keep_me, suppress_after, reporter) items = case nonEmpty
{ traceTc "tryReporter{ " (text str <+> ppr yeses)
; (_, no_errs) <- askNoErrs (reporter ctxt yeses)
; let suppress_now = not no_errs && suppress_after
- -- See Note [Suppressing error messages]
+ -- See (SLIE2) in Note [cec_suppress: suppressing less-important error messages]
ctxt' = ctxt { cec_suppress = suppress_now || cec_suppress ctxt }
; traceTc "tryReporter end }" (text str <+> ppr (cec_suppress ctxt) <+> ppr suppress_after)
; return (ctxt', nos) }
=====================================
compiler/GHC/Tc/Types/Constraint.hs
=====================================
@@ -1214,15 +1214,16 @@ insolubleWantedCt :: Ct -> Bool
--
-- See Note [Insoluble Wanteds]
insolubleWantedCt ct
- | CtWanted (WantedCt { ctev_loc = loc, ctev_rewriters = rewriters })
- <- ctEvidence ct
+ | CtWanted (WantedCt {}) <- ctEvidence ct
-- It's a Wanted
, insolubleCt ct
-- It's insoluble
- , isEmptyCoHoleSet rewriters
+-- , isEmptyCoHoleSet rewriters
-- It has no rewriters – see (IW1) in Note [Insoluble Wanteds]
- , not (isGivenLoc loc)
- -- isGivenLoc: see (IW2) in Note [Insoluble Wanteds]
+
+-- I don't understand IW2 so I'm going to get rid of it
+-- , not (isGivenLoc loc)
+-- -- isGivenLoc: see (IW2) in Note [Insoluble Wanteds]
-- See also historical (IW3) in Note [Insoluble Wanteds]
= True
=====================================
testsuite/tests/typecheck/should_fail/T18851d.hs
=====================================
@@ -0,0 +1,39 @@
+{-# LANGUAGE FunctionalDependencies, FlexibleInstances, UndecidableInstances,
+ ScopedTypeVariables, TypeFamilies, TypeApplications,
+ FlexibleContexts, AllowAmbiguousTypes, ExtendedDefaultRules #-}
+
+module T18851d where
+
+default (Int)
+
+type family C_FD a
+class C_FD a ~ b => C a b
+
+type instance C_FD Int = Bool -- just for Show (C_FD Int)
+instance C Int b => C Int b
+
+class IsInt int
+instance int ~ Int => IsInt int
+
+data A
+instance Show A where
+ show _ = "A"
+data B
+instance Show B where
+ show _ = "B"
+
+data D
+
+f :: forall a b c int
+ . ( Show c, Num int
+ , C int a, C int b, C int c
+ -- , c ~ C_FD int -- add this to get rid of ambiguity error
+ )
+ => String
+f = show (undefined :: c)
+
+g :: String
+g = f @A @B ++ show (undefined :: D)
+ -- This variant, suggested by Claude in a review of !16564,
+ -- has an unsolved (Show D) constraint. It must not be suppressed
+ -- by the insoluble-but-suppressed constraints arising from (C Int a)
=====================================
testsuite/tests/typecheck/should_fail/T27731.hs
=====================================
@@ -0,0 +1,36 @@
+{-# LANGUAGE ImplicitParams, TypeFamilies #-}
+
+module Bug where
+
+type family St (a :: k) :: *
+type family Ev (a :: k) :: * -> *
+
+data T1 a = C1 a
+data T2 h g = C2 (h ())
+
+class (h ~ Ev g, s ~ St g) => Ren s h g
+
+f1 ::
+ (s ~ St h, Ren s h g, ?settings :: settings)
+ => (g v -> g ()) -> g v -> g ()
+f1 form = (\_ a -> a) (C1 (f2 {-@g-})) form
+
+f2 :: forall g h s. ( s ~ St h, Ren s h g) => T2 h g
+f2 = error "urk"
+
+{- Call of f2
+
+[W] s ~ St h --> St g ~ St h --> St g ~ St (Ev g)
+[W] Ren s h g
+[W] s ~ St g -- Superclass of wanted
+[W] h ~ Ev g -- Superclass of wanted
+-}
+
+{-
+f3 ::
+ T1 ()
+ -> (g v -> g ())
+ -> g v -> g ()
+f3 wd form = ((\_ a -> a) wd form)
+
+-}
=====================================
testsuite/tests/typecheck/should_fail/T27731.stderr
=====================================
@@ -0,0 +1,16 @@
+T27731.hs:16:28: [GHC-05617]
+ • Could not deduce ‘St (Ev g0) ~ St g0’
+ arising from a superclass required to satisfy ‘Ren
+ (St (Ev g0)) (Ev g0) g0’,
+ arising from a use of ‘f2’
+ from the context: (s ~ St h, Ren s h g, ?settings::settings)
+ bound by the type signature for:
+ f1 :: forall s (h :: * -> *) (g :: * -> *) settings v.
+ (s ~ St h, Ren s h g, ?settings::settings) =>
+ (g v -> g ()) -> g v -> g ()
+ at T27731.hs:(13,1)-(15,33)
+ Note: ‘St’ is a non-injective type family.
+ The type variable ‘g0’ is ambiguous
+ • In the first argument of ‘C1’, namely ‘(f2)’
+ In the first argument of ‘\ _ a -> a’, namely ‘(C1 (f2))’
+ In the expression: (\ _ a -> a) (C1 (f2)) form
=====================================
testsuite/tests/typecheck/should_fail/all.T
=====================================
@@ -565,6 +565,7 @@ test('T17563', normal, compile_fail, [''])
test('T18851', normal, compile_fail, [''])
test('T18851b', normal, compile, [''])
test('T18851c', normal, compile, [''])
+test('T18851d', normal, compile, [''])
test('T16946', normal, compile_fail, [''])
test('T16502', expect_broken(12854), compile, [''])
test('T17566b', normal, compile_fail, [''])
@@ -763,3 +764,4 @@ test('T26861', normal, compile_fail, [''])
test('T26862', normal, compile_fail, [''])
test('T27210', normal, compile_fail, [''])
test('T26532', normal, compile_fail, [''])
+test('T27731', normal, compile_fail, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2aaebe8bbdf7d6bf280584448b885dd…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2aaebe8bbdf7d6bf280584448b885dd…
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/andrea/ghc-9.14.1-release
by Andrea Vezzosi (@trac-Saizan) 03 Sep '26
by Andrea Vezzosi (@trac-Saizan) 03 Sep '26
03 Sep '26
Andrea Vezzosi pushed new branch wip/andrea/ghc-9.14.1-release at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andrea/ghc-9.14.1-release
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] 7 commits: testsuite: Migrate perf tests off collect_compiler_stats('all')
by Marge Bot (@marge-bot) 03 Sep '26
by Marge Bot (@marge-bot) 03 Sep '26
03 Sep '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
df058f1d by Simon Jakobi at 2026-09-02T07:18:06-04:00
testsuite: Migrate perf tests off collect_compiler_stats('all')
The 'all' metric argument applies a single tolerance to bytes
allocated, max_bytes_used and peak_megabytes_allocated, although their
noise profiles are incompatible (#27653): allocations are nearly
deterministic, residency needs 10-20%, and peak is quantized to 1 MB.
Any single tolerance is too tight for one metric or too slack for
another. This migrates the remaining users of 'all' (and of the 'all'
default) to explicit per-metric collection, ahead of removing 'all'
from the driver.
peak_megabytes_allocated is dropped everywhere: its 1 MB granularity
makes tight relative windows meaningless (#27613), and it is sensitive
to GC timing. In #27489 it drifted by -5.3% while max_bytes_used moved
by less than 0.1%. Where a test guards a memory property,
max_bytes_used covers it at byte granularity.
Where the motivating ticket was about compile-time memory
(T11545, T15304, T26425), residency remains gated via max_bytes_used,
now with a residency-appropriate tolerance.
max_bytes_used is dropped where residency was only ever an accident of
'all':
* T15630, T15630a, T20261: the underlying tickets (#15630, #20261)
contain no memory data at all. One is a simplifier-ticks blowup and
the other is stated entirely in allocation numbers, so the 20%
window never had teeth.
* T21839c: #21839's measurements show residency essentially flat
(+0.16%) while allocations moved +7%, so allocations are the
discriminating metric. They are already gated at 1% via
collect_compiler_runtime. The ghc/max gate had previously broken CI
spuriously (9fd11585eb widened it from 1% to 10% for that reason).
Allocation tolerances are tightened to the testsuite's conventional 2%
where 'all' previously left them at 10-20%.
Assisted-by: Claude Fable 5
- - - - -
72dd2432 by Simon Jakobi at 2026-09-02T07:18:06-04:00
testsuite: Remove the 'all' metric argument of collect_stats
'all' gated bytes allocated, max_bytes_used and peak_megabytes_allocated
at a single tolerance, although their noise profiles are incompatible,
making such tests either flaky or toothless (#27653).
Closes #27653.
Assisted-by: Claude Fable 5
- - - - -
2228cb30 by Simon Jakobi at 2026-09-02T07:18:06-04:00
testsuite: Make the deviation argument of collect_stats mandatory
Almost every caller passes an explicit tolerance matched to the
metric's noise profile, and the silent 20% default is far slacker than
'bytes allocated' merits. Only two tests relied on it. They now state
their tolerance explicitly:
large-project gets 10%, in line with other large compile-time tests.
T9848 gets 2%: its metric is byte-for-byte deterministic across CI
jobs and platforms of a given test_env, has drifted only about 2.5%
since 2015, and the fusion failure it guards against would show up as
a roughly +30000% jump.
Assisted-by: Claude Fable 5
- - - - -
56291fc5 by Cheng Shao at 2026-09-02T07:18:45-04:00
autoconf/ghc-toolchain: bump llvm upper bound to support llvm 23
This commit bumps llvm upper bound to support llvm 23.
- - - - -
20eb3f41 by Cheng Shao at 2026-09-02T07:18:45-04:00
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.
- - - - -
6e6d1609 by Simon Jakobi at 2026-09-03T04:45:17-04:00
Add -Wimplicit-field-strictness (#16836)
This opt-in warning fires when a data constructor field lacks an
explicit strictness annotation (`!` or `~`). It complements the
LazyFieldAnnotations extension (4762a8bf30f) from GHC proposal 752,
which makes `~` annotations available for this purpose.
Deciding which fields to report requires their levity, so the check
runs after typechecking. To keep the noise down, the diagnostic is
emitted once per data declaration, grouped by constructor.
Closes #16836.
Assisted-by: Claude Fable 5
- - - - -
ef675ca4 by mangoiv at 2026-09-03T04:45:18-04:00
simplifier: remove a bogus `assert` in `rebuild_app'` in `GHC.CoreToStg.Prep.cpeApp`.
Prior to this commit
commit 08bc245be70d95801bc1138804ed1de9474fbdc0
Author: sheaf <sam.derbyshire(a)gmail.com>
Date: Sat Feb 28 16:30:43 2026 +0100
Clean up join points, casts & ticks
This commit shores up the logic dealing with casts and ticks occurring
in between a join point binding and a jump
any `PlaceRuntime` ticks we observed were profiling ticks, even though that
isn't necessary.
The more liberal rules in the above commit allow e.g. breakpoint ticks
(which are valid PlaceRuntime ticks) to legitimately appear in an argument
position.
Fixes #27556
- - - - -
38 changed files:
- + changelog.d/27556
- + changelog.d/implicit-field-strictness-warning
- changelog.d/lazy-field-annotations
- + changelog.d/llvm-23
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/Hint.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Tickish.hs
- configure.ac
- docs/users_guide/exts/strict.rst
- docs/users_guide/using-warnings.rst
- libraries/base/tests/all.T
- rts/ProfHeap.c
- rts/eventlog/EventLog.c
- rts/prim/atomic.c
- testsuite/driver/README.md
- testsuite/driver/testlib.py
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/perf/compiler/large-project/all.T
- testsuite/tests/perf/space_leaks/all.T
- + testsuite/tests/simplCore/should_compile/T27556.hs
- + testsuite/tests/simplCore/should_compile/T27556.script
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/warnings/should_compile/T16836a.hs
- + testsuite/tests/warnings/should_compile/T16836a.stderr
- + testsuite/tests/warnings/should_compile/T16836b.hs
- + testsuite/tests/warnings/should_compile/T16836c.hs
- + testsuite/tests/warnings/should_compile/T16836c.stderr
- + testsuite/tests/warnings/should_compile/T16836d.hs
- + testsuite/tests/warnings/should_compile/T16836d.stderr
- testsuite/tests/warnings/should_compile/all.T
- utils/ghc-toolchain/src/GHC/Toolchain/Program.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0b38115b19b524f7c9f8277422bf41…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0b38115b19b524f7c9f8277422bf41…
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/andrea/gbc-backport] 20 commits: compiler: only use `Name` instead of `Id` in `SptEntry`
by Andrea Vezzosi (@trac-Saizan) 03 Sep '26
by Andrea Vezzosi (@trac-Saizan) 03 Sep '26
03 Sep '26
Andrea Vezzosi pushed to branch wip/andrea/gbc-backport at Glasgow Haskell Compiler / GHC
Commits:
270613a6 by Cheng Shao at 2026-09-03T10:37:32+02:00
compiler: only use `Name` instead of `Id` in `SptEntry`
As a part of #26298, this patch refactors `SptEntry` to only carry a
`Name` instead of `Id`: we do not care about extra information like
caffyness or type at all in any static pointer related codegen logic.
This is necessary to make `SptEntry` serializable, as a part of the
grand plan of serializable bytecode.
Co-authored-by: Codex <codex(a)openai.com>
(cherry picked from commit 39b2e3823da3ab168aa2b7365f0f27e01b1ecd0e)
- - - - -
4623b595 by Oleg Grenrus at 2026-09-03T10:37:32+02:00
Generalise thNameToGhcName by adding HasHscEnv
There were multiple single monad-specific `getHscEnv` across codebase.
HasHscEnv is modelled on HasDynFlags.
My first idea was to simply add thNameToGhcNameHsc and
thNameToGhcNameTc, but those would been exactly the same
as thNameToGhcName already.
Also add an usage example to thNameToGhcName and mention that it's
recommended way of looking up names in GHC plugins
(cherry picked from commit eb2ab1e2cadde93c330330ca7fdc64b31cd61473)
- - - - -
df10ae15 by Simon Peyton Jones at 2026-09-03T10:37:32+02:00
Refactor ForAllCo
This is a pure refactor, addressing #26389.
It arranges that the kind coercion in a ForAllCo is a MCoercion, rather
than a plain Coercion, thus removing redundancy in the common case.
See (FC8) in Note [ForAllCo]
It's a nice cleanup.
(cherry picked from commit 94b62aa7e7b40b53442161a0c4f380955fda2f14)
- - - - -
b2f45031 by Cheng Shao at 2026-09-03T10:38:16+02:00
compiler/ghci: replace the LoadDLL message with LoadDLLs
As a part of #25407, this commit changes the LoadDLL message to
LoadDLLs, which takes a list of DLL paths to load and returns the list
of remote pointer handles. The wasm dyld is refactored to take
advantage of LoadDLLs and harvest background parallelism. On other
platforms, LoadDLLs is based on a fallback codepath that does
sequential loading.
The driver is not actually emitting singular LoadDLLs message with
multiple DLLs yet, this is left in subsequent commits.
Co-authored-by: Codex <codex(a)openai.com>
(cherry picked from commit a4d664c78642438f0f178ffa243e2ffdbdf20397)
- - - - -
9c512d0e by Cheng Shao at 2026-09-03T10:38:20+02:00
driver: separate downsweep/upsweep phase in loadPackages'
This commit refactors GHC.Linker.Loader.loadPackages' to be separated
into downsweep/upsweep phases:
- The downsweep phase performs dependency analysis and generates a
list of topologically sorted packages to load
- The upsweep phase sequentially loads these packages by calling
loadPackage
This is a necessary refactoring to make it possible to make loading of
DLLs concurrent.
(cherry picked from commit c7fc4baeddcfad500126b2e91ce94d2b9391560d)
- - - - -
a8d284ea by Cheng Shao at 2026-09-03T10:38:20+02:00
driver: emit single LoadDLLs message to load multiple DLLs
This commit refactors the driver so that it emits a single LoadDLLs
message to load multiple DLLs in GHC.Linker.Loader.loadPackages'.
Closes #25407.
-------------------------
Metric Increase:
MultiLayerModulesTH_OneShot
TcPlugin_RewritePerf
-------------------------
Co-authored-by: Codex <codex(a)openai.com>
(cherry picked from commit ab180104b61a930e8a1e906f013c151669ce6fff)
- - - - -
4af2e65a by Matthew Pickering at 2026-09-03T10:38:20+02:00
driver: Load bytecode static pointer entries during linking
Previously the entries were loaded too eagerly, during upsweep, but we
should delay loading them until we know that the relevant bytecode
object is demanded.
Towards #25230
(cherry picked from commit e9445c013fbccf9318739ca3d095a3e0a2e1be8a)
- - - - -
6cf584e3 by Matthew Pickering at 2026-09-03T10:38:20+02:00
loader: Unify loadDecls and loadModuleLinkables functions
These two functions nearly did the same thing. I have refactored them so
that `loadDecls` now calls `loadModuleLinkables`.
Fixes #26459
(cherry picked from commit da9633a9009a08132b974b0407c4057cae3577f7)
- - - - -
78023870 by Matthew Pickering at 2026-09-03T10:38:20+02:00
testsuite: Use ghci_ways to set ways in PackedDataCon/UnboxedTuples/UnliftedDataTypeInterp tests
These tests reimplemented the logic from `valid_way` in order to
determine what ways to run. It's easier to use this combination of
`only_ways` and `extra_ways` to only run in GHCi ways and always run in
GHCi ways.
(cherry picked from commit 1275d3607299734228adbbc47bfb69bf8800279f)
- - - - -
7b04a1b8 by Matthew Pickering at 2026-09-03T10:38:53+02:00
Rename interpreterBackend to bytecodeBackend
This is preparation for creating bytecode files.
The "interpreter" is one way in which we can run bytecode objects. It is
more accurate to describe that the backend produces bytecode, rather
than the means by which the code will eventually run.
The "interpreterBackend" binding is left as a deprecated alias.
(cherry picked from commit c06b534bbd6dbb570b760f2e82b3e375d3956bcf)
- - - - -
7c5f98be by sheaf at 2026-09-03T10:38:57+02:00
Store SDoc context in SourceError
This commits modifies the SourceError datatype which is used for
throwing and then reporting exceptions by storing all the info we need
to be able to print the SDoc, including whether we should print with
explicit kinds, explicit runtime-reps, etc.
This is done using the new datatype:
data SourceErrorContext
= SEC
!DiagOpts
!(DiagnosticOpts GhcMessage)
Now, when we come to report an error (by handling the exception), we
have access to the full context we need.
Fixes #26387
(cherry picked from commit 129ce32d3a4f2601f5c2d1bbaeeb2fbaf8dc9ef9)
- - - - -
dbf79e13 by sheaf at 2026-09-03T10:38:57+02:00
Improvements to 'mayLookIdentical'
This commit makes significant improvements to the machinery that decides
when we should pretty-print the "invisible bits" of a type, such as:
- kind applications, e.g. '@k' in 'Proxy @k ty'
- RuntimeReps, e.g. 'TYPE r'
- multiplicities and linear arrows 'a %1 -> b'
To do this, this commit refactors 'mayLookIdentical' to return **which**
of the invisible bits don't match up, e.g. in
(a %1 -> b) ~ (a %Many -> b)
we find that the invisible bit that doesn't match up is a multiplicity,
so we should set 'sdocLinearTypes = True' when pretty-printing, and with
e.g.
Proxy @k1 ~ Proxy @k2
we find that the invisible bit that doesn't match up is an invisible
TyCon argument, so we set 'sdocPrintExplicitKinds = True'.
We leverage these changes to remove the ad-hoc treatment of linearity
of data constructors with 'dataConDisplayType' and 'dataConNonLinearType'.
This is now handled by the machinery of 'pprWithInvisibleBits'.
Fixes #26335 #26340
(cherry picked from commit 2b8baada761b13199b99268f243bebd009e6e1b5)
- - - - -
b549d9c4 by Matthew Pickering at 2026-09-03T10:38:57+02:00
Add support for generating bytecode objects
This commit adds the `-fwrite-byte-code` option which makes GHC emit a
`.gbc` file which contains a serialised representation of bytecode.
The bytecode can be loaded by the compiler to avoid having to
reinterpret a module when using the bytecode interpreter (for example,
in GHCi).
There are also the new options:
* -gbcdir=<DIR>: Specify the directory to place the gbc files
* -gbcsuf=<suffix>: Specify the suffix for gbc files
The option `-fbyte-code-and-object-code` now implies
`-fwrite-byte-code`.
These performance tests fail due to https://github.com/haskell/directory/issues/204
-------------------------
Metric Increase:
MultiComponentModules
MultiLayerModules
MultiComponentModulesRecomp
MultiLayerModulesRecomp
MultiLayerModulesTH_Make
MultiLayerModulesTH_OneShot
T13701
-------------------------
The bytecode serialisation part was implemented by Cheng Shao
Co-authored-by: Cheng Shao <terrorjack(a)type.dance>
(cherry picked from commit 6bd8155c991cfce7cca594bc63ba8f6ca6751667)
- - - - -
16e2d353 by Ben Gamari at 2026-09-03T10:38:57+02:00
rts: Eliminate uses of implicit constant arrays
Folding of `const`-sized variable-length arrays to a constant-length
array is a gnu extension which clang complains about.
Closes #26502.
(cherry picked from commit 0c00c9c3b4e9b8515d4839f2c1d7d771781dc6f4)
- - - - -
24974d92 by Matthew Pickering at 2026-09-03T10:39:10+02:00
driver: Properly handle errors during LinkNode steps
Previously we were not properly catching errors during the LinkNode step
(see T9930fail test).
This is fixed by wrapping the `LinkNode` action in `wrapAction`, the
same handler which is used for module compilation.
Fixes #26496
(cherry picked from commit 6c91582f915f80daff774db7738094bda6ab3b44)
- - - - -
198fc051 by Sylvain Henry at 2026-09-03T10:39:21+02:00
Build external interpreter program on demand (#24731)
This patch teaches GHC how to build the external interpreter program
when it is missing. As long as we have the `ghci` library, doing this is
trivial so most of this patch is refactoring for doing it sanely.
(cherry picked from commit 55eab80d337e47decacbe979c29a1b7b47d0a872)
- - - - -
74fbe765 by Matthew Pickering at 2026-09-03T10:39:29+02:00
Use 'OsPath' in getModificationTimeIfExists
This part of the compiler is quite hot during recompilation checking in
particular since the filepaths will be translated to a string. It is
better to use the 'OsPath' native function, which turns out to be easy
to do.
(cherry picked from commit ef0dc33b2034fd91e11950751264e8b2e9f03fc4)
- - - - -
425a31db by Georgios Karachalias at 2026-09-03T10:39:29+02:00
Use OsPath in PkgDbRef and UnitDatabase, not FilePath
(cherry picked from commit fa3bd0a67eea13701d1b50053636f9645e999308)
- - - - -
add2f262 by Matthew Pickering at 2026-09-03T10:39:29+02:00
Add support for building bytecode libraries
A bytecode library is a collection of bytecode files (.gbc) and a
library which combines together additional object files.
A bytecode library is created by invoking GHC with the `-bytecodelib`
flag.
A library can be created from in-memory `ModuleByteCode` linkables or
by passing `.gbc` files as arguments on the command line.
Fixes #26298
(cherry picked from commit e36a5fcbeaa33abb17707173c9d1e81730f85008)
- - - - -
d78ff1a0 by Matthew Pickering at 2026-09-03T10:39:29+02:00
Load bytecode libraries to satisfy package dependencies
This commit allows you to use a bytecode library to satisfy a package
dependency when using the interpreter.
If a user enables `-fprefer-byte-code`, then if a package provides a
bytecode library, that will be loaded and used to satisfy the
dependency.
The main change is to separate the relevant parts of the `LoaderState`
into external and home package byte code. Bytecode is loaded into either
the home package or external part (similar to HPT/EPS split), HPT
bytecode can be unloaded. External bytecode is never unloaded.
The unload function has also only been called with an empty list of
"stable linkables" for a long time. It has been modified to directly
implement a complete unloading of the home package bytecode linkables.
At the moment, the bytecode libraries are found in the "library-dirs"
field from the package description. In the future when `Cabal`
implements support for "bytecode-library-dirs" field, we can read the
bytecode libraries from there. No changes to the Cabal submodule are
necessary at the moment.
Four new tests are added in testsuite/tests/cabal, which generate fake
package descriptions and test loading the libraries into GHCi.
Fixes #26298
(cherry picked from commit 8f9ae3397dbcbb4b0bd7a574ffc6b1fbaa137b6c)
- - - - -
239 changed files:
- compiler/GHC.hs
- compiler/GHC/Builtin/PrimOps.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Linker.hs
- + compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Coercion.hs-boot
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Multiplicity.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Reduction.hs
- compiler/GHC/Core/TyCo/Compare.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Ppr.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/TyCo/Tidy.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Data/FlatBag.hs
- compiler/GHC/Data/OsPath.hs
- compiler/GHC/Data/SmallArray.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/Backend/Internal.hs
- compiler/GHC/Driver/Backpack.hs
- + compiler/GHC/Driver/ByteCode.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Config/Finder.hs
- + compiler/GHC/Driver/Config/Interpreter.hs
- compiler/GHC/Driver/Config/Linker.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Env/Types.hs
- compiler/GHC/Driver/Errors.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Errors/Types.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/Messager.hs
- compiler/GHC/Driver/Monad.hs
- compiler/GHC/Driver/Phases.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Plugins.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Decl.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- + compiler/GHC/Linker/ByteCode.hs
- compiler/GHC/Linker/Config.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Dynamic.hs
- + compiler/GHC/Linker/Executable.hs
- − compiler/GHC/Linker/ExtraObj.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/MacOS.hs
- compiler/GHC/Linker/Static.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Linker/Windows.hs
- compiler/GHC/Parser/Header.hs
- compiler/GHC/Plugins.hs
- compiler/GHC/Runtime/Debugger.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Interpreter.hs
- + compiler/GHC/Runtime/Interpreter/C.hs
- + compiler/GHC/Runtime/Interpreter/Init.hs
- compiler/GHC/Settings.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToJS/StaticPtr.hs
- compiler/GHC/SysTools/Tasks.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types/CtLoc.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Utils/Unify.hs-boot
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/SourceError.hs
- compiler/GHC/Types/SptEntry.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Types/TyThing/Ppr.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Home/PackageTable.hs
- compiler/GHC/Unit/Info.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/Location.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Error.hs
- compiler/GHC/Utils/Misc.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/ghc.cabal.in
- docs/users_guide/extending_ghc.rst
- docs/users_guide/phases.rst
- docs/users_guide/separate_compilation.rst
- ghc/GHCi/UI.hs
- ghc/Main.hs
- libraries/ghc-boot/GHC/Unit/Database.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/ObjLink.hs
- libraries/ghci/GHCi/Run.hs
- rts/Printer.c
- rts/posix/OSMem.c
- testsuite/config/ghc
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/mk/boilerplate.mk
- testsuite/tests/bytecode/T24634/T24634a.stdout
- testsuite/tests/bytecode/T24634/T24634b.stdout
- + testsuite/tests/cabal/Bytecode.hs
- + testsuite/tests/cabal/BytecodeForeign.c
- + testsuite/tests/cabal/BytecodeForeign.hs
- testsuite/tests/cabal/Makefile
- testsuite/tests/cabal/all.T
- + testsuite/tests/cabal/bytecode.pkg
- + testsuite/tests/cabal/bytecode.script
- + testsuite/tests/cabal/bytecode_foreign.pkg
- + testsuite/tests/cabal/bytecode_foreign.script
- testsuite/tests/cabal/ghcpkg03.stderr
- testsuite/tests/cabal/ghcpkg03.stderr-mingw32
- testsuite/tests/cabal/ghcpkg05.stderr
- testsuite/tests/cabal/ghcpkg05.stderr-mingw32
- + testsuite/tests/cabal/pkg_bytecode.stderr
- + testsuite/tests/cabal/pkg_bytecode.stdout
- + testsuite/tests/cabal/pkg_bytecode_foreign.stderr
- + testsuite/tests/cabal/pkg_bytecode_foreign.stdout
- + testsuite/tests/cabal/pkg_bytecode_with_gbc.stderr
- + testsuite/tests/cabal/pkg_bytecode_with_gbc.stdout
- + testsuite/tests/cabal/pkg_bytecode_with_o.stderr
- + testsuite/tests/cabal/pkg_bytecode_with_o.stdout
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/cpranal/should_compile/T18174.stderr
- testsuite/tests/driver/T11429c.stderr
- testsuite/tests/driver/T21682.stderr
- + testsuite/tests/driver/T24731.hs
- testsuite/tests/driver/T5313.hs
- testsuite/tests/driver/all.T
- + testsuite/tests/driver/bytecode-object/A.hs
- + testsuite/tests/driver/bytecode-object/BytecodeForeign.c
- + testsuite/tests/driver/bytecode-object/BytecodeForeign.hs
- + testsuite/tests/driver/bytecode-object/BytecodeMain.hs
- + testsuite/tests/driver/bytecode-object/BytecodeTest.hs
- + testsuite/tests/driver/bytecode-object/Makefile
- + testsuite/tests/driver/bytecode-object/all.T
- + testsuite/tests/driver/bytecode-object/bytecode_object12.stderr
- + testsuite/tests/driver/bytecode-object/bytecode_object13.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object14.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object15.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object16.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object17.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object18.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object19.script
- + testsuite/tests/driver/bytecode-object/bytecode_object19.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object20.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object21.stderr
- + testsuite/tests/driver/bytecode-object/bytecode_object21.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object23.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object24.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object25.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object4.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object5.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object6.stdout
- testsuite/tests/driver/fat-iface/T22405/T22405.stdout
- testsuite/tests/driver/fat-iface/T22405/T22405b.stdout
- testsuite/tests/driver/fat-iface/fat011.stderr
- testsuite/tests/ghc-api/T10052/T10052.hs
- testsuite/tests/ghc-api/T10942.hs
- testsuite/tests/ghc-api/T8639_api.hs
- testsuite/tests/ghc-api/annotations-literals/literals.hs
- testsuite/tests/ghc-api/apirecomp001/myghc.hs
- testsuite/tests/ghc-e/should_fail/T9930fail.stderr
- testsuite/tests/ghc-e/should_fail/all.T
- testsuite/tests/ghci/linking/dyn/T3372.hs
- testsuite/tests/ghci/should_run/PackedDataCon/packeddatacon.T
- testsuite/tests/ghci/should_run/UnboxedTuples/unboxedtuples.T
- testsuite/tests/ghci/should_run/UnliftedDataTypeInterp/unlifteddatatypeinterp.T
- testsuite/tests/indexed-types/should_fail/T14887.stderr
- testsuite/tests/linear/should_fail/T19361.stderr
- testsuite/tests/perf/compiler/Makefile
- + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithBytecodeFiles.script
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/roles/should_compile/Roles13.stderr
- testsuite/tests/rts/linker/T2615.hs
- testsuite/tests/simplCore/should_compile/OpaqueNoCastWW.stderr
- testsuite/tests/simplCore/should_compile/T17673.stderr
- testsuite/tests/simplCore/should_compile/T18078.stderr
- testsuite/tests/simplCore/should_compile/T18995.stderr
- testsuite/tests/simplCore/should_compile/T19890.stderr
- testsuite/tests/simplCore/should_compile/T21948.stderr
- testsuite/tests/simplCore/should_compile/T21960.stderr
- testsuite/tests/simplCore/should_compile/T24808.stderr
- − testsuite/tests/simplCore/should_compile/T25713.stderr
- testsuite/tests/simplCore/should_compile/T4201.stdout
- testsuite/tests/simplCore/should_compile/T8331.stderr
- testsuite/tests/simplStg/should_compile/T22840.stderr
- testsuite/tests/typecheck/no_skolem_info/T20232.stderr
- testsuite/tests/typecheck/should_fail/T11672.stderr
- testsuite/tests/typecheck/should_fail/T12373.stderr
- testsuite/tests/typecheck/should_fail/T15807.stderr
- testsuite/tests/typecheck/should_fail/T16074.stderr
- testsuite/tests/typecheck/should_fail/T18357a.stderr
- testsuite/tests/typecheck/should_fail/T19627.stderr
- testsuite/tests/typecheck/should_fail/T21530a.stderr
- testsuite/tests/typecheck/should_fail/VisFlag1.stderr
- utils/check-exact/Parsers.hs
- utils/check-exact/Preprocess.hs
- utils/ghc-pkg/Main.hs
- utils/iserv/iserv.cabal.in
- utils/jsffi/dyld.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ea088334e51e9bf59f6969ac503f5…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ea088334e51e9bf59f6969ac503f5…
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/sjakobi/T27688-bt-single-bit-tests
by Simon Jakobi (@sjakobi) 03 Sep '26
by Simon Jakobi (@sjakobi) 03 Sep '26
03 Sep '26
Simon Jakobi pushed new branch wip/sjakobi/T27688-bt-single-bit-tests at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sjakobi/T27688-bt-single-bit-…
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