[Git][ghc/ghc][wip/spj-apporv-Oct24] 34 commits: Linker.MacOS reduce dynflags import
by Apoorv Ingle (@ani) 23 Feb '26
by Apoorv Ingle (@ani) 23 Feb '26
23 Feb '26
Apoorv Ingle pushed to branch wip/spj-apporv-Oct24 at Glasgow Haskell Compiler / GHC
Commits:
0e1cd2e0 by Evan Piro at 2026-02-08T10:35:16-08:00
Linker.MacOS reduce dynflags import
- - - - -
1c79a4cd by Michael Alan Dorman at 2026-02-09T08:11:51-05:00
Remove `extra_src_files` variable from `testsuite/driver/testlib.py`
While reading through the test harness code, I noticed this variable
with a TODO attached that referenced #12223. Although that bug is
closed, it strongly implied that this special-case variable that only
affected a single test was expected to be removed at some point.
I also looked at 3415bcaa0b1903b5e12dfaadb5b774718e406eab---where it
was added---whose commit message suggested that it would have been
desirable to remove it, but that there were special circumstances that
meant it had to remain (though it doesn't elucidate what those special
circumstances are).
However, the special circumstances were mentioned as if the test was
in a different location than is currently is, so I decided to try
changing the test to use the standard `extra_files` mechanism, which
works in local testing.
This also seems like a reasonable time to remove the script that was
originally used in the transition, since it doesn't really serve a
purpose anymore.
- - - - -
0020e38a by Matthew Pickering at 2026-02-09T17:29:14-05:00
determinism: Use a stable sort in WithHsDocIdentifiers binary instance
`WithHsDocIdentifiers` is defined as
```
71 data WithHsDocIdentifiers a pass = WithHsDocIdentifiers
72 { hsDocString :: !a
73 , hsDocIdentifiers :: ![Located (IdP pass)]
74 }
```
This list of names is populated from `rnHsDocIdentifiers`, which calls
`lookupGRE`, which calls `lookupOccEnv_AllNameSpaces`, which calls
`nonDetEltsUFM` and returns the results in an order depending on
uniques.
Sorting the list with a stable sort before returning the interface makes
the output deterministic and follows the approach taken by other fields
in `Docs`.
Fixes #26858
- - - - -
89898ce6 by echoumcp1 at 2026-02-09T17:30:01-05:00
Replace putstrln with logMsg in handleSeqHValueStatus
Fixes #26549
- - - - -
7c52c4f9 by John Paul Adrian Glaubitz at 2026-02-10T13:52:43-05:00
rts: Switch prim to use modern atomic compiler builtins
The __sync_*() atomic compiler builtins have been deprecated in GCC
for a while now and also don't provide variants for 64-bit values
such as __sync_fetch_and_add_8().
Thus, replace them with the modern __atomic_*() compiler builtins and
while we're at it, also drop the helper macro CAS_NAND() which is now
no longer needed since we stopped using the __sync_*() compiler builtins
altogether.
Co-authored-by: Ilias Tsitsimpis <iliastsi(a)debian.org>
Fixes #26729
- - - - -
cf60850a by Recursion Ninja at 2026-02-10T13:53:27-05:00
Decoupling L.H.S.Decls from GHC.Types.ForeignCall
- Adding TTG extension point for 'CCallTarget'
- Adding TTG extension point for 'CType'
- Adding TTG extension point for 'Header'
- Moving ForeignCall types that do not need extension
to new L.H.S.Decls.Foreign module
- Replacing 'Bool' parameters with descriptive data-types
to increase clairty and prevent "Boolean Blindness"
- - - - -
11a04cbb by Eric Lee at 2026-02-11T09:20:46-05:00
Derive Semigroup/Monoid for instances believed could be derived in #25871
- - - - -
15d9ce44 by Eric Lee at 2026-02-11T09:20:46-05:00
add Ghc.Data.Pair deriving
- - - - -
c85dc170 by Evan Piro at 2026-02-11T09:21:45-05:00
Linker.MacOS reduce options import
- - - - -
a541dd83 by Chris Wendt at 2026-02-11T16:06:41-05:00
Initialize plugins for `:set +c` in GHCi
Fixes #23110.
- - - - -
0f5a73bc by Cheng Shao at 2026-02-11T16:07:27-05:00
compiler: add Binary Text instance
This patch adds `Binary` instance for strict `Text`, in preparation of
making `Text` usable in certain GHC API use cases (e.g. haddock). This
also introduces `text` as a direct dependency of the `ghc` package.
- - - - -
9e58b8a1 by Cheng Shao at 2026-02-11T16:08:10-05:00
ghc-toolchain: add C11 check
This patch partially reverts commit
b8307eab80c5809df5405d76c822bf86877f5960 that removed C99 check in
autoconf/ghc-toolchain. Now we:
- No longer re-implement `FP_SET_CFLAGS_C11` similar to
`FP_SET_CFLAGS_C99` in the past, since autoconf doesn't provide a
convenient `AC_PROG_CC_C11` function. ghc-toolchain will handle it
anyway.
- The Cmm CPP C99 check is relanded and repurposed for C11.
- The C99 logic in ghc-toolchain is relanded and repurposed for C11.
- The C99 check in Stg.h is corrected to check for C11. The obsolete
_ISOC99_SOURCE trick is dropped.
- Usages of `-std=gnu99` in the testsuite are corrected to use
`-std=gnu11`.
Closes #26908.
- - - - -
4df0adf6 by Simon Peyton Jones at 2026-02-11T21:50:13-05:00
Simplify the treatment of static forms
This MR implements GHC proposal 732: simplify static forms,
https://github.com/ghc-proposals/ghc-proposals/pull/732
thereby addressing #26556.
See `Note [Grand plan for static forms]` in GHC.Iface.Tidy.StaticPtrTable
The main changes are:
* There is a new, simple rule for (static e), namely that the free
term variables of `e` must be bound at top level. The check is
done in the `HsStatic` case of `GHC.Rename.Expr.rnExpr`
* That in turn substantially simplifies the info that the typechecker
carries around in its type environment. Hooray.
* The desugarer emits static bindings to top level directly; see the
`HsStatic` case of `dsExpr`.
* There is no longer any special static-related magic in the FloatOut
pass. And the main Simplifier pipeline no longer needs a special case
to run FloatOut even with -O0. Hooray.
All this forced an unexpected change to the pattern match checker. It
recursively invokes the main Hs desugarer when it wants to take a look
at a term to spot some special cases (notably constructor applications).
We don't want to emit any nested (static e) bindings to top level a
second time! Yikes.
That forced a modest refactor in GHC.HsToCore.Pmc:
* The `dsl_nablas` field of `DsLclEnv` now has a `NoPmc` case, which says
"I'm desugaring just for pattern-match checking purposes".
* When that flag is set we don't emit static binds.
That in turn forces a cascade of refactoring, but the net effect is an
improvement; less risk of duplicated (even exponential?) work.
See Note [Desugaring HsExpr during pattern-match checking].
10% metric decrease, on some architectures, of compile-time max-bytes-used on T15304.
Metric Decrease:
T15304
- - - - -
7922f728 by Teo Camarasu at 2026-02-11T21:50:58-05:00
ghc-internal: avoid depending on GHC.Internal.Exts
This module is mostly just re-exports. It made sense as a user-facing
module, but there's no good reason ghc-internal modules should depend on
it and doing so linearises the module graph
- move considerAccessible to GHC.Internal.Magic
Previously it lived in GHC.Internal.Exts, but it really deserves to live
along with the other magic function, which are already re-exported from .Exts
- move maxTupleSize to GHC.Internal.Tuple
This previously lived in GHC.Internal.Exts but a comment already said it
should be moved to .Tuple
Resolves #26832
- - - - -
b6a4a29b by Eric Lee at 2026-02-11T21:51:55-05:00
Remove unused Semigroup imports to fix GHC 9.14 bootstrapping
- - - - -
99d8c146 by Simon Peyton Jones at 2026-02-12T17:36:59+00:00
Fix subtle bug in cast worker/wrapper
See (CWw4) in Note [Cast worker/wrapper].
The true payload is in the change to the definition of
GHC.Types.Id.Info.hasInlineUnfolding
Everthing else is just documentation.
There is a 2% compile time decrease for T13056;
I'll take the win!
Metric Decrease:
T13056
- - - - -
530e8e58 by Simon Peyton Jones at 2026-02-12T20:17:23-05:00
Add regression tests for four StaticPtr bugs
Tickets #26545, #24464, #24773, #16981 are all solved by the
recently-landed MR
commit 318ee13bcffa6aa8df42ba442ccd92aa0f7e210c
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Oct 20 23:07:20 2025 +0100
Simplify the treatment of static forms
This MR just adds regression tests for them.
- - - - -
4157160f by Cheng Shao at 2026-02-13T06:27:04-05:00
ci: remove unused hlint-ghc-and-base job definition
This patch removes the unused `hlint-ghc-and-base` job definition,
it's never run since !9806. Note that hadrian lint rules still work
locally, so anyone that wishes to run hlint on the codebase can
continue to do so in their local worktree.
- - - - -
039f1977 by Cheng Shao at 2026-02-13T06:27:47-05:00
wasm: use import.meta.main for proper distinction of nodejs main modules
This patch uses `import.meta.main` for proper distinction of nodejs
main modules, especially when the main module might be installed as a
symlink. Fixes #26916.
- - - - -
14f485ee by ARATA Mizuki at 2026-02-17T09:09:24+09:00
Support more x86 extensions: AVX-512 {BW,DQ,VL} and GFNI
Also, mark AVX-512 ER and PF as deprecated.
AVX-512 instructions can be used for certain 64-bit integer vector operations.
GFNI can be used to implement bitReverse (currently not used by NCG, but LLVM may use it).
Closes #26406
Addresses #26509
- - - - -
016f79d5 by fendor at 2026-02-17T09:16:16-05:00
Hide implementation details from base exception stack traces
Ensure we hide the implementation details of the exception throwing mechanisms:
* `undefined`
* `throwSTM`
* `throw`
* `throwIO`
* `error`
The `HasCallStackBacktrace` should always have a length of exactly 1,
not showing internal implementation details in the stack trace, as these
are vastly distracting to end users.
CLC proposal [#387](https://github.com/haskell/core-libraries-committee/issues/387)
- - - - -
4f2840f2 by Brian J. Cardiff at 2026-02-17T17:04:08-05:00
configure: Accept happy-2.2
In Jan 2026 happy-2.2 was released. The most sensible change is https://github.com/haskell/happy/issues/335 which didn't trigger in a fresh build
- - - - -
10b4d364 by Duncan Coutts at 2026-02-17T17:04:52-05:00
Fix errors in the documentation of the eventlog STOP_THREAD status codes
Fix the code for BlockedOnMsgThrowTo.
Document all the known historical warts.
Fixes issue #26867
- - - - -
c5e15b8b by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: use snippets for all list examples
- generate snippet output for docs
- reduce font size to better fit snippets
- Use only directive to guard html snippets
- Add latex snippets for lists
- - - - -
d388bac1 by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: Place the snippet input and output together
- Put the output seemingly inside the example box
- - - - -
016fa306 by Samuel Thibault at 2026-02-18T05:08:35-05:00
Fix linking against libm by moving the -lm option
For those systems that need -lm for getting math functions, this is
currently added on the link line very early, before the object files being
linked together. Newer toolchains enable --as-needed by default, which means
-lm is ignored at that point because no object requires a math function
yet. With such toolchains, we thus have to add -lm after the objects, so the
linker actually includes libm in the link.
- - - - -
68bd0805 by Teo Camarasu at 2026-02-18T05:09:19-05:00
ghc-internal: Move GHC.Internal.Data.Bool to base
This is a tiny module that only defines bool :: Bool -> a -> a -> a. We can just move this to base and delete it from ghc-internal. If we want this functionality there we can just use a case statement or if-then expression.
Resolves 26865
- - - - -
4c40df3d by fendor at 2026-02-20T10:24:48-05:00
Add optional `SrcLoc` to `StackAnnotation` class
`StackAnnotation`s give access to an optional `SrcLoc` field that
user-added stack annotations can use to provide better backtraces in both error
messages and when decoding the callstack.
We update builtin stack annotations such as `StringAnnotation` and
`ShowAnnotation` to also capture the `SrcLoc` of the current `CallStack`
to improve backtraces by default (if stack annotations are used).
This change is backwards compatible with GHC 9.14.1.
- - - - -
fd9aaa28 by Simon Hengel at 2026-02-20T10:25:33-05:00
docs: Fix grammar in explicit_namespaces.rst
- - - - -
44354255 by Vo Minh Thu at 2026-02-20T18:53:06-05:00
GHCi: add a :version command.
This looks like:
ghci> :version
GHCi, version 9.11.20240322
This closes #24576.
Co-Author: Markus Läll <markus.l2ll(a)gmail.com>
- - - - -
eab3dbba by Andreas Klebinger at 2026-02-20T18:53:51-05:00
hadrian/build-cabal: Better respect and utilize -j
* We now respect -j<n> for the cabal invocation to build hadrian rather
than hardcoding -j
* We use the --semaphore flag to ensure cabal/ghc build the hadrian
executable in parallel using the -jsem mechanism.
Saves 10-15s on fresh builds for me.
Fixes #26876
- - - - -
832ddbea by Apoorv Ingle at 2026-02-22T21:56:03-06:00
Work for #25001
Notes added [Error Context Stack]
Notes updated Note [Expanding HsDo with XXExprGhcRn]
-------------------------
Metric Decrease:
T9020
-------------------------
* Streamlines implementations of `tcExpr` and `tcXExpr` to work on `XExpr`
* Kills `VACtxt` (and its associated `VAExpansion` and `VACall`) datatype, it is subsumed by simply a `SrcSpan`.
* Kills the function `addHeadCtxt` as it is now mearly setting a location
* The function `tcValArgs` does its own argument number management
* Makes `splitHsApps` not look through `XExpr`
* `tcExprSigma` is called if the head of the expression after calling `splitHsApps` turns out to be an `XExpr`
* Removes location information from `OrigPat` payload
* Removes special case of tcBody from `tcLambdaMatches`
* Removes special case of `dsExpr` for `ExpandedThingTc`
* Rename `HsThingRn` to `SrcCodeCtxt`
* Kills `tcl_in_gen_code` and `tcl_err_ctxt`. It is subsumed by `ErrCtxtStack`
* Kills `ExpectedFunTyOrig`. It is subsumed by `CtOrigin`
* Fixes `CtOrigin` for `HsProjection` case in `exprCtOrigin`. It was previously assigned to be `SectionOrigin`. It is now just the expression
* Adds a new `CtOrigin.ExpansionOrigin` for storing the original syntax
* Adds a new `CtOrigin.ExpectedTySyntax` as a replacement for `ExpectedTySyntaxOp`. Cannot kill the former yet because of `ApplicativeDo`
* Renames `tcMonoExpr` -> `tcMonoLExpr`, `tcMonoExprNC` -> `tcMonoLExpr`
* Renames `EValArg`, `EValArgQL` fields: `ea_ctxt` -> `ea_loc_span` and `eaql_ctx` -> `eaql_loc_span`
* kill `PopErrCtxt` from `XXExprGhcRn`
* simplify `addArgCtxt` and push `setSrcSpan` inside `addLExprCtxt`. Make sure addExprCtxt is not called by itself
* fun_orig in tcApp depends on the SrcSpan of the head of the application chain (similar to addArgCtxt)
* rename fun_ctxt to fun_lspan, fun_orig passed in tcInstFun to default to app chain head if its user located, fall back to srcCodeOrigin if it's a generated location
* fix quickLookArg function to blame the correct application chain head. The arguments application chain head should be blamed, not the original head when we quick look arg
* Make sure only expression wrapped around generated src span are ignored while adding them to the error context stack
* `getDeepSubsumptionFlag_DataConHead` performs a non-trivial traversal if the expression passed to it is complex.
This traversal is necessary if the head of the function is an `XExpr` and `splitHsApps` does not look through them
- The deepsubsumption flag is stored in EVAlArgQL to reduce the need to call `getDeepSubsumptionFlag_DataConHead`
- `getDeepSubsumptionFlag_DataConHead` is called in `tcExprSigma` and `tcInferAppHead` to reduce AST traversals
* Make a new variant `GeneratedSrcSpan` in `SrcSpan` for HIEAst Nodes
* wrap `fromListN` with a generated src span with GeneratedSrcSpanDetails field to store the original srcspan
* remove `UnhelpfulGenerated` from `UnhelpfulSpanReason` and into new datatype `GeneratedSrcSpanDetails`
- - - - -
775bb8d3 by Simon Peyton Jones at 2026-02-22T21:56:27-06:00
Wibbles
- - - - -
bacf1d88 by Apoorv Ingle at 2026-02-22T21:56:28-06:00
notes update
Note [Typechecking by expansion: overview]
- - - - -
345 changed files:
- .gitlab-ci.yml
- compiler/GHC.hs
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/CmmToAsm/Config.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/Core/Lint.hs
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/CoreToStg.hs
- compiler/GHC/CoreToStg/AddImplicitBinds.hs
- compiler/GHC/Data/Pair.hs
- compiler/GHC/Driver/Config/CmmToAsm.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Doc.hs
- compiler/GHC/Hs/DocString.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Docs.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Foreign/C.hs
- compiler/GHC/HsToCore/Foreign/Call.hs
- compiler/GHC/HsToCore/Foreign/Decl.hs
- compiler/GHC/HsToCore/Foreign/JavaScript.hs
- compiler/GHC/HsToCore/Foreign/Utils.hs
- compiler/GHC/HsToCore/Foreign/Wasm.hs
- compiler/GHC/HsToCore/GuardedRHSs.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/HsToCore/Types.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Ext/Utils.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Linker/Dynamic.hs
- compiler/GHC/Linker/MacOS.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/HaddockLex.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/Foreign.hs
- compiler/GHC/StgToJS/FFI.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- + compiler/GHC/Tc/Gen/App.hs-boot
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Do.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs-boot
- compiler/GHC/Tc/Gen/Foreign.hs
- compiler/GHC/Tc/Gen/Head.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/Module.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Instance.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/CtLoc.hs
- compiler/GHC/Tc/Types/ErrCtxt.hs
- compiler/GHC/Tc/Types/LclEnv.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- − compiler/GHC/Tc/Utils/TcMType.hs-boot
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Zonk/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Error.hs
- compiler/GHC/Types/ForeignCall.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/SrcLoc.hs
- compiler/GHC/Types/Unique/DSet.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Logger.hs
- compiler/GHC/Utils/Ppr/Colour.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- + compiler/Language/Haskell/Syntax/Decls/Foreign.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/ghc.cabal.in
- configure.ac
- distrib/configure.ac.in
- + docs/users_guide/10.0.1-notes.rst
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/eventlog-formats.rst
- docs/users_guide/exts/explicit_namespaces.rst
- docs/users_guide/ghci.rst
- docs/users_guide/phases.rst
- docs/users_guide/using.rst
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Info.hs
- hadrian/build-cabal
- libraries/base/changelog.md
- libraries/base/src/Data/Bool.hs
- libraries/base/src/Data/List.hs
- libraries/base/src/Data/List/NubOrdSet.hs
- libraries/base/src/GHC/Exts.hs
- libraries/ghc-experimental/CHANGELOG.md
- libraries/ghc-experimental/src/GHC/Stack/Annotation/Experimental.hs
- + libraries/ghc-experimental/tests/Makefile
- + libraries/ghc-experimental/tests/all.T
- + libraries/ghc-experimental/tests/backtraces/Makefile
- + libraries/ghc-experimental/tests/backtraces/T26806a.hs
- + libraries/ghc-experimental/tests/backtraces/T26806a.stderr
- + libraries/ghc-experimental/tests/backtraces/T26806b.hs
- + libraries/ghc-experimental/tests/backtraces/T26806b.stderr
- + libraries/ghc-experimental/tests/backtraces/T26806c.hs
- + libraries/ghc-experimental/tests/backtraces/T26806c.stderr
- + libraries/ghc-experimental/tests/backtraces/all.T
- libraries/ghc-internal/ghc-internal.cabal.in
- − libraries/ghc-internal/src/GHC/Internal/Data/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Function.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Ord.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/Exts.hs
- libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghc-internal/src/GHC/Internal/IO/FD.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Foreign/Callback.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim/Internal/Build.hs
- libraries/ghc-internal/src/GHC/Internal/Magic.hs
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/Annotation.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/Tuple.hs
- libraries/ghc-internal/src/GHC/Internal/TypeError.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Exports.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Imports.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Types.hs
- + libraries/ghc-internal/tests/backtraces/T15395.hs
- + libraries/ghc-internal/tests/backtraces/T15395.stdout
- libraries/ghc-internal/tests/backtraces/all.T
- libraries/ghc-internal/tests/stack-annotation/ann_frame001.stdout
- libraries/ghc-internal/tests/stack-annotation/ann_frame002.stdout
- libraries/ghc-internal/tests/stack-annotation/ann_frame003.stdout
- libraries/ghc-internal/tests/stack-annotation/ann_frame004.stdout
- libraries/ghc-internal/tests/stack-annotation/ann_frame005.stdout
- m4/fp_cmm_cpp_cmd_with_args.m4
- m4/fptools_happy.m4
- rts/include/Stg.h
- rts/prim/atomic.c
- testsuite/driver/cpu_features.py
- − testsuite/driver/kill_extra_files.py
- testsuite/driver/testlib.py
- testsuite/tests/arrows/should_compile/T21301.stderr
- testsuite/tests/codeGen/should_gen_asm/all.T
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.hs
- testsuite/tests/codeGen/should_run/CgStaticPointers.hs
- testsuite/tests/codeGen/should_run/CgStaticPointersNoFullLazyness.hs
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- 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_run/T9576.stderr
- testsuite/tests/ffi/should_run/all.T
- testsuite/tests/ghci/scripts/Defer02.stderr
- testsuite/tests/ghci/scripts/T15325.stderr
- testsuite/tests/ghci/scripts/T20150.stdout
- testsuite/tests/indexed-types/should_fail/T2693.stderr
- testsuite/tests/indexed-types/should_fail/T5439.stderr
- 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/overloadedrecflds/should_fail/T26480b.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail10.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail11.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
- testsuite/tests/patsyn/should_run/ghci.stderr
- + testsuite/tests/plugins/T23110.hs
- + testsuite/tests/plugins/T23110.script
- + testsuite/tests/plugins/T23110.stdout
- testsuite/tests/plugins/all.T
- testsuite/tests/plugins/test-defaulting-plugin.stderr
- testsuite/tests/printer/T17697.stderr
- testsuite/tests/process/all.T
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- testsuite/tests/rebindable/rebindable6.stderr
- testsuite/tests/rename/should_fail/RnStaticPointersFail01.stderr
- testsuite/tests/rename/should_fail/RnStaticPointersFail03.stderr
- + testsuite/tests/rename/should_fail/T26545.hs
- + testsuite/tests/rename/should_fail/T26545.stderr
- testsuite/tests/rename/should_fail/all.T
- testsuite/tests/rep-poly/RepPolyDoBind.stderr
- testsuite/tests/rep-poly/RepPolyDoBody1.stderr
- testsuite/tests/rep-poly/RepPolyDoBody2.stderr
- testsuite/tests/rep-poly/RepPolyRecordUpdate.stderr
- testsuite/tests/safeHaskell/safeLanguage/SafeLang15.stderr
- testsuite/tests/showIface/DocsInHiFile1.stdout
- testsuite/tests/showIface/HaddockSpanIssueT24378.stdout
- testsuite/tests/showIface/MagicHashInHaddocks.stdout
- testsuite/tests/simd/should_run/all.T
- + testsuite/tests/simplCore/should_compile/T26903.hs
- + testsuite/tests/simplCore/should_compile/T26903.stderr
- testsuite/tests/simplCore/should_compile/T8331.stderr
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/type-data/should_run/T22332a.stderr
- + testsuite/tests/typecheck/should_compile/ExpansionQLIm.hs
- testsuite/tests/typecheck/should_compile/T14590.stderr
- + testsuite/tests/typecheck/should_compile/T24464.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/valid_hole_fits.stderr
- testsuite/tests/typecheck/should_fail/DoExpansion1.stderr
- testsuite/tests/typecheck/should_fail/DoExpansion2.stderr
- testsuite/tests/typecheck/should_fail/T10971d.stderr
- testsuite/tests/typecheck/should_fail/T13311.stderr
- testsuite/tests/typecheck/should_fail/T3323.stderr
- testsuite/tests/typecheck/should_fail/T3613.stderr
- testsuite/tests/typecheck/should_fail/T6069.stderr
- testsuite/tests/typecheck/should_fail/T7851.stderr
- testsuite/tests/typecheck/should_fail/T7857.stderr
- testsuite/tests/typecheck/should_fail/T8603.stderr
- testsuite/tests/typecheck/should_fail/T9612.stderr
- testsuite/tests/typecheck/should_fail/tcfail102.stderr
- testsuite/tests/typecheck/should_fail/tcfail128.stderr
- testsuite/tests/typecheck/should_fail/tcfail140.stderr
- testsuite/tests/typecheck/should_fail/tcfail181.stderr
- testsuite/tests/typecheck/should_run/T10284.stderr
- testsuite/tests/typecheck/should_run/T13838.stderr
- + testsuite/tests/typecheck/should_run/T16981.hs
- + testsuite/tests/typecheck/should_run/T16981.stdout
- + testsuite/tests/typecheck/should_run/T24773.hs
- + testsuite/tests/typecheck/should_run/T24773.stdout
- 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/typecheck/should_run/all.T
- testsuite/tests/unsatisfiable/T23816.stderr
- testsuite/tests/unsatisfiable/UnsatDefer.stderr
- testsuite/tests/warnings/should_fail/CaretDiagnostics1.stderr
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Parsers.hs
- utils/check-exact/Transform.hs
- utils/check-exact/Utils.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cc.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs
- utils/haddock/doc/.gitignore
- utils/haddock/doc/Makefile
- + utils/haddock/doc/_static/haddock-custom.css
- utils/haddock/doc/conf.py
- utils/haddock/doc/markup.rst
- + utils/haddock/doc/snippets/.gitignore
- + utils/haddock/doc/snippets/Lists.hs
- + utils/haddock/doc/snippets/Makefile
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.html
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.tex
- + utils/haddock/doc/snippets/Snippet-List-Definition.html
- + utils/haddock/doc/snippets/Snippet-List-Definition.tex
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.html
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.tex
- + utils/haddock/doc/snippets/Snippet-List-Indentation.html
- + utils/haddock/doc/snippets/Snippet-List-Indentation.tex
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.tex
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Parser.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Utils.hs
- utils/haddock/haddock-api/src/Haddock/Interface/LexParseRn.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
- utils/haddock/html-test/ref/A.html
- utils/haddock/html-test/ref/Bug1004.html
- utils/haddock/html-test/ref/Bug1033.html
- utils/haddock/html-test/ref/Bug1103.html
- utils/haddock/html-test/ref/Bug548.html
- utils/haddock/html-test/ref/Bug923.html
- utils/haddock/html-test/ref/ConstructorPatternExport.html
- utils/haddock/html-test/ref/FunArgs.html
- utils/haddock/html-test/ref/Hash.html
- utils/haddock/html-test/ref/Instances.html
- utils/haddock/html-test/ref/LinearTypes.html
- utils/haddock/html-test/ref/RedactTypeSynonyms.html
- utils/haddock/html-test/ref/T23616.html
- utils/haddock/html-test/ref/Test.html
- utils/haddock/html-test/ref/TypeFamilies3.html
- utils/jsffi/dyld.mjs
- utils/jsffi/post-link.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bf6586bdd937eea5107f283f69ca0c…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bf6586bdd937eea5107f283f69ca0c…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/ani/kill-SrcCodeOrigin] some in complete data defs
by Apoorv Ingle (@ani) 23 Feb '26
by Apoorv Ingle (@ani) 23 Feb '26
23 Feb '26
Apoorv Ingle pushed to branch wip/ani/kill-SrcCodeOrigin at Glasgow Haskell Compiler / GHC
Commits:
4800bc7c by Apoorv Ingle at 2026-02-22T21:39:54-06:00
some in complete data defs
- - - - -
6 changed files:
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/TyCl/Instance.hs
Changes:
=====================================
compiler/GHC/Hs/Instances.hs
=====================================
@@ -620,48 +620,18 @@ deriving instance Eq (IE GhcTc)
-- ---------------------------------------------------------------------
--- deriving instance Data ErrCtxtMsg
--- deriving instance Data XXExprGhcRn
-con_ExpandedThingRn = mkConstr xXExprGhcRn_T "ExpandedThingRn" [] Prefix
-con_HsRecSelRn = mkConstr xXExprGhcRn_T "HsRecSelRn" [] Prefix
-xXExprGhcRn_T = mkDataType "GHC.Hs.Expr.XXExprGhcRn" []
+instance Data ErrCtxtMsg where
+ gunfold _ _ _ = error "no gunfold for ErrCtxtMsg"
+ gfoldl _ _ _ = error "no goldl for ErrCtxtMsg"
-instance Data XXExprGhcRn where
- toConstr (ExpandedThingRn{}) = con_ExpandedThingRn
- toConstr (HsRecSelRn{}) = con_HsRecSelRn
- dataTypeOf _ = xXExprGhcRn_T
-
- gunfold k z c = error "no gunfold for XXExprGhcRn"
- gfoldl k z c = error "no gfoldl for XXExprGhcRn"
+deriving instance Data XXExprGhcRn
deriving instance Data a => Data (WithUserRdr a)
--- ---------------------------------------------------------------------
-
--- deriving instance Data XXExprGhcTc
-con_ExpandedThingTc = mkConstr xXExprGhcTc_T "ExpandedThingTc" [] Prefix
-con_WrapExpr = mkConstr xXExprGhcTc_T "WrapExpr" [] Prefix
-con_ConLikeTc = mkConstr xXExprGhcTc_T "ConLikeTc" [] Prefix
-con_HsTick = mkConstr xXExprGhcTc_T "HsTick" [] Prefix
-con_HsBinTick = mkConstr xXExprGhcTc_T "HsBinTick" [] Prefix
-con_HsRecSelTc = mkConstr xXExprGhcTc_T "HsRecSelTc" [] Prefix
-xXExprGhcTc_T = mkDataType "GHC.Hs.Expr.XXExprGhcTc" []
-
-instance Data XXExprGhcTc where
- toConstr (ExpandedThingTc{}) = con_ExpandedThingTc
- toConstr (WrapExpr{}) = con_WrapExpr
- toConstr (ConLikeTc{}) = con_ConLikeTc
- toConstr (HsTick{}) = con_HsTick
- toConstr (HsBinTick{}) = con_HsBinTick
- toConstr (HsRecSelTc{}) = con_HsRecSelTc
-
- dataTypeOf _ = xXExprGhcTc_T
-
-
- gunfold _ _ _ = error "no gunfold for XXExprGhcTc"
- gfoldl _ _ _ = error "no gfoldl for XXExprGhcTc"
-
+-- -------------------------------
+--------------------------------------
+deriving instance Data XXExprGhcTc
deriving instance Data XXPatGhcTc
-- ---------------------------------------------------------------------
=====================================
compiler/GHC/HsToCore/Expr.hs
=====================================
@@ -40,6 +40,7 @@ import GHC.Hs
-- needs to see source types
import GHC.Tc.Utils.TcType
import GHC.Tc.Types.Evidence
+import GHC.Tc.Types.ErrCtxt
import GHC.Tc.Utils.Monad
import GHC.Tc.Instance.Class (lookupHasFieldLabel)
@@ -296,7 +297,7 @@ dsExpr e@(XExpr ext_expr_tc)
ConLikeTc {} -> dsApp e
ExpandedThingTc o e
- | OrigStmt (L loc _) _ <- o -- c.f. T14546d. We have lost the location of the first statement in the GhcRn -> GhcTc
+ | DoStmtErrCtxt _ (L loc _) <- o -- c.f. T14546d. We have lost the location of the first statement in the GhcRn -> GhcTc
-> putSrcSpanDsA loc $ dsExpr e
| otherwise -> dsExpr e
=====================================
compiler/GHC/HsToCore/Quote.hs
=====================================
@@ -41,6 +41,7 @@ import GHC.Hs.Decls.Overlap ( OverlapMode(..) )
import GHC.Tc.Utils.TcType
import GHC.Tc.Types.Evidence
+import GHC.Tc.Types.ErrCtxt
import GHC.Tc.TyCl ( IsPrefixConGADT(..), unannotatedMultIsLinear )
import GHC.Core.Class
@@ -1732,7 +1733,7 @@ repE (HsFunArr _ mult arg res) = do
res' <- repLE res
repApps fun [arg', res']
repE e@(XExpr (ExpandedThingRn o x))
- | OrigExpr e <- o
+ | ExprCtxt e <- o
= do { rebindable_on <- lift $ xoptM LangExt.RebindableSyntax
; if rebindable_on -- See Note [Quotation and rebindable syntax]
then repE x
=====================================
compiler/GHC/Tc/Gen/Expr.hs
=====================================
@@ -268,6 +268,13 @@ tcCheckMonoExpr, tcCheckMonoExprNC
tcCheckMonoExpr expr res_ty = tcMonoLExpr expr (mkCheckExpType res_ty)
tcCheckMonoExprNC expr res_ty = tcMonoLExprNC expr (mkCheckExpType res_ty)
+
+-- Expand the HsExpr if it is typechecked after expansions
+-- See Note [Handling overloaded and rebindable constructs]
+-- See Note [Typechecking by expansion: overview]
+expand_expr :: HsExpr GhcRn -> TcM (HsExpr GhcRn)
+expand_expr x = return x
+
---------------
tcMonoLExpr, tcMonoLExprNC
:: LHsExpr GhcRn -- Expression to type check
@@ -276,9 +283,10 @@ tcMonoLExpr, tcMonoLExprNC
-> TcM (LHsExpr GhcTc)
tcMonoLExpr (L loc expr) res_ty
- = addLExprCtxt (locA loc) expr $ -- Note [Error contexts in generated code]
- do { expr' <- tcExpr expr res_ty
- ; return (L loc expr') }
+ = do expanded_expr <- expand_expr expr
+ addLExprCtxt (locA loc) expanded_expr $ -- Note [Error contexts in generated code]
+ do { expr' <- tcExpr expr res_ty
+ ; return (L loc expr') }
tcMonoLExprNC (L loc expr) res_ty
= setSrcSpanA loc $
@@ -676,7 +684,7 @@ tcExpr expr@(RecordUpd { rupd_expr = record_expr
; (ds_expr, ds_res_ty, err_msg)
<- expandRecordUpd record_expr possible_parents rbnds res_ty
- ; addExpansionErrCtxt (ExprCtxt expr) err_msg $
+ ; addExpansionErrCtxt err_msg $
do { -- Typecheck the expanded expression.
expr' <- tcExpr ds_expr (Check ds_res_ty)
-- NB: it's important to use ds_res_ty and not res_ty here.
=====================================
compiler/GHC/Tc/Gen/Match.hs
=====================================
@@ -487,7 +487,7 @@ tcStmtsAndThen ctxt stmt_chk (L loc stmt : stmts) res_ty thing_inside
| otherwise
= do { (stmt', (stmts', thing)) <-
setSrcSpanA loc $
- addErrCtxt (StmtErrCtxt ctxt (L loc stmt)) $
+ addErrCtxt (StmtErrCtxt ctxt stmt) $
stmt_chk ctxt stmt res_ty $ \ res_ty' ->
popErrCtxt $
tcStmtsAndThen ctxt stmt_chk stmts res_ty' $
=====================================
compiler/GHC/Tc/TyCl/Instance.hs
=====================================
@@ -2108,7 +2108,7 @@ tcMethodBodyHelp hs_sig_fn sel_id local_meth_id meth_bind
-- The instance-sig is the focus here; the class-meth-sig
-- is fixed (#18036)
; let orig = InstanceSigOrigin sel_name sig_ty local_meth_ty
- ; hs_wrap <- addErrCtxtM (MethSigCtxt sel_name sig_ty meth_ty) $
+ ; hs_wrap <- addErrCtxtM (MethSigCtxt sel_name sig_ty local_meth_ty) $
tcSubTypeSigma orig ctxt sig_ty local_meth_ty
; return (sig_ty, hs_wrap) }
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4800bc7c37b8085d840c3e41cbd1f2e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4800bc7c37b8085d840c3e41cbd1f2e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Simon Peyton Jones pushed to branch wip/T26868 at Glasgow Haskell Compiler / GHC
Commits:
70cc6607 by Simon Peyton Jones at 2026-02-22T18:24:43+00:00
Add missing file!
- - - - -
1 changed file:
- + compiler/GHC/Types/Var/FV.hs
Changes:
=====================================
compiler/GHC/Types/Var/FV.hs
=====================================
@@ -0,0 +1,230 @@
+{-# LANGUAGE PatternSynonyms #-}
+
+-- | Utilities for efficiently and deterministically computing free variables.
+module GHC.Types.Var.FV (
+ FV( runFV, MkFV ),
+ BoundVars, VarSetFV, DVarSetFV, SelectiveFV,
+ TyCoFV, DTyCoFV,
+ runFVTop, runFVAcc, runTyCoVars, runTyCoVarsDSet,
+ runFVSelective, runFVSelectiveList, runFVSelectiveSet,
+ InterestingVarFun,
+
+ addBndrFV, addBndrsFV, addBndrSelectiveFV, addBndrsSelectiveFV,
+ emptyFV, -- or `mempty`
+ unionFV, -- or `mappend`
+ mapUnionFV
+ ) where
+
+import GHC.Prelude
+
+import GHC.Types.Var
+import GHC.Types.Var.Set
+
+import GHC.Utils.EndoOS
+
+import GHC.Exts( oneShot )
+import Data.Semigroup
+
+{- Note [Finding free variables]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We have lots of different free-variable finders:
+ * Shallow or deep: do we include the kind of a variable occurrence
+ * Deterministic or non-determinstic: what kind of set is collected
+ * Selective or not: selective means there is a predicate that says
+ which variables are of interest
+
+The type (FV env set) is the result-type of a free-variable finder, e.g.
+ tyCoVarsOfType :: Type -> FV BoundVars VarSet
+
+Here
+ * `env` is an environment, which records the locally-bound varaibles
+ (which are not of interest since they aren't free) and optionally
+ the selective predicate.
+
+ * `set` is the accumulating result set
+
+The FV type is roughly
+
+ type FV env set = env -> set -> set
+
+So `tyCoVarsOfType ty` is a function that takes an environment a set-
+valued accumulator, and extends the set with the free vars of `ty`.
+See (FV1) for why we use an accumulating parameter here.
+
+However, we want to take the union of two FV values, thus
+ tyCoVarsOfType t1 `mappend` tyCoVarsOfType t2
+We do this by making `FV` an instance of `Monoid` and `Semigroup`
+and using `mappend`. So we use a newtype wrapper.
+
+Some important wrinkles for efficiency:
+
+(FV1) Accumulating parameter for the free variables. We could return a
+ VarSet, and do lots of `unionVarSet`. But it's quite a bit more efficient
+ to use an accumulating parameter and add free variables one at a time.
+
+ We implement this using a (GHC-specific variant of) the standard `Endo`
+ type. The `mappend` for `Endo` is just function composition; see
+ GHC.Utils.Endo
+
+ This is more efficient for two reasons:
+ * Doing a tree of `unionVarSet` calls is asymptotically inefficient.
+ * For "deep" free variables, if we have an accumulator we can see if we
+ have encountered this variable before; if so, we don't need to look at its
+ kind. See Note [Shallow and deep free variables] in GHC.Core.TyCo.FVs
+
+(FV2) Eta expansion. It's very important that, after optimisation, we end up
+ with an arity-3 function. Let's consider:
+
+ tyCoVarsOfType (AppTy a b) = tyCoVarsOfType a `mappend` tyCoVarsOfType b
+
+ If we aren't careful, ater inlining `mappend`, we'll end up with
+
+ tyCoVarsOfType = \ty ->
+ case ty of
+ AppTy a b -> \env acc ->
+ tyCoVarsOfType a env (tyCoVarsOfType env acc)
+
+ which has to create a lambda, entirely unnecessarily. On the other hand if it
+ is eta-expanded, we get this:
+
+ tyCoVarsOfType = \ty env acc->
+ case ty of
+ AppTy a b -> tyCoVarsOfType a env (tyCoVarsOfType env acc)
+
+ We achieve this using the "one-shot trick" described in
+ Note [The one-shot state monad trick] in GHC.Utils.Monad, both for the
+ `env` parameter (see `oneShot` call in this module), and the `acc`
+ accumulator (see `onShot` call in GHC.Utils.EndoOS).
+
+ See also #11146.
+
+(FV3) Avoiding thunks. The `mappend` for `Endo` is just function composition,
+ but we don't want to get code like
+ tyCoVarsOfType (AppTy a b) env acc = tyCoVarsOfType a env $ tyCoVarsOfType b env acc
+ because that argument is a thunk. We want to be strict in the accumulator, so we get
+ tyCoVarsOfType (AppTy a b) env acc = tyCoVarsOfType env a $! tyCoVarsOfType b env acc
+ The strictness is done by the (<>) mmthod in `EndoOS`.
+
+(FV4) Order. When computing order-deterministic free vars, we'd like to return the
+ variables in left-to-right order. Thus, the free vars of (a -> b -> b) should
+ be [a,b] not [b,a]. This matters for quantifying variables in a predictable
+ way.
+
+ We achieve this by
+ * Combining sub-expressions in the natural left-to-right way. e.g.
+ tyCoVarsOfType (AppTy a b) = tyCoVarsOfType a `unionFV` tyCoVarsOfType b
+ * Ihe EndoOS instance, make (f <> g) do (g.f), that is compose "backwards"
+
+Note [Deterministic FV]
+~~~~~~~~~~~~~~~~~~~~~~~
+When computing free variables, the order in which you get them affects
+the results of floating and specialization. If you use UniqFM to collect
+them and then turn that into a list, you get them in nondeterministic
+order as described in Note [Deterministic UniqFM] in GHC.Types.Unique.DFM.
+
+So we instead collect them in a `DVarSet` (deterministic VarSet).
+-}
+
+
+{- *********************************************************************
+* *
+ Free-var result type
+* *
+********************************************************************* -}
+
+type InterestingVarFun = Var -> Bool
+
+type BoundVars = TyCoVarSet
+
+type VarSetFV = FV BoundVars (EndoOS TyCoVarSet)
+type DVarSetFV = FV BoundVars (EndoOS DTyCoVarSet)
+type SelectiveFV = FV (InterestingVarFun, BoundVars) (EndoOS DVarSet)
+-- VarSetFV: collects a VarSet
+-- DVarSetFV: collects a DVarSet (deterministic)
+-- SelectiveFV: selectively collects a DVarSet
+-- Why EndoOS? See (FV1) in Note [Finding free variables]
+
+type TyCoFV = VarSetFV
+type DTyCoFV = DVarSetFV
+
+newtype FV env acc = MkFV' { runFV :: env -> acc }
+ -- Caries an environment (typically empty, or a set of in-scope variables)
+ -- and a composable accumulator.
+ --
+ -- NB: `acc` is usually (EndoOS something) but not always;
+ -- see for example GHC.Core.TyCo.FVs.afvFolder
+
+pattern MkFV :: (env -> acc) -> FV env acc
+{-# COMPLETE MkFV #-}
+pattern MkFV f <- MkFV' f
+ where
+ MkFV f = MkFV' (oneShot f)
+ -- oneShot: this is the core of the one-shot trick!
+ -- Note [The one-shot state monad trick] in GHC.Utils.Monad.
+
+instance Semigroup a => Semigroup (FV env a) where
+ (<>) = unionFV
+
+instance Monoid a => Monoid (FV env a) where
+ mempty = emptyFV
+
+emptyFV :: Monoid a => FV env a
+emptyFV = MkFV (\_ -> mempty)
+
+unionFV :: Semigroup a => FV env a -> FV env a -> FV env a
+unionFV (MkFV' f1) (MkFV' f2) = MkFV (\env -> f1 env <> f2 env)
+
+upd_bndrs_fv :: (env -> env) -> FV env a -> FV env a
+{-# INLINE addBndrFV #-}
+upd_bndrs_fv upd f = MkFV (\bvs -> runFV f $! upd bvs)
+ -- Strict application to avoid making a thunk
+
+addBndrFV :: TyCoVar -> FV BoundVars a -> FV BoundVars a
+addBndrFV tcv = upd_bndrs_fv (\bvs -> extendVarSet bvs tcv)
+
+addBndrsFV :: [Var] -> FV BoundVars a -> FV BoundVars a
+addBndrsFV tcvs = upd_bndrs_fv (\bvs -> extendVarSetList bvs tcvs)
+
+addBndrSelectiveFV :: TyCoVar -> FV (f, BoundVars) a -> FV (f, BoundVars) a
+addBndrSelectiveFV tcv
+ = upd_bndrs_fv (\(f,bvs) -> let !bvs' = extendVarSet bvs tcv
+ -- Strict let to avoid thunks
+ in (f,bvs'))
+
+addBndrsSelectiveFV :: [Var] -> FV (f, BoundVars) a -> FV (f, BoundVars) a
+addBndrsSelectiveFV bs
+ = upd_bndrs_fv (\(f,bvs) -> let !bvs' = extendVarSetList bvs bs
+ -- Strict let to avoid thunks
+ in (f,bvs'))
+
+mapUnionFV :: (Foldable t, Monoid acc)
+ => (a -> FV env acc) -> t a -> FV env acc
+{-# INLINE mapUnionFV #-}
+mapUnionFV f xs = foldr (mappend . f) mempty xs
+
+
+runFVTop :: FV BoundVars a -> a
+{-# INLINE runFVTop #-}
+runFVTop f = runFV f (emptyVarSet :: BoundVars)
+
+runFVAcc :: FV BoundVars (EndoOS a) -> a -> a
+{-# INLINE runFVAcc #-}
+runFVAcc f = runEndoOS (runFVTop f)
+
+runTyCoVars :: TyCoFV -> TyCoVarSet
+{-# INLINE runTyCoVars #-}
+runTyCoVars f = runFVAcc f emptyVarSet
+
+runTyCoVarsDSet :: DTyCoFV -> DTyCoVarSet
+{-# INLINE runTyCoVarsDSet #-}
+runTyCoVarsDSet f = runFVAcc f emptyDVarSet
+
+runFVSelective :: InterestingVarFun -> SelectiveFV -> DVarSet
+runFVSelective interesting f
+ = runEndoOS (runFV f (interesting, emptyVarSet)) emptyDVarSet
+
+runFVSelectiveList :: InterestingVarFun -> SelectiveFV -> [Var]
+runFVSelectiveList interesting f = dVarSetElems (runFVSelective interesting f)
+
+runFVSelectiveSet :: InterestingVarFun -> SelectiveFV -> VarSet
+runFVSelectiveSet interesting f = dVarSetToVarSet (runFVSelective interesting f)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/70cc6607e91c2a8a512269ce864e6e0…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/70cc6607e91c2a8a512269ce864e6e0…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26868] Major refactor of free-variable functions
by Simon Peyton Jones (@simonpj) 22 Feb '26
by Simon Peyton Jones (@simonpj) 22 Feb '26
22 Feb '26
Simon Peyton Jones pushed to branch wip/T26868 at Glasgow Haskell Compiler / GHC
Commits:
d3f56f61 by Simon Peyton Jones at 2026-02-21T22:55:58+00:00
Major refactor of free-variable functions
For some time we have had two free-variable mechanims for types:
* The "FV" mechanism, embodied in GHC.Utils.FV, which worked OK, but
was fragile where eta-expansion was concerned.
* The TyCoFolder mechanism, using a one-shot EndoOS accumulator
I finally got tired of this and refactored the whole thing. Now we have
* GHC.Types.Var.FV, which has a composable free-variable result type,
very much in the spirit of the old `FV`, but much more robust.
(It uses the "one shot trick".)
* GHC.Core.TyCo.FVs now has just one technology for free variables.
All this led to a lot of renaming.
- - - - -
18 changed files:
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/FVs.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Subst.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Utils/EndoOS.hs
- − compiler/GHC/Utils/FV.hs
- compiler/ghc.cabal.in
- utils/haddock/haddock-api/src/Haddock/GhcUtils.hs
Changes:
=====================================
compiler/GHC/Core/Coercion.hs
=====================================
@@ -78,7 +78,6 @@ module GHC.Core.Coercion (
-- ** Free variables
tyCoVarsOfCo, tyCoVarsOfCos, coVarsOfCo,
- tyCoFVsOfCo, tyCoVarsOfCoDSet,
coercionSize, anyFreeVarsOfCo,
-- ** Substitution
=====================================
compiler/GHC/Core/FVs.hs
=====================================
@@ -35,7 +35,7 @@ module GHC.Core.FVs (
ruleLhsFreeIds, ruleLhsFreeIdsList,
ruleRhsFreeVars, rulesRhsFreeIds,
- exprFVs, addBndrFV, addBndrsFV, unitFV,
+ exprFVs, addCoreBndrFV, addCoreBndrsFV, unitFV,
-- * Orphan names
orphNamesOfType, orphNamesOfTypes, orphNamesOfAxiomLHS,
@@ -61,8 +61,9 @@ import GHC.Types.Id.Info
import GHC.Types.Name.Set
import GHC.Types.Name
import GHC.Types.Tickish
-import GHC.Types.Var.Set
import GHC.Types.Var
+import GHC.Types.Var.Set
+import GHC.Types.Var.FV
import GHC.Core.Type
import GHC.Core.TyCo.Rep
import GHC.Core.TyCo.FVs
@@ -154,10 +155,10 @@ exprsFreeIdsList = dVarSetElems . exprsFreeIdsDSet
bindFreeVars :: CoreBind -> VarSet
bindFreeVars = runFVSelectiveSet isLocalVar . bind_fvs
-bind_fvs :: CoreBind -> SelectiveFVRes
+bind_fvs :: CoreBind -> SelectiveFV
bind_fvs (NonRec b r) = rhs_fvs (b,r)
-bind_fvs (Rec prs) = addBndrsSelectiveFVRes (map fst prs) $
- mapUnionFVRes rhs_fvs prs
+bind_fvs (Rec prs) = addBndrsSelectiveFV (map fst prs) $
+ mapUnionFV rhs_fvs prs
-- | Finds free variables in an expression selected by a predicate
exprSomeFreeVars :: InterestingVarFun -- ^ Says which 'Var's are interesting
@@ -199,20 +200,20 @@ exprsSomeFreeVarsDSet :: InterestingVarFun -- ^ Says which 'Var's are interestin
-> DVarSet
exprsSomeFreeVarsDSet fv_cand = runFVSelective fv_cand . exprsFVs
-addBndrFV :: CoreBndr -> SelectiveFVRes -> SelectiveFVRes
-addBndrFV bndr fvr
+addCoreBndrFV :: CoreBndr -> SelectiveFV -> SelectiveFV
+addCoreBndrFV bndr fvr
= bndrTypeTyCoFVs bndr `mappend`
-- Include type variables in the binder's type
-- (not just Ids; coercion variables too!)
- addBndrSelectiveFVRes bndr fvr
+ addBndrSelectiveFV bndr fvr
-addBndrsFV :: [CoreBndr] -> SelectiveFVRes -> SelectiveFVRes
-addBndrsFV bndrs fv = foldr addBndrFV fv bndrs
+addCoreBndrsFV :: [CoreBndr] -> SelectiveFV -> SelectiveFV
+addCoreBndrsFV bndrs fv = foldr addCoreBndrFV fv bndrs
-unitFV :: Var -> SelectiveFVRes
+unitFV :: Var -> SelectiveFV
-- Deals with an occurrence
-- Shallow: does not look at the kind
-unitFV v = FVRes (\bvs -> EndoOS (do_it bvs))
+unitFV v = MkFV (\bvs -> EndoOS (do_it bvs))
where
do_it (is_interesting,bvs) acc
| not (is_interesting v) = acc -- The "selective" bit
@@ -220,49 +221,49 @@ unitFV v = FVRes (\bvs -> EndoOS (do_it bvs))
| v `elemDVarSet` acc = acc
| otherwise = acc `extendDVarSet` v
-exprsFVs :: [CoreExpr] -> SelectiveFVRes
-exprsFVs = mapUnionFVRes exprFVs
+exprsFVs :: [CoreExpr] -> SelectiveFV
+exprsFVs = mapUnionFV exprFVs
-exprFVs :: CoreExpr -> SelectiveFVRes
-exprFVs (Type ty) = tyCoFVsOfType ty
-exprFVs (Coercion co) = tyCoFVsOfCo co
+exprFVs :: CoreExpr -> SelectiveFV
+exprFVs (Type ty) = shallowSelTypeFV ty
+exprFVs (Coercion co) = shallowSelCoFV co
exprFVs (Var var) = unitFV var
exprFVs (Lit _) = mempty
exprFVs (Tick t expr) = tickish_fvs t `mappend` exprFVs expr
exprFVs (App fun arg) = exprFVs fun `mappend` exprFVs arg
-exprFVs (Lam bndr body) = addBndrFV bndr (exprFVs body)
-exprFVs (Cast expr co) = exprFVs expr `mappend` tyCoFVsOfCo co
+exprFVs (Lam bndr body) = addCoreBndrFV bndr (exprFVs body)
+exprFVs (Cast expr co) = exprFVs expr `mappend` shallowSelCoFV co
exprFVs (Case scrut bndr ty alts)
- = exprFVs scrut `mappend` tyCoFVsOfType ty `mappend`
- addBndrFV bndr (mapUnionFVRes alt_fvs alts)
+ = exprFVs scrut `mappend` shallowSelTypeFV ty `mappend`
+ addCoreBndrFV bndr (mapUnionFV alt_fvs alts)
where
- alt_fvs (Alt _ bndrs rhs) = addBndrsFV bndrs (exprFVs rhs)
+ alt_fvs (Alt _ bndrs rhs) = addCoreBndrsFV bndrs (exprFVs rhs)
exprFVs (Let (NonRec bndr rhs) body)
- = rhs_fvs (bndr, rhs) `mappend` addBndrFV bndr (exprFVs body)
+ = rhs_fvs (bndr, rhs) `mappend` addCoreBndrFV bndr (exprFVs body)
exprFVs (Let (Rec pairs) body)
- = addBndrsFV (map fst pairs) $
- mapUnionFVRes rhs_fvs pairs `mappend` exprFVs body
+ = addCoreBndrsFV (map fst pairs) $
+ mapUnionFV rhs_fvs pairs `mappend` exprFVs body
---------
-rhs_fvs :: (Id, CoreExpr) -> SelectiveFVRes
+rhs_fvs :: (Id, CoreExpr) -> SelectiveFV
rhs_fvs (bndr, rhs) = exprFVs rhs `mappend`
bndrRuleAndUnfoldingFVs bndr
-- Treat any RULES as extra RHSs of the binding
---------
-tickish_fvs :: CoreTickish -> SelectiveFVRes
-tickish_fvs (Breakpoint _ _ ids) = mapUnionFVRes unitFV ids
+tickish_fvs :: CoreTickish -> SelectiveFV
+tickish_fvs (Breakpoint _ _ ids) = mapUnionFV unitFV ids
tickish_fvs _ = mempty
---------
-bndrTypeTyCoFVs :: Var -> SelectiveFVRes
+bndrTypeTyCoFVs :: Var -> SelectiveFV
-- Find the free variables of a binder.
-- In the case of ids, don't forget the multiplicity field!
bndrTypeTyCoFVs var
- = tyCoFVsOfType (varType var) `mappend` mult_fvs
+ = shallowSelTypeFV (varType var) `mappend` mult_fvs
where
mult_fvs = case varMultMaybe var of
- Just mult -> tyCoFVsOfType mult
+ Just mult -> shallowSelTypeFV mult
Nothing -> mempty
dBndrTypeTyCoVars :: Var -> DTyCoVarSet
@@ -278,7 +279,7 @@ dBndrFreeVars :: Id -> DVarSet
-- Shallow free vars
dBndrFreeVars id = runFVSelective isLocalVar $ bndrFVs id
-bndrFVs :: Id -> SelectiveFVRes
+bndrFVs :: Id -> SelectiveFV
-- Shallow free vars of types, rules, and inlining
bndrFVs id = assert (isId id) $
bndrTypeTyCoFVs id `mappend`
@@ -290,7 +291,7 @@ bndrRuleAndUnfoldingVarsDSet = runFVSelective isLocalVar . bndrRuleAndUnfoldingF
bndrRuleAndUnfoldingVars :: Id -> VarSet
bndrRuleAndUnfoldingVars = dVarSetToVarSet . bndrRuleAndUnfoldingVarsDSet
-bndrRuleAndUnfoldingFVs :: Id -> SelectiveFVRes
+bndrRuleAndUnfoldingFVs :: Id -> SelectiveFV
bndrRuleAndUnfoldingFVs id
| isId id = idRuleFVs id `mappend` idUnfoldingFVs id
| otherwise = mempty
@@ -298,7 +299,7 @@ bndrRuleAndUnfoldingFVs id
idRuleVars :: Id -> VarSet -- Does *not* include CoreUnfolding vars
idRuleVars = dVarSetToVarSet . ruleInfoFreeVars . idSpecialisation
-idRuleFVs :: Id -> SelectiveFVRes
+idRuleFVs :: Id -> SelectiveFV
idRuleFVs id = assert (isId id) $
strictFoldDVarSet (mappend . unitFV) mempty $
ruleInfoFreeVars (idSpecialisation id)
@@ -311,21 +312,21 @@ idUnfoldingVars :: Id -> VarSet
-- we might get out-of-scope variables
idUnfoldingVars = runFVSelectiveSet isLocalVar . idUnfoldingFVs
-idUnfoldingFVs :: Id -> SelectiveFVRes
+idUnfoldingFVs :: Id -> SelectiveFV
idUnfoldingFVs id = stableUnfoldingFVs (realIdUnfolding id) `orElse` mempty
stableUnfoldingVars :: Unfolding -> Maybe VarSet
stableUnfoldingVars unf = fmap (runFVSelectiveSet isLocalVar) $
stableUnfoldingFVs unf
-stableUnfoldingFVs :: Unfolding -> Maybe SelectiveFVRes
+stableUnfoldingFVs :: Unfolding -> Maybe SelectiveFV
stableUnfoldingFVs unf
= case unf of
CoreUnfolding { uf_tmpl = rhs, uf_src = src }
| isStableSource src
-> Just (exprFVs rhs)
DFunUnfolding { df_bndrs = bndrs, df_args = args }
- -> Just (addBndrsFV bndrs (exprsFVs args))
+ -> Just (addCoreBndrsFV bndrs (exprsFVs args))
-- DFuns are top level, so no fvs from types of bndrs
_other -> Nothing
@@ -497,13 +498,13 @@ data RuleFVsFrom
-- | Those locally-defined variables free in the left and/or right hand sides
-- of the rule, depending on the first argument.
-ruleFVs :: RuleFVsFrom -> CoreRule -> SelectiveFVRes
+ruleFVs :: RuleFVsFrom -> CoreRule -> SelectiveFV
ruleFVs !_ (BuiltinRule {}) = mempty
ruleFVs from (Rule { ru_fn = _do_not_include
-- See Note [Rule free var hack]
, ru_bndrs = bndrs
, ru_rhs = rhs, ru_args = args })
- = addBndrsFV bndrs (exprsFVs exprs)
+ = addCoreBndrsFV bndrs (exprsFVs exprs)
where
exprs = case from of
LhsOnly -> args
@@ -512,8 +513,8 @@ ruleFVs from (Rule { ru_fn = _do_not_include
-- | Those locally-defined variables free in the left and/or right hand sides
-- from several rules, depending on the first argument.
-rulesFVs :: RuleFVsFrom -> [CoreRule] -> SelectiveFVRes
-rulesFVs from = mapUnionFVRes (ruleFVs from)
+rulesFVs :: RuleFVsFrom -> [CoreRule] -> SelectiveFV
+rulesFVs from = mapUnionFV (ruleFVs from)
-- | Those variables free in the right hand side of a rule returned as a
-- non-deterministic set
@@ -666,7 +667,7 @@ freeVarsBind (Rec binds) body_fvs
(binders, rhss) = unzip binds
rhss2 = map freeVars rhss
rhs_body_fvs = foldr (unionDVarSet . freeVarsOf) body_fvs rhss2
- binders_fvs = runFVSelective isLocalVar $ mapUnionFVRes bndrRuleAndUnfoldingFVs binders
+ binders_fvs = runFVSelective isLocalVar $ mapUnionFV bndrRuleAndUnfoldingFVs binders
-- See Note [The FVAnn invariant]
all_fvs = rhs_body_fvs `unionDVarSet` binders_fvs
-- The "delBinderFV" happens after adding the idSpecVars,
=====================================
compiler/GHC/Core/Opt/SetLevels.hs
=====================================
@@ -101,6 +101,7 @@ import GHC.Types.Id
import GHC.Types.Id.Info
import GHC.Types.Var
import GHC.Types.Var.Set
+import GHC.Types.Var.FV
import GHC.Types.Unique.Set ( nonDetStrictFoldUniqSet )
import GHC.Types.Unique.DSet ( getUniqDSet )
import GHC.Types.Var.Env
@@ -1380,7 +1381,7 @@ lvlBind env (AnnRec pairs)
bind_fvs = ((unionDVarSets [ freeVarsOf rhs | (_, rhs) <- pairs])
`unionDVarSet`
(runFVSelective isLocalVar $
- mapUnionFVRes (\(bndr,_) -> bndrFVs bndr) pairs))
+ mapUnionFV (\(bndr,_) -> bndrFVs bndr) pairs))
`delDVarSetList`
bndrs
=====================================
compiler/GHC/Core/Opt/Specialise.hs
=====================================
@@ -54,6 +54,7 @@ import GHC.Types.Id.Make ( voidArgId, voidPrimId )
import GHC.Types.Var
import GHC.Types.Var.Set
import GHC.Types.Var.Env
+import GHC.Types.Var.FV
import GHC.Types.Id
import GHC.Types.Id.Info
import GHC.Types.InlinePragma
@@ -2512,10 +2513,10 @@ specArgsFVs :: InterestingVarFun -> [SpecArg] -> VarSet
-- Find the shallow deep free vars of the SpecArgs that are not already in scope
specArgsFVs interesting args
= runFVSelectiveSet interesting $
- mapUnionFVRes get args
+ mapUnionFV get args
where
- get :: SpecArg -> SelectiveFVRes
- get (SpecType ty) = tyCoFVsOfType ty
+ get :: SpecArg -> SelectiveFV
+ get (SpecType ty) = shallowSelTypeFV ty
get (SpecDict dx) = exprFVs dx
get UnspecType = mempty
get UnspecArg = mempty
=====================================
compiler/GHC/Core/Subst.hs
=====================================
@@ -48,6 +48,7 @@ import GHC.Core.Coercion( mkCoVarCo, substCoVarBndr )
import GHC.Core.TyCo.FVs
import GHC.Types.Var.Set
+import GHC.Types.Var.FV
import GHC.Types.Var.Env as InScopeSet
import GHC.Types.Id
import GHC.Types.Name ( Name )
@@ -594,10 +595,10 @@ substDVarSet subst@(Subst _ _ tv_env cv_env) fvs
= runFVSelective isLocalVar $
strictFoldDVarSet (mappend . do_one) mempty fvs
where
- do_one :: Var -> SelectiveFVRes
+ do_one :: Var -> SelectiveFV
do_one fv
- | isTyVar fv = tyCoFVsOfType (lookupVarEnv tv_env fv `orElse` mkTyVarTy fv)
- | isCoVar fv = tyCoFVsOfCo (lookupVarEnv cv_env fv `orElse` mkCoVarCo fv)
+ | isTyVar fv = shallowSelTypeFV (lookupVarEnv tv_env fv `orElse` mkTyVarTy fv)
+ | isCoVar fv = shallowSelCoFV (lookupVarEnv cv_env fv `orElse` mkCoVarCo fv)
| otherwise = exprFVs (lookupIdSubst subst fv)
------------------
=====================================
compiler/GHC/Core/TyCo/FVs.hs
=====================================
@@ -1,17 +1,7 @@
-{-# LANGUAGE MultiWayIf, PatternSynonyms #-}
+{-# LANGUAGE MultiWayIf #-}
module GHC.Core.TyCo.FVs
- ( -- FVRes and friends
- FVRes( runFV, FVRes ),
- addBndrFVRes, addBndrsFVRes, addBndrSelectiveFVRes, addBndrsSelectiveFVRes,
- mapUnionFVRes, shallowUnitFVRes, deepUnitFVRes,
- BoundVars, VarSetFVRes, DVarSetFVRes, SelectiveFVRes,
- TyCoFVRes, DTyCoFVRes,
- runFVTop, runFVAcc, runTyCoVars, runTyCoVarsDSet,
- runFVSelective, runFVSelectiveList, runFVSelectiveSet,
- InterestingVarFun,
-
- -- Shallow
+ ( -- Shallow
shallowTyCoVarsOfType, shallowTyCoVarsOfTypes,
shallowTyCoVarsOfCo, shallowTyCoVarsOfCos,
shallowTyCoVarsOfTyVarEnv, shallowTyCoVarsOfCoVarEnv,
@@ -20,13 +10,13 @@ module GHC.Core.TyCo.FVs
tyCoVarsOfType, tyCoVarsOfTypes, tyCoVarsOfTypesList,
tyCoVarsOfThings,
tyCoVarsOfCo, tyCoVarsOfCos, tyCoVarsOfMCo,
- deepTcvFolder, deepTypeFV, deepCoFV,
+ deepTcvFolder, deepTypeFV, deepTypesFV, deepCoFV,
-- Deep, deterministic
tyCoVarsOfTypeDSet, tyCoVarsOfTypesDSet, tyCoVarsOfTypeList,
tyCoVarsOfCoDSet, tyCoVarsOfCoList,
tyCoVarsOfThingsDSet,
- detTyCoVarsOfType, detTyCoVarsOfTypes, detTyCoVarsOfCo,
+ deepDetTypeFV, deepDetTypesFV, deepDetCoFV,
-- Selective
someTyCoVarsOfType, someTyCoVarsOfTypes,
@@ -37,7 +27,7 @@ module GHC.Core.TyCo.FVs
coVarsOfCoDSet, coVarsOfCosDSet,
-- Shallow, deterministic, composable
- tyCoFVsOfType, tyCoFVsOfCo,
+ shallowSelTypeFV, shallowSelCoFV,
-- Almost devoid
almostDevoidCoVarOfCo,
@@ -76,6 +66,7 @@ import GHC.Core.TyCon
import GHC.Core.Coercion.Axiom( CoAxiomRule(..), BuiltInFamRewrite(..), coAxiomTyCon )
import GHC.Types.Var
+import GHC.Types.Var.FV
import GHC.Types.Unique.FM
import GHC.Types.Unique.Set
@@ -86,7 +77,6 @@ import GHC.Utils.Misc
import GHC.Utils.EndoOS
import GHC.Data.Pair
-import GHC.Exts (oneShot)
import Data.Semigroup
@@ -120,97 +110,42 @@ Examples:
(a : (k:Type)) {a} {a,k}
forall (a:(k:Type)). a {k} {k}
(a:k->Type) (b:k) {a,b} {a,b,k}
--}
-
-
-{- Note [Free variables of types]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The family of functions tyCoVarsOfType, tyCoVarsOfTypes etc, returns
-a VarSet that is closed over the types of its variables. More precisely,
- if S = tyCoVarsOfType( t )
- and (a:k) is in S
- then tyCoVarsOftype( k ) is a subset of S
-
-Example: The tyCoVars of this ((a:* -> k) Int) is {a, k}.
-
-We could /not/ close over the kinds of the variable occurrences, and
-instead do so at call sites, but it seems that we always want to do
-so, so it's easiest to do it here.
-
-It turns out that getting the free variables of types is performance critical,
-so we profiled several versions, exploring different implementation strategies.
-
-1. Baseline version: uses FV naively. Essentially:
-
- tyCoVarsOfType ty = fvVarSet $ tyCoFVsOfType ty
-
- This is not nice, because FV introduces some overhead to implement
- determinism, and through its "interesting var" function, neither of which
- we need here, so they are a complete waste.
-2. UnionVarSet version: instead of reusing the FV-based code, we simply used
- VarSets directly, trying to avoid the overhead of FV. E.g.:
- -- FV version:
- tyCoFVsOfType (AppTy fun arg) a b c = (tyCoFVsOfType fun `unionFV` tyCoFVsOfType arg) a b c
+Note [Computing deep free variables]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+tyCoVarsOfType computes the /deep/ free variables of a type; that is, if
+`a::k` is in the result, then so are the free vars of `k`. We say that the
+resulting set is "closed over kinds".
- -- UnionVarSet version:
- tyCoVarsOfType (AppTy fun arg) = (tyCoVarsOfType fun `unionVarSet` tyCoVarsOfType arg)
+But we must take care (see #14880):
- This looks deceptively similar, but while FV internally builds a list- and
- set-generating function, the VarSet functions manipulate sets directly, and
- the latter performs a lot worse than the naive FV version.
+1. Efficiency. If we have Proxy (a::ki) -> Proxy (a::ki) -> Proxy (a::ki), then
+ we don't want to have to traverse ki more than once.
-3. Accumulator-style VarSet version: this is what we use now. We do use VarSet
- as our data structure, but delegate the actual work to a new
- ty_co_vars_of_... family of functions, which use accumulator style and the
- "in-scope set" filter found in the internals of FV, but without the
- determinism overhead.
-
-See #14880.
-
-Note [Closing over free variable kinds]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-tyCoVarsOfType and tyCoFVsOfType, while traversing a type, will also close over
-free variable kinds. In previous GHC versions, this happened naively: whenever
-we would encounter an occurrence of a free type variable, we would close over
-its kind. This, however is wrong for two reasons (see #14880):
-
-1. Efficiency. If we have Proxy (a::k) -> Proxy (a::k) -> Proxy (a::k), then
- we don't want to have to traverse k more than once.
-
-2. Correctness. Imagine we have forall k. b -> k, where b has
- kind k, for some k bound in an outer scope. If we look at b's kind inside
+2. Correctness. Imagine we have forall k. (b::k) -> k, where b has
+ kind k, for some k bound in an /outer/ scope. If we look at b's kind inside
the forall, we'll collect that k is free and then remove k from the set of
free variables. This is plain wrong. We must instead compute that b is free
and then conclude that b's kind is free.
-An obvious first approach is to move the closing-over-kinds from the
-occurrences of a type variable to after finding the free vars - however, this
-turns out to introduce performance regressions, and isn't even entirely
-correct.
-
-In fact, it isn't even important *when* we close over kinds; what matters is
-that we handle each type var exactly once, and that we do it in the right
-context.
+An obvious first approach is to compute the /shallow/ free variables of the type,
+and /then/ close over kinds. But that turns out not to be very efficient.
+Fortunately, there is a simpler way, which works with the accumulating
+free-var story described in (FV1) of Note [Finding free variables] in
+GHC.Types.Var.FV. At an occurrence of a variable (a::k)
-So the next approach we tried was to use the "in-scope set" part of FV or the
-equivalent argument in the accumulator-style `ty_co_vars_of_type` function, to
-say "don't bother with variables we have already closed over". This should work
-fine in theory, but the code is complicated and doesn't perform well.
+* Check if `a` is a locally-bound var; if so, ignore it.
-But there is a simpler way, which is implemented here. Consider the two points
-above:
+* Check if `a` is already in the accumulator; if so, ignore it because we have
+ deal with its kind already. Also pre-checking set membership before inserting
+ ends up not only being faster,
-1. Efficiency: we now have an accumulator, so the second time we encounter 'a',
- we'll ignore it, certainly not looking at its kind - this is why
- pre-checking set membership before inserting ends up not only being faster,
- but also being correct.
+* Otherwise add `a` to the accumulator,
+ AND add on the free vars of its kind `k`.
+ BUT in this latter step, start with an empty BoundVars set.
-2. Correctness: we have an "in-scope set" (I think we should call it it a
- "bound-var set"), specifying variables that are bound by a forall in the type
- we are traversing; we simply ignore these variables, certainly not looking at
- their kind.
+This twist is implemented in `deepUnitFV`
So now consider:
@@ -222,22 +157,6 @@ this is our first encounter with b; we want the free vars of its kind. But we
want to behave as if we took the free vars of its kind at the end; that is,
with no bound vars in scope.
-So the solution is easy. The old code was this:
-
- ty_co_vars_of_type (TyVarTy v) is acc
- | v `elemVarSet` is = acc
- | v `elemVarSet` acc = acc
- | otherwise = ty_co_vars_of_type (tyVarKind v) is (extendVarSet acc v)
-
-Now all we need to do is take the free vars of tyVarKind v *with an empty
-bound-var set*, thus:
-
-ty_co_vars_of_type (TyVarTy v) is acc
- | v `elemVarSet` is = acc
- | v `elemVarSet` acc = acc
- | otherwise = ty_co_vars_of_type (tyVarKind v) emptyVarSet (extendVarSet acc v)
- ^^^^^^^^^^^
-
And that's it. This works because a variable is either bound or free. If it is bound,
then we won't look at it at all. If it is free, then all the variables free in its
kind are free -- regardless of whether some local variable has the same Unique.
@@ -266,147 +185,6 @@ The sole reason is in Note [Emitting the residual implication in simplifyInfer]
in GHC.Tc.Solver. Yuk. This is not pretty.
-}
-{- *********************************************************************
-* *
- Endo for free variables
-* *
-********************************************************************* -}
-
-{- Note [Accumulating parameter free variables]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We can use foldType to build an accumulating-parameter version of a
-free-var finder, thus:
-
- fvs :: Type -> TyCoVarSet
- fvs ty = appEndo (foldType folder ty) emptyVarSet
-
-Recall that
- foldType :: TyCoFolder env a -> env -> Type -> a
-
- newtype Endo a = Endo (a -> a) -- In Data.Monoid
- instance Monoid a => Monoid (Endo a) where
- (Endo f) `mappend` (Endo g) = Endo (f.g)
-
- appEndo :: Endo a -> a -> a
- appEndo (Endo f) x = f x
-
-So `mappend` for Endos is just function composition.
-
-It's very important that, after optimisation, we end up with
-* an arity-three function
-* that is strict in the accumulator
-
- fvs env (TyVarTy v) acc
- | v `elemVarSet` env = acc
- | v `elemVarSet` acc = acc
- | otherwise = acc `extendVarSet` v
- fvs env (AppTy t1 t2) = fvs env t1 (fvs env t2 acc)
- ...
-
-The "strict in the accumulator" part is to ensure that in the
-AppTy equation we don't build a thunk for (fvs env t2 acc).
-
-The optimiser does do all this, but not very robustly. It depends
-critically on the basic arity-2 function not being exported, so that
-all its calls are visibly to three arguments. This analysis is
-done by the Call Arity pass.
-
-TL;DR: check this regularly!
--}
-
-
-{- *********************************************************************
-* *
- Free-var result type
-* *
-********************************************************************* -}
-
-type InterestingVarFun = Var -> Bool
-
-newtype FVRes env acc = FVRes' { runFV :: env -> acc }
- -- Caries an environment (typically empty, or a set of in-scope variables)
- -- and a composable accumulator
-
-pattern FVRes :: (env -> acc) -> FVRes env acc
-pattern FVRes f <- FVRes' f
- where
- FVRes f = FVRes' (oneShot f)
- -- oneShot: this is the core of the one-shot trick!
- -- Note [The one-shot state monad trick] in GHC.Utils.Monad.
-
-instance Semigroup a => Semigroup (FVRes env a) where
- f1 <> f2 = FVRes (\env -> runFV f1 env <> runFV f2 env)
-
-instance Monoid a => Monoid (FVRes env a) where
- mempty = FVRes (\_ -> mempty)
-
-addBndrFV :: (env -> env) -> FVRes env a -> FVRes env a
-{-# INLINE addBndrFV #-}
-addBndrFV upd f = FVRes (\bvs -> runFV f $! upd bvs)
- -- Strict application to avoid making a thunk
-
-addBndrFVRes :: TyCoVar -> FVRes BoundVars a -> FVRes BoundVars a
-addBndrFVRes tcv = addBndrFV (\bvs -> extendVarSet bvs tcv)
-
-addBndrsFVRes :: [Var] -> FVRes BoundVars a -> FVRes BoundVars a
-addBndrsFVRes tcvs = addBndrFV (\bvs -> extendVarSetList bvs tcvs)
-
-addBndrSelectiveFVRes :: TyCoVar -> FVRes (f, BoundVars) a -> FVRes (f, BoundVars) a
-addBndrSelectiveFVRes tcv
- = addBndrFV (\(f,bvs) -> let !bvs' = extendVarSet bvs tcv
- -- Strict let to avoid thunks
- in (f,bvs'))
-addBndrsSelectiveFVRes :: [Var] -> FVRes (f, BoundVars) a -> FVRes (f, BoundVars) a
-addBndrsSelectiveFVRes bs
- = addBndrFV (\(f,bvs) -> let !bvs' = extendVarSetList bvs bs
- -- Strict let to avoid thunks
- in (f,bvs'))
-
-mapUnionFVRes :: (Foldable t, Monoid acc)
- => (a -> FVRes env acc) -> t a -> FVRes env acc
-{-# INLINE mapUnionFVRes #-}
-mapUnionFVRes f xs = foldr (mappend . f) mempty xs
-
-
-type BoundVars = TyCoVarSet
-
-
-type VarSetFVRes = FVRes BoundVars (EndoOS TyCoVarSet)
-type DVarSetFVRes = FVRes BoundVars (EndoOS DTyCoVarSet)
-type SelectiveFVRes = FVRes (InterestingVarFun, BoundVars) (EndoOS DVarSet)
--- VarSetFVRes: collects a VarSet
--- DVarSetFVRes: collects a DVarSet (deterministic)
--- SelectiveFVRes: selectively collects a DVarSet
-
-type TyCoFVRes = VarSetFVRes
-type DTyCoFVRes = DVarSetFVRes
-
-runFVTop :: FVRes BoundVars a -> a
-{-# INLINE runFVTop #-}
-runFVTop f = runFV f emptyVarSet
-
-runFVAcc :: FVRes BoundVars (EndoOS a) -> a -> a
-{-# INLINE runFVAcc #-}
-runFVAcc f = runEndoOS (runFVTop f)
-
-runTyCoVars :: TyCoFVRes -> TyCoVarSet
-{-# INLINE runTyCoVars #-}
-runTyCoVars f = runFVAcc f emptyVarSet
-
-runTyCoVarsDSet :: DTyCoFVRes -> DTyCoVarSet
-{-# INLINE runTyCoVarsDSet #-}
-runTyCoVarsDSet f = runFVAcc f emptyDVarSet
-
-runFVSelective :: InterestingVarFun -> SelectiveFVRes -> DVarSet
-runFVSelective interesting f
- = runEndoOS (runFV f (interesting, emptyVarSet)) emptyDVarSet
-
-runFVSelectiveList :: InterestingVarFun -> SelectiveFVRes -> [Var]
-runFVSelectiveList interesting f = dVarSetElems (runFVSelective interesting f)
-
-runFVSelectiveSet :: InterestingVarFun -> SelectiveFVRes -> VarSet
-runFVSelectiveSet interesting f = dVarSetToVarSet (runFVSelective interesting f)
-
{- *********************************************************************
* *
@@ -429,7 +207,7 @@ tyCoVarsOfTypes tys = runTyCoVars (deepTypesFV tys)
tyCoVarsOfCo :: Coercion -> TyCoVarSet
-- The "deep" TyCoVars of the the coercion
--- See Note [Free variables of types]
+-- See Note [Computing deep free variables]
tyCoVarsOfCo co = runTyCoVars (deepCoFV co)
tyCoVarsOfMCo :: MCoercion -> TyCoVarSet
@@ -441,17 +219,17 @@ tyCoVarsOfCos cos = runTyCoVars (deepCosFV cos)
tyCoVarsOfThings :: Foldable t => (a -> Type) -> t a -> TyCoVarSet
-- Works over a collection of things from which we can extract a type
--- See Note [Free variables of types]
+-- See Note [Computing deep free variables]
tyCoVarsOfThings get_ty things
- = runTyCoVars $ mapUnionFVRes (deepTypeFV . get_ty) things
+ = runTyCoVars $ mapUnionFV (deepTypeFV . get_ty) things
-deepTypeFV :: Type -> TyCoFVRes
-deepTypesFV :: [Type] -> TyCoFVRes
-deepCoFV :: Coercion -> TyCoFVRes
-deepCosFV :: [Coercion] -> TyCoFVRes
+deepTypeFV :: Type -> TyCoFV
+deepTypesFV :: [Type] -> TyCoFV
+deepCoFV :: Coercion -> TyCoFV
+deepCosFV :: [Coercion] -> TyCoFV
(deepTypeFV, deepTypesFV, deepCoFV, deepCosFV) = foldTyCo deepTcvFolder
-deepTcvFolder :: TyCoFolder TyCoFVRes
+deepTcvFolder :: TyCoFolder TyCoFV
-- It's important that we use a one-shot EndoOS, to ensure that all
-- the free-variable finders are eta-expanded. Lacking the one-shot-ness
-- led to some big slow downs. See Note [The one-shot state monad trick]
@@ -459,22 +237,23 @@ deepTcvFolder :: TyCoFolder TyCoFVRes
deepTcvFolder = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms]
, tcf_tyvar = do_tcv, tcf_covar = do_tcv
, tcf_hole = do_hole
- , tcf_tycobinder = addBndrFVRes }
+ , tcf_tycobinder = addBndrFV }
where
- do_tcv :: TyVar -> TyCoFVRes
- do_tcv = deepUnitFVRes deepTypeFV
+ do_tcv :: TyVar -> TyCoFV
+ do_tcv = deepUnitFV deepTypeFV
- do_hole :: CoercionHole -> TyCoFVRes
+ do_hole :: CoercionHole -> TyCoFV
do_hole hole = deepTypeFV (varType (coHoleCoVar hole))
-- We don't collect the CoercionHole itself, but we /do/
-- need to collect the free variables of its /kind/
-- See Note [CoercionHoles and coercion free variables]
-deepUnitFVRes :: (Type -> TyCoFVRes) -> TyCoVar -> TyCoFVRes
+deepUnitFV :: (Type -> TyCoFV) -> TyCoVar -> TyCoFV
-- Deal with a single TyCoVar
-- Takes a function to find free vars of the kind
-deepUnitFVRes fvs_of_kind v
- = FVRes (\bvs -> EndoOS (do_it bvs))
+-- See Note [Computing deep free variables]
+deepUnitFV fvs_of_kind v
+ = MkFV (\bvs -> EndoOS (do_it bvs))
where
do_it :: BoundVars -> TyCoVarSet -> TyCoVarSet
do_it bvs acc | v `elemVarSet` bvs = acc
@@ -490,23 +269,23 @@ deepUnitFVRes fvs_of_kind v
********************************************************************* -}
shallowTyCoVarsOfType :: Type -> TyCoVarSet
--- See Note [Free variables of types]
-shallowTyCoVarsOfType ty = runTyCoVars (shallow_ty ty)
+-- See Note [Shallow and deep free variables]
+shallowTyCoVarsOfType ty = runTyCoVars (shallowTypeFV ty)
shallowTyCoVarsOfTypes :: [Type] -> TyCoVarSet
-shallowTyCoVarsOfTypes tys = runTyCoVars (shallow_tys tys)
+shallowTyCoVarsOfTypes tys = runTyCoVars (shallowTypesFV tys)
shallowTyCoVarsOfCo :: Coercion -> TyCoVarSet
-shallowTyCoVarsOfCo co = runTyCoVars (shallow_co co)
+shallowTyCoVarsOfCo co = runTyCoVars (shallowCoFV co)
shallowTyCoVarsOfCos :: [Coercion] -> TyCoVarSet
-shallowTyCoVarsOfCos cos = runTyCoVars (shallow_cos cos)
+shallowTyCoVarsOfCos cos = runTyCoVars (shallowCosFV cos)
-- | Returns free variables of types, including kind variables as
-- a non-deterministic set. For type synonyms it does /not/ expand the
-- synonym.
shallowTyCoVarsOfTyVarEnv :: TyVarEnv Type -> TyCoVarSet
--- See Note [Free variables of types]
+-- See Note [Shallow and deep free variables]of types]
shallowTyCoVarsOfTyVarEnv tys = shallowTyCoVarsOfTypes (nonDetEltsUFM tys)
-- It's OK to use nonDetEltsUFM here because we immediately
-- forget the ordering by returning a set
@@ -516,25 +295,25 @@ shallowTyCoVarsOfCoVarEnv cos = shallowTyCoVarsOfCos (nonDetEltsUFM cos)
-- It's OK to use nonDetEltsUFM here because we immediately
-- forget the ordering by returning a set
-shallow_ty :: Type -> TyCoFVRes
-shallow_tys :: [Type] -> TyCoFVRes
-shallow_co :: Coercion -> TyCoFVRes
-shallow_cos :: [Coercion] -> TyCoFVRes
-(shallow_ty, shallow_tys, shallow_co, shallow_cos)
+shallowTypeFV :: Type -> TyCoFV
+shallowTypesFV :: [Type] -> TyCoFV
+shallowCoFV :: Coercion -> TyCoFV
+shallowCosFV :: [Coercion] -> TyCoFV
+(shallowTypeFV, shallowTypesFV, shallowCoFV, shallowCosFV)
= foldTyCo shallowTcvFolder
-shallowTcvFolder :: TyCoFolder TyCoFVRes
+shallowTcvFolder :: TyCoFolder TyCoFV
shallowTcvFolder = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms]
, tcf_tyvar = do_tcv, tcf_covar = do_tcv
, tcf_hole = do_hole
- , tcf_tycobinder = addBndrFVRes }
+ , tcf_tycobinder = addBndrFV }
where
- do_tcv = shallowUnitFVRes
+ do_tcv = shallowUnitFV
do_hole _ = mempty -- Ignore coercion holes
-shallowUnitFVRes :: TyCoVar -> TyCoFVRes
-shallowUnitFVRes v
- = FVRes (\bvs -> EndoOS (do_it bvs))
+shallowUnitFV :: TyCoVar -> TyCoFV
+shallowUnitFV v
+ = MkFV (\bvs -> EndoOS (do_it bvs))
where
do_it bvs acc | v `elemVarSet` bvs = acc
| v `elemVarSet` acc = acc
@@ -547,71 +326,71 @@ shallowUnitFVRes v
* *
********************************************************************* -}
--- | `tyCoVarsOfTypeDSet` that returns free variables of a type in a deterministic
--- set. For explanation of why using `VarSet` is not deterministic see
--- Note [Deterministic FV] in "GHC.Utils.FV".
+-- | `tyCoVarsOfTypeDSet` that returns deep free variables of a type in a
+-- deterministic-- set. For explanation of why using `VarSet` is not deterministic
+-- see Note [Deterministic FV] in "GHC.TYpes.Var.FV".
tyCoVarsOfTypeDSet :: Type -> DTyCoVarSet
--- See Note [Free variables of types]
-tyCoVarsOfTypeDSet ty = runTyCoVarsDSet (detTyCoVarsOfType ty)
+-- See Note [Computing deep free variables]
+tyCoVarsOfTypeDSet ty = runTyCoVarsDSet (deepDetTypeFV ty)
-- | Returns free variables of types, including kind variables as
-- a deterministic set. For type synonyms it does /not/ expand the
-- synonym.
tyCoVarsOfTypesDSet :: [Type] -> DTyCoVarSet
--- See Note [Free variables of types]
-tyCoVarsOfTypesDSet tys = runTyCoVarsDSet (detTyCoVarsOfTypes tys)
+-- See Note [Computing deep free variables]
+tyCoVarsOfTypesDSet tys = runTyCoVarsDSet (deepDetTypesFV tys)
tyCoVarsOfThingsDSet :: Foldable t => (a -> Type) -> t a -> DTyCoVarSet
-- Works over a collection of things from which we can extract a type
--- See Note [Free variables of types]
+-- See Note [Computing deep free variables]
tyCoVarsOfThingsDSet get_ty things
- = runTyCoVarsDSet (mapUnionFVRes (detTyCoVarsOfType . get_ty) things)
+ = runTyCoVarsDSet (mapUnionFV (deepDetTypeFV . get_ty) things)
-- | `tyCoVarsOfTypeList` returns free variables of a type in deterministic
-- order. For explanation of why using `VarSet` is not deterministic see
--- Note [Deterministic FV] in "GHC.Utils.FV".
+-- Note [Deterministic FV] in "GHC.Types.Var.FV".
tyCoVarsOfTypeList :: Type -> [TyCoVar]
--- See Note [Free variables of types]
+-- See Note [Computing deep free variables]
tyCoVarsOfTypeList ty = dVarSetElems $ tyCoVarsOfTypeDSet ty
tyCoVarsOfCoDSet :: Coercion -> DTyCoVarSet
--- See Note [Free variables of types]
-tyCoVarsOfCoDSet ty = runTyCoVarsDSet (detTyCoVarsOfCo ty)
+-- See Note [Computing deep free variables]
+tyCoVarsOfCoDSet ty = runTyCoVarsDSet (deepDetCoFV ty)
tyCoVarsOfCoList :: Coercion -> [TyCoVar]
--- See Note [Free variables of types]
+-- See Note [Computing deep free variables]
tyCoVarsOfCoList ty = dVarSetElems $ tyCoVarsOfCoDSet ty
-- | Returns free variables of types, including kind variables as
-- a deterministically ordered list. For type synonyms it does /not/ expand the
-- synonym.
tyCoVarsOfTypesList :: [Type] -> [TyCoVar]
--- See Note [Free variables of types]
+-- See Note [Computing deep free variables]
tyCoVarsOfTypesList tys = dVarSetElems $ tyCoVarsOfTypesDSet tys
-detTyCoVarsOfType :: Type -> DTyCoFVRes
-detTyCoVarsOfTypes :: [Type] -> DTyCoFVRes
-detTyCoVarsOfCo :: Coercion -> DTyCoFVRes
-(detTyCoVarsOfType, detTyCoVarsOfTypes, detTyCoVarsOfCo, _)
- = foldTyCo deepDetTcvFolder
+deepDetTypeFV :: Type -> DTyCoFV
+deepDetTypesFV :: [Type] -> DTyCoFV
+deepDetCoFV :: Coercion -> DTyCoFV
+(deepDetTypeFV, deepDetTypesFV, deepDetCoFV, _) = foldTyCo deepDetTcvFolder
-deepDetTcvFolder :: TyCoFolder DTyCoFVRes
+deepDetTcvFolder :: TyCoFolder DTyCoFV
-- This one returns a /deterministic/ list
-- See `deepTcvFolder` for the general pattern
deepDetTcvFolder
= TyCoFolder { tcf_view = noView
, tcf_tyvar = do_tcv, tcf_covar = do_tcv
, tcf_hole = do_hole
- , tcf_tycobinder = addBndrFVRes }
+ , tcf_tycobinder = addBndrFV }
where
- do_tcv = deepDetUnitFVRes detTyCoVarsOfType
- do_hole hole = detTyCoVarsOfType (varType (coHoleCoVar hole))
+ do_tcv = deepDetUnitFV deepDetTypeFV
+ do_hole hole = deepDetTypeFV (varType (coHoleCoVar hole))
-deepDetUnitFVRes :: (Type -> DTyCoFVRes) -> TyCoVar -> DTyCoFVRes
+deepDetUnitFV :: (Type -> DTyCoFV) -> TyCoVar -> DTyCoFV
-- Deal with a single TyCoVar
-- Takes a function to find free vars of the kind
-deepDetUnitFVRes fvs_of_kind v
- = FVRes (\bvs -> EndoOS (do_it bvs))
+-- See Note [Computing deep free variables]
+deepDetUnitFV fvs_of_kind v
+ = MkFV (\bvs -> EndoOS (do_it bvs))
where
do_it :: BoundVars -> DTyCoVarSet -> DTyCoVarSet
do_it bvs acc | v `elemVarSet` bvs = acc
@@ -627,28 +406,28 @@ deepDetUnitFVRes fvs_of_kind v
someTyCoVarsOfType :: (TyCoVar -> Bool) -> Type -> [TyCoVar]
someTyCoVarsOfType interesting
- = runFVSelectiveList interesting . tyCoFVsOfType
+ = runFVSelectiveList interesting . shallowSelTypeFV
someTyCoVarsOfTypes :: (TyCoVar -> Bool) -> [Type] -> [TyCoVar]
someTyCoVarsOfTypes interesting
- = runFVSelectiveList interesting . mapUnionFVRes tyCoFVsOfType
+ = runFVSelectiveList interesting . mapUnionFV shallowSelTypeFV
-tyCoFVsOfType :: Type -> SelectiveFVRes
-tyCoFVsOfCo :: Coercion -> SelectiveFVRes
+shallowSelTypeFV :: Type -> SelectiveFV
+shallowSelCoFV :: Coercion -> SelectiveFV
-- Returns shallow free vars
--- See Note [Free variables of types]
-(tyCoFVsOfType, _, tyCoFVsOfCo, _) = foldTyCo selectiveTcvFolder
+-- See Note [Shallow and deep free variables]
+(shallowSelTypeFV, _, shallowSelCoFV, _) = foldTyCo selectiveTcvFolder
-selectiveTcvFolder :: TyCoFolder SelectiveFVRes
+selectiveTcvFolder :: TyCoFolder SelectiveFV
-- This one takes an `InterestingVarFun`, and returns shallow free vars
-- See `shallowTcvFolder` for the general pattern
selectiveTcvFolder
= TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms]
, tcf_tyvar = do_tcv, tcf_covar = do_tcv
, tcf_hole = do_hole
- , tcf_tycobinder = addBndrSelectiveFVRes }
+ , tcf_tycobinder = addBndrSelectiveFV }
where
- do_tcv v = FVRes (\bvs -> EndoOS (do_it bvs))
+ do_tcv v = MkFV (\bvs -> EndoOS (do_it bvs))
where
do_it (is_interesting,bvs) acc
| not (is_interesting v) = acc -- The "selective" bit
@@ -656,7 +435,7 @@ selectiveTcvFolder
| v `elemDVarSet` acc = acc
| otherwise = acc `extendDVarSet` v
- do_hole hole = tyCoFVsOfType (varType (coHoleCoVar hole))
+ do_hole hole = shallowSelTypeFV (varType (coHoleCoVar hole))
{- *********************************************************************
@@ -686,24 +465,24 @@ coVarsOfTypes :: [Type] -> CoVarSet
coVarsOfCo :: Coercion -> CoVarSet
coVarsOfCos :: [Coercion] -> CoVarSet
-coVarsOfType ty = runTyCoVars (deep_cv_ty ty)
-coVarsOfTypes tys = runTyCoVars (deep_cv_tys tys)
-coVarsOfCo co = runTyCoVars (deep_cv_co co)
-coVarsOfCos cos = runTyCoVars (deep_cv_cos cos)
+coVarsOfType ty = runTyCoVars (deepCoVarTypeFV ty)
+coVarsOfTypes tys = runTyCoVars (deepCoVarTypesFV tys)
+coVarsOfCo co = runTyCoVars (deepCoVarCoFV co)
+coVarsOfCos cos = runTyCoVars (deepCoVarCosFV cos)
-type CoVarFVRes = FVRes BoundVars (EndoOS CoVarSet)
+type CoVarFV = FV BoundVars (EndoOS CoVarSet)
-deep_cv_ty :: Type -> CoVarFVRes
-deep_cv_tys :: [Type] -> CoVarFVRes
-deep_cv_co :: Coercion -> CoVarFVRes
-deep_cv_cos :: [Coercion] -> CoVarFVRes
-(deep_cv_ty, deep_cv_tys, deep_cv_co, deep_cv_cos) = foldTyCo deepCoVarFolder
+deepCoVarTypeFV :: Type -> CoVarFV
+deepCoVarTypesFV :: [Type] -> CoVarFV
+deepCoVarCoFV :: Coercion -> CoVarFV
+deepCoVarCosFV :: [Coercion] -> CoVarFV
+(deepCoVarTypeFV, deepCoVarTypesFV, deepCoVarCoFV, deepCoVarCosFV) = foldTyCo deepCoVarFolder
-deepCoVarFolder :: TyCoFolder CoVarFVRes
+deepCoVarFolder :: TyCoFolder CoVarFV
deepCoVarFolder = TyCoFolder { tcf_view = noView
, tcf_tyvar = do_tyvar, tcf_covar = do_covar
, tcf_hole = do_hole
- , tcf_tycobinder = addBndrFVRes }
+ , tcf_tycobinder = addBndrFV }
where
do_tyvar _ = mempty
-- This do_tyvar means we won't see any CoVars in this
@@ -712,14 +491,14 @@ deepCoVarFolder = TyCoFolder { tcf_view = noView
-- the tyvar won't end up in the accumulator, so
-- we'd look repeatedly. Blargh.
- do_covar = deepUnitFVRes deep_cv_ty
+ do_covar = deepUnitFV deepCoVarTypeFV
do_hole hole = do_covar (coHoleCoVar hole)
-- We /do/ treat a CoercionHole as a free variable
-- See Note [CoercionHoles and coercion free variables]
-------------- Deterministic versions ------------------
-type DCoVarFVRes = FVRes BoundVars (EndoOS DCoVarSet)
+type DCoVarFV = FV BoundVars (EndoOS DCoVarSet)
coVarsOfCoDSet :: Coercion -> DCoVarSet
coVarsOfCoDSet co = runTyCoVarsDSet (det_co co)
@@ -727,23 +506,23 @@ coVarsOfCoDSet co = runTyCoVarsDSet (det_co co)
coVarsOfCosDSet :: [Coercion] -> DCoVarSet
coVarsOfCosDSet cos = runTyCoVarsDSet (det_cos cos)
-det_ty :: Type -> DCoVarFVRes
-det_co :: Coercion -> DCoVarFVRes
-det_cos :: [Coercion] -> DCoVarFVRes
+det_ty :: Type -> DCoVarFV
+det_co :: Coercion -> DCoVarFV
+det_cos :: [Coercion] -> DCoVarFV
(det_ty, _, det_co, det_cos) = foldTyCo deepDetCoVarFolder
-deepDetCoVarFolder :: TyCoFolder DCoVarFVRes
+deepDetCoVarFolder :: TyCoFolder DCoVarFV
-- Follows deepCoVarFolders, but returns a /deterministic/ set
deepDetCoVarFolder = TyCoFolder { tcf_view = noView
, tcf_tyvar = do_tyvar
, tcf_covar = do_covar
, tcf_hole = do_hole
- , tcf_tycobinder = addBndrFVRes }
+ , tcf_tycobinder = addBndrFV }
where
do_tyvar _ = mempty
- do_covar :: CoVar -> DCoVarFVRes
- do_covar = deepDetUnitFVRes det_ty
+ do_covar :: CoVar -> DCoVarFV
+ do_covar = deepDetUnitFV det_ty
do_hole hole = do_covar (coHoleCoVar hole)
@@ -768,7 +547,7 @@ closeOverKinds vs = nonDetStrictFoldVarSet do_one vs vs
closeOverKindsDSet :: DTyVarSet -> DTyVarSet
closeOverKindsDSet vs = nonDetStrictFoldDVarSet do_one vs vs
where
- do_one v = runFVAcc (detTyCoVarsOfType (varType v))
+ do_one v = runFVAcc (deepDetTypeFV (varType v))
{- --------------- Alternative version 1 (using FV) ------------
closeOverKinds = fvVarSet . closeOverKindsFV . nonDetEltsUniqSet
@@ -1033,18 +812,18 @@ injectiveVarsOfTypes :: Bool -- ^ look under injective type families?
-- in "GHC.Tc.Instance.Family".
-> [Type] -> VarSet
injectiveVarsOfTypes look_under_tfs tys
- = runTyCoVars $ mapUnionFVRes (inj_vars_of_type look_under_tfs) tys
+ = runTyCoVars $ mapUnionFV (inj_vars_of_type look_under_tfs) tys
-inj_vars_of_type :: Bool -> Type -> TyCoFVRes
+inj_vars_of_type :: Bool -> Type -> TyCoFV
inj_vars_of_type look_under_tfs = go
where
go ty | Just ty' <- rewriterView ty = go ty'
- go (TyVarTy v) = deepUnitFVRes go v
+ go (TyVarTy v) = deepUnitFV go v
go (AppTy f a) = go f `mappend` go a
go (FunTy _ w ty1 ty2) = go w `mappend` go ty1 `mappend` go ty2
go (TyConApp tc tys) = go_tc tc tys
go (ForAllTy (Bndr tv _) ty) = go (tyVarKind tv) `mappend`
- addBndrFVRes tv (go ty)
+ addBndrFV tv (go ty)
go LitTy{} = mempty
go (CastTy ty _) = go ty
go CoercionTy{} = mempty
@@ -1053,7 +832,7 @@ inj_vars_of_type look_under_tfs = go
| isTypeFamilyTyCon tc
= if | look_under_tfs
, Injective flags <- tyConInjectivityInfo tc
- -> mapUnionFVRes go $
+ -> mapUnionFV go $
filterByList (flags ++ repeat True) tys
-- Oversaturated arguments to a tycon are
-- always injective, hence the repeat True
@@ -1061,7 +840,7 @@ inj_vars_of_type look_under_tfs = go
-> mempty
| otherwise -- Data type, injective in all positions
- = mapUnionFVRes go tys
+ = mapUnionFV go tys
@@ -1110,15 +889,15 @@ invisibleVarsOfTypes = foldr (unionVarSet . invisibleVarsOfType) emptyVarSet
********************************************************************* -}
{-# INLINE afvFolder #-} -- so that specialization to (const True) works
-afvFolder :: (TyCoVar -> Bool) -> TyCoFolder (FVRes TyCoVarSet DM.Any)
+afvFolder :: (TyCoVar -> Bool) -> TyCoFolder (FV TyCoVarSet DM.Any)
-- 'afvFolder' is short for "any-free-var folder", good for checking
-- if any free var of a type satisfies a predicate `check_fv`
afvFolder check_fv = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms]
, tcf_tyvar = do_tcv, tcf_covar = do_tcv
, tcf_hole = do_hole
- , tcf_tycobinder = addBndrFVRes }
+ , tcf_tycobinder = addBndrFV }
where
- do_tcv tv = FVRes $ \ bvs ->
+ do_tcv tv = MkFV $ \ bvs ->
Any (not (tv `elemVarSet` bvs) && check_fv tv)
do_hole _ = mempty -- I'm unsure; probably never happens
=====================================
compiler/GHC/Core/Type.hs
=====================================
@@ -159,11 +159,8 @@ module GHC.Core.Type (
liftedTypeKind, unliftedTypeKind,
-- * Type free variables
- tyCoFVsOfType,
- tyCoVarsOfType, tyCoVarsOfTypes,
- tyCoVarsOfTypeDSet,
- coVarsOfType,
- coVarsOfTypes,
+ tyCoVarsOfType, tyCoVarsOfTypes, tyCoVarsOfTypeDSet,
+ coVarsOfType, coVarsOfTypes,
anyFreeVarsOfType, anyFreeVarsOfTypes,
noFreeVarsOfType,
=====================================
compiler/GHC/Iface/Ext/Ast.hs
=====================================
@@ -23,7 +23,6 @@ import GHC.Core.DataCon ( dataConWrapperType )
import GHC.Core.Type ( Type, ForAllTyFlag(..) )
import GHC.Core.TyCon ( TyCon, tyConClass_maybe )
import GHC.Core.InstEnv
-import GHC.Core.TyCo.FVs
import GHC.Core.Predicate ( isEvId )
import GHC.Hs
@@ -40,6 +39,7 @@ import GHC.Types.Name.Reader ( RecFieldInfo(..), WithUserRdr(..) )
import GHC.Types.SrcLoc
import GHC.Types.Var ( Id, Var, EvId, varName, varType, varUnique )
import GHC.Types.Var.Env
+import GHC.Types.Var.FV
import GHC.Tc.Types
import GHC.Tc.Types.Evidence
=====================================
compiler/GHC/Tc/Gen/App.hs
=====================================
@@ -37,7 +37,6 @@ import GHC.Core.DataCon ( dataConConcreteTyVars, isNewDataCon, dataConOrigArgTys
import GHC.Core.TyCon
import GHC.Core.TyCo.Rep
import GHC.Core.TyCo.Ppr
-import GHC.Core.TyCo.FVs
import GHC.Core.TyCo.Subst ( substTyWithInScope )
import GHC.Core.Type
import GHC.Core.Coercion
@@ -47,6 +46,7 @@ import GHC.Builtin.PrimOps( tagToEnumKey )
import GHC.Builtin.Names
import GHC.Types.Var
+import GHC.Types.Var.FV
import GHC.Types.Name
import GHC.Types.Name.Env
import GHC.Types.Name.Reader
@@ -2082,7 +2082,7 @@ foldQLInstVars check_tv ty
where
(do_ty, _, _, _) = foldTyCo folder
- folder :: TyCoFolder (FVRes () a)
+ folder :: TyCoFolder (FV () a)
folder = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms]
-- in GHC.Core.TyCo.FVs
, tcf_tyvar = do_tv, tcf_covar = mempty
@@ -2093,8 +2093,8 @@ foldQLInstVars check_tv ty
do_hole hole = do_ty (coVarKind (coHoleCoVar hole))
-- See (MIV2) in Note [Monomorphise instantiation variables]
- do_tv :: TcTyVar -> FVRes () a
- do_tv tv | isQLInstTyVar tv = FVRes $ \_ -> check_tv tv
+ do_tv :: TcTyVar -> FV () a
+ do_tv tv | isQLInstTyVar tv = MkFV $ \_ -> check_tv tv
| otherwise = mempty
{- *********************************************************************
=====================================
compiler/GHC/Tc/Types/Constraint.hs
=====================================
@@ -117,6 +117,7 @@ import GHC.Core.TyCo.FVs
import GHC.Types.Name
import GHC.Types.Var
+import GHC.Types.Var.FV
import GHC.Tc.Utils.TcType
import GHC.Tc.Types.Evidence
@@ -809,7 +810,7 @@ tyCoVarsOfCtList :: Ct -> [TcTyCoVar]
tyCoVarsOfCtList = tyCoVarsOfTypeList . ctPred
-- | Returns free variables of constraints as a deterministically ordered
--- list. See Note [Deterministic FV] in GHC.Utils.FV.
+-- list. See Note [Deterministic FV] in GHC.Types.Var.FV.
tyCoVarsOfCtEvList :: CtEvidence -> [TcTyCoVar]
tyCoVarsOfCtEvList = tyCoVarsOfTypeList . ctEvPred
@@ -819,49 +820,49 @@ tyCoVarsOfCts :: Cts -> TcTyCoVarSet
tyCoVarsOfCts = dVarSetToVarSet . runTyCoVarsDSet . tcvs_of_cts
-- | Returns free variables of a bag of constraints as a deterministically
--- ordered list. See Note [Deterministic FV] in "GHC.Utils.FV".
+-- ordered list. See Note [Deterministic FV] in "GHC.Types.Var.FV".
tyCoVarsOfCtsList :: Cts -> [TcTyCoVar]
tyCoVarsOfCtsList = dVarSetElems . tyCoVarsOfThingsDSet ctPred
-- | Returns free variables of a bag of constraints as a deterministically
--- ordered list. See Note [Deterministic FV] in GHC.Utils.FV.
+-- ordered list. See Note [Deterministic FV] in GHC.Types.Var.FV.
tyCoVarsOfCtEvsList :: [CtEvidence] -> [TcTyCoVar]
tyCoVarsOfCtEvsList = dVarSetElems . runTyCoVarsDSet
- . mapUnionFVRes (detTyCoVarsOfType . ctEvPred)
+ . mapUnionFV (deepDetTypeFV . ctEvPred)
-- | Returns free variables of WantedConstraints as a non-deterministic
--- set. See Note [Deterministic FV] in "GHC.Utils.FV".
+-- set. See Note [Deterministic FV] in "GHC.Types.Var.FV".
tyCoVarsOfWC :: WantedConstraints -> TyCoVarSet
-- Only called on *zonked* things
tyCoVarsOfWC = dVarSetToVarSet . tyCoVarsOfWcDSet
-- | Returns free variables of WantedConstraints as a deterministically
--- ordered list. See Note [Deterministic FV] in "GHC.Utils.FV".
+-- ordered list. See Note [Deterministic FV] in "GHC.Types.Var.FV".
tyCoVarsOfWCList :: WantedConstraints -> [TyCoVar]
-- Only called on *zonked* things
tyCoVarsOfWCList = dVarSetElems . tyCoVarsOfWcDSet
-- | Returns free variables of WantedConstraints as a composable FV
--- computation. See Note [Deterministic FV] in "GHC.Utils.FV".
+-- computation. See Note [Deterministic FV] in "GHC.Types.Var.FV".
tyCoVarsOfWcDSet :: WantedConstraints -> DTyCoVarSet
-- Only called on *zonked* things
tyCoVarsOfWcDSet = runTyCoVarsDSet . tcvs_of_wc
-tcvs_of_wc :: WantedConstraints -> DTyCoFVRes
+tcvs_of_wc :: WantedConstraints -> DTyCoFV
tcvs_of_wc (WC { wc_simple = simple, wc_impl = implics, wc_errors = errors })
= tcvs_of_cts simple `mappend`
- mapUnionFVRes tcvs_of_implic implics `mappend`
- mapUnionFVRes tcvs_of_errs errors
+ mapUnionFV tcvs_of_implic implics `mappend`
+ mapUnionFV tcvs_of_errs errors
-tcvs_of_cts :: Cts -> DTyCoFVRes
-tcvs_of_cts = mapUnionFVRes tcvs_of_ct
+tcvs_of_cts :: Cts -> DTyCoFV
+tcvs_of_cts = mapUnionFV tcvs_of_ct
-tcvs_of_ct :: Ct -> DTyCoFVRes
-tcvs_of_ct ct = detTyCoVarsOfType (ctPred ct)
+tcvs_of_ct :: Ct -> DTyCoFV
+tcvs_of_ct ct = deepDetTypeFV (ctPred ct)
-- | Returns free variables of Implication as a composable FV computation.
--- See Note [Deterministic FV] in "GHC.Utils.FV".
-tcvs_of_implic :: Implication -> DTyCoFVRes
+-- See Note [Deterministic FV] in "GHC.Types.Var.FV".
+tcvs_of_implic :: Implication -> DTyCoFV
-- Only called on *zonked* things
tcvs_of_implic (Implic { ic_skols = skols
, ic_given = givens
@@ -869,17 +870,17 @@ tcvs_of_implic (Implic { ic_skols = skols
| isEmptyWC wanted
= mempty
| otherwise
- = addBndrsFVRes skols $
- addBndrsFVRes givens $
+ = addBndrsFV skols $
+ addBndrsFV givens $
tcvs_of_wc wanted
-tcvs_of_errs :: DelayedError -> DTyCoFVRes
+tcvs_of_errs :: DelayedError -> DTyCoFV
tcvs_of_errs (DE_Hole hole) = tcvs_of_hole hole
tcvs_of_errs (DE_NotConcrete {}) = mempty
-tcvs_of_errs (DE_Multiplicity co _) = detTyCoVarsOfCo co
+tcvs_of_errs (DE_Multiplicity co _) = deepDetCoFV co
-tcvs_of_hole :: Hole -> DTyCoFVRes
-tcvs_of_hole (Hole { hole_ty = ty }) = detTyCoVarsOfType ty
+tcvs_of_hole :: Hole -> DTyCoFV
+tcvs_of_hole (Hole { hole_ty = ty }) = deepDetTypeFV ty
{-
************************************************************************
=====================================
compiler/GHC/Tc/Types/Evidence.hs
=====================================
@@ -64,7 +64,6 @@ import GHC.Core.Ppr () -- Instance OutputableBndr TyVar
import GHC.Core.Predicate
import GHC.Core.Type
import GHC.Core.TyCo.Rep (UnivCoProvenance(..))
-import GHC.Core.TyCo.FVs
import GHC.Core.TyCon
import GHC.Core.Make ( mkWildCase, mkRuntimeErrorApp, tYPE_ERROR_ID )
import GHC.Core.Class ( classTyCon )
@@ -80,6 +79,7 @@ import GHC.Types.Var
import GHC.Types.Id( idType )
import GHC.Types.Var.Env
import GHC.Types.Var.Set
+import GHC.Types.Var.FV
import GHC.Types.Basic
import GHC.Builtin.Names
@@ -1318,25 +1318,25 @@ nestedEvIdsOfTerm :: EvTerm -> VarSet
-- Returns only EvIds satisfying relevantEvId
nestedEvIdsOfTerm = runFVSelectiveSet isNestedEvId . evTermFVs
-evTermFVs :: EvTerm -> SelectiveFVRes
+evTermFVs :: EvTerm -> SelectiveFV
evTermFVs (EvExpr e) = exprFVs e
evTermFVs (EvTypeable _ ev) = evFVsOfTypeable ev
evTermFVs (EvFun { et_tvs = tvs, et_given = given
, et_binds = tc_ev_binds, et_body = v })
= case tc_ev_binds of
TcEvBinds {} -> mempty -- See Note [Free vars of EvFun]
- EvBinds binds -> addBndrsFV bndrs fvs
+ EvBinds binds -> addBndrsSelectiveFV bndrs fvs
where
fvs = foldr (mappend . evTermFVs . eb_rhs) (unitFV v) binds
bndrs = foldr ((:) . eb_lhs) (tvs ++ given) binds
-evTermFVss :: [EvTerm] -> SelectiveFVRes
-evTermFVss = mapUnionFVRes evTermFVs
+evTermFVss :: [EvTerm] -> SelectiveFV
+evTermFVss = mapUnionFV evTermFVs
-evFVsOfTypeable :: EvTypeable -> SelectiveFVRes
+evFVsOfTypeable :: EvTypeable -> SelectiveFV
evFVsOfTypeable ev =
case ev of
- EvTypeableTyCon _ e -> mapUnionFVRes evTermFVs e
+ EvTypeableTyCon _ e -> mapUnionFV evTermFVs e
EvTypeableTyApp e1 e2 -> evTermFVss [e1,e2]
EvTypeableTrFun em e1 e2 -> evTermFVss [em,e1,e2]
EvTypeableTyLit e -> evTermFVs e
=====================================
compiler/GHC/Tc/Utils/TcMType.hs
=====================================
@@ -1565,7 +1565,7 @@ against any specification -- just suboptimal and confounding to users.
Note [Recurring into kinds for candidateQTyVars]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-First, read Note [Closing over free variable kinds] in GHC.Core.TyCo.FVs, paying
+First, read Note [Computing deep free variables] in GHC.Core.TyCo.FVs, paying
attention to the end of the Note about using an empty bound set when
traversing a variable's kind.
@@ -1582,7 +1582,7 @@ type inference, which is seeded by the renamer and its insistence to
use different Uniques for different variables. (In contrast, the Core
functions work on the output of optimizations, which may introduce
shadowing.) Without shadowing, the problem studied by
-Note [Closing over free variable kinds] in GHC.Core.TyCo.FVs cannot happen.
+Note [Computing deep free variables] in GHC.Core.TyCo.FVs cannot happen.
Why it is necessary:
Wiping the bound set would be just plain wrong here. Consider
@@ -1593,7 +1593,7 @@ We really don't want to think k1 and k2 are free here. (It's true that we'll
never be able to fill in `hole`, but we don't want to go off the rails just
because we have an insoluble coercion hole.) So: why is it wrong to wipe
the bound variables here but right in Core? Because the final statement
-in Note [Closing over free variable kinds] in GHC.Core.TyCo.FVs is wrong: not
+in Note [Computing deep free variables] in GHC.Core.TyCo.FVs is wrong: not
every variable is either free or bound. A variable can be a hole, too!
The reasoning in that Note then breaks down.
=====================================
compiler/GHC/Tc/Utils/TcType.hs
=====================================
@@ -219,16 +219,17 @@ import {-# SOURCE #-} GHC.Tc.Types.Origin
( SkolemInfo, unkSkol
, FixedRuntimeRepOrigin, FixedRuntimeRepContext )
--- others:
+import GHC.Types.Var.FV
import GHC.Types.Name as Name
-- We use this to make dictionaries for type literals.
-- Perhaps there's a better way to do this?
import GHC.Types.Name.Env
import GHC.Types.Name.Set
+import GHC.Types.Basic
+
import GHC.Builtin.Names
import GHC.Builtin.Types ( coercibleClass, eqClass, heqClass, unitTyConKey
, listTyCon, constraintKind )
-import GHC.Types.Basic
import GHC.Data.Maybe
import GHC.Data.List.SetOps ( getNth, findDupsEq )
@@ -1178,11 +1179,11 @@ exactTyCoVarsOfTypes :: [Type] -> TyCoVarSet
exactTyCoVarsOfType ty = runTyCoVars (exact_ty ty)
exactTyCoVarsOfTypes tys = runTyCoVars (exact_tys tys)
-exact_ty :: Type -> TyCoFVRes
-exact_tys :: [Type] -> TyCoFVRes
+exact_ty :: Type -> TyCoFV
+exact_tys :: [Type] -> TyCoFV
(exact_ty, exact_tys, _, _) = foldTyCo exactTcvFolder
-exactTcvFolder :: TyCoFolder TyCoFVRes
+exactTcvFolder :: TyCoFolder TyCoFV
exactTcvFolder = deepTcvFolder { tcf_view = coreView }
-- This is the key line
=====================================
compiler/GHC/Tc/Utils/Unify.hs
=====================================
@@ -101,6 +101,7 @@ import GHC.Types.Id( idType )
import GHC.Types.Var as Var
import GHC.Types.Var.Set
import GHC.Types.Var.Env
+import GHC.Types.Var.FV
import GHC.Types.Basic
import GHC.Types.Unique.Set (nonDetEltsUniqSet)
@@ -3572,20 +3573,20 @@ mkOccFolders :: Name -> (TcType -> Bool, TcCoercion -> Bool)
mkOccFolders lhs_tv = ( getAny . runFVTop . check_ty
, getAny . runFVTop . check_co)
where
- check_ty :: Type -> FVRes BoundVars Any
+ check_ty :: Type -> FV BoundVars Any
!(check_ty, _, check_co, _) = foldTyCo occ_folder
- occ_folder :: TyCoFolder (FVRes BoundVars Any)
+ occ_folder :: TyCoFolder (FV BoundVars Any)
occ_folder = TyCoFolder { tcf_view = noView -- Don't expand synonyms
, tcf_tyvar = do_tcv, tcf_covar = do_tcv
, tcf_hole = do_hole
- , tcf_tycobinder = addBndrFVRes }
+ , tcf_tycobinder = addBndrFV }
- do_tcv v = (FVRes $ \ bvs ->
+ do_tcv v = (MkFV $ \ bvs ->
Any (not (v `elemVarSet` bvs) && tyVarName v == lhs_tv))
`mappend` check_ty (varType v)
- do_hole _hole = FVRes $ \ _bvs -> DM.Any True -- Reject coercion holes
+ do_hole _hole = MkFV $ \ _bvs -> DM.Any True -- Reject coercion holes
{- *********************************************************************
* *
=====================================
compiler/GHC/Utils/EndoOS.hs
=====================================
@@ -1,12 +1,13 @@
{-# LANGUAGE PatternSynonyms #-}
-- | One-shot endomorphisms
--- Mostly for backwards compatibility.
-- One-shot endomorphisms
-- Like GHC.Internal.Data.Semigroup.Internal.Endo, but using
-- the one-shot trick from
-- Note [The one-shot state monad trick] in GHC.Utils.Monad.
+--
+-- It is also strict: see the (<>) method in he Semigroup instance
module GHC.Utils.EndoOS( EndoOS(EndoOS, runEndoOS ), foldEndoOS ) where
@@ -19,13 +20,21 @@ newtype EndoOS a = EndoOS' { runEndoOS :: a -> a }
instance Semigroup (EndoOS a) where
- f <> g = EndoOS (\x -> runEndoOS f $! (runEndoOS g x))
- -- Strict application, to avoid thunk creation
+ EndoOS' f <> EndoOS' g = EndoOS (\x -> g $! f x)
+ -- NB1: Strict application, to avoid thunk creation
+ -- See (FV3) in Note [Finding free variables]
+ -- in GHC.Types.Var.FV
+ -- NB2: We apply `f` to the acccumulator first, then `g`
+ -- So if we traverse a type left-to-right, the insertion
+ -- order for (say) free type variables is left-to-right
+ -- See (FV4) in Note [Finding free variables]
+ -- in GHC.Types.Var.FV
instance Monoid (EndoOS a) where
mempty = EndoOS id
pattern EndoOS :: (a->a) -> EndoOS a
+{-# COMPLETE EndoOS #-}
pattern EndoOS f <- EndoOS' f
where
EndoOS f = EndoOS' (oneShot f)
=====================================
compiler/GHC/Utils/FV.hs deleted
=====================================
@@ -1,202 +0,0 @@
-{-
-(c) Bartosz Nitka, Facebook 2015
-
--}
-
--- | Utilities for efficiently and deterministically computing free variables.
-module GHC.Utils.FV (
- -- * Deterministic free vars computations
- FV, InterestingVarFun,
-
- -- * Running the computations
- fvVarList, fvVarSet, fvDVarSet,
-
- -- ** Manipulating those computations
- unitFV,
- emptyFV,
- mkFVs,
- unionFV,
- unionsFV,
- delFV,
- delFVs,
- filterFV,
- mapUnionFV,
- fvDVarSetSome,
- ) where
-
-import GHC.Prelude
-
-import GHC.Types.Var
-import GHC.Types.Var.Set
-
--- | Predicate on possible free variables: returns @True@ iff the variable is
--- interesting
-type InterestingVarFun = Var -> Bool
-
--- Note [Deterministic FV]
--- ~~~~~~~~~~~~~~~~~~~~~~~
--- When computing free variables, the order in which you get them affects
--- the results of floating and specialization. If you use UniqFM to collect
--- them and then turn that into a list, you get them in nondeterministic
--- order as described in Note [Deterministic UniqFM] in GHC.Types.Unique.DFM.
-
--- A naive algorithm for free variables relies on merging sets of variables.
--- Merging costs O(n+m) for UniqFM and for UniqDFM there's an additional log
--- factor. It's cheaper to incrementally add to a list and use a set to check
--- for duplicates.
-type FV = InterestingVarFun -- Used for filtering sets as we build them
- -> VarSet -- Locally bound variables
- -> VarAcc -- Accumulator
- -> VarAcc
-
-type VarAcc = ([Var], VarSet) -- List to preserve ordering and set to check for membership,
- -- so that the list doesn't have duplicates
- -- For explanation of why using `VarSet` is not deterministic see
- -- Note [Deterministic UniqFM] in GHC.Types.Unique.DFM.
-
--- Note [FV naming conventions]
--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- To get the performance and determinism that FV provides, FV computations
--- need to built up from smaller FV computations and then evaluated with
--- one of `fvVarList`, `fvDVarSet` That means the functions
--- returning FV need to be exported.
---
--- The conventions are:
---
--- a) non-deterministic functions:
--- * a function that returns VarSet
--- e.g. `tyVarsOfType`
--- b) deterministic functions:
--- * a worker that returns FV
--- e.g. `tyFVsOfType`
--- * a function that returns [Var]
--- e.g. `tyVarsOfTypeList`
--- * a function that returns DVarSet
--- e.g. `tyVarsOfTypeDSet`
---
--- Where tyVarsOfType, tyVarsOfTypeList, tyVarsOfTypeDSet are implemented
--- in terms of the worker evaluated with fvVarSet, fvVarList, fvDVarSet
--- respectively.
-
--- | Run a free variable computation, returning a list of distinct free
--- variables in deterministic order and a non-deterministic set containing
--- those variables.
-fvVarAcc :: FV -> ([Var], VarSet)
-fvVarAcc fv = fv (const True) emptyVarSet ([], emptyVarSet)
-
--- | Run a free variable computation, returning a list of distinct free
--- variables in deterministic order.
-fvVarList :: FV -> [Var]
-fvVarList = fst . fvVarAcc
-
--- | Run a free variable computation, returning a deterministic set of free
--- variables. Note that this is just a wrapper around the version that
--- returns a deterministic list. If you need a list you should use
--- `fvVarList`.
-fvDVarSet :: FV -> DVarSet
-fvDVarSet = mkDVarSet . fvVarList
-
--- | Run a free variable computation, returning a non-deterministic set of
--- free variables. Don't use if the set will be later converted to a list
--- and the order of that list will impact the generated code.
-fvVarSet :: FV -> VarSet
-fvVarSet = snd . fvVarAcc
-
--- Note [FV eta expansion]
--- ~~~~~~~~~~~~~~~~~~~~~~~
--- Let's consider an eta-reduced implementation of freeVarsOf using FV:
---
--- freeVarsOf (App a b) = freeVarsOf a `unionFV` freeVarsOf b
---
--- If GHC doesn't eta-expand it, after inlining unionFV we end up with
---
--- freeVarsOf = \x ->
--- case x of
--- App a b -> \fv_cand in_scope acc ->
--- freeVarsOf a fv_cand in_scope $! freeVarsOf b fv_cand in_scope $! acc
---
--- which has to create a thunk, resulting in more allocations.
---
--- On the other hand if it is eta-expanded:
---
--- freeVarsOf (App a b) fv_cand in_scope acc =
--- (freeVarsOf a `unionFV` freeVarsOf b) fv_cand in_scope acc
---
--- after inlining unionFV we have:
---
--- freeVarsOf = \x fv_cand in_scope acc ->
--- case x of
--- App a b ->
--- freeVarsOf a fv_cand in_scope $! freeVarsOf b fv_cand in_scope $! acc
---
--- which saves allocations.
---
--- GHC when presented with knowledge about all the call sites, correctly
--- eta-expands in this case. Unfortunately due to the fact that freeVarsOf gets
--- exported to be composed with other functions, GHC doesn't have that
--- information and has to be more conservative here.
---
--- Hence functions that get exported and return FV need to be manually
--- eta-expanded. See also #11146.
-
--- | Add a variable - when free, to the returned free variables.
--- Ignores duplicates and respects the filtering function.
-unitFV :: Id -> FV
-unitFV var fv_cand in_scope acc@(have, haveSet)
- | var `elemVarSet` in_scope = acc
- | var `elemVarSet` haveSet = acc
- | fv_cand var = (var:have, extendVarSet haveSet var)
- | otherwise = acc
-{-# INLINE unitFV #-}
-
--- | Return no free variables.
-emptyFV :: FV
-emptyFV _ _ acc = acc
-{-# INLINE emptyFV #-}
-
--- | Union two free variable computations.
-unionFV :: FV -> FV -> FV
-unionFV fv1 fv2 fv_cand in_scope acc =
- fv1 fv_cand in_scope $! fv2 fv_cand in_scope $! acc
-{-# INLINE unionFV #-}
-
--- | Mark the variable as not free by putting it in scope.
-delFV :: Var -> FV -> FV
-delFV var fv fv_cand !in_scope acc =
- fv fv_cand (extendVarSet in_scope var) acc
-{-# INLINE delFV #-}
-
--- | Mark many free variables as not free.
-delFVs :: VarSet -> FV -> FV
-delFVs vars fv fv_cand !in_scope acc =
- fv fv_cand (in_scope `unionVarSet` vars) acc
-{-# INLINE delFVs #-}
-
--- | Filter a free variable computation.
-filterFV :: InterestingVarFun -> FV -> FV
-filterFV fv_cand2 fv fv_cand1 in_scope acc =
- fv (\v -> fv_cand1 v && fv_cand2 v) in_scope acc
-{-# INLINE filterFV #-}
-
--- | Map a free variable computation over a list and union the results.
-mapUnionFV :: (a -> FV) -> [a] -> FV
-mapUnionFV _f [] _fv_cand _in_scope acc = acc
-mapUnionFV f (a:as) fv_cand in_scope acc =
- mapUnionFV f as fv_cand in_scope $! f a fv_cand in_scope $! acc
-{-# INLINABLE mapUnionFV #-}
-
--- | Union many free variable computations.
-unionsFV :: [FV] -> FV
-unionsFV fvs fv_cand in_scope acc = mapUnionFV id fvs fv_cand in_scope acc
-{-# INLINE unionsFV #-}
-
--- | Add multiple variables - when free, to the returned free variables.
--- Ignores duplicates and respects the filtering function.
-mkFVs :: [Var] -> FV
-mkFVs vars fv_cand in_scope acc =
- mapUnionFV unitFV vars fv_cand in_scope acc
-{-# INLINE mkFVs #-}
-
-fvDVarSetSome :: InterestingVarFun -> FV -> DVarSet
-fvDVarSetSome interesting_var fv =
- mkDVarSet $ fst $ fv interesting_var emptyVarSet ([], emptyVarSet)
=====================================
compiler/ghc.cabal.in
=====================================
@@ -951,6 +951,7 @@ Library
GHC.Types.Var
GHC.Types.Var.Env
GHC.Types.Var.Set
+ GHC.Types.Var.FV
GHC.Unit
GHC.Unit.Env
GHC.Unit.External
@@ -992,7 +993,6 @@ Library
GHC.Utils.EndoOS
GHC.Utils.Exception
GHC.Utils.Fingerprint
- GHC.Utils.FV
GHC.Utils.GlobalVars
GHC.Utils.IO.Unsafe
GHC.Utils.Json
=====================================
utils/haddock/haddock-api/src/Haddock/GhcUtils.hs
=====================================
@@ -43,7 +43,8 @@ import qualified Data.Set as Set
import GHC hiding (HsTypeGhcPsExt (..))
import GHC.Builtin.Types (liftedRepTy)
import GHC.Core.TyCo.Rep (Type (..))
-import GHC.Core.Type (binderVar, isRuntimeRepVar)
+import GHC.Core.TyCo.FVs ( deepDetTypesFV )
+import GHC.Core.Type (isRuntimeRepVar)
import GHC.Data.StringBuffer (StringBuffer)
import qualified GHC.Data.StringBuffer as S
import GHC.Driver.Session
@@ -52,17 +53,11 @@ import GHC.Types.Name
import GHC.Types.SrcLoc (advanceSrcLoc)
import GHC.Types.SourceText (SourceText(..))
import GHC.Types.Var
- ( Specificity
- , TyVarBinder
- , VarBndr (..)
- , isInvisibleForAllTyFlag
- , tyVarKind
- , updateTyVarKind
- )
-import GHC.Types.Var.Env (TyVarEnv, elemVarEnv, emptyVarEnv, extendVarEnv)
-import GHC.Types.Var.Set (VarSet, emptyVarSet)
-import GHC.Utils.FV as FV
+import GHC.Types.Var.Env
+import GHC.Types.Var.Set
+import GHC.Types.Var.FV
import GHC.Utils.Outputable (Outputable, SDocContext, ppr)
+import GHC.Utils.EndoOS
import qualified GHC.Utils.Outputable as Outputable
import GHC.Utils.Panic (panic)
@@ -86,6 +81,7 @@ filterSigNames p orig@(SpecSig _ n _ _) = ifTrueJust (p $ unLoc n) orig
filterSigNames p orig@(InlineSig _ n _) = ifTrueJust (p $ unLoc n) orig
filterSigNames p (FixSig _ (FixitySig ns_spec ns ty)) =
case filter (p . unLoc) ns of
+
[] -> Nothing
filtered -> Just (FixSig noAnn (FixitySig ns_spec filtered ty))
filterSigNames _ orig@(MinimalSig _ _) = Just orig
@@ -817,66 +813,14 @@ isTypeHidden expInfo = typeHidden
-- | Get free type variables in a 'Type' in their order of appearance.
-- See [Ordering of implicit variables].
orderedFVs
- :: VarSet
- -- ^ free variables to ignore
- -> [Type]
- -- ^ types to traverse (in order) looking for free variables
- -> [TyVar]
- -- ^ free type variables, in the order they appear in
-orderedFVs vs tys =
- reverse . fst $ tyCoFVsOfTypes' tys (const True) vs ([], emptyVarSet)
-
--- See the "Free variables of types and coercions" section in 'TyCoRep', or
--- check out Note [Free variables of types]. The functions in this section
--- don't output type variables in the order they first appear in in the 'Type'.
---
--- For example, 'tyCoVarsOfTypeList' reports an incorrect order for the type
--- of 'const :: a -> b -> a':
---
--- >>> import GHC.Types.Name
--- >>> import TyCoRep
--- >>> import GHC.Builtin.Types.Prim
--- >>> import GHC.Types.Var
--- >>> a = TyVarTy alphaTyVar
--- >>> b = TyVarTy betaTyVar
--- >>> constTy = mkFunTys [a, b] a
--- >>> map (getOccString . tyVarName) (tyCoVarsOfTypeList constTy)
--- ["b","a"]
---
--- However, we want to reuse the very optimized traversal machinery there, so
--- so we make our own `tyCoFVsOfType'`, `tyCoFVsBndr'`, and `tyCoVarsOfTypes'`.
--- All these do differently is traverse in a different order and ignore
--- coercion variables.
-
--- | Just like 'tyCoFVsOfType', but traverses type variables in reverse order
--- of appearance.
-tyCoFVsOfType' :: Type -> FV
-tyCoFVsOfType' (TyVarTy v) a b c = (FV.unitFV v `unionFV` tyCoFVsOfType' (tyVarKind v)) a b c
-tyCoFVsOfType' (TyConApp _ tys) a b c = tyCoFVsOfTypes' tys a b c
-tyCoFVsOfType' (LitTy{}) a b c = emptyFV a b c
-tyCoFVsOfType' (AppTy fun arg) a b c = (tyCoFVsOfType' arg `unionFV` tyCoFVsOfType' fun) a b c
-tyCoFVsOfType' (FunTy _ w arg res) a b c =
- ( tyCoFVsOfType' res
- `unionFV` tyCoFVsOfType' w
- `unionFV` tyCoFVsOfType' arg
- )
- a
- b
- c
-tyCoFVsOfType' (ForAllTy bndr ty) a b c = tyCoFVsBndr' bndr (tyCoFVsOfType' ty) a b c
-tyCoFVsOfType' (CastTy ty _) a b c = (tyCoFVsOfType' ty) a b c
-tyCoFVsOfType' (CoercionTy _) a b c = emptyFV a b c
-
--- | Just like 'tyCoFVsOfTypes', but traverses type variables in reverse order
--- of appearance.
-tyCoFVsOfTypes' :: [Type] -> FV
-tyCoFVsOfTypes' (ty : tys) fv_cand in_scope acc = (tyCoFVsOfTypes' tys `unionFV` tyCoFVsOfType' ty) fv_cand in_scope acc
-tyCoFVsOfTypes' [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc
-
--- | Just like 'tyCoFVsBndr', but traverses type variables in reverse order of
--- appearance.
-tyCoFVsBndr' :: TyVarBinder -> FV -> FV
-tyCoFVsBndr' (Bndr tv _) fvs = FV.delFV tv fvs `unionFV` tyCoFVsOfType' (tyVarKind tv)
+ :: VarSet -- ^ Free variables to ignore
+ -> [Type] -- ^ Types to traverse (in order) looking for free variables
+ -> [TyVar] -- ^ Free type variables, /in the order in which they appear/
+orderedFVs ignore_tvs tys
+ = dVarSetElems (runEndoOS (runFV get_fvs ignore_tvs) emptyDVarSet)
+ where
+ get_fvs :: DVarSetFV
+ get_fvs = deepDetTypesFV tys
-------------------------------------------------------------------------------
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3f56f61a8433319d611f292ddae0c1…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3f56f61a8433319d611f292ddae0c1…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc] Pushed new branch wip/jeltsch/system-io-uncovering
by Wolfgang Jeltsch (@jeltsch) 21 Feb '26
by Wolfgang Jeltsch (@jeltsch) 21 Feb '26
21 Feb '26
Wolfgang Jeltsch pushed new branch wip/jeltsch/system-io-uncovering at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/jeltsch/system-io-uncovering
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/supersven/hadrian-cross-stage3] 45 commits: Support more x86 extensions: AVX-512 {BW,DQ,VL} and GFNI
by Sven Tennie (@supersven) 21 Feb '26
by Sven Tennie (@supersven) 21 Feb '26
21 Feb '26
Sven Tennie pushed to branch wip/supersven/hadrian-cross-stage3 at Glasgow Haskell Compiler / GHC
Commits:
14f485ee by ARATA Mizuki at 2026-02-17T09:09:24+09:00
Support more x86 extensions: AVX-512 {BW,DQ,VL} and GFNI
Also, mark AVX-512 ER and PF as deprecated.
AVX-512 instructions can be used for certain 64-bit integer vector operations.
GFNI can be used to implement bitReverse (currently not used by NCG, but LLVM may use it).
Closes #26406
Addresses #26509
- - - - -
016f79d5 by fendor at 2026-02-17T09:16:16-05:00
Hide implementation details from base exception stack traces
Ensure we hide the implementation details of the exception throwing mechanisms:
* `undefined`
* `throwSTM`
* `throw`
* `throwIO`
* `error`
The `HasCallStackBacktrace` should always have a length of exactly 1,
not showing internal implementation details in the stack trace, as these
are vastly distracting to end users.
CLC proposal [#387](https://github.com/haskell/core-libraries-committee/issues/387)
- - - - -
4f2840f2 by Brian J. Cardiff at 2026-02-17T17:04:08-05:00
configure: Accept happy-2.2
In Jan 2026 happy-2.2 was released. The most sensible change is https://github.com/haskell/happy/issues/335 which didn't trigger in a fresh build
- - - - -
10b4d364 by Duncan Coutts at 2026-02-17T17:04:52-05:00
Fix errors in the documentation of the eventlog STOP_THREAD status codes
Fix the code for BlockedOnMsgThrowTo.
Document all the known historical warts.
Fixes issue #26867
- - - - -
c5e15b8b by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: use snippets for all list examples
- generate snippet output for docs
- reduce font size to better fit snippets
- Use only directive to guard html snippets
- Add latex snippets for lists
- - - - -
d388bac1 by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: Place the snippet input and output together
- Put the output seemingly inside the example box
- - - - -
016fa306 by Samuel Thibault at 2026-02-18T05:08:35-05:00
Fix linking against libm by moving the -lm option
For those systems that need -lm for getting math functions, this is
currently added on the link line very early, before the object files being
linked together. Newer toolchains enable --as-needed by default, which means
-lm is ignored at that point because no object requires a math function
yet. With such toolchains, we thus have to add -lm after the objects, so the
linker actually includes libm in the link.
- - - - -
68bd0805 by Teo Camarasu at 2026-02-18T05:09:19-05:00
ghc-internal: Move GHC.Internal.Data.Bool to base
This is a tiny module that only defines bool :: Bool -> a -> a -> a. We can just move this to base and delete it from ghc-internal. If we want this functionality there we can just use a case statement or if-then expression.
Resolves 26865
- - - - -
4be6eff8 by Matthew Pickering at 2026-02-19T19:32:30+01:00
Add missing req_interp modifier to T18441fail3 and T18441fail19
These tests require the interpreter but they were failing in a different
way with the javascript backend because the interpreter was disabled and
stderr is ignored by the test.
- - - - -
a1cc6956 by Matthew Pickering at 2026-02-19T19:32:30+01:00
Use explicit syntax rather than pure
- - - - -
9ceeae6c by Matthew Pickering at 2026-02-19T19:32:30+01:00
packaging: correctly propagate build/host/target to bindist configure script
At the moment the host and target which we will produce a compiler for
is fixed at the initial configure time. Therefore we need to persist
the choice made at this time into the installation bindist as well so we
look for the right tools, with the right prefixes at install time.
In the future, we want to provide a bit more control about what kind of
bindist we produce so the logic about what the host/target will have to
be written by hadrian rather than persisted by the configure script. In
particular with cross compilers we want to either build a normal stage 2
cross bindist or a stage 3 bindist, which creates a bindist which has a
native compiler for the target platform.
Fixes #21970
- - - - -
8843ce11 by Matthew Pickering at 2026-02-19T19:32:30+01:00
hadrian: Fill in more of the default.host toolchain file
When you are building a cross compiler this file will be used to build
stage1 and it's libraries, so we need enough information here to work
accurately. There is still more work to be done (see for example, word
size is still fixed).
- - - - -
eaa41a41 by Matthew Pickering at 2026-02-19T19:32:30+01:00
hadrian: Disable docs when cross compiling
Before there were a variety of ad-hoc places where doc building was
disabled when cross compiling.
* Some CI jobs sets --docs=none in gen_ci.hs
* Some CI jobs set --docs=none in .gitlab/ci.sh
* There was some logic in hadrian to not need the ["docs"] target when
making a bindist.
Now the situation is simple:
* If you are cross compiling then defaultDocsTargets is empty by
default.
In theory, there is no reason why we can't build documentation for cross
compiler bindists, but this is left to future work to generalise the
documentation building rules to allow this (#24289)
- - - - -
b057e7b1 by Matthew Pickering at 2026-02-19T19:32:30+01:00
hadrian: Build stage 2 cross compilers
* Most of hadrian is abstracted over the stage in order to remove the
assumption that the target of all stages is the same platform. This
allows the RTS to be built for two different targets for example.
* Abstracts the bindist creation logic to allow building either normal
or cross bindists. Normal bindists use stage 1 libraries and a stage 2
compiler. Cross bindists use stage 2 libararies and a stage 2
compiler.
* hadrian: Make binary-dist-dir the default build target. This allows us
to have the logic in one place about which libraries/stages to build
with cross compilers. Fixes #24192
New hadrian target:
* `binary-dist-dir-cross`: Build a cross compiler bindist (compiler =
stage 1, libraries = stage 2)
This commit also contains various changes to make stage2 compilers
feasible.
-------------------------
Metric Decrease:
ManyAlternatives
MultiComponentModulesRecomp
MultiLayerModulesRecomp
T10421
T12425
T12707
T13035
T13379
T15703
T16577
T18698a
T18698b
T18923
T1969
T21839c
T3294
T4801
T5030
T5321Fun
T5642
T783
T9198
T9872d
T9961
parsing001
T5321FD
T6048
T12227
T18140
T18282
T9233
T5631
T9630
-------------------------
Co-authored-by: Sven Tennie <sven.tennie(a)gmail.com>
Fix rebase: settings-use-distro-mingw is now staged
- - - - -
be8af267 by Matthew Pickering at 2026-02-19T19:32:30+01:00
ci: Test cross bindists
We remove the special logic for testing in-tree cross
compilers and instead test cross compiler bindists, like we do for all
other platforms.
- - - - -
5088ca0b by Matthew Pickering at 2026-02-19T19:32:30+01:00
ci: Introduce CROSS_STAGE variable
In preparation for building and testing stage3 bindists we introduce the
CROSS_STAGE variable which is used by a CI job to determine what kind of
bindist the CI job should produce.
At the moment we are only using CROSS_STAGE=2 but in the future we will
have some jobs which set CROSS_STAGE=3 to produce native bindists for a
target, but produced by a cross compiler, which can be tested on by
another CI job on the native platform.
CROSS_STAGE=2: Build a normal cross compiler bindist
CROSS_STAGE=3: Build a stage 3 bindist, one which is a native compiler and library for the target
- - - - -
a790621a by Matthew Pickering at 2026-02-19T19:32:30+01:00
hadrian: Refactor system-cxx-std-lib rules0
I noticed a few things wrong with the hadrian rules for `system-cxx-std-lib` rules.
* For `text` there is an ad-hoc check to depend on `system-cxx-std-lib` outside of `configurePackage`.
* The `system-cxx-std-lib` dependency is not read from cabal files.
* Recache is not called on the packge database after the `.conf` file is generated, a more natural place for this rule is `registerRules`.
Treating this uniformly like other packages is complicated by it not having any source code or a cabal file. However we can do a bit better by reporting the dependency firstly in `PackageData` and then needing the `.conf` file in the same place as every other package in `configurePackage`.
Fixes #25303
- - - - -
ab28e95d by Sven Tennie at 2026-02-19T19:32:30+01:00
ci: Increase timeout for emulators
Test runs with emulators naturally take longer than on native machines.
Generate jobs.yml
- - - - -
0d0560d1 by Sven Tennie at 2026-02-19T19:32:30+01:00
ghc: Distinguish between having an interpreter and having an internal one
Otherwise, we fail with warnings when compiling tools. Actually, these
are related but different things:
- ghc can run an interpreter (either internal or external)
- ghc is compiled with an internal interpreter
- - - - -
f19f6046 by Matthew Pickering at 2026-02-19T19:32:30+01:00
ci: Javascript don't set CROSS_EMULATOR
There is no CROSS_EMULATOR needed to run javascript binaries, so we
don't set the CROSS_EMULATOR to some dummy value.
- - - - -
7ed62118 by Sven Tennie at 2026-02-19T19:32:30+01:00
Javascript skip T23697
See #22355 about how HSC2HS and the Javascript target don't play well
together.
- - - - -
f737508e by Sven Tennie at 2026-02-19T19:32:30+01:00
Mark T24602 as fragile
It was skipped before (due to CROSS_EMULATOR being set, which changed
for JS), so we don't make things worse by marking it as fragile.
- - - - -
adf2a1cf by Sven Tennie at 2026-02-19T19:32:30+01:00
Windows needs NM_STAGE0 as well
The stage0 always needs nm.
- - - - -
ce84d7ad by Sven Tennie at 2026-02-19T19:32:30+01:00
T17912 sometimes works for windows-validate
This seems to be timing related. However, just simply increasing the
timeout (sleep) statement of this test didn't help. Maybe, it has been
flaky on CI before.
- - - - -
2595998a by Sven Tennie at 2026-02-19T19:32:30+01:00
Add haddock to `NoEmulatorNeeded TimeoutIncrease`
- - - - -
68d3462f by Sven Tennie at 2026-02-19T19:32:30+01:00
Delete done TODO
- - - - -
0ad7d3c1 by Sven Tennie at 2026-02-19T19:32:30+01:00
Delete done TODO
- - - - -
4b5dfb69 by Sven Tennie at 2026-02-19T19:32:30+01:00
Remove cross special case of performance flavour
- - - - -
9ddc73f9 by Sven Tennie at 2026-02-19T19:32:30+01:00
Delete obsolete iserv comment
- - - - -
ff18fd86 by Sven Tennie at 2026-02-19T19:32:30+01:00
No more cross stage special cases
- - - - -
537146ee by Sven Tennie at 2026-02-19T19:32:30+01:00
Delete libffi-tarballs
Must have been an accidential commit...
- - - - -
08d0f95a by Sven Tennie at 2026-02-19T19:32:30+01:00
Fix commented out code
- - - - -
3c41ceea by Sven Tennie at 2026-02-19T19:32:30+01:00
Remove trace log
- - - - -
9179f498 by Sven Tennie at 2026-02-19T19:32:30+01:00
configure.ac: Remove unnecessay blank
- - - - -
a291b7ab by Sven Tennie at 2026-02-19T19:32:30+01:00
Drop Rules.Libffi
- - - - -
234aa8ca by Sven Tennie at 2026-02-21T15:23:08+01:00
Delete targetSupportsGhciObjects
- - - - -
88af975d by Sven Tennie at 2026-02-21T16:33:44+01:00
Enable stage3 bin-dists
- - - - -
47a7b892 by Sven Tennie at 2026-02-21T16:33:45+01:00
Generated cross stage 3 CI jobs
- - - - -
ba6a9339 by Sven Tennie at 2026-02-21T16:33:45+01:00
Hack
- - - - -
c24ef23a by Sven Tennie at 2026-02-21T16:33:45+01:00
WIP: Validate script
- - - - -
c76a9106 by Sven Tennie at 2026-02-21T16:33:45+01:00
Fix stage3 bindist creation
- - - - -
393050c9 by Sven Tennie at 2026-02-21T16:33:45+01:00
Adjust jobs.yaml
- - - - -
79793b48 by Sven Tennie at 2026-02-21T16:33:45+01:00
Fix final ghc-pkg recache run
Sage3 cross-compiler's ghc-pkg cannot run on the build host. Resort to a
prior stage's ghc-pkg.
- - - - -
c0e14c84 by Sven Tennie at 2026-02-21T16:33:45+01:00
Bindist name must start with ghc*
- - - - -
c52a9b51 by Sven Tennie at 2026-02-21T16:33:45+01:00
Increase generate-ci happyness
Pass its checks by adding some metadata.
- - - - -
180 changed files:
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/GHC/CmmToAsm/Config.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/Driver/Config/CmmToAsm.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Linker/Dynamic.hs
- compiler/GHC/SysTools/Cpp.hs
- configure.ac
- distrib/configure.ac.in
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/eventlog-formats.rst
- docs/users_guide/phases.rst
- docs/users_guide/using.rst
- ghc/GHC/Driver/Session/Mode.hs
- ghc/GHCi/UI.hs
- ghc/Main.hs
- ghc/ghc-bin.cabal.in
- hadrian/README.md
- hadrian/bindist/config.mk.in
- hadrian/cfg/default.host.target.in
- + hadrian/cfg/system.config.host.in
- hadrian/cfg/system.config.in
- + hadrian/cfg/system.config.target.in
- hadrian/hadrian.cabal
- hadrian/src/Base.hs
- + hadrian/src/BindistConfig.hs
- hadrian/src/Builder.hs
- hadrian/src/Context.hs
- hadrian/src/Expression.hs
- hadrian/src/Flavour.hs
- hadrian/src/Flavour/Type.hs
- hadrian/src/Hadrian/Builder.hs
- hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
- hadrian/src/Hadrian/Haskell/Cabal/Type.hs
- hadrian/src/Hadrian/Haskell/Hash.hs
- hadrian/src/Hadrian/Oracles/TextFile.hs
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Oracles/Flavour.hs
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Oracles/TestSettings.hs
- hadrian/src/Packages.hs
- hadrian/src/Rules.hs
- hadrian/src/Rules/BinaryDist.hs
- hadrian/src/Rules/CabalReinstall.hs
- hadrian/src/Rules/Compile.hs
- hadrian/src/Rules/Documentation.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Rules/Library.hs
- hadrian/src/Rules/Program.hs
- hadrian/src/Rules/Register.hs
- hadrian/src/Rules/Test.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/Cabal.hs
- hadrian/src/Settings/Builders/Common.hs
- hadrian/src/Settings/Builders/Configure.hs
- hadrian/src/Settings/Builders/DeriveConstants.hs
- hadrian/src/Settings/Builders/Ghc.hs
- hadrian/src/Settings/Builders/Hsc2Hs.hs
- hadrian/src/Settings/Builders/RunTest.hs
- hadrian/src/Settings/Builders/SplitSections.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Flavours/Benchmark.hs
- hadrian/src/Settings/Flavours/Development.hs
- hadrian/src/Settings/Flavours/GhcInGhci.hs
- hadrian/src/Settings/Flavours/Performance.hs
- hadrian/src/Settings/Flavours/Quick.hs
- hadrian/src/Settings/Flavours/QuickCross.hs
- hadrian/src/Settings/Flavours/Quickest.hs
- hadrian/src/Settings/Flavours/Validate.hs
- hadrian/src/Settings/Packages.hs
- hadrian/src/Settings/Program.hs
- hadrian/src/Settings/Warnings.hs
- libraries/base/changelog.md
- libraries/base/src/Data/Bool.hs
- libraries/base/src/Data/List.hs
- libraries/base/src/Data/List/NubOrdSet.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/tests/IO/all.T
- libraries/base/tests/all.T
- libraries/ghc-internal/ghc-internal.cabal.in
- − libraries/ghc-internal/src/GHC/Internal/Data/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Function.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Ord.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/IO/FD.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/TypeError.hs
- + libraries/ghc-internal/tests/backtraces/T15395.hs
- + libraries/ghc-internal/tests/backtraces/T15395.stdout
- libraries/ghc-internal/tests/backtraces/all.T
- libraries/ghc-internal/tests/stack-annotation/ann_frame005.stdout
- m4/fp_find_nm.m4
- m4/fptools_happy.m4
- m4/fptools_set_platform_vars.m4
- m4/prep_target_file.m4
- testsuite/driver/cpu_features.py
- testsuite/ghc-config/ghc-config.hs
- testsuite/tests/arrows/should_compile/T21301.stderr
- testsuite/tests/codeGen/should_gen_asm/all.T
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.hs
- 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_run/T9576.stderr
- testsuite/tests/ghc-e/should_fail/all.T
- testsuite/tests/ghci/scripts/Defer02.stderr
- testsuite/tests/ghci/scripts/T15325.stderr
- testsuite/tests/javascript/closure/all.T
- testsuite/tests/patsyn/should_run/ghci.stderr
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- testsuite/tests/safeHaskell/safeLanguage/SafeLang15.stderr
- testsuite/tests/simd/should_run/all.T
- testsuite/tests/type-data/should_run/T22332a.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/unsatisfiable/T23816.stderr
- testsuite/tests/unsatisfiable/UnsatDefer.stderr
- utils/haddock/doc/.gitignore
- utils/haddock/doc/Makefile
- + utils/haddock/doc/_static/haddock-custom.css
- utils/haddock/doc/conf.py
- utils/haddock/doc/markup.rst
- + utils/haddock/doc/snippets/.gitignore
- + utils/haddock/doc/snippets/Lists.hs
- + utils/haddock/doc/snippets/Makefile
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.html
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.tex
- + utils/haddock/doc/snippets/Snippet-List-Definition.html
- + utils/haddock/doc/snippets/Snippet-List-Definition.tex
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.html
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.tex
- + utils/haddock/doc/snippets/Snippet-List-Indentation.html
- + utils/haddock/doc/snippets/Snippet-List-Indentation.tex
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.tex
- utils/haddock/html-test/ref/A.html
- utils/haddock/html-test/ref/Bug1004.html
- utils/haddock/html-test/ref/Bug1033.html
- utils/haddock/html-test/ref/Bug1103.html
- utils/haddock/html-test/ref/Bug548.html
- utils/haddock/html-test/ref/Bug923.html
- utils/haddock/html-test/ref/ConstructorPatternExport.html
- utils/haddock/html-test/ref/FunArgs.html
- utils/haddock/html-test/ref/Hash.html
- utils/haddock/html-test/ref/Instances.html
- utils/haddock/html-test/ref/LinearTypes.html
- utils/haddock/html-test/ref/RedactTypeSynonyms.html
- utils/haddock/html-test/ref/T23616.html
- utils/haddock/html-test/ref/Test.html
- utils/haddock/html-test/ref/TypeFamilies3.html
- + validate-riscv-bindist.sh
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a1e1c2b56d150d95d51e54a2e5cf4…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a1e1c2b56d150d95d51e54a2e5cf4…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/romes/hadrian-cross-stage2-rebase_SVEN_FINAL] Delete targetSupportsGhciObjects
by Sven Tennie (@supersven) 21 Feb '26
by Sven Tennie (@supersven) 21 Feb '26
21 Feb '26
Sven Tennie pushed to branch wip/romes/hadrian-cross-stage2-rebase_SVEN_FINAL at Glasgow Haskell Compiler / GHC
Commits:
234aa8ca by Sven Tennie at 2026-02-21T15:23:08+01:00
Delete targetSupportsGhciObjects
- - - - -
2 changed files:
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Rules/Library.hs
Changes:
=====================================
hadrian/src/Oracles/Flag.hs
=====================================
@@ -1,11 +1,8 @@
-{-# LANGUAGE MultiWayIf #-}
-
module Oracles.Flag (
Flag (..), flag, getFlag,
BuildFlag(..), buildFlag,
targetRTSLinkerOnlySupportsSharedLibs,
targetSupportsSharedLibs,
- targetSupportsGhciObjects,
targetSupportsThreadedRts,
targetSupportsSMP,
useLibdw,
@@ -86,14 +83,6 @@ buildFlag f st =
getFlag :: Flag -> Expr c b Bool
getFlag = expr . flag
--- | Does the target platform support object merging (and therefore we can build GHCi objects
--- when appropriate).
-targetSupportsGhciObjects :: Stage -> Action Bool
-targetSupportsGhciObjects stage = do
- has_merge_objs <- isJust <$> queryTargetTarget stage tgtMergeObjs
- only_shared_libs <- targetRTSLinkerOnlySupportsSharedLibs stage
- pure $ has_merge_objs && not only_shared_libs
-
targetRTSLinkerOnlySupportsSharedLibs :: Stage -> Action Bool
targetRTSLinkerOnlySupportsSharedLibs s =
queryTargetTarget s Toolchain.tgtRTSLinkerOnlySupportsSharedLibs
=====================================
hadrian/src/Rules/Library.hs
=====================================
@@ -140,7 +140,7 @@ buildPackage root fp = do
ways <- interpretInContext ctx getLibraryWays
let hasVanilla = elem vanilla ways
hasDynamic = elem dynamic ways
- support <- targetSupportsGhciObjects stage
+ support <- targetSupportsSharedLibs stage
when ((hasVanilla && hasDynamic) &&
support && way == vanilla) $ do
stamp <- (pkgStampFile (ctx { way = dynamic }))
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/234aa8ca794d56c3a550811f1d3218d…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/234aa8ca794d56c3a550811f1d3218d…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc] Pushed new branch wip/jeltsch/system-io-os-imports-improvement
by Wolfgang Jeltsch (@jeltsch) 21 Feb '26
by Wolfgang Jeltsch (@jeltsch) 21 Feb '26
21 Feb '26
Wolfgang Jeltsch pushed new branch wip/jeltsch/system-io-os-imports-improvement at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/jeltsch/system-io-os-imports-…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] hadrian/build-cabal: Better respect and utilize -j
by Marge Bot (@marge-bot) 20 Feb '26
by Marge Bot (@marge-bot) 20 Feb '26
20 Feb '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
eab3dbba by Andreas Klebinger at 2026-02-20T18:53:51-05:00
hadrian/build-cabal: Better respect and utilize -j
* We now respect -j<n> for the cabal invocation to build hadrian rather
than hardcoding -j
* We use the --semaphore flag to ensure cabal/ghc build the hadrian
executable in parallel using the -jsem mechanism.
Saves 10-15s on fresh builds for me.
Fixes #26876
- - - - -
1 changed file:
- hadrian/build-cabal
Changes:
=====================================
hadrian/build-cabal
=====================================
@@ -23,9 +23,52 @@ fi
CABVERSTR=$("$CABAL" --numeric-version)
CABVER=( ${CABVERSTR//./ } )
+THREADS="-j1"
+GC_THREADS=""
+SEMAPHORE=""
+
+echo "$@"
+
+# Try building hadrian in parallel. We check for -j<n>.
+# If threads > 1 we pass --semaphore to allow ghc to build more than one module in parallel
+# If threads > 4 we pass -qn as higher parallel gc thread counts can lead to slow downs
+# We only do any of thise for cabal >= 3.14, because I don't trust older versions to handle --semaphore right
+if [ "${CABVER[0]}" -gt 3 ] || [ "${CABVER[0]}" -eq 3 -a "${CABVER[1]}" -ge 14 ];
+then
+
+ for arg in "$@"; do
+ case "$arg" in
+ -j)
+ GC_THREADS="-qn4"
+ SEMAPHORE="--semaphore"
+ THREADS="-j"
+ ;;
+ -j[0-9]*)
+ threads="${arg#-j}"
+ if [[ "$threads" =~ ^[0-9]+$ ]] && [ "$threads" -ne 0 ]; then
+ THREADS="-j${threads}"
+ if [ $threads -ge 4 ]; then
+ GC_THREADS="-qn4"
+ fi
+ if [ $threads -gt 1 ]; then
+ SEMAPHORE="--semaphore"
+ fi
+ fi
+ ;;
+ esac
+
+ done
+
+fi
+
+if [ "$(uname -s)" = "FreeBSD" ]; then
+ # Can't rely on posix semaphore support in free bsd.
+ SEMAPHORE=""
+fi
+
if [ "${CABVER[0]}" -gt 2 -o "${CABVER[0]}" -eq 2 -a "${CABVER[1]}" -ge 2 ];
then
- "$CABAL" --project-file="$PROJ" new-build "${CABFLAGS[@]}" -j exe:hadrian
+ "$CABAL" --project-file="$PROJ" new-build "${CABFLAGS[@]}" ${THREADS} ${SEMAPHORE} --ghc-options="+RTS ${GC_THREADS} -RTS" exe:hadrian
# use new-exec instead of new-run to make sure that the build-tools (alex & happy) are in PATH
"$CABAL" --project-file="$PROJ" new-exec "${CABFLAGS[@]}" hadrian -- \
--directory "$PWD" \
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eab3dbba79650e6046efca79133b4c0…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eab3dbba79650e6046efca79133b4c0…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
20 Feb '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
44354255 by Vo Minh Thu at 2026-02-20T18:53:06-05:00
GHCi: add a :version command.
This looks like:
ghci> :version
GHCi, version 9.11.20240322
This closes #24576.
Co-Author: Markus Läll <markus.l2ll(a)gmail.com>
- - - - -
3 changed files:
- + docs/users_guide/10.0.1-notes.rst
- docs/users_guide/ghci.rst
- ghc/GHCi/UI.hs
Changes:
=====================================
docs/users_guide/10.0.1-notes.rst
=====================================
@@ -0,0 +1,36 @@
+.. _release-10-0-1:
+
+Version 10.0.1
+==============
+
+Language
+~~~~~~~~
+
+Compiler
+~~~~~~~~
+
+GHCi
+~~~~
+
+- Added the :ghci-cmd:`:version` command. This displays the current GHC version.
+
+Runtime system
+~~~~~~~~~~~~~~
+
+``base`` library
+~~~~~~~~~~~~~~~~
+
+``ghc-prim`` library
+~~~~~~~~~~~~~~~~~~~~
+
+``ghc`` library
+~~~~~~~~~~~~~~~
+
+``ghc-heap`` library
+~~~~~~~~~~~~~~~~~~~~
+
+``template-haskell`` library
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Included libraries
+~~~~~~~~~~~~~~~~~~
=====================================
docs/users_guide/ghci.rst
=====================================
@@ -3140,6 +3140,10 @@ commonly used commands.
The :ghci-cmd:`:uses` command requires :ghci-cmd:`:set +c` to be set.
+.. ghci-cmd:: :version
+
+ Display the current GHC version.
+
.. ghci-cmd:: :where
Show the current evaluation stack while stopped at a breakpoint.
=====================================
ghc/GHCi/UI.hs
=====================================
@@ -193,9 +193,11 @@ defaultGhciSettings =
fullHelpText = defFullHelpText
}
+versionString :: String
+versionString = "GHCi, version " ++ cProjectVersion
+
ghciWelcomeMsg :: String
-ghciWelcomeMsg = "GHCi, version " ++ cProjectVersion ++
- ": https://www.haskell.org/ghc/ :? for help"
+ghciWelcomeMsg = versionString ++ ": https://www.haskell.org/ghc/ :? for help"
ghciCommands :: [Command]
ghciCommands = map mkCmd [
@@ -253,6 +255,7 @@ ghciCommands = map mkCmd [
("unadd", keepGoingPaths unAddModule, completeFilename),
("undef", keepGoing undefineMacro, completeMacro),
("unset", keepGoing unsetOptions, completeSetOptions),
+ ("version", keepGoing showVersion', noCompletion),
("where", keepGoing whereCmd, noCompletion),
("instances", keepGoing' instancesCmd, completeExpression)
] ++ map mkCmdHidden [ -- hidden commands
@@ -366,6 +369,7 @@ defFullHelpText =
" :type +d <expr> show the type of <expr>, defaulting type variables\n" ++
" :unadd <module> ... remove module(s) from the current target set\n" ++
" :undef <cmd> undefine user-defined command :<cmd>\n" ++
+ " :version display the current GHC version\n" ++
" ::<cmd> run the builtin command\n" ++
" :!<command> run the shell command <command>\n" ++
" :shell <command> run shell via sh -c <command>\n" ++
@@ -3626,6 +3630,9 @@ unsetOptions str
no_flags <- mapM no_flag minus_opts
when (not (null no_flags)) $ newDynFlags False no_flags
+showVersion' :: GhciMonad m => String -> m ()
+showVersion' _ = liftIO (putStrLn versionString)
+
isMinus :: String -> Bool
isMinus ('-':_) = True
isMinus _ = False
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44354255ce5d5df51c84834bff64674…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44354255ce5d5df51c84834bff64674…
You're receiving this email because of your account on gitlab.haskell.org.
1
0