[Git][ghc/ghc][wip/haanss/depdir] 29 commits: configure: Allow use of LLVM 20
by Hassan Al-Awwadi (@hassan.awwadi) 26 Aug '25
by Hassan Al-Awwadi (@hassan.awwadi) 26 Aug '25
26 Aug '25
Hassan Al-Awwadi pushed to branch wip/haanss/depdir at Glasgow Haskell Compiler / GHC
Commits:
ca03226d by Ben Gamari at 2025-08-18T13:43:20+00:00
configure: Allow use of LLVM 20
- - - - -
783cd7d6 by Cheng Shao at 2025-08-18T20:13:14-04:00
compiler: use `UniqMap` instead of `Map` for `BCEnv` in bytecode compiler
The bytecode compiler maintains a `BCEnv` which was previously `Map Id
StackDepth`. Given `Id` is `Uniquable`, we might as well use `UniqMap`
here as a more efficient data structure, hence this patch.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
58e46da9 by fendor at 2025-08-18T20:13:56-04:00
rts: Strip lower three bits when hashing Word instead of lower eight bits
- - - - -
45dbfa23 by Cheng Shao at 2025-08-18T20:14:37-04:00
libffi: update to 3.5.2
Bumps libffi submodule.
- - - - -
54be78ef by Ben Gamari at 2025-08-19T16:28:05-04:00
testsuite: Fix T20006b
This test is supposed to fail for non-threaded ways yet it
was previously marked as only failing in `normal`.
Fix this.
- - - - -
f4bac607 by Simon Peyton Jones at 2025-08-19T16:28:47-04:00
Take yet more care with reporting redundant constraints
This small patch fixes #25992, which relates to reporting redundant
constraints on default-method declarations.
See (TRC5) in Note [Tracking redundant constraints]
- - - - -
ab130fec by fendor at 2025-08-19T16:29:29-04:00
Bump dependencies of hadrian-bootstrap-gen to use GHC 9.6.7
- - - - -
6d02ac6f by fendor at 2025-08-19T16:29:29-04:00
Bump required GHC version for test-bootstrap jobs to 9.10.1
Include test-bootstrap job for GHC 9.12.2.
Update hadrian bootstrap plans use GHC 9.10 and 9.12
Remove older GHC bootstrap configurations.
We require at least GHC 9.10.1 to build GHC.
Adds plans for:
* 9.10.1
* 9.10.2
* 9.12.1
* 9.12.2
- - - - -
9e857171 by Brandon Chinn at 2025-08-20T11:47:46-04:00
Don't warn unused-imports with used generated imports
Fixes #21730
* The old notion of "implicit" import has been renamed to "generated". See Note [Generated imports] in GHC.Hs.ImpExp.
* ImportMap now keeps track of generated and user-written imports separately. This avoids the fake SrcSpan we used to give the implicit Prelude import, and the hack that went with it.
* -ddump-minimal-imports now considers generated imports (but still only
warns on + prints user-written imports)
* bestImport considers generated imports to take priority over user-written imports.
- - - - -
9fb3bad4 by Ben Gamari at 2025-08-20T11:48:31-04:00
mailmap: Use ben(a)well-typed.com more liberally
Nearly all of this work was done while working for Well-Typed.
- - - - -
774fec37 by Ben Gamari at 2025-08-20T11:49:15-04:00
Add primop to annotate the call stack with arbitrary data
We introduce a new primop `annotateStack#` which allows us to push
arbitrary data onto the call-stack.
This allows us to extract the data later when decoding the stack, for
example when an exception is thrown, showing more information to the
user without having to annotate the full call-stack with `HasCallStack`
constraints.
A new stack frame value is introduced `AnnFrame`, which consists of
nothing but a generic payload.
The primop has a small wrapper API that allows users to annotate their
call-stack in programs.
There is a pure API and an IO-based one. The former is a little bit
dubious, as it affects the evaluation of a program, so use with care.
The latter is "safe", as it doesn't change the evaluation of the
program.
The stack annotation mechanism is similarly implemented to the
`ExceptionAnnotation` and `Exception`, there is a typeclass to indicate
something can be pushed onto the call-stack and all values are wrapped
in the existential `SomeStackAnnotation`, which recover the type of the
annotation payload.
There is currently no builtin way to show the stack annotations when
`Backtraces` are displayed (i.e., when showing stack traces to the user),
which we will address in a follow-up MR.
-------------------------
Metric Increase:
ghc_experimental_so
-------------------------
We increase the size of the package, so this is not unreasonable.
Co-Authored-By: fendor <fendor(a)posteo.de>
Co-Authored-By: Ben Gamari <bgamari.foss(a)gmail.com>
- - - - -
fdfa3892 by Ben Gamari at 2025-08-20T11:49:57-04:00
testsuite: Add regression test for #24606
- - - - -
39b2e382 by Cheng Shao at 2025-08-20T11:50:40-04:00
compiler: only use `Name` instead of `Id` in `SptEntry`
As a part of #26298, this patch refactors `SptEntry` to only carry a
`Name` instead of `Id`: we do not care about extra information like
caffyness or type at all in any static pointer related codegen logic.
This is necessary to make `SptEntry` serializable, as a part of the
grand plan of serializable bytecode.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
276f8ea8 by Vekhir -- at 2025-08-20T11:51:35-04:00
Bump Cabal dependency
- - - - -
0b9c7437 by Zubin Duggal at 2025-08-20T11:52:18-04:00
ci: Teach ci.sh to fetch FreeBSD artifacts from ghcup unofficial bindists and bootstrap compiler on FreeBSD to 9.10.1
Also refactor fetch_ghc logic in ci.sh, renaming the GHC_VERSION enviorment configuration variable to FETCH_GHC_VERSION,
making it clear that it is intended for use on platforms like Windows and FreeBSD where we don't want to use the GHC
excecutable from the platform environment and instead need to download and install GHC-$FETCH_GHC_VERSION from a release
bindist.
Fixes #26296
- - - - -
b2914797 by Cheng Shao at 2025-08-20T11:53:00-04:00
driver: use UniqSet for hiddenModules in DynFlags/FinderOpts
This patch replaces Set ModuleName with UniqSet ModuleName in
DynFlags.hiddenModules and FinderOpts.finder_hiddenModules for
improved efficiency.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
0335d899 by Cheng Shao at 2025-08-20T11:53:00-04:00
driver: use UniqMap ModuleName in the finder
This patch replaces Map ModuleName with UniqMap ModuleName in the
finder for improved efficiency.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
91f4faaa by Cheng Shao at 2025-08-20T11:53:43-04:00
configure: check python3 version and require minimal 3.7
Since !9515, the testsuite driver requires python3 version to be at
least 3.7, though this has never been checked by configure logic. This
patch implements the version check. Fixes #23234.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
df4ee9b4 by Cheng Shao at 2025-08-20T11:54:25-04:00
compiler: use zero cost coerce in GHC.CmmToAsm.CFG.loopInfo
This patch refactors GHC.CmmToAsm.CFG.loopInfo to use zero cost coerce
and thus addresses the TODO. For coerce to work, constructors of
Label/LabelMap/LabelSet from GHC.Cmm.Dataflow.Label are exposed,
though I believe it's a worthy tradeoff to avoid unnecessary runtime
cost without using unsafeCoerce, since the latter could be a landmine
for future refactoring.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
ccda188d by Simon Peyton Jones at 2025-08-20T11:55:07-04:00
Start with empty inerts in shortcut solving
When short-cut solving we were starting with an inert set that had
unsolved Wanteds. This caused an infinite loop (#26314), because a
typechecker plugin kept being given that unsolved Wanted.
It's better just to start with an empty inert set
- - - - -
c8882ed7 by Ben Gamari at 2025-08-20T11:55:49-04:00
configure: Bump minimal bootstrap GHC version to 9.8
- - - - -
f0a19d74 by fendor at 2025-08-20T19:55:00-04:00
Remove deprecated functions from the ghci package
- - - - -
ebeb991b by fendor at 2025-08-20T19:55:00-04:00
base: Remove unstable heap representation details from GHC.Exts
- - - - -
e368e247 by Rodrigo Mesquita at 2025-08-20T19:55:42-04:00
bytecode: Use 32bits for breakpoint index
Fixes #26325
- - - - -
42724462 by Simon Hengel at 2025-08-21T17:52:11-04:00
Serialize wired-in names as external names when creating HIE files
Note that the domain of de-serialized names stays the same.
Specifically, for known-key names, before `lookupKnownKeyName` was used,
while now this is handled by `lookupOrigNameCache` which captures the
same range provided that the OrigNameCache has been initialized with
`knownKeyNames` (which is the case by default).
(fixes #26238)
- - - - -
6a43f8ec by Cheng Shao at 2025-08-21T17:52:52-04:00
compiler: fix closure C type in SPT init code
This patch fixes the closure C type in SPT init code to StgClosure,
instead of the previously incorrect StgPtr. Having an incorrect C type
makes SPT init code not compatible with other foreign stub generation
logic, which may also emit their own extern declarations for the same
closure symbols and thus will clash with the incorrect prototypes in
SPT init code.
- - - - -
5b5d9d47 by Ben Gamari at 2025-08-25T14:29:35-04:00
Revert "STM: don't create a transaction in the rhs of catchRetry# (#26028)"
This reverts commit 0a5836891ca29836a24c306d2a364c2e4b5377fd
- - - - -
10f06163 by Cheng Shao at 2025-08-25T14:30:16-04:00
wasm: ensure setKeepCAFs() is called in ghci
This patch is a critical bugfix for #26106, see comment and linked
issue for details.
- - - - -
f6f88dc8 by Hassan Al-Awwadi at 2025-08-26T14:29:27+02:00
Adds the fucnction addDependentDirectory to Q, resolving issue #26148.
This function adds a new directory to the list of things a module depends upon. That means that when the contents of the directory change, the recompilation checker will notice this and the module will be recompiled. Documentation has also been added for addDependentFunction and addDependentDirectory in the user guide.
- - - - -
203 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .mailmap
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/Cmm/Dataflow/Label.hs
- compiler/GHC/CmmToAsm/CFG.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Config/Finder.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/HsToCore/Docs.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Ext/Binary.hs
- compiler/GHC/Iface/Ext/Types.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Types.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Parser/Header.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/Prim.hs
- compiler/GHC/StgToJS/StaticPtr.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/SptEntry.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Module/Deps.hs
- configure.ac
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/separate_compilation.rst
- ghc/GHCi/UI.hs
- hadrian/bootstrap/generate_bootstrap_plans
- hadrian/bootstrap/hadrian-bootstrap-gen.cabal
- hadrian/bootstrap/plan-9_10_1.json
- hadrian/bootstrap/plan-9_6_5.json → hadrian/bootstrap/plan-9_10_2.json
- hadrian/bootstrap/plan-9_6_6.json → hadrian/bootstrap/plan-9_12_1.json
- hadrian/bootstrap/plan-9_6_4.json → hadrian/bootstrap/plan-9_12_2.json
- − hadrian/bootstrap/plan-9_6_1.json
- − hadrian/bootstrap/plan-9_6_2.json
- − hadrian/bootstrap/plan-9_6_3.json
- − hadrian/bootstrap/plan-9_8_1.json
- − hadrian/bootstrap/plan-9_8_2.json
- hadrian/bootstrap/plan-bootstrap-9_10_1.json
- hadrian/bootstrap/plan-bootstrap-9_6_5.json → hadrian/bootstrap/plan-bootstrap-9_10_2.json
- hadrian/bootstrap/plan-bootstrap-9_6_6.json → hadrian/bootstrap/plan-bootstrap-9_12_1.json
- hadrian/bootstrap/plan-bootstrap-9_8_1.json → hadrian/bootstrap/plan-bootstrap-9_12_2.json
- − hadrian/bootstrap/plan-bootstrap-9_6_1.json
- − hadrian/bootstrap/plan-bootstrap-9_6_2.json
- − hadrian/bootstrap/plan-bootstrap-9_6_3.json
- − hadrian/bootstrap/plan-bootstrap-9_6_4.json
- − hadrian/bootstrap/plan-bootstrap-9_8_2.json
- hadrian/bootstrap/src/Main.hs
- hadrian/hadrian.cabal
- libffi-tarballs
- libraries/base/changelog.md
- libraries/base/src/GHC/Exts.hs
- libraries/ghc-experimental/ghc-experimental.cabal.in
- + libraries/ghc-experimental/src/GHC/Stack/Annotation/Experimental.hs
- libraries/ghc-heap/GHC/Exts/Heap/ClosureTypes.hs
- libraries/ghc-heap/GHC/Exts/Heap/Closures.hs
- libraries/ghc-heap/GHC/Exts/Stack.hs
- libraries/ghc-heap/GHC/Exts/Stack/Constants.hsc
- libraries/ghc-heap/GHC/Exts/Stack/Decode.hs
- + libraries/ghc-heap/tests/stack-annotation/Makefile
- + libraries/ghc-heap/tests/stack-annotation/TestUtils.hs
- + libraries/ghc-heap/tests/stack-annotation/all.T
- + libraries/ghc-heap/tests/stack-annotation/ann_frame001.hs
- + libraries/ghc-heap/tests/stack-annotation/ann_frame001.stdout
- + libraries/ghc-heap/tests/stack-annotation/ann_frame002.hs
- + libraries/ghc-heap/tests/stack-annotation/ann_frame002.stdout
- + libraries/ghc-heap/tests/stack-annotation/ann_frame003.hs
- + libraries/ghc-heap/tests/stack-annotation/ann_frame003.stdout
- + libraries/ghc-heap/tests/stack-annotation/ann_frame004.hs
- + libraries/ghc-heap/tests/stack-annotation/ann_frame004.stdout
- libraries/ghc-internal/src/GHC/Internal/ClosureTypes.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- libraries/ghci/GHCi/CreateBCO.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/TH.hs
- libraries/ghci/ghci.cabal.in
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- m4/find_python.m4
- rts/ClosureFlags.c
- rts/Disassembler.c
- rts/Hash.c
- rts/Interpreter.c
- rts/LdvProfile.c
- rts/PrimOps.cmm
- rts/Printer.c
- rts/RaiseAsync.c
- rts/RetainerProfile.c
- rts/RtsSymbols.c
- rts/STM.c
- rts/TraverseHeap.c
- rts/include/rts/storage/ClosureTypes.h
- rts/include/rts/storage/Closures.h
- rts/include/stg/MiscClosures.h
- rts/js/profiling.js
- rts/sm/Compact.c
- rts/sm/Evac.c
- rts/sm/NonMovingMark.c
- rts/sm/Sanity.c
- rts/sm/Scav.c
- testsuite/.gitignore
- testsuite/tests/gadt/T12468.stderr
- testsuite/tests/ghc-e/should_fail/T24172.stderr
- testsuite/tests/ghci/scripts/T8353.stderr
- testsuite/tests/ghci/scripts/ghci038.stdout
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- − testsuite/tests/lib/stm/T26028.hs
- − testsuite/tests/lib/stm/T26028.stdout
- − testsuite/tests/lib/stm/all.T
- − testsuite/tests/module/T21752.stderr
- testsuite/tests/module/mod150.stderr
- testsuite/tests/module/mod151.stderr
- testsuite/tests/module/mod152.stderr
- testsuite/tests/module/mod153.stderr
- testsuite/tests/overloadedrecflds/should_fail/T18999_NoDisambiguateRecordFields.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T19082.stderr
- testsuite/tests/perf/compiler/hard_hole_fits.stderr
- testsuite/tests/plugins/Makefile
- + testsuite/tests/plugins/T21730-plugin/Makefile
- + testsuite/tests/plugins/T21730-plugin/Setup.hs
- + testsuite/tests/plugins/T21730-plugin/T21730-plugin.cabal
- + testsuite/tests/plugins/T21730-plugin/T21730_Plugin.hs
- + testsuite/tests/plugins/T21730.hs
- testsuite/tests/plugins/all.T
- testsuite/tests/quotes/LiftErrMsg.stderr
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- testsuite/tests/quotes/LiftErrMsgTyped.stderr
- testsuite/tests/rename/should_compile/T22513d.stderr
- testsuite/tests/rename/should_compile/T22513e.stderr
- testsuite/tests/rename/should_compile/T22513f.stderr
- testsuite/tests/rename/should_compile/T22513g.stderr
- testsuite/tests/rename/should_compile/T22513h.stderr
- testsuite/tests/rename/should_compile/T22513i.stderr
- testsuite/tests/rename/should_compile/rn039.ghc.stderr
- testsuite/tests/rename/should_fail/T15487.stderr
- testsuite/tests/rename/should_fail/T18740a.stderr
- testsuite/tests/rename/should_fail/rnfail044.stderr
- testsuite/tests/rts/flags/all.T
- testsuite/tests/safeHaskell/flags/SafeFlags17.stderr
- + testsuite/tests/simplCore/should_compile/T24606.hs
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/th/Makefile
- testsuite/tests/th/T10267.stderr
- testsuite/tests/th/T14627.stderr
- testsuite/tests/th/T15321.stderr
- + testsuite/tests/th/TH_Depends_Dir.hs
- + testsuite/tests/th/TH_Depends_Dir.stdout
- + testsuite/tests/th/TH_Depends_Dir_External.hs
- testsuite/tests/th/all.T
- testsuite/tests/typecheck/should_compile/T13050.stderr
- testsuite/tests/typecheck/should_compile/T14273.stderr
- testsuite/tests/typecheck/should_compile/T14590.stderr
- testsuite/tests/typecheck/should_compile/T25180.stderr
- + testsuite/tests/typecheck/should_compile/T25992a.hs
- testsuite/tests/typecheck/should_compile/T9497a.stderr
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/refinement_hole_fits.stderr
- testsuite/tests/typecheck/should_compile/subsumption_sort_hole_fits.stderr
- testsuite/tests/typecheck/should_fail/T14884.stderr
- testsuite/tests/typecheck/should_fail/T21130.stderr
- testsuite/tests/typecheck/should_fail/T23739b.stderr
- testsuite/tests/typecheck/should_fail/T23739c.stderr
- testsuite/tests/typecheck/should_fail/T9497d.stderr
- testsuite/tests/typecheck/should_fail/tcfail037.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/vdq-rta/should_fail/T23738_fail_pun.stderr
- utils/deriveConstants/Main.hs
- utils/haddock/haddock-api/src/Haddock/InterfaceFile.hs
- utils/jsffi/dyld.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/562ee8a273e58635e59e87f2ebf3f5…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/562ee8a273e58635e59e87f2ebf3f5…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/haanss/depdir] Adds the fucnction addDependentDirectory to Q, resolving issue #26148.
by Hassan Al-Awwadi (@hassan.awwadi) 26 Aug '25
by Hassan Al-Awwadi (@hassan.awwadi) 26 Aug '25
26 Aug '25
Hassan Al-Awwadi pushed to branch wip/haanss/depdir at Glasgow Haskell Compiler / GHC
Commits:
562ee8a2 by Hassan Al-Awwadi at 2025-08-26T14:18:51+02:00
Adds the fucnction addDependentDirectory to Q, resolving issue #26148.
This function adds a new directory to the list of things a module depends upon. That means that when the contents of the directory change, the recompilation checker will notice this and the module will be recompiled. Documentation has also been added for addDependentFunction and addDependentDirectory in the user guide.
- - - - -
23 changed files:
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Types.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Module/Deps.hs
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/separate_compilation.rst
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/TH.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- testsuite/.gitignore
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- testsuite/tests/th/Makefile
- + testsuite/tests/th/TH_Depends_Dir.hs
- + testsuite/tests/th/TH_Depends_Dir.stdout
- + testsuite/tests/th/TH_Depends_Dir_External.hs
- testsuite/tests/th/all.T
Changes:
=====================================
compiler/GHC/HsToCore/Usage.hs
=====================================
@@ -75,14 +75,15 @@ data UsageConfig = UsageConfig
mkUsageInfo :: UsageConfig -> Plugins -> FinderCache -> UnitEnv
-> Module -> ImportedMods -> [ImportUserSpec] -> NameSet
- -> [FilePath] -> [(Module, Fingerprint)] -> [Linkable] -> PkgsLoaded
+ -> [FilePath] -> [FilePath] -> [(Module, Fingerprint)] -> [Linkable] -> PkgsLoaded
-> IfG [Usage]
mkUsageInfo uc plugins fc unit_env
this_mod dir_imp_mods imp_decls used_names
- dependent_files merged needed_links needed_pkgs
+ dependent_files dependent_dirs merged needed_links needed_pkgs
= do
eps <- liftIO $ readIORef (euc_eps (ue_eps unit_env))
- hashes <- liftIO $ mapM getFileHash dependent_files
+ file_hashes <- liftIO $ mapM getFileHash dependent_files
+ dirs_hashes <- liftIO $ mapM getDirHash dependent_dirs
let hu = ue_unsafeHomeUnit unit_env
hug = ue_home_unit_graph unit_env
-- Dependencies on object files due to TH and plugins
@@ -93,7 +94,11 @@ mkUsageInfo uc plugins fc unit_env
let usages = mod_usages ++ [ UsageFile { usg_file_path = mkFastString f
, usg_file_hash = hash
, usg_file_label = Nothing }
- | (f, hash) <- zip dependent_files hashes ]
+ | (f, hash) <- zip dependent_files file_hashes ]
+ ++ [ UsageDirectory { usg_dir_path = mkFastString d
+ , usg_dir_hash = hash
+ , usg_dir_label = Nothing }
+ | (d, hash) <- zip dependent_dirs dirs_hashes]
++ [ UsageMergedRequirement
{ usg_mod = mod,
usg_mod_hash = hash
=====================================
compiler/GHC/Iface/Make.hs
=====================================
@@ -269,6 +269,7 @@ mkRecompUsageInfo hsc_env tc_result = do
else do
let used_names = mkUsedNames tc_result
dep_files <- (readIORef (tcg_dependent_files tc_result))
+ dep_dirs <- (readIORef (tcg_dependent_dirs tc_result))
(needed_links, needed_pkgs) <- readIORef (tcg_th_needed_deps tc_result)
let uc = initUsageConfig hsc_env
plugins = hsc_plugins hsc_env
@@ -289,6 +290,7 @@ mkRecompUsageInfo hsc_env tc_result = do
(tcg_import_decls tc_result)
used_names
dep_files
+ dep_dirs
(tcg_merged tc_result)
needed_links
needed_pkgs
=====================================
compiler/GHC/Iface/Recomp.hs
=====================================
@@ -194,6 +194,7 @@ data RecompReason
| ModuleChangedRaw ModuleName
| ModuleChangedIface ModuleName
| FileChanged FilePath
+ | DirChanged FilePath
| CustomReason String
| FlagsChanged
| LinkFlagsChanged
@@ -230,6 +231,7 @@ instance Outputable RecompReason where
ModuleRemoved (_st, _uid, m) -> ppr m <+> text "removed"
ModuleAdded (_st, _uid, m) -> ppr m <+> text "added"
FileChanged fp -> text fp <+> text "changed"
+ DirChanged dp -> text "Contents of" <+> text dp <+> text "changed"
CustomReason s -> text s
FlagsChanged -> text "Flags changed"
LinkFlagsChanged -> text "Flags changed"
@@ -815,6 +817,22 @@ checkModUsage fc UsageFile{ usg_file_path = file,
then \e -> pprTrace "UsageFile" (text (show e)) $ return recomp
else \_ -> return recomp -- if we can't find the file, just recompile, don't fail
+checkModUsage fc UsageDirectory{ usg_dir_path = dir,
+ usg_dir_hash = old_hash,
+ usg_dir_label = mlabel } =
+ liftIO $
+ handleIO handler $ do
+ new_hash <- lookupDirCache fc $ unpackFS dir
+ if (old_hash /= new_hash)
+ then return recomp
+ else return UpToDate
+ where
+ reason = DirChanged $ unpackFS dir
+ recomp = needsRecompileBecause $ fromMaybe reason $ fmap CustomReason mlabel
+ handler = if debugIsOn
+ then \e -> pprTrace "UsageDirectory" (text (show e)) $ return recomp
+ else \_ -> return recomp -- if we can't find the dir, just recompile, don't fail
+
-- | We are importing a module whose exports have changed.
-- Does this require recompilation?
--
=====================================
compiler/GHC/Iface/Recomp/Types.hs
=====================================
@@ -140,6 +140,10 @@ pprUsage usage@UsageFile{}
= hsep [text "addDependentFile",
doubleQuotes (ftext (usg_file_path usage)),
ppr (usg_file_hash usage)]
+pprUsage usage@UsageDirectory{}
+ = hsep [text "AddDependentDirectory",
+ doubleQuotes (ftext (usg_dir_path usage)),
+ ppr (usg_dir_hash usage)]
pprUsage usage@UsageMergedRequirement{}
= hsep [text "merged", ppr (usg_mod usage), ppr (usg_mod_hash usage)]
pprUsage usage@UsageHomeModuleInterface{}
=====================================
compiler/GHC/Tc/Gen/Splice.hs
=====================================
@@ -173,8 +173,6 @@ import GHC.Parser.HaddockLex (lexHsDoc)
import GHC.Parser (parseIdentifier)
import GHC.Rename.Doc (rnHsDoc)
-
-
{-
Note [Template Haskell state diagram]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1524,6 +1522,11 @@ instance TH.Quasi TcM where
dep_files <- readTcRef ref
writeTcRef ref (fp:dep_files)
+ qAddDependentDirectory dp = do
+ ref <- fmap tcg_dependent_dirs getGblEnv
+ dep_dirs <- readTcRef ref
+ writeTcRef ref (dp:dep_dirs)
+
qAddTempFile suffix = do
dflags <- getDynFlags
logger <- getLogger
@@ -1928,6 +1931,7 @@ handleTHMessage msg = case msg of
ReifyConStrictness nm -> wrapTHResult $ TH.qReifyConStrictness nm
GetPackageRoot -> wrapTHResult $ TH.qGetPackageRoot
AddDependentFile f -> wrapTHResult $ TH.qAddDependentFile f
+ AddDependentDirectory d -> wrapTHResult $ TH.qAddDependentDirectory d
AddTempFile s -> wrapTHResult $ TH.qAddTempFile s
AddModFinalizer r -> do
interp <- hscInterp <$> getTopEnv
=====================================
compiler/GHC/Tc/Types.hs
=====================================
@@ -603,6 +603,7 @@ data TcGblEnv
-- decls.
tcg_dependent_files :: TcRef [FilePath], -- ^ dependencies from addDependentFile
+ tcg_dependent_dirs :: TcRef [FilePath], -- ^ dependencies from addDependentDirectory
tcg_th_topdecls :: TcRef [LHsDecl GhcPs],
-- ^ Top-level declarations from addTopDecls
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -55,7 +55,7 @@ module GHC.Tc.Utils.Monad(
getRdrEnvs, getImports,
getFixityEnv, extendFixityEnv,
getDeclaredDefaultTys,
- addDependentFiles,
+ addDependentFiles, addDependentDirectories,
-- * Error management
getSrcSpanM, setSrcSpan, setSrcSpanA, addLocM,
@@ -273,6 +273,7 @@ initTc hsc_env hsc_src keep_rn_syntax mod loc do_this
let { type_env_var = hsc_type_env_vars hsc_env };
dependent_files_var <- newIORef [] ;
+ dependent_dirs_var <- newIORef [] ;
static_wc_var <- newIORef emptyWC ;
cc_st_var <- newIORef newCostCentreState ;
th_topdecls_var <- newIORef [] ;
@@ -368,6 +369,7 @@ initTc hsc_env hsc_src keep_rn_syntax mod loc do_this
tcg_safe_infer = infer_var,
tcg_safe_infer_reasons = infer_reasons_var,
tcg_dependent_files = dependent_files_var,
+ tcg_dependent_dirs = dependent_dirs_var,
tcg_tc_plugin_solvers = [],
tcg_tc_plugin_rewriters = emptyUFM,
tcg_defaulting_plugins = [],
@@ -956,6 +958,12 @@ addDependentFiles fs = do
dep_files <- readTcRef ref
writeTcRef ref (fs ++ dep_files)
+addDependentDirectories :: [FilePath] -> TcRn ()
+addDependentDirectories ds = do
+ ref <- fmap tcg_dependent_dirs getGblEnv
+ dep_dirs <- readTcRef ref
+ writeTcRef ref (ds ++ dep_dirs)
+
{-
************************************************************************
* *
=====================================
compiler/GHC/Unit/Finder.hs
=====================================
@@ -31,6 +31,9 @@ module GHC.Unit.Finder (
findObjectLinkableMaybe,
findObjectLinkable,
+
+ -- important that GHC.HsToCore.Usage uses the same hashing method for usage dirs as is used here.
+ getDirHash,
) where
import GHC.Prelude
@@ -68,7 +71,9 @@ import qualified Data.Map as M
import GHC.Driver.Env
import GHC.Driver.Config.Finder
import qualified Data.Set as Set
+import qualified Data.List as L(sort)
import Data.List.NonEmpty ( NonEmpty (..) )
+import qualified System.Directory as SD
import qualified System.OsPath as OsPath
import qualified Data.List.NonEmpty as NE
@@ -107,10 +112,12 @@ initFinderCache :: IO FinderCache
initFinderCache = do
mod_cache <- newIORef emptyInstalledModuleEnv
file_cache <- newIORef M.empty
+ dir_cache <- newIORef M.empty
let flushFinderCaches :: UnitEnv -> IO ()
flushFinderCaches ue = do
atomicModifyIORef' mod_cache $ \fm -> (filterInstalledModuleEnv is_ext fm, ())
atomicModifyIORef' file_cache $ \_ -> (M.empty, ())
+ atomicModifyIORef' dir_cache $ \_ -> (M.empty, ())
where
is_ext mod _ = not (isUnitEnvInstalledModule ue mod)
@@ -137,8 +144,27 @@ initFinderCache = do
atomicModifyIORef' file_cache $ \c -> (M.insert key hash c, ())
return hash
Just fp -> return fp
+ lookupDirCache :: FilePath -> IO Fingerprint
+ lookupDirCache key = do
+ c <- readIORef dir_cache
+ case M.lookup key c of
+ Nothing -> do
+ hash <- getDirHash key
+ atomicModifyIORef' dir_cache $ \c -> (M.insert key hash c, ())
+ return hash
+ Just fp -> return fp
return FinderCache{..}
+-- | This function computes a shallow hash of a directory, so really just what files and directories are directly inside it.
+-- It does not look at the contents of the files, or the contents of the directories it contains.
+getDirHash :: FilePath -> IO Fingerprint
+getDirHash dir = do
+ contents <- SD.listDirectory dir
+ let hashes = fingerprintString <$> contents
+ let s_hashes = L.sort hashes
+ let hash = fingerprintFingerprints s_hashes
+ return hash
+
-- -----------------------------------------------------------------------------
-- The three external entry points
=====================================
compiler/GHC/Unit/Finder/Types.hs
=====================================
@@ -37,6 +37,7 @@ data FinderCache = FinderCache { flushFinderCaches :: UnitEnv -> IO ()
, lookupFileCache :: FilePath -> IO Fingerprint
-- ^ Look for the hash of a file in the cache. This should add it to the
-- cache. If the file doesn't exist, raise an IOException.
+ , lookupDirCache :: FilePath -> IO Fingerprint
}
data InstalledFindResult
=====================================
compiler/GHC/Unit/Module/Deps.hs
=====================================
@@ -357,6 +357,23 @@ data Usage
-- contents don't change. This previously lead to odd
-- recompilation behaviors; see #8114
}
+ | UsageDirectory {
+ usg_dir_path :: FastString,
+ -- ^ External dir dependency. From TH addDependentFile.
+ -- Should be absolute.
+ usg_dir_hash :: Fingerprint,
+ -- ^ 'Fingerprint' of the directories contents.
+
+ usg_dir_label :: Maybe String
+ -- ^ An optional string which is used in recompilation messages if
+ -- dir in question has changed.
+
+ -- Note: We do a very shallow check indeed, just what the contents of
+ -- the directory are, aka what files and directories are within it.
+ -- If those files/directories have their own contents changed, then
+ -- we won't spot it here. If you do want to spot that, the caller
+ -- should recursively add them to their useage.
+ }
| UsageHomeModuleInterface {
usg_mod_name :: ModuleName
-- ^ Name of the module
@@ -395,6 +412,7 @@ instance NFData Usage where
rnf (UsagePackageModule mod hash safe) = rnf mod `seq` rnf hash `seq` rnf safe `seq` ()
rnf (UsageHomeModule mod uid hash entities exports safe) = rnf mod `seq` rnf uid `seq` rnf hash `seq` rnf entities `seq` rnf exports `seq` rnf safe `seq` ()
rnf (UsageFile file hash label) = rnf file `seq` rnf hash `seq` rnf label `seq` ()
+ rnf (UsageDirectory dir hash label) = rnf dir `seq` rnf hash `seq` rnf label `seq` ()
rnf (UsageMergedRequirement mod hash) = rnf mod `seq` rnf hash `seq` ()
rnf (UsageHomeModuleInterface mod uid hash) = rnf mod `seq` rnf uid `seq` rnf hash `seq` ()
@@ -431,6 +449,12 @@ instance Binary Usage where
put_ bh (usg_unit_id usg)
put_ bh (usg_iface_hash usg)
+ put_ bh usg@UsageDirectory{} = do
+ putByte bh 5
+ put_ bh (usg_dir_path usg)
+ put_ bh (usg_dir_hash usg)
+ put_ bh (usg_dir_label usg)
+
get bh = do
h <- getByte bh
case h of
@@ -462,6 +486,12 @@ instance Binary Usage where
uid <- get bh
hash <- get bh
return UsageHomeModuleInterface { usg_mod_name = mod, usg_unit_id = uid, usg_iface_hash = hash }
+ 5 -> do
+ dp <- get bh
+ hash <- get bh
+ label <- get bh
+ return UsageDirectory { usg_dir_path = dp, usg_dir_hash = hash, usg_dir_label = label }
+
i -> error ("Binary.get(Usage): " ++ show i)
-- | Records the imports that we depend on from a home module,
=====================================
docs/users_guide/9.16.1-notes.rst
=====================================
@@ -50,6 +50,11 @@ Cmm
``template-haskell`` library
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+- We have added the ``addDependentDirectory`` function to match
+ ``addDependentFile``, which adds a directory to the list of dependencies that
+ the recompilation checker will look at to determine if a module needs to be
+ recompiled.
+
Included libraries
~~~~~~~~~~~~~~~~~~
=====================================
docs/users_guide/separate_compilation.rst
=====================================
@@ -710,7 +710,7 @@ beautiful sight!
You can read about :ghc-wiki:`how all this works <commentary/compiler/recompilation-avoidance>` in the GHC commentary.
Recompilation for Template Haskell and Plugins
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Recompilation checking gets a bit more complicated when using Template Haskell or
plugins. Both these features execute code at compile time and so if any of the
@@ -727,6 +727,19 @@ if ``foo`` is from module ``A`` and ``bar`` is from module ``B``, the module wil
now depend on ``A.o`` and ``B.o``, if either of these change then the module will
be recompiled.
+``addDependentFile`` and ``addDependentDirectory``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When using Template Haskell or plugins, you can use the functions
+``addDependentFile`` and ``addDependentDirectory`` to add additional
+dependencies to the module being compiled.
+
+- When adding a file, this means that the contents of the file changing between
+ compilations will trigger a recompilation of the module.
+- When adding a directory, this means that any file or subdirectory *added* to or
+ *removed* from the directory will trigger recompilation of the module, so
+ it is not a recursive dependency.
+
.. _mutual-recursion:
Mutually recursive modules and hs-boot files
=====================================
libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
=====================================
@@ -132,6 +132,9 @@ class (MonadIO m, MonadFail m) => Quasi m where
-- | See 'addDependentFile'.
qAddDependentFile :: FilePath -> m ()
+ -- | See 'addDependentDirectory'.
+ qAddDependentDirectory :: FilePath -> m ()
+
-- | See 'addTempFile'.
qAddTempFile :: String -> m FilePath
@@ -202,6 +205,7 @@ instance Quasi IO where
qExtsEnabled = badIO "extsEnabled"
qPutDoc _ _ = badIO "putDoc"
qGetDoc _ = badIO "getDoc"
+ qAddDependentDirectory _ = badIO "AddDependentDirectory"
instance Quote IO where
newName = newNameIO
@@ -819,6 +823,24 @@ getPackageRoot :: Q FilePath
getPackageRoot = Q qGetPackageRoot
+-- | Record external directories that runIO is using (dependent upon).
+-- The compiler can then recognize that it should re-compile the Haskell file
+-- when a directory changes.
+--
+-- Notes:
+--
+-- * ghc -M does not know about these dependencies - it does not execute TH.
+--
+-- * The dependency is shallow, based only on the direct content.
+-- Basically, it only sees a list of names. It does not look at directory
+-- metadata, recurse into subdirectories, or look at file contents. As
+-- long as the list of names remains the same, the directory is considered
+-- unchanged.
+--
+-- * The state of the directory is read at the interface generation time,
+-- not at the time of the function call.
+addDependentDirectory :: FilePath -> Q ()
+addDependentDirectory dp = Q (qAddDependentDirectory dp)
-- | Record external files that runIO is using (dependent upon).
-- The compiler can then recognize that it should re-compile the Haskell file
@@ -830,7 +852,11 @@ getPackageRoot = Q qGetPackageRoot
--
-- * ghc -M does not know about these dependencies - it does not execute TH.
--
--- * The dependency is based on file content, not a modification time
+-- * The dependency is based on file content, not a modification time or
+-- any other metadata associated with the file (e.g. permissions).
+--
+-- * The state of the file is read at the interface generation time,
+-- not at the time of the function call.
addDependentFile :: FilePath -> Q ()
addDependentFile fp = Q (qAddDependentFile fp)
@@ -952,32 +978,33 @@ instance MonadIO Q where
liftIO = runIO
instance Quasi Q where
- qNewName = newName
- qReport = report
- qRecover = recover
- qReify = reify
- qReifyFixity = reifyFixity
- qReifyType = reifyType
- qReifyInstances = reifyInstances
- qReifyRoles = reifyRoles
- qReifyAnnotations = reifyAnnotations
- qReifyModule = reifyModule
- qReifyConStrictness = reifyConStrictness
- qLookupName = lookupName
- qLocation = location
- qGetPackageRoot = getPackageRoot
- qAddDependentFile = addDependentFile
- qAddTempFile = addTempFile
- qAddTopDecls = addTopDecls
- qAddForeignFilePath = addForeignFilePath
- qAddModFinalizer = addModFinalizer
- qAddCorePlugin = addCorePlugin
- qGetQ = getQ
- qPutQ = putQ
- qIsExtEnabled = isExtEnabled
- qExtsEnabled = extsEnabled
- qPutDoc = putDoc
- qGetDoc = getDoc
+ qNewName = newName
+ qReport = report
+ qRecover = recover
+ qReify = reify
+ qReifyFixity = reifyFixity
+ qReifyType = reifyType
+ qReifyInstances = reifyInstances
+ qReifyRoles = reifyRoles
+ qReifyAnnotations = reifyAnnotations
+ qReifyModule = reifyModule
+ qReifyConStrictness = reifyConStrictness
+ qLookupName = lookupName
+ qLocation = location
+ qGetPackageRoot = getPackageRoot
+ qAddDependentFile = addDependentFile
+ qAddDependentDirectory = addDependentDirectory
+ qAddTempFile = addTempFile
+ qAddTopDecls = addTopDecls
+ qAddForeignFilePath = addForeignFilePath
+ qAddModFinalizer = addModFinalizer
+ qAddCorePlugin = addCorePlugin
+ qGetQ = getQ
+ qPutQ = putQ
+ qIsExtEnabled = isExtEnabled
+ qExtsEnabled = extsEnabled
+ qPutDoc = putDoc
+ qGetDoc = getDoc
----------------------------------------------------
=====================================
libraries/ghci/GHCi/Message.hs
=====================================
@@ -291,6 +291,7 @@ data THMessage a where
GetPackageRoot :: THMessage (THResult FilePath)
AddDependentFile :: FilePath -> THMessage (THResult ())
+ AddDependentDirectory :: FilePath -> THMessage (THResult ())
AddTempFile :: String -> THMessage (THResult FilePath)
AddModFinalizer :: RemoteRef (TH.Q ()) -> THMessage (THResult ())
AddCorePlugin :: String -> THMessage (THResult ())
@@ -343,6 +344,7 @@ getTHMessage = do
23 -> THMsg <$> (PutDoc <$> get <*> get)
24 -> THMsg <$> GetDoc <$> get
25 -> THMsg <$> return GetPackageRoot
+ 26 -> THMsg <$> AddDependentDirectory <$> get
n -> error ("getTHMessage: unknown message " ++ show n)
putTHMessage :: THMessage a -> Put
@@ -373,7 +375,7 @@ putTHMessage m = case m of
PutDoc l s -> putWord8 23 >> put l >> put s
GetDoc l -> putWord8 24 >> put l
GetPackageRoot -> putWord8 25
-
+ AddDependentDirectory a -> putWord8 26 >> put a
data EvalOpts = EvalOpts
{ useSandboxThread :: Bool
=====================================
libraries/ghci/GHCi/TH.hs
=====================================
@@ -198,6 +198,7 @@ instance TH.Quasi GHCiQ where
qLocation = fromMaybe noLoc . qsLocation <$> getState
qGetPackageRoot = ghcCmd GetPackageRoot
qAddDependentFile file = ghcCmd (AddDependentFile file)
+ qAddDependentDirectory dir = ghcCmd (AddDependentDirectory dir)
qAddTempFile suffix = ghcCmd (AddTempFile suffix)
qAddTopDecls decls = ghcCmd (AddTopDecls decls)
qAddForeignFilePath lang fp = ghcCmd (AddForeignFilePath lang fp)
=====================================
libraries/template-haskell/Language/Haskell/TH/Syntax.hs
=====================================
@@ -34,6 +34,7 @@ module Language.Haskell.TH.Syntax (
ModName (..),
addCorePlugin,
addDependentFile,
+ addDependentDirectory,
addForeignFile,
addForeignFilePath,
addForeignSource,
=====================================
testsuite/.gitignore
=====================================
@@ -1523,6 +1523,7 @@ mk/ghcconfig*_test___spaces_ghc*.exe.mk
/tests/th/T8633
/tests/th/TH_Depends
/tests/th/TH_Depends_external.txt
+/tests/th/TH_Depends_external/dummy.txt
/tests/th/TH_StringPrimL
/tests/th/TH_import_loop/ModuleA.hi-boot
/tests/th/TH_import_loop/ModuleA.o-boot
=====================================
testsuite/tests/interface-stability/template-haskell-exports.stdout
=====================================
@@ -1717,6 +1717,7 @@ module Language.Haskell.TH.Syntax where
qRunIO :: forall a. GHC.Internal.Types.IO a -> m a
qGetPackageRoot :: m GHC.Internal.IO.FilePath
qAddDependentFile :: GHC.Internal.IO.FilePath -> m ()
+ qAddDependentDirectory :: GHC.Internal.IO.FilePath -> m ()
qAddTempFile :: GHC.Internal.Base.String -> m GHC.Internal.IO.FilePath
qAddTopDecls :: [Dec] -> m ()
qAddForeignFilePath :: ForeignSrcLang -> GHC.Internal.Base.String -> m ()
@@ -1728,7 +1729,7 @@ module Language.Haskell.TH.Syntax where
qExtsEnabled :: m [Extension]
qPutDoc :: DocLoc -> GHC.Internal.Base.String -> m ()
qGetDoc :: DocLoc -> m (GHC.Internal.Maybe.Maybe GHC.Internal.Base.String)
- {-# MINIMAL qNewName, qReport, qRecover, qLookupName, qReify, qReifyFixity, qReifyType, qReifyInstances, qReifyRoles, qReifyAnnotations, qReifyModule, qReifyConStrictness, qLocation, qGetPackageRoot, qAddDependentFile, qAddTempFile, qAddTopDecls, qAddForeignFilePath, qAddModFinalizer, qAddCorePlugin, qGetQ, qPutQ, qIsExtEnabled, qExtsEnabled, qPutDoc, qGetDoc #-}
+ {-# MINIMAL qNewName, qReport, qRecover, qLookupName, qReify, qReifyFixity, qReifyType, qReifyInstances, qReifyRoles, qReifyAnnotations, qReifyModule, qReifyConStrictness, qLocation, qGetPackageRoot, qAddDependentFile, qAddDependentDirectory, qAddTempFile, qAddTopDecls, qAddForeignFilePath, qAddModFinalizer, qAddCorePlugin, qGetQ, qPutQ, qIsExtEnabled, qExtsEnabled, qPutDoc, qGetDoc #-}
type Quote :: (* -> *) -> Constraint
class GHC.Internal.Base.Monad m => Quote m where
newName :: GHC.Internal.Base.String -> m Name
@@ -1781,6 +1782,7 @@ module Language.Haskell.TH.Syntax where
type VarStrictType :: *
type VarStrictType = VarBangType
addCorePlugin :: GHC.Internal.Base.String -> Q ()
+ addDependentDirectory :: GHC.Internal.IO.FilePath -> Q ()
addDependentFile :: GHC.Internal.IO.FilePath -> Q ()
addForeignFile :: ForeignSrcLang -> GHC.Internal.Base.String -> Q ()
addForeignFilePath :: ForeignSrcLang -> GHC.Internal.IO.FilePath -> Q ()
=====================================
testsuite/tests/th/Makefile
=====================================
@@ -43,6 +43,46 @@ TH_Depends:
'$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) --make -v0 TH_Depends
./TH_Depends
+.PHONY: TH_Depends_Dir
+TH_Depends_Dir:
+ rm -rf TRIGGER_RECOMP
+ rm -rf DONT_TRIGGER_RECOMP
+ $(RM) TH_Depends_Dir TH_Depends_Dir.exe
+ $(RM) TH_Depends_Dir.o TH_Depends_Dir.hi
+ $(RM) TH_Depends_Dir_External.o TH_Depends_Dir_External.hi
+
+ mkdir TRIGGER_RECOMP
+ mkdir DONT_TRIGGER_RECOMP
+
+# First build with an empty dependent directory
+ '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) --make -package directory -package template-haskell -v0 TH_Depends_Dir
+ ./TH_Depends_Dir
+
+# Create a file in the dependent directory to trigger recompilation
+ sleep 2
+ echo "dummy" > TRIGGER_RECOMP/dummy.txt
+ '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) --make -package directory -package template-haskell -v0 TH_Depends_Dir
+ ./TH_Depends_Dir
+
+# Remove the file to check that recompilation is triggered
+ sleep 2
+ $(RM) TRIGGER_RECOMP/dummy.txt
+ '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) --make -package directory -package template-haskell -v0 TH_Depends_Dir
+ ./TH_Depends_Dir
+
+# Should not trigger recompilation
+ sleep 2
+ echo "dummy" > DONT_TRIGGER_RECOMP/dummy.txt
+ '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) --make -package directory -package template-haskell -v0 TH_Depends_Dir
+ ./TH_Depends_Dir
+
+# Should trigger a recompilation. Note that we should also see the change
+# in the non-dependent directory now, since it is still rechecked as long
+# as we recompile, it just doesn't *trigger* a recompilation.
+ sleep 2
+ rm -rf TRIGGER_RECOMP
+ '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) --make -package directory -package template-haskell -v0 TH_Depends_Dir
+ ./TH_Depends_Dir
T8333:
'$(TEST_HC)' $(TEST_HC_OPTS_INTERACTIVE) $(ghcThWayFlags) T8333.hs < /dev/null
=====================================
testsuite/tests/th/TH_Depends_Dir.hs
=====================================
@@ -0,0 +1,10 @@
+
+{-# LANGUAGE TemplateHaskell #-}
+
+module Main where
+
+import TH_Depends_Dir_External (checkDirectoryContent)
+
+main :: IO ()
+main = do
+ print $checkDirectoryContent
=====================================
testsuite/tests/th/TH_Depends_Dir.stdout
=====================================
@@ -0,0 +1,5 @@
+"dependent directory is empty, non-dependent directory is empty."
+"dependent directory is non-empty, non-dependent directory is empty."
+"dependent directory is empty, non-dependent directory is empty."
+"dependent directory is empty, non-dependent directory is empty."
+"dependent directory does not exist, non-dependent directory is non-empty."
=====================================
testsuite/tests/th/TH_Depends_Dir_External.hs
=====================================
@@ -0,0 +1,41 @@
+
+module TH_Depends_Dir_External where
+
+import Language.Haskell.TH.Syntax
+import Language.Haskell.TH.Lib
+import System.Directory (listDirectory, doesDirectoryExist)
+
+-- | This function checks the contents of a dependent directory and a non-dependent directory.
+-- So its value will change if the contents of the dependent directory change.
+-- It will not change if the contents of the non-dependent directory change.
+checkDirectoryContent :: Q Exp
+checkDirectoryContent = do
+ let dependentDir = "TRIGGER_RECOMP"
+ let nonDependentDir = "DONT_TRIGGER_RECOMP"
+
+ -- this will error when dependentDir does not exist
+ -- which is the last thing we test for in the Makefile
+ exists <- qRunIO $ doesDirectoryExist dependentDir
+ dep_str <- if exists
+ then do
+ qAddDependentDirectory dependentDir
+ l <- qRunIO $ listDirectory dependentDir
+ case l of
+ [] -> pure "dependent directory is empty"
+ _ -> pure "dependent directory is non-empty"
+ else do
+ -- note that once we are here we no longer depend on the directory
+ -- so no more recompilation will happen.
+ pure "dependent directory does not exist"
+
+ -- Now the part that shouldn't trigger recompilation.
+ -- This is somewhat of a sanity check, if we change nonDependentDir
+ -- and it triggers recompilation, then something must be wrong
+ -- with the recompilation logic.
+ non_deps <- qRunIO $ listDirectory nonDependentDir
+ non_dep_str <- case non_deps of
+ [] -> pure "non-dependent directory is empty."
+ _ -> pure "non-dependent directory is non-empty."
+
+ -- Return the result as a string expression
+ stringE $ dep_str ++ ", " ++ non_dep_str
=====================================
testsuite/tests/th/all.T
=====================================
@@ -214,6 +214,7 @@ test('T5434', [], multimod_compile,
['T5434', '-v0 -Wall ' + config.ghc_th_way_flags])
test('T5508', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques'])
test('TH_Depends', [only_ways(['normal'])], makefile_test, ['TH_Depends'])
+test('TH_Depends_Dir', [only_ways(['normal']), js_skip], makefile_test, ['TH_Depends_Dir'])
test('T5597', [], multimod_compile, ['T5597', '-v0 ' + config.ghc_th_way_flags])
test('T5665', [], multimod_compile, ['T5665', '-v0 ' + config.ghc_th_way_flags])
test('T5700', [], multimod_compile,
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/562ee8a273e58635e59e87f2ebf3f54…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/562ee8a273e58635e59e87f2ebf3f54…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sol/use-logInfo] Refactoring: More consistently use logOutput, logInfo, fatalErrorMsg
by Simon Hengel (@sol) 26 Aug '25
by Simon Hengel (@sol) 26 Aug '25
26 Aug '25
Simon Hengel pushed to branch wip/sol/use-logInfo at Glasgow Haskell Compiler / GHC
Commits:
ab39da10 by Simon Hengel at 2025-08-26T17:25:13+07:00
Refactoring: More consistently use logOutput, logInfo, fatalErrorMsg
- - - - -
7 changed files:
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Stg/Lint.hs
- compiler/GHC/Tc/Utils/Monad.hs
Changes:
=====================================
compiler/GHC/Core/Lint.hs
=====================================
@@ -26,6 +26,7 @@ module GHC.Core.Lint (
-- ** Debug output
EndPassConfig (..),
endPassIO,
+ lintMessage,
displayLintResults, dumpPassResult
) where
@@ -309,11 +310,6 @@ path does not result in allocation in the hot path. This can be surprisingly
impactful. Changing `lint_app` reduced allocations for one test program I was
looking at by ~4%.
-Note [MCInfo for Lint]
-~~~~~~~~~~~~~~~~~~~~~~
-When printing a Lint message, use the MCInfo severity so that the
-message is printed on stderr rather than stdout (#13342).
-
************************************************************************
* *
Beginning and ending passes
@@ -321,6 +317,12 @@ message is printed on stderr rather than stdout (#13342).
************************************************************************
-}
+lintMessage :: Logger -> SDoc -> IO ()
+lintMessage logger =
+ -- Note: Use logInfo when printing a Lint message, so that the message is
+ -- printed on stderr rather than stdout (#13342).
+ logInfo logger . withPprStyle defaultDumpStyle
+
-- | Configuration for boilerplate operations at the end of a
-- compilation pass producing Core.
data EndPassConfig = EndPassConfig
@@ -436,8 +438,7 @@ displayLintResults :: Logger
-> IO ()
displayLintResults logger display_warnings pp_what pp_pgm (warns, errs)
| not (isEmptyBag errs)
- = do { logMsg logger Err.MCInfo noSrcSpan -- See Note [MCInfo for Lint]
- $ withPprStyle defaultDumpStyle
+ = do { lintMessage logger
(vcat [ lint_banner "errors" pp_what, Err.pprMessageBag errs
, text "*** Offending Program ***"
, pp_pgm
@@ -447,8 +448,7 @@ displayLintResults logger display_warnings pp_what pp_pgm (warns, errs)
| not (isEmptyBag warns)
, log_enable_debug (logFlags logger)
, display_warnings
- = logMsg logger Err.MCInfo noSrcSpan -- See Note [MCInfo for Lint]
- $ withPprStyle defaultDumpStyle
+ = lintMessage logger
(lint_banner "warnings" pp_what $$ Err.pprMessageBag (mapBag ($$ blankLine) warns))
| otherwise = return ()
=====================================
compiler/GHC/Driver/CodeOutput.hs
=====================================
@@ -18,6 +18,7 @@ import GHC.Prelude
import GHC.Platform
import GHC.ForeignSrcLang
import GHC.Data.FastString
+import GHC.Core.Lint ( lintMessage )
import GHC.CmmToAsm ( nativeCodeGen )
import GHC.CmmToLlvm ( llvmCodeGen )
@@ -55,7 +56,6 @@ import GHC.Utils.Panic.Plain ( pgmError )
import GHC.Unit
import GHC.Unit.Finder ( mkStubPaths )
-import GHC.Types.SrcLoc
import GHC.Types.CostCentre
import GHC.Types.ForeignStubs
import GHC.Types.Unique.DSM
@@ -109,10 +109,7 @@ codeOutput logger tmpfs llvm_config dflags unit_state this_mod filenm location g
(text "CmmLint"<+>brackets (ppr this_mod))
(const ()) $ do
{ case cmmLint (targetPlatform dflags) cmm of
- Just err -> do { logMsg logger
- MCInfo -- See Note [MCInfo for Lint] in "GHC.Core.Lint"
- noSrcSpan
- $ withPprStyle defaultDumpStyle err
+ Just err -> do { lintMessage logger err
; ghcExit logger 1
}
Nothing -> return ()
=====================================
compiler/GHC/Driver/Pipeline/Execute.hs
=====================================
@@ -1162,7 +1162,7 @@ getHCFilePackages filename =
linkDynLibCheck :: Logger -> TmpFs -> DynFlags -> UnitEnv -> [String] -> [UnitId] -> IO ()
linkDynLibCheck logger tmpfs dflags unit_env o_files dep_units = do
when (haveRtsOptsFlags dflags) $
- logMsg logger MCInfo noSrcSpan
+ logInfo logger
$ withPprStyle defaultUserStyle
(text "Warning: -rtsopts and -with-rtsopts have no effect with -shared." $$
text " Call hs_init_ghc() from your main() function to set these options.")
=====================================
compiler/GHC/Iface/Load.hs
=====================================
@@ -1105,7 +1105,7 @@ For some background on this choice see #15269.
showIface :: Logger -> DynFlags -> UnitState -> NameCache -> FilePath -> IO ()
showIface logger dflags unit_state name_cache filename = do
let profile = targetProfile dflags
- printer = logMsg logger MCOutput noSrcSpan . withPprStyle defaultDumpStyle
+ printer = logOutput logger . withPprStyle defaultDumpStyle
-- skip the hi way check; we don't want to worry about profiled vs.
-- non-profiled interfaces, for example.
=====================================
compiler/GHC/Linker/Loader.hs
=====================================
@@ -507,7 +507,7 @@ classifyLdInput logger platform f
| isObjectFilename platform f = return (Just (Objects [f]))
| isDynLibFilename platform f = return (Just (DLLPath f))
| otherwise = do
- logMsg logger MCInfo noSrcSpan
+ logInfo logger
$ withPprStyle defaultUserStyle
(text ("Warning: ignoring unrecognised input `" ++ f ++ "'"))
return Nothing
=====================================
compiler/GHC/Stg/Lint.hs
=====================================
@@ -104,6 +104,7 @@ import GHC.Stg.Utils
import GHC.Core.DataCon
import GHC.Core ( AltCon(..) )
import GHC.Core.Type
+import GHC.Core.Lint ( lintMessage )
import GHC.Types.Basic ( TopLevelFlag(..), isTopLevel, isMarkedCbv )
import GHC.Types.CostCentre ( isCurrentCCS )
@@ -148,8 +149,7 @@ lintStgTopBindings platform logger diag_opts opts extra_vars this_mod unarised w
Nothing ->
return ()
Just msg -> do
- logMsg logger Err.MCInfo noSrcSpan -- See Note [MCInfo for Lint] in "GHC.Core.Lint"
- $ withPprStyle defaultDumpStyle
+ lintMessage logger
(vcat [ text "*** Stg Lint ErrMsgs: in" <+>
text whodunit <+> text "***",
msg,
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -2343,8 +2343,7 @@ failIfM msg = do
env <- getLclEnv
let full_msg = (if_loc env <> colon) $$ nest 2 msg
logger <- getLogger
- liftIO (logMsg logger MCFatal
- noSrcSpan $ withPprStyle defaultErrStyle full_msg)
+ liftIO $ fatalErrorMsg logger full_msg
failM
--------------------
@@ -2376,10 +2375,7 @@ forkM doc thing_inside
logger <- getLogger
let msg = hang (text "forkM failed:" <+> doc)
2 (text (show exn))
- liftIO $ logMsg logger
- MCFatal
- noSrcSpan
- $ withPprStyle defaultErrStyle msg
+ liftIO $ fatalErrorMsg logger msg
; traceIf (text "} ending fork (badly)" <+> doc)
; pgmError "Cannot continue after interface file error" }
}
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ab39da10eee20aea8b75028fdb09510…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ab39da10eee20aea8b75028fdb09510…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc] Pushed new branch wip/andreask/prof_test_t26056
by Andreas Klebinger (@AndreasK) 26 Aug '25
by Andreas Klebinger (@AndreasK) 26 Aug '25
26 Aug '25
Andreas Klebinger pushed new branch wip/andreask/prof_test_t26056 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/prof_test_t26056
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fendor/remove-stg_stackDecode] Remove stg_decodeStackzh
by Hannes Siebenhandl (@fendor) 26 Aug '25
by Hannes Siebenhandl (@fendor) 26 Aug '25
26 Aug '25
Hannes Siebenhandl pushed to branch wip/fendor/remove-stg_stackDecode at Glasgow Haskell Compiler / GHC
Commits:
5dbb3e43 by fendor at 2025-08-26T11:31:14+02:00
Remove stg_decodeStackzh
- - - - -
5 changed files:
- libraries/ghc-internal/cbits/StackCloningDecoding.cmm
- libraries/ghc-internal/jsbits/base.js
- rts/CloneStack.c
- rts/CloneStack.h
- rts/RtsSymbols.c
Changes:
=====================================
libraries/ghc-internal/cbits/StackCloningDecoding.cmm
=====================================
@@ -17,10 +17,3 @@ stg_sendCloneStackMessagezh (gcptr threadId, gcptr mVarStablePtr) {
return ();
}
-
-stg_decodeStackzh (gcptr stgStack) {
- gcptr stackEntries;
- ("ptr" stackEntries) = ccall decodeClonedStack(MyCapability() "ptr", stgStack "ptr");
-
- return (stackEntries);
-}
=====================================
libraries/ghc-internal/jsbits/base.js
=====================================
@@ -1245,7 +1245,7 @@ function h$mkdir(path, path_offset, mode) {
// It is required by Google Closure Compiler to be at least defined if
// somewhere it is used
-var h$stg_cloneMyStackzh, h$stg_decodeStackzh,
+var h$stg_cloneMyStackzh,
h$advanceStackFrameLocationzh, h$getStackFieldszh, h$getStackClosurezh,
h$getWordzh, h$getStackInfoTableAddrzh, h$getRetFunSmallBitmapzh, h$getRetFunLargeBitmapzh,
h$isArgGenBigRetFunTypezh,
@@ -1253,7 +1253,6 @@ var h$stg_cloneMyStackzh, h$stg_decodeStackzh,
h$getInfoTableAddrszh,
h$getLargeBitmapzh, h$getSmallBitmapzh, h$getBCOLargeBitmapzh
h$stg_cloneMyStackzh
- = h$stg_decodeStackzh
= h$advanceStackFrameLocationzh
= h$getStackFieldszh = h$getStackClosurezh
= h$getWordzh, h$getStackInfoTableAddrzh = h$getRetFunSmallBitmapzh = h$getRetFunLargeBitmapzh
=====================================
rts/CloneStack.c
=====================================
@@ -26,11 +26,6 @@
#include <string.h>
-static StgWord getStackFrameCount(StgStack* stack);
-static StgWord getStackChunkClosureCount(StgStack* stack);
-static StgArrBytes* allocateByteArray(Capability *cap, StgWord bytes);
-static void copyPtrsToArray(StgArrBytes* arr, StgStack* stack);
-
static StgStack* cloneStackChunk(Capability* capability, const StgStack* stack)
{
StgWord spOffset = stack->sp - stack->stack;
@@ -112,94 +107,3 @@ void sendCloneStackMessage(StgTSO *tso STG_UNUSED, HsStablePtr mvar STG_UNUSED)
}
#endif // end !defined(THREADED_RTS)
-
-// Creates a MutableArray# (Haskell representation) that contains a
-// InfoProvEnt* for every stack frame on the given stack. Thus, the size of the
-// array is the count of stack frames.
-// Each InfoProvEnt* is looked up by lookupIPE(). If there's no IPE for a stack
-// frame it's represented by null.
-StgArrBytes* decodeClonedStack(Capability *cap, StgStack* stack) {
- StgWord closureCount = getStackFrameCount(stack);
-
- StgArrBytes* array = allocateByteArray(cap, sizeof(StgInfoTable*) * closureCount);
-
- copyPtrsToArray(array, stack);
-
- return array;
-}
-
-// Count the stack frames that are on the given stack.
-// This is the sum of all stack frames in all stack chunks of this stack.
-StgWord getStackFrameCount(StgStack* stack) {
- StgWord closureCount = 0;
- StgStack *last_stack = stack;
- while (true) {
- closureCount += getStackChunkClosureCount(last_stack);
-
- // check whether the stack ends in an underflow frame
- StgUnderflowFrame *frame = (StgUnderflowFrame *) (last_stack->stack
- + last_stack->stack_size - sizeofW(StgUnderflowFrame));
- if (frame->info == &stg_stack_underflow_frame_d_info
- ||frame->info == &stg_stack_underflow_frame_v16_info
- ||frame->info == &stg_stack_underflow_frame_v32_info
- ||frame->info == &stg_stack_underflow_frame_v64_info) {
- last_stack = frame->next_chunk;
- } else {
- break;
- }
- }
- return closureCount;
-}
-
-StgWord getStackChunkClosureCount(StgStack* stack) {
- StgWord closureCount = 0;
- StgPtr sp = stack->sp;
- StgPtr spBottom = stack->stack + stack->stack_size;
- for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) {
- closureCount++;
- }
-
- return closureCount;
-}
-
-// Allocate and initialize memory for a ByteArray# (Haskell representation).
-StgArrBytes* allocateByteArray(Capability *cap, StgWord bytes) {
- // Idea stolen from PrimOps.cmm:stg_newArrayzh()
- StgWord words = sizeofW(StgArrBytes) + bytes;
-
- StgArrBytes* array = (StgArrBytes*) allocate(cap, words);
-
- SET_HDR(array, &stg_ARR_WORDS_info, CCS_SYSTEM);
- array->bytes = bytes;
- return array;
-}
-
-static void copyPtrsToArray(StgArrBytes* arr, StgStack* stack) {
- StgWord index = 0;
- StgStack *last_stack = stack;
- const StgInfoTable **result = (const StgInfoTable **) arr->payload;
- while (true) {
- StgPtr sp = last_stack->sp;
- StgPtr spBottom = last_stack->stack + last_stack->stack_size;
- for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) {
- const StgInfoTable* infoTable = ((StgClosure *)sp)->header.info;
- result[index] = infoTable;
- index++;
- }
-
- // Ensure that we didn't overflow the result array
- ASSERT(index-1 < arr->bytes / sizeof(StgInfoTable*));
-
- // check whether the stack ends in an underflow frame
- StgUnderflowFrame *frame = (StgUnderflowFrame *) (last_stack->stack
- + last_stack->stack_size - sizeofW(StgUnderflowFrame));
- if (frame->info == &stg_stack_underflow_frame_d_info
- ||frame->info == &stg_stack_underflow_frame_v16_info
- ||frame->info == &stg_stack_underflow_frame_v32_info
- ||frame->info == &stg_stack_underflow_frame_v64_info) {
- last_stack = frame->next_chunk;
- } else {
- break;
- }
- }
-}
=====================================
rts/CloneStack.h
=====================================
@@ -15,8 +15,6 @@ StgStack* cloneStack(Capability* capability, const StgStack* stack);
void sendCloneStackMessage(StgTSO *tso, HsStablePtr mvar);
-StgArrBytes* decodeClonedStack(Capability *cap, StgStack* stack);
-
#include "BeginPrivate.h"
#if defined(THREADED_RTS)
=====================================
rts/RtsSymbols.c
=====================================
@@ -951,7 +951,6 @@ extern char **environ;
SymI_HasProto(lookupIPE) \
SymI_HasProto(sendCloneStackMessage) \
SymI_HasProto(cloneStack) \
- SymI_HasProto(decodeClonedStack) \
SymI_HasProto(stg_newPromptTagzh) \
SymI_HasProto(stg_promptzh) \
SymI_HasProto(stg_control0zh) \
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5dbb3e43e6e4bec76743b2518bb9fd2…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5dbb3e43e6e4bec76743b2518bb9fd2…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/gdc-files] 4 commits: testsuite: Use ghci_ways to set ways in PackedDataCon/UnboxedTuples/UnliftedDataTypeInterp tests
by Matthew Pickering (@mpickering) 26 Aug '25
by Matthew Pickering (@mpickering) 26 Aug '25
26 Aug '25
Matthew Pickering pushed to branch wip/gdc-files at Glasgow Haskell Compiler / GHC
Commits:
1a77d303 by Matthew Pickering at 2025-08-26T09:58:52+01:00
testsuite: Use ghci_ways to set ways in PackedDataCon/UnboxedTuples/UnliftedDataTypeInterp tests
These tests reimplemented the logic from `valid_way` in order to
determine what ways to run. It's easier to use this combination of
`only_ways` and `extra_ways` to only run in GHCi ways and always run in
GHCi ways.
- - - - -
2e87f1d7 by Matthew Pickering at 2025-08-26T09:58:52+01:00
Rename interpreterBackend to bytecodeBackend
- - - - -
f0d63f12 by Cheng Shao at 2025-08-26T09:58:52+01:00
compiler: implement and test bytecode serialization logic
- - - - -
63e8e333 by Matthew Pickering at 2025-08-26T10:25:05+01:00
Add support for generating bytecode objects
This commit adds the `-fwrite-byte-code` option which makes GHC emit a
`.gbc` file which contains a serialised representation of bytecode.
The bytecode can be loaded by the compiler to avoid having to
reinterpret a module when using the bytecode interpreter (for example,
in GHCi).
There are also the new options:
* -gbcdir=<DIR>: Specify the directory to place the gbc files
* -gbcsuf=<suffix>: Specify the suffix for gbc files
The option `-fbyte-code-and-object-code` now implies
`-fwrite-byte-code`.
- - - - -
56 changed files:
- compiler/GHC.hs
- compiler/GHC/Builtin/PrimOps.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- + compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Data/FlatBag.hs
- compiler/GHC/Data/SmallArray.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/Backend/Internal.hs
- compiler/GHC/Driver/Backpack.hs
- + compiler/GHC/Driver/ByteCode.hs
- compiler/GHC/Driver/Config/Finder.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Types/SptEntry.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/Location.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Utils/Binary.hs
- compiler/ghc.cabal.in
- docs/users_guide/phases.rst
- docs/users_guide/separate_compilation.rst
- ghc/Main.hs
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/driver/bytecode-object/A.hs
- + testsuite/tests/driver/bytecode-object/BytecodeMain.hs
- + testsuite/tests/driver/bytecode-object/BytecodeTest.hs
- + testsuite/tests/driver/bytecode-object/Makefile
- + testsuite/tests/driver/bytecode-object/all.T
- + testsuite/tests/driver/bytecode-object/bytecode_object12.stderr
- + testsuite/tests/driver/bytecode-object/bytecode_object13.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object14.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object15.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object16.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object17.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object18.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object19.script
- + testsuite/tests/driver/bytecode-object/bytecode_object19.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object4.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object5.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object6.stdout
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6f56a971247344abcc822509635805…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6f56a971247344abcc822509635805…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: compiler: use zero cost coerce in hoopl setElems/mapToList
by Marge Bot (@marge-bot) 26 Aug '25
by Marge Bot (@marge-bot) 26 Aug '25
26 Aug '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
fd24a551 by Cheng Shao at 2025-08-26T04:39:02-04:00
compiler: use zero cost coerce in hoopl setElems/mapToList
This patch is a follow-up of !14680 and changes setElems/mapToList in
GHC/Cmm/Dataflow/Label to use coerce instead of mapping mkHooplLabel
over the keys.
- - - - -
32f8482d by Ryan Scott at 2025-08-26T04:39:02-04:00
Reject infix promoted data constructors without DataKinds
In the rename, make sure to apply the same `DataKinds` checks for both
`HsTyVar` (for prefix promoted data constructors) and `HsOpTy` (for infix
promoted data constructors) alike.
Fixes #26318.
- - - - -
6 changed files:
- compiler/GHC/Cmm/Dataflow/Label.hs
- compiler/GHC/Rename/HsType.hs
- docs/users_guide/9.16.1-notes.rst
- + testsuite/tests/typecheck/should_fail/T26318.hs
- + testsuite/tests/typecheck/should_fail/T26318.stderr
- testsuite/tests/typecheck/should_fail/all.T
Changes:
=====================================
compiler/GHC/Cmm/Dataflow/Label.hs
=====================================
@@ -83,6 +83,7 @@ import GHC.Data.Word64Map.Strict (Word64Map)
import qualified GHC.Data.Word64Map.Strict as M
import GHC.Data.TrieMap
+import Data.Coerce
import Data.Word (Word64)
@@ -164,7 +165,7 @@ setFoldr k z (LS s) = S.foldr (\v a -> k (mkHooplLabel v) a) z s
{-# INLINE setElems #-}
setElems :: LabelSet -> [Label]
-setElems (LS s) = map mkHooplLabel (S.elems s)
+setElems (LS s) = coerce $ S.elems s
{-# INLINE setFromList #-}
setFromList :: [Label] -> LabelSet
@@ -272,7 +273,7 @@ mapKeys (LM m) = map (mkHooplLabel . fst) (M.toList m)
{-# INLINE mapToList #-}
mapToList :: LabelMap b -> [(Label, b)]
-mapToList (LM m) = [(mkHooplLabel k, v) | (k, v) <- M.toList m]
+mapToList (LM m) = coerce $ M.toList m
{-# INLINE mapFromList #-}
mapFromList :: [(Label, v)] -> LabelMap v
=====================================
compiler/GHC/Rename/HsType.hs
=====================================
@@ -547,15 +547,7 @@ rnHsTyKi env tv@(HsTyVar _ ip (L loc rdr_name))
; this_mod <- getModule
; when (nameIsLocalOrFrom this_mod name) $
checkThLocalTyName name
- ; when (isDataConName name && not (isKindName name)) $
- -- Any use of a promoted data constructor name (that is not
- -- specifically exempted by isKindName) is illegal without the use
- -- of DataKinds. See Note [Checking for DataKinds] in
- -- GHC.Tc.Validity.
- checkDataKinds env tv
- ; when (isDataConName name && not (isPromoted ip)) $
- -- NB: a prefix symbolic operator such as (:) is represented as HsTyVar.
- addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor Prefix name)
+ ; checkPromotedDataConName env tv Prefix ip name
; return (HsTyVar noAnn ip (L loc $ WithUserRdr rdr_name name), unitFV name) }
rnHsTyKi env ty@(HsOpTy _ prom ty1 l_op ty2)
@@ -567,8 +559,7 @@ rnHsTyKi env ty@(HsOpTy _ prom ty1 l_op ty2)
; (ty1', fvs2) <- rnLHsTyKi env ty1
; (ty2', fvs3) <- rnLHsTyKi env ty2
; res_ty <- mkHsOpTyRn prom (fmap (WithUserRdr op_rdr) l_op') fix ty1' ty2'
- ; when (isDataConName op_name && not (isPromoted prom)) $
- addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor Infix op_name)
+ ; checkPromotedDataConName env ty Infix prom op_name
; return (res_ty, plusFVs [fvs1, fvs2, fvs3]) }
rnHsTyKi env (HsParTy _ ty)
@@ -1670,6 +1661,30 @@ checkDataKinds env thing
type_or_kind | isRnKindLevel env = KindLevel
| otherwise = TypeLevel
+-- | If a 'Name' is that of a promoted data constructor, perform various
+-- validity checks on it.
+checkPromotedDataConName ::
+ RnTyKiEnv ->
+ -- | The type that the 'Name' belongs to. This will always be an 'HsTyVar'
+ -- (for 'Prefix' names) or an 'HsOpTy' (for 'Infix' names).
+ HsType GhcPs ->
+ -- | Whether the type is written 'Prefix' or 'Infix'.
+ LexicalFixity ->
+ -- | Whether the name was written with an explicit promotion tick or not.
+ PromotionFlag ->
+ -- | The name to check.
+ Name ->
+ TcM ()
+checkPromotedDataConName env ty fixity ip name
+ = do when (isDataConName name && not (isKindName name)) $
+ -- Any use of a promoted data constructor name (that is not
+ -- specifically exempted by isKindName) is illegal without the use
+ -- of DataKinds. See Note [Checking for DataKinds] in
+ -- GHC.Tc.Validity.
+ checkDataKinds env ty
+ when (isDataConName name && not (isPromoted ip)) $
+ addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor fixity name)
+
warnUnusedForAll :: OutputableBndrFlag flag 'Renamed
=> HsDocContext -> LHsTyVarBndr flag GhcRn -> FreeVars -> TcM ()
warnUnusedForAll doc (L loc tvb) used_names =
=====================================
docs/users_guide/9.16.1-notes.rst
=====================================
@@ -11,6 +11,11 @@ for specific guidance on migrating programs to this release.
Language
~~~~~~~~
+- Fix a bug introduced in GHC 9.10 where GHC would erroneously accept infix uses
+ of promoted data constructors without enabling :extension:`DataKinds`. As a
+ result, you may need to enable :extension:`DataKinds` in code that did not
+ previously require it.
+
Compiler
~~~~~~~~
=====================================
testsuite/tests/typecheck/should_fail/T26318.hs
=====================================
@@ -0,0 +1,15 @@
+{-# LANGUAGE GHC2021 #-}
+{-# LANGUAGE NoDataKinds #-}
+module T26318 where
+
+class C1 l
+instance C1 (x : xs)
+
+class C2 l
+instance C2 (x ': xs)
+
+class C3 l
+instance C3 ((:) x xs)
+
+class C4 l
+instance C4 ('(:) x xs)
=====================================
testsuite/tests/typecheck/should_fail/T26318.stderr
=====================================
@@ -0,0 +1,20 @@
+T26318.hs:6:16: error: [GHC-68567]
+ Illegal type: ‘x : xs’
+ Suggested fix:
+ Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
+
+T26318.hs:9:16: error: [GHC-68567]
+ Illegal type: ‘x ': xs’
+ Suggested fix:
+ Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
+
+T26318.hs:12:14: error: [GHC-68567]
+ Illegal type: ‘(:)’
+ Suggested fix:
+ Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
+
+T26318.hs:15:14: error: [GHC-68567]
+ Illegal type: ‘'(:)’
+ Suggested fix:
+ Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
+
=====================================
testsuite/tests/typecheck/should_fail/all.T
=====================================
@@ -741,3 +741,4 @@ test('T25325', normal, compile_fail, [''])
test('T25004', normal, compile_fail, [''])
test('T25004k', normal, compile_fail, [''])
test('T26004', normal, compile_fail, [''])
+test('T26318', normal, compile_fail, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/04fbc92cfff2e7f2f10e1e26efc754…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/04fbc92cfff2e7f2f10e1e26efc754…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fendor/remove-stg_stackDecode] 3 commits: Move stack decoding logic from ghc-heap to ghc-internal
by Hannes Siebenhandl (@fendor) 26 Aug '25
by Hannes Siebenhandl (@fendor) 26 Aug '25
26 Aug '25
Hannes Siebenhandl pushed to branch wip/fendor/remove-stg_stackDecode at Glasgow Haskell Compiler / GHC
Commits:
9ea55b0d by fendor at 2025-08-26T09:17:04+02:00
Move stack decoding logic from ghc-heap to ghc-internal
The stack decoding logic in `ghc-heap` is more sophisticated than the one
currently employed in `CloneStack`. We want to use the stack decoding
implementation from `ghc-heap` in `base`.
We cannot simply depend on `ghc-heap` in `base` due do bootstrapping
issues.
Thus, we move the code that is necessary to implement stack decoding to
`ghc-internal`. This is the right location, as we don't want to add a
new API to `base`.
Moving the stack decoding logic and re-exposing it in ghc-heap is
insufficient, though, as we have a dependency cycle between.
* ghc-heap depends on stage1:ghc-internal
* stage0:ghc depends on stage0:ghc-heap
To fix this, we remove ghc-heap from the set of `stage0` dependencies.
This is not entirely straight-forward, as a couple of boot dependencies,
such as `ghci` depend on `ghc-heap`.
Luckily, the boot compiler of GHC is now >=9.10, so we can migrate `ghci`
to use `ghc-internal` instead of `ghc-heap`, which already exports the
relevant modules.
However, we cannot 100% remove ghc's dependency on `ghc-heap`, since
when we compile `stage0:ghc`, `stage1:ghc-internal` is not yet
available.
Thus, when we compile with the boot-compiler, we still depend on an
older version of `ghc-heap`, and only use the modules from `ghc-internal`,
if the `ghc-internal` version is recent enough.
-------------------------
Metric Increase:
T24602_perf_size
T25046_perf_size_gzip
T25046_perf_size_unicode
T25046_perf_size_unicode_gzip
size_hello_artifact
size_hello_artifact_gzip
size_hello_unicode
size_hello_unicode_gzip
-------------------------
These metric increases are unfortunate, they are most likely caused by
the larger (literally in terms of lines of code) stack decoder implementation
that are now linked into hello-word binaries.
On linux, it is almost a 10% increase, which is considerable.
- - - - -
fbb7ae1d by fendor at 2025-08-26T09:17:07+02:00
Implement `decode` in terms of `decodeStackWithIpe`
Uses the more efficient stack decoder implementation.
- - - - -
fd1ef199 by fendor at 2025-08-26T09:17:29+02:00
Remove stg_decodeStackzh
- - - - -
52 changed files:
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/ghc.cabal.in
- hadrian/src/Rules/ToolArgs.hs
- hadrian/src/Settings/Default.hs
- libraries/base/src/GHC/Stack/CloneStack.hs
- libraries/ghc-heap/GHC/Exts/Heap/ClosureTypes.hs
- libraries/ghc-heap/GHC/Exts/Heap/Closures.hs
- + libraries/ghc-heap/GHC/Exts/Heap/Constants.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTable.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTable/Types.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hs
- libraries/ghc-heap/GHC/Exts/Heap/ProfInfo/Types.hs
- + libraries/ghc-heap/GHC/Exts/Stack/Constants.hs
- libraries/ghc-heap/GHC/Exts/Stack/Decode.hs
- libraries/ghc-heap/ghc-heap.cabal.in
- libraries/ghc-heap/cbits/HeapPrim.cmm → libraries/ghc-internal/cbits/HeapPrim.cmm
- libraries/ghc-heap/cbits/Stack.cmm → libraries/ghc-internal/cbits/Stack.cmm
- libraries/ghc-internal/cbits/StackCloningDecoding.cmm
- libraries/ghc-heap/cbits/Stack_c.c → libraries/ghc-internal/cbits/Stack_c.c
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/jsbits/base.js
- libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs
- + libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghc-heap/GHC/Exts/Heap/Constants.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/Constants.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTable.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTable/Types.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable/Types.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTableProf.hsc
- + libraries/ghc-internal/src/GHC/Internal/Heap/ProfInfo/Types.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/CloneStack.hs
- libraries/ghc-heap/GHC/Exts/Stack/Constants.hsc → libraries/ghc-internal/src/GHC/Internal/Stack/Constants.hsc
- + libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-heap/tests/stack-annotation/Makefile → libraries/ghc-internal/tests/stack-annotation/Makefile
- libraries/ghc-heap/tests/stack-annotation/TestUtils.hs → libraries/ghc-internal/tests/stack-annotation/TestUtils.hs
- libraries/ghc-heap/tests/stack-annotation/all.T → libraries/ghc-internal/tests/stack-annotation/all.T
- libraries/ghc-heap/tests/stack-annotation/ann_frame001.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame001.hs
- libraries/ghc-heap/tests/stack-annotation/ann_frame001.stdout → libraries/ghc-internal/tests/stack-annotation/ann_frame001.stdout
- libraries/ghc-heap/tests/stack-annotation/ann_frame002.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame002.hs
- libraries/ghc-heap/tests/stack-annotation/ann_frame002.stdout → libraries/ghc-internal/tests/stack-annotation/ann_frame002.stdout
- libraries/ghc-heap/tests/stack-annotation/ann_frame003.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame003.hs
- libraries/ghc-heap/tests/stack-annotation/ann_frame003.stdout → libraries/ghc-internal/tests/stack-annotation/ann_frame003.stdout
- libraries/ghc-heap/tests/stack-annotation/ann_frame004.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame004.hs
- libraries/ghc-heap/tests/stack-annotation/ann_frame004.stdout → libraries/ghc-internal/tests/stack-annotation/ann_frame004.stdout
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/ghci.cabal.in
- rts/CloneStack.c
- rts/CloneStack.h
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b03931447bf30389df4b624826d758…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b03931447bf30389df4b624826d758…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Simon Hengel pushed new branch wip/sol/use-logInfo at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sol/use-logInfo
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Revert "STM: don't create a transaction in the rhs of catchRetry# (#26028)"
by Marge Bot (@marge-bot) 25 Aug '25
by Marge Bot (@marge-bot) 25 Aug '25
25 Aug '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
5b5d9d47 by Ben Gamari at 2025-08-25T14:29:35-04:00
Revert "STM: don't create a transaction in the rhs of catchRetry# (#26028)"
This reverts commit 0a5836891ca29836a24c306d2a364c2e4b5377fd
- - - - -
10f06163 by Cheng Shao at 2025-08-25T14:30:16-04:00
wasm: ensure setKeepCAFs() is called in ghci
This patch is a critical bugfix for #26106, see comment and linked
issue for details.
- - - - -
6dfa209e by Cheng Shao at 2025-08-25T19:02:15-04:00
compiler: use zero cost coerce in hoopl setElems/mapToList
This patch is a follow-up of !14680 and changes setElems/mapToList in
GHC/Cmm/Dataflow/Label to use coerce instead of mapping mkHooplLabel
over the keys.
- - - - -
04fbc92c by Ryan Scott at 2025-08-25T19:02:15-04:00
Reject infix promoted data constructors without DataKinds
In the rename, make sure to apply the same `DataKinds` checks for both
`HsTyVar` (for prefix promoted data constructors) and `HsOpTy` (for infix
promoted data constructors) alike.
Fixes #26318.
- - - - -
13 changed files:
- compiler/GHC/Cmm/Dataflow/Label.hs
- compiler/GHC/Rename/HsType.hs
- docs/users_guide/9.16.1-notes.rst
- rts/PrimOps.cmm
- rts/RaiseAsync.c
- rts/STM.c
- − testsuite/tests/lib/stm/T26028.hs
- − testsuite/tests/lib/stm/T26028.stdout
- − testsuite/tests/lib/stm/all.T
- + testsuite/tests/typecheck/should_fail/T26318.hs
- + testsuite/tests/typecheck/should_fail/T26318.stderr
- testsuite/tests/typecheck/should_fail/all.T
- utils/jsffi/dyld.mjs
Changes:
=====================================
compiler/GHC/Cmm/Dataflow/Label.hs
=====================================
@@ -83,6 +83,7 @@ import GHC.Data.Word64Map.Strict (Word64Map)
import qualified GHC.Data.Word64Map.Strict as M
import GHC.Data.TrieMap
+import Data.Coerce
import Data.Word (Word64)
@@ -164,7 +165,7 @@ setFoldr k z (LS s) = S.foldr (\v a -> k (mkHooplLabel v) a) z s
{-# INLINE setElems #-}
setElems :: LabelSet -> [Label]
-setElems (LS s) = map mkHooplLabel (S.elems s)
+setElems (LS s) = coerce $ S.elems s
{-# INLINE setFromList #-}
setFromList :: [Label] -> LabelSet
@@ -272,7 +273,7 @@ mapKeys (LM m) = map (mkHooplLabel . fst) (M.toList m)
{-# INLINE mapToList #-}
mapToList :: LabelMap b -> [(Label, b)]
-mapToList (LM m) = [(mkHooplLabel k, v) | (k, v) <- M.toList m]
+mapToList (LM m) = coerce $ M.toList m
{-# INLINE mapFromList #-}
mapFromList :: [(Label, v)] -> LabelMap v
=====================================
compiler/GHC/Rename/HsType.hs
=====================================
@@ -547,15 +547,7 @@ rnHsTyKi env tv@(HsTyVar _ ip (L loc rdr_name))
; this_mod <- getModule
; when (nameIsLocalOrFrom this_mod name) $
checkThLocalTyName name
- ; when (isDataConName name && not (isKindName name)) $
- -- Any use of a promoted data constructor name (that is not
- -- specifically exempted by isKindName) is illegal without the use
- -- of DataKinds. See Note [Checking for DataKinds] in
- -- GHC.Tc.Validity.
- checkDataKinds env tv
- ; when (isDataConName name && not (isPromoted ip)) $
- -- NB: a prefix symbolic operator such as (:) is represented as HsTyVar.
- addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor Prefix name)
+ ; checkPromotedDataConName env tv Prefix ip name
; return (HsTyVar noAnn ip (L loc $ WithUserRdr rdr_name name), unitFV name) }
rnHsTyKi env ty@(HsOpTy _ prom ty1 l_op ty2)
@@ -567,8 +559,7 @@ rnHsTyKi env ty@(HsOpTy _ prom ty1 l_op ty2)
; (ty1', fvs2) <- rnLHsTyKi env ty1
; (ty2', fvs3) <- rnLHsTyKi env ty2
; res_ty <- mkHsOpTyRn prom (fmap (WithUserRdr op_rdr) l_op') fix ty1' ty2'
- ; when (isDataConName op_name && not (isPromoted prom)) $
- addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor Infix op_name)
+ ; checkPromotedDataConName env ty Infix prom op_name
; return (res_ty, plusFVs [fvs1, fvs2, fvs3]) }
rnHsTyKi env (HsParTy _ ty)
@@ -1670,6 +1661,30 @@ checkDataKinds env thing
type_or_kind | isRnKindLevel env = KindLevel
| otherwise = TypeLevel
+-- | If a 'Name' is that of a promoted data constructor, perform various
+-- validity checks on it.
+checkPromotedDataConName ::
+ RnTyKiEnv ->
+ -- | The type that the 'Name' belongs to. This will always be an 'HsTyVar'
+ -- (for 'Prefix' names) or an 'HsOpTy' (for 'Infix' names).
+ HsType GhcPs ->
+ -- | Whether the type is written 'Prefix' or 'Infix'.
+ LexicalFixity ->
+ -- | Whether the name was written with an explicit promotion tick or not.
+ PromotionFlag ->
+ -- | The name to check.
+ Name ->
+ TcM ()
+checkPromotedDataConName env ty fixity ip name
+ = do when (isDataConName name && not (isKindName name)) $
+ -- Any use of a promoted data constructor name (that is not
+ -- specifically exempted by isKindName) is illegal without the use
+ -- of DataKinds. See Note [Checking for DataKinds] in
+ -- GHC.Tc.Validity.
+ checkDataKinds env ty
+ when (isDataConName name && not (isPromoted ip)) $
+ addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor fixity name)
+
warnUnusedForAll :: OutputableBndrFlag flag 'Renamed
=> HsDocContext -> LHsTyVarBndr flag GhcRn -> FreeVars -> TcM ()
warnUnusedForAll doc (L loc tvb) used_names =
=====================================
docs/users_guide/9.16.1-notes.rst
=====================================
@@ -11,6 +11,11 @@ for specific guidance on migrating programs to this release.
Language
~~~~~~~~
+- Fix a bug introduced in GHC 9.10 where GHC would erroneously accept infix uses
+ of promoted data constructors without enabling :extension:`DataKinds`. As a
+ result, you may need to enable :extension:`DataKinds` in code that did not
+ previously require it.
+
Compiler
~~~~~~~~
=====================================
rts/PrimOps.cmm
=====================================
@@ -1211,27 +1211,16 @@ INFO_TABLE_RET(stg_catch_retry_frame, CATCH_RETRY_FRAME,
gcptr trec, outer, arg;
trec = StgTSO_trec(CurrentTSO);
- if (running_alt_code != 1) {
- // When exiting the lhs code of catchRetry# lhs rhs, we need to cleanup
- // the nested transaction.
- // See Note [catchRetry# implementation]
- outer = StgTRecHeader_enclosing_trec(trec);
- (r) = ccall stmCommitNestedTransaction(MyCapability() "ptr", trec "ptr");
- if (r != 0) {
- // Succeeded in first branch
- StgTSO_trec(CurrentTSO) = outer;
- return (ret);
- } else {
- // Did not commit: abort and restart.
- StgTSO_trec(CurrentTSO) = outer;
- jump stg_abort();
- }
- }
- else {
- // nothing to do in the rhs code of catchRetry# lhs rhs, it's already
- // using the parent transaction (not a nested one).
- // See Note [catchRetry# implementation]
- return (ret);
+ outer = StgTRecHeader_enclosing_trec(trec);
+ (r) = ccall stmCommitNestedTransaction(MyCapability() "ptr", trec "ptr");
+ if (r != 0) {
+ // Succeeded (either first branch or second branch)
+ StgTSO_trec(CurrentTSO) = outer;
+ return (ret);
+ } else {
+ // Did not commit: abort and restart.
+ StgTSO_trec(CurrentTSO) = outer;
+ jump stg_abort();
}
}
@@ -1464,26 +1453,21 @@ retry_pop_stack:
outer = StgTRecHeader_enclosing_trec(trec);
if (frame_type == CATCH_RETRY_FRAME) {
- // The retry reaches a CATCH_RETRY_FRAME before the ATOMICALLY_FRAME
-
+ // The retry reaches a CATCH_RETRY_FRAME before the atomic frame
+ ASSERT(outer != NO_TREC);
+ // Abort the transaction attempting the current branch
+ ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr");
+ ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr");
if (!StgCatchRetryFrame_running_alt_code(frame) != 0) {
- // Retrying in the lhs of catchRetry# lhs rhs, i.e. in a nested
- // transaction. See Note [catchRetry# implementation]
-
- // check that we have a parent transaction
- ASSERT(outer != NO_TREC);
-
- // Abort the nested transaction
- ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr");
- ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr");
-
- // As we are retrying in the lhs code, we must now try the rhs code
- StgTSO_trec(CurrentTSO) = outer;
+ // Retry in the first branch: try the alternative
+ ("ptr" trec) = ccall stmStartTransaction(MyCapability() "ptr", outer "ptr");
+ StgTSO_trec(CurrentTSO) = trec;
StgCatchRetryFrame_running_alt_code(frame) = 1 :: CInt; // true;
R1 = StgCatchRetryFrame_alt_code(frame);
jump stg_ap_v_fast [R1];
} else {
- // Retry in the rhs code: propagate the retry
+ // Retry in the alternative code: propagate the retry
+ StgTSO_trec(CurrentTSO) = outer;
Sp = Sp + SIZEOF_StgCatchRetryFrame;
goto retry_pop_stack;
}
=====================================
rts/RaiseAsync.c
=====================================
@@ -1043,7 +1043,8 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception,
}
case CATCH_STM_FRAME:
- // CATCH_STM frame within an atomically block: abort the
+ case CATCH_RETRY_FRAME:
+ // CATCH frames within an atomically block: abort the
// inner transaction and continue. Eventually we will
// hit the outer transaction that will get frozen (see
// above).
@@ -1055,40 +1056,14 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception,
{
StgTRecHeader *trec = tso -> trec;
StgTRecHeader *outer = trec -> enclosing_trec;
- debugTraceCap(DEBUG_stm, cap, "raiseAsync: traversing CATCH_STM frame");
+ debugTraceCap(DEBUG_stm, cap,
+ "found atomically block delivering async exception");
stmAbortTransaction(cap, trec);
stmFreeAbortedTRec(cap, trec);
tso -> trec = outer;
break;
};
- case CATCH_RETRY_FRAME:
- // CATCH_RETY frame within an atomically block: if we're executing
- // the lhs code, abort the inner transaction and continue; if we're
- // executing thr rhs, continue (no nested transaction to abort. See
- // Note [catchRetry# implementation]). Eventually we will hit the
- // outer transaction that will get frozen (see above).
- //
- // As for the CATCH_STM_FRAME case above, we do not care
- // whether the transaction is valid or not because its
- // possible validity cannot have caused the exception
- // and will not be visible after the abort.
- {
- if (!((StgCatchRetryFrame *)frame) -> running_alt_code) {
- debugTraceCap(DEBUG_stm, cap, "raiseAsync: traversing CATCH_RETRY frame (lhs)");
- StgTRecHeader *trec = tso -> trec;
- StgTRecHeader *outer = trec -> enclosing_trec;
- stmAbortTransaction(cap, trec);
- stmFreeAbortedTRec(cap, trec);
- tso -> trec = outer;
- }
- else
- {
- debugTraceCap(DEBUG_stm, cap, "raiseAsync: traversing CATCH_RETRY frame (rhs)");
- }
- break;
- };
-
default:
// see Note [Update async masking state on unwind] in Schedule.c
if (*frame == (W_)&stg_unmaskAsyncExceptionszh_ret_info) {
=====================================
rts/STM.c
=====================================
@@ -1505,30 +1505,3 @@ void stmWriteTVar(Capability *cap,
}
/*......................................................................*/
-
-
-
-/*
-
-Note [catchRetry# implementation]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-catchRetry# creates a nested transaction for its lhs:
-- if the lhs transaction succeeds:
- - the lhs transaction is committed
- - its read-variables are merged with those of the parent transaction
- - the rhs code is ignored
-- if the lhs transaction retries:
- - the lhs transaction is aborted
- - its read-variables are merged with those of the parent transaction
- - the rhs code is executed directly in the parent transaction (see #26028).
-
-So note that:
-- lhs code uses a nested transaction
-- rhs code doesn't use a nested transaction
-
-We have to take which case we're in into account (using the running_alt_code
-field of the catchRetry frame) in catchRetry's entry code, in retry#
-implementation, and also when an async exception is received (to cleanup the
-right number of transactions).
-
-*/
=====================================
testsuite/tests/lib/stm/T26028.hs deleted
=====================================
@@ -1,23 +0,0 @@
-module Main where
-
-import GHC.Conc
-
-forever :: IO String
-forever = delay 10 >> forever
-
-terminates :: IO String
-terminates = delay 1 >> pure "terminates"
-
-delay s = threadDelay (1000000 * s)
-
-async :: IO a -> IO (STM a)
-async a = do
- var <- atomically (newTVar Nothing)
- forkIO (a >>= atomically . writeTVar var . Just)
- pure (readTVar var >>= maybe retry pure)
-
-main :: IO ()
-main = do
- x <- mapM async $ terminates : replicate 50000 forever
- r <- atomically (foldr1 orElse x)
- print r
=====================================
testsuite/tests/lib/stm/T26028.stdout deleted
=====================================
@@ -1 +0,0 @@
-"terminates"
=====================================
testsuite/tests/lib/stm/all.T deleted
=====================================
@@ -1 +0,0 @@
-test('T26028', only_ways(['threaded1']), compile_and_run, ['-O2'])
=====================================
testsuite/tests/typecheck/should_fail/T26318.hs
=====================================
@@ -0,0 +1,15 @@
+{-# LANGUAGE GHC2021 #-}
+{-# LANGUAGE NoDataKinds #-}
+module T26318 where
+
+class C1 l
+instance C1 (x : xs)
+
+class C2 l
+instance C2 (x ': xs)
+
+class C3 l
+instance C3 ((:) x xs)
+
+class C4 l
+instance C4 ('(:) x xs)
=====================================
testsuite/tests/typecheck/should_fail/T26318.stderr
=====================================
@@ -0,0 +1,20 @@
+T26318.hs:6:16: error: [GHC-68567]
+ Illegal type: ‘x : xs’
+ Suggested fix:
+ Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
+
+T26318.hs:9:16: error: [GHC-68567]
+ Illegal type: ‘x ': xs’
+ Suggested fix:
+ Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
+
+T26318.hs:12:14: error: [GHC-68567]
+ Illegal type: ‘(:)’
+ Suggested fix:
+ Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
+
+T26318.hs:15:14: error: [GHC-68567]
+ Illegal type: ‘'(:)’
+ Suggested fix:
+ Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
+
=====================================
testsuite/tests/typecheck/should_fail/all.T
=====================================
@@ -741,3 +741,4 @@ test('T25325', normal, compile_fail, [''])
test('T25004', normal, compile_fail, [''])
test('T25004k', normal, compile_fail, [''])
test('T26004', normal, compile_fail, [''])
+test('T26318', normal, compile_fail, [''])
=====================================
utils/jsffi/dyld.mjs
=====================================
@@ -1105,6 +1105,20 @@ class DyLD {
if (/libHSghc-internal-\d+(\.\d+)*/i.test(soname)) {
this.rts_init();
delete this.rts_init;
+
+ // At this point the RTS symbols in linear memory are fixed
+ // and constructors are run, especially the one in JSFFI.c
+ // that does GHC RTS initialization for any code that links
+ // JSFFI.o. Luckily no Haskell computation or gc has taken
+ // place yet, so we must set keepCAFs=1 right now! Otherwise,
+ // any BCO created by later TH splice or ghci expression may
+ // refer to any CAF that's not reachable from GC roots (here
+ // our only entry point is defaultServer) and the CAF could
+ // have been GC'ed! (#26106)
+ //
+ // We call it here instead of in RTS C code, since we only
+ // want keepCAFs=1 for ghci, not user code.
+ this.exportFuncs.setKeepCAFs();
}
init();
}
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b69a9c35fc31b044bcac49ba80bc0f…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b69a9c35fc31b044bcac49ba80bc0f…
You're receiving this email because of your account on gitlab.haskell.org.
1
0