[Git][ghc/ghc][wip/T26343] 38 commits: Revert "STM: don't create a transaction in the rhs of catchRetry# (#26028)"
by Teo Camarasu (@teo) 04 Sep '25
by Teo Camarasu (@teo) 04 Sep '25
04 Sep '25
Teo Camarasu pushed to branch wip/T26343 at Glasgow Haskell Compiler / GHC
Commits:
5b5d9d47 by Ben Gamari at 2025-08-25T14:29:35-04:00
Revert "STM: don't create a transaction in the rhs of catchRetry# (#26028)"
This reverts commit 0a5836891ca29836a24c306d2a364c2e4b5377fd
- - - - -
10f06163 by Cheng Shao at 2025-08-25T14:30:16-04:00
wasm: ensure setKeepCAFs() is called in ghci
This patch is a critical bugfix for #26106, see comment and linked
issue for details.
- - - - -
bedc1004 by Cheng Shao at 2025-08-26T09:31:18-04:00
compiler: use zero cost coerce in hoopl setElems/mapToList
This patch is a follow-up of !14680 and changes setElems/mapToList in
GHC/Cmm/Dataflow/Label to use coerce instead of mapping mkHooplLabel
over the keys.
- - - - -
13250d97 by Ryan Scott at 2025-08-26T09:31:59-04:00
Reject infix promoted data constructors without DataKinds
In the rename, make sure to apply the same `DataKinds` checks for both
`HsTyVar` (for prefix promoted data constructors) and `HsOpTy` (for infix
promoted data constructors) alike.
Fixes #26318.
- - - - -
37655c46 by Teo Camarasu at 2025-08-26T15:24:51-04:00
tests: disable T22859 under LLVM
This test was failing under the LLVM backend since the allocations
differ from the NCG.
Resolves #26282
- - - - -
2cbba9d6 by Teo Camarasu at 2025-08-26T15:25:33-04:00
base-exports: update version numbers
As the version of the compiler has been bumped, a lot of the embedded
version numbers will need to be updated if we ever run this test with
`--test-accept` so let's just update them now, and keep future diffs
clean.
- - - - -
f9f2ffcf by Alexandre Esteves at 2025-08-27T07:19:14-04:00
Import new name for 'utimbuf' on windows to fix #26337
Fixes an `-Wincompatible-pointer-types` instance that turns into an error on
recent toolchains and surfaced as such on nixpkgs when doing linux->ucrt cross.
This long-standing warning has been present at least since 9.4:
```
C:\GitLabRunner\builds\0\1709189\tmp\ghc16652_0\ghc_4.c:26:115: error:
warning: incompatible pointer types passing 'struct utimbuf *' to parameter of type 'struct _utimbuf *' [-Wincompatible-pointer-types]
|
26 | HsInt32 ghczuwrapperZC9ZCbaseZCSystemziPosixziInternalsZCzuutime(char* a1, struct utimbuf* a2) {return _utime(a1, a2);}
| ^
HsInt32 ghczuwrapperZC9ZCbaseZCSystemziPosixziInternalsZCzuutime(char* a1, struct utimbuf* a2) {return _utime(a1, a2);}
^~
C:\GitLabRunner\builds\0\1709189\_build\stage0\lib\..\..\mingw\x86_64-w64-mingw32\include\sys\utime.h:109:72: error:
note: passing argument to parameter '_Utimbuf' here
|
109 | __CRT_INLINE int __cdecl _utime(const char *_Filename,struct _utimbuf *_Utimbuf) {
| ^
__CRT_INLINE int __cdecl _utime(const char *_Filename,struct _utimbuf *_Utimbuf) {
```
- - - - -
ae89f000 by Hassan Al-Awwadi at 2025-08-27T07:19:56-04:00
Adds the fucnction addDependentDirectory to Q, resolving issue #26148.
This function adds a new directory to the list of things a module depends upon. That means that when the contents of the directory change, the recompilation checker will notice this and the module will be recompiled. Documentation has also been added for addDependentFunction and addDependentDirectory in the user guide.
- - - - -
00478944 by Simon Peyton Jones at 2025-08-27T16:48:30+01:00
Comments only
- - - - -
a7884589 by Simon Peyton Jones at 2025-08-28T11:08:23+01:00
Type-family occurs check in unification
The occurs check in `GHC.Core.Unify.uVarOrFam` was inadequate in dealing
with type families.
Better now. See Note [The occurs check in the Core unifier].
As I did this I realised that the whole apartness thing is trickier than I
thought: see the new Note [Shortcomings of the apartness test]
- - - - -
8adfc222 by sheaf at 2025-08-28T19:47:17-04:00
Fix orientation in HsWrapper composition (<.>)
This commit fixes the order in which WpCast HsWrappers are composed,
fixing a bug introduced in commit 56b32c5a2d5d7cad89a12f4d74dc940e086069d1.
Fixes #26350
- - - - -
eb2ab1e2 by Oleg Grenrus at 2025-08-29T11:00:53-04: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
- - - - -
2d575a7f by fendor at 2025-08-29T11:01:36-04:00
configure: Bump minimal bootstrap GHC version to 9.10
- - - - -
716274a5 by Simon Peyton Jones at 2025-08-29T17:27:12-04:00
Fix deep subsumption again
This commit fixed #26255:
commit 56b32c5a2d5d7cad89a12f4d74dc940e086069d1
Author: sheaf <sam.derbyshire(a)gmail.com>
Date: Mon Aug 11 15:50:47 2025 +0200
Improve deep subsumption
This commit improves the DeepSubsumption sub-typing implementation
in GHC.Tc.Utils.Unify.tc_sub_type_deep by being less eager to fall back
to unification.
But alas it still wasn't quite right for view patterns: #26331
This MR does a generalisation to fix it. A bit of a sledgehammer to crack
a nut, but nice.
* Add a field `ir_inst :: InferInstFlag` to `InferResult`, where
```
data InferInstFlag = IIF_Sigma | IIF_ShallowRho | IIF_DeepRho
```
* The flag says exactly how much `fillInferResult` should instantiate
before filling the hole.
* We can also use this to replace the previous very ad-hoc `tcInferSigma`
that was used to implement GHCi's `:type` command.
- - - - -
27206c5e by sheaf at 2025-08-29T17:28:14-04:00
Back-compat for TH SpecialiseP data-con of Pragma
This commit improves the backwards-compatibility story for the
SpecialiseP constructor of the Template Haskell 'Pragma' datatype.
Instead of keeping the constructor but deprecating it, this commit makes
it into a bundled pattern synonym of the Pragma datatype. We no longer
deprecate it; it's useful for handling old-form specialise pragmas.
- - - - -
26dbcf61 by fendor at 2025-08-30T05:10:08-04:00
Move stack decoding logic from ghc-heap to ghc-internal
The stack decoding logic in `ghc-heap` is more sophisticated than the one
currently employed in `CloneStack`. We want to use the stack decoding
implementation from `ghc-heap` in `base`.
We cannot simply depend on `ghc-heap` in `base` due do bootstrapping
issues.
Thus, we move the code that is necessary to implement stack decoding to
`ghc-internal`. This is the right location, as we don't want to add a
new API to `base`.
Moving the stack decoding logic and re-exposing it in ghc-heap is
insufficient, though, as we have a dependency cycle between.
* ghc-heap depends on stage1:ghc-internal
* stage0:ghc depends on stage0:ghc-heap
To fix this, we remove ghc-heap from the set of `stage0` dependencies.
This is not entirely straight-forward, as a couple of boot dependencies,
such as `ghci` depend on `ghc-heap`.
Luckily, the boot compiler of GHC is now >=9.10, so we can migrate `ghci`
to use `ghc-internal` instead of `ghc-heap`, which already exports the
relevant modules.
However, we cannot 100% remove ghc's dependency on `ghc-heap`, since
when we compile `stage0:ghc`, `stage1:ghc-internal` is not yet
available.
Thus, when we compile with the boot-compiler, we still depend on an
older version of `ghc-heap`, and only use the modules from `ghc-internal`,
if the `ghc-internal` version is recent enough.
-------------------------
Metric Increase:
T24602_perf_size
T25046_perf_size_gzip
T25046_perf_size_unicode
T25046_perf_size_unicode_gzip
size_hello_artifact
size_hello_artifact_gzip
size_hello_unicode
size_hello_unicode_gzip
-------------------------
These metric increases are unfortunate, they are most likely caused by
the larger (literally in terms of lines of code) stack decoder implementation
that are now linked into hello-word binaries.
On linux, it is almost a 10% increase, which is considerable.
- - - - -
bd80bb70 by fendor at 2025-08-30T05:10:08-04:00
Implement `decode` in terms of `decodeStackWithIpe`
Uses the more efficient stack decoder implementation.
- - - - -
24441165 by fendor at 2025-08-30T05:10:08-04:00
Remove stg_decodeStackzh
- - - - -
fb9cc882 by Simon Peyton Jones at 2025-08-30T05:10:51-04:00
Fix a long standing bug in the coercion optimiser
We were mis-optimising ForAllCo, leading to #26345
Part of the poblem was the tricky tower of abstractions leading to
the dreadful
GHC.Core.TyCo.Subst.substForAllCoTyVarBndrUsing
This function was serving two masters: regular substitution, but also
coercion optimsation. So tricky was it that it did so wrong.
In this MR I locate all the fancy footwork for coercion optimisation
in GHC.Core.Coercion.Opt, where it belongs. That leaves substitution
free to be much simpler.
- - - - -
6c78de2d by Sylvain Henry at 2025-09-01T08:46:19-04:00
Driver: substitute virtual Prim module in --make mode too
When we build ghc-internal with --make (e.g. with cabal-install), we
need to be careful to substitute the virtual interface file for
GHC.Internal.Prim:
- after code generation (we generate code for an empty module, so we get
an empty interface)
- when we try to reload its .hi file
- - - - -
26e0db16 by fendor at 2025-09-01T08:47:01-04:00
Expose Stack Annotation frames in IPE backtraces by default
When decoding the Haskell-native call stack and displaying the IPE information
for the stack frames, we print the `StackAnnotation` of the `AnnFrame` by default.
This means, when an exception is thrown, any intermediate stack annotations will
be displayed in the `IPE Backtrace`.
Example backtrace:
```
Exception: ghc-internal:GHC.Internal.Exception.ErrorCall:
Oh no!
IPE backtrace:
annotateCallStackIO, called at app/Main.hs:48:10 in backtrace-0.1.0.0-inplace-server:Main
annotateCallStackIO, called at app/Main.hs:46:13 in backtrace-0.1.0.0-inplace-server:Main
Main.handler (app/Main.hs:(46,1)-(49,30))
Main.liftIO (src/Servant/Server/Internal/Handler.hs:30:36-42)
Servant.Server.Internal.Delayed.runHandler' (src/Servant/Server/Internal/Handler.hs:27:31-41)
Control.Monad.Trans.Resource.runResourceT (./Control/Monad/Trans/Resource.hs:(192,14)-(197,18))
Network.Wai.Handler.Warp.HTTP1.processRequest (./Network/Wai/Handler/Warp/HTTP1.hs:195:20-22)
Network.Wai.Handler.Warp.HTTP1.processRequest (./Network/Wai/Handler/Warp/HTTP1.hs:(195,5)-(203,31))
Network.Wai.Handler.Warp.HTTP1.http1server.loop (./Network/Wai/Handler/Warp/HTTP1.hs:(141,9)-(157,42))
HasCallStack backtrace:
error, called at app/Main.hs:48:32 in backtrace-0.1.0.0-inplace-server:Main
```
The first two entries have been added by `annotateCallStackIO`, defined in `annotateCallStackIO`.
- - - - -
a1567efd by Sylvain Henry at 2025-09-01T23:01:35-04:00
RTS: rely less on Hadrian for flag setting (#25843)
Hadrian used to pass -Dfoo command-line flags directly to build the rts.
We can replace most of these flags with CPP based on cabal flags.
It makes building boot libraries with cabal-install simpler (cf #25843).
- - - - -
ca5b0283 by Sergey Vinokurov at 2025-09-01T23:02:23-04:00
Remove unnecessary irrefutable patterns from Bifunctor instances for tuples
Implementation of https://github.com/haskell/core-libraries-committee/issues/339
Metric Decrease:
mhu-perf
- - - - -
2da84b7a by sheaf at 2025-09-01T23:03:23-04:00
Only use active rules when simplifying rule RHSs
When we are simplifying the RHS of a rule, we make sure to only apply
rewrites from rules that are active throughout the original rule's
range of active phases.
For example, if a rule is always active, we only fire rules that are
themselves always active when simplifying the RHS. Ditto for inline
activations.
This is achieved by setting the simplifier phase to a range of phases,
using the new SimplPhaseRange constructor. Then:
1. When simplifying the RHS of a rule, or of a stable unfolding,
we set the simplifier phase to a range of phases, computed from
the activation of the RULE/unfolding activation, using the
function 'phaseFromActivation'.
The details are explained in Note [What is active in the RHS of a RULE?]
in GHC.Core.Opt.Simplify.Utils.
2. The activation check for other rules and inlinings is then:
does the activation of the other rule/inlining cover the whole
phase range set in sm_phase? This continues to use the 'isActive'
function, which now accounts for phase ranges.
On the way, this commit also moves the exact-print SourceText annotation
from the Activation datatype to the ActivationAnn type. This keeps the
main Activation datatype free of any extra cruft.
Fixes #26323
- - - - -
79816cc4 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
cleanup: Move dehydrateCgBreakInfo to Stg2Bc
This no longer has anything to do with Core.
- - - - -
53da94ff by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
rts/Disassembler: Fix spacing of BRK_FUN
- - - - -
08c0cf85 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Fix bciPtr in Step-out
We need to use `BCO_NEXT` to move bciPtr to ix=1, because ix=0 points to
the instruction itself!
I do not understand how this didn't crash before.
- - - - -
e7e021fa by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Allow BRK_FUNs to head case continuation BCOs
When we start executing a BCO, we may want to yield to the scheduler:
this may be triggered by a heap/stack check, context switch, or a
breakpoint. To yield, we need to put the stack in a state such that
when execution is resumed we are back to where we yielded from.
Previously, a BKR_FUN could only head a function BCO because we only
knew how to construct a valid stack for yielding from one -- simply add
`apply_interp_info` + the BCO to resume executing. This is valid because
the stack at the start of run_BCO is headed by that BCO's arguments.
However, in case continuation BCOs (as per Note [Case continuation BCOs]),
we couldn't easily reconstruct a valid stack that could be resumed
because we dropped too soon the stack frames regarding the value
returned (stg_ret) and received (stg_ctoi) by that continuation.
This is especially tricky because of the variable type and size return
frames (e.g. pointer ret_p/ctoi_R1p vs a tuple ret_t/ctoi_t2).
The trick to being able to yield from a BRK_FUN at the start of a case
cont BCO is to stop removing the ret frame headers eagerly and instead
keep them until the BCO starts executing. The new layout at the start of
a case cont. BCO is described by the new Note [Stack layout when entering run_BCO].
Now, we keep the ret_* and ctoi_* frames when entering run_BCO.
A BRK_FUN is then executed if found, and the stack is yielded as-is with
the preserved ret and ctoi frames.
Then, a case cont BCO's instructions always SLIDE off the headers of the
ret and ctoi frames, in StgToByteCode.doCase, turning a stack like
| .... |
+---------------+
| fv2 |
+---------------+
| fv1 |
+---------------+
| BCO |
+---------------+
| stg_ctoi_ret_ |
+---------------+
| retval |
+---------------+
| stg_ret_..... |
+---------------+
into
| .... |
+---------------+
| fv2 |
+---------------+
| fv1 |
+---------------+
| retval |
+---------------+
for the remainder of the BCO.
Moreover, this more uniform approach of keeping the ret and ctoi frames
means we need less ad-hoc logic concerning the variable size of
ret_tuple vs ret_p/np frames in the code generator and interpreter:
Always keep the return to cont. stack intact at the start of run_BCO,
and the statically generated instructions will take care of adjusting
it.
Unlocks BRK_FUNs at the start of case cont. BCOs which will enable a
better user-facing step-out (#26042) which is free of the bugs the
current BRK_ALTS implementation suffers from (namely, using BRK_FUN
rather than BRK_ALTS in a case cont. means we'll never accidentally end
up in a breakpoint "deeper" than the continuation, because we stop at
the case cont itself rather than on the first breakpoint we evaluate
after it).
- - - - -
ade3c1e6 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
BRK_FUN with InternalBreakLocs for code-generation time breakpoints
At the start of a case continuation BCO, place a BRK_FUN.
This BRK_FUN uses the new "internal breakpoint location" -- allowing us
to come up with a valid source location for this breakpoint that is not associated with a source-level tick.
For case continuation BCOs, we use the last tick seen before it as the
source location. The reasoning is described in Note [Debugger: Stepout internal break locs].
Note how T26042c, which was broken because it displayed the incorrect
behavior of the previous step out when we'd end up at a deeper level
than the one from which we initiated step-out, is now fixed.
As of this commit, BRK_ALTS is now dead code and is thus dropped.
Note [Debugger: Stepout internal break locs]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Step-out tells the interpreter to run until the current function
returns to where it was called from, and stop there.
This is achieved by enabling the BRK_FUN found on the first RET_BCO
frame on the stack (See [Note Debugger: Step-out]).
Case continuation BCOs (which select an alternative branch) must
therefore be headed by a BRK_FUN. An example:
f x = case g x of <--- end up here
1 -> ...
2 -> ...
g y = ... <--- step out from here
- `g` will return a value to the case continuation BCO in `f`
- The case continuation BCO will receive the value returned from g
- Match on it and push the alternative continuation for that branch
- And then enter that alternative.
If we step-out of `g`, the first RET_BCO on the stack is the case
continuation of `f` -- execution should stop at its start, before
selecting an alternative. (One might ask, "why not enable the breakpoint
in the alternative instead?", because the alternative continuation is
only pushed to the stack *after* it is selected by the case cont. BCO)
However, the case cont. BCO is not associated with any source-level
tick, it is merely the glue code which selects alternatives which do
have source level ticks. Therefore, we have to come up at code
generation time with a breakpoint location ('InternalBreakLoc') to
display to the user when it is stopped there.
Our solution is to use the last tick seen just before reaching the case
continuation. This is robust because a case continuation will thus
always have a relevant breakpoint location:
- The source location will be the last source-relevant expression
executed before the continuation is pushed
- So the source location will point to the thing you've just stepped
out of
- Doing :step-local from there will put you on the selected
alternative (which at the source level may also be the e.g. next
line in a do-block)
Examples, using angle brackets (<<...>>) to denote the breakpoint span:
f x = case <<g x>> {- step in here -} of
1 -> ...
2 -> ...>
g y = <<...>> <--- step out from here
...
f x = <<case g x of <--- end up here, whole case highlighted
1 -> ...
2 -> ...>>
doing :step-local ...
f x = case g x of
1 -> <<...>> <--- stop in the alternative
2 -> ...
A second example based on T26042d2, where the source is a do-block IO
action, optimised to a chain of `case expressions`.
main = do
putStrLn "hello1"
<<f>> <--- step-in here
putStrLn "hello3"
putStrLn "hello4"
f = do
<<putStrLn "hello2.1">> <--- step-out from here
putStrLn "hello2.2"
...
main = do
putStrLn "hello1"
<<f>> <--- end up here again, the previously executed expression
putStrLn "hello3"
putStrLn "hello4"
doing step/step-local ...
main = do
putStrLn "hello1"
f
<<putStrLn "hello3">> <--- straight to the next line
putStrLn "hello4"
Finishes #26042
- - - - -
c66910c0 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Re-use the last BreakpointId whole in step-out
Previously, to come up with a location to stop at for `:stepout`, we
would store the location of the last BreakpointId surrounding the
continuation, as described by Note [Debugger: Stepout internal break locs].
However, re-using just the location from the last source breakpoint
isn't sufficient to provide the necessary information in the break
location. Specifically, it wouldn't bind any variables at that location.
Really, there is no reason not to re-use the last breakpoint wholesale,
and re-use all the information we had there. Step-out should behave just
as if we had stopped at the call, but s.t. continuing will not
re-execute the call.
This commit updates the CgBreakInfo to always store a BreakpointId, be
it the original one or the one we're emulating (for step-out).
It makes variable bindings on :stepout work
- - - - -
e4abed7b by sheaf at 2025-09-02T12:20:40-04:00
Revert accidental changes to hie.yaml
- - - - -
003b715b by meooow25 at 2025-09-02T23:48:51+02:00
Adjust the strictness of Data.List.iterate'
* Don't force the next element in advance when generating a (:).
* Force the first element to WHNF like every other element.
Now every element in the output list is forced to WHNF when the (:)
containing it is forced.
CLC proposal:
https://github.com/haskell/core-libraries-committee/issues/335
- - - - -
b2f6aad0 by Simon Hengel at 2025-09-03T04:36:10-04:00
Refactoring: More consistently use logOutput, logInfo, fatalErrorMsg
- - - - -
60a16db7 by Rodrigo Mesquita at 2025-09-03T10:55:50+01:00
bytecode: Don't PUSH_L 0; SLIDE 1 1
While looking through bytecode I noticed a quite common unfortunate
pattern:
...
PUSH_L 0
SLIDE 1 1
We do this often by generically constructing a tail call from a function
atom that may be somewhere arbitrary on the stack.
However, for the special case that the function can be found directly on
top of the stack, as part of the arguments, it's plain redundant to push
then slide it.
In this commit we add a small optimisation to the generation of
tailcalls in bytecode. Simply: lookahead for the function in the stack.
If it is the first thing on the stack and it is part of the arguments
which would be dropped as we entered the tail call, then don't push then
slide it.
In a simple example (T26042b), this already produced a drastic
improvement in generated code (left is old, right is with this patch):
```diff
3c3
< 2025-07-29 10:14:02.081277 UTC
---
> 2025-07-29 10:50:36.560949 UTC
160,161c160
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
164,165d162
< PUSH_L 0
< SLIDE 1 1
175,176c172
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
179,180d174
< PUSH_L 0
< SLIDE 1 1
206,207d199
< PUSH_L 0
< SLIDE 1 1
210,211d201
< PUSH_L 0
< SLIDE 1 1
214,215d203
< PUSH_L 0
< SLIDE 1 1
218,219d205
< PUSH_L 0
< SLIDE 1 1
222,223d207
< PUSH_L 0
< SLIDE 1 1
...
600,601c566
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
604,605d568
< PUSH_L 0
< SLIDE 1 1
632,633d594
< PUSH_L 0
< SLIDE 1 1
636,637d596
< PUSH_L 0
< SLIDE 1 1
640,641d598
< PUSH_L 0
< SLIDE 1 1
644,645d600
< PUSH_L 0
< SLIDE 1 1
648,649d602
< PUSH_L 0
< SLIDE 1 1
652,653d604
< PUSH_L 0
< SLIDE 1 1
656,657d606
< PUSH_L 0
< SLIDE 1 1
660,661d608
< PUSH_L 0
< SLIDE 1 1
664,665d610
< PUSH_L 0
< SLIDE 1 1
```
I also compiled lib:Cabal to bytecode and counted the number of bytecode
lines with `find dist-newstyle -name "*.dump-BCOs" -exec wc {} +`:
with unoptimized core:
1190689 lines (before) - 1172891 lines (now)
= 17798 less redundant instructions (-1.5% lines)
with optimized core:
1924818 lines (before) - 1864836 lines (now)
= 59982 less redundant instructions (-3.1% lines)
- - - - -
8b2c72c0 by L0neGamer at 2025-09-04T06:32:03-04:00
Add Control.Monad.thenM and Control.Applicative.thenA
- - - - -
39e1b7cb by Teo Camarasu at 2025-09-04T06:32:46-04:00
ghc-internal: invert dependency of GHC.Internal.TH.Syntax on Data.Data
This means that Data.Data no longer blocks building TH.Syntax, which
allows greater parallelism in our builds.
We move the Data.Data.Data instances to Data.Data. Quasi depends on
Data.Data for one of its methods, so,
we split the Quasi/Q, etc definition out of GHC.Internal.TH.Syntax
into its own module. This has the added benefit of splitting up this
quite large module.
Previously TH.Syntax was a bottleneck when compiling ghc-internal. Now
it is less of a bottle-neck and is also slightly quicker to
compile (since it no longer contains these instances) at the cost of
making Data.Data slightly more expensive to compile.
TH.Lift which depends on TH.Syntax can also compile quicker and no
longer blocks ghc-internal finishing to compile.
Resolves #26217
-------------------------
Metric Decrease:
MultiLayerModulesTH_OneShot
T13253
T21839c
T24471
Metric Increase:
T12227
-------------------------
- - - - -
bdf82fd2 by Teo Camarasu at 2025-09-04T06:32:46-04:00
compiler: delete unused names in Builtins.Names.TH
returnQ and bindQ are no longer used in the compiler.
There was also a very old comment that referred to them that I have modernized
- - - - -
5b6a9de3 by Teo Camarasu at 2025-09-04T12:17:37+00:00
base: don't expose GHC.Num.{BigNat, Integer, Natural}
WIP
- - - - -
244 changed files:
- .gitlab-ci.yml
- compiler/GHC/Builtin/Names/TH.hs
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm/Dataflow/Label.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/Pipeline/Types.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Inline.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/TyCo/Compare.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Data/IOEnv.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Config/Core/Opt/Simplify.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Env/Types.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Types.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Parser.y
- compiler/GHC/Plugins.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Stg/Lint.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/Tc/Deriv/Generics.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs-boot
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Gen/Splice.hs-boot
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/TH.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Utils/Binary.hs
- compiler/ghc.cabal.in
- configure.ac
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/separate_compilation.rst
- ghc/GHCi/UI.hs
- hadrian/src/Rules/ToolArgs.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- libraries/base/src/Control/Applicative.hs
- libraries/base/src/Control/Monad.hs
- libraries/base/src/Data/Array/Byte.hs
- libraries/base/src/Data/Bifunctor.hs
- libraries/base/src/Data/Fixed.hs
- libraries/base/src/GHC/Num.hs
- − libraries/base/src/GHC/Num/BigNat.hs
- − libraries/base/src/GHC/Num/Integer.hs
- − libraries/base/src/GHC/Num/Natural.hs
- libraries/base/src/GHC/Stack/CloneStack.hs
- libraries/base/src/System/CPUTime/Utils.hs
- libraries/ghc-bignum/ghc-bignum.cabal
- + libraries/ghc-boot-th/GHC/Boot/TH/Monad.hs
- libraries/ghc-boot-th/GHC/Boot/TH/Ppr.hs
- libraries/ghc-boot-th/ghc-boot-th.cabal.in
- libraries/ghc-experimental/src/GHC/Stack/Annotation/Experimental.hs
- libraries/ghc-experimental/src/GHC/TypeNats/Experimental.hs
- libraries/ghc-heap/GHC/Exts/Heap/ClosureTypes.hs
- libraries/ghc-heap/GHC/Exts/Heap/Closures.hs
- + libraries/ghc-heap/GHC/Exts/Heap/Constants.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTable.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTable/Types.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hs
- libraries/ghc-heap/GHC/Exts/Heap/ProfInfo/Types.hs
- + libraries/ghc-heap/GHC/Exts/Stack/Constants.hs
- libraries/ghc-heap/GHC/Exts/Stack/Decode.hs
- libraries/ghc-heap/ghc-heap.cabal.in
- − libraries/ghc-heap/tests/stack-annotation/ann_frame004.stdout
- libraries/ghc-heap/cbits/HeapPrim.cmm → libraries/ghc-internal/cbits/HeapPrim.cmm
- libraries/ghc-heap/cbits/Stack.cmm → libraries/ghc-internal/cbits/Stack.cmm
- libraries/ghc-internal/cbits/StackCloningDecoding.cmm
- libraries/ghc-heap/cbits/Stack_c.c → libraries/ghc-internal/cbits/Stack_c.c
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/jsbits/base.js
- libraries/ghc-internal/src/GHC/Internal/Base.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs
- + libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghc-heap/GHC/Exts/Heap/Constants.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/Constants.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTable.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTable/Types.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable/Types.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTableProf.hsc
- + libraries/ghc-internal/src/GHC/Internal/Heap/ProfInfo/Types.hs
- libraries/ghc-internal/src/GHC/Internal/List.hs
- + libraries/ghc-internal/src/GHC/Internal/Stack/Annotation.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/CloneStack.hs
- libraries/ghc-heap/GHC/Exts/Stack/Constants.hsc → libraries/ghc-internal/src/GHC/Internal/Stack/Constants.hsc
- + libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- + libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- libraries/ghc-heap/tests/stack-annotation/Makefile → libraries/ghc-internal/tests/stack-annotation/Makefile
- libraries/ghc-heap/tests/stack-annotation/TestUtils.hs → libraries/ghc-internal/tests/stack-annotation/TestUtils.hs
- libraries/ghc-heap/tests/stack-annotation/all.T → libraries/ghc-internal/tests/stack-annotation/all.T
- libraries/ghc-heap/tests/stack-annotation/ann_frame001.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame001.hs
- libraries/ghc-heap/tests/stack-annotation/ann_frame001.stdout → libraries/ghc-internal/tests/stack-annotation/ann_frame001.stdout
- libraries/ghc-heap/tests/stack-annotation/ann_frame002.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame002.hs
- libraries/ghc-heap/tests/stack-annotation/ann_frame002.stdout → libraries/ghc-internal/tests/stack-annotation/ann_frame002.stdout
- libraries/ghc-heap/tests/stack-annotation/ann_frame003.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame003.hs
- libraries/ghc-heap/tests/stack-annotation/ann_frame003.stdout → libraries/ghc-internal/tests/stack-annotation/ann_frame003.stdout
- libraries/ghc-heap/tests/stack-annotation/ann_frame004.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame004.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame004.stdout
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/Run.hs
- libraries/ghci/GHCi/TH.hs
- libraries/ghci/ghci.cabal.in
- libraries/template-haskell/Language/Haskell/TH/Lib.hs
- libraries/template-haskell/Language/Haskell/TH/Quote.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- libraries/template-haskell/changelog.md
- rts/CloneStack.c
- rts/CloneStack.h
- rts/Disassembler.c
- rts/Interpreter.c
- rts/PrimOps.cmm
- rts/Profiling.c
- rts/RaiseAsync.c
- rts/RtsMessages.c
- rts/RtsSymbols.c
- rts/RtsUtils.c
- rts/STM.c
- rts/Trace.c
- rts/include/rts/Bytecodes.h
- testsuite/.gitignore
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/deriving/should_compile/T14682.stderr
- testsuite/tests/deriving/should_compile/drv-empty-data.stderr
- + testsuite/tests/driver/make-prim/GHC/Internal/Prim.hs
- + testsuite/tests/driver/make-prim/Makefile
- + testsuite/tests/driver/make-prim/Test.hs
- + testsuite/tests/driver/make-prim/Test2.hs
- + testsuite/tests/driver/make-prim/all.T
- testsuite/tests/ghci.debugger/scripts/T26042b.script
- testsuite/tests/ghci.debugger/scripts/T26042b.stdout
- testsuite/tests/ghci.debugger/scripts/T26042c.script
- testsuite/tests/ghci.debugger/scripts/T26042c.stdout
- + testsuite/tests/ghci.debugger/scripts/T26042d2.hs
- + testsuite/tests/ghci.debugger/scripts/T26042d2.script
- + testsuite/tests/ghci.debugger/scripts/T26042d2.stdout
- testsuite/tests/ghci.debugger/scripts/T26042e.stdout
- testsuite/tests/ghci.debugger/scripts/T26042f.script
- testsuite/tests/ghci.debugger/scripts/T26042f1.stdout
- testsuite/tests/ghci.debugger/scripts/T26042f2.stdout
- testsuite/tests/ghci.debugger/scripts/T26042g.stdout
- testsuite/tests/ghci.debugger/scripts/all.T
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- − testsuite/tests/lib/stm/T26028.hs
- − testsuite/tests/lib/stm/T26028.stdout
- − testsuite/tests/lib/stm/all.T
- + testsuite/tests/patsyn/should_compile/T26331.hs
- + testsuite/tests/patsyn/should_compile/T26331a.hs
- testsuite/tests/patsyn/should_compile/all.T
- testsuite/tests/perf/compiler/T4007.stdout
- testsuite/tests/plugins/plugins10.stdout
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/rts/all.T
- testsuite/tests/simplCore/should_compile/T15056.stderr
- testsuite/tests/simplCore/should_compile/T15445.stderr
- + testsuite/tests/simplCore/should_compile/T26323b.hs
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/simplCore/should_run/T26323.hs
- + testsuite/tests/simplCore/should_run/T26323.stdout
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/splice-imports/SI29.stderr
- testsuite/tests/th/Makefile
- testsuite/tests/th/T11452.stderr
- testsuite/tests/th/T15321.stderr
- testsuite/tests/th/T7276.stderr
- + testsuite/tests/th/TH_Depends_Dir.hs
- + testsuite/tests/th/TH_Depends_Dir.stdout
- + testsuite/tests/th/TH_Depends_Dir_External.hs
- testsuite/tests/th/TH_NestedSplicesFail3.stderr
- testsuite/tests/th/TH_NestedSplicesFail4.stderr
- testsuite/tests/th/all.T
- + testsuite/tests/typecheck/should_compile/T26345.hs
- + testsuite/tests/typecheck/should_compile/T26346.hs
- + testsuite/tests/typecheck/should_compile/T26350.hs
- + testsuite/tests/typecheck/should_compile/T26358.hs
- testsuite/tests/typecheck/should_compile/all.T
- + testsuite/tests/typecheck/should_fail/T26318.hs
- + testsuite/tests/typecheck/should_fail/T26318.stderr
- testsuite/tests/typecheck/should_fail/all.T
- utils/check-exact/ExactPrint.hs
- 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/0cbf4024a6bc059b8c917743dc036e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0cbf4024a6bc059b8c917743dc036e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Simon Peyton Jones pushed to branch wip/T26315 at Glasgow Haskell Compiler / GHC
Commits:
6a93a288 by Simon Peyton Jones at 2025-09-04T13:08:04+01:00
Wibbles
- - - - -
8 changed files:
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Solver/Solve.hs-boot
- compiler/GHC/Tc/Types/Evidence.hs
Changes:
=====================================
compiler/GHC/Tc/Gen/Sig.hs
=====================================
@@ -741,7 +741,7 @@ Note that
the same (Eq p) dictionary. Reason: we don't want to force them to be visibly
equal at the call site.
-* The `spec_bnrs`, which are lambda-bound in the specialised function `$sf`,
+* The `spec_bndrs`, which are lambda-bound in the specialised function `$sf`,
are a subset of `rule_bndrs`.
spec_bndrs = @p (d2::Eq p) (x::Int) (y::p)
@@ -759,7 +759,8 @@ This is done in three parts.
(1) Typecheck the expression, capturing its constraints
- (2) Solve these constraints
+ (2) Solve these constraints. When doing so, switch on `tcsmFullySolveQCIs`;
+ see wrinkle (NFS1) below.
(3) Compute the constraints to quantify over, using `getRuleQuantCts` on
the unsolved constraints returned by (2).
@@ -795,6 +796,28 @@ This is done in three parts.
of the form:
forall @a @b d1 d2 d3. f d1 d2 d3 = $sf d1 d2 d3
+(NFS1) Consider
+ f :: forall f a. (Ix a, forall x. Eq x => Eq (f x)) => a -> f a
+ {-# SPECIALISE f :: forall f. (forall x. Eq x => Eq (f x)) => Int -> f Int #-}
+ This SPECIALISE is treated like an expression with a type signature, so
+ we instantiate the constraints, simplify them and re-generalise. From the
+ instantiation we get [W] d :: (forall x. Eq a => Eq (f x))
+ and we want to generalise over that. We do not want to attempt to solve it
+ and then get stuck, and emit an error message. If we can't solve it, it is
+ much, much better to leave it alone.
+
+ We still need to simplify quantified constraints that can be /fully solved/
+ from instances, otherwise we would never be able to specialise them
+ away. Example: {-# SPECIALISE f @[] @a #-}. So:
+
+ * The constraint solver has a mode flag `tcsmFullySolveQCIs` that says
+ "fully solve quantified constraint, or leave them alone
+ * When simplifying constraints in a SPECIALISE pragma, we switch on this
+ flag the `SpecPragE` case of `tcSpecPrag`.
+
+ You might worry about the wasted work from failed attempts to fully-solve, but
+ it is seldom repeated (because the constraint solver seldom iterates much).
+
Note [Handling old-form SPECIALISE pragmas]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NB: this code path is deprecated, and is scheduled to be removed in GHC 9.18, as per #25440.
@@ -976,12 +999,11 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl)
tcInferRho spec_e
-- (2) Solve the resulting wanteds
- -- When doing so, switch on `tcsmFullySolveQCIs`; see (WFA4) in
- -- Note [Solving a Wanted forall-constraint] in GHC.Tc.Solver.Solve
; ev_binds_var <- newTcEvBinds
; spec_e_wanted <- setTcLevel rhs_tclvl $
runTcSWithEvBinds ev_binds_var $
setTcSMode (vanillaTcSMode { tcsmFullySolveQCIs = True }) $
+ -- tcsmFullySolveQCIs: see (NFS1)a
solveWanteds spec_e_wanted
; spec_e_wanted <- liftZonkM $ zonkWC spec_e_wanted
=====================================
compiler/GHC/Tc/Solver.hs
=====================================
@@ -1028,15 +1028,15 @@ findInferredDiff annotated_theta inferred_theta
; let given_loc = mkGivenLoc topTcLevel (getSkolemInfo unkSkol) (mkCtLocEnv lcl_env)
given_cts = mkGivens given_loc given_ids
- ; (residual, _) <- runTcS $
- do { _ <- solveSimpleGivens given_cts
- ; solveSimpleWanteds (listToBag (map mkNonCanonical wanteds)) }
+ ; (residual_wc, _) <- runTcS $
+ do { _ <- solveSimpleGivens given_cts
+ ; solveSimpleWanteds (listToBag (map mkNonCanonical wanteds)) }
-- NB: There are no meta tyvars fromn this level annotated_theta
-- because we have either promoted them or unified them
-- See `Note [Quantification and partial signatures]` Wrinkle 2
; return (map (box_pred . ctPred) $
- bagToList residual) }
+ bagToList (wc_simple residual_wc)) }
where
box_pred :: PredType -> PredType
box_pred pred = case classifyPredType pred of
=====================================
compiler/GHC/Tc/Solver/Default.hs
=====================================
@@ -1189,7 +1189,7 @@ tryDefaultGroup wanteds (Proposal assignments)
| CtWanted wtd <- map ctEvidence wanteds
]
; residual <- solveSimpleWanteds (listToBag new_wanteds)
- ; return $ if isEmptyBag residual then Just (tvs, subst) else Nothing }
+ ; return $ if isEmptyWC residual then Just (tvs, subst) else Nothing }
| otherwise
= return Nothing
=====================================
compiler/GHC/Tc/Solver/Dict.hs
=====================================
@@ -834,7 +834,7 @@ tryShortCutSolver try_short_cut dict_w@(DictCt { di_ev = ev_w })
-> tryShortCutTcS $ -- tryTcS tries to completely solve some contraints
do { residual <- solveSimpleWanteds (unitBag (CDictCan dict_w))
- ; return (isEmptyBag residual) }
+ ; return (isEmptyWC residual) }
| otherwise
-> return False }
=====================================
compiler/GHC/Tc/Solver/Monad.hs
=====================================
@@ -196,9 +196,11 @@ import GHC.Types.Unique.Set( elementOfUniqSet )
import GHC.Types.Id
import GHC.Types.Basic (allImportLevels)
import GHC.Types.ThLevelIndex (thLevelIndexFromImportLevel)
+import GHC.Types.SrcLoc
import GHC.Unit.Module
import qualified GHC.Rename.Env as TcM
+import GHC.Rename.Env
import GHC.Utils.Outputable
import GHC.Utils.Panic
@@ -213,12 +215,11 @@ import GHC.Exts (oneShot)
import Control.Monad
import Data.Foldable hiding ( foldr1 )
import Data.IORef
+import Data.Maybe( catMaybes )
import Data.List ( mapAccumL )
import Data.List.NonEmpty ( nonEmpty )
import qualified Data.List.NonEmpty as NE
import qualified Data.Semigroup as S
-import GHC.Types.SrcLoc
-import GHC.Rename.Env
import GHC.LanguageExtensions as LangExt
#if defined(DEBUG)
@@ -920,11 +921,14 @@ vanillaTcSMode = TcSMode { tcsmPmCheck = False
instance Outputable TcSMode where
ppr (TcSMode { tcsmPmCheck = pm, tcsmEarlyAbort = ea
, tcsmSkipOverlappable = so, tcsmFullySolveQCIs = fs })
- = text "TcSMode" <> (braces $
- text "pm=" <> ppr pm <> comma <>
- text "ea=" <> ppr ea <> comma <>
- text "so=" <> ppr so <> comma <>
- text "fs=" <> ppr fs)
+ = text "TcSMode" <> (braces $ cat $ punctuate comma $ catMaybes $
+ [ pp_one pm "PmCheck", pp_one ea "EarlyAbort"
+ , pp_one so "SkipOverlappable", pp_one fs "FullySolveQCIs" ])
+ -- We get something like TcSMode{EarlyAbort,FullySolveQCIs},
+ -- mentioning just the flags that are on
+ where
+ pp_one True s = Just (text s)
+ pp_one False _ = Nothing
{- Note [TcSMode]
~~~~~~~~~~~~~~~~~
=====================================
compiler/GHC/Tc/Solver/Solve.hs
=====================================
@@ -119,22 +119,18 @@ simplify_loop n limit definitely_redo_implications
, int (lengthBag simples) <+> text "simples to solve" ])
; traceTcS "simplify_loop: wc =" (ppr wc)
- ; (unifs1, simples1) <- reportUnifications $ -- See Note [Superclass iteration]
- solveSimpleWanteds simples
+ ; (unifs1, wc1) <- reportUnifications $ -- See Note [Superclass iteration]
+ solveSimpleWanteds simples
-- Any insoluble constraints are in 'simples' and so get rewritten
-- See Note [Rewrite insolubles] in GHC.Tc.Solver.InertSet
- -- Now try to solve any Wanted QCInsts in `simples1`
- ; (simples', implics_from_qcis) <- solveWantedQCIs simples1
-
-- Next, solve implications from wc_impl
; implics' <- if not definitely_redo_implications -- See Note [Superclass iteration]
&& unifs1 == 0 -- for this conditional
then return implics
else solveNestedImplications implics
- ; let wc' = wc { wc_simple = simples'
- , wc_impl = implics' `unionBags` implics_from_qcis }
+ ; let wc' = wc1 { wc_impl = wc_impl wc1 `unionBags` implics' }
; unif_happened <- resetUnificationFlag
; csTraceTcS $ text "unif_happened" <+> ppr unif_happened
@@ -1020,7 +1016,9 @@ solveSimpleGivens givens
; when (notNull new_givens) $
go new_givens }
-solveSimpleWanteds :: Cts -> TcS Cts
+solveSimpleWanteds :: Cts -> TcS WantedConstraints
+-- Returns unsolved constraints, mostly just flat ones (Cts),
+-- but also any unsolved implications arising from forall-constraints
-- The result is not necessarily zonked
solveSimpleWanteds simples
= do { mode <- getTcSMode
@@ -1032,43 +1030,59 @@ solveSimpleWanteds simples
, text "Inerts:" <+> ppr inerts
, text "Wanteds to solve:" <+> ppr simples ]
- ; (n,wc) <- go 1 (solverIterations dflags) simples
+ ; (n,simples',implics') <- go (solverIterations dflags) 1 emptyBag simples
+
+ ; let unsolved_wc = emptyWC { wc_simple = simples', wc_impl = implics' }
; traceTcS "solveSimpleWanteds end }" $
vcat [ text "iterations =" <+> ppr n
- , text "residual =" <+> ppr wc ]
- ; return wc }
+ , text "residual =" <+> ppr unsolved_wc ]
+
+ ; return unsolved_wc }
where
- go :: Int -> IntWithInf -> Cts -> TcS (Int, Cts)
+ go :: IntWithInf -- Limit
+ -> Int -- Iteration number
+ -> Bag Implication -- Accumulating parameter: unsolved implications
+ -> Cts -- Try to solve these
+ -> TcS (Int, Cts, Bag Implication)
-- See Note [The solveSimpleWanteds loop]
- go n limit wc
+ go limit n implics wanted
| n `intGtLimit` limit
= failTcS $ TcRnSimplifierTooManyIterations
- simples limit (emptyWC { wc_simple = wc })
- | isEmptyBag wc
- = return (n,wc)
+ simples limit
+ (emptyWC { wc_simple = wanted, wc_impl = implics })
+
+ | isEmptyBag wanted
+ = return (n, wanted, implics)
+
| otherwise
= do { -- Solve
- wc1 <- solve_simple_wanteds wc
+ (wanted1, implics1) <- solve_one wanted
+ ; let implics2 = implics `unionBags` implics1
-- Run plugins
- -- NB: runTcPluginsWanted has a fast path for empty wc1,
- -- which is the common case
- ; (rerun_plugin, wc2) <- runTcPluginsWanted wc1
+ -- NB: runTcPluginsWanted has a fast path for
+ -- empty wanted1, which is the common case
+ ; (rerun_plugin, wanted2) <- runTcPluginsWanted wanted1
; if rerun_plugin
then do { traceTcS "solveSimple going round again:" (ppr rerun_plugin)
- ; go (n+1) limit wc2 } -- Loop
- else return (n, wc2) } -- Done
+ ; go limit (n+1) implics2 wanted2 } -- Loop
+ else return (n, wanted2, implics2) } -- Done
-solve_simple_wanteds :: Cts -> TcS Cts
--- Try solving these constraints
--- Affects the unification state (of course) but not the inert set
--- The result is not necessarily zonked
-solve_simple_wanteds simples
- = nestTcS $ do { solveSimples simples
- ; getUnsolvedInerts }
+ solve_one :: Cts -> TcS (Cts, Bag Implication)
+ -- Try solving these constraints
+ -- Affects the unification state (of course) but not the inert set
+ -- The result is not necessarily zonked
+ solve_one simples
+ = nestTcS $
+ do { solveSimples simples
+ ; simples' <- getUnsolvedInerts
+ -- Now try to solve any Wanted quantified
+ -- constraints (i.e. QCInsts) in `simples1`
+ ; solveWantedQCIs simples' }
+
{- Note [The solveSimpleWanteds loop]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1320,25 +1334,24 @@ where <binds> is filled in by solving the implication constraint.
What we actually do is this:
* In `solveForAll` we see if we have an identical quantified constraint
- to solve it (using tryInertQCs), and then just add it to `inert_qcis :: [QCInst]`
- See Note [Solving Wanted QCs from Given QCs]
+ to solve it (using tryInertQCs). In particular, solve a Wanted QCI
+ from an identical Given. This is more than a simple optimisation:
+ see Note [Solving Wanted QCs from Given QCs]
-* In the main solver loop, `GHC.Tc.Solver.Solve.simplify_loop`:
+ If not, just stash it in `inert_qcis :: [QCInst]`. (If it's a Given
+ we can use it to solve other constraints; if a Wanted we will solve
+ it later using `solveWantedQCIs`.)
- - We attempt to solve the `wc_simple` constraints with `solveSimpleWanteds`
- Unsolved quantified constraints just accumulate in the `inert_qcis` field
- of the `InertSet`.
+* In the main `solveSimpleWanteds` (specifically `solve_one`):
- - Then we use `solveWantedQCIs` to solve any quantified constraints. It usually
- turns the `QCInst` into an `Implication`; but not invariably (WFA4)
+ - We attempt to solve the `wc_simple` constraints with `solveSimples`
+ Unsolved quantified constraints just accumulate in the `inert_qcis` field
+ of the `InertSet`.
-Wrinkles:
+ - Then we use `solveWantedQCIs` to solve any quantified constraints. That
+ often turns the `QCInst` into an `Implication`; but not invariably (WFA4)
-(WFA1) We can take a more straightforward path when there is a matching Given, e.g.
- [W] dg :: forall c d. (Eq c, Ord d) => C x c d
- In this case, it's better to directly solve the Wanted from the Given, instead
- of building an implication. This is more than a simple optimisation; see
- Note [Solving Wanted QCs from Given QCs].
+Wrinkles:
(WFA2) Termination: see #19690. We want to maintain the invariant (QC-INV):
@@ -1364,27 +1377,9 @@ Wrinkles:
So the `IsQC` origin carries that info, and `GHC.Tc.Errors.Ppr.pprQCOriginExtra`
prints the extra info.
-(WFA4) Consider
- f :: forall f a. (Ix a, forall x. Eq x => Eq (f x)) => a -> f a
- {-# SPECIALISE f :: forall f. (forall x. Eq x => Eq (f x)) => Int -> f Int #-}
- This SPECIALISE is treated like an expression with a type signature, so
- we instantiate the constraints, simplify them and re-generalise. From the
- instantiation we get [W] d :: (forall x. Eq a => Eq (f x))
- and we want to generalise over that. We do not want to attempt to solve it
- and then get stuck, and emit an error message. If we can't solve it, it is
- much, much better to leave it alone.
-
- We still need to simplify quantified constraints that can be /fully solved/
- from instances, otherwise we would never be able to specialise them
- away. Example: {-# SPECIALISE f @[] @a #-}. So:
-
- * The constraint solver has a mode flag `tcsmFullySolveQCIs` that says
- "fully solve quantified constraint, or leave them alone
- * When simplifying constraints in a SPECIALISE pragma, we switch on this
- flag (see `GHC.Tc.Gen.Sig.tcSpecPrag`, the `SpecSigE` case).
-
- You might worry about the wasted work from failed attempts to fully-solve, but
- it is seldom repeated (because the constraint solver seldom iterates much).
+(WFA4) When `tcsmFullySolveQCIs` is on, we adopt an all-or-nothing strategy:
+ either solve the forall-constraint /fully/ or do nothing at all.
+ Why? See (NFS1) in Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig
(WFA5) Why not /always/ us the all-or-nothing strategy, so we don't need a
flag? Several reasons:
@@ -1579,7 +1574,7 @@ solveWantedQCI mode ct@(CQuantCan (QCI { qci_ev = ev, qci_tvs = tvs
return (Left ct)
| otherwise
- -> -- Commit to the (partuly or fully solved) implication
+ -> -- Commit to the (partly or fully solved) implication
-- See (WFA5) in Note [Solving a Wanted forall-constraint]
-- Record evidence and return residual implication
-- NB: even if it is fully solved we must return it, because it is
=====================================
compiler/GHC/Tc/Solver/Solve.hs-boot
=====================================
@@ -2,7 +2,7 @@ module GHC.Tc.Solver.Solve where
import Prelude( Bool )
import GHC.Tc.Solver.Monad( TcS )
-import GHC.Tc.Types.Constraint( Cts, Implication )
+import GHC.Tc.Types.Constraint( Cts, Implication, WantedConstraints )
-solveSimpleWanteds :: Cts -> TcS Cts
+solveSimpleWanteds :: Cts -> TcS WantedConstraints
trySolveImplication :: Implication -> TcS Bool
=====================================
compiler/GHC/Tc/Types/Evidence.hs
=====================================
@@ -956,7 +956,14 @@ nestedEvIdsOfTerm tm = fvVarSet (filterFV isNestedEvId (evTermFVs tm))
evTermFVs :: EvTerm -> FV
evTermFVs (EvExpr e) = exprFVs e
evTermFVs (EvTypeable _ ev) = evFVsOfTypeable ev
-evTermFVs (EvFun {}) = emptyFV -- See Note [Free vars of EvFun]
+evTermFVs (EvFun { et_tvs = tvs, et_given = given
+ , et_binds = tc_ev_binds, et_body = v })
+ = case tc_ev_binds of
+ TcEvBinds {} -> emptyFV -- See Note [Free vars of EvFun]
+ EvBinds binds -> addBndrsFV bndrs fvs
+ where
+ fvs = foldr (unionFV . evTermFVs . eb_rhs) (unitFV v) binds
+ bndrs = foldr ((:) . eb_lhs) (tvs ++ given) binds
evTermFVss :: [EvTerm] -> FV
evTermFVss = mapUnionFV evTermFVs
@@ -975,12 +982,15 @@ Finding the free vars of an EvFun is made tricky by the fact the
bindings et_binds may be a mutable variable. Fortunately, we
can just squeeze by. Here's how.
-* evTermFVs is used only by GHC.Tc.Solver.neededEvVars.
-* Each EvBindsVar in an et_binds field of an EvFun is /also/ in the
- ic_binds field of an Implication
-* So we can track usage via the processing for that implication,
- (see Note [Tracking redundant constraints] in GHC.Tc.Solver).
- We can ignore usage from the EvFun altogether.
+* /During/ typechecking, `evTermFVs` is used only by `GHC.Tc.Solver.neededEvVars`
+ * Each EvBindsVar in an et_binds field of an EvFun is /also/ in the
+ ic_binds field of an Implication
+ * So we can track usage via the processing for that implication,
+ (see Note [Tracking redundant constraints] in GHC.Tc.Solver).
+ We can ignore usage from the EvFun altogether.
+
+* /After/ typechecking `evTermFVs` is used by `GHC.Iface.Ext.Ast`, but by
+ then it has been zonked so we can get at the bindings.
-}
{- *********************************************************************
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a93a2883a2fba1653de0ea71ea57c6…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a93a2883a2fba1653de0ea71ea57c6…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Simon Peyton Jones pushed to branch wip/T26369 at Glasgow Haskell Compiler / GHC
Commits:
2897da11 by Simon Peyton Jones at 2025-09-04T12:58:10+01: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.
- - - - -
22 changed files:
- 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/Opt/Arity.hs
- compiler/GHC/Core/Reduction.hs
- compiler/GHC/Core/TyCo/FVs.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/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Types/Id/Make.hs
- testsuite/tests/simplCore/should_compile/OpaqueNoCastWW.stderr
Changes:
=====================================
compiler/GHC/Core/Coercion.hs
=====================================
@@ -47,7 +47,7 @@ module GHC.Core.Coercion (
mkProofIrrelCo,
downgradeRole,
mkGReflRightCo, mkGReflLeftCo, mkCoherenceLeftCo, mkCoherenceRightCo,
- mkKindCo,
+ mkKindCo, forAllCoKindCo,
castCoercionKind, castCoercionKind1, castCoercionKind2,
-- ** Decomposition
@@ -66,11 +66,14 @@ module GHC.Core.Coercion (
tyConRoleListX, tyConRoleListRepresentational, funRole,
pickLR,
- isGReflCo, isReflCo, isReflCo_maybe, isGReflCo_maybe, isReflexiveCo, isReflexiveCo_maybe,
- isReflCoVar_maybe, isGReflMCo, mkGReflLeftMCo, mkGReflRightMCo,
+ isReflKindCo,isReflKindMCo,
+ isReflCo, isReflCo_maybe,
+ isReflexiveMCo, isReflexiveCo, isReflexiveCo_maybe,
+ isReflCoVar_maybe, mkGReflLeftMCo, mkGReflRightMCo,
mkCoherenceRightMCo,
- coToMCo, mkTransMCo, mkTransMCoL, mkTransMCoR, mkCastTyMCo, mkSymMCo,
+ coToMCo, kindCoToMKindCo,
+ mkTransMCo, mkTransMCoL, mkTransMCoR, mkCastTyMCo, mkSymMCo,
mkFunResMCo, mkPiMCos,
isReflMCo, checkReflexiveMCo,
@@ -85,7 +88,7 @@ module GHC.Core.Coercion (
-- ** Substitution
CvSubstEnv, emptyCvSubstEnv,
lookupCoVar,
- substCo, substCos, substCoVar, substCoVars, substCoWith,
+ substCo, substCos, substCoVar, substCoVars, substCoWithInScope,
substCoVarBndr,
extendTvSubstAndInScope, getCvSubstEnv,
@@ -317,23 +320,23 @@ coToMCo :: Coercion -> MCoercion
coToMCo co | isReflCo co = MRefl
| otherwise = MCo co
+kindCoToMKindCo :: KindCoercion -> KindMCoercion
+-- Convert a KindCoercion to a KindMCoercion,
+-- coToMCo doesn't eliminate GRefl, but kindCoToMCo can
+-- See Note [KindCoercion]
+kindCoToMKindCo co | isReflKindCo co = MRefl
+ | otherwise = MCo co
+
checkReflexiveMCo :: MCoercion -> MCoercion
checkReflexiveMCo MRefl = MRefl
checkReflexiveMCo (MCo co) | isReflexiveCo co = MRefl
| otherwise = MCo co
--- | Tests if this MCoercion is obviously generalized reflexive
--- Guaranteed to work very quickly.
-isGReflMCo :: MCoercion -> Bool
-isGReflMCo MRefl = True
-isGReflMCo (MCo co) | isGReflCo co = True
-isGReflMCo _ = False
-
-- | Make a generalized reflexive coercion
mkGReflCo :: Role -> Type -> MCoercionN -> Coercion
mkGReflCo r ty mco
- | isGReflMCo mco = if r == Nominal then Refl ty
- else GRefl r ty MRefl
+ | isReflKindMCo mco = if r == Nominal then Refl ty
+ else GRefl r ty MRefl
| otherwise
= -- I'd like to have this assert, but sadly it's not true during type
-- inference because the types are not fully zonked
@@ -565,10 +568,13 @@ splitFunCo_maybe :: Coercion -> Maybe (Coercion, Coercion)
splitFunCo_maybe (FunCo { fco_arg = arg, fco_res = res }) = Just (arg, res)
splitFunCo_maybe _ = Nothing
-splitForAllCo_maybe :: Coercion -> Maybe (TyCoVar, ForAllTyFlag, ForAllTyFlag, Coercion, Coercion)
+splitForAllCo_maybe :: Coercion
+ -> Maybe (TyCoVar, ForAllTyFlag, ForAllTyFlag, KindCoercion, Coercion)
+-- You might think that this function should return KindMCoercion (rather
+-- than a KindCoercion), but in fact most of the clients want a KindCoercion.
splitForAllCo_maybe (ForAllCo { fco_tcv = tv, fco_visL = vL, fco_visR = vR
- , fco_kind = k_co, fco_body = co })
- = Just (tv, vL, vR, k_co, co)
+ , fco_kind = k_mco, fco_body = co })
+ = Just (tv, vL, vR, forAllCoKindCo tv k_mco, co)
splitForAllCo_maybe co
| Just (ty, r) <- isReflCo_maybe co
, Just (Bndr tcv vis, body_ty) <- splitForAllForAllTyBinder_maybe ty
@@ -576,7 +582,8 @@ splitForAllCo_maybe co
splitForAllCo_maybe _ = Nothing
-- | Like 'splitForAllCo_maybe', but only returns Just for tyvar binder
-splitForAllCo_ty_maybe :: Coercion -> Maybe (TyVar, ForAllTyFlag, ForAllTyFlag, Coercion, Coercion)
+splitForAllCo_ty_maybe :: Coercion
+ -> Maybe (TyVar, ForAllTyFlag, ForAllTyFlag, KindCoercion, Coercion)
splitForAllCo_ty_maybe co
| Just stuff@(tv, _, _, _, _) <- splitForAllCo_maybe co
, isTyVar tv
@@ -584,7 +591,8 @@ splitForAllCo_ty_maybe co
splitForAllCo_ty_maybe _ = Nothing
-- | Like 'splitForAllCo_maybe', but only returns Just for covar binder
-splitForAllCo_co_maybe :: Coercion -> Maybe (CoVar, ForAllTyFlag, ForAllTyFlag, Coercion, Coercion)
+splitForAllCo_co_maybe :: Coercion
+ -> Maybe (CoVar, ForAllTyFlag, ForAllTyFlag, KindCoercion, Coercion)
splitForAllCo_co_maybe co
| Just stuff@(cv, _, _, _, _) <- splitForAllCo_maybe co
, isCoVar cv
@@ -676,34 +684,50 @@ isReflCoVar_maybe cv
| otherwise
= Nothing
--- | Tests if this coercion is obviously a generalized reflexive coercion.
+-- | Tests whether this is a "kind coercion":
+-- that is, Nominal and between two types of kind @Type@.
+-- See Note [KindCoercion] in GHC.Core.TyCo.Rep
+isKindCo :: Coercion -> Bool
+isKindCo co
+ = role == Nominal && isLiftedTypeKind kk1 && isLiftedTypeKind kk2
+ where
+ (Pair kk1 kk2, role) = coercionKindRole co
+
+-- | Tests if this /kind/ coercion is Refl
+-- Guaranteed to work very quickly.
+-- PRECONDITION: the argument is a KindCoercion
+-- So if it sees (GRefl k (MCo kk)) :: k ~ (k |> kk)
+-- then we know that kk must be reflexive.
+-- And hence if co = GRefl {} then it is equivalent to Refl,
+-- because GRefl N ty MRefl = Refl ty
+-- so we return True
+-- See Note [KindCoercion] in GHC.Core.TyCo.Rep
+isReflKindCo :: HasDebugCallStack => KindCoercion -> Bool
+isReflKindCo co@(GRefl {}) = assertPpr (isKindCo co) (ppr co) $
+ True
+isReflKindCo (Refl{}) = True -- Refl ty == GRefl N ty MRefl
+isReflKindCo _ = False
+
+-- | Tests if this /kind/ MCoercion is obviously generalized reflexive
-- Guaranteed to work very quickly.
-isGReflCo :: Coercion -> Bool
-isGReflCo (GRefl{}) = True
-isGReflCo (Refl{}) = True -- Refl ty == GRefl N ty MRefl
-isGReflCo _ = False
+isReflKindMCo :: KindMCoercion -> Bool
+isReflKindMCo MRefl = True
+isReflKindMCo (MCo co) = isReflKindCo co
-- | Tests if this coercion is obviously reflexive. Guaranteed to work
-- very quickly. Sometimes a coercion can be reflexive, but not obviously
-- so. c.f. 'isReflexiveCo'
isReflCo :: Coercion -> Bool
isReflCo (Refl{}) = True
-isReflCo (GRefl _ _ mco) | isGReflMCo mco = True
+isReflCo (GRefl _ _ mco) | isReflKindMCo mco = True
isReflCo _ = False
--- | Returns the type coerced if this coercion is a generalized reflexive
--- coercion. Guaranteed to work very quickly.
-isGReflCo_maybe :: Coercion -> Maybe (Type, Role)
-isGReflCo_maybe (GRefl r ty _) = Just (ty, r)
-isGReflCo_maybe (Refl ty) = Just (ty, Nominal)
-isGReflCo_maybe _ = Nothing
-
-- | Returns the type coerced if this coercion is reflexive. Guaranteed
-- to work very quickly. Sometimes a coercion can be reflexive, but not
-- obviously so. c.f. 'isReflexiveCo_maybe'
isReflCo_maybe :: Coercion -> Maybe (Type, Role)
isReflCo_maybe (Refl ty) = Just (ty, Nominal)
-isReflCo_maybe (GRefl r ty mco) | isGReflMCo mco = Just (ty, r)
+isReflCo_maybe (GRefl r ty mco) | isReflKindMCo mco = Just (ty, r)
isReflCo_maybe _ = Nothing
-- | Slowly checks if the coercion is reflexive. Don't call this in a loop,
@@ -711,11 +735,15 @@ isReflCo_maybe _ = Nothing
isReflexiveCo :: Coercion -> Bool
isReflexiveCo = isJust . isReflexiveCo_maybe
+isReflexiveMCo :: MCoercion -> Bool
+isReflexiveMCo MRefl = True
+isReflexiveMCo (MCo co) = isReflexiveCo co
+
-- | Extracts the coerced type from a reflexive coercion. This potentially
-- walks over the entire coercion, so avoid doing this in a loop.
isReflexiveCo_maybe :: Coercion -> Maybe (Type, Role)
isReflexiveCo_maybe (Refl ty) = Just (ty, Nominal)
-isReflexiveCo_maybe (GRefl r ty mco) | isGReflMCo mco = Just (ty, r)
+isReflexiveCo_maybe (GRefl r ty mco) | isReflKindMCo mco = Just (ty, r)
isReflexiveCo_maybe co
| ty1 `eqType` ty2
= Just (ty1, r)
@@ -723,6 +751,10 @@ isReflexiveCo_maybe co
= Nothing
where (Pair ty1 ty2, r) = coercionKindRole co
+forAllCoKindCo :: TyCoVar -> KindMCoercion -> KindCoercion
+-- Get the kind coercion from a ForAllCo
+forAllCoKindCo _ (MCo co) = co
+forAllCoKindCo tcv MRefl = mkNomReflCo (varType tcv)
{-
%************************************************************************
@@ -939,10 +971,11 @@ mkAppCos co1 cos = foldl' mkAppCo co1 cos
-- | Make a Coercion from a tycovar, a kind coercion, and a body coercion.
-mkForAllCo :: HasDebugCallStack => TyCoVar -> ForAllTyFlag -> ForAllTyFlag -> CoercionN -> Coercion -> Coercion
+mkForAllCo :: HasDebugCallStack => TyCoVar -> ForAllTyFlag -> ForAllTyFlag
+ -> KindMCoercion -> Coercion -> Coercion
mkForAllCo v visL visR kind_co co
| Just (ty, r) <- isReflCo_maybe co
- , isReflCo kind_co
+ , isReflMCo kind_co
, visL `eqForAllVis` visR
= mkReflCo r (mkTyCoForAllTy v visL ty)
@@ -955,8 +988,7 @@ mkForAllCo v visL visR kind_co co
mkForAllVisCos :: HasDebugCallStack => [ForAllTyBinder] -> Coercion -> Coercion
mkForAllVisCos bndrs orig_co = foldr go orig_co bndrs
where
- go (Bndr tv vis)
- = mkForAllCo tv coreTyLamForAllTyFlag vis (mkNomReflCo (varType tv))
+ go (Bndr tv vis) = mkForAllCo tv coreTyLamForAllTyFlag vis MRefl
-- | Make a Coercion quantified over a type/coercion variable;
-- the variable has the same kind and visibility in both sides of the coercion
@@ -967,29 +999,30 @@ mkHomoForAllCos vs orig_co
| otherwise
= foldr go orig_co vs
where
- go (Bndr var vis) co
- = mkForAllCo_NoRefl var vis vis (mkNomReflCo (varType var)) co
+ go :: ForAllTyBinder -> Coercion -> Coercion
+ go (Bndr var vis) = mkForAllCo_NoRefl var vis vis MRefl
-- | Like 'mkForAllCo', but there is no need to check that the inner coercion isn't Refl;
-- the caller has done that. (For example, it is guaranteed in 'mkHomoForAllCos'.)
-- The kind of the tycovar should be the left-hand kind of the kind coercion.
-mkForAllCo_NoRefl :: TyCoVar -> ForAllTyFlag -> ForAllTyFlag -> CoercionN -> Coercion -> Coercion
+mkForAllCo_NoRefl :: TyCoVar -> ForAllTyFlag -> ForAllTyFlag
+ -> KindMCoercion -> Coercion -> Coercion
mkForAllCo_NoRefl tcv visL visR kind_co co
= assertGoodForAllCo tcv visL visR kind_co co $
- assertPpr (not (isReflCo co && isReflCo kind_co && visL == visR)) (ppr co) $
+ assertPpr (not (isReflCo co && isReflMCo kind_co && visL == visR)) (ppr co) $
ForAllCo { fco_tcv = tcv, fco_visL = visL, fco_visR = visR
, fco_kind = kind_co, fco_body = co }
assertGoodForAllCo :: HasDebugCallStack
- => TyCoVar -> ForAllTyFlag -> ForAllTyFlag
- -> CoercionN -> Coercion -> a -> a
+ => TyCoVar -> ForAllTyFlag -> ForAllTyFlag
+ -> KindMCoercion -> Coercion -> a -> a
-- Check ForAllCo invariants; see Note [ForAllCo] in GHC.Core.TyCo.Rep
assertGoodForAllCo tcv visL visR kind_co co
| isTyVar tcv
- = assertPpr (tcv_type `eqType` kind_co_lkind) doc
+ = assertPpr tcv_kind_co_agree doc
| otherwise
- = assertPpr (tcv_type `eqType` kind_co_lkind) doc
+ = assertPpr tcv_kind_co_agree doc
-- The kind of the tycovar should be the left-hand kind of the kind coercion.
. assertPpr (almostDevoidCoVarOfCo tcv co) doc
-- See (FC6) in Note [ForAllCo] in GHC.Core.TyCo.Rep
@@ -998,13 +1031,17 @@ assertGoodForAllCo tcv visL visR kind_co co
-- See (FC7) in Note [ForAllCo] in GHC.Core.TyCo.Rep
where
tcv_type = varType tcv
- kind_co_lkind = coercionLKind kind_co
+ tcv_kind_co_agree = case kind_co of
+ MRefl -> True
+ MCo co -> tcv_type `eqType` coercionLKind co
doc = vcat [ text "Var:" <+> ppr tcv <+> dcolon <+> ppr tcv_type
, text "Vis:" <+> ppr visL <+> ppr visR
- , text "kind_co:" <+> ppr kind_co
- , text "kind_co_lkind" <+> ppr kind_co_lkind
+ , text "kind_co:" <+> pp_kind_co
, text "body_co" <+> ppr co ]
+ pp_kind_co = case kind_co of
+ MRefl -> text "MRefl"
+ MCo co -> ppr co <+> dcolon <+> ppr (coercionKind co)
mkNakedForAllCo :: TyVar -- Never a CoVar
@@ -1024,7 +1061,7 @@ mkNakedForAllCo tv visL visR kind_co co
= mkReflCo r (mkForAllTy (Bndr tv visL) ty)
| otherwise
= ForAllCo { fco_tcv = tv, fco_visL = visL, fco_visR = visR
- , fco_kind = kind_co, fco_body = co }
+ , fco_kind = MCo kind_co, fco_body = co }
mkCoVarCo :: CoVar -> Coercion
@@ -1149,7 +1186,7 @@ mkSymCo co | isReflCo co = co
mkSymCo (SymCo co) = co
mkSymCo (SubCo (SymCo co)) = SubCo co
mkSymCo co@(ForAllCo { fco_kind = kco, fco_body = body_co })
- | isReflCo kco = co { fco_body = mkSymCo body_co }
+ | isReflMCo kco = co { fco_body = mkSymCo body_co }
mkSymCo co = SymCo co
-- | mkTransCo creates a new 'Coercion' by composing the two
@@ -1193,8 +1230,8 @@ mkSelCo_maybe cs co
go cs co
where
- go SelForAll (ForAllCo { fco_kind = kind_co })
- = Just kind_co
+ go SelForAll (ForAllCo { fco_tcv = tcv, fco_kind = kind_co })
+ = Just (forAllCoKindCo tcv kind_co)
-- If co :: (forall a1:k1. t1) ~ (forall a2:k2. t2)
-- then (nth SelForAll co :: k1 ~N k2)
-- If co :: (forall a1:t1 ~ t2. t1) ~ (forall a2:t3 ~ t4. t2)
@@ -1312,46 +1349,45 @@ mkInstCo :: Coercion -> CoercionN -> Coercion
mkInstCo co_fun co_arg
| Just (tcv, _, _, kind_co, body_co) <- splitForAllCo_maybe co_fun
, Just (arg, _) <- isReflCo_maybe co_arg
+ , let in_scope = mkInScopeSet $
+ tyCoVarsOfType arg `unionVarSet` tyCoVarsOfCo body_co
+ subst = extendTCvSubst (mkEmptySubst in_scope) tcv arg
= assertPpr (isReflexiveCo kind_co) (ppr co_fun $$ ppr co_arg) $
-- If the arg is Refl, then kind_co must be reflexive too
- substCoUnchecked (zipTCvSubst [tcv] [arg]) body_co
+ substCo subst body_co
mkInstCo co arg = InstCo co arg
-- | Given @ty :: k1@, @co :: k1 ~ k2@,
-- produces @co' :: ty ~r (ty |> co)@
-mkGReflRightCo :: Role -> Type -> CoercionN -> Coercion
+mkGReflRightCo :: Role -> Type -> KindCoercion -> Coercion
mkGReflRightCo r ty co
- | isGReflCo co = mkReflCo r ty
- -- the kinds of @k1@ and @k2@ are the same, thus @isGReflCo@
- -- instead of @isReflCo@
- | otherwise = mkGReflMCo r ty co
+ | isReflKindCo co = mkReflCo r ty -- Homo (tested) AND nominal (I promise) => Refl
+ | otherwise = mkGReflMCo r ty co
-- | Given @r@, @ty :: k1@, and @co :: k1 ~N k2@,
-- produces @co' :: (ty |> co) ~r ty@
-mkGReflLeftCo :: Role -> Type -> CoercionN -> Coercion
+mkGReflLeftCo :: Role -> Type -> KindCoercion -> Coercion
mkGReflLeftCo r ty co
- | isGReflCo co = mkReflCo r ty
- -- the kinds of @k1@ and @k2@ are the same, thus @isGReflCo@
- -- instead of @isReflCo@
- | otherwise = mkSymCo $ mkGReflMCo r ty co
+ | isReflKindCo co = mkReflCo r ty
+ | otherwise = mkSymCo $ mkGReflMCo r ty co
-- | Given @ty :: k1@, @co :: k1 ~ k2@, @co2:: ty ~r ty'@,
-- produces @co' :: (ty |> co) ~r ty'
-- It is not only a utility function, but it saves allocation when co
-- is a GRefl coercion.
-mkCoherenceLeftCo :: Role -> Type -> CoercionN -> Coercion -> Coercion
+mkCoherenceLeftCo :: Role -> Type -> KindCoercion -> Coercion -> Coercion
mkCoherenceLeftCo r ty co co2
- | isGReflCo co = co2
- | otherwise = (mkSymCo $ mkGReflMCo r ty co) `mkTransCo` co2
+ | isReflKindCo co = co2
+ | otherwise = (mkSymCo $ mkGReflMCo r ty co) `mkTransCo` co2
-- | Given @ty :: k1@, @co :: k1 ~ k2@, @co2:: ty' ~r ty@,
-- produces @co' :: ty' ~r (ty |> co)
-- It is not only a utility function, but it saves allocation when co
-- is a GRefl coercion.
-mkCoherenceRightCo :: HasDebugCallStack => Role -> Type -> CoercionN -> Coercion -> Coercion
+mkCoherenceRightCo :: HasDebugCallStack => Role -> Type -> KindCoercion -> Coercion -> Coercion
mkCoherenceRightCo r ty co co2
- | isGReflCo co = co2
- | otherwise = co2 `mkTransCo` mkGReflMCo r ty co
+ | isReflKindCo co = co2
+ | otherwise = co2 `mkTransCo` mkGReflMCo r ty co
-- | Given @co :: (a :: k) ~ (b :: k')@ produce @co' :: k ~ k'@.
mkKindCo :: Coercion -> Coercion
@@ -1411,18 +1447,19 @@ downgradeRole r1 r2 co
Nothing -> pprPanic "downgradeRole" (ppr co)
-- | Make a "coercion between coercions".
-mkProofIrrelCo :: Role -- ^ role of the created coercion, "r"
- -> CoercionN -- ^ :: phi1 ~N phi2
- -> Coercion -- ^ g1 :: phi1
- -> Coercion -- ^ g2 :: phi2
- -> Coercion -- ^ :: g1 ~r g2
+mkProofIrrelCo :: Role -- ^ role of the created coercion, "r"
+ -> KindCoercion -- ^ :: phi1 ~N phi2
+ -> Coercion -- ^ g1 :: phi1
+ -> Coercion -- ^ g2 :: phi2
+ -> Coercion -- ^ :: g1 ~r g2
-- if the two coercion prove the same fact, I just don't care what
-- the individual coercions are.
-mkProofIrrelCo r co g _ | isGReflCo co = mkReflCo r (mkCoercionTy g)
- -- kco is a kind coercion, thus @isGReflCo@ rather than @isReflCo@
-mkProofIrrelCo r kco g1 g2 = mkUnivCo ProofIrrelProv [kco] r
- (mkCoercionTy g1) (mkCoercionTy g2)
+mkProofIrrelCo r kco g1 g2
+ | isReflKindCo kco = mkReflCo r (mkCoercionTy g1)
+ -- kco is a kind coercion, thus @isReflKindCo@ rather than @isReflCo@
+ | otherwise = mkUnivCo ProofIrrelProv [kco] r
+ (mkCoercionTy g1) (mkCoercionTy g2)
{-
%************************************************************************
@@ -2165,16 +2202,17 @@ ty_co_subst !lc role ty
go r (TyConApp tc tys) = mkTyConAppCo r tc (zipWith go (tyConRoleListX r tc) tys)
go r (FunTy af w t1 t2) = mkFunCo r af (go Nominal w) (go r t1) (go r t2)
go r t@(ForAllTy (Bndr v vis) ty)
- = let (lc', v', h) = liftCoSubstVarBndr lc v
- body_co = ty_co_subst lc' r ty in
- if isTyVar v' || almostDevoidCoVarOfCo v' body_co
+ = let (lc', v', k_co) = liftCoSubstVarBndr lc v
+ body_co = ty_co_subst lc' r ty
+ k_mco = kindCoToMKindCo k_co
+ in if isTyVar v' || almostDevoidCoVarOfCo v' body_co
-- Lifting a ForAllTy over a coercion variable could fail as ForAllCo
-- imposes an extra restriction on where a covar can appear. See
-- (FC6) of Note [ForAllCo] in GHC.Tc.TyCo.Rep
-- We specifically check for this and panic because we know that
-- there's a hole in the type system here (see (FC6), and we'd rather
-- panic than fall into it.
- then mkForAllCo v' vis vis h body_co
+ then mkForAllCo v' vis vis k_mco body_co
else pprPanic "ty_co_subst: covar is not almost devoid" (ppr t)
go r ty@(LitTy {}) = assert (r == Nominal) $
mkNomReflCo ty
@@ -2262,6 +2300,7 @@ liftCoSubstVarBndr :: LiftingContext -> TyCoVar
liftCoSubstVarBndr lc tv
= liftCoSubstVarBndrUsing id callback lc tv
where
+ callback :: LiftingContext -> Type -> Coercion
callback lc' ty' = ty_co_subst lc' Nominal ty'
-- the callback must produce a nominal coercion
@@ -2424,7 +2463,7 @@ seqCo (SubCo co) = seqCo co
seqCo (AxiomCo _ cs) = seqCos cs
seqCo (ForAllCo tv visL visR k co)
= seqType (varType tv) `seq` rnf visL `seq` rnf visR `seq`
- seqCo k `seq` seqCo co
+ seqMCo k `seq` seqCo co
seqCo (FunCo r af1 af2 w co1 co2)
= r `seq` af1 `seq` af2 `seq` seqCo w `seq` seqCo co1 `seq` seqCo co2
seqCo (UnivCo { uco_prov = p, uco_role = r
@@ -2522,7 +2561,7 @@ coercion_lr_kind which orig_co
, fco_kind = k_co, fco_body = co1 })
= case which of
CLeft -> mkTyCoForAllTy tv1 visL (go co1)
- CRight | isGReflCo k_co -- kind_co always has kind `Type`, thus `isGReflCo`
+ CRight | isReflKindMCo k_co
-> mkTyCoForAllTy tv1 visR (go co1)
| otherwise
-> go_forall_right empty_subst co
@@ -2577,43 +2616,47 @@ coercion_lr_kind which orig_co
-------------
go_forall_right subst (ForAllCo { fco_tcv = tv1, fco_visR = visR
- , fco_kind = k_co, fco_body = co })
+ , fco_kind = k_mco, fco_body = co })
-- See Note [Nested ForAllCos]
| isTyVar tv1
- = mkForAllTy (Bndr tv2 visR) (go_forall_right subst' co)
- where
- k2 = coercionRKind k_co
- tv2 = setTyVarKind tv1 (substTy subst k2)
- subst' | isGReflCo k_co = extendSubstInScope subst tv1
- -- kind_co always has kind @Type@, thus @isGReflCo@
- | otherwise = extendTvSubst (extendSubstInScope subst tv2) tv1 $
- TyVarTy tv2 `mkCastTy` mkSymCo k_co
+ = case k_mco of
+ MRefl -> mkForAllTy (Bndr tv1 visR) (go_forall_right subst' co)
+ where
+ subst' = extendSubstInScope subst tv1
+ MCo k_co -> mkForAllTy (Bndr tv2 visR) (go_forall_right subst' co)
+ where
+ k2 = coercionRKind k_co
+ tv2 = setTyVarKind tv1 (substTy subst k2)
+ subst' = extendTvSubst (extendSubstInScope subst tv2) tv1 $
+ TyVarTy tv2 `mkCastTy` mkSymCo k_co
go_forall_right subst (ForAllCo { fco_tcv = cv1, fco_visR = visR
- , fco_kind = k_co, fco_body = co })
+ , fco_kind = k_mco, fco_body = co })
| isCoVar cv1
- = mkTyCoForAllTy cv2 visR (go_forall_right subst' co)
- where
- k2 = coercionRKind k_co
- r = coVarRole cv1
- k_co' = downgradeRole r Nominal k_co
- eta1 = mkSelCo (SelTyCon 2 r) k_co'
- eta2 = mkSelCo (SelTyCon 3 r) k_co'
-
- -- k_co :: (t1 ~r t2) ~N (s1 ~r s2)
- -- k1 = t1 ~r t2
- -- k2 = s1 ~r s2
- -- cv1 :: t1 ~r t2
- -- cv2 :: s1 ~r s2
- -- eta1 :: t1 ~r s1
- -- eta2 :: t2 ~r s2
- -- n_subst = (eta1 ; cv2 ; sym eta2) :: t1 ~r t2
-
- cv2 = setVarType cv1 (substTy subst k2)
- n_subst = eta1 `mkTransCo` (mkCoVarCo cv2) `mkTransCo` (mkSymCo eta2)
- subst' | isReflCo k_co = extendSubstInScope subst cv1
- | otherwise = extendCvSubst (extendSubstInScope subst cv2)
- cv1 n_subst
+ = case k_mco of
+ MRefl -> mkTyCoForAllTy cv1 visR (go_forall_right subst' co)
+ where
+ subst' = extendSubstInScope subst cv1
+ MCo k_co -> mkTyCoForAllTy cv2 visR (go_forall_right subst' co)
+ where
+ k2 = coercionRKind k_co
+ r = coVarRole cv1
+ k_co' = downgradeRole r Nominal k_co
+ eta1 = mkSelCo (SelTyCon 2 r) k_co'
+ eta2 = mkSelCo (SelTyCon 3 r) k_co'
+
+ -- k_co :: (t1 ~r t2) ~N (s1 ~r s2)
+ -- k1 = t1 ~r t2
+ -- k2 = s1 ~r s2
+ -- cv1 :: t1 ~r t2
+ -- cv2 :: s1 ~r s2
+ -- eta1 :: t1 ~r s1
+ -- eta2 :: t2 ~r s2
+ -- n_subst = (eta1 ; cv2 ; sym eta2) :: t1 ~r t2
+
+ cv2 = setVarType cv1 (substTy subst k2)
+ n_subst = eta1 `mkTransCo` (mkCoVarCo cv2) `mkTransCo` (mkSymCo eta2)
+ subst' = extendCvSubst (extendSubstInScope subst cv2) cv1 n_subst
go_forall_right subst other_co
-- when other_co is not a ForAllCo
@@ -2729,7 +2772,7 @@ buildCoercion orig_ty1 orig_ty2 = go orig_ty1 orig_ty2
go (ForAllTy (Bndr tv1 flag1) ty1) (ForAllTy (Bndr tv2 flag2) ty2)
| isTyVar tv1
= assert (isTyVar tv2) $
- mkForAllCo tv1 flag1 flag2 kind_co (go ty1 ty2')
+ mkForAllCo tv1 flag1 flag2 (kindCoToMKindCo kind_co) (go ty1 ty2')
where kind_co = go (tyVarKind tv1) (tyVarKind tv2)
in_scope = mkInScopeSet $ tyCoVarsOfType ty2 `unionVarSet` tyCoVarsOfCo kind_co
ty2' = substTyWithInScope in_scope [tv2]
@@ -2738,7 +2781,7 @@ buildCoercion orig_ty1 orig_ty2 = go orig_ty1 orig_ty2
go (ForAllTy (Bndr cv1 flag1) ty1) (ForAllTy (Bndr cv2 flag2) ty2)
= assert (isCoVar cv1 && isCoVar cv2) $
- mkForAllCo cv1 flag1 flag2 kind_co (go ty1 ty2')
+ mkForAllCo cv1 flag1 flag2 (kindCoToMKindCo kind_co) (go ty1 ty2')
where s1 = varType cv1
s2 = varType cv2
kind_co = go s1 s2
@@ -2755,7 +2798,7 @@ buildCoercion orig_ty1 orig_ty2 = go orig_ty1 orig_ty2
eta2 = mkSelCo (SelTyCon 3 r) kind_co'
subst = mkEmptySubst $ mkInScopeSet $
- tyCoVarsOfType ty2 `unionVarSet` tyCoVarsOfCo kind_co
+ tyCoVarsOfType ty2 `unionVarSet` tyCoVarsOfCo kind_co
ty2' = substTy (extendCvSubst subst cv2 $ mkSymCo eta1 `mkTransCo`
mkCoVarCo cv1 `mkTransCo`
eta2)
=====================================
compiler/GHC/Core/Coercion.hs-boot
=====================================
@@ -16,7 +16,7 @@ import GHC.Utils.Misc
mkReflCo :: Role -> Type -> Coercion
mkTyConAppCo :: HasDebugCallStack => Role -> TyCon -> [Coercion] -> Coercion
mkAppCo :: Coercion -> Coercion -> Coercion
-mkForAllCo :: HasDebugCallStack => TyCoVar -> ForAllTyFlag -> ForAllTyFlag -> Coercion -> Coercion -> Coercion
+mkForAllCo :: HasDebugCallStack => TyCoVar -> ForAllTyFlag -> ForAllTyFlag -> MCoercion -> Coercion -> Coercion
mkFunCo :: Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion
mkNakedFunCo :: Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion
mkFunCo2 :: Role -> FunTyFlag -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion
@@ -37,7 +37,6 @@ mkAxiomCo :: CoAxiomRule -> [Coercion] -> Coercion
funRole :: Role -> FunSel -> Role
-isGReflCo :: Coercion -> Bool
isReflCo :: Coercion -> Bool
isReflexiveCo :: Coercion -> Bool
decomposePiCos :: HasDebugCallStack => Coercion -> Pair Type -> [Type] -> ([Coercion], Coercion)
=====================================
compiler/GHC/Core/Coercion/Opt.hs
=====================================
@@ -177,12 +177,12 @@ optCoercion opts env co
= optCoercion' env co
{-
- = pprTrace "optCoercion {" (text "Co:" <> ppr (coercionSize co)) $
+ = pprTrace "optCoercion {" (text "Co:" <> ppr co) $
let result = optCoercion' env co in
pprTrace "optCoercion }"
(vcat [ text "Co:" <+> ppr (coercionSize co)
, text "Optco:" <+> ppWhen (isReflCo result) (text "(refl)")
- <+> ppr (coercionSize result) ]) $
+ <+> ppr result ]) $
result
-}
@@ -317,7 +317,7 @@ opt_co4' env sym rep r (GRefl _r ty (MCo kco))
(text "Expected role:" <+> ppr r $$
text "Found role:" <+> ppr _r $$
text "Type:" <+> ppr ty) $
- if isGReflCo kco || isGReflCo kco'
+ if isReflKindCo kco || isReflKindCo kco'
then wrapSym sym ty_co
else wrapSym sym $ mk_coherence_right_co r' (coercionRKind ty_co) kco' ty_co
-- ty :: k1
@@ -841,55 +841,58 @@ opt_trans_rule is co1 co2@(AppCo co2a co2b)
-- Push transitivity inside forall
-- forall over types.
opt_trans_rule is co1 co2
- | Just (tv1, visL1, _visR1, eta1, r1) <- splitForAllCo_ty_maybe co1
- , Just (tv2, _visL2, visR2, eta2, r2) <- etaForAllCo_ty_maybe co2
- = push_trans tv1 eta1 r1 tv2 eta2 r2 visL1 visR2
+ | Just (tv1, visL1, _visR1, kco1, r1) <- splitForAllCo_ty_maybe co1
+ , Just (tv2, _visL2, visR2, kco2, r2) <- etaForAllCo_ty_maybe co2
+ = push_trans tv1 kco1 r1 tv2 kco2 r2 visL1 visR2
- | Just (tv2, _visL2, visR2, eta2, r2) <- splitForAllCo_ty_maybe co2
- , Just (tv1, visL1, _visR1, eta1, r1) <- etaForAllCo_ty_maybe co1
- = push_trans tv1 eta1 r1 tv2 eta2 r2 visL1 visR2
+ | Just (tv2, _visL2, visR2, kco2, r2) <- splitForAllCo_ty_maybe co2
+ , Just (tv1, visL1, _visR1, kco1, r1) <- etaForAllCo_ty_maybe co1
+ = push_trans tv1 kco1 r1 tv2 kco2 r2 visL1 visR2
where
- push_trans tv1 eta1 r1 tv2 eta2 r2 visL visR
+ push_trans tv1 kco1 r1 tv2 kco2 r2 visL visR
-- Given:
- -- co1 = /\ tv1 : eta1 <visL, visM>. r1
- -- co2 = /\ tv2 : eta2 <visM, visR>. r2
+ -- co1 = /\ tv1 : kco1 <visL, visM>. r1
+ -- co2 = /\ tv2 : kco2 <visM, visR>. r2
-- Wanted:
- -- /\tv1 : (eta1;eta2) <visL, visR>. (r1; r2[tv2 |-> tv1 |> eta1])
+ -- /\tv1 : (kco1;kco2) <visL, visR>. (r1; r2[tv2 |-> tv1 |> kco1])
= fireTransRule "EtaAllTy_ty" co1 co2 $
- mkForAllCo tv1 visL visR (opt_trans is eta1 eta2) (opt_trans is' r1 r2')
+ mkForAllCo tv1 visL visR
+ (kindCoToMKindCo (opt_trans is kco1 kco2))
+ (opt_trans is' r1 r2')
where
is' = is `extendInScopeSet` tv1
- r2' = substCoWithUnchecked [tv2] [mkCastTy (TyVarTy tv1) eta1] r2
+ r2' = substCoWithInScope is' [tv2] [mkCastTy (TyVarTy tv1) kco1] r2
-- Push transitivity inside forall
-- forall over coercions.
opt_trans_rule is co1 co2
- | Just (cv1, visL1, _visR1, eta1, r1) <- splitForAllCo_co_maybe co1
- , Just (cv2, _visL2, visR2, eta2, r2) <- etaForAllCo_co_maybe co2
- = push_trans cv1 eta1 r1 cv2 eta2 r2 visL1 visR2
+ | Just (cv1, visL1, _visR1, kco1, r1) <- splitForAllCo_co_maybe co1
+ , Just (cv2, _visL2, visR2, kco2, r2) <- etaForAllCo_co_maybe co2
+ = push_trans cv1 kco1 r1 cv2 kco2 r2 visL1 visR2
- | Just (cv2, _visL2, visR2, eta2, r2) <- splitForAllCo_co_maybe co2
- , Just (cv1, visL1, _visR1, eta1, r1) <- etaForAllCo_co_maybe co1
- = push_trans cv1 eta1 r1 cv2 eta2 r2 visL1 visR2
+ | Just (cv2, _visL2, visR2, kco2, r2) <- splitForAllCo_co_maybe co2
+ , Just (cv1, visL1, _visR1, kco1, r1) <- etaForAllCo_co_maybe co1
+ = push_trans cv1 kco1 r1 cv2 kco2 r2 visL1 visR2
where
- push_trans cv1 eta1 r1 cv2 eta2 r2 visL visR
+ push_trans cv1 kco1 r1 cv2 kco2 r2 visL visR
-- Given:
- -- co1 = /\ (cv1 : eta1) <visL, visM>. r1
- -- co2 = /\ (cv2 : eta2) <visM, visR>. r2
+ -- co1 = /\ (cv1 : kco1) <visL, visM>. r1
+ -- co2 = /\ (cv2 : kco2) <visM, visR>. r2
-- Wanted:
- -- n1 = nth 2 eta1
- -- n2 = nth 3 eta1
- -- nco = /\ cv1 : (eta1;eta2). (r1; r2[cv2 |-> (sym n1);cv1;n2])
+ -- n1 = nth 2 kco1
+ -- n2 = nth 3 kco1
+ -- nco = /\ cv1 : (kco1;kco2). (r1; r2[cv2 |-> (sym n1);cv1;n2])
= fireTransRule "EtaAllTy_co" co1 co2 $
- mkForAllCo cv1 visL visR (opt_trans is eta1 eta2) (opt_trans is' r1 r2')
+ mkForAllCo cv1 visL visR (coToMCo (opt_trans is kco1 kco2))
+ (opt_trans is' r1 r2')
where
is' = is `extendInScopeSet` cv1
role = coVarRole cv1
- eta1' = downgradeRole role Nominal eta1
- n1 = mkSelCo (SelTyCon 2 role) eta1'
- n2 = mkSelCo (SelTyCon 3 role) eta1'
+ kco1' = downgradeRole role Nominal kco1
+ n1 = mkSelCo (SelTyCon 2 role) kco1'
+ n2 = mkSelCo (SelTyCon 3 role) kco1'
r2' = substCo (zipCvSubst [cv2] [(mkSymCo n1) `mk_trans_co`
(mkCoVarCo cv1) `mk_trans_co` n2])
r2
@@ -1285,7 +1288,8 @@ Here,
eta2 = mkSelCo (SelTyCon 3 r) h1 :: (s2 ~ s4)
h2 = mkInstCo g (cv1 ~ (sym eta1;c1;eta2))
-}
-etaForAllCo_ty_maybe :: Coercion -> Maybe (TyVar, ForAllTyFlag, ForAllTyFlag, Coercion, Coercion)
+etaForAllCo_ty_maybe :: Coercion
+ -> Maybe (TyVar, ForAllTyFlag, ForAllTyFlag, KindCoercion, Coercion)
-- Try to make the coercion be of form (forall tv:kind_co. co)
etaForAllCo_ty_maybe co
| Just (tv, visL, visR, kind_co, r) <- splitForAllCo_ty_maybe co
@@ -1305,7 +1309,8 @@ etaForAllCo_ty_maybe co
| otherwise
= Nothing
-etaForAllCo_co_maybe :: Coercion -> Maybe (CoVar, ForAllTyFlag, ForAllTyFlag, Coercion, Coercion)
+etaForAllCo_co_maybe :: Coercion
+ -> Maybe (CoVar, ForAllTyFlag, ForAllTyFlag, KindCoercion, Coercion)
-- Try to make the coercion be of form (forall cv:kind_co. co)
etaForAllCo_co_maybe co
| Just (cv, visL, visR, kind_co, r) <- splitForAllCo_co_maybe co
@@ -1428,13 +1433,17 @@ But if sym=Swapped, things are trickier. Here is an identity that helps:
-}
optForAllCoBndr :: LiftingContext -> SwapFlag
- -> TyCoVar -> Coercion
- -> (LiftingContext, TyCoVar, Coercion)
+ -> TyCoVar -> MCoercionN
+ -> (LiftingContext, TyCoVar, MCoercionN)
-- See Note [Optimising ForAllCo]
-optForAllCoBndr env sym tcv kco
- = (env', tcv', kco')
+optForAllCoBndr env sym tcv k_mco
+ = (env', tcv', k_mco')
where
- kco' = opt_co4 env sym False Nominal kco -- Push sym into kco
+ -- Push sym into kco
+ k_mco' = case k_mco of
+ MRefl -> MRefl
+ MCo co -> MCo (opt_co4 env sym False Nominal co)
+
(env', tcv') = updateLCSubst env upd_subst
upd_subst :: Subst -> (Subst, TyCoVar)
@@ -1443,26 +1452,32 @@ optForAllCoBndr env sym tcv kco
| otherwise = upd_subst_cv subst
upd_subst_tv subst
- | notSwapped sym || isReflCo kco' = (subst1, tv1)
- | otherwise = (subst2, tv2)
+ = case k_mco' of
+ MCo k_co' | isSwapped sym -> (subst2, tv2)
+ where
+ -- In the Swapped case, we re-kind the type variable, AND
+ -- override the substitution for the original variable to the
+ -- re-kinded one, suitably casted
+ tv2 = tv1 `setTyVarKind` coercionLKind k_co'
+ subst2 = (extendTvSubst subst1 tcv (mkTyVarTy tv2 `CastTy` k_co'))
+ `extendSubstInScope` tv2
+
+ _ -> (subst1, tv1)
where
-- subst1,tv1: apply the substitution to the binder and its kind
-- NB: varKind tv = coercionLKind kco
(subst1, tv1) = substTyVarBndr subst tcv
- -- In the Swapped case, we re-kind the type variable, AND
- -- override the substitution for the original variable to the
- -- re-kinded one, suitably casted
- tv2 = tv1 `setTyVarKind` coercionLKind kco'
- subst2 = (extendTvSubst subst1 tcv (mkTyVarTy tv2 `CastTy` kco'))
- `extendSubstInScope` tv2
upd_subst_cv subst -- ToDo: probably not right yet
- | notSwapped sym || isReflCo kco' = (subst1, cv1)
- | otherwise = (subst2, cv2)
- where
+ = case k_mco' of
+ MCo k_co' | isSwapped sym -> (subst2, cv2)
+ where
+ cv2 = cv1 `setTyVarKind` coercionLKind k_co'
+ subst2 = subst1 `extendSubstInScope` cv2
+
+ _ -> (subst1, cv1)
+ where
(subst1, cv1) = substCoVarBndr subst tcv
- cv2 = cv1 `setTyVarKind` coercionLKind kco'
- subst2 = subst1 `extendSubstInScope` cv2
{- **********************************************************************
=====================================
compiler/GHC/Core/Lint.hs
=====================================
@@ -2424,15 +2424,19 @@ lintCoercion co@(ForAllCo {})
go :: [OutTyCoVar] -- Binders in reverse order
-> InCoercion -> LintM Role
go tcvs co@(ForAllCo { fco_tcv = tcv, fco_visL = visL, fco_visR = visR
- , fco_kind = kind_co, fco_body = body_co })
+ , fco_kind = kind_mco, fco_body = body_co })
| not (isTyCoVar tcv)
= failWithL (text "Non tyco binder in ForAllCo:" <+> ppr co)
| otherwise
- = do { lk <- lintStarCoercion kind_co
+ = do { mb_lk <- case kind_mco of
+ MRefl -> return Nothing
+ MCo kind_co -> Just <$> lintStarCoercion kind_co
; lintTyCoBndr tcv $ \tcv' ->
- do { ensureEqTys (varType tcv') lk $
- text "Kind mis-match in ForallCo" <+> ppr co
+ do { case mb_lk of
+ Nothing -> return ()
+ Just lk -> ensureEqTys (varType tcv') lk $
+ text "Kind mis-match in ForallCo" <+> ppr co
-- I'm not very sure about this part, because it traverses body_co
-- but at least it's on a cold path (a ForallCo for a CoVar)
=====================================
compiler/GHC/Core/Opt/Arity.hs
=====================================
@@ -2367,8 +2367,7 @@ mkEtaForAllMCo (Bndr tcv vis) ty mco
| otherwise -> mk_fco (mkRepReflCo ty)
MCo co -> mk_fco co
where
- mk_fco co = MCo (mkForAllCo tcv vis coreTyLamForAllTyFlag
- (mkNomReflCo (varType tcv)) co)
+ mk_fco co = MCo (mkForAllCo tcv vis coreTyLamForAllTyFlag MRefl co)
-- coreTyLamForAllTyFlag: See Note [The EtaInfo mechanism], particularly
-- the (EtaInfo Invariant). (sym co) wraps a lambda that always has
-- a ForAllTyFlag of coreTyLamForAllTyFlag; see Note [Required foralls in Core]
@@ -2808,11 +2807,10 @@ tryEtaReduce rec_ids bndrs body eval_sd
| Just tv <- getTyVar_maybe arg_ty
, bndr == tv = case splitForAllForAllTyBinder_maybe fun_ty of
Just (Bndr _ vis, _) -> Just (fco, [])
- where !fco = mkForAllCo tv vis coreTyLamForAllTyFlag kco co
+ where !fco = mkForAllCo tv vis coreTyLamForAllTyFlag MRefl co
-- The lambda we are eta-reducing always has visibility
-- 'coreTyLamForAllTyFlag' which may or may not match
-- the visibility on the inner function (#24014)
- kco = mkNomReflCo (tyVarKind tv)
Nothing -> pprPanic "tryEtaReduce: type arg to non-forall type"
(text "fun:" <+> ppr bndr
$$ text "arg:" <+> ppr arg_ty
=====================================
compiler/GHC/Core/Reduction.hs
=====================================
@@ -373,7 +373,7 @@ mkForAllRedn :: ForAllTyFlag
-> Reduction
mkForAllRedn vis tv1 (Reduction h ki') (Reduction co ty)
= mkReduction
- (mkForAllCo tv1 vis vis h co)
+ (mkForAllCo tv1 vis vis (kindCoToMKindCo h) co)
(mkForAllTy (Bndr tv2 vis) ty)
where
tv2 = setTyVarKind tv1 ki'
=====================================
compiler/GHC/Core/TyCo/FVs.hs
=====================================
@@ -51,7 +51,6 @@ module GHC.Core.TyCo.FVs
import GHC.Prelude
import {-# SOURCE #-} GHC.Core.Type( partitionInvisibleTypes, coreView, rewriterView )
-import {-# SOURCE #-} GHC.Core.Coercion( coercionLKind )
import GHC.Builtin.Types.Prim( funTyFlagTyCon )
@@ -641,8 +640,10 @@ tyCoVarsOfCoList :: Coercion -> [TyCoVar]
tyCoVarsOfCoList co = fvVarList $ tyCoFVsOfCo co
tyCoFVsOfMCo :: MCoercion -> FV
-tyCoFVsOfMCo MRefl = emptyFV
-tyCoFVsOfMCo (MCo co) = tyCoFVsOfCo co
+tyCoFVsOfMCo mco fv_cand in_scope acc
+ = case mco of
+ MRefl -> emptyFV fv_cand in_scope acc
+ MCo co -> tyCoFVsOfCo co fv_cand in_scope acc
tyCoFVsOfCo :: Coercion -> FV
-- Extracts type and coercion variables from a coercion
@@ -655,7 +656,7 @@ tyCoFVsOfCo (TyConAppCo _ _ cos) fv_cand in_scope acc = tyCoFVsOfCos cos fv_cand
tyCoFVsOfCo (AppCo co arg) fv_cand in_scope acc
= (tyCoFVsOfCo co `unionFV` tyCoFVsOfCo arg) fv_cand in_scope acc
tyCoFVsOfCo (ForAllCo { fco_tcv = tv, fco_kind = kind_co, fco_body = co }) fv_cand in_scope acc
- = (tyCoFVsVarBndr tv (tyCoFVsOfCo co) `unionFV` tyCoFVsOfCo kind_co) fv_cand in_scope acc
+ = (tyCoFVsVarBndr tv (tyCoFVsOfCo co) `unionFV` tyCoFVsOfMCo kind_co) fv_cand in_scope acc
tyCoFVsOfCo (FunCo { fco_mult = w, fco_arg = co1, fco_res = co2 }) fv_cand in_scope acc
= (tyCoFVsOfCo co1 `unionFV` tyCoFVsOfCo co2 `unionFV` tyCoFVsOfCo w) fv_cand in_scope acc
tyCoFVsOfCo (CoVarCo v) fv_cand in_scope acc
@@ -693,6 +694,10 @@ almostDevoidCoVarOfCo :: CoVar -> Coercion -> Bool
almostDevoidCoVarOfCo cv co =
almost_devoid_co_var_of_co co cv
+almost_devoid_co_var_of_mco :: MCoercion -> CoVar -> Bool
+almost_devoid_co_var_of_mco MRefl _ = True
+almost_devoid_co_var_of_mco (MCo co) cv = almost_devoid_co_var_of_co co cv
+
almost_devoid_co_var_of_co :: Coercion -> CoVar -> Bool
almost_devoid_co_var_of_co (Refl {}) _ = True -- covar is allowed in Refl and
almost_devoid_co_var_of_co (GRefl {}) _ = True -- GRefl, so we don't look into
@@ -703,7 +708,7 @@ almost_devoid_co_var_of_co (AppCo co arg) cv
= almost_devoid_co_var_of_co co cv
&& almost_devoid_co_var_of_co arg cv
almost_devoid_co_var_of_co (ForAllCo { fco_tcv = v, fco_kind = kind_co, fco_body = co }) cv
- = almost_devoid_co_var_of_co kind_co cv
+ = almost_devoid_co_var_of_mco kind_co cv
&& (v == cv || almost_devoid_co_var_of_co co cv)
almost_devoid_co_var_of_co (FunCo { fco_mult = w, fco_arg = co1, fco_res = co2 }) cv
= almost_devoid_co_var_of_co w cv
@@ -1032,7 +1037,7 @@ tyConsOfType ty
go_co (TyConAppCo _ tc args) = go_tc tc `unionUniqSets` go_cos args
go_co (AppCo co arg) = go_co co `unionUniqSets` go_co arg
go_co (ForAllCo { fco_kind = kind_co, fco_body = co })
- = go_co kind_co `unionUniqSets` go_co co
+ = go_mco kind_co `unionUniqSets` go_co co
go_co (FunCo { fco_mult = m, fco_arg = a, fco_res = r })
= go_co m `unionUniqSets` go_co a `unionUniqSets` go_co r
go_co (AxiomCo ax args) = go_ax ax `unionUniqSets` go_cos args
@@ -1230,14 +1235,14 @@ occCheckExpand vs_to_avoid ty
go_co cxt (SubCo co) = do { co' <- go_co cxt co
; return (SubCo co') }
- go_co cxt@(as, env) co@(ForAllCo { fco_tcv = tv, fco_kind = kind_co, fco_body = body_co })
- = do { kind_co' <- go_co cxt kind_co
- ; let tv' = setVarType tv $
- coercionLKind kind_co'
- env' = extendVarEnv env tv tv'
- as' = as `delVarSet` tv
+ go_co cxt@(as, env) co@(ForAllCo { fco_tcv = tcv, fco_kind = kind_co, fco_body = body_co })
+ = do { ki' <- go cxt (varType tcv)
+ ; let tcv' = setVarType tcv ki'
+ env' = extendVarEnv env tcv tcv'
+ as' = as `delVarSet` tcv
+ ; kind_co' <- go_mco cxt kind_co
; body' <- go_co (as', env') body_co
- ; return (co { fco_tcv = tv', fco_kind = kind_co', fco_body = body' }) }
+ ; return (co { fco_tcv = tcv', fco_kind = kind_co', fco_body = body' }) }
go_co cxt co@(FunCo { fco_mult = w, fco_arg = co1 ,fco_res = co2 })
= do { co1' <- go_co cxt co1
=====================================
compiler/GHC/Core/TyCo/Rep.hs
=====================================
@@ -39,7 +39,7 @@ module GHC.Core.TyCo.Rep (
UnivCoProvenance(..),
CoercionHole(..), coHoleCoVar, setCoHoleCoVar,
CoercionN, CoercionR, CoercionP, KindCoercion,
- MCoercion(..), MCoercionR, MCoercionN,
+ MCoercion(..), MCoercionR, MCoercionN, KindMCoercion,
-- * Functions over types
mkNakedTyConTy, mkTyVarTy, mkTyVarTys,
@@ -806,6 +806,34 @@ tcMkScaledFunTy (Scaled mult arg) res = tcMkVisFunTy mult arg res
%************************************************************************
-}
+type CoercionN = Coercion -- always Nominal
+type CoercionR = Coercion -- always Representational
+type CoercionP = Coercion -- always Phantom
+
+type MCoercionN = MCoercion -- alwyas Nominal
+type MCoercionR = MCoercion -- always Representational
+
+{- Note [KindCoercion]
+~~~~~~~~~~~~~~~~~~~~~~
+A KindCoercion kco :: k1 ~r k2 is a Coercion with these properties:
+ (a) It is Nominal; that is r=Nominal
+ (b) Both (k1::Type) and (k2::Type); it is homogeneous
+
+The coercion in (a) ForAllCo and (b) CastTy is a KindCoercion.
+
+The invariants of KindCoercion allow `isReflKindCo` to elminate GRefl,
+whereas isReflCo cannot. In particular, consider a KindCoercion
+ kco = GRefl r k (MCo kk)) :: k ~ (k |> kk)
+Since `kco`is a KindCoercion, we know that
+ r = Nominal
+ k :: Type and (k |> kk) :: Type
+Hence kk must be Refl. And hence kco = GRefl N k MRefl, which is
+the same as Refl. See `isReflKindCo`.
+-}
+
+type KindCoercion = CoercionN -- See Note [KindCoercion]
+type KindMCoercion = MCoercionN -- See Note [KindCoercion]
+
-- | A 'Coercion' is concrete evidence of the equality/convertibility
-- of two types.
@@ -829,7 +857,7 @@ data Coercion
-- GRefl :: "e" -> _ -> Maybe N -> e
-- See Note [Generalized reflexive coercion]
- | GRefl Role Type MCoercionN -- See Note [Refl invariant]
+ | GRefl Role Type KindMCoercion -- See Note [Refl invariant]
-- Use (Refl ty), not (GRefl Nominal ty MRefl)
-- Use (GRefl Representational _ _), not (SubCo (GRefl Nominal _ _))
@@ -853,7 +881,7 @@ data Coercion
, fco_visL :: !ForAllTyFlag -- Visibility of coercionLKind
, fco_visR :: !ForAllTyFlag -- Visibility of coercionRKind
-- See (FC7) of Note [ForAllCo]
- , fco_kind :: KindCoercion
+ , fco_kind :: KindMCoercion -- See (FC8) of Note [ForAllCo]
, fco_body :: Coercion }
-- ForAllCo :: _ -> N -> e -> e
@@ -911,6 +939,15 @@ data Coercion
-- Only present during typechecking
deriving Data.Data
+-- | A semantically more meaningful type to represent what may or may not be a
+-- useful 'Coercion'.
+data MCoercion
+ = MRefl
+ -- A trivial Reflexivity coercion
+ | MCo Coercion
+ -- Other coercions
+ deriving Data.Data
+
data CoSel -- See Note [SelCo]
= SelTyCon Int Role -- Decomposes (T co1 ... con); zero-indexed
-- Invariant: Given: SelCo (SelTyCon i r) co
@@ -932,11 +969,6 @@ data FunSel -- See Note [SelCo]
| SelRes -- Result of function
deriving( Eq, Data.Data, Ord )
-type CoercionN = Coercion -- always nominal
-type CoercionR = Coercion -- always representational
-type CoercionP = Coercion -- always phantom
-type KindCoercion = CoercionN -- always nominal
-
instance Outputable Coercion where
ppr = pprCo
@@ -980,17 +1012,6 @@ instance NFData CoSel where
rnf SelForAll = ()
rnf (SelFun fs) = rnf fs `seq` ()
--- | A semantically more meaningful type to represent what may or may not be a
--- useful 'Coercion'.
-data MCoercion
- = MRefl
- -- A trivial Reflexivity coercion
- | MCo Coercion
- -- Other coercions
- deriving Data.Data
-type MCoercionR = MCoercion
-type MCoercionN = MCoercion
-
instance Outputable MCoercion where
ppr MRefl = text "MRefl"
ppr (MCo co) = text "MCo" <+> ppr co
@@ -1278,6 +1299,14 @@ Several things to note here
fco_visL = fco_visR = coreTyLamForAllTyFlag
c.f. (FT2) in Note [ForAllTy]
+(FC8) We /represent/ a ForAllCo { fco_tcv = tcv, fco_kind = kmco } as follows:
+ * The tcv::TyCoVar has a kind (like any Var), say tcv::ki
+ * The kind-coercion `kmco` is a KindMCoercion:
+ - If kmco = MRefl, then the coercion in the typing rule is (Refl ki)
+ - If kmco = MCo kco, then the coercion in the typing rule is `co`,
+ /and/ ki = coercionLKind kco
+ So in the common MRefl case, the kind of `tcv` plays a useful role.
+
Note [Predicate coercions]
~~~~~~~~~~~~~~~~~~~~~~~~~~
Suppose we have
@@ -1937,11 +1966,14 @@ foldTyCo (TyCoFolder { tcf_view = view
go_co env (FunCo { fco_mult = cw, fco_arg = c1, fco_res = c2 })
= go_co env cw `mappend` go_co env c1 `mappend` go_co env c2
- go_co env (ForAllCo tv _vis1 _vis2 kind_co co)
- = go_co env kind_co `mappend` go_ty env (varType tv)
- `mappend` go_co env' co
+ go_co env (ForAllCo { fco_tcv = tcv, fco_kind = kind_co, fco_body = co })
+ = go_mco env kind_co `mappend` go_ty env (varType tcv)
+ `mappend` go_co env' co
where
- env' = tycobinder env tv Inferred
+ env' = tycobinder env tcv Inferred
+
+ go_mco _ MRefl = mempty
+ go_mco env (MCo co) = go_co env co
-- | A view function that looks through nothing.
noView :: Type -> Maybe Type
@@ -1983,18 +2015,19 @@ typesSize tys = foldr ((+) . typeSize) 0 tys
coercionSize :: Coercion -> Int
coercionSize (Refl ty) = typeSize ty
-coercionSize (GRefl _ ty MRefl) = typeSize ty
-coercionSize (GRefl _ ty (MCo co)) = 1 + typeSize ty + coercionSize co
+coercionSize (GRefl _ ty mco) = typeSize ty + mCoercionSize mco
coercionSize (TyConAppCo _ _ args) = 1 + sum (map coercionSize args)
coercionSize (AppCo co arg) = coercionSize co + coercionSize arg
coercionSize (ForAllCo { fco_kind = h, fco_body = co })
- = 1 + coercionSize co + coercionSize h
+ = 1 + coercionSize co + mCoercionSize h
coercionSize (FunCo _ _ _ w c1 c2) = 1 + coercionSize c1 + coercionSize c2
+ coercionSize w
coercionSize (CoVarCo _) = 1
coercionSize (HoleCo _) = 1
coercionSize (AxiomCo _ cs) = 1 + sum (map coercionSize cs)
-coercionSize (UnivCo { uco_lty = t1, uco_rty = t2 }) = 1 + typeSize t1 + typeSize t2
+coercionSize (UnivCo { uco_lty = t1, uco_rty = t2, uco_deps = deps })
+ = 1 + typeSize t1 + typeSize t2
+ + sum (map coercionSize deps)
coercionSize (SymCo co) = 1 + coercionSize co
coercionSize (TransCo co1 co2) = 1 + coercionSize co1 + coercionSize co2
coercionSize (SelCo _ co) = 1 + coercionSize co
@@ -2003,6 +2036,10 @@ coercionSize (InstCo co arg) = 1 + coercionSize co + coercionSize arg
coercionSize (KindCo co) = 1 + coercionSize co
coercionSize (SubCo co) = 1 + coercionSize co
+mCoercionSize :: MCoercion -> Int
+mCoercionSize MRefl = 0
+mCoercionSize (MCo co) = coercionSize co
+
{-
************************************************************************
* *
=====================================
compiler/GHC/Core/TyCo/Subst.hs
=====================================
@@ -29,11 +29,10 @@ module GHC.Core.TyCo.Subst
mkTvSubstPrs,
substTyWith, substTyWithCoVars, substTysWith, substTysWithCoVars,
- substCoWith,
+ substCoWithInScope,
substTy, substTyAddInScope, substScaledTy,
substTyUnchecked, substTysUnchecked, substScaledTysUnchecked, substThetaUnchecked,
substTyWithUnchecked, substScaledTyUnchecked,
- substCoUnchecked, substCoWithUnchecked,
substTyWithInScope,
substTys, substScaledTys, substTheta,
lookupTyVar,
@@ -44,8 +43,8 @@ module GHC.Core.TyCo.Subst
substCoVarBndr, substDCoVarSet,
substTyVar, substTyVars, substTyVarToTyVar,
substTyCoVars,
- substTyCoBndr, substForAllCoBndr,
- substVarBndrUsing, substForAllCoBndrUsing,
+ substTyCoBndr,
+ substVarBndrUsing,
checkValidSubst, isValidTCvSubst,
) where
@@ -60,7 +59,7 @@ import {-# SOURCE #-} GHC.Core.Coercion
, mkAxiomCo, mkAppCo, mkGReflCo
, mkInstCo, mkLRCo, mkTyConAppCo
, mkCoercionType
- , coercionLKind, coVarTypesRole )
+ , coVarTypesRole )
import {-# SOURCE #-} GHC.Core.TyCo.Ppr ( pprTyVar )
import {-# SOURCE #-} GHC.Core.Ppr ( ) -- instance Outputable CoreExpr
import {-# SOURCE #-} GHC.Core ( CoreExpr )
@@ -618,28 +617,19 @@ substTyWithUnchecked tvs tys
-- Pre-condition: the 'in_scope' set should satisfy Note [The substitution
-- invariant]; specifically it should include the free vars of 'tys',
-- and of 'ty' minus the domain of the subst.
-substTyWithInScope :: HasDebugCallStack => InScopeSet -> [TyVar] -> [Type] -> Type -> Type
+substTyWithInScope :: HasDebugCallStack
+ => InScopeSet -> [TyVar] -> [Type] -> Type -> Type
substTyWithInScope in_scope tvs tys ty =
assert (tvs `equalLength` tys )
substTy (mkTvSubst in_scope tenv) ty
where tenv = zipTyEnv tvs tys
-- | Coercion substitution, see 'zipTvSubst'
-substCoWith :: HasDebugCallStack => [TyVar] -> [Type] -> Coercion -> Coercion
-substCoWith tvs tys = assert (tvs `equalLength` tys )
- substCo (zipTvSubst tvs tys)
-
--- | Coercion substitution, see 'zipTvSubst'. Disables sanity checks.
--- The problems that the sanity checks in substCo catch are described in
--- Note [The substitution invariant].
--- The goal of #11371 is to migrate all the calls of substCoUnchecked to
--- substCo and remove this function. Please don't use in new code.
-substCoWithUnchecked :: [TyVar] -> [Type] -> Coercion -> Coercion
-substCoWithUnchecked tvs tys
+substCoWithInScope :: HasDebugCallStack
+ => InScopeSet -> [TyVar] -> [Type] -> Coercion -> Coercion
+substCoWithInScope in_scope tvs tys co
= assert (tvs `equalLength` tys )
- substCoUnchecked (zipTvSubst tvs tys)
-
-
+ substCo (mkTvSubst in_scope (zipTyEnv tvs tys)) co
-- | Substitute covars within a type
substTyWithCoVars :: [CoVar] -> [Coercion] -> Type -> Type
@@ -800,10 +790,10 @@ subst_ty subst ty
!res' = go res
in ty { ft_mult = mult', ft_arg = arg', ft_res = res' }
go (ForAllTy (Bndr tv vis) ty)
- = case substVarBndrUnchecked subst tv of
- (subst', tv') ->
- (ForAllTy $! ((Bndr $! tv') vis)) $!
- (subst_ty subst' ty)
+ = (ForAllTy $! ((Bndr $! tv') vis)) $! (subst_ty subst' ty)
+ where
+ !(subst',tv') = substVarBndrUnchecked subst tv
+ -- Unchecked because subst_ty is used from substTyUnchecked
go (LitTy n) = LitTy $! n
go (CastTy ty co) = (mkCastTy $! (go ty)) $! (subst_co subst co)
go (CoercionTy co) = CoercionTy $! (subst_co subst co)
@@ -850,16 +840,6 @@ substCo subst co
| isEmptyTCvSubst subst = co
| otherwise = checkValidSubst subst [] [co] $ subst_co subst co
--- | Substitute within a 'Coercion' disabling sanity checks.
--- The problems that the sanity checks in substCo catch are described in
--- Note [The substitution invariant].
--- The goal of #11371 is to migrate all the calls of substCoUnchecked to
--- substCo and remove this function. Please don't use in new code.
-substCoUnchecked :: Subst -> Coercion -> Coercion
-substCoUnchecked subst co
- | isEmptyTCvSubst subst = co
- | otherwise = subst_co subst co
-
-- | Substitute within several 'Coercion's
-- The substitution has to satisfy the invariants described in
-- Note [The substitution invariant].
@@ -868,7 +848,7 @@ substCos subst cos
| isEmptyTCvSubst subst = cos
| otherwise = checkValidSubst subst [] cos $ map (subst_co subst) cos
-subst_co :: Subst -> Coercion -> Coercion
+subst_co :: HasDebugCallStack => Subst -> Coercion -> Coercion
subst_co subst co
= go co
where
@@ -885,10 +865,14 @@ subst_co subst co
go (TyConAppCo r tc args)= mkTyConAppCo r tc $! go_cos args
go (AxiomCo con cos) = mkAxiomCo con $! go_cos cos
go (AppCo co arg) = (mkAppCo $! go co) $! go arg
- go (ForAllCo tv visL visR kind_co co)
- = case substForAllCoBndrUnchecked subst tv kind_co of
- (subst', tv', kind_co') ->
- ((mkForAllCo $! tv') visL visR $! kind_co') $! subst_co subst' co
+ go (ForAllCo { fco_tcv = tcv, fco_visL = visL, fco_visR = visR
+ , fco_kind = kind_co, fco_body = co })
+ = ((mkForAllCo $! tcv') visL visR
+ $! go_mco kind_co)
+ $! subst_co subst' co
+ where
+ !(subst', tcv') = substVarBndrUnchecked subst tcv
+ -- Unchecked because used from substTyUnchecked
go (FunCo r afl afr w co1 co2) = ((mkFunCo2 r afl afr $! go w) $! go co1) $! go co2
go (CoVarCo cv) = substCoVar subst cv
go (UnivCo { uco_prov = p, uco_role = r
@@ -917,75 +901,6 @@ substDCoVarSet :: Subst -> DCoVarSet -> DCoVarSet
substDCoVarSet subst cvs = coVarsOfCosDSet $ map (substCoVar subst) $
dVarSetElems cvs
-substForAllCoBndr :: Subst -> TyCoVar -> KindCoercion
- -> (Subst, TyCoVar, Coercion)
-substForAllCoBndr subst
- = substForAllCoBndrUsing (substCo subst) subst
-
--- | Like 'substForAllCoBndr', but disables sanity checks.
--- The problems that the sanity checks in substCo catch are described in
--- Note [The substitution invariant].
--- The goal of #11371 is to migrate all the calls of substCoUnchecked to
--- substCo and remove this function. Please don't use in new code.
-substForAllCoBndrUnchecked :: Subst -> TyCoVar -> KindCoercion
- -> (Subst, TyCoVar, Coercion)
-substForAllCoBndrUnchecked subst
- = substForAllCoBndrUsing (substCoUnchecked subst) subst
-
--- See Note [Sym and ForAllCo]
-substForAllCoBndrUsing :: (Coercion -> Coercion) -- transformation to kind co
- -> Subst -> TyCoVar -> KindCoercion
- -> (Subst, TyCoVar, KindCoercion)
-substForAllCoBndrUsing sco subst old_var
- | isTyVar old_var = substForAllCoTyVarBndrUsing sco subst old_var
- | otherwise = substForAllCoCoVarBndrUsing sco subst old_var
-
-substForAllCoTyVarBndrUsing :: (Coercion -> Coercion) -- transformation to kind co
- -> Subst -> TyVar -> KindCoercion
- -> (Subst, TyVar, KindCoercion)
-substForAllCoTyVarBndrUsing sco (Subst in_scope idenv tenv cenv) old_var old_kind_co
- = assert (isTyVar old_var )
- ( Subst (in_scope `extendInScopeSet` new_var) idenv new_env cenv
- , new_var, new_kind_co )
- where
- new_env | no_change = delVarEnv tenv old_var
- | otherwise = extendVarEnv tenv old_var (TyVarTy new_var)
-
- no_kind_change = noFreeVarsOfCo old_kind_co
- no_change = no_kind_change && (new_var == old_var)
-
- new_kind_co | no_kind_change = old_kind_co
- | otherwise = sco old_kind_co
-
- new_ki1 = coercionLKind new_kind_co
- -- We could do substitution to (tyVarKind old_var). We don't do so because
- -- we already substituted new_kind_co, which contains the kind information
- -- we want. We don't want to do substitution once more. Also, in most cases,
- -- new_kind_co is a Refl, in which case coercionKind is really fast.
-
- new_var = uniqAway in_scope (setTyVarKind old_var new_ki1)
-
-substForAllCoCoVarBndrUsing :: (Coercion -> Coercion) -- transformation to kind co
- -> Subst -> CoVar -> KindCoercion
- -> (Subst, CoVar, KindCoercion)
-substForAllCoCoVarBndrUsing sco (Subst in_scope idenv tenv cenv)
- old_var old_kind_co
- = assert (isCoVar old_var )
- ( Subst (in_scope `extendInScopeSet` new_var) idenv tenv new_cenv
- , new_var, new_kind_co )
- where
- new_cenv | no_change = delVarEnv cenv old_var
- | otherwise = extendVarEnv cenv old_var (mkCoVarCo new_var)
-
- no_kind_change = noFreeVarsOfCo old_kind_co
- no_change = no_kind_change && (new_var == old_var)
-
- new_kind_co | no_kind_change = old_kind_co
- | otherwise = sco old_kind_co
-
- new_ki1 = coercionLKind new_kind_co
- new_var = uniqAway in_scope $ mkCoVar (varName old_var) new_ki1
-
substCoVar :: Subst -> CoVar -> Coercion
substCoVar (Subst _ _ _ cenv) cv
= case lookupVarEnv cenv cv of
=====================================
compiler/GHC/Core/TyCo/Tidy.hs
=====================================
@@ -334,7 +334,7 @@ tidyCo env co
go (TyConAppCo r tc cos) = TyConAppCo r tc $! strictMap go cos
go (AppCo co1 co2) = (AppCo $! go co1) $! go co2
go (ForAllCo tv visL visR h co)
- = ((((ForAllCo $! tvp) $! visL) $! visR) $! (go h)) $! (tidyCo envp co)
+ = ((((ForAllCo $! tvp) $! visL) $! visR) $! (go_mco h)) $! (tidyCo envp co)
where (envp, tvp) = tidyVarBndr env tv
-- the case above duplicates a bit of work in tidying h and the kind
-- of tv. But the alternative is to use coercionKind, which seems worse.
=====================================
compiler/GHC/Core/Type.hs
=====================================
@@ -210,7 +210,7 @@ module GHC.Core.Type (
substTyAddInScope,
substTyUnchecked, substTysUnchecked, substScaledTyUnchecked, substScaledTysUnchecked,
substThetaUnchecked, substTyWithUnchecked,
- substCo, substCoUnchecked, substCoWithUnchecked,
+ substCo, substCoWithInScope,
substTyVarBndr, substTyVarBndrs, substTyVar, substTyVars,
substVarBndr, substVarBndrs,
substTyCoBndr, substTyVarToTyVar,
@@ -530,10 +530,13 @@ expandTypeSynonyms ty
= mkTyConAppCo r tc (map (go_co subst) args)
go_co subst (AppCo co arg)
= mkAppCo (go_co subst co) (go_co subst arg)
- go_co subst (ForAllCo { fco_tcv = tv, fco_visL = visL, fco_visR = visR
+ go_co subst (ForAllCo { fco_tcv = tcv, fco_visL = visL, fco_visR = visR
, fco_kind = kind_co, fco_body = co })
- = let (subst', tv', kind_co') = go_cobndr subst tv kind_co in
- mkForAllCo tv' visL visR kind_co' (go_co subst' co)
+ = mkForAllCo tcv' visL visR
+ (go_mco subst kind_co)
+ (go_co subst' co)
+ where
+ (subst', tcv') = substVarBndr subst tcv
go_co subst (FunCo r afl afr w co1 co2)
= mkFunCo2 r afl afr (go_co subst w) (go_co subst co1) (go_co subst co2)
go_co subst (CoVarCo cv)
@@ -559,8 +562,6 @@ expandTypeSynonyms ty
go_co _ (HoleCo h)
= pprPanic "expandTypeSynonyms hit a hole" (ppr h)
- go_cobndr subst = substForAllCoBndrUsing (go_co subst) subst
-
{- Notes on type synonyms
~~~~~~~~~~~~~~~~~~~~~~~~~
The various "split" functions (splitFunTy, splitRhoTy, splitForAllTy) try
@@ -971,7 +972,7 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar
= mkTyConAppCo r tc <$> go_cos env cos
go_co !env (ForAllCo { fco_tcv = tv, fco_visL = visL, fco_visR = visR
, fco_kind = kind_co, fco_body = co })
- = do { kind_co' <- go_co env kind_co
+ = do { kind_co' <- go_mco env kind_co
; tycobinder env tv visL $ \env' tv' -> do
; co' <- go_co env' co
; return $ mkForAllCo tv' visL visR kind_co' co' }
=====================================
compiler/GHC/Core/Unify.hs
=====================================
@@ -2414,14 +2414,15 @@ ty_co_match menv subst (FunTy { ft_mult = w, ft_arg = ty1, ft_res = ty2 })
-- not doing so caused #21205.
ty_co_match menv subst (ForAllTy (Bndr tv1 vis1t) ty1)
- (ForAllCo tv2 vis1c vis2c kind_co2 co2)
+ (ForAllCo tv2 vis1c vis2c kind_mco2 co2)
lkco rkco
| isTyVar tv1 && isTyVar tv2
, vis1t == vis1c && vis1c == vis2c -- Is this necessary?
-- Is this visibility check necessary? @rae says: yes, I think the
-- check is necessary, if we're caring about visibility (and we are).
-- But ty_co_match is a dark and not important corner.
- = do { subst1 <- ty_co_match menv subst (tyVarKind tv1) kind_co2
+ = do { subst1 <- ty_co_match menv subst (tyVarKind tv1)
+ (forAllCoKindCo tv2 kind_mco2)
ki_ki_co ki_ki_co
; let rn_env0 = me_env menv
rn_env1 = rnBndr2 rn_env0 tv1 tv2
@@ -2522,6 +2523,6 @@ pushRefl co =
-> Just (TyConAppCo r tc (zipWith mkReflCo (tyConRoleListX r tc) tys))
Just (ForAllTy (Bndr tv vis) ty, r)
-> Just (ForAllCo { fco_tcv = tv, fco_visL = vis, fco_visR = vis
- , fco_kind = mkNomReflCo (varType tv)
+ , fco_kind = MRefl
, fco_body = mkReflCo r ty })
_ -> Nothing
=====================================
compiler/GHC/CoreToIface.hs
=====================================
@@ -312,7 +312,7 @@ toIfaceCoercionX fr co
= IfaceForAllCo (toIfaceBndr tv)
visL
visR
- (toIfaceCoercionX fr' k)
+ (go_mco k)
(toIfaceCoercionX fr' co)
where
fr' = fr `delVarSet` tv
=====================================
compiler/GHC/Iface/Rename.hs
=====================================
@@ -689,7 +689,7 @@ rnIfaceCo (IfaceAxiomCo ax cos) = IfaceAxiomCo ax <$> mapM rnIfaceCo cos
rnIfaceCo (IfaceKindCo c) = IfaceKindCo <$> rnIfaceCo c
rnIfaceCo (IfaceForAllCo bndr visL visR co1 co2)
= (\bndr' co1' co2' -> IfaceForAllCo bndr' visL visR co1' co2')
- <$> rnIfaceBndr bndr <*> rnIfaceCo co1 <*> rnIfaceCo co2
+ <$> rnIfaceBndr bndr <*> rnIfaceMCo co1 <*> rnIfaceCo co2
rnIfaceCo (IfaceUnivCo s r t1 t2 deps)
= IfaceUnivCo s r <$> rnIfaceType t1 <*> rnIfaceType t2 <*> mapM rnIfaceCo deps
=====================================
compiler/GHC/Iface/Syntax.hs
=====================================
@@ -2076,7 +2076,7 @@ freeNamesIfCoercion (IfaceTyConAppCo _ tc cos)
freeNamesIfCoercion (IfaceAppCo c1 c2)
= freeNamesIfCoercion c1 &&& freeNamesIfCoercion c2
freeNamesIfCoercion (IfaceForAllCo _tcv _visL _visR kind_co co)
- = freeNamesIfCoercion kind_co &&& freeNamesIfCoercion co
+ = freeNamesIfMCoercion kind_co &&& freeNamesIfCoercion co
freeNamesIfCoercion (IfaceFreeCoVar _) = emptyNameSet
freeNamesIfCoercion (IfaceCoVarCo _) = emptyNameSet
freeNamesIfCoercion (IfaceHoleCo _) = emptyNameSet
=====================================
compiler/GHC/Iface/Type.hs
=====================================
@@ -132,7 +132,7 @@ data IfaceBndr -- Local (non-top-level) binders
deriving (Eq, Ord)
-type IfaceIdBndr = (IfaceType, IfLclName, IfaceType)
+type IfaceIdBndr = (IfaceType, IfLclName, IfaceType) -- (multiplicity, name, type)
type IfaceTvBndr = (IfLclName, IfaceKind)
ifaceTvBndrName :: IfaceTvBndr -> IfLclName
@@ -479,7 +479,7 @@ data IfaceCoercion
| IfaceFunCo Role IfaceCoercion IfaceCoercion IfaceCoercion
| IfaceTyConAppCo Role IfaceTyCon [IfaceCoercion]
| IfaceAppCo IfaceCoercion IfaceCoercion
- | IfaceForAllCo IfaceBndr !ForAllTyFlag !ForAllTyFlag IfaceCoercion IfaceCoercion
+ | IfaceForAllCo IfaceBndr !ForAllTyFlag !ForAllTyFlag IfaceMCoercion IfaceCoercion
| IfaceCoVarCo IfLclName
| IfaceAxiomCo IfaceAxiomRule [IfaceCoercion]
-- ^ There are only a fixed number of CoAxiomRules, so it suffices
@@ -1454,10 +1454,9 @@ pprIfaceForAllPartMust :: [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc
pprIfaceForAllPartMust tvs ctxt sdoc
= ppr_iface_forall_part ShowForAllMust tvs ctxt sdoc
-pprIfaceForAllCoPart :: [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
+pprIfaceForAllCoPart :: [(IfaceBndr, IfaceMCoercion, ForAllTyFlag, ForAllTyFlag)]
-> SDoc -> SDoc
-pprIfaceForAllCoPart tvs sdoc
- = sep [ pprIfaceForAllCo tvs, sdoc ]
+pprIfaceForAllCoPart tvs sdoc = sep [ pprIfaceForAllCo tvs, sdoc ]
ppr_iface_forall_part :: ShowForAllFlag
-> [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc
@@ -1494,11 +1493,11 @@ ppr_itv_bndrs all_bndrs@(bndr@(Bndr _ vis) : bndrs) vis1
| otherwise = (all_bndrs, [])
ppr_itv_bndrs [] _ = ([], [])
-pprIfaceForAllCo :: [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)] -> SDoc
+pprIfaceForAllCo :: [(IfaceBndr, IfaceMCoercion, ForAllTyFlag, ForAllTyFlag)] -> SDoc
pprIfaceForAllCo [] = empty
pprIfaceForAllCo tvs = text "forall" <+> pprIfaceForAllCoBndrs tvs <> dot
-pprIfaceForAllCoBndrs :: [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)] -> SDoc
+pprIfaceForAllCoBndrs :: [(IfaceBndr, IfaceMCoercion, ForAllTyFlag, ForAllTyFlag)] -> SDoc
pprIfaceForAllCoBndrs bndrs = hsep $ map pprIfaceForAllCoBndr bndrs
pprIfaceForAllBndr :: IfaceForAllBndr -> SDoc
@@ -1513,10 +1512,17 @@ pprIfaceForAllBndr bndr =
-- See Note [Suppressing binder signatures]
suppress_sig = SuppressBndrSig False
-pprIfaceForAllCoBndr :: (IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag) -> SDoc
-pprIfaceForAllCoBndr (tv, kind_co, visL, visR)
- = parens (ppr tv <> pp_vis <+> dcolon <+> pprIfaceCoercion kind_co)
+pprIfaceForAllCoBndr :: (IfaceBndr, IfaceMCoercion, ForAllTyFlag, ForAllTyFlag) -> SDoc
+pprIfaceForAllCoBndr (tcv, kind_mco, visL, visR)
+ = parens (ppr (ifaceBndrName tcv) <> pp_vis
+ <+> text "::~" <+> pprIfaceCoercion kind_co)
+ -- We print (tcv ::~ kind_co), with the "::~" reminding us the type of tcv
+ -- isn't kind_co; rather it's (coercionLKind kind_co). We used "::" previously
+ -- which grievously confused me.
where
+ kind_co = case kind_mco of
+ IfaceMRefl -> IfaceReflCo (ifaceBndrType tcv)
+ IfaceMCo co -> co
pp_vis | visL == coreTyLamForAllTyFlag
, visR == coreTyLamForAllTyFlag
= empty
@@ -2069,10 +2075,8 @@ ppr_co ctxt_prec co@(IfaceForAllCo {})
where
(tvs, inner_co) = split_co co
- split_co (IfaceForAllCo (IfaceTvBndr (name, _)) visL visR kind_co co')
- = let (tvs, co'') = split_co co' in ((name,kind_co,visL,visR):tvs,co'')
- split_co (IfaceForAllCo (IfaceIdBndr (_, name, _)) visL visR kind_co co')
- = let (tvs, co'') = split_co co' in ((name,kind_co,visL,visR):tvs,co'')
+ split_co (IfaceForAllCo bndr visL visR kind_co co')
+ = let (tvs, co'') = split_co co' in ((bndr,kind_co,visL,visR):tvs,co'')
split_co co' = ([], co')
-- Why these three? See Note [Free TyVars and CoVars in IfaceType]
=====================================
compiler/GHC/IfaceToCore.hs
=====================================
@@ -1576,9 +1576,12 @@ tcIfaceCo = go
go (IfaceFunCo r w c1 c2) = mkFunCoNoFTF r <$> go w <*> go c1 <*> go c2
go (IfaceTyConAppCo r tc cs) = TyConAppCo r <$> tcIfaceTyCon tc <*> mapM go cs
go (IfaceAppCo c1 c2) = AppCo <$> go c1 <*> go c2
- go (IfaceForAllCo tv visL visR k c) = do { k' <- go k
- ; bindIfaceBndr tv $ \ tv' ->
- ForAllCo tv' visL visR k' <$> go c }
+ go (IfaceForAllCo tcv visL visR k co)
+ = do { k' <- go_mco k
+ ; bindIfaceBndr tcv $ \ tv' ->
+ do { co' <- go co
+ ; return (ForAllCo { fco_tcv = tv', fco_visL = visL, fco_visR = visR
+ , fco_kind = k', fco_body = co' }) } }
go (IfaceCoVarCo n) = CoVarCo <$> go_var n
go (IfaceUnivCo p r t1 t2 ds) = do { t1' <- tcIfaceType t1; t2' <- tcIfaceType t2
; ds' <- mapM go ds
=====================================
compiler/GHC/Tc/TyCl/Utils.hs
=====================================
@@ -135,7 +135,7 @@ synonymTyConsOfType ty
go_co (TyConAppCo _ tc cs) = go_tc tc `plusNameEnv` go_co_s cs
go_co (AppCo co co') = go_co co `plusNameEnv` go_co co'
go_co (ForAllCo { fco_kind = kind_co, fco_body = body_co })
- = go_co kind_co `plusNameEnv` go_co body_co
+ = go_mco kind_co `plusNameEnv` go_co body_co
go_co (FunCo { fco_mult = m, fco_arg = a, fco_res = r })
= go_co m `plusNameEnv` go_co a `plusNameEnv` go_co r
go_co (CoVarCo _) = emptyNameEnv
=====================================
compiler/GHC/Tc/Utils/TcMType.hs
=====================================
@@ -1586,7 +1586,7 @@ collect_cand_qtvs_co orig_ty cur_lvl bound = go_co
go_co dv (CoVarCo cv) = go_cv dv cv
go_co dv (ForAllCo { fco_tcv = tcv, fco_kind = kind_co, fco_body = co })
- = do { dv1 <- go_co dv kind_co
+ = do { dv1 <- go_mco dv kind_co
; collect_cand_qtvs_co orig_ty cur_lvl (bound `extendVarSet` tcv) dv1 co }
go_mco dv MRefl = return dv
=====================================
compiler/GHC/Tc/Utils/TcType.hs
=====================================
@@ -176,7 +176,6 @@ module GHC.Tc.Utils.TcType (
substTyUnchecked, substTysUnchecked, substScaledTyUnchecked,
substThetaUnchecked,
substTyWithUnchecked,
- substCoUnchecked, substCoWithUnchecked,
substTheta,
isUnliftedType,
=====================================
compiler/GHC/Types/Id/Make.hs
=====================================
@@ -1206,10 +1206,11 @@ wrapCo co rep_ty (unbox_rep, box_rep) -- co :: arg_ty ~ rep_ty
boxer = Boxer $ \ subst ->
do { (rep_ids, rep_expr)
<- case box_rep of
- UnitBox -> do { rep_id <- newLocal (fsLit "cowrap_bx") (linear $ TcType.substTy subst rep_ty)
+ UnitBox -> do { rep_id <- newLocal (fsLit "cowrap_bx")
+ (linear $ TcType.substTy subst rep_ty)
; return ([rep_id], Var rep_id) }
Boxer boxer -> boxer subst
- ; let sco = substCoUnchecked subst co
+ ; let sco = substCo subst co
; return (rep_ids, rep_expr `Cast` mkSymCo sco) }
------------------------
=====================================
testsuite/tests/simplCore/should_compile/OpaqueNoCastWW.stderr
=====================================
@@ -1,24 +1,24 @@
==================== Tidy Core ====================
Result size of Tidy Core
- = {terms: 82, types: 52, coercions: 29, joins: 0/0}
+ = {terms: 82, types: 52, coercions: 26, joins: 0/0}
-- RHS size: {terms: 3, types: 3, coercions: 0, joins: 0/0}
unsafeToInteger1 :: forall (n :: Nat). Signed n -> Signed n
[GblId, Arity=1, Unf=OtherCon []]
unsafeToInteger1 = \ (@(n :: Nat)) (ds :: Signed n) -> ds
--- RHS size: {terms: 1, types: 0, coercions: 8, joins: 0/0}
+-- RHS size: {terms: 1, types: 0, coercions: 7, joins: 0/0}
unsafeToInteger :: forall (n :: Nat). Signed n -> Integer
[GblId[[RecSel]], Arity=1, Unf=OtherCon []]
unsafeToInteger
= unsafeToInteger1
- `cast` (forall (n :: <Nat>_N).
+ `cast` (forall (n ::~ <Nat>_N).
<Signed n>_R %<Many>_N ->_R OpaqueNoCastWW.N:Signed <n>_P
:: (forall (n :: Nat). Signed n -> Signed n)
~R# (forall (n :: Nat). Signed n -> Integer))
--- RHS size: {terms: 8, types: 7, coercions: 21, joins: 0/0}
+-- RHS size: {terms: 8, types: 7, coercions: 19, joins: 0/0}
times [InlPrag=OPAQUE]
:: forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (m + n)
@@ -33,7 +33,7 @@ times
(ds `cast` (OpaqueNoCastWW.N:Signed <m>_P :: Signed m ~R# Integer))
(ds1
`cast` (OpaqueNoCastWW.N:Signed <n>_P :: Signed n ~R# Integer)))
- `cast` (forall (m :: <Nat>_N) (n :: <Nat>_N).
+ `cast` (forall (m ::~ <Nat>_N) (n ::~ <Nat>_N).
<Signed m>_R
%<Many>_N ->_R <Signed n>_R
%<Many>_N ->_R Sym (OpaqueNoCastWW.N:Signed <m + n>_P)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2897da11f158099cb3c6e9834e7fe0c…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2897da11f158099cb3c6e9834e7fe0c…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 2 commits: ghc-internal: invert dependency of GHC.Internal.TH.Syntax on Data.Data
by Marge Bot (@marge-bot) 04 Sep '25
by Marge Bot (@marge-bot) 04 Sep '25
04 Sep '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
39e1b7cb by Teo Camarasu at 2025-09-04T06:32:46-04:00
ghc-internal: invert dependency of GHC.Internal.TH.Syntax on Data.Data
This means that Data.Data no longer blocks building TH.Syntax, which
allows greater parallelism in our builds.
We move the Data.Data.Data instances to Data.Data. Quasi depends on
Data.Data for one of its methods, so,
we split the Quasi/Q, etc definition out of GHC.Internal.TH.Syntax
into its own module. This has the added benefit of splitting up this
quite large module.
Previously TH.Syntax was a bottleneck when compiling ghc-internal. Now
it is less of a bottle-neck and is also slightly quicker to
compile (since it no longer contains these instances) at the cost of
making Data.Data slightly more expensive to compile.
TH.Lift which depends on TH.Syntax can also compile quicker and no
longer blocks ghc-internal finishing to compile.
Resolves #26217
-------------------------
Metric Decrease:
MultiLayerModulesTH_OneShot
T13253
T21839c
T24471
Metric Increase:
T12227
-------------------------
- - - - -
bdf82fd2 by Teo Camarasu at 2025-09-04T06:32:46-04:00
compiler: delete unused names in Builtins.Names.TH
returnQ and bindQ are no longer used in the compiler.
There was also a very old comment that referred to them that I have modernized
- - - - -
36 changed files:
- compiler/GHC/Builtin/Names/TH.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Gen/Splice.hs-boot
- compiler/GHC/Tc/Types/TH.hs
- libraries/base/src/Data/Array/Byte.hs
- libraries/base/src/Data/Fixed.hs
- + libraries/ghc-boot-th/GHC/Boot/TH/Monad.hs
- libraries/ghc-boot-th/ghc-boot-th.cabal.in
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- + libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/TH.hs
- libraries/template-haskell/Language/Haskell/TH/Quote.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- testsuite/tests/deriving/should_compile/T14682.stderr
- testsuite/tests/deriving/should_compile/drv-empty-data.stderr
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- testsuite/tests/plugins/plugins10.stdout
- testsuite/tests/splice-imports/SI29.stderr
- testsuite/tests/th/T11452.stderr
- testsuite/tests/th/T15321.stderr
- testsuite/tests/th/T7276.stderr
- testsuite/tests/th/TH_NestedSplicesFail3.stderr
- testsuite/tests/th/TH_NestedSplicesFail4.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8b2c72c039ddf3eaa292e32556a291…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8b2c72c039ddf3eaa292e32556a291…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] Add Control.Monad.thenM and Control.Applicative.thenA
by Marge Bot (@marge-bot) 04 Sep '25
by Marge Bot (@marge-bot) 04 Sep '25
04 Sep '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
8b2c72c0 by L0neGamer at 2025-09-04T06:32:03-04:00
Add Control.Monad.thenM and Control.Applicative.thenA
- - - - -
11 changed files:
- compiler/GHC/Data/IOEnv.hs
- libraries/base/changelog.md
- libraries/base/src/Control/Applicative.hs
- libraries/base/src/Control/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/Base.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/profiling/should_run/callstack001.stdout
Changes:
=====================================
compiler/GHC/Data/IOEnv.hs
=====================================
@@ -45,7 +45,7 @@ import Data.IORef ( IORef, newIORef, readIORef, writeIORef, modifyIORef,
atomicModifyIORef, atomicModifyIORef' )
import System.IO.Unsafe ( unsafeInterleaveIO )
import System.IO ( fixIO )
-import Control.Monad
+import Control.Monad ( MonadPlus )
import Control.Monad.Trans.Reader
import Control.Monad.Catch (MonadCatch, MonadMask, MonadThrow)
import GHC.Utils.Monad
=====================================
libraries/base/changelog.md
=====================================
@@ -6,6 +6,7 @@
* Fix issues with toRational for types capable to represent infinite and not-a-number values ([CLC proposal #338](https://github.com/haskell/core-libraries-committee/issues/338))
* Modify the implementation of `Data.List.sortOn` to use `(>)` instead of `compare`. ([CLC proposal #332](https://github.com/haskell/core-libraries-committee/issues/332))
* `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
+ * Add `thenA` and `thenM`. ([CLC proposal #351](https://github.com/haskell/core-libraries-committee/issues/351))
* Fix bug where `naturalAndNot` was incorrectly truncating results ([CLC proposal #350](github.com/haskell/core-libraries-committee/issues/350))
* Remove extra laziness from `Data.Bifunctor.Bifunctor` instances for all tuples to have the same laziness as their `Data.Functor.Functor` counterparts (i.e. they became more strict than before) ([CLC proposal #339](https://github.com/haskell/core-libraries-committee/issues/339))
* Adjust the strictness of `Data.List.iterate'` to be more reasonable: every element of the output list is forced to WHNF when the `(:)` containing it is forced. ([CLC proposal #335)](https://github.com/haskell/core-libraries-committee/issues/335)
=====================================
libraries/base/src/Control/Applicative.hs
=====================================
@@ -49,6 +49,7 @@ module Control.Applicative (
liftA, liftA3,
optional,
asum,
+ thenA,
) where
import GHC.Internal.Control.Category hiding ((.), id)
=====================================
libraries/base/src/Control/Monad.hs
=====================================
@@ -57,6 +57,7 @@ module Control.Monad
liftM4,
liftM5,
ap,
+ thenM,
-- ** Strict monadic functions
(<$!>)
) where
=====================================
libraries/ghc-internal/src/GHC/Internal/Base.hs
=====================================
@@ -1223,6 +1223,9 @@ class Functor f => Applicative f where
--
-- As such this function may be used to implement a `Functor` instance from an `Applicative` one.
--
+-- This function can be used to define `fmap = liftA`, if `Applicative` is already
+-- defined for a data type.
+--
-- ==== __Examples__
-- Using the Applicative instance for Lists:
--
@@ -1233,7 +1236,6 @@ class Functor f => Applicative f where
--
-- >>> liftA (+1) (Just 3)
-- Just 4
-
liftA :: Applicative f => (a -> b) -> f a -> f b
liftA f a = pure f <*> a
-- Caution: since this may be used for `fmap`, we can't use the obvious
@@ -1253,6 +1255,18 @@ liftA3 f a b c = liftA2 f a b <*> c
{-# SPECIALISE liftA3 :: (a1->a2->a3->r) ->
Maybe a1 -> Maybe a2 -> Maybe a3 -> Maybe r #-}
+-- | Sequence two `Applicative` actions, discarding the result of the first one.
+--
+-- Defined as `thenA fa fb = (id <$ fa) <*> fb`.
+--
+-- This can be used to explicitly define `(*>) = thenA`, which is the default
+-- definition.
+--
+-- @since 4.23.0.0
+thenA :: Applicative f => f a -> f b -> f b
+thenA fa fb = (id <$ fa) <*> fb
+{-# INLINEABLE thenA #-}
+
-- | The 'join' function is the conventional monad join operator. It
-- is used to remove one level of monadic structure, projecting its
-- bound argument into the outer level.
@@ -1453,12 +1467,18 @@ similar problems in nofib.
-- | Promote a function to a monad.
-- This is equivalent to 'fmap' but specialised to Monads.
+--
+-- This function can be used to define `fmap = liftM`, if `Monad` is already
+-- defined for a data type.
liftM :: (Monad m) => (a1 -> r) -> m a1 -> m r
liftM f m1 = do { x1 <- m1; return (f x1) }
-- | Promote a function to a monad, scanning the monadic arguments from
-- left to right.
--
+-- This function can be used to define `liftA2 = liftM2`, if `Monad` is already
+-- defined for a data type.
+--
-- ==== __Examples__
--
-- >>> liftM2 (+) [0,1] [0,2]
@@ -1514,6 +1534,9 @@ is equivalent to
> liftM<n> f x1 x2 ... xn
+This function can be used to define `(<*>) = ap`, if `Monad` is already
+defined for a data type.
+
==== __Examples__
>>> pure (\x y z -> x + y * z) `ap` Just 1 `ap` Just 5 `ap` Just 10
@@ -1527,6 +1550,17 @@ ap m1 m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) }
{-# SPECIALISE ap :: IO (a -> b) -> IO a -> IO b #-}
{-# SPECIALISE ap :: Maybe (a -> b) -> Maybe a -> Maybe b #-}
+-- | Sequence two monadic actions, discarding the result of the first one.
+--
+-- Defined as `thenM ma mb = ma >>= const mb`.
+--
+-- This can be used to define `(*>) = thenM`.
+--
+-- @since 4.23.0.0
+thenM :: (Monad m) => m a -> m b -> m b
+thenM ma mb = ma >>= const mb
+{-# INLINEABLE thenM #-}
+
-- instances for Prelude types
-- | @since base-2.01
=====================================
libraries/ghc-internal/src/GHC/Internal/Control/Monad.hs
=====================================
@@ -71,6 +71,8 @@ module GHC.Internal.Control.Monad
, ap
+ , thenM
+
-- ** Strict monadic functions
, (<$!>)
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -34,6 +34,7 @@ module Control.Applicative where
liftA :: forall (f :: * -> *) a b. Applicative f => (a -> b) -> f a -> f b
liftA3 :: forall (f :: * -> *) a b c d. Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
optional :: forall (f :: * -> *) a. Alternative f => f a -> f (GHC.Internal.Maybe.Maybe a)
+ thenA :: forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
module Control.Arrow where
-- Safety: Safe
@@ -483,6 +484,7 @@ module Control.Monad where
replicateM_ :: forall (m :: * -> *) a. GHC.Internal.Base.Applicative m => GHC.Internal.Types.Int -> m a -> m ()
sequence :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Traversable.Traversable t, Monad m) => t (m a) -> m (t a)
sequence_ :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Foldable.Foldable t, Monad m) => t (m a) -> m ()
+ thenM :: forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
unless :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
void :: forall (f :: * -> *) a. Functor f => f a -> f ()
when :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -34,6 +34,7 @@ module Control.Applicative where
liftA :: forall (f :: * -> *) a b. Applicative f => (a -> b) -> f a -> f b
liftA3 :: forall (f :: * -> *) a b c d. Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
optional :: forall (f :: * -> *) a. Alternative f => f a -> f (GHC.Internal.Maybe.Maybe a)
+ thenA :: forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
module Control.Arrow where
-- Safety: Safe
@@ -483,6 +484,7 @@ module Control.Monad where
replicateM_ :: forall (m :: * -> *) a. GHC.Internal.Base.Applicative m => GHC.Internal.Types.Int -> m a -> m ()
sequence :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Traversable.Traversable t, Monad m) => t (m a) -> m (t a)
sequence_ :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Foldable.Foldable t, Monad m) => t (m a) -> m ()
+ thenM :: forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
unless :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
void :: forall (f :: * -> *) a. Functor f => f a -> f ()
when :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -34,6 +34,7 @@ module Control.Applicative where
liftA :: forall (f :: * -> *) a b. Applicative f => (a -> b) -> f a -> f b
liftA3 :: forall (f :: * -> *) a b c d. Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
optional :: forall (f :: * -> *) a. Alternative f => f a -> f (GHC.Internal.Maybe.Maybe a)
+ thenA :: forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
module Control.Arrow where
-- Safety: Safe
@@ -483,6 +484,7 @@ module Control.Monad where
replicateM_ :: forall (m :: * -> *) a. GHC.Internal.Base.Applicative m => GHC.Internal.Types.Int -> m a -> m ()
sequence :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Traversable.Traversable t, Monad m) => t (m a) -> m (t a)
sequence_ :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Foldable.Foldable t, Monad m) => t (m a) -> m ()
+ thenM :: forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
unless :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
void :: forall (f :: * -> *) a. Functor f => f a -> f ()
when :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
=====================================
testsuite/tests/interface-stability/base-exports.stdout-ws-32
=====================================
@@ -34,6 +34,7 @@ module Control.Applicative where
liftA :: forall (f :: * -> *) a b. Applicative f => (a -> b) -> f a -> f b
liftA3 :: forall (f :: * -> *) a b c d. Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
optional :: forall (f :: * -> *) a. Alternative f => f a -> f (GHC.Internal.Maybe.Maybe a)
+ thenA :: forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
module Control.Arrow where
-- Safety: Safe
@@ -483,6 +484,7 @@ module Control.Monad where
replicateM_ :: forall (m :: * -> *) a. GHC.Internal.Base.Applicative m => GHC.Internal.Types.Int -> m a -> m ()
sequence :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Traversable.Traversable t, Monad m) => t (m a) -> m (t a)
sequence_ :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Foldable.Foldable t, Monad m) => t (m a) -> m ()
+ thenM :: forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
unless :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
void :: forall (f :: * -> *) a. Functor f => f a -> f ()
when :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
=====================================
testsuite/tests/profiling/should_run/callstack001.stdout
=====================================
@@ -1,2 +1,2 @@
-["GHC.Internal.TopHandler.runMainIO1 (<no location info>)","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","Main.mapM.go (callstack001.hs:13:17-19)","Main.f (callstack001.hs:7:7-49)","Main.f (callstack001.hs:7:10-35)","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1350:5-55)","GHC.Internal.Base.$fMonadIO1 (<no location info>)","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 (<no location info>)"]
-["GHC.Internal.TopHandler.runMainIO1 (<no location info>)","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1350:5-55)","GHC.Internal.Base.$fMonadIO1 (<no location info>)","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 (<no location info>)"]
+["GHC.Internal.TopHandler.runMainIO1 (<no location info>)","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","Main.mapM.go (callstack001.hs:13:17-19)","Main.f (callstack001.hs:7:7-49)","Main.f (callstack001.hs:7:10-35)","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1364:5-55)","GHC.Internal.Base.$fMonadIO1 (<no location info>)","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 (<no location info>)"]
+["GHC.Internal.TopHandler.runMainIO1 (<no location info>)","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1364:5-55)","GHC.Internal.Base.$fMonadIO1 (<no location info>)","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 (<no location info>)"]
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8b2c72c039ddf3eaa292e32556a2918…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8b2c72c039ddf3eaa292e32556a2918…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
04 Sep '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
60a16db7 by Rodrigo Mesquita at 2025-09-03T10:55:50+01:00
bytecode: Don't PUSH_L 0; SLIDE 1 1
While looking through bytecode I noticed a quite common unfortunate
pattern:
...
PUSH_L 0
SLIDE 1 1
We do this often by generically constructing a tail call from a function
atom that may be somewhere arbitrary on the stack.
However, for the special case that the function can be found directly on
top of the stack, as part of the arguments, it's plain redundant to push
then slide it.
In this commit we add a small optimisation to the generation of
tailcalls in bytecode. Simply: lookahead for the function in the stack.
If it is the first thing on the stack and it is part of the arguments
which would be dropped as we entered the tail call, then don't push then
slide it.
In a simple example (T26042b), this already produced a drastic
improvement in generated code (left is old, right is with this patch):
```diff
3c3
< 2025-07-29 10:14:02.081277 UTC
---
> 2025-07-29 10:50:36.560949 UTC
160,161c160
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
164,165d162
< PUSH_L 0
< SLIDE 1 1
175,176c172
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
179,180d174
< PUSH_L 0
< SLIDE 1 1
206,207d199
< PUSH_L 0
< SLIDE 1 1
210,211d201
< PUSH_L 0
< SLIDE 1 1
214,215d203
< PUSH_L 0
< SLIDE 1 1
218,219d205
< PUSH_L 0
< SLIDE 1 1
222,223d207
< PUSH_L 0
< SLIDE 1 1
...
600,601c566
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
604,605d568
< PUSH_L 0
< SLIDE 1 1
632,633d594
< PUSH_L 0
< SLIDE 1 1
636,637d596
< PUSH_L 0
< SLIDE 1 1
640,641d598
< PUSH_L 0
< SLIDE 1 1
644,645d600
< PUSH_L 0
< SLIDE 1 1
648,649d602
< PUSH_L 0
< SLIDE 1 1
652,653d604
< PUSH_L 0
< SLIDE 1 1
656,657d606
< PUSH_L 0
< SLIDE 1 1
660,661d608
< PUSH_L 0
< SLIDE 1 1
664,665d610
< PUSH_L 0
< SLIDE 1 1
```
I also compiled lib:Cabal to bytecode and counted the number of bytecode
lines with `find dist-newstyle -name "*.dump-BCOs" -exec wc {} +`:
with unoptimized core:
1190689 lines (before) - 1172891 lines (now)
= 17798 less redundant instructions (-1.5% lines)
with optimized core:
1924818 lines (before) - 1864836 lines (now)
= 59982 less redundant instructions (-3.1% lines)
- - - - -
1 changed file:
- compiler/GHC/StgToByteCode.hs
Changes:
=====================================
compiler/GHC/StgToByteCode.hs
=====================================
@@ -748,12 +748,21 @@ doTailCall init_d s p fn args = do
where
do_pushes !d [] reps = do
- assert (null reps) return ()
- (push_fn, sz) <- pushAtom d p (StgVarArg fn)
platform <- profilePlatform <$> getProfile
- assert (sz == wordSize platform) return ()
- let slide = mkSlideB platform (d - init_d + wordSize platform) (init_d - s)
- return (push_fn `appOL` (slide `appOL` unitOL ENTER))
+ assert (null reps) return ()
+ case lookupBCEnv_maybe fn p of
+ Just d_v
+ | d - d_v == 0 -- shortcut; the first thing on the stack is what we want to enter,
+ , d_v <= init_d -- and it is between init_d and sequel (which will be dropped)
+ -> do
+ let slide = mkSlideB platform (d - init_d + wordSize platform)
+ (init_d - s - wordSize platform)
+ return (slide `appOL` unitOL ENTER)
+ _ -> do
+ (push_fn, sz) <- pushAtom d p (StgVarArg fn)
+ assert (sz == wordSize platform) return ()
+ let slide = mkSlideB platform (d - init_d + wordSize platform) (init_d - s)
+ return (push_fn `appOL` (slide `appOL` unitOL ENTER))
do_pushes !d args reps = do
let (push_apply, n, rest_of_reps) = findPushSeq reps
(these_args, rest_of_args) = splitAt n args
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/60a16db7cbbe6f37b22eea8ae4d9e79…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/60a16db7cbbe6f37b22eea8ae4d9e79…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26369] 10 commits: cleanup: Move dehydrateCgBreakInfo to Stg2Bc
by Simon Peyton Jones (@simonpj) 04 Sep '25
by Simon Peyton Jones (@simonpj) 04 Sep '25
04 Sep '25
Simon Peyton Jones pushed to branch wip/T26369 at Glasgow Haskell Compiler / GHC
Commits:
79816cc4 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
cleanup: Move dehydrateCgBreakInfo to Stg2Bc
This no longer has anything to do with Core.
- - - - -
53da94ff by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
rts/Disassembler: Fix spacing of BRK_FUN
- - - - -
08c0cf85 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Fix bciPtr in Step-out
We need to use `BCO_NEXT` to move bciPtr to ix=1, because ix=0 points to
the instruction itself!
I do not understand how this didn't crash before.
- - - - -
e7e021fa by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Allow BRK_FUNs to head case continuation BCOs
When we start executing a BCO, we may want to yield to the scheduler:
this may be triggered by a heap/stack check, context switch, or a
breakpoint. To yield, we need to put the stack in a state such that
when execution is resumed we are back to where we yielded from.
Previously, a BKR_FUN could only head a function BCO because we only
knew how to construct a valid stack for yielding from one -- simply add
`apply_interp_info` + the BCO to resume executing. This is valid because
the stack at the start of run_BCO is headed by that BCO's arguments.
However, in case continuation BCOs (as per Note [Case continuation BCOs]),
we couldn't easily reconstruct a valid stack that could be resumed
because we dropped too soon the stack frames regarding the value
returned (stg_ret) and received (stg_ctoi) by that continuation.
This is especially tricky because of the variable type and size return
frames (e.g. pointer ret_p/ctoi_R1p vs a tuple ret_t/ctoi_t2).
The trick to being able to yield from a BRK_FUN at the start of a case
cont BCO is to stop removing the ret frame headers eagerly and instead
keep them until the BCO starts executing. The new layout at the start of
a case cont. BCO is described by the new Note [Stack layout when entering run_BCO].
Now, we keep the ret_* and ctoi_* frames when entering run_BCO.
A BRK_FUN is then executed if found, and the stack is yielded as-is with
the preserved ret and ctoi frames.
Then, a case cont BCO's instructions always SLIDE off the headers of the
ret and ctoi frames, in StgToByteCode.doCase, turning a stack like
| .... |
+---------------+
| fv2 |
+---------------+
| fv1 |
+---------------+
| BCO |
+---------------+
| stg_ctoi_ret_ |
+---------------+
| retval |
+---------------+
| stg_ret_..... |
+---------------+
into
| .... |
+---------------+
| fv2 |
+---------------+
| fv1 |
+---------------+
| retval |
+---------------+
for the remainder of the BCO.
Moreover, this more uniform approach of keeping the ret and ctoi frames
means we need less ad-hoc logic concerning the variable size of
ret_tuple vs ret_p/np frames in the code generator and interpreter:
Always keep the return to cont. stack intact at the start of run_BCO,
and the statically generated instructions will take care of adjusting
it.
Unlocks BRK_FUNs at the start of case cont. BCOs which will enable a
better user-facing step-out (#26042) which is free of the bugs the
current BRK_ALTS implementation suffers from (namely, using BRK_FUN
rather than BRK_ALTS in a case cont. means we'll never accidentally end
up in a breakpoint "deeper" than the continuation, because we stop at
the case cont itself rather than on the first breakpoint we evaluate
after it).
- - - - -
ade3c1e6 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
BRK_FUN with InternalBreakLocs for code-generation time breakpoints
At the start of a case continuation BCO, place a BRK_FUN.
This BRK_FUN uses the new "internal breakpoint location" -- allowing us
to come up with a valid source location for this breakpoint that is not associated with a source-level tick.
For case continuation BCOs, we use the last tick seen before it as the
source location. The reasoning is described in Note [Debugger: Stepout internal break locs].
Note how T26042c, which was broken because it displayed the incorrect
behavior of the previous step out when we'd end up at a deeper level
than the one from which we initiated step-out, is now fixed.
As of this commit, BRK_ALTS is now dead code and is thus dropped.
Note [Debugger: Stepout internal break locs]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Step-out tells the interpreter to run until the current function
returns to where it was called from, and stop there.
This is achieved by enabling the BRK_FUN found on the first RET_BCO
frame on the stack (See [Note Debugger: Step-out]).
Case continuation BCOs (which select an alternative branch) must
therefore be headed by a BRK_FUN. An example:
f x = case g x of <--- end up here
1 -> ...
2 -> ...
g y = ... <--- step out from here
- `g` will return a value to the case continuation BCO in `f`
- The case continuation BCO will receive the value returned from g
- Match on it and push the alternative continuation for that branch
- And then enter that alternative.
If we step-out of `g`, the first RET_BCO on the stack is the case
continuation of `f` -- execution should stop at its start, before
selecting an alternative. (One might ask, "why not enable the breakpoint
in the alternative instead?", because the alternative continuation is
only pushed to the stack *after* it is selected by the case cont. BCO)
However, the case cont. BCO is not associated with any source-level
tick, it is merely the glue code which selects alternatives which do
have source level ticks. Therefore, we have to come up at code
generation time with a breakpoint location ('InternalBreakLoc') to
display to the user when it is stopped there.
Our solution is to use the last tick seen just before reaching the case
continuation. This is robust because a case continuation will thus
always have a relevant breakpoint location:
- The source location will be the last source-relevant expression
executed before the continuation is pushed
- So the source location will point to the thing you've just stepped
out of
- Doing :step-local from there will put you on the selected
alternative (which at the source level may also be the e.g. next
line in a do-block)
Examples, using angle brackets (<<...>>) to denote the breakpoint span:
f x = case <<g x>> {- step in here -} of
1 -> ...
2 -> ...>
g y = <<...>> <--- step out from here
...
f x = <<case g x of <--- end up here, whole case highlighted
1 -> ...
2 -> ...>>
doing :step-local ...
f x = case g x of
1 -> <<...>> <--- stop in the alternative
2 -> ...
A second example based on T26042d2, where the source is a do-block IO
action, optimised to a chain of `case expressions`.
main = do
putStrLn "hello1"
<<f>> <--- step-in here
putStrLn "hello3"
putStrLn "hello4"
f = do
<<putStrLn "hello2.1">> <--- step-out from here
putStrLn "hello2.2"
...
main = do
putStrLn "hello1"
<<f>> <--- end up here again, the previously executed expression
putStrLn "hello3"
putStrLn "hello4"
doing step/step-local ...
main = do
putStrLn "hello1"
f
<<putStrLn "hello3">> <--- straight to the next line
putStrLn "hello4"
Finishes #26042
- - - - -
c66910c0 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Re-use the last BreakpointId whole in step-out
Previously, to come up with a location to stop at for `:stepout`, we
would store the location of the last BreakpointId surrounding the
continuation, as described by Note [Debugger: Stepout internal break locs].
However, re-using just the location from the last source breakpoint
isn't sufficient to provide the necessary information in the break
location. Specifically, it wouldn't bind any variables at that location.
Really, there is no reason not to re-use the last breakpoint wholesale,
and re-use all the information we had there. Step-out should behave just
as if we had stopped at the call, but s.t. continuing will not
re-execute the call.
This commit updates the CgBreakInfo to always store a BreakpointId, be
it the original one or the one we're emulating (for step-out).
It makes variable bindings on :stepout work
- - - - -
e4abed7b by sheaf at 2025-09-02T12:20:40-04:00
Revert accidental changes to hie.yaml
- - - - -
003b715b by meooow25 at 2025-09-02T23:48:51+02:00
Adjust the strictness of Data.List.iterate'
* Don't force the next element in advance when generating a (:).
* Force the first element to WHNF like every other element.
Now every element in the output list is forced to WHNF when the (:)
containing it is forced.
CLC proposal:
https://github.com/haskell/core-libraries-committee/issues/335
- - - - -
b2f6aad0 by Simon Hengel at 2025-09-03T04:36:10-04:00
Refactoring: More consistently use logOutput, logInfo, fatalErrorMsg
- - - - -
79cd6c57 by Simon Peyton Jones at 2025-09-04T10:15:37+01: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.
- - - - -
57 changed files:
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Instr.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/Opt/Arity.hs
- compiler/GHC/Core/Reduction.hs
- compiler/GHC/Core/TyCo/FVs.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/Driver/CodeOutput.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Stg/Lint.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Types/Id/Make.hs
- ghc/GHCi/UI.hs
- hie.yaml
- libraries/base/changelog.md
- libraries/ghc-internal/src/GHC/Internal/List.hs
- libraries/ghci/GHCi/Run.hs
- rts/Disassembler.c
- rts/Interpreter.c
- rts/Profiling.c
- rts/include/rts/Bytecodes.h
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/ghci.debugger/scripts/T26042b.script
- testsuite/tests/ghci.debugger/scripts/T26042b.stdout
- testsuite/tests/ghci.debugger/scripts/T26042c.script
- testsuite/tests/ghci.debugger/scripts/T26042c.stdout
- + testsuite/tests/ghci.debugger/scripts/T26042d2.hs
- + testsuite/tests/ghci.debugger/scripts/T26042d2.script
- + testsuite/tests/ghci.debugger/scripts/T26042d2.stdout
- testsuite/tests/ghci.debugger/scripts/T26042e.stdout
- testsuite/tests/ghci.debugger/scripts/T26042f.script
- testsuite/tests/ghci.debugger/scripts/T26042f1.stdout
- testsuite/tests/ghci.debugger/scripts/T26042f2.stdout
- testsuite/tests/ghci.debugger/scripts/T26042g.stdout
- testsuite/tests/ghci.debugger/scripts/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ef45e941c56f19346e4ff22f870c92…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ef45e941c56f19346e4ff22f870c92…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Add Control.Monad.thenM and Control.Applicative.thenA
by Marge Bot (@marge-bot) 04 Sep '25
by Marge Bot (@marge-bot) 04 Sep '25
04 Sep '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
07cd809c by L0neGamer at 2025-09-04T01:50:52-04:00
Add Control.Monad.thenM and Control.Applicative.thenA
- - - - -
0aa93912 by Teo Camarasu at 2025-09-04T01:50:55-04:00
ghc-internal: invert dependency of GHC.Internal.TH.Syntax on Data.Data
This means that Data.Data no longer blocks building TH.Syntax, which
allows greater parallelism in our builds.
We move the Data.Data.Data instances to Data.Data. Quasi depends on
Data.Data for one of its methods, so,
we split the Quasi/Q, etc definition out of GHC.Internal.TH.Syntax
into its own module. This has the added benefit of splitting up this
quite large module.
Previously TH.Syntax was a bottleneck when compiling ghc-internal. Now
it is less of a bottle-neck and is also slightly quicker to
compile (since it no longer contains these instances) at the cost of
making Data.Data slightly more expensive to compile.
TH.Lift which depends on TH.Syntax can also compile quicker and no
longer blocks ghc-internal finishing to compile.
Resolves #26217
-------------------------
Metric Decrease:
MultiLayerModulesTH_OneShot
T13253
T21839c
T24471
Metric Increase:
T12227
-------------------------
- - - - -
ec472110 by Teo Camarasu at 2025-09-04T01:50:55-04:00
compiler: delete unused names in Builtins.Names.TH
returnQ and bindQ are no longer used in the compiler.
There was also a very old comment that referred to them that I have modernized
- - - - -
43 changed files:
- compiler/GHC/Builtin/Names/TH.hs
- compiler/GHC/Data/IOEnv.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Gen/Splice.hs-boot
- compiler/GHC/Tc/Types/TH.hs
- libraries/base/changelog.md
- libraries/base/src/Control/Applicative.hs
- libraries/base/src/Control/Monad.hs
- libraries/base/src/Data/Array/Byte.hs
- libraries/base/src/Data/Fixed.hs
- + libraries/ghc-boot-th/GHC/Boot/TH/Monad.hs
- libraries/ghc-boot-th/ghc-boot-th.cabal.in
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Base.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- + libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/TH.hs
- libraries/template-haskell/Language/Haskell/TH/Quote.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- testsuite/tests/deriving/should_compile/T14682.stderr
- testsuite/tests/deriving/should_compile/drv-empty-data.stderr
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- testsuite/tests/plugins/plugins10.stdout
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/splice-imports/SI29.stderr
- testsuite/tests/th/T11452.stderr
- testsuite/tests/th/T15321.stderr
- testsuite/tests/th/T7276.stderr
- testsuite/tests/th/TH_NestedSplicesFail3.stderr
- testsuite/tests/th/TH_NestedSplicesFail4.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d0d567245b683a276f700a12992986…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d0d567245b683a276f700a12992986…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Refactoring: More consistently use logOutput, logInfo, fatalErrorMsg
by Marge Bot (@marge-bot) 03 Sep '25
by Marge Bot (@marge-bot) 03 Sep '25
03 Sep '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
b2f6aad0 by Simon Hengel at 2025-09-03T04:36:10-04:00
Refactoring: More consistently use logOutput, logInfo, fatalErrorMsg
- - - - -
60a16db7 by Rodrigo Mesquita at 2025-09-03T10:55:50+01:00
bytecode: Don't PUSH_L 0; SLIDE 1 1
While looking through bytecode I noticed a quite common unfortunate
pattern:
...
PUSH_L 0
SLIDE 1 1
We do this often by generically constructing a tail call from a function
atom that may be somewhere arbitrary on the stack.
However, for the special case that the function can be found directly on
top of the stack, as part of the arguments, it's plain redundant to push
then slide it.
In this commit we add a small optimisation to the generation of
tailcalls in bytecode. Simply: lookahead for the function in the stack.
If it is the first thing on the stack and it is part of the arguments
which would be dropped as we entered the tail call, then don't push then
slide it.
In a simple example (T26042b), this already produced a drastic
improvement in generated code (left is old, right is with this patch):
```diff
3c3
< 2025-07-29 10:14:02.081277 UTC
---
> 2025-07-29 10:50:36.560949 UTC
160,161c160
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
164,165d162
< PUSH_L 0
< SLIDE 1 1
175,176c172
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
179,180d174
< PUSH_L 0
< SLIDE 1 1
206,207d199
< PUSH_L 0
< SLIDE 1 1
210,211d201
< PUSH_L 0
< SLIDE 1 1
214,215d203
< PUSH_L 0
< SLIDE 1 1
218,219d205
< PUSH_L 0
< SLIDE 1 1
222,223d207
< PUSH_L 0
< SLIDE 1 1
...
600,601c566
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
604,605d568
< PUSH_L 0
< SLIDE 1 1
632,633d594
< PUSH_L 0
< SLIDE 1 1
636,637d596
< PUSH_L 0
< SLIDE 1 1
640,641d598
< PUSH_L 0
< SLIDE 1 1
644,645d600
< PUSH_L 0
< SLIDE 1 1
648,649d602
< PUSH_L 0
< SLIDE 1 1
652,653d604
< PUSH_L 0
< SLIDE 1 1
656,657d606
< PUSH_L 0
< SLIDE 1 1
660,661d608
< PUSH_L 0
< SLIDE 1 1
664,665d610
< PUSH_L 0
< SLIDE 1 1
```
I also compiled lib:Cabal to bytecode and counted the number of bytecode
lines with `find dist-newstyle -name "*.dump-BCOs" -exec wc {} +`:
with unoptimized core:
1190689 lines (before) - 1172891 lines (now)
= 17798 less redundant instructions (-1.5% lines)
with optimized core:
1924818 lines (before) - 1864836 lines (now)
= 59982 less redundant instructions (-3.1% lines)
- - - - -
d0d56724 by L0neGamer at 2025-09-03T18:57:25-04:00
Add Control.Monad.thenM and Control.Applicative.thenA
- - - - -
19 changed files:
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Data/IOEnv.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Stg/Lint.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/Tc/Utils/Monad.hs
- libraries/base/changelog.md
- libraries/base/src/Control/Applicative.hs
- libraries/base/src/Control/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/Base.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/profiling/should_run/callstack001.stdout
Changes:
=====================================
compiler/GHC/Core/Lint.hs
=====================================
@@ -26,6 +26,7 @@ module GHC.Core.Lint (
-- ** Debug output
EndPassConfig (..),
endPassIO,
+ lintMessage,
displayLintResults, dumpPassResult
) where
@@ -309,11 +310,6 @@ path does not result in allocation in the hot path. This can be surprisingly
impactful. Changing `lint_app` reduced allocations for one test program I was
looking at by ~4%.
-Note [MCInfo for Lint]
-~~~~~~~~~~~~~~~~~~~~~~
-When printing a Lint message, use the MCInfo severity so that the
-message is printed on stderr rather than stdout (#13342).
-
************************************************************************
* *
Beginning and ending passes
@@ -321,6 +317,12 @@ message is printed on stderr rather than stdout (#13342).
************************************************************************
-}
+lintMessage :: Logger -> SDoc -> IO ()
+lintMessage logger =
+ -- Note: Use logInfo when printing a Lint message, so that the message is
+ -- printed on stderr rather than stdout (#13342).
+ logInfo logger . withPprStyle defaultDumpStyle
+
-- | Configuration for boilerplate operations at the end of a
-- compilation pass producing Core.
data EndPassConfig = EndPassConfig
@@ -436,8 +438,7 @@ displayLintResults :: Logger
-> IO ()
displayLintResults logger display_warnings pp_what pp_pgm (warns, errs)
| not (isEmptyBag errs)
- = do { logMsg logger Err.MCInfo noSrcSpan -- See Note [MCInfo for Lint]
- $ withPprStyle defaultDumpStyle
+ = do { lintMessage logger
(vcat [ lint_banner "errors" pp_what, Err.pprMessageBag errs
, text "*** Offending Program ***"
, pp_pgm
@@ -447,8 +448,7 @@ displayLintResults logger display_warnings pp_what pp_pgm (warns, errs)
| not (isEmptyBag warns)
, log_enable_debug (logFlags logger)
, display_warnings
- = logMsg logger Err.MCInfo noSrcSpan -- See Note [MCInfo for Lint]
- $ withPprStyle defaultDumpStyle
+ = lintMessage logger
(lint_banner "warnings" pp_what $$ Err.pprMessageBag (mapBag ($$ blankLine) warns))
| otherwise = return ()
=====================================
compiler/GHC/Data/IOEnv.hs
=====================================
@@ -45,7 +45,7 @@ import Data.IORef ( IORef, newIORef, readIORef, writeIORef, modifyIORef,
atomicModifyIORef, atomicModifyIORef' )
import System.IO.Unsafe ( unsafeInterleaveIO )
import System.IO ( fixIO )
-import Control.Monad
+import Control.Monad ( MonadPlus )
import Control.Monad.Trans.Reader
import Control.Monad.Catch (MonadCatch, MonadMask, MonadThrow)
import GHC.Utils.Monad
=====================================
compiler/GHC/Driver/CodeOutput.hs
=====================================
@@ -18,6 +18,7 @@ import GHC.Prelude
import GHC.Platform
import GHC.ForeignSrcLang
import GHC.Data.FastString
+import GHC.Core.Lint ( lintMessage )
import GHC.CmmToAsm ( nativeCodeGen )
import GHC.CmmToLlvm ( llvmCodeGen )
@@ -55,7 +56,6 @@ import GHC.Utils.Panic.Plain ( pgmError )
import GHC.Unit
import GHC.Unit.Finder ( mkStubPaths )
-import GHC.Types.SrcLoc
import GHC.Types.CostCentre
import GHC.Types.ForeignStubs
import GHC.Types.Unique.DSM
@@ -109,10 +109,7 @@ codeOutput logger tmpfs llvm_config dflags unit_state this_mod filenm location g
(text "CmmLint"<+>brackets (ppr this_mod))
(const ()) $ do
{ case cmmLint (targetPlatform dflags) cmm of
- Just err -> do { logMsg logger
- MCInfo -- See Note [MCInfo for Lint] in "GHC.Core.Lint"
- noSrcSpan
- $ withPprStyle defaultDumpStyle err
+ Just err -> do { lintMessage logger err
; ghcExit logger 1
}
Nothing -> return ()
=====================================
compiler/GHC/Driver/Pipeline/Execute.hs
=====================================
@@ -1162,7 +1162,7 @@ getHCFilePackages filename =
linkDynLibCheck :: Logger -> TmpFs -> DynFlags -> UnitEnv -> [String] -> [UnitId] -> IO ()
linkDynLibCheck logger tmpfs dflags unit_env o_files dep_units = do
when (haveRtsOptsFlags dflags) $
- logMsg logger MCInfo noSrcSpan
+ logInfo logger
$ withPprStyle defaultUserStyle
(text "Warning: -rtsopts and -with-rtsopts have no effect with -shared." $$
text " Call hs_init_ghc() from your main() function to set these options.")
=====================================
compiler/GHC/Iface/Load.hs
=====================================
@@ -1104,7 +1104,7 @@ For some background on this choice see #15269.
showIface :: Logger -> DynFlags -> UnitState -> NameCache -> FilePath -> IO ()
showIface logger dflags unit_state name_cache filename = do
let profile = targetProfile dflags
- printer = logMsg logger MCOutput noSrcSpan . withPprStyle defaultDumpStyle
+ printer = logOutput logger . withPprStyle defaultDumpStyle
-- skip the hi way check; we don't want to worry about profiled vs.
-- non-profiled interfaces, for example.
=====================================
compiler/GHC/Linker/Loader.hs
=====================================
@@ -508,7 +508,7 @@ classifyLdInput logger platform f
| isObjectFilename platform f = return (Just (Objects [f]))
| isDynLibFilename platform f = return (Just (DLLPath f))
| otherwise = do
- logMsg logger MCInfo noSrcSpan
+ logInfo logger
$ withPprStyle defaultUserStyle
(text ("Warning: ignoring unrecognised input `" ++ f ++ "'"))
return Nothing
=====================================
compiler/GHC/Stg/Lint.hs
=====================================
@@ -104,6 +104,7 @@ import GHC.Stg.Utils
import GHC.Core.DataCon
import GHC.Core ( AltCon(..) )
import GHC.Core.Type
+import GHC.Core.Lint ( lintMessage )
import GHC.Types.Basic ( TopLevelFlag(..), isTopLevel, isMarkedCbv )
import GHC.Types.CostCentre ( isCurrentCCS )
@@ -148,8 +149,7 @@ lintStgTopBindings platform logger diag_opts opts extra_vars this_mod unarised w
Nothing ->
return ()
Just msg -> do
- logMsg logger Err.MCInfo noSrcSpan -- See Note [MCInfo for Lint] in "GHC.Core.Lint"
- $ withPprStyle defaultDumpStyle
+ lintMessage logger
(vcat [ text "*** Stg Lint ErrMsgs: in" <+>
text whodunit <+> text "***",
msg,
=====================================
compiler/GHC/StgToByteCode.hs
=====================================
@@ -748,12 +748,21 @@ doTailCall init_d s p fn args = do
where
do_pushes !d [] reps = do
- assert (null reps) return ()
- (push_fn, sz) <- pushAtom d p (StgVarArg fn)
platform <- profilePlatform <$> getProfile
- assert (sz == wordSize platform) return ()
- let slide = mkSlideB platform (d - init_d + wordSize platform) (init_d - s)
- return (push_fn `appOL` (slide `appOL` unitOL ENTER))
+ assert (null reps) return ()
+ case lookupBCEnv_maybe fn p of
+ Just d_v
+ | d - d_v == 0 -- shortcut; the first thing on the stack is what we want to enter,
+ , d_v <= init_d -- and it is between init_d and sequel (which will be dropped)
+ -> do
+ let slide = mkSlideB platform (d - init_d + wordSize platform)
+ (init_d - s - wordSize platform)
+ return (slide `appOL` unitOL ENTER)
+ _ -> do
+ (push_fn, sz) <- pushAtom d p (StgVarArg fn)
+ assert (sz == wordSize platform) return ()
+ let slide = mkSlideB platform (d - init_d + wordSize platform) (init_d - s)
+ return (push_fn `appOL` (slide `appOL` unitOL ENTER))
do_pushes !d args reps = do
let (push_apply, n, rest_of_reps) = findPushSeq reps
(these_args, rest_of_args) = splitAt n args
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -2351,8 +2351,7 @@ failIfM msg = do
env <- getLclEnv
let full_msg = (if_loc env <> colon) $$ nest 2 msg
logger <- getLogger
- liftIO (logMsg logger MCFatal
- noSrcSpan $ withPprStyle defaultErrStyle full_msg)
+ liftIO $ fatalErrorMsg logger full_msg
failM
--------------------
@@ -2384,10 +2383,7 @@ forkM doc thing_inside
logger <- getLogger
let msg = hang (text "forkM failed:" <+> doc)
2 (text (show exn))
- liftIO $ logMsg logger
- MCFatal
- noSrcSpan
- $ withPprStyle defaultErrStyle msg
+ liftIO $ fatalErrorMsg logger msg
; traceIf (text "} ending fork (badly)" <+> doc)
; pgmError "Cannot continue after interface file error" }
}
=====================================
libraries/base/changelog.md
=====================================
@@ -6,6 +6,7 @@
* Fix issues with toRational for types capable to represent infinite and not-a-number values ([CLC proposal #338](https://github.com/haskell/core-libraries-committee/issues/338))
* Modify the implementation of `Data.List.sortOn` to use `(>)` instead of `compare`. ([CLC proposal #332](https://github.com/haskell/core-libraries-committee/issues/332))
* `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
+ * Add `thenA` and `thenM`. ([CLC proposal #351](https://github.com/haskell/core-libraries-committee/issues/351))
* Fix bug where `naturalAndNot` was incorrectly truncating results ([CLC proposal #350](github.com/haskell/core-libraries-committee/issues/350))
* Remove extra laziness from `Data.Bifunctor.Bifunctor` instances for all tuples to have the same laziness as their `Data.Functor.Functor` counterparts (i.e. they became more strict than before) ([CLC proposal #339](https://github.com/haskell/core-libraries-committee/issues/339))
* Adjust the strictness of `Data.List.iterate'` to be more reasonable: every element of the output list is forced to WHNF when the `(:)` containing it is forced. ([CLC proposal #335)](https://github.com/haskell/core-libraries-committee/issues/335)
=====================================
libraries/base/src/Control/Applicative.hs
=====================================
@@ -49,6 +49,7 @@ module Control.Applicative (
liftA, liftA3,
optional,
asum,
+ thenA,
) where
import GHC.Internal.Control.Category hiding ((.), id)
=====================================
libraries/base/src/Control/Monad.hs
=====================================
@@ -57,6 +57,7 @@ module Control.Monad
liftM4,
liftM5,
ap,
+ thenM,
-- ** Strict monadic functions
(<$!>)
) where
=====================================
libraries/ghc-internal/src/GHC/Internal/Base.hs
=====================================
@@ -1223,6 +1223,9 @@ class Functor f => Applicative f where
--
-- As such this function may be used to implement a `Functor` instance from an `Applicative` one.
--
+-- This function can be used to define `fmap = liftA`, if `Applicative` is already
+-- defined for a data type.
+--
-- ==== __Examples__
-- Using the Applicative instance for Lists:
--
@@ -1233,7 +1236,6 @@ class Functor f => Applicative f where
--
-- >>> liftA (+1) (Just 3)
-- Just 4
-
liftA :: Applicative f => (a -> b) -> f a -> f b
liftA f a = pure f <*> a
-- Caution: since this may be used for `fmap`, we can't use the obvious
@@ -1253,6 +1255,18 @@ liftA3 f a b c = liftA2 f a b <*> c
{-# SPECIALISE liftA3 :: (a1->a2->a3->r) ->
Maybe a1 -> Maybe a2 -> Maybe a3 -> Maybe r #-}
+-- | Sequence two `Applicative` actions, discarding the result of the first one.
+--
+-- Defined as `thenA fa fb = (id <$ fa) <*> fb`.
+--
+-- This can be used to explicitly define `(*>) = thenA`, which is the default
+-- definition.
+--
+-- @since 4.23.0.0
+thenA :: Applicative f => f a -> f b -> f b
+thenA fa fb = (id <$ fa) <*> fb
+{-# INLINEABLE thenA #-}
+
-- | The 'join' function is the conventional monad join operator. It
-- is used to remove one level of monadic structure, projecting its
-- bound argument into the outer level.
@@ -1453,12 +1467,18 @@ similar problems in nofib.
-- | Promote a function to a monad.
-- This is equivalent to 'fmap' but specialised to Monads.
+--
+-- This function can be used to define `fmap = liftM`, if `Monad` is already
+-- defined for a data type.
liftM :: (Monad m) => (a1 -> r) -> m a1 -> m r
liftM f m1 = do { x1 <- m1; return (f x1) }
-- | Promote a function to a monad, scanning the monadic arguments from
-- left to right.
--
+-- This function can be used to define `liftA2 = liftM2`, if `Monad` is already
+-- defined for a data type.
+--
-- ==== __Examples__
--
-- >>> liftM2 (+) [0,1] [0,2]
@@ -1514,6 +1534,9 @@ is equivalent to
> liftM<n> f x1 x2 ... xn
+This function can be used to define `(<*>) = ap`, if `Monad` is already
+defined for a data type.
+
==== __Examples__
>>> pure (\x y z -> x + y * z) `ap` Just 1 `ap` Just 5 `ap` Just 10
@@ -1527,6 +1550,17 @@ ap m1 m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) }
{-# SPECIALISE ap :: IO (a -> b) -> IO a -> IO b #-}
{-# SPECIALISE ap :: Maybe (a -> b) -> Maybe a -> Maybe b #-}
+-- | Sequence two monadic actions, discarding the result of the first one.
+--
+-- Defined as `thenM ma mb = ma >>= const mb`.
+--
+-- This can be used to define `(*>) = thenM`.
+--
+-- @since 4.23.0.0
+thenM :: (Monad m) => m a -> m b -> m b
+thenM ma mb = ma >>= const mb
+{-# INLINEABLE thenM #-}
+
-- instances for Prelude types
-- | @since base-2.01
=====================================
libraries/ghc-internal/src/GHC/Internal/Control/Monad.hs
=====================================
@@ -71,6 +71,8 @@ module GHC.Internal.Control.Monad
, ap
+ , thenM
+
-- ** Strict monadic functions
, (<$!>)
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -34,6 +34,7 @@ module Control.Applicative where
liftA :: forall (f :: * -> *) a b. Applicative f => (a -> b) -> f a -> f b
liftA3 :: forall (f :: * -> *) a b c d. Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
optional :: forall (f :: * -> *) a. Alternative f => f a -> f (GHC.Internal.Maybe.Maybe a)
+ thenA :: forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
module Control.Arrow where
-- Safety: Safe
@@ -483,6 +484,7 @@ module Control.Monad where
replicateM_ :: forall (m :: * -> *) a. GHC.Internal.Base.Applicative m => GHC.Internal.Types.Int -> m a -> m ()
sequence :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Traversable.Traversable t, Monad m) => t (m a) -> m (t a)
sequence_ :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Foldable.Foldable t, Monad m) => t (m a) -> m ()
+ thenM :: forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
unless :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
void :: forall (f :: * -> *) a. Functor f => f a -> f ()
when :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -34,6 +34,7 @@ module Control.Applicative where
liftA :: forall (f :: * -> *) a b. Applicative f => (a -> b) -> f a -> f b
liftA3 :: forall (f :: * -> *) a b c d. Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
optional :: forall (f :: * -> *) a. Alternative f => f a -> f (GHC.Internal.Maybe.Maybe a)
+ thenA :: forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
module Control.Arrow where
-- Safety: Safe
@@ -483,6 +484,7 @@ module Control.Monad where
replicateM_ :: forall (m :: * -> *) a. GHC.Internal.Base.Applicative m => GHC.Internal.Types.Int -> m a -> m ()
sequence :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Traversable.Traversable t, Monad m) => t (m a) -> m (t a)
sequence_ :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Foldable.Foldable t, Monad m) => t (m a) -> m ()
+ thenM :: forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
unless :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
void :: forall (f :: * -> *) a. Functor f => f a -> f ()
when :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -34,6 +34,7 @@ module Control.Applicative where
liftA :: forall (f :: * -> *) a b. Applicative f => (a -> b) -> f a -> f b
liftA3 :: forall (f :: * -> *) a b c d. Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
optional :: forall (f :: * -> *) a. Alternative f => f a -> f (GHC.Internal.Maybe.Maybe a)
+ thenA :: forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
module Control.Arrow where
-- Safety: Safe
@@ -483,6 +484,7 @@ module Control.Monad where
replicateM_ :: forall (m :: * -> *) a. GHC.Internal.Base.Applicative m => GHC.Internal.Types.Int -> m a -> m ()
sequence :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Traversable.Traversable t, Monad m) => t (m a) -> m (t a)
sequence_ :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Foldable.Foldable t, Monad m) => t (m a) -> m ()
+ thenM :: forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
unless :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
void :: forall (f :: * -> *) a. Functor f => f a -> f ()
when :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
=====================================
testsuite/tests/interface-stability/base-exports.stdout-ws-32
=====================================
@@ -34,6 +34,7 @@ module Control.Applicative where
liftA :: forall (f :: * -> *) a b. Applicative f => (a -> b) -> f a -> f b
liftA3 :: forall (f :: * -> *) a b c d. Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
optional :: forall (f :: * -> *) a. Alternative f => f a -> f (GHC.Internal.Maybe.Maybe a)
+ thenA :: forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
module Control.Arrow where
-- Safety: Safe
@@ -483,6 +484,7 @@ module Control.Monad where
replicateM_ :: forall (m :: * -> *) a. GHC.Internal.Base.Applicative m => GHC.Internal.Types.Int -> m a -> m ()
sequence :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Traversable.Traversable t, Monad m) => t (m a) -> m (t a)
sequence_ :: forall (t :: * -> *) (m :: * -> *) a. (GHC.Internal.Data.Foldable.Foldable t, Monad m) => t (m a) -> m ()
+ thenM :: forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
unless :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
void :: forall (f :: * -> *) a. Functor f => f a -> f ()
when :: forall (f :: * -> *). GHC.Internal.Base.Applicative f => GHC.Internal.Types.Bool -> f () -> f ()
=====================================
testsuite/tests/profiling/should_run/callstack001.stdout
=====================================
@@ -1,2 +1,2 @@
-["GHC.Internal.TopHandler.runMainIO1 (<no location info>)","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","Main.mapM.go (callstack001.hs:13:17-19)","Main.f (callstack001.hs:7:7-49)","Main.f (callstack001.hs:7:10-35)","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1350:5-55)","GHC.Internal.Base.$fMonadIO1 (<no location info>)","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 (<no location info>)"]
-["GHC.Internal.TopHandler.runMainIO1 (<no location info>)","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1350:5-55)","GHC.Internal.Base.$fMonadIO1 (<no location info>)","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 (<no location info>)"]
+["GHC.Internal.TopHandler.runMainIO1 (<no location info>)","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","Main.mapM.go (callstack001.hs:13:17-19)","Main.f (callstack001.hs:7:7-49)","Main.f (callstack001.hs:7:10-35)","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1364:5-55)","GHC.Internal.Base.$fMonadIO1 (<no location info>)","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 (<no location info>)"]
+["GHC.Internal.TopHandler.runMainIO1 (<no location info>)","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1364:5-55)","GHC.Internal.Base.$fMonadIO1 (<no location info>)","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 (<no location info>)"]
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fa557b8706ddf89b28f87675dcbded…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fa557b8706ddf89b28f87675dcbded…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T20264] 215 commits: Consider `PromotedDataCon` in `tyConStupidTheta`
by Simon Peyton Jones (@simonpj) 03 Sep '25
by Simon Peyton Jones (@simonpj) 03 Sep '25
03 Sep '25
Simon Peyton Jones pushed to branch wip/T20264 at Glasgow Haskell Compiler / GHC
Commits:
8d33d048 by Berk Özkütük at 2025-07-07T20:42:20-04:00
Consider `PromotedDataCon` in `tyConStupidTheta`
Haddock checks data declarations for the stupid theta so as not to
pretty-print them as empty contexts. Type data declarations end up as
`PromotedDataCon`s by the time Haddock performs this check, causing a
panic. This commit extends `tyConStupidTheta` so that it returns an
empty list for `PromotedDataCon`s. This decision was guided by the fact
that type data declarations never have data type contexts (see (R1) in
Note [Type data declarations]).
Fixes #25739.
- - - - -
a26243fd by Ryan Hendrickson at 2025-07-07T20:43:07-04:00
haddock: Document instances from other packages
When attaching instances to `Interface`s, it isn't enough just to look
for instances in the list of `Interface`s being processed. We also need
to look in the modules on which they depend, including those outside of
this package.
Fixes #25147.
Fixes #26079.
- - - - -
0fb24420 by Rodrigo Mesquita at 2025-07-07T20:43:49-04:00
hadrian: Fallback logic for internal interpreter
When determining whether to build the internal interpreter, the `make`
build system had a fallback case for platforms not in the list of
explicitly-supported operating systems and architectures.
This fallback says we should try to build the internal interpreter if
building dynamic GHC programs (if the architecture is unknown).
Fixes #24098
- - - - -
fe925bd4 by Ben Gamari at 2025-07-07T20:44:30-04:00
users-guide: Reference Wasm FFI section
- - - - -
5856284b by Ben Gamari at 2025-07-07T20:44:30-04:00
users-guide: Fix too-short heading warning
- - - - -
a48dcdf3 by Duncan Coutts at 2025-07-07T20:45:18-04:00
Reorganise documentation for allocate* functions
Consolodate interface information into the .h file, keeping just
implementation details in the .c file.
Use Notes stlye in the .h file and refer to notes from the .c file.
- - - - -
de5b528c by Duncan Coutts at 2025-07-07T20:45:18-04:00
Introduce common utilities for allocating arrays
The intention is to share code among the several places that do this
already.
- - - - -
b321319d by Duncan Coutts at 2025-07-07T20:45:18-04:00
Use new array alloc utils in Heap.c
The CMM primop can now report heap overflow.
- - - - -
1d557ffb by Duncan Coutts at 2025-07-07T20:45:18-04:00
Use new array alloc utils in ThreadLabels.c
Replacing a local utility.
- - - - -
e59a1430 by Duncan Coutts at 2025-07-07T20:45:18-04:00
Use new array alloc utils in Threads.c
Replacing local open coded version.
- - - - -
482df1c9 by Duncan Coutts at 2025-07-07T20:45:18-04:00
Add exitHeapOverflow helper utility
This will be useful with the array alloc functions, since unlike
allocate/allocateMaybeFail, they do not come in two versions. So if it's
not convenient to propagate failure, then one can use this.
- - - - -
4d3ec8f9 by Duncan Coutts at 2025-07-07T20:45:18-04:00
Use new array alloc utils in Weak.c
Also add a cpp macro CCS_SYSTEM_OR_NULL which does what it says. The
benefit of this is that it allows us to referece CCS_SYSTEM even when
we're not in PROFILING mode. That makes abstracting over profiling vs
normal mode a lot easier.
- - - - -
0c4f2fde by Duncan Coutts at 2025-07-07T20:45:18-04:00
Convert the array alloc primops to use the new array alloc utils
- - - - -
a3354ad9 by Duncan Coutts at 2025-07-07T20:45:18-04:00
While we're at it, add one missing 'likely' hint
To a cmm primops that raises an exception, like the others now do.
- - - - -
33b546bd by meooow25 at 2025-07-07T20:46:09-04:00
Keep scanl' strict in the head on rewrite
`scanl'` forces elements to WHNF when the corresponding `(:)`s are
forced. The rewrite rule for `scanl'` missed forcing the first element,
which is fixed here with a `seq`.
- - - - -
8a69196e by Rodrigo Mesquita at 2025-07-08T07:39:47-04:00
debugger/rts: Allow toggling step-in per thread
The RTS global flag `rts_stop_next_breakpoint` globally sets the
interpreter to stop at the immediate next breakpoint.
With this commit, single step mode can additionally be set per thread in
the TSO flag (TSO_STOP_NEXT_BREAKPOINT).
Being able to toggle "stop at next breakpoint" per thread is an
important requirement for implementing "stepping out" of a function in a
multi-threaded context.
And, more generally, having a per-thread flag for single-stepping paves the
way for multi-threaded debugging.
That said, when we want to enable "single step" mode for the whole
interpreted program we still want to stop at the immediate next
breakpoint, whichever thread it belongs to.
That's why we also keep the global `rts_stop_next_breakpoint` flag, with
`rts_enableStopNextBreakpointAll` and `rts_disableStopNextBreakpointAll` helpers.
Preparation for #26042
- - - - -
73d3f864 by Rodrigo Mesquita at 2025-07-08T07:39:47-04:00
docs: Case continuation BCOs
This commit documents a subtle interaction between frames for case BCOs
and their parents frames. Namely, case continuation BCOs may refer to
(non-local) variables that are part of the parent's frame.
The note expanding a bit on these details is called [Case continuation BCOs]
- - - - -
d7aeddcf by Rodrigo Mesquita at 2025-07-08T07:39:47-04:00
debugger: Implement step-out feature
Implements support for stepping-out of a function (aka breaking right after
returning from a function) in the interactive debugger.
It also introduces a GHCi command :stepout to step-out of a function
being debugged in the interpreter. The feature is described as:
Stop at the first breakpoint immediately after returning from the current
function scope.
Known limitations: because a function tail-call does not push a stack
frame, if step-out is used inside of a function that was tail-called,
execution will not be returned to its caller, but rather its caller's
first non-tail caller. On the other hand, it means the debugger
follows the more realistic execution of the program.
In the following example:
.. code-block:: none
f = do
a
b <--- (1) set breakpoint then step in here
c
b = do
...
d <--- (2) step-into this tail call
d = do
...
something <--- (3) step-out here
...
Stepping-out will stop execution at the `c` invokation in `f`, rather than
stopping at `b`.
The key idea is simple: When step-out is enabled, traverse the runtime
stack until a continuation BCO is found -- and enable the breakpoint
heading that BCO explicitly using its tick-index.
The details are specified in `Note [Debugger: Step-out]` in `rts/Interpreter.c`.
Since PUSH_ALTS BCOs (representing case continuations) were never headed
by a breakpoint (unlike the case alternatives they push), we introduced
the BRK_ALTS instruction to allow the debugger to set a case
continuation to stop at the breakpoint heading the alternative that is
taken. This is further described in `Note [Debugger: BRK_ALTS]`.
Fixes #26042
- - - - -
5d9adf51 by Rodrigo Mesquita at 2025-07-08T07:39:47-04:00
debugger: Filter step-out stops by SrcSpan
To implement step-out, the RTS looks for the first continuation frame on
the stack and explicitly enables its entry breakpoint. However, some
continuations will be contained in the function from which step-out was
initiated (trivial example is a case expression).
Similarly to steplocal, we will filter the breakpoints at which the RTS
yields to the debugger based on the SrcSpan. When doing step-out, only
stop if the breakpoint is /not/ contained in the function from which we
initiated it.
This is especially relevant in monadic statements such as IO which is
compiled to a long chain of case expressions.
See Note [Debugger: Filtering step-out stops]
- - - - -
7677adcc by Cheng Shao at 2025-07-08T07:40:29-04:00
compiler: make ModBreaks serializable
- - - - -
14f67c6d by Rodrigo Mesquita at 2025-07-08T07:40:29-04:00
refactor: "Inspecting the session" moved from GHC
Moved utilities for inspecting the session from the GHC module to
GHC.Driver.Session.Inspect
Purely a clean up
- - - - -
9d3f484a by Rodrigo Mesquita at 2025-07-08T07:40:30-04:00
cleanup: Pass the HUG to readModBreaks, not HscEnv
A minor cleanup. The associated history and setupBreakpoint functions
are changed accordingly.
- - - - -
b595f713 by Rodrigo Mesquita at 2025-07-08T07:40:30-04:00
cleanup: Move readModBreaks to GHC.Runtime.Interpreter
With some small docs changes
- - - - -
d223227a by Rodrigo Mesquita at 2025-07-08T07:40:30-04:00
cleanup: Move interpreterProfiled to Interp.Types
Moves interpreterProfiled and interpreterDynamic to
GHC.Runtime.Interpreter.Types from GHC.Runtime.Interpreter.
- - - - -
7fdd0a3d by Rodrigo Mesquita at 2025-07-08T07:40:30-04:00
cleanup: Don't import GHC in Debugger.Breakpoints
Remove the top-level
import GHC
from GHC.Runtime.Debugger.Breakpoints
This makes the module dependencies more granular and cleans up the
qualified imports from the code.
- - - - -
5e4da31b by Rodrigo Mesquita at 2025-07-08T07:40:30-04:00
refactor: Use BreakpointId in Core and Ifaces
- - - - -
741ac3a8 by Rodrigo Mesquita at 2025-07-08T07:40:30-04:00
stg2bc: Derive BcM via ReaderT StateT
A small refactor that simplifies GHC.StgToByteCode by deriving-via the
Monad instances for BcM. This is done along the lines of previous
similar refactors like 72b54c0760bbf85be1f73c1a364d4701e5720465.
- - - - -
0414fcc9 by Rodrigo Mesquita at 2025-07-08T07:40:30-04:00
refact: Split InternalModBreaks out of ModBreaks
There are currently two competing ways of referring to a Breakpoint:
1. Using the Tick module + Tick index
2. Using the Info module + Info index
1. The Tick index is allocated during desugaring in `mkModBreaks`. It is
used to refer to a breakpoint associated to a Core Tick. For a given
Tick module, there are N Ticks indexed by Tick index.
2. The Info index is allocated during code generation (in StgToByteCode)
and uniquely identifies the breakpoints at runtime (and is indeed used
to determine which breakpoint was hit at runtime).
Why we need both is described by Note [Breakpoint identifiers].
For every info index we used to keep a `CgBreakInfo`, a datatype containing
information relevant to ByteCode Generation, in `ModBreaks`.
This commit splits out the `IntMap CgBreakInfo` out of `ModBreaks` into
a new datatype `InternalModBreaks`.
- The purpose is to separate the `ModBreaks` datatype, which stores
data associated from tick-level information which is fixed after
desugaring, from the unrelated `IntMap CgBreakInfo` information
accumulated during bytecode generation.
- We move `ModBreaks` to GHC.HsToCore.Breakpoints
The new `InternalModBreaks` simply combines the `IntMap CgBreakInfo`
with `ModBreaks`. After code generation we construct an
`InternalModBreaks` with the `CgBreakInfo`s we accumulated and the
existing `ModBreaks` and store that in the compiled BCO in `bc_breaks`.
- Note that we previously only updated the `modBreaks_breakInfo`
field of `ModBreaks` at this exact location, and then stored the
updated `ModBreaks` in the same `bc_breaks`.
- We put this new datatype in GHC.ByteCode.Breakpoints
The rest of the pipeline for which CgBreakInfo is relevant is
accordingly updated to also use `InternalModBreaks`
- - - - -
2a097955 by Rodrigo Mesquita at 2025-07-08T07:40:30-04:00
cleanup: Use BreakpointIds in bytecode gen
Small clean up to use BreakpointId and InternalBreakpointId more
uniformly in bytecode generation rather than using Module + Ix pairs
- - - - -
0515cc2f by Rodrigo Mesquita at 2025-07-08T07:40:30-04:00
ghci: Allocate BreakArrays at link time only
Previously, a BreakArray would be allocated with a slot for every tick
in a module at `mkModBreaks`, in HsToCore. However, this approach has
a few downsides:
- It interleaves interpreter behaviour (allocating arrays for
breakpoints) within the desugarer
- It is inflexible in the sense it is impossible for the bytecode
generator to add "internal" breakpoints that can be triggered at
runtime, because those wouldn't have a source tick. (This is relevant
for our intended implementation plan of step-out in #26042)
- It ties the BreakArray indices to the *tick* indexes, while at runtime
we would rather just have the *info* indexes (currently we have both
because BreakArrays are indexed by the *tick* one).
Paving the way for #26042 and #26064, this commit moves the allocation
of BreakArrays to bytecode-loading time -- akin to what is done for CCS
arrays.
Since a BreakArray is allocated only when bytecode is linked, if a
breakpoint is set (e.g. `:break 10`) before the bytecode is linked,
there will exist no BreakArray to trigger the breakpoint in.
Therefore, the function to allocate break arrays (`allocateBreakArrays`)
is exposed and also used in GHC.Runtime.Eval to allocate a break array
when a breakpoint is set, if it doesn't exist yet (in the linker env).
- - - - -
8016561f by Simon Peyton Jones at 2025-07-08T07:41:13-04:00
Add a test for T26176
- - - - -
454cd682 by Simon Peyton Jones at 2025-07-08T07:41:13-04:00
Add test for #14010
This test started to work in GHC 9.6 and has worked since.
This MR just adds a regression test
- - - - -
ea2c6673 by Teo Camarasu at 2025-07-08T13:24:43-04:00
Implement user-defined allocation limit handlers
Allocation Limits allow killing a thread if they allocate more than a
user-specified limit.
We extend this feature to allow more versatile behaviour.
- We allow not killing the thread if the limit is exceeded.
- We allow setting a custom handler to be called when the limit is exceeded.
User-specified allocation limit handlers run in a fresh thread and are passed
the ThreadId of the thread that exceeded its limit.
We introduce utility functions for getting and setting the allocation
limits of other threads, so that users can reset the limit of a thread
from a handler. Both of these are somewhat coarse-grained as we are
unaware of the allocations in the current nursery chunk.
We provide several examples of usages in testsuite/tests/rts/T22859.hs
Resolves #22859
- - - - -
03e047f9 by Simon Hengel at 2025-07-08T13:25:25-04:00
Fix typo in using.rst
- - - - -
67957854 by Ben Gamari at 2025-07-09T09:44:44-04:00
compiler: Import AnnotationWrapper from ghc-internal
Since `GHC.Desugar` exported from `base` has been deprecated.
- - - - -
813d99d6 by Ben Gamari at 2025-07-09T09:44:44-04:00
ghc-compact: Eliminate dependency on ghc-prim
- - - - -
0ec952a1 by Ben Gamari at 2025-07-09T09:44:44-04:00
ghc-heap: Eliminate dependency on ghc-prim
- - - - -
480074c3 by Ben Gamari at 2025-07-09T09:44:44-04:00
ghc-heap: Drop redundant import
- - - - -
03455829 by Ben Gamari at 2025-07-09T09:44:45-04:00
ghc-prim: Bump version to 0.13.1
There are no interface changes from 0.13.0 but the implementation now
lives in `ghc-internal`.
- - - - -
d315345a by Ben Gamari at 2025-07-09T09:44:45-04:00
template-haskell: Bump version number to 2.24.0.0
Bumps exceptions submodule.
- - - - -
004c800e by Ben Gamari at 2025-07-09T09:44:45-04:00
Bump GHC version number to 9.14
- - - - -
eb1a3816 by Ben Gamari at 2025-07-09T09:44:45-04:00
Bump parsec to 3.1.18.0
Bumps parsec submodule.
- - - - -
86f83296 by Ben Gamari at 2025-07-09T09:44:45-04:00
unix: Bump to 2.8.7.0
Bumps unix submodule.
- - - - -
89e13998 by Ben Gamari at 2025-07-09T09:44:45-04:00
binary: Bump to 0.8.9.3
Bumps binary submodule.
- - - - -
55fff191 by Ben Gamari at 2025-07-09T09:44:45-04:00
Win32: Bump to 2.14.2.0
Bumps Win32 submodule.
- - - - -
7dafa40c by Ben Gamari at 2025-07-09T09:44:45-04:00
base: Bump version to 4.22.0
Bumps various submodules.
- - - - -
ef03d8b8 by Rodrigo Mesquita at 2025-07-09T09:45:28-04:00
base: Export displayExceptionWithInfo
This function should be exposed from base following CLC#285
Approved change in CLC#344
Fixes #26058
- - - - -
01d3154e by Wen Kokke at 2025-07-10T17:06:36+01:00
Fix documentation for HEAP_PROF_SAMPLE_STRING
- - - - -
ac259c48 by Wen Kokke at 2025-07-10T17:06:38+01:00
Fix documentation for HEAP_PROF_SAMPLE_COST_CENTRE
- - - - -
2b4db9ba by Pi Delport at 2025-07-11T16:40:52-04:00
(Applicative docs typo: missing "one")
- - - - -
f707bab4 by Andreas Klebinger at 2025-07-12T14:56:16+01:00
Specialise: Improve specialisation by refactoring interestingDict
This MR addresses #26051, which concerns missed type-class specialisation.
The main payload of the MR is to completely refactor the key function
`interestingDict` in GHC.Core.Opt.Specialise
The main change is that we now also look at the structure of the
dictionary we consider specializing on, rather than only the type.
See the big `Note [Interesting dictionary arguments]`
- - - - -
ca7a9d42 by Simon Peyton Jones at 2025-07-12T14:56:16+01:00
Treat tuple dictionaries uniformly; don't unbox them
See `Note [Do not unbox class dictionaries]` in DmdAnal.hs,
sep (DNB1).
This MR reverses the plan in #23398, which suggested a special case to
unbox tuple dictionaries in worker/wrapper. But:
- This was the cause of a pile of complexity in the specialiser (#26158)
- Even with that complexity, specialision was still bad, very bad
See https://gitlab.haskell.org/ghc/ghc/-/issues/19747#note_626297
And it's entirely unnecessary! Specialision works fine without
unboxing tuple dictionaries.
- - - - -
be7296c9 by Andreas Klebinger at 2025-07-12T14:56:16+01:00
Remove complex special case from the type-class specialiser
There was a pretty tricky special case in Specialise which is no
longer necessary.
* Historical Note [Floating dictionaries out of cases]
* #26158
* #19747 https://gitlab.haskell.org/ghc/ghc/-/issues/19747#note_626297
This MR removes it. Hooray.
- - - - -
4acf3a86 by Ben Gamari at 2025-07-15T05:46:32-04:00
configure: bump version to 9.15
- - - - -
45efaf71 by Teo Camarasu at 2025-07-15T05:47:13-04:00
rts/nonmovingGC: remove n_free
We remove the nonmovingHeap.n_free variable.
We wanted this to track the length of nonmovingHeap.free.
But this isn't possible to do atomically.
When this isn't accurate we can get a segfault by going past the end of
the list.
Instead, we just count the length of the list when we grab it in
nonmovingPruneFreeSegment.
Resolves #26186
- - - - -
c635f164 by Ben Gamari at 2025-07-15T14:05:54-04:00
configure: Drop probing of ld.gold
As noted in #25716, `gold` has been dropped from binutils-2.44.
Fixes #25716.
Metric Increase:
size_hello_artifact_gzip
size_hello_unicode_gzip
ghc_prim_so
- - - - -
637bb538 by Ben Gamari at 2025-07-15T14:05:55-04:00
testsuite/recomp015: Ignore stderr
This is necessary since ld.bfd complains
that we don't have a .note.GNU-stack section,
potentially resulting in an executable stack.
- - - - -
d3cd4ec8 by Wen Kokke at 2025-07-15T14:06:39-04:00
Fix documentation for heap profile ID
- - - - -
73082769 by Ben Gamari at 2025-07-15T16:56:38-04:00
Bump win32-tarballs to v0.9
- - - - -
3b63b254 by Ben Gamari at 2025-07-15T16:56:39-04:00
rts/LoadArchive: Handle null terminated string tables
As of `llvm-ar` now emits filename tables terminated with null
characters instead of the usual POSIX `/\n` sequence.
Fixes #26150.
- - - - -
195f6527 by Tamar Christina at 2025-07-15T16:56:39-04:00
rts: rename label so name doesn't conflict with param
- - - - -
63373b95 by Tamar Christina at 2025-07-15T16:56:39-04:00
rts: Handle API set symbol versioning conflicts
- - - - -
48e9aa3e by Tamar Christina at 2025-07-15T16:56:39-04:00
rts: Mark API set symbols as HIDDEN and correct symbol type
- - - - -
959e827a by Tamar Christina at 2025-07-15T16:56:39-04:00
rts: Implement WEAK EXTERNAL undef redirection by target symbol name
- - - - -
65f19293 by Ben Gamari at 2025-07-15T16:56:39-04:00
rts/LoadArchive: Handle string table entries terminated with /
llvm-ar appears to terminate string table entries with `/\n` [1]. This
matters in the case of thin archives, since the filename is used. In the
past this worked since `llvm-ar` would produce archives with "small"
filenames when possible. However, now it appears to always use the
string table.
[1] https://github.com/llvm/llvm-project/blob/bfb686bb5ba503e9386dc899e1ebbe248…
- - - - -
9cbb3ef5 by Ben Gamari at 2025-07-15T16:56:39-04:00
testsuite: Mark T12497 as fixed
Thanks to the LLVM toolchain update.
Closes #22694.
- - - - -
2854407e by Ben Gamari at 2025-07-15T16:56:39-04:00
testsuite: Accept new output of T11223_link_order_a_b_2_fail on Windows
The archive member number changed due to the fact that llvm-ar now uses a
string table.
- - - - -
28439593 by Ben Gamari at 2025-07-15T16:56:39-04:00
rts/linker/PEi386: Implement IMAGE_REL_AMD64_SECREL
This appears to now be used by libc++ as distributed by msys2.
- - - - -
2b053755 by Tamar Christina at 2025-07-15T16:56:39-04:00
rts: Cleanup merge resolution residue in lookupSymbolInDLL_PEi386 and make safe without dependent
- - - - -
e8acd2e7 by Wen Kokke at 2025-07-16T08:37:04-04:00
Remove the `profile_id` parameter from various RTS functions.
Various RTS functions took a `profile_id` parameter, intended to be used to
distinguish parallel heap profile breakdowns (e.g., `-hT` and `-hi`). However,
this feature was never implemented and the `profile_id` parameter was set to 0
throughout the RTS. This commit removes the parameter but leaves the hardcoded
profile ID in the functions that emit the encoded eventlog events as to not
change the protocol.
The affected functions are `traceHeapProfBegin`, `postHeapProfBegin`,
`traceHeapProfSampleString`, `postHeapProfSampleString`,
`traceHeapProfSampleCostCentre`, and `postHeapProfSampleCostCentre`.
- - - - -
76d392a2 by Wen Kokke at 2025-07-16T08:37:04-04:00
Make `traceHeapProfBegin` an init event.
- - - - -
bbaa44a7 by Peng Fan at 2025-07-16T16:50:42-04:00
NCG/LA64: Support finer-grained DBAR hints
For LA664 and newer uarchs, they have made finer granularity hints
available:
Bit4: ordering or completion (0: completion, 1: ordering)
Bit3: barrier for previous read (0: true, 1: false)
Bit2: barrier for previous write (0: true, 1: false)
Bit1: barrier for succeeding read (0: true, 1: false)
Bit0: barrier for succeeding write (0: true, 1: false)
And not affect the existing models because other hints are treated
as 'dbar 0' there.
- - - - -
7da86e16 by Andreas Klebinger at 2025-07-16T16:51:25-04:00
Disable -fprof-late-overloaded-calls for join points.
Currently GHC considers cost centres as destructive to
join contexts. Or in other words this is not considered valid:
join f x = ...
in
... -> scc<tick> jmp
This makes the functionality of `-fprof-late-overloaded-calls` not feasible
for join points in general. We used to try to work around this by putting the
ticks on the rhs of the join point rather than around the jump. However beyond
the loss of accuracy this was broken for recursive join points as we ended up
with something like:
rec-join f x = scc<tick> ... jmp f x
Which similarly is not valid as the tick once again destroys the tail call.
One might think we could limit ourselves to non-recursive tail calls and do
something clever like:
join f x = scc<tick> ...
in ... jmp f x
And sometimes this works! But sometimes the full rhs would look something like:
join g x = ....
join f x = scc<tick> ... -> jmp g x
Which, would again no longer be valid. I believe in the long run we can make
cost centre ticks non-destructive to join points. Or we could keep track of
where we are/are not allowed to insert a cost centre. But in the short term I will
simply disable the annotation of join calls under this flag.
- - - - -
7ee22fd5 by ARATA Mizuki at 2025-07-17T06:05:30-04:00
x86 NCG: Better lowering for shuffleFloatX4# and shuffleDoubleX2#
The new implementation
* make use of specialized instructions like (V)UNPCK{L,H}{PS,PD}, and
* do not require -mavx.
Close #26096
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
c6cd2da1 by Jappie Klooster at 2025-07-17T06:06:20-04:00
Update interact docs to explain about buffering
We need to tell the user to set to the
appropriate buffer format.
Otherwise, this function may get randomly stuck,
or just behave confusingly.
issue: https://gitlab.haskell.org/ghc/ghc/-/issues/26131
NB, I'm running this with cabal *NOT* ghci. ghci messes with buffering anyway.
```haskell
interaction :: String -> String
interaction "jappie" = "hi"
interaction "jakob" = "hello"
interaction x = "unkown input: " <> x
main :: IO ()
main = interact interaction
```
so in my input (prefixed by `>`) I get:
```
> jappie
unkown input: jappie
```
we confirmed later this was due to lack of \n matching.
Anyway movnig on to more unexpected stuff:
```haskell
main :: IO ()
main = do
interact (concatMap interaction . lines)
```
get's stuck forever.
actually `^D` (ctrl+d) unstucks it and runs all input as expected.
for example you can get:
```
> sdfkds
> fakdsf
unkown input: sdfkdsunkown input: fakdsf
```
This program works!
```haskell
interaction :: String -> String
interaction "jappie" = "hi \n"
interaction "jakob" = "hello \n"
interaction x = "unkown input: " <> x <> "\n"
main :: IO ()
main = do
interact (concatMap interaction . lines)
```
the reason is that linebuffering is set for both in and output by default.
so lines eats the input lines, and all the \n postfixes make sure the buffer
is put out.
- - - - -
9fa590a6 by Zubin Duggal at 2025-07-17T06:07:03-04:00
fetch_gitlab: Ensure we copy users_guide.pdf and Haddock.pdf to the release docs directory
Fixes #24093
- - - - -
cc650b4b by Andrew Lelechenko at 2025-07-17T12:30:24-04:00
Add Data.List.NonEmpty.mapMaybe
As per https://github.com/haskell/core-libraries-committee/issues/337
- - - - -
360fa82c by Duncan Coutts at 2025-07-17T12:31:14-04:00
base: Deprecate GHC.Weak.Finalize.runFinalizerBatch
https://github.com/haskell/core-libraries-committee/issues/342
- - - - -
f4e8466c by Alan Zimmerman at 2025-07-17T12:31:55-04:00
EPA: Update exact printing based on GHC 9.14 tests
As a result of migrating the GHC ghc-9.14 branch tests to
ghc-exactprint in
https://github.com/alanz/ghc-exactprint/tree/ghc-9.14, a couple of
discrepancies were picked up
- The opening paren for a DefaultDecl was printed in the wrong place
- The import declaration level specifiers were not printed.
This commit adds those fixes, and some tests for them.
The tests brought to light that the ImportDecl ppr instance had not
been updated for level specifiers, so it updates that too.
- - - - -
8b731e3c by Matthew Pickering at 2025-07-21T13:36:43-04:00
level imports: Fix infinite loop with cyclic module imports
I didn't anticipate that downsweep would run before we checked for
cyclic imports. Therefore we need to use the reachability function which
handles cyclic graphs.
Fixes #26087
- - - - -
d751a9f1 by Pierre Thierry at 2025-07-21T13:37:28-04:00
Fix documentation about deriving from generics
- - - - -
f8d9d016 by Andrew Lelechenko at 2025-07-22T21:13:28-04:00
Fix issues with toRational for types capable to represent infinite and not-a-number values
This commit fixes all of the following pitfalls:
> toRational (read "Infinity" :: Double)
179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216 % 1
> toRational (read "NaN" :: Double)
269653970229347386159395778618353710042696546841345985910145121736599013708251444699062715983611304031680170819807090036488184653221624933739271145959211186566651840137298227914453329401869141179179624428127508653257226023513694322210869665811240855745025766026879447359920868907719574457253034494436336205824 % 1
> realToFrac (read "NaN" :: Double) -- With -O0
Infinity
> realToFrac (read "NaN" :: Double) -- With -O1
NaN
> realToFrac (read "NaN" :: Double) :: CDouble
Infinity
> realToFrac (read "NaN" :: CDouble) :: Double
Infinity
Implements https://github.com/haskell/core-libraries-committee/issues/338
- - - - -
5dabc718 by Zubin Duggal at 2025-07-22T21:14:10-04:00
haddock: Don't warn about missing link destinations for derived names.
Fixes #26114
- - - - -
9c3a0937 by Matthew Pickering at 2025-07-22T21:14:52-04:00
template haskell: use a precise condition when implicitly lifting
Implicit lifting corrects a level error by replacing references to `x`
with `$(lift x)`, therefore you can use a level `n` binding at level `n
+ 1`, if it can be lifted.
Therefore, we now have a precise check that the use level is 1 more than
the bind level.
Before this bug was not observable as you only had 0 and 1 contexts but
it is easily evident when using explicit level imports.
Fixes #26088
- - - - -
5144b22f by Andreas Klebinger at 2025-07-22T21:15:34-04:00
Add since tag and more docs for do-clever-arg-eta-expansion
Fixes #26113
- - - - -
c865623b by Andreas Klebinger at 2025-07-22T21:15:34-04:00
Add since tag for -fexpose-overloaded-unfoldings
Fixes #26112
- - - - -
49a44ab7 by Simon Hengel at 2025-07-23T17:59:55+07:00
Refactor GHC.Driver.Errors.printMessages
- - - - -
84711c39 by Simon Hengel at 2025-07-23T18:27:34+07:00
Respect `-fdiagnostics-as-json` for error messages from pre-processors
(fixes #25480)
- - - - -
d046b5ab by Simon Hengel at 2025-07-24T06:12:05-04:00
Include the rendered message in -fdiagnostics-as-json output
This implements #26173.
- - - - -
d2b89603 by Ben Gamari at 2025-07-24T06:12:47-04:00
rts/Interpreter: Factor out ctoi tuple info tables into data
Instead of a massive case let's put this into data which we can reuse
elsewhere.
- - - - -
4bc78496 by Sebastian Graf at 2025-07-24T16:19:34-04:00
CprAnal: Detect recursive newtypes (#25944)
While `cprTransformDataConWork` handles recursive data con workers, it
did not detect the case when a newtype is responsible for the recursion.
This is now detected in the `Cast` case of `cprAnal`.
The same reproducer made it clear that `isRecDataCon` lacked congruent
handling for `AppTy` and `CastTy`, now fixed.
Furthermore, the new repro case T25944 triggered this bug via an
infinite loop in `cprFix`, caused by the infelicity in `isRecDataCon`.
While it should be much less likely to trigger such an infinite loop now
that `isRecDataCon` has been fixed, I made sure to abort the loop after
10 iterations and emitting a warning instead.
Fixes #25944.
- - - - -
0a583689 by Sylvain Henry at 2025-07-24T16:20:26-04:00
STM: don't create a transaction in the rhs of catchRetry# (#26028)
We don't need to create a transaction for the rhs of (catchRetry#)
because contrary to the lhs we don't need to abort it on retry. Moreover
it is particularly harmful if we have code such as (#26028):
let cN = readTVar vN >> retry
tree = c1 `orElse` (c2 `orElse` (c3 `orElse` ...))
atomically tree
Because it will stack transactions for the rhss and the read-sets of all
the transactions will be iteratively merged in O(n^2) after the
execution of the most nested retry.
- - - - -
a49eca26 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Renaming around predicate types
.. we were (as it turned out) abstracting over
type-class selectors in SPECIALISATION rules!
Wibble isEqPred
- - - - -
f80375dd by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Refactor of Specialise.hs
This patch just tidies up `specHeader` a bit, removing one
of its many results, and adding some comments.
No change in behaviour.
Also add a few more `HasDebugCallStack` contexts.
- - - - -
1bd12371 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Improve treatment of SPECIALISE pragmas -- again!
This MR does another major refactor of the way that SPECIALISE
pragmas work, to fix #26115, #26116, #26117.
* We now /always/ solve forall-constraints in an all-or-nothing way.
See Note [Solving a Wanted forall-constraint] in GHC.Tc.Solver.Solve
This means we might have unsolved quantified constraints, which need
to be reported. See `inert_insts` in `getUnsolvedInerts`.
* I refactored the short-cut solver for type classes to work by
recursively calling the solver rather than by having a little baby
solver that kept being not clever enough.
See Note [Shortcut solving] in GHC.Tc.Solver.Dict
* I totally rewrote the desugaring of SPECIALISE pragmas, again.
The new story is in Note [Desugaring new-form SPECIALISE pragmas]
in GHC.HsToCore.Binds
Both old-form and new-form SPECIALISE pragmas now route through the same
function `dsSpec_help`. The tricky function `decomposeRuleLhs` is now used only
for user-written RULES, not for SPECIALISE pragmas.
* I improved `solveOneFromTheOther` to account for rewriter sets. Previously
it would solve a non-rewritten dict from a rewritten one. For equalities
we were already dealing with this, in
Some incidental refactoring
* A small refactor: `ebv_tcvs` in `EvBindsBar` now has a list of coercions, rather
than a set of tyvars. We just delay taking the free vars.
* GHC.Core.FVs.exprFVs now returns /all/ free vars.
Use `exprLocalFVs` for Local vars.
Reason: I wanted another variant for /evidence/ variables.
* Ues `EvId` in preference to `EvVar`. (Evidence variables are always Ids.)
Rename `isEvVar` to `isEvId`.
* I moved `inert_safehask` out of `InertCans` and into `InertSet` where it
more properly belongs.
Compiler-perf changes:
* There was a palpable bug (#26117) which this MR fixes in
newWantedEvVar, which bypassed all the subtle overlapping-Given
and shortcutting logic. (See the new `newWantedEvVar`.) Fixing this
but leads to extra dictionary bindings; they are optimised away quickly
but they made CoOpt_Read allocate 3.6% more.
* Hpapily T15164 improves.
* The net compiler-allocation change is 0.0%
Metric Decrease:
T15164
Metric Increase:
CoOpt_Read
T12425
- - - - -
953fd8f1 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Solve forall-constraints immediately, or not at all
This MR refactors the constraint solver to solve forall-constraints immediately,
rather than emitting an implication constraint to be solved later.
The most immediate motivation was that when solving quantified constraints
in SPECIALISE pragmas, we really really don't want to leave behind half-
solved implications. Also it's in tune with the approach of the new
short-cut solver, which recursively invokes the solver.
It /also/ saves quite a bit of plumbing; e.g
- The `wl_implics` field of `WorkList` is gone,
- The types of `solveSimpleWanteds` and friends are simplified.
- An EvFun contains binding, rather than an EvBindsVar ref-cell that
will in the future contain bindings. That makes `evVarsOfTerm`
simpler. Much nicer.
It also improves error messages a bit.
All described in Note [Solving a Wanted forall-constraint] in
GHC.Tc.Solver.Solve.
One tiresome point: in the tricky case of `inferConstraintsCoerceBased`
we make a forall-constraint. This we /do/ want to partially solve, so
we can infer a suitable context. (I'd be quite happy to force the user to
write a context, bt I don't want to change behavior.) So we want to generate
an /implication/ constraint in `emitPredSpecConstraints` rather than a
/forall-constraint/ as we were doing before. Discussed in (WFA3) of
the above Note.
Incidental refactoring
* `GHC.Tc.Deriv.Infer.inferConstraints` was consulting the state monad for
the DerivEnv that the caller had just consulted. Nicer to pass it as an
argument I think, so I have done that. No change in behaviour.
- - - - -
6921ab42 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Remove duplicated code in Ast.hs for evTermFreeVars
This is just a tidy up.
- - - - -
1165f587 by Simon Peyton Jones at 2025-07-25T09:49:58+01:00
Small tc-tracing changes only
- - - - -
0776ffe0 by Simon Hengel at 2025-07-26T04:54:20-04:00
Respect `-fdiagnostics-as-json` for core diagnostics (see #24113)
- - - - -
cc1116e0 by Andrew Lelechenko at 2025-07-26T04:55:01-04:00
docs: add since pragma to Data.List.NonEmpty.mapMaybe
- - - - -
ee2dc248 by Simon Hengel at 2025-07-31T06:25:35-04:00
Update comments on `OptKind` to reflect the code reality
- - - - -
b029633a by Wen Kokke at 2025-07-31T06:26:21-04:00
rts: Disable --eventlog-flush-interval unless compiled with -threaded.
This commit fixes issue #26222:
Using --eventlog-flush-interval with the non-threaded RTS leads to eventlog corruption.
https://gitlab.haskell.org/ghc/ghc/-/issues/26222
This commit makes three changes when code is compiled against the non-threaded RTS:
1. It disables the --eventlog-flush-interval flag.
2. It disables the documentation for the --eventlog-flush-interval flag.
3. It disables the relevant state from RtsConfig and code from Timer.
4. It updates the entry for --eventlog-flush-interval in the users guide.
- - - - -
31159f1d by Wen Kokke at 2025-07-31T06:26:21-04:00
rts: Split T20006 into tests with and without -threaded
- - - - -
618687ef by Simon Hengel at 2025-07-31T06:27:03-04:00
docs/users_guide/win32-dlls.rst: Remove references to `readline`
- - - - -
083e40f1 by Rodrigo Mesquita at 2025-08-01T04:38:23-04:00
debugger: Uniquely identify breakpoints by internal id
Since b85b11994e0130ff2401dd4bbdf52330e0bcf776 (support inlining
breakpoints), a breakpoint has been identified at runtime by *two* pairs
of <module,index>.
- The first, aka a 'BreakpointId', uniquely identifies a breakpoint in
the source of a module by using the Tick index. A Tick index can index
into ModBreaks.modBreaks_xxx to fetch source-level information about
where that tick originated.
- When a user specifies e.g. a line breakpoint using :break, we'll reverse
engineer what a Tick index for that line
- We update the `BreakArray` of that module (got from the
LoaderState) at that tick index to `breakOn`.
- A BCO we can stop at is headed by a BRK_FUN instruction. This
instruction stores in an operand the `tick index` it is associated
to. We look it up in the associated `BreakArray` (also an operand)
and check wheter it was set to `breakOn`.
- The second, aka the `ibi_info_mod` + `ibi_info_ix` of the
`InternalBreakpointId`, uniquely index into the `imodBreaks_breakInfo`
-- the information we gathered during code generation about the
existing breakpoint *ocurrences*.
- Note that with optimisation there may be many occurrences of the
same source-tick-breakpoint across different modules. The
`ibi_info_ix` is unique per occurrence, but the `bi_tick_ix` may be
shared. See Note [Breakpoint identifiers] about this.
- Note that besides the tick ids, info ids are also stored in
`BRK_FUN` so the break handler can refer to the associated
`CgBreakInfo`.
In light of that, the driving changes come from the desire to have the
info_id uniquely identify the breakpoint at runtime, and the source tick
id being derived from it:
- An InternalBreakpointId should uniquely identify a breakpoint just
from the code-generation identifiers of `ibi_info_ix` and `ibi_info_mod`.
So we drop `ibi_tick_mod` and `ibi_tick_ix`.
- A BRK_FUN instruction need only record the "internal breakpoint id",
not the tick-level id.
So we drop the tick mod and tick index operands.
- A BreakArray should be indexed by InternalBreakpointId rather than
BreakpointId
That means we need to do some more work when setting a breakpoint.
Specifically, we need to figure out the internal ids (occurrences of a
breakpoint) from the source-level BreakpointId we want to set the
breakpoint at (recall :break refers to breaks at the source level).
Besides this change being an improvement to the handling of breakpoints
(it's clearer to have a single unique identifier than two competing
ones), it unlocks the possibility of generating "internal" breakpoints
during Cg (needed for #26042).
It should also be easier to introduce multi-threaded-aware `BreakArrays`
following this change (needed for #26064).
Se also the new Note [ModBreaks vs InternalModBreaks]
On i386-linux:
-------------------------
Metric Decrease:
interpreter_steplocal
-------------------------
- - - - -
bf03bbaa by Simon Hengel at 2025-08-01T04:39:05-04:00
Don't use MCDiagnostic for `ghcExit`
This changes the error message of `ghcExit` from
```
<no location info>: error:
Compilation had errors
```
to
```
Compilation had errors
```
- - - - -
a889ec75 by Simon Hengel at 2025-08-01T04:39:05-04:00
Respect `-fdiagnostics-as-json` for driver diagnostics (see #24113)
- - - - -
81577fe7 by Ben Gamari at 2025-08-02T04:29:39-04:00
configure: Allow override of CrossCompiling
As noted in #26236, the current inference logic is a bit simplistic. In
particular, there are many cases (e.g. building for a new libc) where
the target and host triples may differ yet we are still able to run the
produced artifacts as native code.
Closes #26236.
- - - - -
01136779 by Andreas Klebinger at 2025-08-02T04:30:20-04:00
rts: Support COFF BigObj files in archives.
- - - - -
1f9e4f54 by Stephen Morgan at 2025-08-03T15:14:08+10:00
refactor: Modify Data.List.sortOn to use (>) instead of compare. (#26184)
This lets a more efficient (>) operation be used if one exists.
This is technically a breaking change for malformed Ord instances, where
x > y is not equivalent to compare x y == GT.
Discussed by the CLC in issue #332: https://github.com/haskell/core-libraries-committee/issues/332
- - - - -
4f6bc9cf by fendor at 2025-08-04T17:50:06-04:00
Revert "base: Expose Backtraces constructor and fields"
This reverts commit 17db44c5b32fff82ea988fa4f1a233d1a27bdf57.
- - - - -
bcdec657 by Zubin Duggal at 2025-08-05T10:37:29+05:30
compiler: Export a version of `newNameCache` that is not prone to footguns.
`newNameCache` must be initialized with both a non-"reserved" unique tag, as well
as a list of known key names. Failing to do so results in hard to debug unique conflicts.
It is difficult for API users to tell which unique tags are safe to use. So instead of leaving
this up to the user to decide, we now export a version of `newNameCache` which uses a guaranteed
non-reserved unique tag. In fact, this is now the way the unique tag is initialized for all invocations
of the compiler.
The original version of `newNameCache` is now exported as `newNameCache'` for advanced users.
We also deprecate `initNameCache` as it is also prone to footguns and is completely subsumed in
functionality by `newNameCache` and `newNameCache'`.
Fixes #26135 and #26055
- - - - -
57d3b4a8 by Andrew Lelechenko at 2025-08-05T18:36:31-04:00
hadrian: bump Stackage snapshot to LTS 24.2 / GHC 9.10.2
In line with #25693 we should use GHC 9.10 as a boot compiler,
while Hadrian stack.yaml was stuck on GHC 9.6.
- - - - -
c2a78cea by Peng Fan at 2025-08-05T18:37:27-04:00
NCG/LA64: implement atomic write with finer-grained DBAR hints
Signed-off-by: Peng Fan <fanpeng(a)loongson.cn>
- - - - -
95231c8e by Teo Camarasu at 2025-08-06T08:35:58-04:00
CODEOWNERS: add CLC as codeowner of base
We also remove hvr, since I think he is no longer active
- - - - -
77df0ded by Andrew Lelechenko at 2025-08-06T08:36:39-04:00
Bump submodule text to 2.1.3
- - - - -
8af260d0 by Nikolaos Chatzikonstantinou at 2025-08-06T08:37:23-04:00
docs: fix internal import in getopt examples
This external-facing doc example shouldn't mention GHC internals when
using 'fromMaybe'.
- - - - -
69cc16ca by Marc Scholten at 2025-08-06T15:51:28-04:00
README: Add note on ghc.nix
- - - - -
93a2f450 by Daniel Díaz at 2025-08-06T15:52:14-04:00
Link to the "Strict Bindings" docs from the linear types docs
Strict Bidings are relevant for the kinds of multiplicity annotations
linear lets support.
- - - - -
246b7853 by Matthew Pickering at 2025-08-07T06:58:30-04:00
level imports: Check the level of exported identifiers
The level imports specification states that exported identifiers have to
be at level 0. This patch adds the requird level checks that all
explicitly mentioned identifiers occur at level 0.
For implicit export specifications (T(..) and module B), only level 0
identifiers are selected for re-export.
ghc-proposal: https://github.com/ghc-proposals/ghc-proposals/pull/705
Fixes #26090
- - - - -
358bc4fc by fendor at 2025-08-07T06:59:12-04:00
Bump GHC on darwin CI to 9.10.1
- - - - -
1903ae35 by Matthew Pickering at 2025-08-07T12:21:10+01:00
ipe: Place strings and metadata into specific .ipe section
By placing the .ipe metadata into a specific section it can be stripped
from the final binary if desired.
```
objcopy --remove-section .ipe <binary>
upx <binary>
```
Towards #21766
- - - - -
c80dd91c by Matthew Pickering at 2025-08-07T12:22:42+01:00
ipe: Place magic word at the start of entries in the .ipe section
The magic word "IPE\nIPE\n" is placed at the start of .ipe sections,
then if the section is stripped, we can check whether the section starts
with the magic word or not to determine whether there is metadata
present or not.
Towards #21766
- - - - -
cab42666 by Matthew Pickering at 2025-08-07T12:22:42+01:00
ipe: Use stable IDs for IPE entries
IPEs have historically been indexed and reported by their address.
This makes it impossible to compare profiles between runs, since the
addresses may change (due to ASLR) and also makes it tricky to separate
out the IPE map from the binary.
This small patch adds a stable identifier for each IPE entry.
The stable identifier is a single 64 bit word. The high-bits are a
per-module identifier and the low bits identify which entry in each
module.
1. When a node is added into the IPE buffer it is assigned a unique
identifier from an incrementing global counter.
2. Each entry already has an index by it's position in the
`IpeBufferListNode`.
The two are combined together by the `IPE_ENTRY_KEY` macro.
Info table profiling uses the stable identifier rather than the address
of the info table.
The benefits of this change are:
* Profiles from different runs can be easily compared
* The metadata can be extracted from the binary (via the eventlog for
example) and then stripped from the executable.
Fixes #21766
- - - - -
2860a9a5 by Simon Peyton Jones at 2025-08-07T20:29:18-04:00
In TcSShortCut, typechecker plugins should get empty Givens
Solving in TcShortCut mode means /ignoring the Givens/. So we
should not pass them to typechecker plugins!
Fixes #26258.
This is a fixup to the earlier MR:
commit 1bd12371feacc52394a0e660ef9349f9e8ee1c06
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Jul 21 10:04:49 2025 +0100
Improve treatment of SPECIALISE pragmas -- again!
- - - - -
2157db2d by sterni at 2025-08-08T15:32:39-04:00
hadrian: enable terminfo if --with-curses-* flags are given
The GHC make build system used to support WITH_TERMINFO in ghc.mk which
allowed controlling whether to build GHC with terminfo or not. hadrian
has replaced this with a system where this is effectively controlled by
the cross-compiling setting (the default WITH_TERMINFO value was bassed
on CrossCompiling, iirc).
This behavior is undesireable in some cases and there is not really a
good way to work around it. Especially for downstream packagers,
modifying this via UserSettings is not really feasible since such a
source file has to be kept in sync with Settings/Default.hs manually
since it can't import Settings.Default or any predefined Flavour
definitions.
To avoid having to add a new setting to cfg/system.config and/or a new
configure flag (though I'm happy to implement both if required), I've
chosen to take --with-curses-* being set explicitly as an indication
that the user wants to have terminfo enabled. This would work for
Nixpkgs which sets these flags [1] as well as haskell.nix [2] (which
goes to some extreme measures [3] [4] to force terminfo in all scenarios).
In general, I'm an advocate for making the GHC build be the same for
native and cross insofar it is possible since it makes packaging GHC and
Haskell related things while still supporting cross much less
compilicated. A more minimal GHC with reduced dependencies should
probably be a specific flavor, not the default.
Partially addresses #26288 by forcing terminfo to be built if the user
explicitly passes configure flags related to it. However, it isn't built
by default when cross-compiling yet nor is there an explicit way to
control the package being built.
[1]: https://github.com/NixOS/nixpkgs/blob/3a7266fcefcb9ce353df49ba3f292d0644376…
[2]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
[3]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
[4]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
- - - - -
b3c31488 by David Feuer at 2025-08-08T15:33:21-04:00
Add default QuasiQuoters
Add `defaultQuasiQuoter` and `namedDefaultQuasiQuoter` to make it easier
to write `QuasiQuoters` that give helpful error messages when they're
used in inappropriate contexts.
Closes #24434.
- - - - -
03555ed8 by Sylvain Henry at 2025-08-10T22:20:57-04:00
Handle non-fractional CmmFloats in Cmm's CBE (#26229)
Since f8d9d016305be355f518c141f6c6d4826f2de9a2, toRational for Float and
Double converts float's infinity and NaN into Rational's infinity and
NaN (respectively 1%0 and 0%0).
Cmm CommonBlockEliminator hashing function needs to take these values
into account as they can appear as literals now. See added testcase.
- - - - -
6c956af3 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Fix extensions list in `DoAndIfThenElse` docs
- - - - -
6dc420b1 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Document status of `RelaxedPolyRec` extension
This adds a brief extension page explaining the status of the
`RelaxedPolyRec` extension. The behaviour of this mode is already
explained elsewhere, so this page is mainly for completeness so that
various lists of extensions have somewhere to point to for this flag.
Fixes #18630
- - - - -
18036d52 by Simon Peyton Jones at 2025-08-11T11:31:20-04:00
Take more care in zonkEqTypes on AppTy/AppTy
This patch fixes #26256.
See Note [zonkEqTypes and the PKTI] in GHC.Tc.Solver.Equality
- - - - -
c8d76a29 by Zubin Duggal at 2025-08-11T11:32:02-04:00
ci: upgrade bootstrap compiler on windows to 9.10.1
- - - - -
34fc50c1 by Ben Gamari at 2025-08-11T13:36:25-04:00
Kill IOPort#
This type is unnecessary, having been superceded by `MVar` and a rework
of WinIO's blocking logic.
See #20947.
See https://github.com/haskell/core-libraries-committee/issues/213.
- - - - -
56b32c5a by sheaf at 2025-08-12T10:00:19-04:00
Improve deep subsumption
This commit improves the DeepSubsumption sub-typing implementation
in GHC.Tc.Utils.Unify.tc_sub_type_deep by being less eager to fall back
to unification.
For example, we now are properly able to prove the subtyping relationship
((∀ a. a->a) -> Int) -> Bool <= β[tau] Bool
for an unfilled metavariable β. In this case (with an AppTy on the right),
we used to fall back to unification. No longer: now, given that the LHS
is a FunTy and that the RHS is a deep rho type (does not need any instantiation),
we try to make the RHS into a FunTy, viz.
β := (->) γ
We can then continue using covariance & contravariance of the function
arrow, which allows us to prove the subtyping relationship, instead of
trying to unify which would cause us to error out with:
Couldn't match expected type ‘β’ with actual type ‘(->) ((∀ a. a -> a) -> Int)
See Note [FunTy vs non-FunTy case in tc_sub_type_deep] in GHC.Tc.Utils.Unify.
The other main improvement in this patch concerns type inference.
The main subsumption logic happens (before & after this patch) in
GHC.Tc.Gen.App.checkResultTy. However, before this patch, all of the
DeepSubsumption logic only kicked in in 'check' mode, not in 'infer' mode.
This patch adds deep instantiation in the 'infer' mode of checkResultTy
when we are doing deep subsumption, which allows us to accept programs
such as:
f :: Int -> (forall a. a->a)
g :: Int -> Bool -> Bool
test1 b =
case b of
True -> f
False -> g
test2 b =
case b of
True -> g
False -> f
See Note [Deeply instantiate in checkResultTy when inferring].
Finally, we add representation-polymorphism checks to ensure that the
lambda abstractions we introduce when doing subsumption obey the
representation polymorphism invariants of Note [Representation polymorphism invariants]
in GHC.Core. See Note [FunTy vs FunTy case in tc_sub_type_deep].
This is accompanied by a courtesy change to `(<.>) :: HsWrapper -> HsWrapper -> HsWrapper`,
adding the equation:
WpCast c1 <.> WpCast c2 = WpCast (c1 `mkTransCo` c2)
This is useful because mkWpFun does not introduce an eta-expansion when
both of the argument & result wrappers are casts; so this change allows
us to avoid introducing lambda abstractions when casts suffice.
Fixes #26225
- - - - -
d175aff8 by Sylvain Henry at 2025-08-12T10:01:31-04:00
Add regression test for #18619
- - - - -
a3983a26 by Sylvain Henry at 2025-08-12T10:02:20-04:00
RTS: remove some TSAN annotations (#20464)
Use RELAXED_LOAD_ALWAYS macro instead.
- - - - -
0434af81 by Ben Gamari at 2025-08-12T10:03:02-04:00
Bump time submodule to 1.15
Also required bumps of Cabal, directory, and hpc.
- - - - -
62899117 by Florian Ragwitz at 2025-08-13T21:01:34-04:00
Extend record-selector usage ticking to all binds using a record field
This extends the previous handling of ticking for RecordWildCards and
NamedFieldPuns to all var bindings that involve record selectors.
Note that certain patterns such as `Foo{foo = 42}` will currently not tick the
`foo` selector, as ticking is triggered by `HsVar`s.
Closes #26191.
- - - - -
b37b3af7 by Florian Ragwitz at 2025-08-13T21:01:34-04:00
Add release notes for 9.16.1 and move description of latest HPC changes there.
- - - - -
a5e4b7d9 by Ben Gamari at 2025-08-13T21:02:18-04:00
rts: Clarify rationale for undefined atomic wrappers
Since c06e3f46d24ef69f3a3d794f5f604cb8c2a40cbc the RTS has declared
various atomic operation wrappers defined by ghc-internal as undefined.
While the rationale for this isn't clear from the commit message, I
believe that this is necessary due to the unregisterised backend.
Specifically, the code generator will reference these symbols when
compiling RTS Cmm sources.
- - - - -
50842f83 by Andreas Klebinger at 2025-08-13T21:03:01-04:00
Make unexpected LLVM versions a warning rather than an error.
Typically a newer LLVM version *will* work so erroring out if
a user uses a newer LLVM version is too aggressive.
Fixes #25915
- - - - -
c91e2650 by fendor at 2025-08-13T21:03:43-04:00
Store `StackTrace` and `StackSnapshot` in `Backtraces`
Instead of decoding the stack traces when collecting the `Backtraces`,
defer this decoding until actually showing the `Backtraces`.
This allows users to customise how `Backtraces` are displayed by
using a custom implementation of `displayExceptionWithInfo`, overwriting
the default implementation for `Backtraces` (`displayBacktraces`).
- - - - -
dee28cdd by fendor at 2025-08-13T21:03:43-04:00
Allow users to customise the collection of exception annotations
Add a global `CollectExceptionAnnotationMechanism` which determines how
`ExceptionAnnotation`s are collected upon throwing an `Exception`.
This API is exposed via `ghc-experimental`.
By overriding how we collect `Backtraces`, we can control how the
`Backtraces` are displayed to the user by newtyping `Backtraces` and
giving a different instance for `ExceptionAnnotation`.
A concrete use-case for this feature is allowing us to experiment with
alternative stack decoders, without having to modify `base`, which take
additional information from the stack frames.
This commit does not modify how `Backtraces` are currently
collected or displayed.
- - - - -
66024722 by fendor at 2025-08-13T21:03:43-04:00
Expose Backtraces internals from ghc-experimental
Additionally, expose the same API `base:Control.Exception.Backtrace`
to make it easier to use as a drop-in replacement.
- - - - -
a766286f by Reed Mullanix at 2025-08-13T21:04:36-04:00
ghc-internal: Fix naturalAndNot for NB/NS case
When the first argument to `naturalAndNot` is larger than a `Word` and the second is `Word`-sized, `naturalAndNot` will truncate the
result:
```
>>> naturalAndNot ((2 ^ 65) .|. (2 ^ 3)) (2 ^ 3)
0
```
In contrast, `naturalAndNot` does not truncate when both arguments are larger than a `Word`, so this appears to be a bug.
Luckily, the fix is pretty easy: we just need to call `bigNatAndNotWord#` instead of truncating.
Fixes #26230
- - - - -
3506fa7d by Simon Hengel at 2025-08-13T21:05:18-04:00
Report -pgms as a deprecated flag
(instead of reporting an unspecific warning)
Before:
on the commandline: warning:
Object splitting was removed in GHC 8.8
After:
on the commandline: warning: [GHC-53692] [-Wdeprecated-flags]
-pgms is deprecated: Object splitting was removed in GHC 8.8
- - - - -
51c701fe by Zubin Duggal at 2025-08-13T21:06:00-04:00
testsuite: Be more permissive when filtering out GNU_PROPERTY_TYPE linker warnings
The warning text is slightly different with ld.bfd.
Fixes #26249
- - - - -
dfe6f464 by Simon Hengel at 2025-08-13T21:06:43-04:00
Refactoring: Don't misuse `MCDiagnostic` for lint messages
`MCDiagnostic` is meant to be used for compiler diagnostics.
Any code that creates `MCDiagnostic` directly, without going through
`GHC.Driver.Errors.printMessage`, side steps `-fdiagnostics-as-json`
(see e.g. !14475, !14492 !14548).
To avoid this in the future I want to control more narrowly who creates
`MCDiagnostic` (see #24113).
Some parts of the compiler use `MCDiagnostic` purely for formatting
purposes, without creating any real compiler diagnostics. This change
introduces a helper function, `formatDiagnostic`, that can be used in
such cases instead of constructing `MCDiagnostic`.
- - - - -
a8b2fbae by Teo Camarasu at 2025-08-13T21:07:24-04:00
rts: ensure MessageBlackHole.link is always a valid closure
We turn a MessageBlackHole into an StgInd in wakeBlockingQueue().
Therefore it's important that the link field, which becomes the
indirection field, always points to a valid closure.
It's unclear whether it's currently possible for the previous behaviour
to lead to a crash, but it's good to be consistent about this invariant nonetheless.
Co-authored-by: Andreas Klebinger <klebinger.andreas(a)gmx.at>
- - - - -
4021181e by Teo Camarasu at 2025-08-13T21:07:24-04:00
rts: spin if we see a WHITEHOLE in messageBlackHole
When a BLACKHOLE gets cancelled in raiseAsync, we indirect to a THUNK.
GC can then shortcut this, replacing our BLACKHOLE with a fresh THUNK.
This THUNK is not guaranteed to have a valid indirectee field.
If at the same time, a message intended for the previous BLACKHOLE is
processed and concurrently we BLACKHOLE the THUNK, thus temporarily
turning it into a WHITEHOLE, we can get a segfault, since we look at the
undefined indirectee field of the THUNK
The fix is simple: spin if we see a WHITEHOLE, and it will soon be
replaced with a valid BLACKHOLE.
Resolves #26205
- - - - -
1107af89 by Oleg Grenrus at 2025-08-13T21:08:06-04:00
Allow defining HasField instances for naughty fields
Resolves #26295
... as HasField solver doesn't solve for fields with "naughty"
selectors, we could as well allow defining HasField instances for these
fields.
- - - - -
020e7587 by Sylvain Henry at 2025-08-13T21:09:00-04:00
Fix Data.List unqualified import warning
- - - - -
fd811ded by Simon Peyton Jones at 2025-08-14T17:56:47-04:00
Make injecting implicit bindings into its own pass
Previously we were injecting "impliicit bindings" (data constructor
worker and wrappers etc)
- both at the end of CoreTidy,
- and at the start of CorePrep
This is unpleasant and confusing. This patch puts it it its own pass,
addImplicitBinds, which runs between the two.
The function `GHC.CoreToStg.AddImplicitBinds.addImplicitBinds` now takes /all/
TyCons, not just the ones for algebraic data types. That change ripples
through to
- corePrepPgm
- doCodeGen
- byteCodeGen
All take [TyCon] which includes all TyCons
- - - - -
9bd7fcc5 by Simon Peyton Jones at 2025-08-14T17:56:47-04:00
Implement unary classes
The big change is described exhaustively in
Note [Unary class magic] in GHC.Core.TyCon
Other changes
* We never unbox class dictionaries in worker/wrapper. This has been true for some
time now, but the logic is now centralised in functions in
GHC.Core.Opt.WorkWrap.Utils, namely `canUnboxTyCon`, and `canUnboxArg`
See Note [Do not unbox class dictionaries] in GHC.Core.Opt.WorkWrap.Utils.
* Refactored the `notWorthFloating` logic in GHc.Core.Opt.SetLevels.
I can't remember if I actually changed any behaviour here, but if so it's
only in a corner cases.
* Fixed a bug in `GHC.Core.TyCon.isEnumerationTyCon`, which was wrongly returning
True for (##).
* Remove redundant Role argument to `liftCoSubstWithEx`. It was always
Representational.
* I refactored evidence generation in the constraint solver:
* Made GHC.Tc.Types.Evidence contain better abstactions for evidence
generation.
* I deleted the file `GHC.Tc.Types.EvTerm` and merged its (small) contents
elsewhere. It wasn't paying its way.
* Made evidence for implicit parameters go via a proper abstraction.
* Fix inlineBoringOk; see (IB6) in Note [inlineBoringOk]
This fixes a slowdown in `countdownEffectfulDynLocal`
in the `effectful` library.
Smaller things
* Rename `isDataTyCon` to `isBoxedDataTyCon`.
* GHC.Core.Corecion.liftCoSubstWithEx was only called with Representational role,
so I baked that into the function and removed the argument.
* Get rid of `GHC.Core.TyCon.tyConSingleAlgDataCon_maybe` in favour of calling
`not isNewTyCon` at the call sites; more explicit.
* Refatored `GHC.Core.TyCon.isInjectiveTyCon`; but I don't think I changed its
behaviour
* Moved `decomposeIPPred` to GHC.Core.Predicate
Compile time performance changes:
geo. mean +0.1%
minimum -6.8%
maximum +14.4%
The +14% one is in T21839c, where it seems that a bit more inlining
is taking place. That seems acceptable; and the average change is small
Metric Decrease:
LargeRecord
T12227
T12707
T16577
T21839r
T5642
Metric Increase:
T15164
T21839c
T3294
T5321FD
T5321Fun
WWRec
- - - - -
b4075d71 by Simon Peyton Jones at 2025-08-14T17:56:47-04:00
Slight improvement to pre/postInlineUnconditionally
Avoids an extra simplifier iteration
- - - - -
9e443596 by Simon Peyton Jones at 2025-08-14T17:56:47-04:00
Fix a long-standing assertion error in normSplitTyConApp_maybe
- - - - -
91310ad0 by Simon Peyton Jones at 2025-08-14T17:56:47-04:00
Add comment to coercion optimiser
- - - - -
5b841d82 by Teo Camarasu at 2025-08-14T17:57:56-04:00
template-haskell: move some identifiers from ghc-internal to template-haskell
These identifiers are not used internally by the compiler. Therefore we
have no reason for them to be in ghc-internal.
By moving them to template-haskell, we benefit from it being easier to
change them and we avoid having to build them in stage0.
Resolves #26048
- - - - -
33e2c7e5 by Teo Camarasu at 2025-08-14T17:57:56-04:00
template-haskell: transfer $infix note to public module
This Haddock note should be in the public facing module
- - - - -
2a411fc4 by Sylvain Henry at 2025-08-14T17:59:09-04:00
JS: export HEAP8 symbol (#26290)
Newer Emscripten requires this.
- - - - -
248f78ca by Ben Gamari at 2025-08-14T17:59:51-04:00
users-guide: Drop the THREAD_RUNNABLE event
As of f361281c89fbce42865d8b8b27b0957205366186 it is no longer emitted.
- - - - -
706d33e3 by Recursion Ninja at 2025-08-15T04:12:12-04:00
Resolving issues #20645 and #26109
Correctly sign extending and casting smaller bit width types for LLVM operations:
- bitReverse8#
- bitReverse16#
- bitReverse32#
- byteSwap16#
- byteSwap32#
- pdep8#
- pdep16#
- pext8#
- pext16#
- - - - -
1cdc6f46 by Cheng Shao at 2025-08-15T04:12:56-04:00
hadrian: enforce have_llvm=False for wasm32/js
This patch fixes hadrian to always pass have_llvm=False to the
testsuite driver for wasm32/js targets. These targets don't really
support the LLVM backend, and the optllvm test way doesn't work. We
used to special-case wasm32/js to avoid auto-adding optllvm way in
testsuite/config/ghc, but this is still problematic if someone writes
a new LLVM-related test and uses something like when(have_llvm(),
extra_ways(["optllvm"])). So better just enforce have_llvm=False for
these targets here.
- - - - -
ca03226d by Ben Gamari at 2025-08-18T13:43:20+00:00
configure: Allow use of LLVM 20
- - - - -
783cd7d6 by Cheng Shao at 2025-08-18T20:13:14-04:00
compiler: use `UniqMap` instead of `Map` for `BCEnv` in bytecode compiler
The bytecode compiler maintains a `BCEnv` which was previously `Map Id
StackDepth`. Given `Id` is `Uniquable`, we might as well use `UniqMap`
here as a more efficient data structure, hence this patch.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
58e46da9 by fendor at 2025-08-18T20:13:56-04:00
rts: Strip lower three bits when hashing Word instead of lower eight bits
- - - - -
45dbfa23 by Cheng Shao at 2025-08-18T20:14:37-04:00
libffi: update to 3.5.2
Bumps libffi submodule.
- - - - -
54be78ef by Ben Gamari at 2025-08-19T16:28:05-04:00
testsuite: Fix T20006b
This test is supposed to fail for non-threaded ways yet it
was previously marked as only failing in `normal`.
Fix this.
- - - - -
f4bac607 by Simon Peyton Jones at 2025-08-19T16:28:47-04:00
Take yet more care with reporting redundant constraints
This small patch fixes #25992, which relates to reporting redundant
constraints on default-method declarations.
See (TRC5) in Note [Tracking redundant constraints]
- - - - -
ab130fec by fendor at 2025-08-19T16:29:29-04:00
Bump dependencies of hadrian-bootstrap-gen to use GHC 9.6.7
- - - - -
6d02ac6f by fendor at 2025-08-19T16:29:29-04:00
Bump required GHC version for test-bootstrap jobs to 9.10.1
Include test-bootstrap job for GHC 9.12.2.
Update hadrian bootstrap plans use GHC 9.10 and 9.12
Remove older GHC bootstrap configurations.
We require at least GHC 9.10.1 to build GHC.
Adds plans for:
* 9.10.1
* 9.10.2
* 9.12.1
* 9.12.2
- - - - -
9e857171 by Brandon Chinn at 2025-08-20T11:47:46-04:00
Don't warn unused-imports with used generated imports
Fixes #21730
* The old notion of "implicit" import has been renamed to "generated". See Note [Generated imports] in GHC.Hs.ImpExp.
* ImportMap now keeps track of generated and user-written imports separately. This avoids the fake SrcSpan we used to give the implicit Prelude import, and the hack that went with it.
* -ddump-minimal-imports now considers generated imports (but still only
warns on + prints user-written imports)
* bestImport considers generated imports to take priority over user-written imports.
- - - - -
9fb3bad4 by Ben Gamari at 2025-08-20T11:48:31-04:00
mailmap: Use ben(a)well-typed.com more liberally
Nearly all of this work was done while working for Well-Typed.
- - - - -
774fec37 by Ben Gamari at 2025-08-20T11:49:15-04:00
Add primop to annotate the call stack with arbitrary data
We introduce a new primop `annotateStack#` which allows us to push
arbitrary data onto the call-stack.
This allows us to extract the data later when decoding the stack, for
example when an exception is thrown, showing more information to the
user without having to annotate the full call-stack with `HasCallStack`
constraints.
A new stack frame value is introduced `AnnFrame`, which consists of
nothing but a generic payload.
The primop has a small wrapper API that allows users to annotate their
call-stack in programs.
There is a pure API and an IO-based one. The former is a little bit
dubious, as it affects the evaluation of a program, so use with care.
The latter is "safe", as it doesn't change the evaluation of the
program.
The stack annotation mechanism is similarly implemented to the
`ExceptionAnnotation` and `Exception`, there is a typeclass to indicate
something can be pushed onto the call-stack and all values are wrapped
in the existential `SomeStackAnnotation`, which recover the type of the
annotation payload.
There is currently no builtin way to show the stack annotations when
`Backtraces` are displayed (i.e., when showing stack traces to the user),
which we will address in a follow-up MR.
-------------------------
Metric Increase:
ghc_experimental_so
-------------------------
We increase the size of the package, so this is not unreasonable.
Co-Authored-By: fendor <fendor(a)posteo.de>
Co-Authored-By: Ben Gamari <bgamari.foss(a)gmail.com>
- - - - -
fdfa3892 by Ben Gamari at 2025-08-20T11:49:57-04:00
testsuite: Add regression test for #24606
- - - - -
39b2e382 by Cheng Shao at 2025-08-20T11:50:40-04: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>
- - - - -
276f8ea8 by Vekhir -- at 2025-08-20T11:51:35-04:00
Bump Cabal dependency
- - - - -
0b9c7437 by Zubin Duggal at 2025-08-20T11:52:18-04:00
ci: Teach ci.sh to fetch FreeBSD artifacts from ghcup unofficial bindists and bootstrap compiler on FreeBSD to 9.10.1
Also refactor fetch_ghc logic in ci.sh, renaming the GHC_VERSION enviorment configuration variable to FETCH_GHC_VERSION,
making it clear that it is intended for use on platforms like Windows and FreeBSD where we don't want to use the GHC
excecutable from the platform environment and instead need to download and install GHC-$FETCH_GHC_VERSION from a release
bindist.
Fixes #26296
- - - - -
b2914797 by Cheng Shao at 2025-08-20T11:53:00-04:00
driver: use UniqSet for hiddenModules in DynFlags/FinderOpts
This patch replaces Set ModuleName with UniqSet ModuleName in
DynFlags.hiddenModules and FinderOpts.finder_hiddenModules for
improved efficiency.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
0335d899 by Cheng Shao at 2025-08-20T11:53:00-04:00
driver: use UniqMap ModuleName in the finder
This patch replaces Map ModuleName with UniqMap ModuleName in the
finder for improved efficiency.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
91f4faaa by Cheng Shao at 2025-08-20T11:53:43-04:00
configure: check python3 version and require minimal 3.7
Since !9515, the testsuite driver requires python3 version to be at
least 3.7, though this has never been checked by configure logic. This
patch implements the version check. Fixes #23234.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
df4ee9b4 by Cheng Shao at 2025-08-20T11:54:25-04:00
compiler: use zero cost coerce in GHC.CmmToAsm.CFG.loopInfo
This patch refactors GHC.CmmToAsm.CFG.loopInfo to use zero cost coerce
and thus addresses the TODO. For coerce to work, constructors of
Label/LabelMap/LabelSet from GHC.Cmm.Dataflow.Label are exposed,
though I believe it's a worthy tradeoff to avoid unnecessary runtime
cost without using unsafeCoerce, since the latter could be a landmine
for future refactoring.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
ccda188d by Simon Peyton Jones at 2025-08-20T11:55:07-04:00
Start with empty inerts in shortcut solving
When short-cut solving we were starting with an inert set that had
unsolved Wanteds. This caused an infinite loop (#26314), because a
typechecker plugin kept being given that unsolved Wanted.
It's better just to start with an empty inert set
- - - - -
c8882ed7 by Ben Gamari at 2025-08-20T11:55:49-04:00
configure: Bump minimal bootstrap GHC version to 9.8
- - - - -
f0a19d74 by fendor at 2025-08-20T19:55:00-04:00
Remove deprecated functions from the ghci package
- - - - -
ebeb991b by fendor at 2025-08-20T19:55:00-04:00
base: Remove unstable heap representation details from GHC.Exts
- - - - -
e368e247 by Rodrigo Mesquita at 2025-08-20T19:55:42-04:00
bytecode: Use 32bits for breakpoint index
Fixes #26325
- - - - -
42724462 by Simon Hengel at 2025-08-21T17:52:11-04:00
Serialize wired-in names as external names when creating HIE files
Note that the domain of de-serialized names stays the same.
Specifically, for known-key names, before `lookupKnownKeyName` was used,
while now this is handled by `lookupOrigNameCache` which captures the
same range provided that the OrigNameCache has been initialized with
`knownKeyNames` (which is the case by default).
(fixes #26238)
- - - - -
6a43f8ec by Cheng Shao at 2025-08-21T17:52:52-04:00
compiler: fix closure C type in SPT init code
This patch fixes the closure C type in SPT init code to StgClosure,
instead of the previously incorrect StgPtr. Having an incorrect C type
makes SPT init code not compatible with other foreign stub generation
logic, which may also emit their own extern declarations for the same
closure symbols and thus will clash with the incorrect prototypes in
SPT init code.
- - - - -
5b5d9d47 by Ben Gamari at 2025-08-25T14:29:35-04:00
Revert "STM: don't create a transaction in the rhs of catchRetry# (#26028)"
This reverts commit 0a5836891ca29836a24c306d2a364c2e4b5377fd
- - - - -
10f06163 by Cheng Shao at 2025-08-25T14:30:16-04:00
wasm: ensure setKeepCAFs() is called in ghci
This patch is a critical bugfix for #26106, see comment and linked
issue for details.
- - - - -
bedc1004 by Cheng Shao at 2025-08-26T09:31:18-04:00
compiler: use zero cost coerce in hoopl setElems/mapToList
This patch is a follow-up of !14680 and changes setElems/mapToList in
GHC/Cmm/Dataflow/Label to use coerce instead of mapping mkHooplLabel
over the keys.
- - - - -
13250d97 by Ryan Scott at 2025-08-26T09:31:59-04:00
Reject infix promoted data constructors without DataKinds
In the rename, make sure to apply the same `DataKinds` checks for both
`HsTyVar` (for prefix promoted data constructors) and `HsOpTy` (for infix
promoted data constructors) alike.
Fixes #26318.
- - - - -
37655c46 by Teo Camarasu at 2025-08-26T15:24:51-04:00
tests: disable T22859 under LLVM
This test was failing under the LLVM backend since the allocations
differ from the NCG.
Resolves #26282
- - - - -
2cbba9d6 by Teo Camarasu at 2025-08-26T15:25:33-04:00
base-exports: update version numbers
As the version of the compiler has been bumped, a lot of the embedded
version numbers will need to be updated if we ever run this test with
`--test-accept` so let's just update them now, and keep future diffs
clean.
- - - - -
f9f2ffcf by Alexandre Esteves at 2025-08-27T07:19:14-04:00
Import new name for 'utimbuf' on windows to fix #26337
Fixes an `-Wincompatible-pointer-types` instance that turns into an error on
recent toolchains and surfaced as such on nixpkgs when doing linux->ucrt cross.
This long-standing warning has been present at least since 9.4:
```
C:\GitLabRunner\builds\0\1709189\tmp\ghc16652_0\ghc_4.c:26:115: error:
warning: incompatible pointer types passing 'struct utimbuf *' to parameter of type 'struct _utimbuf *' [-Wincompatible-pointer-types]
|
26 | HsInt32 ghczuwrapperZC9ZCbaseZCSystemziPosixziInternalsZCzuutime(char* a1, struct utimbuf* a2) {return _utime(a1, a2);}
| ^
HsInt32 ghczuwrapperZC9ZCbaseZCSystemziPosixziInternalsZCzuutime(char* a1, struct utimbuf* a2) {return _utime(a1, a2);}
^~
C:\GitLabRunner\builds\0\1709189\_build\stage0\lib\..\..\mingw\x86_64-w64-mingw32\include\sys\utime.h:109:72: error:
note: passing argument to parameter '_Utimbuf' here
|
109 | __CRT_INLINE int __cdecl _utime(const char *_Filename,struct _utimbuf *_Utimbuf) {
| ^
__CRT_INLINE int __cdecl _utime(const char *_Filename,struct _utimbuf *_Utimbuf) {
```
- - - - -
ae89f000 by Hassan Al-Awwadi at 2025-08-27T07:19:56-04:00
Adds the fucnction addDependentDirectory to Q, resolving issue #26148.
This function adds a new directory to the list of things a module depends upon. That means that when the contents of the directory change, the recompilation checker will notice this and the module will be recompiled. Documentation has also been added for addDependentFunction and addDependentDirectory in the user guide.
- - - - -
00478944 by Simon Peyton Jones at 2025-08-27T16:48:30+01:00
Comments only
- - - - -
a7884589 by Simon Peyton Jones at 2025-08-28T11:08:23+01:00
Type-family occurs check in unification
The occurs check in `GHC.Core.Unify.uVarOrFam` was inadequate in dealing
with type families.
Better now. See Note [The occurs check in the Core unifier].
As I did this I realised that the whole apartness thing is trickier than I
thought: see the new Note [Shortcomings of the apartness test]
- - - - -
8adfc222 by sheaf at 2025-08-28T19:47:17-04:00
Fix orientation in HsWrapper composition (<.>)
This commit fixes the order in which WpCast HsWrappers are composed,
fixing a bug introduced in commit 56b32c5a2d5d7cad89a12f4d74dc940e086069d1.
Fixes #26350
- - - - -
eb2ab1e2 by Oleg Grenrus at 2025-08-29T11:00:53-04: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
- - - - -
2d575a7f by fendor at 2025-08-29T11:01:36-04:00
configure: Bump minimal bootstrap GHC version to 9.10
- - - - -
716274a5 by Simon Peyton Jones at 2025-08-29T17:27:12-04:00
Fix deep subsumption again
This commit fixed #26255:
commit 56b32c5a2d5d7cad89a12f4d74dc940e086069d1
Author: sheaf <sam.derbyshire(a)gmail.com>
Date: Mon Aug 11 15:50:47 2025 +0200
Improve deep subsumption
This commit improves the DeepSubsumption sub-typing implementation
in GHC.Tc.Utils.Unify.tc_sub_type_deep by being less eager to fall back
to unification.
But alas it still wasn't quite right for view patterns: #26331
This MR does a generalisation to fix it. A bit of a sledgehammer to crack
a nut, but nice.
* Add a field `ir_inst :: InferInstFlag` to `InferResult`, where
```
data InferInstFlag = IIF_Sigma | IIF_ShallowRho | IIF_DeepRho
```
* The flag says exactly how much `fillInferResult` should instantiate
before filling the hole.
* We can also use this to replace the previous very ad-hoc `tcInferSigma`
that was used to implement GHCi's `:type` command.
- - - - -
27206c5e by sheaf at 2025-08-29T17:28:14-04:00
Back-compat for TH SpecialiseP data-con of Pragma
This commit improves the backwards-compatibility story for the
SpecialiseP constructor of the Template Haskell 'Pragma' datatype.
Instead of keeping the constructor but deprecating it, this commit makes
it into a bundled pattern synonym of the Pragma datatype. We no longer
deprecate it; it's useful for handling old-form specialise pragmas.
- - - - -
26dbcf61 by fendor at 2025-08-30T05:10:08-04:00
Move stack decoding logic from ghc-heap to ghc-internal
The stack decoding logic in `ghc-heap` is more sophisticated than the one
currently employed in `CloneStack`. We want to use the stack decoding
implementation from `ghc-heap` in `base`.
We cannot simply depend on `ghc-heap` in `base` due do bootstrapping
issues.
Thus, we move the code that is necessary to implement stack decoding to
`ghc-internal`. This is the right location, as we don't want to add a
new API to `base`.
Moving the stack decoding logic and re-exposing it in ghc-heap is
insufficient, though, as we have a dependency cycle between.
* ghc-heap depends on stage1:ghc-internal
* stage0:ghc depends on stage0:ghc-heap
To fix this, we remove ghc-heap from the set of `stage0` dependencies.
This is not entirely straight-forward, as a couple of boot dependencies,
such as `ghci` depend on `ghc-heap`.
Luckily, the boot compiler of GHC is now >=9.10, so we can migrate `ghci`
to use `ghc-internal` instead of `ghc-heap`, which already exports the
relevant modules.
However, we cannot 100% remove ghc's dependency on `ghc-heap`, since
when we compile `stage0:ghc`, `stage1:ghc-internal` is not yet
available.
Thus, when we compile with the boot-compiler, we still depend on an
older version of `ghc-heap`, and only use the modules from `ghc-internal`,
if the `ghc-internal` version is recent enough.
-------------------------
Metric Increase:
T24602_perf_size
T25046_perf_size_gzip
T25046_perf_size_unicode
T25046_perf_size_unicode_gzip
size_hello_artifact
size_hello_artifact_gzip
size_hello_unicode
size_hello_unicode_gzip
-------------------------
These metric increases are unfortunate, they are most likely caused by
the larger (literally in terms of lines of code) stack decoder implementation
that are now linked into hello-word binaries.
On linux, it is almost a 10% increase, which is considerable.
- - - - -
bd80bb70 by fendor at 2025-08-30T05:10:08-04:00
Implement `decode` in terms of `decodeStackWithIpe`
Uses the more efficient stack decoder implementation.
- - - - -
24441165 by fendor at 2025-08-30T05:10:08-04:00
Remove stg_decodeStackzh
- - - - -
fb9cc882 by Simon Peyton Jones at 2025-08-30T05:10:51-04:00
Fix a long standing bug in the coercion optimiser
We were mis-optimising ForAllCo, leading to #26345
Part of the poblem was the tricky tower of abstractions leading to
the dreadful
GHC.Core.TyCo.Subst.substForAllCoTyVarBndrUsing
This function was serving two masters: regular substitution, but also
coercion optimsation. So tricky was it that it did so wrong.
In this MR I locate all the fancy footwork for coercion optimisation
in GHC.Core.Coercion.Opt, where it belongs. That leaves substitution
free to be much simpler.
- - - - -
6c78de2d by Sylvain Henry at 2025-09-01T08:46:19-04:00
Driver: substitute virtual Prim module in --make mode too
When we build ghc-internal with --make (e.g. with cabal-install), we
need to be careful to substitute the virtual interface file for
GHC.Internal.Prim:
- after code generation (we generate code for an empty module, so we get
an empty interface)
- when we try to reload its .hi file
- - - - -
26e0db16 by fendor at 2025-09-01T08:47:01-04:00
Expose Stack Annotation frames in IPE backtraces by default
When decoding the Haskell-native call stack and displaying the IPE information
for the stack frames, we print the `StackAnnotation` of the `AnnFrame` by default.
This means, when an exception is thrown, any intermediate stack annotations will
be displayed in the `IPE Backtrace`.
Example backtrace:
```
Exception: ghc-internal:GHC.Internal.Exception.ErrorCall:
Oh no!
IPE backtrace:
annotateCallStackIO, called at app/Main.hs:48:10 in backtrace-0.1.0.0-inplace-server:Main
annotateCallStackIO, called at app/Main.hs:46:13 in backtrace-0.1.0.0-inplace-server:Main
Main.handler (app/Main.hs:(46,1)-(49,30))
Main.liftIO (src/Servant/Server/Internal/Handler.hs:30:36-42)
Servant.Server.Internal.Delayed.runHandler' (src/Servant/Server/Internal/Handler.hs:27:31-41)
Control.Monad.Trans.Resource.runResourceT (./Control/Monad/Trans/Resource.hs:(192,14)-(197,18))
Network.Wai.Handler.Warp.HTTP1.processRequest (./Network/Wai/Handler/Warp/HTTP1.hs:195:20-22)
Network.Wai.Handler.Warp.HTTP1.processRequest (./Network/Wai/Handler/Warp/HTTP1.hs:(195,5)-(203,31))
Network.Wai.Handler.Warp.HTTP1.http1server.loop (./Network/Wai/Handler/Warp/HTTP1.hs:(141,9)-(157,42))
HasCallStack backtrace:
error, called at app/Main.hs:48:32 in backtrace-0.1.0.0-inplace-server:Main
```
The first two entries have been added by `annotateCallStackIO`, defined in `annotateCallStackIO`.
- - - - -
a1567efd by Sylvain Henry at 2025-09-01T23:01:35-04:00
RTS: rely less on Hadrian for flag setting (#25843)
Hadrian used to pass -Dfoo command-line flags directly to build the rts.
We can replace most of these flags with CPP based on cabal flags.
It makes building boot libraries with cabal-install simpler (cf #25843).
- - - - -
ca5b0283 by Sergey Vinokurov at 2025-09-01T23:02:23-04:00
Remove unnecessary irrefutable patterns from Bifunctor instances for tuples
Implementation of https://github.com/haskell/core-libraries-committee/issues/339
Metric Decrease:
mhu-perf
- - - - -
2da84b7a by sheaf at 2025-09-01T23:03:23-04:00
Only use active rules when simplifying rule RHSs
When we are simplifying the RHS of a rule, we make sure to only apply
rewrites from rules that are active throughout the original rule's
range of active phases.
For example, if a rule is always active, we only fire rules that are
themselves always active when simplifying the RHS. Ditto for inline
activations.
This is achieved by setting the simplifier phase to a range of phases,
using the new SimplPhaseRange constructor. Then:
1. When simplifying the RHS of a rule, or of a stable unfolding,
we set the simplifier phase to a range of phases, computed from
the activation of the RULE/unfolding activation, using the
function 'phaseFromActivation'.
The details are explained in Note [What is active in the RHS of a RULE?]
in GHC.Core.Opt.Simplify.Utils.
2. The activation check for other rules and inlinings is then:
does the activation of the other rule/inlining cover the whole
phase range set in sm_phase? This continues to use the 'isActive'
function, which now accounts for phase ranges.
On the way, this commit also moves the exact-print SourceText annotation
from the Activation datatype to the ActivationAnn type. This keeps the
main Activation datatype free of any extra cruft.
Fixes #26323
- - - - -
7418e237 by Joseph Fourment at 2025-09-03T10:26:34+01:00
Add type-lets into Core
The plan for #20264 is to introduce let-bound types to have observable sharing in types.
To avoid the need to carry an environment when dealing with occurrences of these type variables,
we embed the types they're bound to (if any) in a `tv_unfolding :: Maybe Type` attribute.
This way, one can look through let-bound type variables using `coreView` and friends.
In particular, definitional equality looks through unfoldings.
simple-opt: don't inline type-lets
specialise: fix type-lets in DFun unfoldings
During specialisation, a dictionary being specialised gets a new unfolding by turning
`DFun \ bndrs -> MkD @<T1> ... @<Tm> <op1> ... <opn>` into
`DFun \ spec_bndrs -> MkD @((\ bndrs -> TYPE: <T1>) spec_args) ... ((\ bndrs -> <opn>) spec_args)`
which in turns gets beta-reduced into
`DFun \ spec_bndrs -> MkD (let { bndrs = spec_args } in TYPE: <T1>) ... (let { bndrs = spec_args } in <opn>)`.
Previously, such let binders would immediately be substituted into the type so it didn't cause any issue,
but now we want to avoid inlining.
Arguments of the form `let { bndrs = spec_args } in TYPE: <T1>` are not considered as type arguments since they're
not of the canonical form `TYPE: something`.
This commit restores the previous behavior of substituting the specialised type arguments.
Alternatively, we could attach some floated type bindings to `DFun`s.
occur-anal: implement occurence analysis for type variables
In order to find out let-bound type variables that are used only once, in the hope of inlining them,
we need to track type variables as well in the occurrence analiser. Just like Id's, we attach an
`OccInfo` to each (immutable) type variable, and we walk into types and coercions to accurately gather
occurrences.
simplifier: don't inline type-lets
Keep propagating type-lets further down the pipeline, in the simplifier.
We also update CallArity, CprAnal, DmdAnal, WorkWrap, and Specialise to ignore type-lets.
prep: make type-lets pass through CorePrep
As a first attempt, ignore type-lets in CorePrep to avoid crashes.
However, this is not enough: CorePrep also does some let-floating.
If we don't float type-lets along with value-level let-bindings,
the latter can float out of the scope of a type variable in use.
simple-opt: fix simple_type_bind
Also:
- Inline small types using a new typeIsSmallEnoughToInline predicate
- Inline single-occurrence variables
simple-opt: make beta-reduction use simple_bind_type
iface: add IfaceTypeLetBndr to represent non-top-level type-let binders
IfaceLetBndr isn't fit to represent type-let binders, as it includes a
bunch of vacuous flags for Ids only.
Instead of putting squares in circles, I added a new constructor for type binders.
The downside is that it breaks existing iface files, so since we can't bootstrap
yet so we have to bootstrap a cherry-picked branch and then checkout again to build
with --freeze1.
To avoid similar issues in the future, IfaceTyVarInfoItem serialises with a tag
despite there being only one constructor for now.
dmd-anal: prefix unused variable with _ to avoid warning
type: inline unfoldView in sORTKind_maybe
tidy: deal with type-lets
notes: add Note [Type and coercion lets]
notes: update Note [Comparing nullary type synonyms] to account for type variables
While updating backlinks, I noticed the optimisation for type variables
could be performed in more places.
simplifier: inline single-occurring type-lets
cleanup: remove NOINLINE on tyVarOccInfo
Wibbles
Wibbles
Progress
Progress
More progress
Progress
...doesn't compile though
Mostly working now
Aggressively create type-lets
more progress
More progress
Temp debug printing
Remove bogus assert
Fix anoher couple of bugs
in SimpleOpt and exprIsTrivial
Improve zonking of foreign decls to avoid TcTyVars escaping
Wibbles
Some small wibbles
Improvements
Rmmove trace
Wibbles
Use lambda, not let, in WorkWrap
Using type let did not work right with type lets and shadowing
Requires Lint to be OK join points under beta redexes -- but it is!
Needs better documentation
Wibbles
More improvements
More improvements
* Less cloning in SpecConstr
* Lint checks RULES for imported binders
Comments only
Wibble
Wibbles
Wibbles
.. getting Lint errors when compiling GHC.Internal.Classes
Wibbles
More improvements
..now getting to the back end an interface file generation
Wibbles
Wibble unsed var
Missing case in tyThingEntityInfo
Add IfaceExtTyVar
Wibbles
Start to make OccAnal count TyCoVars properly [skip ci]
Proper occurrence analysis for TyCoVars
Wibble imports
Wibble imports again
Fix two tricky buglets
More small fixes
Add missing mkAbsCoreApps
...which caused bad Lint errors
More wibbles
More wibbles exp around mkPolyAbsLams
- - - - -
30d3c77f by Simon Peyton Jones at 2025-09-03T15:22:02+01:00
Make it compile again
- - - - -
842 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/darwin/toolchain.nix
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .mailmap
- CODEOWNERS
- README.md
- compiler/GHC.hs
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/Builtin/PrimOps/Ids.hs
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/Builtin/Types/Prim.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/ByteCode/Asm.hs
- + compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/InfoTable.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Linker.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm.hs
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/Cmm/Dataflow/Label.hs
- compiler/GHC/CmmToAsm/CFG.hs
- compiler/GHC/CmmToAsm/LA64/CodeGen.hs
- compiler/GHC/CmmToAsm/LA64/Instr.hs
- compiler/GHC/CmmToAsm/LA64/Ppr.hs
- compiler/GHC/CmmToAsm/PPC/Ppr.hs
- compiler/GHC/CmmToAsm/Ppr.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/CmmToLlvm/Data.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Class.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Coercion/Axiom.hs
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Core/DataCon.hs
- compiler/GHC/Core/FVs.hs
- compiler/GHC/Core/FamInstEnv.hs
- compiler/GHC/Core/LateCC/OverloadedCalls.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Make.hs
- compiler/GHC/Core/Map/Expr.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/CSE.hs
- compiler/GHC/Core/Opt/CallArity.hs
- compiler/GHC/Core/Opt/CprAnal.hs
- compiler/GHC/Core/Opt/DmdAnal.hs
- compiler/GHC/Core/Opt/Exitify.hs
- compiler/GHC/Core/Opt/FloatIn.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Pipeline/Types.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Simplify.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Inline.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Monad.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/Seq.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Subst.hs
- compiler/GHC/Core/Tidy.hs
- compiler/GHC/Core/TyCo/Compare.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Ppr.hs
- compiler/GHC/Core/TyCo/Ppr.hs-boot
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/TyCo/Tidy.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unfold.hs
- compiler/GHC/Core/Unfold/Make.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/CoreToStg.hs
- + compiler/GHC/CoreToStg/AddImplicitBinds.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/CmdLine.hs
- compiler/GHC/Driver/Config.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Config/Core/Opt/Simplify.hs
- compiler/GHC/Driver/Config/Finder.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/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Session.hs
- + compiler/GHC/Driver/Session/Inspect.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/HsToCore/Docs.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Foreign/Call.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Pmc/Utils.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Decl.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Ext/Binary.hs
- compiler/GHC/Iface/Ext/Types.hs
- compiler/GHC/Iface/Ext/Utils.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Types.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Header.hs
- compiler/GHC/Plugins.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Eval/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- compiler/GHC/Stg/BcPrep.hs
- compiler/GHC/Stg/FVs.hs
- compiler/GHC/Stg/Lint.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm.hs
- compiler/GHC/StgToCmm/InfoTableProv.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/Prim.hs
- compiler/GHC/StgToJS/StaticPtr.hs
- compiler/GHC/SysTools/Process.hs
- compiler/GHC/SysTools/Tasks.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Generics.hs
- compiler/GHC/Tc/Deriv/Infer.hs
- compiler/GHC/Tc/Deriv/Utils.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs-boot
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Instance/Family.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Rewrite.hs
- compiler/GHC/Tc/Solver/Solve.hs
- + compiler/GHC/Tc/Solver/Solve.hs-boot
- compiler/GHC/Tc/Solver/Types.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Build.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/BasicTypes.hs
- compiler/GHC/Tc/Types/Constraint.hs
- − compiler/GHC/Tc/Types/EvTerm.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Concrete.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Validity.hs
- compiler/GHC/Tc/Zonk/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- − compiler/GHC/Types/Breakpoint.hs
- compiler/GHC/Types/Demand.hs
- compiler/GHC/Types/Error.hs
- compiler/GHC/Types/Id.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Types/SptEntry.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Types/TyThing.hs
- compiler/GHC/Types/TypeEnv.hs
- compiler/GHC/Types/Var.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/ModGuts.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Error.hs
- compiler/GHC/Utils/Logger.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/GHC/Utils/Trace.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- compiler/ghc.cabal.in
- configure.ac
- − docs/users_guide/9.14.1-notes.rst
- + docs/users_guide/9.16.1-notes.rst
- docs/users_guide/conf.py
- docs/users_guide/debug-info.rst
- + docs/users_guide/diagnostics-as-json-schema-1_2.json
- docs/users_guide/eventlog-formats.rst
- docs/users_guide/expected-undocumented-flags.txt
- docs/users_guide/exts/doandifthenelse.rst
- docs/users_guide/exts/ffi.rst
- docs/users_guide/exts/linear_types.rst
- + docs/users_guide/exts/relaxed_poly_rec.rst
- docs/users_guide/exts/strict.rst
- docs/users_guide/exts/types.rst
- docs/users_guide/ghci.rst
- docs/users_guide/profiling.rst
- docs/users_guide/release-notes.rst
- docs/users_guide/runtime_control.rst
- docs/users_guide/separate_compilation.rst
- docs/users_guide/using-optimisation.rst
- docs/users_guide/using.rst
- docs/users_guide/win32-dlls.rst
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Monad.hs
- ghc/ghc-bin.cabal.in
- hadrian/bootstrap/generate_bootstrap_plans
- hadrian/bootstrap/hadrian-bootstrap-gen.cabal
- hadrian/bootstrap/plan-9_10_1.json
- hadrian/bootstrap/plan-9_6_5.json → hadrian/bootstrap/plan-9_10_2.json
- hadrian/bootstrap/plan-9_6_6.json → hadrian/bootstrap/plan-9_12_1.json
- hadrian/bootstrap/plan-9_6_4.json → hadrian/bootstrap/plan-9_12_2.json
- − hadrian/bootstrap/plan-9_6_1.json
- − hadrian/bootstrap/plan-9_6_2.json
- − hadrian/bootstrap/plan-9_6_3.json
- − hadrian/bootstrap/plan-9_8_1.json
- − hadrian/bootstrap/plan-9_8_2.json
- hadrian/bootstrap/plan-bootstrap-9_10_1.json
- hadrian/bootstrap/plan-bootstrap-9_6_5.json → hadrian/bootstrap/plan-bootstrap-9_10_2.json
- hadrian/bootstrap/plan-bootstrap-9_6_6.json → hadrian/bootstrap/plan-bootstrap-9_12_1.json
- hadrian/bootstrap/plan-bootstrap-9_8_1.json → hadrian/bootstrap/plan-bootstrap-9_12_2.json
- − hadrian/bootstrap/plan-bootstrap-9_6_1.json
- − hadrian/bootstrap/plan-bootstrap-9_6_2.json
- − hadrian/bootstrap/plan-bootstrap-9_6_3.json
- − hadrian/bootstrap/plan-bootstrap-9_6_4.json
- − hadrian/bootstrap/plan-bootstrap-9_8_2.json
- hadrian/bootstrap/src/Main.hs
- hadrian/hadrian.cabal
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/ToolArgs.hs
- hadrian/src/Settings/Builders/Cabal.hs
- hadrian/src/Settings/Builders/RunTest.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- hadrian/src/Settings/Program.hs
- hadrian/stack.yaml
- hadrian/stack.yaml.lock
- hie.yaml
- libffi-tarballs
- libraries/Cabal
- libraries/Win32
- libraries/array
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- libraries/base/src/Control/Exception.hs
- libraries/base/src/Control/Exception/Backtrace.hs
- libraries/base/src/Data/Bifunctor.hs
- libraries/base/src/Data/List/NonEmpty.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/GHC/Generics.hs
- − libraries/base/src/GHC/IOPort.hs
- libraries/base/src/GHC/Stack/CloneStack.hs
- libraries/base/src/GHC/Weak/Finalize.hs
- libraries/base/src/System/Console/GetOpt.hs
- libraries/binary
- libraries/deepseq
- libraries/directory
- libraries/exceptions
- libraries/filepath
- libraries/ghc-bignum/changelog.md
- libraries/ghc-boot-th/GHC/Boot/TH/Ppr.hs
- libraries/ghc-boot-th/ghc-boot-th.cabal.in
- libraries/ghc-boot/ghc-boot.cabal.in
- libraries/ghc-compact/GHC/Compact.hs
- libraries/ghc-compact/GHC/Compact/Serialized.hs
- libraries/ghc-compact/ghc-compact.cabal
- libraries/ghc-experimental/ghc-experimental.cabal.in
- + libraries/ghc-experimental/src/GHC/Exception/Backtrace/Experimental.hs
- + libraries/ghc-experimental/src/GHC/Stack/Annotation/Experimental.hs
- + libraries/ghc-experimental/src/System/Mem/Experimental.hs
- libraries/ghc-heap/GHC/Exts/Heap/ClosureTypes.hs
- libraries/ghc-heap/GHC/Exts/Heap/Closures.hs
- + libraries/ghc-heap/GHC/Exts/Heap/Constants.hs
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingDisabled.hsc
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTable.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTable/Types.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hs
- libraries/ghc-heap/GHC/Exts/Heap/ProfInfo/Types.hs
- libraries/ghc-heap/GHC/Exts/Heap/Utils.hsc
- libraries/ghc-heap/GHC/Exts/Stack.hs
- + libraries/ghc-heap/GHC/Exts/Stack/Constants.hs
- libraries/ghc-heap/GHC/Exts/Stack/Decode.hs
- libraries/ghc-heap/ghc-heap.cabal.in
- libraries/ghc-heap/tests/parse_tso_flags.hs
- libraries/ghc-heap/cbits/HeapPrim.cmm → libraries/ghc-internal/cbits/HeapPrim.cmm
- libraries/ghc-heap/cbits/Stack.cmm → libraries/ghc-internal/cbits/Stack.cmm
- libraries/ghc-internal/cbits/StackCloningDecoding.cmm
- libraries/ghc-heap/cbits/Stack_c.c → libraries/ghc-internal/cbits/Stack_c.c
- libraries/ghc-internal/cbits/pdep.c
- libraries/ghc-internal/cbits/pext.c
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/jsbits/base.js
- + libraries/ghc-internal/src/GHC/Internal/AllocationLimitHandler.hs
- libraries/ghc-internal/src/GHC/Internal/Base.hs
- libraries/ghc-internal/src/GHC/Internal/Bignum/Natural.hs
- libraries/ghc-internal/src/GHC/Internal/ClosureTypes.hs
- libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/Thread.hs
- libraries/ghc-internal/src/GHC/Internal/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
- libraries/ghc-internal/src/GHC/Internal/Exts.hs
- libraries/ghc-internal/src/GHC/Internal/Float.hs
- + libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghc-heap/GHC/Exts/Heap/Constants.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/Constants.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTable.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTable/Types.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable/Types.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTableProf.hsc
- + libraries/ghc-internal/src/GHC/Internal/Heap/ProfInfo/Types.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Buffer.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Windows/Handle.hsc
- − libraries/ghc-internal/src/GHC/Internal/IOPort.hs
- libraries/ghc-internal/src/GHC/Internal/List.hs
- libraries/ghc-internal/src/GHC/Internal/Prim/PtrEq.hs
- libraries/ghc-internal/src/GHC/Internal/Real.hs
- + libraries/ghc-internal/src/GHC/Internal/Stack/Annotation.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/CloneStack.hs
- libraries/ghc-heap/GHC/Exts/Stack/Constants.hsc → libraries/ghc-internal/src/GHC/Internal/Stack/Constants.hsc
- + libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO.hs
- libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- + libraries/ghc-internal/tests/Makefile
- + libraries/ghc-internal/tests/all.T
- + libraries/ghc-internal/tests/backtraces/Makefile
- + libraries/ghc-internal/tests/backtraces/T14532a.hs
- + libraries/ghc-internal/tests/backtraces/T14532a.stdout
- + libraries/ghc-internal/tests/backtraces/T14532b.hs
- + libraries/ghc-internal/tests/backtraces/T14532b.stdout
- + libraries/ghc-internal/tests/backtraces/all.T
- + libraries/ghc-internal/tests/stack-annotation/Makefile
- + libraries/ghc-internal/tests/stack-annotation/TestUtils.hs
- + libraries/ghc-internal/tests/stack-annotation/all.T
- + libraries/ghc-internal/tests/stack-annotation/ann_frame001.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame001.stdout
- + libraries/ghc-internal/tests/stack-annotation/ann_frame002.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame002.stdout
- + libraries/ghc-internal/tests/stack-annotation/ann_frame003.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame003.stdout
- + libraries/ghc-internal/tests/stack-annotation/ann_frame004.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame004.stdout
- libraries/ghc-prim/changelog.md
- libraries/ghc-prim/ghc-prim.cabal
- libraries/ghci/GHCi/CreateBCO.hs
- + libraries/ghci/GHCi/Debugger.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/Run.hs
- libraries/ghci/GHCi/TH.hs
- libraries/ghci/ghci.cabal.in
- libraries/haskeline
- libraries/hpc
- libraries/os-string
- libraries/parsec
- libraries/process
- libraries/semaphore-compat
- libraries/stm
- libraries/template-haskell/Language/Haskell/TH/Lib.hs
- libraries/template-haskell/Language/Haskell/TH/Quote.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- libraries/template-haskell/changelog.md
- libraries/template-haskell/template-haskell.cabal.in
- libraries/template-haskell/tests/all.T
- libraries/terminfo
- libraries/text
- libraries/time
- libraries/unix
- m4/find_ld.m4
- m4/find_python.m4
- mk/get-win32-tarballs.py
- + rts/AllocArray.c
- + rts/AllocArray.h
- rts/CloneStack.c
- rts/CloneStack.h
- rts/ClosureFlags.c
- rts/Disassembler.c
- rts/Exception.cmm
- rts/Hash.c
- rts/Heap.c
- rts/IPE.c
- rts/Interpreter.c
- rts/Interpreter.h
- rts/LdvProfile.c
- rts/Messages.c
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/Printer.c
- rts/ProfHeap.c
- rts/RetainerProfile.c
- rts/RetainerSet.c
- rts/RtsFlags.c
- rts/RtsMessages.c
- rts/RtsStartup.c
- rts/RtsSymbols.c
- rts/RtsUtils.c
- rts/Schedule.c
- rts/StgMiscClosures.cmm
- rts/ThreadLabels.c
- rts/Threads.c
- rts/Timer.c
- rts/Trace.c
- rts/Trace.h
- rts/TraverseHeap.c
- rts/Updates.h
- rts/Weak.c
- rts/eventlog/EventLog.c
- rts/eventlog/EventLog.h
- rts/external-symbols.list.in
- rts/include/Rts.h
- rts/include/rts/Bytecodes.h
- rts/include/rts/Constants.h
- rts/include/rts/Flags.h
- rts/include/rts/IPE.h
- rts/include/rts/prof/CCS.h
- rts/include/rts/storage/ClosureTypes.h
- rts/include/rts/storage/Closures.h
- rts/include/rts/storage/GC.h
- rts/include/rts/storage/Heap.h
- rts/include/rts/storage/TSO.h
- rts/include/stg/MiscClosures.h
- rts/include/stg/SMP.h
- rts/js/mem.js
- rts/js/profiling.js
- rts/linker/LoadArchive.c
- rts/linker/PEi386.c
- rts/posix/ticker/Pthread.c
- rts/posix/ticker/TimerFd.c
- rts/rts.cabal
- rts/sm/Compact.c
- rts/sm/Evac.c
- rts/sm/NonMoving.c
- rts/sm/NonMoving.h
- rts/sm/NonMovingAllocate.c
- rts/sm/NonMovingMark.c
- rts/sm/Sanity.c
- rts/sm/Scav.c
- rts/sm/Storage.c
- rts/win32/AsyncWinIO.c
- rts/win32/libHSghc-internal.def
- testsuite/.gitignore
- testsuite/config/ghc
- testsuite/driver/testlib.py
- testsuite/tests/arrows/should_compile/T21301.stderr
- testsuite/tests/backpack/cabal/bkpcabal08/bkpcabal08.stdout
- testsuite/tests/core-to-stg/T24124.stderr
- testsuite/tests/corelint/LintEtaExpand.stderr
- testsuite/tests/corelint/T21115b.stderr
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/cpranal/sigs/T25944.hs
- + testsuite/tests/cpranal/sigs/T25944.stderr
- testsuite/tests/cpranal/sigs/all.T
- testsuite/tests/deSugar/should_compile/T2431.stderr
- testsuite/tests/deSugar/should_fail/DsStrictFail.stderr
- testsuite/tests/deSugar/should_run/T20024.stderr
- testsuite/tests/deSugar/should_run/dsrun005.stderr
- testsuite/tests/deSugar/should_run/dsrun007.stderr
- testsuite/tests/deSugar/should_run/dsrun008.stderr
- testsuite/tests/deriving/should_compile/T20815.hs
- testsuite/tests/deriving/should_fail/T12768.stderr
- testsuite/tests/deriving/should_fail/T1496.stderr
- testsuite/tests/deriving/should_fail/T5498.stderr
- testsuite/tests/deriving/should_fail/T7148.stderr
- testsuite/tests/deriving/should_fail/T7148a.stderr
- testsuite/tests/deriving/should_run/T9576.stderr
- testsuite/tests/dmdanal/should_compile/T16029.stdout
- testsuite/tests/dmdanal/should_compile/T23398.hs
- testsuite/tests/dmdanal/should_compile/T23398.stderr
- testsuite/tests/dmdanal/sigs/T21119.stderr
- testsuite/tests/dmdanal/sigs/T21888.stderr
- testsuite/tests/driver/json.stderr
- testsuite/tests/driver/json_warn.stderr
- + testsuite/tests/driver/make-prim/GHC/Internal/Prim.hs
- + testsuite/tests/driver/make-prim/Makefile
- + testsuite/tests/driver/make-prim/Test.hs
- + testsuite/tests/driver/make-prim/Test2.hs
- + testsuite/tests/driver/make-prim/all.T
- testsuite/tests/driver/recomp015/all.T
- testsuite/tests/gadt/T12468.stderr
- testsuite/tests/ghc-e/should_fail/T24172.stderr
- + testsuite/tests/ghci.debugger/scripts/T26042b.hs
- + testsuite/tests/ghci.debugger/scripts/T26042b.script
- + testsuite/tests/ghci.debugger/scripts/T26042b.stdout
- + testsuite/tests/ghci.debugger/scripts/T26042c.hs
- + testsuite/tests/ghci.debugger/scripts/T26042c.script
- + testsuite/tests/ghci.debugger/scripts/T26042c.stdout
- + testsuite/tests/ghci.debugger/scripts/T26042d.hs
- + testsuite/tests/ghci.debugger/scripts/T26042d.script
- + testsuite/tests/ghci.debugger/scripts/T26042d.stdout
- + testsuite/tests/ghci.debugger/scripts/T26042e.hs
- + testsuite/tests/ghci.debugger/scripts/T26042e.script
- + testsuite/tests/ghci.debugger/scripts/T26042e.stdout
- + testsuite/tests/ghci.debugger/scripts/T26042f.hs
- + testsuite/tests/ghci.debugger/scripts/T26042f.script
- + testsuite/tests/ghci.debugger/scripts/T26042f1.stderr
- + testsuite/tests/ghci.debugger/scripts/T26042f1.stdout
- + testsuite/tests/ghci.debugger/scripts/T26042f2.stdout
- + testsuite/tests/ghci.debugger/scripts/T26042g.hs
- + testsuite/tests/ghci.debugger/scripts/T26042g.script
- + testsuite/tests/ghci.debugger/scripts/T26042g.stdout
- testsuite/tests/ghci.debugger/scripts/all.T
- testsuite/tests/ghci.debugger/scripts/break011.stdout
- testsuite/tests/ghci.debugger/scripts/break024.stdout
- testsuite/tests/ghci/scripts/Defer02.stderr
- testsuite/tests/ghci/scripts/T15325.stderr
- testsuite/tests/ghci/scripts/T8353.stderr
- testsuite/tests/ghci/scripts/ghci038.stdout
- testsuite/tests/haddock/haddock_testsuite/Makefile
- + testsuite/tests/haddock/haddock_testsuite/T26114.hs
- + testsuite/tests/haddock/haddock_testsuite/T26114.stdout
- testsuite/tests/haddock/haddock_testsuite/all.T
- testsuite/tests/hiefile/should_run/HieQueries.stdout
- testsuite/tests/hiefile/should_run/TestUtils.hs
- testsuite/tests/hpc/recsel/recsel.hs
- testsuite/tests/hpc/recsel/recsel.stdout
- testsuite/tests/impredicative/T17332.stderr
- testsuite/tests/indexed-types/should_compile/T2238.hs
- + testsuite/tests/indexed-types/should_fail/T26176.hs
- + testsuite/tests/indexed-types/should_fail/T26176.stderr
- testsuite/tests/indexed-types/should_fail/T5439.stderr
- testsuite/tests/indexed-types/should_fail/all.T
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- + testsuite/tests/llvm/should_run/T20645.hs
- + testsuite/tests/llvm/should_run/T20645.stdout
- testsuite/tests/llvm/should_run/all.T
- − testsuite/tests/module/T21752.stderr
- testsuite/tests/module/mod150.stderr
- testsuite/tests/module/mod151.stderr
- testsuite/tests/module/mod152.stderr
- testsuite/tests/module/mod153.stderr
- testsuite/tests/numeric/should_compile/T15547.stderr
- testsuite/tests/numeric/should_compile/T23907.stderr
- + testsuite/tests/numeric/should_compile/T26229.hs
- testsuite/tests/numeric/should_compile/all.T
- + testsuite/tests/numeric/should_run/T18619.hs
- + testsuite/tests/numeric/should_run/T18619.stderr
- + testsuite/tests/numeric/should_run/T26230.hs
- + testsuite/tests/numeric/should_run/T26230.stdout
- testsuite/tests/numeric/should_run/T9810.stdout
- testsuite/tests/numeric/should_run/all.T
- testsuite/tests/numeric/should_run/foundation.hs
- testsuite/tests/overloadedrecflds/should_fail/T18999_NoDisambiguateRecordFields.stderr
- + testsuite/tests/overloadedrecflds/should_run/T26295.hs
- + testsuite/tests/overloadedrecflds/should_run/T26295.stdout
- testsuite/tests/overloadedrecflds/should_run/all.T
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T19082.stderr
- testsuite/tests/partial-sigs/should_compile/T10403.stderr
- + testsuite/tests/partial-sigs/should_compile/T26256.hs
- + testsuite/tests/partial-sigs/should_compile/T26256.stderr
- testsuite/tests/partial-sigs/should_compile/all.T
- testsuite/tests/partial-sigs/should_fail/T10615.stderr
- + testsuite/tests/patsyn/should_compile/T26331.hs
- + testsuite/tests/patsyn/should_compile/T26331a.hs
- testsuite/tests/patsyn/should_compile/all.T
- testsuite/tests/patsyn/should_run/ghci.stderr
- testsuite/tests/perf/compiler/T4007.stdout
- testsuite/tests/perf/compiler/hard_hole_fits.stderr
- + testsuite/tests/perf/should_run/SpecTyFamRun.hs
- + testsuite/tests/perf/should_run/SpecTyFamRun.stdout
- + testsuite/tests/perf/should_run/SpecTyFam_Import.hs
- testsuite/tests/perf/should_run/all.T
- testsuite/tests/plugins/Makefile
- + testsuite/tests/plugins/T21730-plugin/Makefile
- + testsuite/tests/plugins/T21730-plugin/Setup.hs
- + testsuite/tests/plugins/T21730-plugin/T21730-plugin.cabal
- + testsuite/tests/plugins/T21730-plugin/T21730_Plugin.hs
- + testsuite/tests/plugins/T21730.hs
- testsuite/tests/plugins/all.T
- testsuite/tests/primops/should_run/UnliftedIOPort.hs
- testsuite/tests/primops/should_run/all.T
- testsuite/tests/printer/Makefile
- + testsuite/tests/printer/TestLevelImports.hs
- + testsuite/tests/printer/TestNamedDefaults.hs
- testsuite/tests/printer/all.T
- testsuite/tests/quantified-constraints/T15290a.stderr
- testsuite/tests/quantified-constraints/T19690.stderr
- testsuite/tests/quantified-constraints/T19921.stderr
- testsuite/tests/quantified-constraints/T21006.stderr
- testsuite/tests/quasiquotation/T4491/test.T
- testsuite/tests/quotes/LiftErrMsg.stderr
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- testsuite/tests/quotes/LiftErrMsgTyped.stderr
- testsuite/tests/rename/should_compile/T22513d.stderr
- testsuite/tests/rename/should_compile/T22513e.stderr
- testsuite/tests/rename/should_compile/T22513f.stderr
- testsuite/tests/rename/should_compile/T22513g.stderr
- testsuite/tests/rename/should_compile/T22513h.stderr
- testsuite/tests/rename/should_compile/T22513i.stderr
- testsuite/tests/rename/should_compile/rn039.ghc.stderr
- testsuite/tests/rename/should_fail/T15487.stderr
- testsuite/tests/rename/should_fail/T18740a.stderr
- testsuite/tests/rename/should_fail/rnfail044.stderr
- + testsuite/tests/rep-poly/NoEtaRequired.hs
- testsuite/tests/rep-poly/T21906.stderr
- testsuite/tests/rep-poly/all.T
- testsuite/tests/roles/should_compile/Roles14.stderr
- testsuite/tests/roles/should_compile/Roles3.stderr
- testsuite/tests/roles/should_compile/Roles4.stderr
- testsuite/tests/roles/should_fail/RolesIArray.stderr
- + testsuite/tests/rts/T22859.hs
- + testsuite/tests/rts/T22859.stderr
- testsuite/tests/rts/all.T
- testsuite/tests/rts/flags/all.T
- testsuite/tests/rts/ipe/ipeMap.c
- testsuite/tests/rts/ipe/ipe_lib.c
- testsuite/tests/rts/linker/T11223/T11223_link_order_a_b_2_fail.stderr-ws-32-mingw32
- testsuite/tests/rts/linker/T11223/T11223_link_order_a_b_2_fail.stderr-ws-64-mingw32
- testsuite/tests/safeHaskell/flags/SafeFlags17.stderr
- testsuite/tests/safeHaskell/safeLanguage/SafeLang15.stderr
- testsuite/tests/simd/should_run/all.T
- + testsuite/tests/simd/should_run/doublex2_shuffle.hs
- + testsuite/tests/simd/should_run/doublex2_shuffle.stdout
- + testsuite/tests/simd/should_run/doublex2_shuffle_baseline.hs
- + testsuite/tests/simd/should_run/doublex2_shuffle_baseline.stdout
- + testsuite/tests/simd/should_run/floatx4_shuffle.hs
- + testsuite/tests/simd/should_run/floatx4_shuffle.stdout
- + testsuite/tests/simd/should_run/floatx4_shuffle_baseline.hs
- + testsuite/tests/simd/should_run/floatx4_shuffle_baseline.stdout
- testsuite/tests/simplCore/should_compile/DataToTagFamilyScrut.stderr
- testsuite/tests/simplCore/should_compile/T15056.stderr
- testsuite/tests/simplCore/should_compile/T15205.stderr
- testsuite/tests/simplCore/should_compile/T15445.stderr
- testsuite/tests/simplCore/should_compile/T17366.stderr
- testsuite/tests/simplCore/should_compile/T17966.stderr
- testsuite/tests/simplCore/should_compile/T22309.stderr
- testsuite/tests/simplCore/should_compile/T22375DataFamily.stderr
- testsuite/tests/simplCore/should_compile/T23307.stderr
- testsuite/tests/simplCore/should_compile/T23307a.stderr
- + testsuite/tests/simplCore/should_compile/T24606.hs
- testsuite/tests/simplCore/should_compile/T25389.stderr
- testsuite/tests/simplCore/should_compile/T25713.stderr
- + testsuite/tests/simplCore/should_compile/T26051.hs
- + testsuite/tests/simplCore/should_compile/T26051.stderr
- + testsuite/tests/simplCore/should_compile/T26051_Import.hs
- + testsuite/tests/simplCore/should_compile/T26115.hs
- + testsuite/tests/simplCore/should_compile/T26115.stderr
- + testsuite/tests/simplCore/should_compile/T26116.hs
- + testsuite/tests/simplCore/should_compile/T26116.stderr
- + testsuite/tests/simplCore/should_compile/T26117.hs
- + testsuite/tests/simplCore/should_compile/T26117.stderr
- + testsuite/tests/simplCore/should_compile/T26323b.hs
- testsuite/tests/simplCore/should_compile/T7360.stderr
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/simplCore/should_run/T26323.hs
- + testsuite/tests/simplCore/should_run/T26323.stdout
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/simplStg/should_compile/T15226b.stderr
- + testsuite/tests/splice-imports/DodgyLevelExport.hs
- + testsuite/tests/splice-imports/DodgyLevelExport.stderr
- + testsuite/tests/splice-imports/DodgyLevelExportA.hs
- + testsuite/tests/splice-imports/LevelImportExports.hs
- + testsuite/tests/splice-imports/LevelImportExports.stdout
- + testsuite/tests/splice-imports/LevelImportExportsA.hs
- testsuite/tests/splice-imports/Makefile
- + testsuite/tests/splice-imports/ModuleExport.hs
- + testsuite/tests/splice-imports/ModuleExport.stderr
- + testsuite/tests/splice-imports/ModuleExportA.hs
- + testsuite/tests/splice-imports/ModuleExportB.hs
- + testsuite/tests/splice-imports/T26087.stderr
- + testsuite/tests/splice-imports/T26087A.hs
- + testsuite/tests/splice-imports/T26087B.hs
- + testsuite/tests/splice-imports/T26088.stderr
- + testsuite/tests/splice-imports/T26088A.hs
- + testsuite/tests/splice-imports/T26088B.hs
- + testsuite/tests/splice-imports/T26090.hs
- + testsuite/tests/splice-imports/T26090.stderr
- + testsuite/tests/splice-imports/T26090A.hs
- testsuite/tests/splice-imports/all.T
- testsuite/tests/tcplugins/CtIdPlugin.hs
- testsuite/tests/th/Makefile
- testsuite/tests/th/T10267.stderr
- testsuite/tests/th/T14627.stderr
- testsuite/tests/th/T15321.stderr
- + testsuite/tests/th/TH_Depends_Dir.hs
- + testsuite/tests/th/TH_Depends_Dir.stdout
- + testsuite/tests/th/TH_Depends_Dir_External.hs
- testsuite/tests/th/all.T
- testsuite/tests/type-data/should_run/T22332a.stderr
- testsuite/tests/typecheck/should_compile/Makefile
- testsuite/tests/typecheck/should_compile/T12427a.stderr
- testsuite/tests/typecheck/should_compile/T12763.stderr
- testsuite/tests/typecheck/should_compile/T13050.stderr
- + testsuite/tests/typecheck/should_compile/T14010.hs
- testsuite/tests/typecheck/should_compile/T14273.stderr
- testsuite/tests/typecheck/should_compile/T14590.stderr
- testsuite/tests/typecheck/should_compile/T14774.stdout
- testsuite/tests/typecheck/should_compile/T18406b.stderr
- testsuite/tests/typecheck/should_compile/T18529.stderr
- testsuite/tests/typecheck/should_compile/T23171.hs
- testsuite/tests/typecheck/should_compile/T25180.stderr
- + testsuite/tests/typecheck/should_compile/T25992a.hs
- + testsuite/tests/typecheck/should_compile/T26225.hs
- + testsuite/tests/typecheck/should_compile/T26225b.hs
- + testsuite/tests/typecheck/should_compile/T26256a.hs
- + testsuite/tests/typecheck/should_compile/T26345.hs
- + testsuite/tests/typecheck/should_compile/T26346.hs
- + testsuite/tests/typecheck/should_compile/T26350.hs
- + testsuite/tests/typecheck/should_compile/T26358.hs
- testsuite/tests/typecheck/should_compile/T9497a.stderr
- testsuite/tests/typecheck/should_compile/TcSpecPragmas.stderr
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/refinement_hole_fits.stderr
- testsuite/tests/typecheck/should_compile/subsumption_sort_hole_fits.stderr
- − testsuite/tests/typecheck/should_fail/T12563.stderr
- testsuite/tests/typecheck/should_fail/T14605.hs
- testsuite/tests/typecheck/should_fail/T14605.stderr
- testsuite/tests/typecheck/should_fail/T14618.stderr
- testsuite/tests/typecheck/should_fail/T14884.stderr
- testsuite/tests/typecheck/should_fail/T15801.stderr
- testsuite/tests/typecheck/should_fail/T18640a.stderr
- testsuite/tests/typecheck/should_fail/T18640b.stderr
- testsuite/tests/typecheck/should_fail/T19627.stderr
- testsuite/tests/typecheck/should_fail/T21130.stderr
- testsuite/tests/typecheck/should_fail/T21530b.stderr
- testsuite/tests/typecheck/should_fail/T22912.stderr
- testsuite/tests/typecheck/should_fail/T23739b.stderr
- testsuite/tests/typecheck/should_fail/T23739c.stderr
- + testsuite/tests/typecheck/should_fail/T26318.hs
- + testsuite/tests/typecheck/should_fail/T26318.stderr
- testsuite/tests/typecheck/should_fail/T6022.stderr
- testsuite/tests/typecheck/should_fail/T8883.stderr
- testsuite/tests/typecheck/should_fail/T9497d.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail037.stderr
- testsuite/tests/typecheck/should_fail/tcfail140.stderr
- testsuite/tests/typecheck/should_fail/tcfail174.stderr
- testsuite/tests/typecheck/should_run/T10284.stderr
- testsuite/tests/typecheck/should_run/T13838.stderr
- testsuite/tests/typecheck/should_run/T9497a-run.stderr
- testsuite/tests/typecheck/should_run/T9497b-run.stderr
- testsuite/tests/typecheck/should_run/T9497c-run.stderr
- testsuite/tests/unboxedsums/unpack_sums_7.stdout
- testsuite/tests/unsatisfiable/T23816.stderr
- testsuite/tests/unsatisfiable/UnsatDefer.stderr
- testsuite/tests/vdq-rta/should_fail/T23738_fail_pun.stderr
- testsuite/tests/wasm/should_run/control-flow/LoadCmmGroup.hs
- testsuite/tests/wasm/should_run/control-flow/RunWasm.hs
- utils/check-exact/ExactPrint.hs
- utils/deriveConstants/Main.hs
- utils/genprimopcode/Lexer.x
- utils/genprimopcode/Main.hs
- utils/genprimopcode/Parser.y
- utils/genprimopcode/ParserM.hs
- utils/genprimopcode/Syntax.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Link.hs
- utils/haddock/CHANGES.md
- utils/haddock/haddock-api/haddock-api.cabal
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/Interface/AttachInstances.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Create.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/InterfaceFile.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
- utils/haddock/haddock-library/haddock-library.cabal
- utils/haddock/haddock-test/haddock-test.cabal
- utils/haddock/haddock-test/src/Test/Haddock/Config.hs
- utils/haddock/haddock.cabal
- utils/haddock/html-test/ref/Bug1004.html
- + utils/haddock/html-test/ref/Bug25739.html
- + utils/haddock/html-test/src/Bug25739.hs
- utils/hsc2hs
- 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/d03142f5aa758ee1298296d3e5c938…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d03142f5aa758ee1298296d3e5c938…
You're receiving this email because of your account on gitlab.haskell.org.
1
0