[Git][ghc/ghc][wip/andreask/ghc_par] 70 commits: Add SIMD absolute value on x86 and LLVM
by Andreas Klebinger (@AndreasK) 08 Mar '26
by Andreas Klebinger (@AndreasK) 08 Mar '26
08 Mar '26
Andreas Klebinger pushed to branch wip/andreask/ghc_par at Glasgow Haskell Compiler / GHC
Commits:
476c4cdf by Sean D. Gillespie at 2026-03-02T10:14:37-05:00
Add SIMD absolute value on x86 and LLVM
On x86, absolute value of 32 bits or less is implemented with
PABSB/PABSW/PABSD if SSSE3 is available. Otherwise, there is a fallback
for SSE2. For 64 bit integers it uses VPABSQ, required by AVX-512VL,
with fallbacks for SSE4.2 and SSE2.
There is no dedicated instruction for floating point absolute value on
x86, so it is simulated using bitwise AND.
Absolute value for signed integers and floats are implemented by the
"llvm.abs/llvm.fabs" standard library intrinsics. This implementation
uses MachOps constructors, unlike non-vector floating point absolute
value, which uses CallishMachOps.
- - - - -
709448c0 by Sean D. Gillespie at 2026-03-02T10:14:46-05:00
Add SIMD floating point square root
On x86, this is implemented with the SQRTPS and SQRTPD instructions. On
LLVM, it uses the sqrt library intrinstic.
- - - - -
0deadf66 by Sean D. Gillespie at 2026-03-02T10:14:47-05:00
Improve error message for SIMD on aarch64
When encountering vector literals on aarch64, previously it would
throw:
<no location info>: error:
panic! (the 'impossible' happened)
GHC version 9.15.20251219:
getRegister' (CmmLit:CmmVec):
Now it is more consistent with the other vector operations:
<no location info>: error:
sorry! (unimplemented feature or known bug)
GHC version 9.15.20251219:
SIMD operations on AArch64 currently require the LLVM backend
- - - - -
7d64031b by Vladislav Zavialov at 2026-03-03T11:09:28-05:00
Replace maybeAddSpace with spaceIfSingleQuote
Simplify pretty-printing of HsTypes by using spaceIfSingleQuote.
This allows us to drop the unwieldy lhsTypeHasLeadingPromotionQuote
helper function.
Follow-up to 178c1fd830c78377ef5d338406a41e1d8eb5f0da
- - - - -
598db847 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Correct `hIsReadable` and `hIsWritable` for duplex handles
This contribution implements CLC proposal #371. It changes `hIsReadable`
and `hIsWritable` such that they always throw a respective exception
when encountering a closed or semi-closed handle, not just in the case
of a file handle.
- - - - -
b90201e5 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Document `SemiClosedHandle`
- - - - -
c9df72b5 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Tell users what “semi-closed” means for duplex handles
- - - - -
a8aa1868 by Ilias Tsitsimpis at 2026-03-06T06:26:29-05:00
Fix determinism of linker arguments
The switch from Data.Map to UniqMap in 3b5be05ac29 introduced
non-determinism in the order of packages passed to the linker.
This resulted in non-reproducible builds where the DT_NEEDED entries in
dynamic libraries were ordered differently across builds.
Fix the regression by explicitly sorting the package list derived from
UniqMap.
Fixes #26838
- - - - -
9b64ad3a by Matthew Pickering at 2026-03-06T06:27:16-05:00
determinism: Use a deterministic renaming when writing bytecode files
Now when writing the bytecode file, a counter and substitution are used
to provide deterministic keys to local variables (rather than relying on
uniques). This change ensures that `.gbc` are produced
deterministically.
Fixes #26499
- - - - -
d29800e0 by Teo Camarasu at 2026-03-06T06:28:46-05:00
ghc-internal: delete Version hs-boot loop
Version has a Read instance which needs Unicode but part of the Unicode interface is the unicode version. This is easy to resolve. We simply don't re-export the version from the Unicode module.
Resolves #26940
- - - - -
ad25af90 by Sylvain Henry at 2026-03-06T06:30:33-05:00
Linker: implement support for COMMON symbols (#6107)
Add some support for COMMON symbols. We don't support common symbols
having different sizes where the larger one is allocated after the
smaller one. The linker will fail with an appropriate error message if
it happens.
- - - - -
3b59f158 by Cheng Shao at 2026-03-06T06:31:16-05:00
compiler: fix redundant import of GHC.Hs.Lit
This patch removes a redundant import of `GHC.Hs.Lit` which causes a
ghc build failure with validate flavours when bootstrapping from 9.14.
Fixes #26972.
- - - - -
148d36f3 by Cheng Shao at 2026-03-06T06:32:01-05:00
compiler: avoid unneeded traversals in GHC.Unit.State
Following !15591, this patch avoids unneeded traversals in
`reportCycles`/`reportUnusable` when log verbosity is below given
threshold. Also applies `logVerbAtLeast` when appropriate.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
7e31367c by Cheng Shao at 2026-03-06T06:32:46-05:00
ghc-internal: fix redundant import in GHC.Internal.Event.Windows.ManagedThreadPool
This patch fixes redundant import in
`GHC.Internal.Event.Windows.ManagedThreadPool` that causes a
compilation error when building windows target with validate flavours
and bootstrapping from 9.14. Fixes #26976.
- - - - -
fc8b8e27 by sheaf at 2026-03-06T06:33:28-05:00
System.Info.fullCompilerVersion: add 'since' annot
Fixes #26973
- - - - -
c8238375 by Sylvain Henry at 2026-03-06T06:34:23-05:00
Hadrian: deprecate --bignum and automatically enable +native_bignum for JS
Deprecate --bignum=... to select the bignum backend. It's only used to
select the native backend, and this can be done with the +native_bignum
flavour transformer.
Additionally, we automatically enable +native_bignum for the JS target
because the GMP backend isn't supported.
- - - - -
a3ac7074 by Sylvain Henry at 2026-03-06T06:35:17-05:00
JS: fix putEnum/fromEnum (#24593)
Don't go through Word16 when serializing Enums.
- - - - -
0b36e96c by Andreas Klebinger at 2026-03-06T06:35:58-05:00
Docs: Document -fworker-wrapper-cbv default setting.
Fixes #26841
- - - - -
eca445e7 by mangoiv at 2026-03-07T05:02:36-05:00
drop deb9/10 from CI, add deb13
debian 9 and 10 are end of life, hence we drop them
from our CI, but we do add debian 13. Jobs that were
previously run on 9 and 10 run on 13, too, jobs that
were run on 10, are run on 11 now. Jobs that were
previously run on debian 12 are run on debian 13 now.
This MR also updates hadrian's bootstrap plans for that
reason.
Metric Decrease:
T9872d
- - - - -
12f8b829 by Luite Stegeman at 2026-03-07T05:03:33-05:00
Fix GHC.Internal.Prim haddock
Haddock used to parse Haskell source to generate documentation,
but switched to using interface files instead. This broke documentation
of the GHC.Internal.Prim module, since it's a wired-in interface that
didn't provide a document structure.
This patch adds the missing document structure and updates genprimopcode
to make the section headers and descriptions available.
fixes #26954
- - - - -
f87e5e57 by Luite Stegeman at 2026-03-07T05:03:33-05:00
Remove obsolete --make-haskell-source from genprimopcode
Now that haddock uses the wired-in interface for GHC.Internal.Prim,
the generated Haskell source file is no longer needed. Remove the
--make-haskell-source code generator from genprimopcode and replace
the generated GHC/Internal/Prim.hs with a minimal static source file.
- - - - -
4a7ddc7b by Sylvain Henry at 2026-03-07T05:04:59-05:00
JS: fix linking of exposed but non-preload units (#24886)
Units exposed in the unit database but not explicitly passed on the
command-line were not considered by the JS linker. This isn't an issue
for cabal which passes every unit explicitly but it is an issue when
using GHC directly (cf T24886 test).
- - - - -
689aafcd by mangoiv at 2026-03-07T05:05:52-05:00
testsuite: double foundation timeout multiplier
The runtime timeout in the foundation test was regularly hit by code
generated by the wasm backend - we increase the timout since the high
runtime is expected on the wasm backend for this rather complex test.
Resolves #26938
- - - - -
f41ff125 by Andreas Klebinger at 2026-03-08T20:46:15+00:00
core: add CoreCompUnit newtype
- - - - -
1069971e by Andreas Klebinger at 2026-03-08T20:46:15+00:00
Thread CompilationUnit through compiler.
Instead of a CoreProgram being a list of types it's now a list of compilation units which can be compiled independently.
- - - - -
1a39613e by Andreas Klebinger at 2026-03-08T20:46:15+00:00
Put local rules into compilation unit
- - - - -
7a54d5a9 by Andreas Klebinger at 2026-03-08T20:46:15+00:00
Needs checking: Combine compilation units
When compiling compilation units we must ensure the uniques of top level functions don't clash.
We do so by substituting over them.
- - - - -
81aeb179 by Andreas Klebinger at 2026-03-08T20:46:15+00:00
Maybe deal with glomming
- - - - -
968fddc2 by Andreas Klebinger at 2026-03-08T20:46:15+00:00
Simplify deshadowBinds and make it operate only on binds.
- - - - -
f7a07729 by Andreas Klebinger at 2026-03-08T20:46:15+00:00
Add splitting pass, fix some printing stuff
- - - - -
6d55d9b2 by Andreas Klebinger at 2026-03-08T20:46:15+00:00
Merge/Split core around CSE
- - - - -
a22dc75f by Andreas Klebinger at 2026-03-08T20:46:15+00:00
Enable split core by default
- - - - -
9ef65916 by Andreas Klebinger at 2026-03-08T20:46:15+00:00
More simple plugin test failures
- - - - -
88a4166e by Andreas Klebinger at 2026-03-08T20:46:15+00:00
Better flattening, we should now retain rules
- - - - -
d3645d58 by Andreas Klebinger at 2026-03-08T20:46:15+00:00
Take apart ModGuts for simplifier.
- - - - -
2f324822 by Andreas Klebinger at 2026-03-08T20:46:15+00:00
Don't output compilation unit header if there is only a singly unit
- - - - -
7557d0ae by Andreas Klebinger at 2026-03-08T20:46:16+00:00
suppress unit marker for single unit
- - - - -
60cc0cb7 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Place local-relevant rules in compilation unit
- - - - -
e40644d3 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Fix rule assignment to comp units during occAnalSplit
- - - - -
78e28598 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Dead code analysis now respects unit rules.
- - - - -
9dd7360a by Andreas Klebinger at 2026-03-08T20:46:16+00:00
[Slop] Testsuite: Detect errors that only consist of output reordering
- - - - -
8180a503 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Don't pass full ModGuts to Specialise
- - - - -
f4b81743 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
FloatOut: Use list of binds rather than CoreProgram
- - - - -
e99cf96e by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Include unit rules in simplifier rules env during interations
- - - - -
20ebc186 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
HACK: Always run occAnal after merge to clear up letrecs
- - - - -
817c7fe0 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Lint: Better check for CompUnit invariants
- - - - -
bb7d2545 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Do unit/guts split for specialise
- - - - -
e030e234 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Fiddle with dumps
- - - - -
c95587d2 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Some fixes to specialise.
It now processes units one at a time.
- - - - -
64dfbe8d by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Use all fvs of rules as edges when splitting
- - - - -
5290e4ee by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Handle rules which stop refering to local binders
- - - - -
26081203 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Refactored splitting.
Broke it into parts to make it easier to understand.
- - - - -
d5f94558 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Make sure CoreMerge reattaches unstable unfoldings
- - - - -
169bb1bc by Andreas Klebinger at 2026-03-08T20:46:16+00:00
testsuite: Ignore compilation unit header in output comparison
- - - - -
e61ea11e by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Some useless checks
- - - - -
b7d21061 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Possible fixes to simplifier/specConstr from the bot
- - - - -
e7f43bf9 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
merge/split around late cse
- - - - -
312195a1 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Make CSE work independently over compilation units
- - - - -
d3941fe3 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Keep rules attributed to units in the simplifier
- - - - -
096254a9 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Some vibe based fixes
- - - - -
6b71cac7 by Andreas Klebinger at 2026-03-08T20:46:16+00:00
Fix an issue with dependency analysis with boot files
- - - - -
7aecf8f3 by Andreas Klebinger at 2026-03-08T22:45:49+00:00
Don't split if module has a boot file to avoid expensive dep analysis.
- - - - -
fe27f5b3 by Andreas Klebinger at 2026-03-08T23:23:01+00:00
Allow split cse with -fsplit-cse
- - - - -
d2a79687 by Andreas Klebinger at 2026-03-08T23:28:25+00:00
Dubious: Stop looking at imported unfoldings
- - - - -
15a8a1ca by Andreas Klebinger at 2026-03-08T23:58:28+00:00
Increase unit independent processing
- - - - -
7810af67 by Andreas Klebinger at 2026-03-09T00:10:22+00:00
AI tuning of Split.hs
- - - - -
33ec5869 by Andreas Klebinger at 2026-03-09T00:19:45+00:00
Do some stuff in parallel
- - - - -
8d7e76b6 by Andreas Klebinger at 2026-03-09T00:40:02+00:00
par WW
- - - - -
e62e43fe by Andreas Klebinger at 2026-03-09T01:25:13+00:00
Make simp more per unit
- - - - -
a1fc3262 by Andreas Klebinger at 2026-03-09T01:37:57+00:00
Make things parallel
- - - - -
168 changed files:
- .gitlab-ci.yml
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- compiler/GHC.hs
- compiler/GHC/Builtin/PrimOps.hs
- compiler/GHC/Builtin/Utils.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core.hs-boot
- + compiler/GHC/Core/FVs.hs-boot
- compiler/GHC/Core/LateCC.hs
- compiler/GHC/Core/LateCC/Utils.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/CSE.hs
- compiler/GHC/Core/Opt/CallArity.hs
- compiler/GHC/Core/Opt/CallerCC.hs
- + compiler/GHC/Core/Opt/CompUnit.hs
- compiler/GHC/Core/Opt/CprAnal.hs
- compiler/GHC/Core/Opt/DmdAnal.hs
- compiler/GHC/Core/Opt/Exitify.hs
- compiler/GHC/Core/Opt/FloatIn.hs
- compiler/GHC/Core/Opt/FloatOut.hs
- compiler/GHC/Core/Opt/LiberateCase.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- + compiler/GHC/Core/Opt/OccurAnal.hs-boot
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/Pipeline/Types.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Simplify.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/Specialise.hs
- + compiler/GHC/Core/Opt/Split.hs
- compiler/GHC/Core/Opt/StaticArgs.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Subst.hs
- + compiler/GHC/Core/Subst.hs-boot
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg.hs
- compiler/GHC/CoreToStg/AddImplicitBinds.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Runtime/Interpreter/JS.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/Object.hs
- compiler/GHC/StgToJS/Prim.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Utils/Error.hs
- compiler/ghc.cabal.in
- docs/users_guide/using-optimisation.rst
- hadrian/README.md
- hadrian/bootstrap/generate_bootstrap_plans
- hadrian/bootstrap/plan-9_10_1.json
- hadrian/bootstrap/plan-9_10_2.json
- + hadrian/bootstrap/plan-9_10_3.json
- hadrian/bootstrap/plan-bootstrap-9_10_1.json
- hadrian/bootstrap/plan-bootstrap-9_10_2.json
- + hadrian/bootstrap/plan-bootstrap-9_10_3.json
- hadrian/src/CommandLine.hs
- hadrian/src/Main.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/GenPrimopCode.hs
- libraries/base/changelog.md
- libraries/base/src/GHC/Base.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/GHC/Unicode.hs
- libraries/base/src/System/Info.hs
- libraries/ghc-experimental/CHANGELOG.md
- libraries/ghc-internal/ghc-internal.cabal.in
- − libraries/ghc-internal/src/GHC/Internal/Data/Version.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/ManagedThreadPool.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Text.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Types.hs
- + libraries/ghc-internal/src/GHC/Internal/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Version.hs
- libraries/ghc-internal/tools/ucd2haskell/exe/UCD2Haskell/ModuleGenerators.hs
- rts/Linker.c
- rts/LinkerInternals.h
- rts/linker/Elf.c
- rts/linker/MachO.c
- rts/linker/PEi386.c
- testsuite/driver/junit.py
- testsuite/driver/perf_notes.py
- testsuite/driver/runtests.py
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/ghci/should_run/all.T
- 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/javascript/T24886.hs
- + testsuite/tests/javascript/T24886.stderr
- + testsuite/tests/javascript/T24886.stdout
- testsuite/tests/javascript/all.T
- testsuite/tests/numeric/should_run/all.T
- testsuite/tests/overloadedrecflds/should_compile/all.T
- testsuite/tests/overloadedrecflds/should_run/all.T
- testsuite/tests/plugins/HomePackagePlugin.hs
- testsuite/tests/plugins/all.T
- testsuite/tests/plugins/annotation-plugin/SayAnnNames.hs
- testsuite/tests/plugins/late-plugin/LatePlugin.hs
- testsuite/tests/plugins/simple-plugin/Simple/Plugin.hs
- testsuite/tests/plugins/simple-plugin/Simple/ReplacePlugin.hs
- testsuite/tests/pmcheck/should_compile/T11303.hs
- testsuite/tests/quasiquotation/qq005/test.T
- testsuite/tests/quasiquotation/qq006/test.T
- testsuite/tests/rts/linker/Makefile
- + testsuite/tests/rts/linker/T6107.hs
- + testsuite/tests/rts/linker/T6107.stdout
- + testsuite/tests/rts/linker/T6107_sym1.s
- + testsuite/tests/rts/linker/T6107_sym2.s
- testsuite/tests/rts/linker/all.T
- testsuite/tests/saks/should_compile/all.T
- testsuite/tests/showIface/all.T
- testsuite/tests/simd/should_run/doublex2_arith.hs
- testsuite/tests/simd/should_run/doublex2_arith.stdout
- testsuite/tests/simd/should_run/doublex2_arith_baseline.hs
- testsuite/tests/simd/should_run/doublex2_arith_baseline.stdout
- testsuite/tests/simd/should_run/floatx4_arith.hs
- testsuite/tests/simd/should_run/floatx4_arith.stdout
- testsuite/tests/simd/should_run/floatx4_arith_baseline.hs
- testsuite/tests/simd/should_run/floatx4_arith_baseline.stdout
- testsuite/tests/simd/should_run/int16x8_arith.hs
- testsuite/tests/simd/should_run/int16x8_arith.stdout
- testsuite/tests/simd/should_run/int16x8_arith_baseline.hs
- testsuite/tests/simd/should_run/int16x8_arith_baseline.stdout
- testsuite/tests/simd/should_run/int32x4_arith.hs
- testsuite/tests/simd/should_run/int32x4_arith.stdout
- testsuite/tests/simd/should_run/int32x4_arith_baseline.hs
- testsuite/tests/simd/should_run/int32x4_arith_baseline.stdout
- testsuite/tests/simd/should_run/int64x2_arith.hs
- testsuite/tests/simd/should_run/int64x2_arith.stdout
- testsuite/tests/simd/should_run/int64x2_arith_baseline.hs
- testsuite/tests/simd/should_run/int64x2_arith_baseline.stdout
- testsuite/tests/simd/should_run/int8x16_arith.hs
- testsuite/tests/simd/should_run/int8x16_arith.stdout
- testsuite/tests/simd/should_run/int8x16_arith_baseline.hs
- testsuite/tests/simd/should_run/int8x16_arith_baseline.stdout
- testsuite/tests/th/all.T
- testsuite/tests/vdq-rta/should_compile/all.T
- utils/genprimopcode/Main.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ec5be4425b0ee8c19f4a817d36236b…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ec5be4425b0ee8c19f4a817d36236b…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sjakobi/T2057] Add regression test for #2057
by Simon Jakobi (@sjakobi2) 08 Mar '26
by Simon Jakobi (@sjakobi2) 08 Mar '26
08 Mar '26
Simon Jakobi pushed to branch wip/sjakobi/T2057 at Glasgow Haskell Compiler / GHC
Commits:
14fa99ca by Simon Jakobi at 2026-03-09T02:12:44+01:00
Add regression test for #2057
Test that GHC stops after an interface-file error instead of
continuing into the linker.
The test constructs a stale package dependency on purpose. `pkgB` is compiled
against one version of package `A`, then the same unit id is replaced by an
incompatible build of `A`. When `Main` imports `B`, GHC has to read `B.hi`,
finds an unfolding that still mentions the old `A`, and should fail while
loading interfaces.
Closes #2057.
Assisted-by: Codex
- - - - -
12 changed files:
- + testsuite/tests/driver/T2057/.gitignore
- + testsuite/tests/driver/T2057/Makefile
- + testsuite/tests/driver/T2057/README.md
- + testsuite/tests/driver/T2057/T2057.stderr
- + testsuite/tests/driver/T2057/all.T
- + testsuite/tests/driver/T2057/app/Main.hs
- + testsuite/tests/driver/T2057/pkgA1/A.hs
- + testsuite/tests/driver/T2057/pkgA1/pkg.conf.in
- + testsuite/tests/driver/T2057/pkgA2/A.hs
- + testsuite/tests/driver/T2057/pkgA2/pkg.conf.in
- + testsuite/tests/driver/T2057/pkgB/B.hs
- + testsuite/tests/driver/T2057/pkgB/pkg.conf.in
Changes:
=====================================
testsuite/tests/driver/T2057/.gitignore
=====================================
@@ -0,0 +1 @@
+work/
=====================================
testsuite/tests/driver/T2057/Makefile
=====================================
@@ -0,0 +1,59 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+WORK = work
+PKGDB = $(WORK)/pkgdb
+PKGA1 = $(WORK)/pkgA1
+PKGA2 = $(WORK)/pkgA2
+PKGB = $(WORK)/pkgB
+APP = $(WORK)/app
+OUT = $(WORK)/T2057.out
+BASE_ID := $(shell "$(GHC_PKG)" field base id --simple-output)
+
+.PHONY: T2057 clean
+
+clean:
+ rm -rf $(WORK)
+
+# Dependency graph:
+# pkgB is built against pkgA1, where A exports f1.
+# We then rebuild the same installed unit id (pkgA) from the pkgA2 sources,
+# where A instead exports f2. Reading B.hi therefore finds an unfolding for g
+# that still refers to f1, and compiling Main against pkgB should stop at the
+# interface error.
+T2057: clean
+
+ # Create an isolated package DB and output directories for the repro.
+ mkdir -p '$(PKGA1)' '$(PKGA2)' '$(PKGB)' '$(APP)'
+ '$(GHC_PKG)' init '$(PKGDB)'
+
+ # Build and register pkgA1, the original version of A.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -this-unit-id pkgA -O -c pkgA1/A.hs -outputdir '$(PKGA1)'
+ ar q '$(PKGA1)/libHSpkgA.a' '$(PKGA1)/A.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA1/pkg.conf.in >'$(WORK)/pkgA1.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgA1.conf' >/dev/null
+
+ # Build and register pkgB against pkgA1 so B.hi records the unfolding of g = f1.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -package pkgA1 -this-unit-id pkgB -O -c pkgB/B.hs \
+ -outputdir '$(PKGB)'
+ ar q '$(PKGB)/libHSpkgB.a' '$(PKGB)/B.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgB/pkg.conf.in >'$(WORK)/pkgB.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgB.conf' >/dev/null
+
+ # Rebuild the same installed unit id from pkgA2, replacing f1 with f2.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -this-unit-id pkgA -O -c pkgA2/A.hs -outputdir '$(PKGA2)'
+ ar q '$(PKGA2)/libHSpkgA.a' '$(PKGA2)/A.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA2/pkg.conf.in >'$(WORK)/pkgA2.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' update '$(WORK)/pkgA2.conf' >/dev/null
+
+ # Compiling Main against pkgB should now fail while loading the stale B.hi.
+ ! '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make app/Main.hs \
+ -O -fforce-recomp -package-db '$(PKGDB)' -package pkgB \
+ >'$(OUT)' 2>&1 || { echo "expected compilation failure" >&2; exit 1; }
+
+ # Strip the absolute test directory prefix before comparing against T2057.stderr.
+ sed "s#$(CURDIR)/##g" '$(OUT)' >&2
=====================================
testsuite/tests/driver/T2057/README.md
=====================================
@@ -0,0 +1,8 @@
+`T2057` checks that GHC stops after an interface-file error instead of
+continuing into the linker.
+
+The test constructs a stale package dependency on purpose. `pkgB` is compiled
+against one version of package `A`, then the same unit id is replaced by an
+incompatible build of `A`. When `Main` imports `B`, GHC has to read `B.hi`,
+finds an unfolding that still mentions the old `A`, and should fail while
+loading interfaces.
=====================================
testsuite/tests/driver/T2057/T2057.stderr
=====================================
@@ -0,0 +1,9 @@
+work/pkgB/B.hi
+Declaration for g
+Unfolding of g:
+ f1 ErrorWithoutFlag
+ Can't find interface-file declaration for variable f1
+ Probable cause: bug in .hi-boot file, or inconsistent .hi file
+ Use -ddump-if-trace to get an idea of which file caused the error
+<no location info>:
+ Cannot continue after interface file error
=====================================
testsuite/tests/driver/T2057/all.T
=====================================
@@ -0,0 +1,11 @@
+test(
+ 'T2057',
+ [ extra_files(['pkgA1', 'pkgA2', 'pkgB', 'app', 'README.md'])
+ , when(opsys('mingw32'), skip)
+ , js_skip
+ , wasm_skip
+ , ignore_stdout
+ ],
+ makefile_test,
+ []
+)
=====================================
testsuite/tests/driver/T2057/app/Main.hs
=====================================
@@ -0,0 +1,6 @@
+module Main where
+
+import B
+
+main :: IO ()
+main = print (g 41)
=====================================
testsuite/tests/driver/T2057/pkgA1/A.hs
=====================================
@@ -0,0 +1,5 @@
+module A (f1) where
+
+{-# INLINE f1 #-}
+f1 :: Int -> Int
+f1 x = x + 1
=====================================
testsuite/tests/driver/T2057/pkgA1/pkg.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgA1
+version: 1.0
+id: pkgA
+key: pkgA
+exposed: True
+exposed-modules: A
+import-dirs: ${pkgroot}/pkgA1
+library-dirs: ${pkgroot}/pkgA1
+dynamic-library-dirs: ${pkgroot}/pkgA1
+hs-libraries: HSpkgA
+depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgA2/A.hs
=====================================
@@ -0,0 +1,4 @@
+module A (f2) where
+
+f2 :: Int -> Int
+f2 x = x + 100
=====================================
testsuite/tests/driver/T2057/pkgA2/pkg.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgA1
+version: 1.0
+id: pkgA
+key: pkgA
+exposed: True
+exposed-modules: A
+import-dirs: ${pkgroot}/pkgA2
+library-dirs: ${pkgroot}/pkgA2
+dynamic-library-dirs: ${pkgroot}/pkgA2
+hs-libraries: HSpkgA
+depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgB/B.hs
=====================================
@@ -0,0 +1,7 @@
+module B (g) where
+
+import A
+
+{-# INLINE g #-}
+g :: Int -> Int
+g x = f1 x
=====================================
testsuite/tests/driver/T2057/pkgB/pkg.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgB
+version: 1.0
+id: pkgB
+key: pkgB
+exposed: True
+exposed-modules: B
+import-dirs: ${pkgroot}/pkgB
+library-dirs: ${pkgroot}/pkgB
+dynamic-library-dirs: ${pkgroot}/pkgB
+hs-libraries: HSpkgB
+depends: pkgA @BASE_ID@
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14fa99cac2deab1e84de199ba2a570c…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14fa99cac2deab1e84de199ba2a570c…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sjakobi/T2057] Add regression test for #2057
by Simon Jakobi (@sjakobi2) 08 Mar '26
by Simon Jakobi (@sjakobi2) 08 Mar '26
08 Mar '26
Simon Jakobi pushed to branch wip/sjakobi/T2057 at Glasgow Haskell Compiler / GHC
Commits:
e894fe64 by Simon Jakobi at 2026-03-09T02:03:45+01:00
Add regression test for #2057
Test that GHC stops after an interface-file error instead of
continuing into the linker.
The test constructs a stale package dependency on purpose. `pkgB` is compiled
against one version of package `A`, then the same unit id is replaced by an
incompatible build of `A`. When `Main` imports `B`, GHC has to read `B.hi`,
finds an unfolding that still mentions the old `A`, and should fail while
loading interfaces.
Closes #2057.
Assisted-by: Codex
- - - - -
12 changed files:
- + testsuite/tests/driver/T2057/.gitignore
- + testsuite/tests/driver/T2057/Makefile
- + testsuite/tests/driver/T2057/README.md
- + testsuite/tests/driver/T2057/T2057.stderr
- + testsuite/tests/driver/T2057/all.T
- + testsuite/tests/driver/T2057/app/Main.hs
- + testsuite/tests/driver/T2057/pkgA1.conf.in
- + testsuite/tests/driver/T2057/pkgA1/A.hs
- + testsuite/tests/driver/T2057/pkgA2.conf.in
- + testsuite/tests/driver/T2057/pkgA2/A.hs
- + testsuite/tests/driver/T2057/pkgB.conf.in
- + testsuite/tests/driver/T2057/pkgB/B.hs
Changes:
=====================================
testsuite/tests/driver/T2057/.gitignore
=====================================
@@ -0,0 +1 @@
+work/
=====================================
testsuite/tests/driver/T2057/Makefile
=====================================
@@ -0,0 +1,59 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+WORK = work
+PKGDB = $(WORK)/pkgdb
+PKGA1 = $(WORK)/pkgA1
+PKGA2 = $(WORK)/pkgA2
+PKGB = $(WORK)/pkgB
+APP = $(WORK)/app
+OUT = $(WORK)/T2057.out
+BASE_ID := $(shell "$(GHC_PKG)" field base id --simple-output)
+
+.PHONY: T2057 clean
+
+clean:
+ rm -rf $(WORK)
+
+# Dependency graph:
+# pkgB is built against pkgA1, where A exports f1.
+# We then rebuild the same installed unit id (pkgA) from the pkgA2 sources,
+# where A instead exports f2. Reading B.hi therefore finds an unfolding for g
+# that still refers to f1, and compiling Main against pkgB should stop at the
+# interface error.
+T2057: clean
+
+ # Create an isolated package DB and output directories for the repro.
+ mkdir -p '$(PKGA1)' '$(PKGA2)' '$(PKGB)' '$(APP)'
+ '$(GHC_PKG)' init '$(PKGDB)'
+
+ # Build and register pkgA1, the original version of A.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -this-unit-id pkgA -O -c pkgA1/A.hs -outputdir '$(PKGA1)'
+ ar q '$(PKGA1)/libHSpkgA.a' '$(PKGA1)/A.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA1.conf.in >'$(WORK)/pkgA1.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgA1.conf' >/dev/null
+
+ # Build and register pkgB against pkgA1 so B.hi records the unfolding of g = f1.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -package pkgA1 -this-unit-id pkgB -O -c pkgB/B.hs \
+ -outputdir '$(PKGB)'
+ ar q '$(PKGB)/libHSpkgB.a' '$(PKGB)/B.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgB.conf.in >'$(WORK)/pkgB.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgB.conf' >/dev/null
+
+ # Rebuild the same installed unit id from pkgA2, replacing f1 with f2.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -this-unit-id pkgA -O -c pkgA2/A.hs -outputdir '$(PKGA2)'
+ ar q '$(PKGA2)/libHSpkgA.a' '$(PKGA2)/A.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA2.conf.in >'$(WORK)/pkgA2.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' update '$(WORK)/pkgA2.conf' >/dev/null
+
+ # Compiling Main against pkgB should now fail while loading the stale B.hi.
+ ! '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make app/Main.hs \
+ -O -fforce-recomp -package-db '$(PKGDB)' -package pkgB \
+ >'$(OUT)' 2>&1 || { echo "expected compilation failure" >&2; exit 1; }
+
+ # Strip the absolute test directory prefix before comparing against T2057.stderr.
+ sed "s#$(CURDIR)/##g" '$(OUT)' >&2
=====================================
testsuite/tests/driver/T2057/README.md
=====================================
@@ -0,0 +1,8 @@
+`T2057` checks that GHC stops after an interface-file error instead of
+continuing into the linker.
+
+The test constructs a stale package dependency on purpose. `pkgB` is compiled
+against one version of package `A`, then the same unit id is replaced by an
+incompatible build of `A`. When `Main` imports `B`, GHC has to read `B.hi`,
+finds an unfolding that still mentions the old `A`, and should fail while
+loading interfaces.
=====================================
testsuite/tests/driver/T2057/T2057.stderr
=====================================
@@ -0,0 +1,9 @@
+work/pkgB/B.hi
+Declaration for g
+Unfolding of g:
+ f1 ErrorWithoutFlag
+ Can't find interface-file declaration for variable f1
+ Probable cause: bug in .hi-boot file, or inconsistent .hi file
+ Use -ddump-if-trace to get an idea of which file caused the error
+<no location info>:
+ Cannot continue after interface file error
=====================================
testsuite/tests/driver/T2057/all.T
=====================================
@@ -0,0 +1,11 @@
+test(
+ 'T2057',
+ [ extra_files(['pkgA1', 'pkgA2', 'pkgB', 'app', 'README.md', 'pkgA1.conf.in', 'pkgA2.conf.in', 'pkgB.conf.in'])
+ , when(opsys('mingw32'), skip)
+ , js_skip
+ , wasm_skip
+ , ignore_stdout
+ ],
+ makefile_test,
+ []
+)
=====================================
testsuite/tests/driver/T2057/app/Main.hs
=====================================
@@ -0,0 +1,6 @@
+module Main where
+
+import B
+
+main :: IO ()
+main = print (g 41)
=====================================
testsuite/tests/driver/T2057/pkgA1.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgA1
+version: 1.0
+id: pkgA
+key: pkgA
+exposed: True
+exposed-modules: A
+import-dirs: ${pkgroot}/pkgA1
+library-dirs: ${pkgroot}/pkgA1
+dynamic-library-dirs: ${pkgroot}/pkgA1
+hs-libraries: HSpkgA
+depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgA1/A.hs
=====================================
@@ -0,0 +1,5 @@
+module A (f1) where
+
+{-# INLINE f1 #-}
+f1 :: Int -> Int
+f1 x = x + 1
=====================================
testsuite/tests/driver/T2057/pkgA2.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgA1
+version: 1.0
+id: pkgA
+key: pkgA
+exposed: True
+exposed-modules: A
+import-dirs: ${pkgroot}/pkgA2
+library-dirs: ${pkgroot}/pkgA2
+dynamic-library-dirs: ${pkgroot}/pkgA2
+hs-libraries: HSpkgA
+depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgA2/A.hs
=====================================
@@ -0,0 +1,4 @@
+module A (f2) where
+
+f2 :: Int -> Int
+f2 x = x + 100
=====================================
testsuite/tests/driver/T2057/pkgB.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgB
+version: 1.0
+id: pkgB
+key: pkgB
+exposed: True
+exposed-modules: B
+import-dirs: ${pkgroot}/pkgB
+library-dirs: ${pkgroot}/pkgB
+dynamic-library-dirs: ${pkgroot}/pkgB
+hs-libraries: HSpkgB
+depends: pkgA @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgB/B.hs
=====================================
@@ -0,0 +1,7 @@
+module B (g) where
+
+import A
+
+{-# INLINE g #-}
+g :: Int -> Int
+g x = f1 x
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e894fe640926df1ae83c757dd4a821f…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e894fe640926df1ae83c757dd4a821f…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sjakobi/T2057] Add regression test for #2057
by Simon Jakobi (@sjakobi2) 08 Mar '26
by Simon Jakobi (@sjakobi2) 08 Mar '26
08 Mar '26
Simon Jakobi pushed to branch wip/sjakobi/T2057 at Glasgow Haskell Compiler / GHC
Commits:
40c3c3c3 by Simon Jakobi at 2026-03-09T02:01:42+01:00
Add regression test for #2057
Closes #2057.
Assisted-by: Codex
- - - - -
12 changed files:
- + testsuite/tests/driver/T2057/.gitignore
- + testsuite/tests/driver/T2057/Makefile
- + testsuite/tests/driver/T2057/README.md
- + testsuite/tests/driver/T2057/T2057.stderr
- + testsuite/tests/driver/T2057/all.T
- + testsuite/tests/driver/T2057/app/Main.hs
- + testsuite/tests/driver/T2057/pkgA1.conf.in
- + testsuite/tests/driver/T2057/pkgA1/A.hs
- + testsuite/tests/driver/T2057/pkgA2.conf.in
- + testsuite/tests/driver/T2057/pkgA2/A.hs
- + testsuite/tests/driver/T2057/pkgB.conf.in
- + testsuite/tests/driver/T2057/pkgB/B.hs
Changes:
=====================================
testsuite/tests/driver/T2057/.gitignore
=====================================
@@ -0,0 +1 @@
+work/
=====================================
testsuite/tests/driver/T2057/Makefile
=====================================
@@ -0,0 +1,59 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+WORK = work
+PKGDB = $(WORK)/pkgdb
+PKGA1 = $(WORK)/pkgA1
+PKGA2 = $(WORK)/pkgA2
+PKGB = $(WORK)/pkgB
+APP = $(WORK)/app
+OUT = $(WORK)/T2057.out
+BASE_ID := $(shell "$(GHC_PKG)" field base id --simple-output)
+
+.PHONY: T2057 clean
+
+clean:
+ rm -rf $(WORK)
+
+# Dependency graph:
+# pkgB is built against pkgA1, where A exports f1.
+# We then rebuild the same installed unit id (pkgA) from the pkgA2 sources,
+# where A instead exports f2. Reading B.hi therefore finds an unfolding for g
+# that still refers to f1, and compiling Main against pkgB should stop at the
+# interface error.
+T2057: clean
+
+ # Create an isolated package DB and output directories for the repro.
+ mkdir -p '$(PKGA1)' '$(PKGA2)' '$(PKGB)' '$(APP)'
+ '$(GHC_PKG)' init '$(PKGDB)'
+
+ # Build and register pkgA1, the original version of A.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -this-unit-id pkgA -O -c pkgA1/A.hs -outputdir '$(PKGA1)'
+ ar q '$(PKGA1)/libHSpkgA.a' '$(PKGA1)/A.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA1.conf.in >'$(WORK)/pkgA1.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgA1.conf' >/dev/null
+
+ # Build and register pkgB against pkgA1 so B.hi records the unfolding of g = f1.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -package pkgA1 -this-unit-id pkgB -O -c pkgB/B.hs \
+ -outputdir '$(PKGB)'
+ ar q '$(PKGB)/libHSpkgB.a' '$(PKGB)/B.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgB.conf.in >'$(WORK)/pkgB.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgB.conf' >/dev/null
+
+ # Rebuild the same installed unit id from pkgA2, replacing f1 with f2.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -this-unit-id pkgA -O -c pkgA2/A.hs -outputdir '$(PKGA2)'
+ ar q '$(PKGA2)/libHSpkgA.a' '$(PKGA2)/A.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA2.conf.in >'$(WORK)/pkgA2.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' update '$(WORK)/pkgA2.conf' >/dev/null
+
+ # Compiling Main against pkgB should now fail while loading the stale B.hi.
+ ! '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make app/Main.hs \
+ -O -fforce-recomp -package-db '$(PKGDB)' -package pkgB \
+ >'$(OUT)' 2>&1 || { echo "expected compilation failure" >&2; exit 1; }
+
+ # Strip the absolute test directory prefix before comparing against T2057.stderr.
+ sed "s#$(CURDIR)/##g" '$(OUT)' >&2
=====================================
testsuite/tests/driver/T2057/README.md
=====================================
@@ -0,0 +1,8 @@
+`T2057` checks that GHC stops after an interface-file error instead of
+continuing into the linker.
+
+The test constructs a stale package dependency on purpose. `pkgB` is compiled
+against one version of package `A`, then the same unit id is replaced by an
+incompatible build of `A`. When `Main` imports `B`, GHC has to read `B.hi`,
+finds an unfolding that still mentions the old `A`, and should fail while
+loading interfaces.
=====================================
testsuite/tests/driver/T2057/T2057.stderr
=====================================
@@ -0,0 +1,9 @@
+work/pkgB/B.hi
+Declaration for g
+Unfolding of g:
+ f1 ErrorWithoutFlag
+ Can't find interface-file declaration for variable f1
+ Probable cause: bug in .hi-boot file, or inconsistent .hi file
+ Use -ddump-if-trace to get an idea of which file caused the error
+<no location info>:
+ Cannot continue after interface file error
=====================================
testsuite/tests/driver/T2057/all.T
=====================================
@@ -0,0 +1,11 @@
+test(
+ 'T2057',
+ [ extra_files(['pkgA1', 'pkgA2', 'pkgB', 'app', 'README.md', 'pkgA1.conf.in', 'pkgA2.conf.in', 'pkgB.conf.in'])
+ , when(opsys('mingw32'), skip)
+ , js_skip
+ , wasm_skip
+ , ignore_stdout
+ ],
+ makefile_test,
+ []
+)
=====================================
testsuite/tests/driver/T2057/app/Main.hs
=====================================
@@ -0,0 +1,6 @@
+module Main where
+
+import B
+
+main :: IO ()
+main = print (g 41)
=====================================
testsuite/tests/driver/T2057/pkgA1.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgA1
+version: 1.0
+id: pkgA
+key: pkgA
+exposed: True
+exposed-modules: A
+import-dirs: ${pkgroot}/pkgA1
+library-dirs: ${pkgroot}/pkgA1
+dynamic-library-dirs: ${pkgroot}/pkgA1
+hs-libraries: HSpkgA
+depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgA1/A.hs
=====================================
@@ -0,0 +1,5 @@
+module A (f1) where
+
+{-# INLINE f1 #-}
+f1 :: Int -> Int
+f1 x = x + 1
=====================================
testsuite/tests/driver/T2057/pkgA2.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgA1
+version: 1.0
+id: pkgA
+key: pkgA
+exposed: True
+exposed-modules: A
+import-dirs: ${pkgroot}/pkgA2
+library-dirs: ${pkgroot}/pkgA2
+dynamic-library-dirs: ${pkgroot}/pkgA2
+hs-libraries: HSpkgA
+depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgA2/A.hs
=====================================
@@ -0,0 +1,4 @@
+module A (f2) where
+
+f2 :: Int -> Int
+f2 x = x + 100
=====================================
testsuite/tests/driver/T2057/pkgB.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgB
+version: 1.0
+id: pkgB
+key: pkgB
+exposed: True
+exposed-modules: B
+import-dirs: ${pkgroot}/pkgB
+library-dirs: ${pkgroot}/pkgB
+dynamic-library-dirs: ${pkgroot}/pkgB
+hs-libraries: HSpkgB
+depends: pkgA @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgB/B.hs
=====================================
@@ -0,0 +1,7 @@
+module B (g) where
+
+import A
+
+{-# INLINE g #-}
+g :: Int -> Int
+g x = f1 x
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/40c3c3c3f69fd83c87a9a0a5bde3a18…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/40c3c3c3f69fd83c87a9a0a5bde3a18…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
08 Mar '26
Simon Jakobi pushed to branch wip/sjakobi/T2057 at Glasgow Haskell Compiler / GHC
Commits:
a2a79272 by Simon Jakobi at 2026-03-09T01:48:39+01:00
Shorten README
- - - - -
359dd071 by Simon Jakobi at 2026-03-09T01:51:06+01:00
Wibbles
- - - - -
2 changed files:
- testsuite/tests/driver/T2057/Makefile
- testsuite/tests/driver/T2057/README.md
Changes:
=====================================
testsuite/tests/driver/T2057/Makefile
=====================================
@@ -19,29 +19,41 @@ clean:
# Dependency graph:
# pkgB is built against pkgA1, where A exports f1.
# We then rebuild the same installed unit id (pkgA-1) from the pkgA2 sources,
-# where A instead exports f2.
-# Reading B.hi therefore finds an unfolding for g that still refers to f1,
-# and compiling Main against pkgB should stop at the interface error.
+# where A instead exports f2. Reading B.hi therefore finds an unfolding for g
+# that still refers to f1, and compiling Main against pkgB should stop at the
+# interface error.
T2057: clean
+
# Create an isolated package DB and output directories for the repro.
mkdir -p '$(PKGA1)' '$(PKGA2)' '$(PKGB)' '$(APP)'
'$(GHC_PKG)' init '$(PKGDB)'
+
# Build and register pkgA1, the original version of A.
- '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id pkgA-1 -O -c pkgA1/A.hs -outputdir '$(PKGA1)'
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -this-unit-id pkgA-1 -O -c pkgA1/A.hs -outputdir '$(PKGA1)'
ar q '$(PKGA1)/libHSpkgA-1.a' '$(PKGA1)/A.o' >/dev/null 2>&1
sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA1.conf.in >'$(WORK)/pkgA1.conf'
'$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgA1.conf' >/dev/null
+
# Build and register pkgB against pkgA1 so B.hi records the unfolding of g = f1.
- '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -package pkgA1 -this-unit-id pkgB-1 -O -c pkgB/B.hs -outputdir '$(PKGB)'
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -package pkgA1 -this-unit-id pkgB-1 -O -c pkgB/B.hs \
+ -outputdir '$(PKGB)'
ar q '$(PKGB)/libHSpkgB-1.a' '$(PKGB)/B.o' >/dev/null 2>&1
sed "s|@BASE_ID@|$(BASE_ID)|g" pkgB.conf.in >'$(WORK)/pkgB.conf'
'$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgB.conf' >/dev/null
+
# Rebuild the same installed unit id from pkgA2, replacing f1 with f2.
- '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id pkgA-1 -O -c pkgA2/A.hs -outputdir '$(PKGA2)'
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' \
+ -this-unit-id pkgA-1 -O -c pkgA2/A.hs -outputdir '$(PKGA2)'
ar q '$(PKGA2)/libHSpkgA-1.a' '$(PKGA2)/A.o' >/dev/null 2>&1
sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA2.conf.in >'$(WORK)/pkgA2.conf'
'$(GHC_PKG)' --package-db '$(PKGDB)' update '$(WORK)/pkgA2.conf' >/dev/null
+
# Compiling Main against pkgB should now fail while loading the stale B.hi.
- ! '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make app/Main.hs -O -fforce-recomp -package-db '$(PKGDB)' -package pkgB >'$(OUT)' 2>&1 || { echo "expected compilation failure" >&2; exit 1; }
+ ! '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make app/Main.hs \
+ -O -fforce-recomp -package-db '$(PKGDB)' -package pkgB \
+ >'$(OUT)' 2>&1 || { echo "expected compilation failure" >&2; exit 1; }
+
# Strip the absolute test directory prefix before comparing against T2057.stderr.
sed "s#$(CURDIR)/##g" '$(OUT)' >&2
=====================================
testsuite/tests/driver/T2057/README.md
=====================================
@@ -6,8 +6,3 @@ against one version of package `A`, then the same unit id is replaced by an
incompatible build of `A`. When `Main` imports `B`, GHC has to read `B.hi`,
finds an unfolding that still mentions the old `A`, and should fail while
loading interfaces.
-
-The golden [`T2057.stderr`](T2057.stderr) captures the expected behaviour on a
-fixed compiler: report the missing declaration from the stale interface and
-then abort with `Cannot continue after interface file error`. Any linker output
-would be a regression.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/89ed54d65e87dda1c86b0165988115…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/89ed54d65e87dda1c86b0165988115…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sjakobi/T2057] 5 commits: testsuite: simplify T2057 Makefile recipe
by Simon Jakobi (@sjakobi2) 08 Mar '26
by Simon Jakobi (@sjakobi2) 08 Mar '26
08 Mar '26
Simon Jakobi pushed to branch wip/sjakobi/T2057 at Glasgow Haskell Compiler / GHC
Commits:
500dde14 by Simon Jakobi at 2026-03-09T01:18:11+01:00
testsuite: simplify T2057 Makefile recipe
- - - - -
2dea8545 by Simon Jakobi at 2026-03-09T01:22:05+01:00
testsuite: document T2057 Makefile steps
Assisted-by: Codex
- - - - -
f6f4894e by Simon Jakobi at 2026-03-09T01:32:25+01:00
testsuite: rename T2057 pkgA unit id
- - - - -
4f3ec643 by Simon Jakobi at 2026-03-09T01:33:36+01:00
testsuite: simplify T2057 binding names
- - - - -
89ed54d6 by Simon Jakobi at 2026-03-09T01:41:47+01:00
testsuite: document T2057 test setup
- - - - -
11 changed files:
- testsuite/tests/driver/T2057/Makefile
- + testsuite/tests/driver/T2057/README.md
- testsuite/tests/driver/T2057/T2057.stderr
- testsuite/tests/driver/T2057/all.T
- testsuite/tests/driver/T2057/app/Main.hs
- testsuite/tests/driver/T2057/pkgA1.conf.in
- testsuite/tests/driver/T2057/pkgA1/A.hs
- testsuite/tests/driver/T2057/pkgA2.conf.in
- testsuite/tests/driver/T2057/pkgA2/A.hs
- testsuite/tests/driver/T2057/pkgB.conf.in
- testsuite/tests/driver/T2057/pkgB/B.hs
Changes:
=====================================
testsuite/tests/driver/T2057/Makefile
=====================================
@@ -9,6 +9,7 @@ PKGA2 = $(WORK)/pkgA2
PKGB = $(WORK)/pkgB
APP = $(WORK)/app
OUT = $(WORK)/T2057.out
+BASE_ID := $(shell "$(GHC_PKG)" field base id --simple-output)
.PHONY: T2057 clean
@@ -16,31 +17,31 @@ clean:
rm -rf $(WORK)
# Dependency graph:
-# pkgB is built against pkgA1.
-# We then rebuild the same installed unit id (pkgA1-1) from the pkgA2 sources,
-# leaving pkgB with a stale unfolding that still references pkgA1's old API.
-# Compiling Main against pkgB should therefore stop at the interface error.
+# pkgB is built against pkgA1, where A exports f1.
+# We then rebuild the same installed unit id (pkgA-1) from the pkgA2 sources,
+# where A instead exports f2.
+# Reading B.hi therefore finds an unfolding for g that still refers to f1,
+# and compiling Main against pkgB should stop at the interface error.
T2057: clean
- @set -eu; \
- BASE_ID=`'$(GHC_PKG)' field base id --simple-output`; \
- mkdir -p '$(PKGA1)' '$(PKGA2)' '$(PKGB)' '$(APP)'; \
- '$(GHC_PKG)' init '$(PKGDB)'; \
- '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id pkgA1-1 -O -c pkgA1/A.hs -outputdir '$(PKGA1)'; \
- ar q '$(PKGA1)/libHSpkgA1-1.a' '$(PKGA1)/A.o' >/dev/null 2>&1; \
- sed "s|@BASE_ID@|$$BASE_ID|g" pkgA1.conf.in >'$(WORK)/pkgA1.conf'; \
- '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgA1.conf' >/dev/null; \
- '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -package pkgA1 -this-unit-id pkgB-1 -O -c pkgB/B.hs -outputdir '$(PKGB)'; \
- ar q '$(PKGB)/libHSpkgB-1.a' '$(PKGB)/B.o' >/dev/null 2>&1; \
- sed "s|@BASE_ID@|$$BASE_ID|g" pkgB.conf.in >'$(WORK)/pkgB.conf'; \
- '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgB.conf' >/dev/null; \
- '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id pkgA1-1 -O -c pkgA2/A.hs -outputdir '$(PKGA2)'; \
- ar q '$(PKGA2)/libHSpkgA1-1.a' '$(PKGA2)/A.o' >/dev/null 2>&1; \
- sed "s|@BASE_ID@|$$BASE_ID|g" pkgA2.conf.in >'$(WORK)/pkgA2.conf'; \
- '$(GHC_PKG)' --package-db '$(PKGDB)' update '$(WORK)/pkgA2.conf' >/dev/null; \
- status=0; \
- '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make app/Main.hs -O -fforce-recomp -package-db '$(PKGDB)' -package pkgB >'$(OUT)' 2>&1 || status=$$?; \
- if [ $$status -eq 0 ]; then \
- echo "expected compilation failure" >&2; \
- exit 1; \
- fi; \
- sed "s#`pwd`/##g" '$(OUT)' >&2
+ # Create an isolated package DB and output directories for the repro.
+ mkdir -p '$(PKGA1)' '$(PKGA2)' '$(PKGB)' '$(APP)'
+ '$(GHC_PKG)' init '$(PKGDB)'
+ # Build and register pkgA1, the original version of A.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id pkgA-1 -O -c pkgA1/A.hs -outputdir '$(PKGA1)'
+ ar q '$(PKGA1)/libHSpkgA-1.a' '$(PKGA1)/A.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA1.conf.in >'$(WORK)/pkgA1.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgA1.conf' >/dev/null
+ # Build and register pkgB against pkgA1 so B.hi records the unfolding of g = f1.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -package pkgA1 -this-unit-id pkgB-1 -O -c pkgB/B.hs -outputdir '$(PKGB)'
+ ar q '$(PKGB)/libHSpkgB-1.a' '$(PKGB)/B.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgB.conf.in >'$(WORK)/pkgB.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgB.conf' >/dev/null
+ # Rebuild the same installed unit id from pkgA2, replacing f1 with f2.
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id pkgA-1 -O -c pkgA2/A.hs -outputdir '$(PKGA2)'
+ ar q '$(PKGA2)/libHSpkgA-1.a' '$(PKGA2)/A.o' >/dev/null 2>&1
+ sed "s|@BASE_ID@|$(BASE_ID)|g" pkgA2.conf.in >'$(WORK)/pkgA2.conf'
+ '$(GHC_PKG)' --package-db '$(PKGDB)' update '$(WORK)/pkgA2.conf' >/dev/null
+ # Compiling Main against pkgB should now fail while loading the stale B.hi.
+ ! '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make app/Main.hs -O -fforce-recomp -package-db '$(PKGDB)' -package pkgB >'$(OUT)' 2>&1 || { echo "expected compilation failure" >&2; exit 1; }
+ # Strip the absolute test directory prefix before comparing against T2057.stderr.
+ sed "s#$(CURDIR)/##g" '$(OUT)' >&2
=====================================
testsuite/tests/driver/T2057/README.md
=====================================
@@ -0,0 +1,13 @@
+`T2057` checks that GHC stops after an interface-file error instead of
+continuing into the linker.
+
+The test constructs a stale package dependency on purpose. `pkgB` is compiled
+against one version of package `A`, then the same unit id is replaced by an
+incompatible build of `A`. When `Main` imports `B`, GHC has to read `B.hi`,
+finds an unfolding that still mentions the old `A`, and should fail while
+loading interfaces.
+
+The golden [`T2057.stderr`](T2057.stderr) captures the expected behaviour on a
+fixed compiler: report the missing declaration from the stale interface and
+then abort with `Cannot continue after interface file error`. Any linker output
+would be a regression.
=====================================
testsuite/tests/driver/T2057/T2057.stderr
=====================================
@@ -1,8 +1,8 @@
work/pkgB/B.hi
-Declaration for saved
-Unfolding of saved:
- staleDependencyBinding ErrorWithoutFlag
- Can't find interface-file declaration for variable staleDependencyBinding
+Declaration for g
+Unfolding of g:
+ f1 ErrorWithoutFlag
+ Can't find interface-file declaration for variable f1
Probable cause: bug in .hi-boot file, or inconsistent .hi file
Use -ddump-if-trace to get an idea of which file caused the error
<no location info>:
=====================================
testsuite/tests/driver/T2057/all.T
=====================================
@@ -1,6 +1,6 @@
test(
'T2057',
- [ extra_files(['pkgA1', 'pkgA2', 'pkgB', 'app', 'pkgA1.conf.in', 'pkgA2.conf.in', 'pkgB.conf.in'])
+ [ extra_files(['pkgA1', 'pkgA2', 'pkgB', 'app', 'README.md', 'pkgA1.conf.in', 'pkgA2.conf.in', 'pkgB.conf.in'])
, when(opsys('mingw32'), skip)
, js_skip
, wasm_skip
=====================================
testsuite/tests/driver/T2057/app/Main.hs
=====================================
@@ -3,4 +3,4 @@ module Main where
import B
main :: IO ()
-main = print (saved 41)
+main = print (g 41)
=====================================
testsuite/tests/driver/T2057/pkgA1.conf.in
=====================================
@@ -1,11 +1,11 @@
name: pkgA1
version: 1.0
-id: pkgA1-1
-key: pkgA1-1
+id: pkgA-1
+key: pkgA-1
exposed: True
exposed-modules: A
import-dirs: ${pkgroot}/pkgA1
library-dirs: ${pkgroot}/pkgA1
dynamic-library-dirs: ${pkgroot}/pkgA1
-hs-libraries: HSpkgA1-1
+hs-libraries: HSpkgA-1
depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgA1/A.hs
=====================================
@@ -1,5 +1,5 @@
-module A (staleDependencyBinding) where
+module A (f1) where
-{-# INLINE staleDependencyBinding #-}
-staleDependencyBinding :: Int -> Int
-staleDependencyBinding x = x + 1
+{-# INLINE f1 #-}
+f1 :: Int -> Int
+f1 x = x + 1
=====================================
testsuite/tests/driver/T2057/pkgA2.conf.in
=====================================
@@ -1,11 +1,11 @@
name: pkgA1
version: 1.0
-id: pkgA1-1
-key: pkgA1-1
+id: pkgA-1
+key: pkgA-1
exposed: True
exposed-modules: A
import-dirs: ${pkgroot}/pkgA2
library-dirs: ${pkgroot}/pkgA2
dynamic-library-dirs: ${pkgroot}/pkgA2
-hs-libraries: HSpkgA1-1
+hs-libraries: HSpkgA-1
depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgA2/A.hs
=====================================
@@ -1,4 +1,4 @@
-module A (replacementBinding) where
+module A (f2) where
-replacementBinding :: Int -> Int
-replacementBinding x = x + 100
+f2 :: Int -> Int
+f2 x = x + 100
=====================================
testsuite/tests/driver/T2057/pkgB.conf.in
=====================================
@@ -8,4 +8,4 @@ import-dirs: ${pkgroot}/pkgB
library-dirs: ${pkgroot}/pkgB
dynamic-library-dirs: ${pkgroot}/pkgB
hs-libraries: HSpkgB-1
-depends: pkgA1-1 @BASE_ID@
+depends: pkgA-1 @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgB/B.hs
=====================================
@@ -1,7 +1,7 @@
-module B (saved) where
+module B (g) where
import A
-{-# INLINE saved #-}
-saved :: Int -> Int
-saved x = staleDependencyBinding x
+{-# INLINE g #-}
+g :: Int -> Int
+g x = f1 x
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/13ab42f498dbac37cb568b0ad63b76…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/13ab42f498dbac37cb568b0ad63b76…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sjakobi/T2057] 2 commits: testsuite: refactor T2057 test layout
by Simon Jakobi (@sjakobi2) 08 Mar '26
by Simon Jakobi (@sjakobi2) 08 Mar '26
08 Mar '26
Simon Jakobi pushed to branch wip/sjakobi/T2057 at Glasgow Haskell Compiler / GHC
Commits:
3180476f by Simon Jakobi at 2026-03-09T01:02:03+01:00
testsuite: refactor T2057 test layout
- - - - -
13ab42f4 by Simon Jakobi at 2026-03-09T01:02:21+01:00
testsuite: drop T2057 generated work files
- - - - -
14 changed files:
- + testsuite/tests/driver/T2057/.gitignore
- testsuite/tests/driver/T2057/Makefile
- testsuite/tests/driver/T2057/T2057.stderr
- testsuite/tests/driver/T2057/all.T
- testsuite/tests/driver/T2057/src/app/Main.hs → testsuite/tests/driver/T2057/app/Main.hs
- − testsuite/tests/driver/T2057/basepkg-v1.conf.in
- − testsuite/tests/driver/T2057/basepkg-v2.conf.in
- − testsuite/tests/driver/T2057/dep.conf.in
- + testsuite/tests/driver/T2057/pkgA1.conf.in
- testsuite/tests/driver/T2057/src/base-v1/Base.hs → testsuite/tests/driver/T2057/pkgA1/A.hs
- + testsuite/tests/driver/T2057/pkgA2.conf.in
- testsuite/tests/driver/T2057/src/base-v2/Base.hs → testsuite/tests/driver/T2057/pkgA2/A.hs
- + testsuite/tests/driver/T2057/pkgB.conf.in
- testsuite/tests/driver/T2057/src/dep/Dep.hs → testsuite/tests/driver/T2057/pkgB/B.hs
Changes:
=====================================
testsuite/tests/driver/T2057/.gitignore
=====================================
@@ -0,0 +1 @@
+work/
=====================================
testsuite/tests/driver/T2057/Makefile
=====================================
@@ -4,9 +4,9 @@ include $(TOP)/mk/test.mk
WORK = work
PKGDB = $(WORK)/pkgdb
-BASE_V1 = $(WORK)/basepkg-v1
-BASE_V2 = $(WORK)/basepkg-v2
-DEP = $(WORK)/dep
+PKGA1 = $(WORK)/pkgA1
+PKGA2 = $(WORK)/pkgA2
+PKGB = $(WORK)/pkgB
APP = $(WORK)/app
OUT = $(WORK)/T2057.out
@@ -15,29 +15,30 @@ OUT = $(WORK)/T2057.out
clean:
rm -rf $(WORK)
+# Dependency graph:
+# pkgB is built against pkgA1.
+# We then rebuild the same installed unit id (pkgA1-1) from the pkgA2 sources,
+# leaving pkgB with a stale unfolding that still references pkgA1's old API.
+# Compiling Main against pkgB should therefore stop at the interface error.
T2057: clean
@set -eu; \
BASE_ID=`'$(GHC_PKG)' field base id --simple-output`; \
- mkdir -p '$(BASE_V1)' '$(BASE_V2)' '$(DEP)' '$(APP)'; \
+ mkdir -p '$(PKGA1)' '$(PKGA2)' '$(PKGB)' '$(APP)'; \
'$(GHC_PKG)' init '$(PKGDB)'; \
- cp src/base-v1/Base.hs '$(BASE_V1)/Base.hs'; \
- cp src/base-v2/Base.hs '$(BASE_V2)/Base.hs'; \
- cp src/dep/Dep.hs '$(DEP)/Dep.hs'; \
- cp src/app/Main.hs '$(APP)/Main.hs'; \
- '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id basepkg-1 -O -c '$(BASE_V1)/Base.hs' -outputdir '$(BASE_V1)'; \
- ar q '$(BASE_V1)/libHSbasepkg-1.a' '$(BASE_V1)/Base.o' >/dev/null 2>&1; \
- sed "s|@BASE_ID@|$$BASE_ID|g" basepkg-v1.conf.in >'$(WORK)/basepkg-v1.conf'; \
- '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/basepkg-v1.conf' >/dev/null; \
- '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -package basepkg -this-unit-id dep-1 -O -c '$(DEP)/Dep.hs' -outputdir '$(DEP)'; \
- ar q '$(DEP)/libHSdep-1.a' '$(DEP)/Dep.o' >/dev/null 2>&1; \
- sed "s|@BASE_ID@|$$BASE_ID|g" dep.conf.in >'$(WORK)/dep.conf'; \
- '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/dep.conf' >/dev/null; \
- '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id basepkg-1 -O -c '$(BASE_V2)/Base.hs' -outputdir '$(BASE_V2)'; \
- ar q '$(BASE_V2)/libHSbasepkg-1.a' '$(BASE_V2)/Base.o' >/dev/null 2>&1; \
- sed "s|@BASE_ID@|$$BASE_ID|g" basepkg-v2.conf.in >'$(WORK)/basepkg-v2.conf'; \
- '$(GHC_PKG)' --package-db '$(PKGDB)' update '$(WORK)/basepkg-v2.conf' >/dev/null; \
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id pkgA1-1 -O -c pkgA1/A.hs -outputdir '$(PKGA1)'; \
+ ar q '$(PKGA1)/libHSpkgA1-1.a' '$(PKGA1)/A.o' >/dev/null 2>&1; \
+ sed "s|@BASE_ID@|$$BASE_ID|g" pkgA1.conf.in >'$(WORK)/pkgA1.conf'; \
+ '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgA1.conf' >/dev/null; \
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -package pkgA1 -this-unit-id pkgB-1 -O -c pkgB/B.hs -outputdir '$(PKGB)'; \
+ ar q '$(PKGB)/libHSpkgB-1.a' '$(PKGB)/B.o' >/dev/null 2>&1; \
+ sed "s|@BASE_ID@|$$BASE_ID|g" pkgB.conf.in >'$(WORK)/pkgB.conf'; \
+ '$(GHC_PKG)' --package-db '$(PKGDB)' register '$(WORK)/pkgB.conf' >/dev/null; \
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -package-db '$(PKGDB)' -this-unit-id pkgA1-1 -O -c pkgA2/A.hs -outputdir '$(PKGA2)'; \
+ ar q '$(PKGA2)/libHSpkgA1-1.a' '$(PKGA2)/A.o' >/dev/null 2>&1; \
+ sed "s|@BASE_ID@|$$BASE_ID|g" pkgA2.conf.in >'$(WORK)/pkgA2.conf'; \
+ '$(GHC_PKG)' --package-db '$(PKGDB)' update '$(WORK)/pkgA2.conf' >/dev/null; \
status=0; \
- '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make '$(APP)/Main.hs' -O -fforce-recomp -package-db '$(PKGDB)' -package dep >'$(OUT)' 2>&1 || status=$$?; \
+ '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make app/Main.hs -O -fforce-recomp -package-db '$(PKGDB)' -package pkgB >'$(OUT)' 2>&1 || status=$$?; \
if [ $$status -eq 0 ]; then \
echo "expected compilation failure" >&2; \
exit 1; \
=====================================
testsuite/tests/driver/T2057/T2057.stderr
=====================================
@@ -1,4 +1,4 @@
-work/dep/Dep.hi
+work/pkgB/B.hi
Declaration for saved
Unfolding of saved:
staleDependencyBinding ErrorWithoutFlag
=====================================
testsuite/tests/driver/T2057/all.T
=====================================
@@ -1,6 +1,6 @@
test(
'T2057',
- [ extra_files(['src', 'basepkg-v1.conf.in', 'basepkg-v2.conf.in', 'dep.conf.in'])
+ [ extra_files(['pkgA1', 'pkgA2', 'pkgB', 'app', 'pkgA1.conf.in', 'pkgA2.conf.in', 'pkgB.conf.in'])
, when(opsys('mingw32'), skip)
, js_skip
, wasm_skip
=====================================
testsuite/tests/driver/T2057/src/app/Main.hs → testsuite/tests/driver/T2057/app/Main.hs
=====================================
@@ -1,6 +1,6 @@
module Main where
-import Dep
+import B
main :: IO ()
main = print (saved 41)
=====================================
testsuite/tests/driver/T2057/basepkg-v1.conf.in deleted
=====================================
@@ -1,11 +0,0 @@
-name: basepkg
-version: 1.0
-id: basepkg-1
-key: basepkg-1
-exposed: True
-exposed-modules: Base
-import-dirs: ${pkgroot}/basepkg-v1
-library-dirs: ${pkgroot}/basepkg-v1
-dynamic-library-dirs: ${pkgroot}/basepkg-v1
-hs-libraries: HSbasepkg-1
-depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/basepkg-v2.conf.in deleted
=====================================
@@ -1,11 +0,0 @@
-name: basepkg
-version: 1.0
-id: basepkg-1
-key: basepkg-1
-exposed: True
-exposed-modules: Base
-import-dirs: ${pkgroot}/basepkg-v2
-library-dirs: ${pkgroot}/basepkg-v2
-dynamic-library-dirs: ${pkgroot}/basepkg-v2
-hs-libraries: HSbasepkg-1
-depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/dep.conf.in deleted
=====================================
@@ -1,11 +0,0 @@
-name: dep
-version: 1.0
-id: dep-1
-key: dep-1
-exposed: True
-exposed-modules: Dep
-import-dirs: ${pkgroot}/dep
-library-dirs: ${pkgroot}/dep
-dynamic-library-dirs: ${pkgroot}/dep
-hs-libraries: HSdep-1
-depends: basepkg-1 @BASE_ID@
=====================================
testsuite/tests/driver/T2057/pkgA1.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgA1
+version: 1.0
+id: pkgA1-1
+key: pkgA1-1
+exposed: True
+exposed-modules: A
+import-dirs: ${pkgroot}/pkgA1
+library-dirs: ${pkgroot}/pkgA1
+dynamic-library-dirs: ${pkgroot}/pkgA1
+hs-libraries: HSpkgA1-1
+depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/src/base-v1/Base.hs → testsuite/tests/driver/T2057/pkgA1/A.hs
=====================================
@@ -1,4 +1,4 @@
-module Base (staleDependencyBinding) where
+module A (staleDependencyBinding) where
{-# INLINE staleDependencyBinding #-}
staleDependencyBinding :: Int -> Int
=====================================
testsuite/tests/driver/T2057/pkgA2.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgA1
+version: 1.0
+id: pkgA1-1
+key: pkgA1-1
+exposed: True
+exposed-modules: A
+import-dirs: ${pkgroot}/pkgA2
+library-dirs: ${pkgroot}/pkgA2
+dynamic-library-dirs: ${pkgroot}/pkgA2
+hs-libraries: HSpkgA1-1
+depends: @BASE_ID@
=====================================
testsuite/tests/driver/T2057/src/base-v2/Base.hs → testsuite/tests/driver/T2057/pkgA2/A.hs
=====================================
@@ -1,4 +1,4 @@
-module Base (replacementBinding) where
+module A (replacementBinding) where
replacementBinding :: Int -> Int
replacementBinding x = x + 100
=====================================
testsuite/tests/driver/T2057/pkgB.conf.in
=====================================
@@ -0,0 +1,11 @@
+name: pkgB
+version: 1.0
+id: pkgB-1
+key: pkgB-1
+exposed: True
+exposed-modules: B
+import-dirs: ${pkgroot}/pkgB
+library-dirs: ${pkgroot}/pkgB
+dynamic-library-dirs: ${pkgroot}/pkgB
+hs-libraries: HSpkgB-1
+depends: pkgA1-1 @BASE_ID@
=====================================
testsuite/tests/driver/T2057/src/dep/Dep.hs → testsuite/tests/driver/T2057/pkgB/B.hs
=====================================
@@ -1,6 +1,6 @@
-module Dep (saved) where
+module B (saved) where
-import Base
+import A
{-# INLINE saved #-}
saved :: Int -> Int
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aacab4158c96a461eff6dd80010224…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aacab4158c96a461eff6dd80010224…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
08 Mar '26
Simon Jakobi pushed new branch wip/sjakobi/T2057 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sjakobi/T2057
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: compiler: add myCapabilityExpr to GHC.Cmm.Utils
by Marge Bot (@marge-bot) 08 Mar '26
by Marge Bot (@marge-bot) 08 Mar '26
08 Mar '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
176c0d27 by Cheng Shao at 2026-03-08T18:19:31-04:00
compiler: add myCapabilityExpr to GHC.Cmm.Utils
This commit adds `myCapabilityExpr` to `GHC.Cmm.Utils` which is
computed from `BaseReg`. It's convenient for codegen logic where one
needs to pass the current Capability's pointer.
- - - - -
db303e85 by Cheng Shao at 2026-03-08T18:19:31-04:00
compiler: lower tryPutMVar# into a ccall directly
This patch addresses an old TODO of `stg_tryPutMVarzh` by removing it
completely and making the compiler lower `tryPutMVar#` into a ccall to
`performTryPutMVar` directly, without landing into an intermediate C
or Cmm function. `performTryPutMVar` is promoted to a public RTS
function with default visibility, and the compiler lowering logic
takes into account the C ABI of `performTryPutMVar` and converts from
C Bool to primop's `Int#` result properly.
- - - - -
52957fe0 by Simon Hengel at 2026-03-08T18:19:33-04:00
Don't use #line in haddocks
This confuses the parser. Haddock output is unaffected by this change.
(read: this still produces the same documentation)
- - - - -
878dcddf by Wolfgang Jeltsch at 2026-03-08T18:19:35-04:00
Remove in-package dependencies on `GHC.Internal.System.IO`
This contribution eliminates all dependencies on
`GHC.Internal.System.IO` from within `ghc-internal`. It comprises the
following changes:
* Make `GHC.Internal.Fingerprint` independent of I/O support
* Tighten the dependencies of `GHC.Internal.Data.Version`
* Tighten the dependencies of `GHC.Internal.TH.Monad`
* Tighten the dependencies of `GHCi.Helpers`
* Move some code that needs `System.IO` to `template-haskell`
* Move the `GHC.ResponseFile` implementation into `base`
* Move the `System.Exit` implementation into `base`
* Move the `System.IO.OS` implementation into `base`
Metric Decrease:
size_hello_artifact
size_hello_artifact_gzip
size_hello_unicode
size_hello_unicode_gzip
- - - - -
0a1ff530 by Sylvain Henry at 2026-03-08T18:19:44-04:00
T18832: fix Windows CI failure by dropping removeDirectoryRecursive
On Windows, open file handles prevent deletion. After killThread, the
closer thread may not have called hClose yet, causing removeDirectoryRecursive
to fail with "permission denied". The test harness cleans up the run
directory anyway, so the call is redundant.
- - - - -
b52fbf43 by Cheng Shao at 2026-03-08T18:19:45-04:00
compiler: fix redundant import in GHC.StgToJS.Object
This patch fixes a redundant import in GHC.StgToJS.Object that causes
a build failure when compiling head from 9.14 with validate flavours.
Fixes #26991.
- - - - -
9c734a7e by Cheng Shao at 2026-03-08T18:19:46-04:00
wasm: fix `Illegal foreign declaration` failure when ghci loads modules with JSFFI exports
This patch fixes a wasm ghci error when loading modules with JSFFI
exports; the `backendValidityOfCExport` check in `tcCheckFEType`
should only makes sense and should be performed when not checking the
JavaScript calling convention; otherwise, when the calling convention
is JavaScript, the codegen logic should be trusted to backends that
actually make use of it. Fixes #26998.
- - - - -
29 changed files:
- compiler/GHC/Cmm/Utils.hs
- compiler/GHC/Iface/Ext/Utils.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/Object.hs
- compiler/GHC/Tc/Gen/Foreign.hs
- libraries/base/src/GHC/Fingerprint.hs
- libraries/base/src/GHC/ResponseFile.hs
- libraries/base/src/System/Exit.hs
- libraries/base/src/System/IO/OS.hs
- libraries/base/tests/IO/T18832.hs
- libraries/ghc-heap/GHC/Exts/Heap/Closures.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/Fingerprint.hs
- libraries/ghc-internal/src/GHC/Internal/GHCi/Helpers.hs
- − libraries/ghc-internal/src/GHC/Internal/ResponseFile.hs
- − libraries/ghc-internal/src/GHC/Internal/System/Exit.hs
- − libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- rts/PrimOps.cmm
- rts/RtsSymbols.c
- rts/Threads.c
- rts/Threads.h
- rts/include/rts/Threads.h
- rts/include/stg/MiscClosures.h
- testsuite/tests/ffi/should_compile/all.T
- + testsuite/tests/ghci-wasm/T26998.hs
- testsuite/tests/ghci-wasm/all.T
Changes:
=====================================
compiler/GHC/Cmm/Utils.hs
=====================================
@@ -37,6 +37,7 @@ module GHC.Cmm.Utils(
baseExpr, spExpr, hpExpr, spLimExpr, hpLimExpr,
currentTSOExpr, currentNurseryExpr, cccsExpr,
+ myCapabilityExpr,
-- Tagging
cmmTagMask, cmmPointerMask, cmmUntag, cmmIsTagged, cmmIsNotTagged,
@@ -569,7 +570,7 @@ blockTicks b = reverse $ foldBlockNodesF goStmt b []
-- Access to common global registers
baseExpr, spExpr, hpExpr, currentTSOExpr, currentNurseryExpr,
- spLimExpr, hpLimExpr, cccsExpr :: Platform -> CmmExpr
+ spLimExpr, hpLimExpr, cccsExpr, myCapabilityExpr :: Platform -> CmmExpr
baseExpr p = CmmReg $ baseReg p
spExpr p = CmmReg $ spReg p
spLimExpr p = CmmReg $ spLimReg p
@@ -578,3 +579,5 @@ hpLimExpr p = CmmReg $ hpLimReg p
currentTSOExpr p = CmmReg $ currentTSOReg p
currentNurseryExpr p = CmmReg $ currentNurseryReg p
cccsExpr p = CmmReg $ cccsReg p
+myCapabilityExpr p =
+ cmmRegOff (baseReg p) $ negate $ pc_OFFSET_Capability_r $ platformConstants p
=====================================
compiler/GHC/Iface/Ext/Utils.hs
=====================================
@@ -461,11 +461,11 @@ in which @foozball@ and @quuuuuux@ have overlapping spans:
@
module Baz where
-# line 3 "Baz.hs"
+# \line 3 "Baz.hs"
foozball :: Int
foozball = 0
-# line 3 "Baz.hs"
+# \line 3 "Baz.hs"
bar, quuuuuux :: Int
bar = 1
quuuuuux = 2
=====================================
compiler/GHC/StgToCmm/Prim.hs
=====================================
@@ -345,6 +345,25 @@ emitPrimOp cfg primop =
emitPrimCall [res] (MO_Xchg (wordWidth platform)) [dst, val]
emitDirtyMutVar mutv (CmmReg (CmmLocal res))
+ TryPutMVarOp -> \[mvar, val] -> inlinePrimop $ \[res] -> do
+ cres <- newTemp b8
+ emitCCall
+ [(cres, NoHint)]
+ ( CmmLit
+ ( CmmLabel
+ ( mkForeignLabel
+ (fsLit "performTryPutMVar")
+ ForeignLabelInExternalPackage
+ IsFunction
+ )
+ )
+ )
+ [(myCapabilityExpr platform, AddrHint), (mvar, AddrHint), (val, AddrHint)]
+ emitAssign (CmmLocal res) $
+ CmmMachOp
+ (MO_UU_Conv W8 (wordWidth platform))
+ [CmmReg (CmmLocal cres)]
+
-- #define sizzeofByteArrayzh(r,a) \
-- r = ((StgArrBytes *)(a))->bytes
SizeofByteArrayOp -> \[arg] -> inlinePrimop $ \[res] ->
@@ -1777,7 +1796,6 @@ emitPrimOp cfg primop =
TakeMVarOp -> alwaysExternal
TryTakeMVarOp -> alwaysExternal
PutMVarOp -> alwaysExternal
- TryPutMVarOp -> alwaysExternal
ReadMVarOp -> alwaysExternal
TryReadMVarOp -> alwaysExternal
IsEmptyMVarOp -> alwaysExternal
=====================================
compiler/GHC/StgToJS/Object.hs
=====================================
@@ -72,7 +72,6 @@ import Data.List (sortOn)
import qualified Data.List as List
import Data.Map (Map)
import qualified Data.Map as M
-import Data.Word
import Data.Semigroup
import System.IO
=====================================
compiler/GHC/Tc/Gen/Foreign.hs
=====================================
@@ -449,8 +449,9 @@ tcFExport d = pprPanic "tcFExport" (ppr d)
tcCheckFEType :: Type -> ForeignExport GhcRn -> TcM (ForeignExport GhcTc)
tcCheckFEType sig_ty edecl@(CExport src (L l (CExportStatic str cconv))) = do
- checkCg (Left edecl) backendValidityOfCExport
- when (cconv /= JavaScriptCallConv) $ checkTc (isCLabelString str) (TcRnInvalidCIdentifier str)
+ when (cconv /= JavaScriptCallConv) $ do
+ checkCg (Left edecl) backendValidityOfCExport
+ checkTc (isCLabelString str) (TcRnInvalidCIdentifier str)
cconv' <- checkCConv (Left edecl) cconv
checkForeignArgs isFFIExternalTy arg_tys
checkForeignRes nonIOok noCheckSafe isFFIExportResultTy res_ty
=====================================
libraries/base/src/GHC/Fingerprint.hs
=====================================
@@ -9,3 +9,45 @@ module GHC.Fingerprint (
) where
import GHC.Internal.Fingerprint
+
+import Data.Function (($))
+import Control.Monad (return, when)
+import Data.Bool (not, (&&))
+import Data.List ((++))
+import Data.Maybe (Maybe (Nothing, Just))
+import Data.Int (Int)
+import Data.Word (Word8)
+import Data.Eq ((/=))
+import Text.Show (show)
+import System.IO
+ (
+ IO,
+ FilePath,
+ IOMode (ReadMode),
+ withBinaryFile,
+ hGetBuf,
+ hIsEOF
+ )
+import Foreign.Ptr (Ptr)
+import GHC.Err (errorWithoutStackTrace)
+
+-- | Computes the hash of a given file.
+-- This function runs in constant memory.
+--
+-- @since base-4.7.0.0
+getFileHash :: FilePath -> IO Fingerprint
+getFileHash path = withBinaryFile path ReadMode $ \ hdl ->
+ let
+ readChunk :: Ptr Word8 -> Int -> IO (Maybe Int)
+ readChunk bufferPtr bufferSize = do
+ chunkSize <- hGetBuf hdl bufferPtr bufferSize
+ isFinished <- hIsEOF hdl
+ when (chunkSize /= bufferSize && not isFinished)
+ (
+ errorWithoutStackTrace $
+ "GHC.Fingerprint.getFileHash: could only read " ++
+ show chunkSize ++
+ " bytes, but more are available"
+ )
+ return (if isFinished then Just chunkSize else Nothing)
+ in fingerprintBufferedStream readChunk
=====================================
libraries/base/src/GHC/ResponseFile.hs
=====================================
@@ -1,3 +1,4 @@
+{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Safe #-}
-- |
@@ -19,4 +20,145 @@ module GHC.ResponseFile (
expandResponse
) where
-import GHC.Internal.ResponseFile
+import Control.Monad (return, (>>=), mapM)
+import Control.Exception (IOException, catch)
+import Data.Function (($), (.))
+import Data.Bool (Bool (False, True), otherwise, not, (||))
+import Data.Char (Char, isSpace)
+import Data.List ((++), map, filter, concat, reverse)
+import Data.String (String, unlines)
+import Data.Functor (fmap)
+import Data.Foldable (null, foldl')
+import Data.Eq ((==))
+import Text.Show (show)
+import System.Environment (getArgs)
+import System.IO (IO, hPutStrLn, readFile, stderr)
+import System.Exit (exitFailure)
+
+{-|
+Like 'getArgs', but can also read arguments supplied via response files.
+
+
+For example, consider a program @foo@:
+
+@
+main :: IO ()
+main = do
+ args <- getArgsWithResponseFiles
+ putStrLn (show args)
+@
+
+
+And a response file @args.txt@:
+
+@
+--one 1
+--\'two\' 2
+--"three" 3
+@
+
+Then the result of invoking @foo@ with @args.txt@ is:
+
+> > ./foo @args.txt
+> ["--one","1","--two","2","--three","3"]
+
+-}
+getArgsWithResponseFiles :: IO [String]
+getArgsWithResponseFiles = getArgs >>= expandResponse
+
+-- | Given a string of concatenated strings, separate each by removing
+-- a layer of /quoting/ and\/or /escaping/ of certain characters.
+--
+-- These characters are: any whitespace, single quote, double quote,
+-- and the backslash character. The backslash character always
+-- escapes (i.e., passes through without further consideration) the
+-- character which follows. Characters can also be escaped in blocks
+-- by quoting (i.e., surrounding the blocks with matching pairs of
+-- either single- or double-quotes which are not themselves escaped).
+--
+-- Any whitespace which appears outside of either of the quoting and
+-- escaping mechanisms, is interpreted as having been added by this
+-- special concatenation process to designate where the boundaries
+-- are between the original, un-concatenated list of strings. These
+-- added whitespace characters are removed from the output.
+--
+-- > unescapeArgs "hello\\ \\\"world\\\"\n" == ["hello \"world\""]
+unescapeArgs :: String -> [String]
+unescapeArgs = filter (not . null) . unescape
+
+-- | Given a list of strings, concatenate them into a single string
+-- with escaping of certain characters, and the addition of a newline
+-- between each string. The escaping is done by adding a single
+-- backslash character before any whitespace, single quote, double
+-- quote, or backslash character, so this escaping character must be
+-- removed. Unescaped whitespace (in this case, newline) is part
+-- of this "transport" format to indicate the end of the previous
+-- string and the start of a new string.
+--
+-- While 'unescapeArgs' allows using quoting (i.e., convenient
+-- escaping of many characters) by having matching sets of single- or
+-- double-quotes,'escapeArgs' does not use the quoting mechanism,
+-- and thus will always escape any whitespace, quotes, and
+-- backslashes.
+--
+-- > escapeArgs ["hello \"world\""] == "hello\\ \\\"world\\\"\n"
+escapeArgs :: [String] -> String
+escapeArgs = unlines . map escapeArg
+
+-- | Arguments which look like @\@foo@ will be replaced with the
+-- contents of file @foo@. A gcc-like syntax for response files arguments
+-- is expected. This must re-constitute the argument list by doing an
+-- inverse of the escaping mechanism done by the calling-program side.
+--
+-- We quit if the file is not found or reading somehow fails.
+-- (A convenience routine for haddock or possibly other clients)
+expandResponse :: [String] -> IO [String]
+expandResponse = fmap concat . mapM expand
+ where
+ expand :: String -> IO [String]
+ expand ('@':f) = readFileExc f >>= return . unescapeArgs
+ expand x = return [x]
+
+ readFileExc f =
+ readFile f `catch` \(e :: IOException) -> do
+ hPutStrLn stderr $ "Error while expanding response file: " ++ show e
+ exitFailure
+
+data Quoting = NoneQ | SngQ | DblQ
+
+unescape :: String -> [String]
+unescape args = reverse . map reverse $ go args NoneQ False [] []
+ where
+ -- n.b., the order of these cases matters; these are cribbed from gcc
+ -- case 1: end of input
+ go [] _q _bs a as = a:as
+ -- case 2: back-slash escape in progress
+ go (c:cs) q True a as = go cs q False (c:a) as
+ -- case 3: no back-slash escape in progress, but got a back-slash
+ go (c:cs) q False a as
+ | '\\' == c = go cs q True a as
+ -- case 4: single-quote escaping in progress
+ go (c:cs) SngQ False a as
+ | '\'' == c = go cs NoneQ False a as
+ | otherwise = go cs SngQ False (c:a) as
+ -- case 5: double-quote escaping in progress
+ go (c:cs) DblQ False a as
+ | '"' == c = go cs NoneQ False a as
+ | otherwise = go cs DblQ False (c:a) as
+ -- case 6: no escaping is in progress
+ go (c:cs) NoneQ False a as
+ | isSpace c = go cs NoneQ False [] (a:as)
+ | '\'' == c = go cs SngQ False a as
+ | '"' == c = go cs DblQ False a as
+ | otherwise = go cs NoneQ False (c:a) as
+
+escapeArg :: String -> String
+escapeArg = reverse . foldl' escape []
+
+escape :: String -> Char -> String
+escape cs c
+ | isSpace c
+ || '\\' == c
+ || '\'' == c
+ || '"' == c = c:'\\':cs -- n.b., our caller must reverse the result
+ | otherwise = c:cs
=====================================
libraries/base/src/System/Exit.hs
=====================================
@@ -21,4 +21,67 @@ module System.Exit
die
) where
-import GHC.Internal.System.Exit
\ No newline at end of file
+import GHC.IO.Exception
+ (
+ IOErrorType (InvalidArgument),
+ IOException (IOError),
+ ExitCode (ExitSuccess, ExitFailure)
+ )
+import Control.Monad ((>>))
+import Control.Exception (throwIO, ioError)
+import Data.Bool (otherwise)
+import Data.Maybe (Maybe (Nothing))
+import Data.String (String)
+import Data.Eq ((/=))
+import System.IO (IO, hPutStrLn, stderr)
+
+-- ---------------------------------------------------------------------------
+-- exitWith
+
+-- | Computation 'exitWith' @code@ throws 'ExitCode' @code@.
+-- Normally this terminates the program, returning @code@ to the
+-- program's caller.
+--
+-- On program termination, the standard 'Handle's 'stdout' and
+-- 'stderr' are flushed automatically; any other buffered 'Handle's
+-- need to be flushed manually, otherwise the buffered data will be
+-- discarded.
+--
+-- A program that fails in any other way is treated as if it had
+-- called 'exitFailure'.
+-- A program that terminates successfully without calling 'exitWith'
+-- explicitly is treated as if it had called 'exitWith' 'ExitSuccess'.
+--
+-- As an 'ExitCode' is an 'Control.Exception.Exception', it can be
+-- caught using the functions of "Control.Exception". This means that
+-- cleanup computations added with 'GHC.Internal.Control.Exception.bracket' (from
+-- "Control.Exception") are also executed properly on 'exitWith'.
+--
+-- Note: in GHC, 'exitWith' should be called from the main program
+-- thread in order to exit the process. When called from another
+-- thread, 'exitWith' will throw an 'ExitCode' as normal, but the
+-- exception will not cause the process itself to exit.
+--
+exitWith :: ExitCode -> IO a
+exitWith ExitSuccess = throwIO ExitSuccess
+exitWith code@(ExitFailure n)
+ | n /= 0 = throwIO code
+ | otherwise = ioError (IOError Nothing InvalidArgument "exitWith" "ExitFailure 0" Nothing Nothing)
+
+-- | The computation 'exitFailure' is equivalent to
+-- 'exitWith' @(@'ExitFailure' /exitfail/@)@,
+-- where /exitfail/ is implementation-dependent.
+exitFailure :: IO a
+exitFailure = exitWith (ExitFailure 1)
+
+-- | The computation 'exitSuccess' is equivalent to
+-- 'exitWith' 'ExitSuccess', It terminates the program
+-- successfully.
+exitSuccess :: IO a
+exitSuccess = exitWith ExitSuccess
+
+-- | Write given error message to `stderr` and terminate with `exitFailure`.
+--
+-- @since base-4.8.0.0
+die :: String -> IO a
+die err = hPutStrLn stderr err >> exitFailure
=====================================
libraries/base/src/System/IO/OS.hs
=====================================
@@ -1,4 +1,6 @@
{-# LANGUAGE Safe #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE RankNTypes #-}
{-|
This module bridges between Haskell handles and underlying operating-system
@@ -21,17 +23,293 @@ module System.IO.OS
)
where
-import GHC.Internal.System.IO.OS
+import Control.Monad (return)
+import Control.Concurrent.MVar (MVar)
+import Control.Exception (mask)
+import Data.Function (const, (.), ($))
+import Data.Functor (fmap)
+import Data.Maybe (Maybe (Nothing), maybe)
+#if defined(mingw32_HOST_OS)
+import Data.Bool (otherwise)
+import Data.Maybe (Maybe (Just))
+#endif
+import Data.List ((++))
+import Data.String (String)
+import Data.Typeable (Typeable, cast)
+import System.IO (IO)
+import GHC.IO.FD (fdFD)
+#if defined(mingw32_HOST_OS)
+import GHC.IO.Windows.Handle
(
- withFileDescriptorReadingBiased,
- withFileDescriptorWritingBiased,
- withWindowsHandleReadingBiased,
- withWindowsHandleWritingBiased,
- withFileDescriptorReadingBiasedRaw,
- withFileDescriptorWritingBiasedRaw,
- withWindowsHandleReadingBiasedRaw,
- withWindowsHandleWritingBiasedRaw
+ NativeHandle,
+ ConsoleHandle,
+ IoHandle,
+ toHANDLE
)
+#endif
+import GHC.IO.Handle.Types
+ (
+ Handle (FileHandle, DuplexHandle),
+ Handle__ (Handle__, haDevice)
+ )
+import GHC.IO.Handle.Internals (withHandle_', flushBuffer)
+import GHC.IO.Exception
+ (
+ IOErrorType (InappropriateType),
+ IOException (IOError),
+ ioException
+ )
+import Foreign.Ptr (Ptr)
+import Foreign.C.Types (CInt)
+
+-- * Obtaining POSIX file descriptors and Windows handles
+
+{-|
+ Executes a user-provided action on an operating-system handle that underlies
+ a Haskell handle. Before the user-provided action is run, user-defined
+ preparation based on the handle state that contains the operating-system
+ handle is performed. While the user-provided action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withOSHandle :: String
+ -- ^ The name of the overall operation
+ -> (Handle -> MVar Handle__)
+ {-^
+ Obtaining of the handle state variable that holds the
+ operating-system handle
+ -}
+ -> (forall d. Typeable d => d -> IO a)
+ -- ^ Conversion of a device into an operating-system handle
+ -> (Handle__ -> IO ())
+ -- ^ The preparation
+ -> Handle
+ -- ^ The Haskell handle to use
+ -> (a -> IO r)
+ -- ^ The action to execute on the operating-system handle
+ -> IO r
+withOSHandle opName handleStateVar getOSHandle prepare handle act
+ = mask $ \ withOriginalMaskingState ->
+ withHandleState $ \ handleState@Handle__ {haDevice = dev} -> do
+ osHandle <- getOSHandle dev
+ prepare handleState
+ withOriginalMaskingState $ act osHandle
+ where
+
+ withHandleState = withHandle_' opName handle (handleStateVar handle)
+{-
+ The 'withHandle_'' operation, which we use here, already performs masking.
+ Still, we have to employ 'mask', in order do obtain the operation that
+ restores the original masking state. The user-provided action should be
+ executed with this original masking state, as there is no inherent reason to
+ generally perform it with masking in place. The masking that 'withHandle_''
+ performs is only for safely accessing handle state and thus constitutes an
+ implementation detail; it has nothing to do with the user-provided action.
+-}
+{-
+ The order of actions in 'withOSHandle' is such that any exception from
+ 'getOSHandle' is thrown before the user-defined preparation is performed.
+-}
+
+{-|
+ Obtains the handle state variable that underlies a handle or specifically
+ the handle state variable for reading if the handle uses different state
+ variables for reading and writing.
+-}
+handleStateVarReadingBiased :: Handle -> MVar Handle__
+handleStateVarReadingBiased (FileHandle _ var) = var
+handleStateVarReadingBiased (DuplexHandle _ readingVar _) = readingVar
+
+{-|
+ Obtains the handle state variable that underlies a handle or specifically
+ the handle state variable for writing if the handle uses different state
+ variables for reading and writing.
+-}
+handleStateVarWritingBiased :: Handle -> MVar Handle__
+handleStateVarWritingBiased (FileHandle _ var) = var
+handleStateVarWritingBiased (DuplexHandle _ _ writingVar) = writingVar
+
+{-|
+ Yields the result of another operation if that operation succeeded, and
+ otherwise throws an exception that signals that the other operation failed
+ because some Haskell handle does not use an operating-system handle of a
+ required type.
+-}
+requiringOSHandleOfType :: String
+ -- ^ The name of the operating-system handle type
+ -> Maybe a
+ {-^
+ The result of the other operation if it succeeded
+ -}
+ -> IO a
+requiringOSHandleOfType osHandleTypeName
+ = maybe (ioException osHandleOfTypeRequired) return
+ where
+
+ osHandleOfTypeRequired :: IOException
+ osHandleOfTypeRequired
+ = IOError Nothing
+ InappropriateType
+ ""
+ ("handle does not use " ++ osHandleTypeName ++ "s")
+ Nothing
+ Nothing
+
+{-|
+ Obtains the POSIX file descriptor of a device if the device contains one,
+ and throws an exception otherwise.
+-}
+getFileDescriptor :: Typeable d => d -> IO CInt
+getFileDescriptor = requiringOSHandleOfType "POSIX file descriptor" .
+ fmap fdFD . cast
+
+{-|
+ Obtains the Windows handle of a device if the device contains one, and
+ throws an exception otherwise.
+-}
+getWindowsHandle :: Typeable d => d -> IO (Ptr ())
+getWindowsHandle = requiringOSHandleOfType "Windows handle" .
+ toMaybeWindowsHandle
+ where
+
+ toMaybeWindowsHandle :: Typeable d => d -> Maybe (Ptr ())
+#if defined(mingw32_HOST_OS)
+ toMaybeWindowsHandle dev
+ | Just nativeHandle <- cast dev :: Maybe (IoHandle NativeHandle)
+ = Just (toHANDLE nativeHandle)
+ | Just consoleHandle <- cast dev :: Maybe (IoHandle ConsoleHandle)
+ = Just (toHANDLE consoleHandle)
+ | otherwise
+ = Nothing
+ {-
+ This is inspired by the implementation of
+ 'System.Win32.Types.withHandleToHANDLENative'.
+ -}
+#else
+ toMaybeWindowsHandle _ = Nothing
+#endif
+
+{-|
+ Executes a user-provided action on the POSIX file descriptor that underlies
+ a handle or specifically on the POSIX file descriptor for reading if the
+ handle uses different file descriptors for reading and writing. The
+ Haskell-managed buffers related to the file descriptor are flushed before
+ the user-provided action is run. While this action is executed, further
+ operations on the handle are blocked to a degree that interference with this
+ action is prevented.
+
+ If the handle does not use POSIX file descriptors, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withFileDescriptorReadingBiased :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorReadingBiased = withOSHandle "withFileDescriptorReadingBiased"
+ handleStateVarReadingBiased
+ getFileDescriptor
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the POSIX file descriptor that underlies
+ a handle or specifically on the POSIX file descriptor for writing if the
+ handle uses different file descriptors for reading and writing. The
+ Haskell-managed buffers related to the file descriptor are flushed before
+ the user-provided action is run. While this action is executed, further
+ operations on the handle are blocked to a degree that interference with this
+ action is prevented.
+
+ If the handle does not use POSIX file descriptors, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withFileDescriptorWritingBiased :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorWritingBiased = withOSHandle "withFileDescriptorWritingBiased"
+ handleStateVarWritingBiased
+ getFileDescriptor
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the Windows handle that underlies a
+ Haskell handle or specifically on the Windows handle for reading if the
+ Haskell handle uses different Windows handles for reading and writing. The
+ Haskell-managed buffers related to the Windows handle are flushed before the
+ user-provided action is run. While this action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ If the Haskell handle does not use Windows handles, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withWindowsHandleReadingBiased :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleReadingBiased = withOSHandle "withWindowsHandleReadingBiased"
+ handleStateVarReadingBiased
+ getWindowsHandle
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the Windows handle that underlies a
+ Haskell handle or specifically on the Windows handle for writing if the
+ Haskell handle uses different Windows handles for reading and writing. The
+ Haskell-managed buffers related to the Windows handle are flushed before the
+ user-provided action is run. While this action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ If the Haskell handle does not use Windows handles, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withWindowsHandleWritingBiased :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleWritingBiased = withOSHandle "withWindowsHandleWritingBiased"
+ handleStateVarWritingBiased
+ getWindowsHandle
+ flushBuffer
+
+{-|
+ Like 'withFileDescriptorReadingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withFileDescriptorReadingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorReadingBiasedRaw
+ = withOSHandle "withFileDescriptorReadingBiasedRaw"
+ handleStateVarReadingBiased
+ getFileDescriptor
+ (const $ return ())
+
+{-|
+ Like 'withFileDescriptorWritingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withFileDescriptorWritingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorWritingBiasedRaw
+ = withOSHandle "withFileDescriptorWritingBiasedRaw"
+ handleStateVarWritingBiased
+ getFileDescriptor
+ (const $ return ())
+
+{-|
+ Like 'withWindowsHandleReadingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withWindowsHandleReadingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleReadingBiasedRaw
+ = withOSHandle "withWindowsHandleReadingBiasedRaw"
+ handleStateVarReadingBiased
+ getWindowsHandle
+ (const $ return ())
+
+{-|
+ Like 'withWindowsHandleWritingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withWindowsHandleWritingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleWritingBiasedRaw
+ = withOSHandle "withWindowsHandleWritingBiasedRaw"
+ handleStateVarWritingBiased
+ getWindowsHandle
+ (const $ return ())
-- ** Caveats
=====================================
libraries/base/tests/IO/T18832.hs
=====================================
@@ -41,7 +41,6 @@ test dir' = do
-- cleanup
mapM_ killThread [interrupter, deleter, closer]
- removeDirectoryRecursive dir
either throwIO (const $ putStrLn "No failures observed - success") result
=====================================
libraries/ghc-heap/GHC/Exts/Heap/Closures.hs
=====================================
@@ -1,17 +1,3 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE ForeignFunctionInterface #-}
-{-# LANGUAGE GHCForeignImportPrim #-}
-{-# LANGUAGE MagicHash #-}
-{-# LANGUAGE RecordWildCards #-}
-{-# LANGUAGE UnliftedFFITypes #-}
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE DeriveTraversable #-}
--- Late cost centres introduce a thunk in the asBox function, which leads to
--- an additional wrapper being added to any value placed inside a box.
--- This can be removed once our boot compiler is no longer affected by #25212
-{-# OPTIONS_GHC -fno-prof-late #-}
-{-# LANGUAGE NamedFieldPuns #-}
-
module GHC.Exts.Heap.Closures (
-- * Closures
Closure
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -284,7 +284,6 @@ Library
GHC.Internal.Read
GHC.Internal.Real
GHC.Internal.Records
- GHC.Internal.ResponseFile
GHC.Internal.RTS.Flags
GHC.Internal.RTS.Flags.Test
GHC.Internal.ST
@@ -324,10 +323,8 @@ Library
GHC.Internal.Numeric.Natural
GHC.Internal.System.Environment
GHC.Internal.System.Environment.Blank
- GHC.Internal.System.Exit
GHC.Internal.System.IO
GHC.Internal.System.IO.Error
- GHC.Internal.System.IO.OS
GHC.Internal.System.Mem
GHC.Internal.System.Mem.StableName
GHC.Internal.System.Posix.Internals
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
=====================================
@@ -41,8 +41,7 @@ import GHC.Internal.Data.Eq
import GHC.Internal.Int ( Int )
import GHC.Internal.Data.List ( map, sort, concat, concatMap, intersperse, (++) )
import GHC.Internal.Data.Ord
-import GHC.Internal.Data.String ( String )
-import GHC.Internal.Base ( Applicative(..), (&&) )
+import GHC.Internal.Base ( Applicative(..), (&&), String )
import GHC.Internal.Generics
import GHC.Internal.Unicode ( isDigit, isAlphaNum )
import GHC.Internal.Read
=====================================
libraries/ghc-internal/src/GHC/Internal/Fingerprint.hs
=====================================
@@ -16,23 +16,22 @@ module GHC.Internal.Fingerprint (
fingerprintData,
fingerprintString,
fingerprintFingerprints,
- getFileHash
+ fingerprintBufferedStream
) where
import GHC.Internal.IO
import GHC.Internal.Base
import GHC.Internal.Bits
import GHC.Internal.Num
+import GHC.Internal.Data.Maybe
import GHC.Internal.List
import GHC.Internal.Real
import GHC.Internal.Word
-import GHC.Internal.Show
import GHC.Internal.Ptr
import GHC.Internal.Foreign.C.Types
import GHC.Internal.Foreign.Marshal.Alloc
import GHC.Internal.Foreign.Marshal.Array
import GHC.Internal.Foreign.Storable
-import GHC.Internal.System.IO
import GHC.Internal.Fingerprint.Type
@@ -71,41 +70,27 @@ fingerprintString str = unsafeDupablePerformIO $
fromIntegral (w32 `shiftR` 8),
fromIntegral w32]
--- | Computes the hash of a given file.
--- This function loops over the handle, running in constant memory.
---
--- @since base-4.7.0.0
-getFileHash :: FilePath -> IO Fingerprint
-getFileHash path = withBinaryFile path ReadMode $ \h ->
+-- | Reads data in chunks and computes its hash.
+-- This function runs in constant memory.
+fingerprintBufferedStream :: (Ptr Word8 -> Int -> IO (Maybe Int))
+ -> IO Fingerprint
+fingerprintBufferedStream readChunk =
allocaBytes SIZEOF_STRUCT_MD5CONTEXT $ \pctxt -> do
c_MD5Init pctxt
-
- processChunks h (\buf size -> c_MD5Update pctxt buf (fromIntegral size))
-
+ allocaBytes _BUFSIZE $ \arrPtr ->
+ let loop = do
+ maybeRemainderSize <- readChunk arrPtr _BUFSIZE
+ c_MD5Update pctxt
+ arrPtr
+ (fromIntegral (fromMaybe _BUFSIZE maybeRemainderSize))
+ when (isNothing maybeRemainderSize) loop
+ in loop
allocaBytes 16 $ \pdigest -> do
c_MD5Final pdigest pctxt
peek (castPtr pdigest :: Ptr Fingerprint)
-
where
_BUFSIZE = 4096
- -- Loop over _BUFSIZE sized chunks read from the handle,
- -- passing the callback a block of bytes and its size.
- processChunks :: Handle -> (Ptr Word8 -> Int -> IO ()) -> IO ()
- processChunks h f = allocaBytes _BUFSIZE $ \arrPtr ->
-
- let loop = do
- count <- hGetBuf h arrPtr _BUFSIZE
- eof <- hIsEOF h
- when (count /= _BUFSIZE && not eof) $ errorWithoutStackTrace $
- "GHC.Internal.Fingerprint.getFileHash: only read " ++ show count ++ " bytes"
-
- f arrPtr count
-
- when (not eof) loop
-
- in loop
-
data MD5Context
foreign import ccall unsafe "__hsbase_MD5Init"
=====================================
libraries/ghc-internal/src/GHC/Internal/GHCi/Helpers.hs
=====================================
@@ -24,9 +24,10 @@ module GHC.Internal.GHCi.Helpers
, evalWrapper
) where
-import GHC.Internal.Base
-import GHC.Internal.System.IO
-import GHC.Internal.System.Environment
+import GHC.Internal.Base (String, IO)
+import GHC.Internal.IO.Handle (BufferMode (NoBuffering), hSetBuffering, hFlush)
+import GHC.Internal.IO.StdHandles (stdin, stdout, stderr)
+import GHC.Internal.System.Environment (withProgName, withArgs)
disableBuffering :: IO ()
disableBuffering = do
=====================================
libraries/ghc-internal/src/GHC/Internal/ResponseFile.hs deleted
=====================================
@@ -1,163 +0,0 @@
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE Trustworthy #-}
-
------------------------------------------------------------------------------
--- |
--- Module : GHC.Internal.ResponseFile
--- License : BSD-style (see the file LICENSE)
---
--- Maintainer : libraries(a)haskell.org
--- Stability : internal
--- Portability : portable
---
--- GCC style response files.
---
--- @since base-4.12.0.0
-----------------------------------------------------------------------------
-
--- Migrated from Haddock.
-
-module GHC.Internal.ResponseFile (
- getArgsWithResponseFiles,
- unescapeArgs,
- escapeArgs, escapeArg,
- expandResponse
- ) where
-
-import GHC.Internal.Control.Exception
-import GHC.Internal.Data.Foldable (Foldable(..))
-import GHC.Internal.Base
-import GHC.Internal.Unicode (isSpace)
-import GHC.Internal.Data.List (filter, unlines, concat, reverse)
-import GHC.Internal.Text.Show (show)
-import GHC.Internal.System.Environment (getArgs)
-import GHC.Internal.System.Exit (exitFailure)
-import GHC.Internal.System.IO
-
-{-|
-Like 'getArgs', but can also read arguments supplied via response files.
-
-
-For example, consider a program @foo@:
-
-@
-main :: IO ()
-main = do
- args <- getArgsWithResponseFiles
- putStrLn (show args)
-@
-
-
-And a response file @args.txt@:
-
-@
---one 1
---\'two\' 2
---"three" 3
-@
-
-Then the result of invoking @foo@ with @args.txt@ is:
-
-> > ./foo @args.txt
-> ["--one","1","--two","2","--three","3"]
-
--}
-getArgsWithResponseFiles :: IO [String]
-getArgsWithResponseFiles = getArgs >>= expandResponse
-
--- | Given a string of concatenated strings, separate each by removing
--- a layer of /quoting/ and\/or /escaping/ of certain characters.
---
--- These characters are: any whitespace, single quote, double quote,
--- and the backslash character. The backslash character always
--- escapes (i.e., passes through without further consideration) the
--- character which follows. Characters can also be escaped in blocks
--- by quoting (i.e., surrounding the blocks with matching pairs of
--- either single- or double-quotes which are not themselves escaped).
---
--- Any whitespace which appears outside of either of the quoting and
--- escaping mechanisms, is interpreted as having been added by this
--- special concatenation process to designate where the boundaries
--- are between the original, un-concatenated list of strings. These
--- added whitespace characters are removed from the output.
---
--- > unescapeArgs "hello\\ \\\"world\\\"\n" == ["hello \"world\""]
-unescapeArgs :: String -> [String]
-unescapeArgs = filter (not . null) . unescape
-
--- | Given a list of strings, concatenate them into a single string
--- with escaping of certain characters, and the addition of a newline
--- between each string. The escaping is done by adding a single
--- backslash character before any whitespace, single quote, double
--- quote, or backslash character, so this escaping character must be
--- removed. Unescaped whitespace (in this case, newline) is part
--- of this "transport" format to indicate the end of the previous
--- string and the start of a new string.
---
--- While 'unescapeArgs' allows using quoting (i.e., convenient
--- escaping of many characters) by having matching sets of single- or
--- double-quotes,'escapeArgs' does not use the quoting mechanism,
--- and thus will always escape any whitespace, quotes, and
--- backslashes.
---
--- > escapeArgs ["hello \"world\""] == "hello\\ \\\"world\\\"\n"
-escapeArgs :: [String] -> String
-escapeArgs = unlines . map escapeArg
-
--- | Arguments which look like @\@foo@ will be replaced with the
--- contents of file @foo@. A gcc-like syntax for response files arguments
--- is expected. This must re-constitute the argument list by doing an
--- inverse of the escaping mechanism done by the calling-program side.
---
--- We quit if the file is not found or reading somehow fails.
--- (A convenience routine for haddock or possibly other clients)
-expandResponse :: [String] -> IO [String]
-expandResponse = fmap concat . mapM expand
- where
- expand :: String -> IO [String]
- expand ('@':f) = readFileExc f >>= return . unescapeArgs
- expand x = return [x]
-
- readFileExc f =
- readFile f `catch` \(e :: IOException) -> do
- hPutStrLn stderr $ "Error while expanding response file: " ++ show e
- exitFailure
-
-data Quoting = NoneQ | SngQ | DblQ
-
-unescape :: String -> [String]
-unescape args = reverse . map reverse $ go args NoneQ False [] []
- where
- -- n.b., the order of these cases matters; these are cribbed from gcc
- -- case 1: end of input
- go [] _q _bs a as = a:as
- -- case 2: back-slash escape in progress
- go (c:cs) q True a as = go cs q False (c:a) as
- -- case 3: no back-slash escape in progress, but got a back-slash
- go (c:cs) q False a as
- | '\\' == c = go cs q True a as
- -- case 4: single-quote escaping in progress
- go (c:cs) SngQ False a as
- | '\'' == c = go cs NoneQ False a as
- | otherwise = go cs SngQ False (c:a) as
- -- case 5: double-quote escaping in progress
- go (c:cs) DblQ False a as
- | '"' == c = go cs NoneQ False a as
- | otherwise = go cs DblQ False (c:a) as
- -- case 6: no escaping is in progress
- go (c:cs) NoneQ False a as
- | isSpace c = go cs NoneQ False [] (a:as)
- | '\'' == c = go cs SngQ False a as
- | '"' == c = go cs DblQ False a as
- | otherwise = go cs NoneQ False (c:a) as
-
-escapeArg :: String -> String
-escapeArg = reverse . foldl' escape []
-
-escape :: String -> Char -> String
-escape cs c
- | isSpace c
- || '\\' == c
- || '\'' == c
- || '"' == c = c:'\\':cs -- n.b., our caller must reverse the result
- | otherwise = c:cs
=====================================
libraries/ghc-internal/src/GHC/Internal/System/Exit.hs deleted
=====================================
@@ -1,81 +0,0 @@
-{-# LANGUAGE Trustworthy #-}
-
------------------------------------------------------------------------------
--- |
--- Module : GHC.Internal.System.Exit
--- Copyright : (c) The University of Glasgow 2001
--- License : BSD-style (see the file libraries/base/LICENSE)
---
--- Maintainer : libraries(a)haskell.org
--- Stability : provisional
--- Portability : portable
---
--- Exiting the program.
---
------------------------------------------------------------------------------
-
-module GHC.Internal.System.Exit
- (
- ExitCode(ExitSuccess,ExitFailure)
- , exitWith
- , exitFailure
- , exitSuccess
- , die
- ) where
-
-import GHC.Internal.System.IO
-
-import GHC.Internal.Base
-import GHC.Internal.IO
-import GHC.Internal.IO.Exception
-
--- ---------------------------------------------------------------------------
--- exitWith
-
--- | Computation 'exitWith' @code@ throws 'ExitCode' @code@.
--- Normally this terminates the program, returning @code@ to the
--- program's caller.
---
--- On program termination, the standard 'Handle's 'stdout' and
--- 'stderr' are flushed automatically; any other buffered 'Handle's
--- need to be flushed manually, otherwise the buffered data will be
--- discarded.
---
--- A program that fails in any other way is treated as if it had
--- called 'exitFailure'.
--- A program that terminates successfully without calling 'exitWith'
--- explicitly is treated as if it had called 'exitWith' 'ExitSuccess'.
---
--- As an 'ExitCode' is an 'Control.Exception.Exception', it can be
--- caught using the functions of "Control.Exception". This means that
--- cleanup computations added with 'GHC.Internal.Control.Exception.bracket' (from
--- "Control.Exception") are also executed properly on 'exitWith'.
---
--- Note: in GHC, 'exitWith' should be called from the main program
--- thread in order to exit the process. When called from another
--- thread, 'exitWith' will throw an 'ExitCode' as normal, but the
--- exception will not cause the process itself to exit.
---
-exitWith :: ExitCode -> IO a
-exitWith ExitSuccess = throwIO ExitSuccess
-exitWith code@(ExitFailure n)
- | n /= 0 = throwIO code
- | otherwise = ioError (IOError Nothing InvalidArgument "exitWith" "ExitFailure 0" Nothing Nothing)
-
--- | The computation 'exitFailure' is equivalent to
--- 'exitWith' @(@'ExitFailure' /exitfail/@)@,
--- where /exitfail/ is implementation-dependent.
-exitFailure :: IO a
-exitFailure = exitWith (ExitFailure 1)
-
--- | The computation 'exitSuccess' is equivalent to
--- 'exitWith' 'ExitSuccess', It terminates the program
--- successfully.
-exitSuccess :: IO a
-exitSuccess = exitWith ExitSuccess
-
--- | Write given error message to `stderr` and terminate with `exitFailure`.
---
--- @since base-4.8.0.0
-die :: String -> IO a
-die err = hPutStrLn stderr err >> exitFailure
=====================================
libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs deleted
=====================================
@@ -1,323 +0,0 @@
-{-# LANGUAGE Trustworthy #-}
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE RankNTypes #-}
-
-{-|
- This module bridges between Haskell handles and underlying operating-system
- features.
--}
-module GHC.Internal.System.IO.OS
-(
- -- * Obtaining file descriptors and Windows handles
- withFileDescriptorReadingBiased,
- withFileDescriptorWritingBiased,
- withWindowsHandleReadingBiased,
- withWindowsHandleWritingBiased,
- withFileDescriptorReadingBiasedRaw,
- withFileDescriptorWritingBiasedRaw,
- withWindowsHandleReadingBiasedRaw,
- withWindowsHandleWritingBiasedRaw
-
- -- ** Caveats
- -- $with-ref-caveats
-)
-where
-
-#if defined(mingw32_HOST_OS)
-import GHC.Internal.Base (otherwise)
-#endif
-import GHC.Internal.Control.Monad (return)
-import GHC.Internal.Control.Concurrent.MVar (MVar)
-import GHC.Internal.Control.Exception (mask)
-import GHC.Internal.Data.Function (const, (.), ($))
-import GHC.Internal.Data.Functor (fmap)
-import GHC.Internal.Data.Maybe (Maybe (Nothing), maybe)
-#if defined(mingw32_HOST_OS)
-import GHC.Internal.Data.Maybe (Maybe (Just))
-#endif
-import GHC.Internal.Data.List ((++))
-import GHC.Internal.Data.String (String)
-import GHC.Internal.Data.Typeable (Typeable, cast)
-import GHC.Internal.System.IO (IO)
-import GHC.Internal.IO.FD (fdFD)
-#if defined(mingw32_HOST_OS)
-import GHC.Internal.IO.Windows.Handle
- (
- NativeHandle,
- ConsoleHandle,
- IoHandle,
- toHANDLE
- )
-#endif
-import GHC.Internal.IO.Handle.Types
- (
- Handle (FileHandle, DuplexHandle),
- Handle__ (Handle__, haDevice)
- )
-import GHC.Internal.IO.Handle.Internals (withHandle_', flushBuffer)
-import GHC.Internal.IO.Exception
- (
- IOErrorType (InappropriateType),
- IOException (IOError),
- ioException
- )
-import GHC.Internal.Foreign.Ptr (Ptr)
-import GHC.Internal.Foreign.C.Types (CInt)
-
--- * Obtaining POSIX file descriptors and Windows handles
-
-{-|
- Executes a user-provided action on an operating-system handle that underlies
- a Haskell handle. Before the user-provided action is run, user-defined
- preparation based on the handle state that contains the operating-system
- handle is performed. While the user-provided action is executed, further
- operations on the Haskell handle are blocked to a degree that interference
- with this action is prevented.
-
- See [below](#with-ref-caveats) for caveats regarding this operation.
--}
-withOSHandle :: String
- -- ^ The name of the overall operation
- -> (Handle -> MVar Handle__)
- {-^
- Obtaining of the handle state variable that holds the
- operating-system handle
- -}
- -> (forall d. Typeable d => d -> IO a)
- -- ^ Conversion of a device into an operating-system handle
- -> (Handle__ -> IO ())
- -- ^ The preparation
- -> Handle
- -- ^ The Haskell handle to use
- -> (a -> IO r)
- -- ^ The action to execute on the operating-system handle
- -> IO r
-withOSHandle opName handleStateVar getOSHandle prepare handle act
- = mask $ \ withOriginalMaskingState ->
- withHandleState $ \ handleState@Handle__ {haDevice = dev} -> do
- osHandle <- getOSHandle dev
- prepare handleState
- withOriginalMaskingState $ act osHandle
- where
-
- withHandleState = withHandle_' opName handle (handleStateVar handle)
-{-
- The 'withHandle_'' operation, which we use here, already performs masking.
- Still, we have to employ 'mask', in order do obtain the operation that
- restores the original masking state. The user-provided action should be
- executed with this original masking state, as there is no inherent reason to
- generally perform it with masking in place. The masking that 'withHandle_''
- performs is only for safely accessing handle state and thus constitutes an
- implementation detail; it has nothing to do with the user-provided action.
--}
-{-
- The order of actions in 'withOSHandle' is such that any exception from
- 'getOSHandle' is thrown before the user-defined preparation is performed.
--}
-
-{-|
- Obtains the handle state variable that underlies a handle or specifically
- the handle state variable for reading if the handle uses different state
- variables for reading and writing.
--}
-handleStateVarReadingBiased :: Handle -> MVar Handle__
-handleStateVarReadingBiased (FileHandle _ var) = var
-handleStateVarReadingBiased (DuplexHandle _ readingVar _) = readingVar
-
-{-|
- Obtains the handle state variable that underlies a handle or specifically
- the handle state variable for writing if the handle uses different state
- variables for reading and writing.
--}
-handleStateVarWritingBiased :: Handle -> MVar Handle__
-handleStateVarWritingBiased (FileHandle _ var) = var
-handleStateVarWritingBiased (DuplexHandle _ _ writingVar) = writingVar
-
-{-|
- Yields the result of another operation if that operation succeeded, and
- otherwise throws an exception that signals that the other operation failed
- because some Haskell handle does not use an operating-system handle of a
- required type.
--}
-requiringOSHandleOfType :: String
- -- ^ The name of the operating-system handle type
- -> Maybe a
- {-^
- The result of the other operation if it succeeded
- -}
- -> IO a
-requiringOSHandleOfType osHandleTypeName
- = maybe (ioException osHandleOfTypeRequired) return
- where
-
- osHandleOfTypeRequired :: IOException
- osHandleOfTypeRequired
- = IOError Nothing
- InappropriateType
- ""
- ("handle does not use " ++ osHandleTypeName ++ "s")
- Nothing
- Nothing
-
-{-|
- Obtains the POSIX file descriptor of a device if the device contains one,
- and throws an exception otherwise.
--}
-getFileDescriptor :: Typeable d => d -> IO CInt
-getFileDescriptor = requiringOSHandleOfType "POSIX file descriptor" .
- fmap fdFD . cast
-
-{-|
- Obtains the Windows handle of a device if the device contains one, and
- throws an exception otherwise.
--}
-getWindowsHandle :: Typeable d => d -> IO (Ptr ())
-getWindowsHandle = requiringOSHandleOfType "Windows handle" .
- toMaybeWindowsHandle
- where
-
- toMaybeWindowsHandle :: Typeable d => d -> Maybe (Ptr ())
-#if defined(mingw32_HOST_OS)
- toMaybeWindowsHandle dev
- | Just nativeHandle <- cast dev :: Maybe (IoHandle NativeHandle)
- = Just (toHANDLE nativeHandle)
- | Just consoleHandle <- cast dev :: Maybe (IoHandle ConsoleHandle)
- = Just (toHANDLE consoleHandle)
- | otherwise
- = Nothing
- {-
- This is inspired by the implementation of
- 'System.Win32.Types.withHandleToHANDLENative'.
- -}
-#else
- toMaybeWindowsHandle _ = Nothing
-#endif
-
-{-|
- Executes a user-provided action on the POSIX file descriptor that underlies
- a handle or specifically on the POSIX file descriptor for reading if the
- handle uses different file descriptors for reading and writing. The
- Haskell-managed buffers related to the file descriptor are flushed before
- the user-provided action is run. While this action is executed, further
- operations on the handle are blocked to a degree that interference with this
- action is prevented.
-
- If the handle does not use POSIX file descriptors, an exception is thrown.
-
- See [below](#with-ref-caveats) for caveats regarding this operation.
--}
-withFileDescriptorReadingBiased :: Handle -> (CInt -> IO r) -> IO r
-withFileDescriptorReadingBiased = withOSHandle "withFileDescriptorReadingBiased"
- handleStateVarReadingBiased
- getFileDescriptor
- flushBuffer
-
-{-|
- Executes a user-provided action on the POSIX file descriptor that underlies
- a handle or specifically on the POSIX file descriptor for writing if the
- handle uses different file descriptors for reading and writing. The
- Haskell-managed buffers related to the file descriptor are flushed before
- the user-provided action is run. While this action is executed, further
- operations on the handle are blocked to a degree that interference with this
- action is prevented.
-
- If the handle does not use POSIX file descriptors, an exception is thrown.
-
- See [below](#with-ref-caveats) for caveats regarding this operation.
--}
-withFileDescriptorWritingBiased :: Handle -> (CInt -> IO r) -> IO r
-withFileDescriptorWritingBiased = withOSHandle "withFileDescriptorWritingBiased"
- handleStateVarWritingBiased
- getFileDescriptor
- flushBuffer
-
-{-|
- Executes a user-provided action on the Windows handle that underlies a
- Haskell handle or specifically on the Windows handle for reading if the
- Haskell handle uses different Windows handles for reading and writing. The
- Haskell-managed buffers related to the Windows handle are flushed before the
- user-provided action is run. While this action is executed, further
- operations on the Haskell handle are blocked to a degree that interference
- with this action is prevented.
-
- If the Haskell handle does not use Windows handles, an exception is thrown.
-
- See [below](#with-ref-caveats) for caveats regarding this operation.
--}
-withWindowsHandleReadingBiased :: Handle -> (Ptr () -> IO r) -> IO r
-withWindowsHandleReadingBiased = withOSHandle "withWindowsHandleReadingBiased"
- handleStateVarReadingBiased
- getWindowsHandle
- flushBuffer
-
-{-|
- Executes a user-provided action on the Windows handle that underlies a
- Haskell handle or specifically on the Windows handle for writing if the
- Haskell handle uses different Windows handles for reading and writing. The
- Haskell-managed buffers related to the Windows handle are flushed before the
- user-provided action is run. While this action is executed, further
- operations on the Haskell handle are blocked to a degree that interference
- with this action is prevented.
-
- If the Haskell handle does not use Windows handles, an exception is thrown.
-
- See [below](#with-ref-caveats) for caveats regarding this operation.
--}
-withWindowsHandleWritingBiased :: Handle -> (Ptr () -> IO r) -> IO r
-withWindowsHandleWritingBiased = withOSHandle "withWindowsHandleWritingBiased"
- handleStateVarWritingBiased
- getWindowsHandle
- flushBuffer
-
-{-|
- Like 'withFileDescriptorReadingBiased' except that Haskell-managed buffers
- are not flushed.
--}
-withFileDescriptorReadingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
-withFileDescriptorReadingBiasedRaw
- = withOSHandle "withFileDescriptorReadingBiasedRaw"
- handleStateVarReadingBiased
- getFileDescriptor
- (const $ return ())
-
-{-|
- Like 'withFileDescriptorWritingBiased' except that Haskell-managed buffers
- are not flushed.
--}
-withFileDescriptorWritingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
-withFileDescriptorWritingBiasedRaw
- = withOSHandle "withFileDescriptorWritingBiasedRaw"
- handleStateVarWritingBiased
- getFileDescriptor
- (const $ return ())
-
-{-|
- Like 'withWindowsHandleReadingBiased' except that Haskell-managed buffers
- are not flushed.
--}
-withWindowsHandleReadingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
-withWindowsHandleReadingBiasedRaw
- = withOSHandle "withWindowsHandleReadingBiasedRaw"
- handleStateVarReadingBiased
- getWindowsHandle
- (const $ return ())
-
-{-|
- Like 'withWindowsHandleWritingBiased' except that Haskell-managed buffers
- are not flushed.
--}
-withWindowsHandleWritingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
-withWindowsHandleWritingBiasedRaw
- = withOSHandle "withWindowsHandleWritingBiasedRaw"
- handleStateVarWritingBiased
- getWindowsHandle
- (const $ return ())
-
--- ** Caveats
-
-{-$with-ref-caveats
- #with-ref-caveats#This subsection is just a dummy, whose purpose is to serve
- as the target of the hyperlinks above. The real documentation of the caveats
- is in the /Caveats/ subsection in the @base@ module @System.IO.OS@, which
- re-exports the above operations.
--}
=====================================
libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
=====================================
@@ -26,17 +26,19 @@ module GHC.Internal.TH.Monad
import Prelude
import Data.Data hiding (Fixity(..))
import Data.IORef
-import System.IO.Unsafe ( unsafePerformIO )
+import System.IO.Unsafe (unsafePerformIO)
import Control.Monad.IO.Class (MonadIO (..))
-import System.IO ( hPutStrLn, stderr )
+import System.IO (FilePath, hPutStrLn, stderr)
import qualified Data.Kind as Kind (Type)
-import GHC.Types (TYPE, RuntimeRep(..))
+import GHC.Types (TYPE, RuntimeRep(..))
#else
import GHC.Internal.Base hiding (NonEmpty(..),Type, Module, sequence)
import GHC.Internal.Data.Data hiding (Fixity(..))
import GHC.Internal.Data.Traversable
import GHC.Internal.IORef
-import GHC.Internal.System.IO
+import GHC.Internal.IO (FilePath)
+import GHC.Internal.IO.Handle.Text (hPutStrLn)
+import GHC.Internal.IO.StdHandles (stderr)
import GHC.Internal.Data.Foldable
import GHC.Internal.Data.Typeable
import GHC.Internal.Control.Monad.IO.Class
@@ -819,38 +821,6 @@ addTempFile suffix = Q (qAddTempFile suffix)
addTopDecls :: [Dec] -> Q ()
addTopDecls ds = Q (qAddTopDecls ds)
-
--- | Emit a foreign file which will be compiled and linked to the object for
--- the current module. Currently only languages that can be compiled with
--- the C compiler are supported, and the flags passed as part of -optc will
--- be also applied to the C compiler invocation that will compile them.
---
--- Note that for non-C languages (for example C++) @extern "C"@ directives
--- must be used to get symbols that we can access from Haskell.
---
--- To get better errors, it is recommended to use #line pragmas when
--- emitting C files, e.g.
---
--- > {-# LANGUAGE CPP #-}
--- > ...
--- > addForeignSource LangC $ unlines
--- > [ "#line " ++ show (__LINE__ + 1) ++ " " ++ show __FILE__
--- > , ...
--- > ]
-addForeignSource :: ForeignSrcLang -> String -> Q ()
-addForeignSource lang src = do
- let suffix = case lang of
- LangC -> "c"
- LangCxx -> "cpp"
- LangObjc -> "m"
- LangObjcxx -> "mm"
- LangAsm -> "s"
- LangJs -> "js"
- RawObject -> "a"
- path <- addTempFile suffix
- runIO $ writeFile path src
- addForeignFilePath lang path
-
-- | Same as 'addForeignSource', but expects to receive a path pointing to the
-- foreign file instead of a 'String' of its contents. Consider using this in
-- conjunction with 'addTempFile'.
=====================================
libraries/template-haskell/Language/Haskell/TH/Syntax.hs
=====================================
@@ -209,7 +209,7 @@ import Data.List.NonEmpty (NonEmpty(..))
import GHC.Lexeme ( startsVarSym, startsVarId )
-- This module completely re-exports 'GHC.Boot.TH.Syntax',
--- and exports additionally functions that depend on filepath.
+-- and exports additionally functions that depend on @filepath@ or @System.IO@.
-- |
addForeignFile :: ForeignSrcLang -> String -> Q ()
@@ -218,6 +218,37 @@ addForeignFile = addForeignSource
"Use 'Language.Haskell.TH.Syntax.addForeignSource' instead"
#-} -- deprecated in 8.6
+-- | Emit a foreign file which will be compiled and linked to the object for
+-- the current module. Currently only languages that can be compiled with
+-- the C compiler are supported, and the flags passed as part of -optc will
+-- be also applied to the C compiler invocation that will compile them.
+--
+-- Note that for non-C languages (for example C++) @extern "C"@ directives
+-- must be used to get symbols that we can access from Haskell.
+--
+-- To get better errors, it is recommended to use #line pragmas when
+-- emitting C files, e.g.
+--
+-- > {-# LANGUAGE CPP #-}
+-- > ...
+-- > addForeignSource LangC $ unlines
+-- > [ "#line " ++ show (__LINE__ + 1) ++ " " ++ show __FILE__
+-- > , ...
+-- > ]
+addForeignSource :: ForeignSrcLang -> String -> Q ()
+addForeignSource lang src = do
+ let suffix = case lang of
+ LangC -> "c"
+ LangCxx -> "cpp"
+ LangObjc -> "m"
+ LangObjcxx -> "mm"
+ LangAsm -> "s"
+ LangJs -> "js"
+ RawObject -> "a"
+ path <- addTempFile suffix
+ runIO $ writeFile path src
+ addForeignFilePath lang path
+
-- | The input is a filepath, which if relative is offset by the package root.
makeRelativeToProject :: FilePath -> Q FilePath
makeRelativeToProject fp | isRelative fp = do
=====================================
rts/PrimOps.cmm
=====================================
@@ -1927,95 +1927,6 @@ loop:
}
-// NOTE: there is another implementation of this function in
-// Threads.c:performTryPutMVar(). Keep them in sync! It was
-// measurably slower to call the C function from here (70% for a
-// tight loop doing tryPutMVar#).
-//
-// TODO: we could kill the duplication by making tryPutMVar# into an
-// inline primop that expands into a C call to performTryPutMVar().
-stg_tryPutMVarzh ( P_ mvar, /* :: MVar a */
- P_ val, /* :: a */ )
-{
- W_ info, tso, q, qinfo;
-
- LOCK_CLOSURE(mvar, info);
-
- if (StgMVar_value(mvar) != stg_END_TSO_QUEUE_closure) {
-#if defined(THREADED_RTS)
- unlockClosure(mvar, info);
-#endif
- return (0);
- }
-
- q = StgMVar_head(mvar);
-loop:
- if (q == stg_END_TSO_QUEUE_closure) {
- /* No further takes, the MVar is now full. */
- if (info == stg_MVAR_CLEAN_info) {
- ccall dirty_MVAR(BaseReg "ptr", mvar "ptr", StgMVar_value(mvar) "ptr");
- }
-
- StgMVar_value(mvar) = val;
- unlockClosure(mvar, stg_MVAR_DIRTY_info);
- return (1);
- }
-
- qinfo = GET_INFO_ACQUIRE(q);
-
- if (qinfo == stg_IND_info ||
- qinfo == stg_MSG_NULL_info) {
- q = %acquire StgInd_indirectee(q);
- goto loop;
- }
-
- // There are takeMVar(s) waiting: wake up the first one
-
- tso = StgMVarTSOQueue_tso(q);
- q = StgMVarTSOQueue_link(q);
- StgMVar_head(mvar) = q;
- if (q == stg_END_TSO_QUEUE_closure) {
- StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure;
- } else {
- if (info == stg_MVAR_CLEAN_info) {
- // Resolve #18919.
- ccall dirty_MVAR(BaseReg "ptr", mvar "ptr",
- StgMVar_value(mvar) "ptr");
- info = stg_MVAR_DIRTY_info;
- }
- }
-
- // save why_blocked here, because waking up the thread destroys
- // this information
- W_ why_blocked;
- why_blocked = TO_W_(StgTSO_why_blocked(tso)); // TODO: Missing barrier
- ASSERT(StgTSO_block_info(tso) == mvar);
-
- // actually perform the takeMVar
- W_ stack;
- stack = StgTSO_stackobj(tso);
- if (IS_STACK_CLEAN(stack)) {
- ccall dirty_STACK(MyCapability() "ptr", stack "ptr");
- }
- PerformTake(stack, val);
-
- // indicate that the MVar operation has now completed.
- StgTSO__link(tso) = stg_END_TSO_QUEUE_closure;
-
- ccall tryWakeupThread(MyCapability() "ptr", tso);
-
- // If it was a readMVar, then we can still do work,
- // so loop back. (XXX: This could take a while)
- if (why_blocked == BlockedOnMVarRead)
- goto loop;
-
- ASSERT(why_blocked == BlockedOnMVar);
-
- unlockClosure(mvar, info);
- return (1);
-}
-
-
stg_readMVarzh ( P_ mvar, /* :: MVar a */ )
{
W_ val, info, tso, q;
=====================================
rts/RtsSymbols.c
=====================================
@@ -678,6 +678,7 @@ extern char **environ;
SymI_HasDataProto(stg_readTVarIOzh) \
SymI_HasProto(resumeThread) \
SymI_HasProto(setNumCapabilities) \
+ SymI_HasProto(performTryPutMVar) \
SymI_HasProto(getNumberOfProcessors) \
SymI_HasProto(resolveObjs) \
SymI_HasDataProto(stg_retryzh) \
@@ -869,7 +870,6 @@ extern char **environ;
SymI_HasDataProto(stg_takeMVarzh) \
SymI_HasDataProto(stg_readMVarzh) \
SymI_HasDataProto(stg_threadStatuszh) \
- SymI_HasDataProto(stg_tryPutMVarzh) \
SymI_HasDataProto(stg_tryTakeMVarzh) \
SymI_HasDataProto(stg_tryReadMVarzh) \
SymI_HasDataProto(stg_unmaskAsyncExceptionszh) \
=====================================
rts/Threads.c
=====================================
@@ -795,8 +795,6 @@ threadStackUnderflow (Capability *cap, StgTSO *tso)
/* ----------------------------------------------------------------------------
Implementation of tryPutMVar#
-
- NOTE: this should be kept in sync with stg_tryPutMVarzh in PrimOps.cmm
------------------------------------------------------------------------- */
bool performTryPutMVar(Capability *cap, StgMVar *mvar, StgClosure *value)
=====================================
rts/Threads.h
=====================================
@@ -24,7 +24,7 @@ void migrateThread (Capability *from, StgTSO *tso, Capability *to);
//
#if defined(THREADED_RTS)
void wakeupThreadOnCapability (Capability *cap,
- Capability *other_cap,
+ Capability *other_cap,
StgTSO *tso);
#endif
@@ -40,8 +40,6 @@ StgBool isThreadBound (StgTSO* tso);
void threadStackOverflow (Capability *cap, StgTSO *tso);
W_ threadStackUnderflow (Capability *cap, StgTSO *tso);
-bool performTryPutMVar(Capability *cap, StgMVar *mvar, StgClosure *value);
-
#if defined(DEBUG)
void printThreadBlockage (StgTSO *tso);
void printThreadStatus (StgTSO *t);
=====================================
rts/include/rts/Threads.h
=====================================
@@ -90,3 +90,5 @@ extern Capability MainCapability;
// current value at the moment).
//
extern void setNumCapabilities (uint32_t new_);
+
+bool performTryPutMVar(Capability *cap, StgMVar *mvar, StgClosure *value);
=====================================
rts/include/stg/MiscClosures.h
=====================================
@@ -512,7 +512,6 @@ RTS_FUN_DECL(stg_takeMVarzh);
RTS_FUN_DECL(stg_putMVarzh);
RTS_FUN_DECL(stg_readMVarzh);
RTS_FUN_DECL(stg_tryTakeMVarzh);
-RTS_FUN_DECL(stg_tryPutMVarzh);
RTS_FUN_DECL(stg_tryReadMVarzh);
RTS_FUN_DECL(stg_waitReadzh);
=====================================
testsuite/tests/ffi/should_compile/all.T
=====================================
@@ -33,6 +33,7 @@ test(
compile,
[
'-optc=-DC -optcxx=-DCXX -optcxx=-std=c++11'
+ + ' -package=template-haskell'
+ (' -optcxx=-stdlib=libc++' if opsys('darwin') else '')
],
)
=====================================
testsuite/tests/ghci-wasm/T26998.hs
=====================================
@@ -0,0 +1,4 @@
+main :: IO ()
+main = pure ()
+
+foreign export javascript "my_main" main :: IO ()
=====================================
testsuite/tests/ghci-wasm/all.T
=====================================
@@ -10,3 +10,5 @@ test('T26430', [
extra_hc_opts('-L. -lT26430B')]
, compile_and_run, ['']
)
+
+test('T26998', [], compile_and_run, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a2567c46e7bfe5a746f415f1561826…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a2567c46e7bfe5a746f415f1561826…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/ani/kill-SrcCodeOrigin] 37 commits: Check for negative type literals in the type checker (#26861)
by Apoorv Ingle (@ani) 08 Mar '26
by Apoorv Ingle (@ani) 08 Mar '26
08 Mar '26
Apoorv Ingle pushed to branch wip/ani/kill-SrcCodeOrigin at Glasgow Haskell Compiler / GHC
Commits:
bd3eba86 by Vladislav Zavialov at 2026-02-27T05:48:01-05:00
Check for negative type literals in the type checker (#26861)
GHC disallows negative type literals (e.g., -1), as tested by T8306 and
T8412. This check is currently performed in the renamer:
rnHsTyLit tyLit@(HsNumTy x i) = do
when (i < 0) $
addErr $ TcRnNegativeNumTypeLiteral tyLit
However, this check can be bypassed using RequiredTypeArguments
(see the new test case T26861). Prior to this patch, such programs
caused the compiler to hang instead of reporting a proper error.
This patch addresses the issue by adding an equivalent check in
the type checker, namely in tcHsType.
The diff is deliberately minimal to facilitate backporting. A more
comprehensive rework of HsTyLit is planned for a separate commit.
- - - - -
faf14e0c by Vladislav Zavialov at 2026-02-27T05:48:45-05:00
Consistent pretty-printing of HsString, HsIsString, HsStrTy
Factor out a helper to pretty-print string literals, thus fixing newline
handling for overloaded string literals and type literals.
Test cases: T26860ppr T26860ppr_overloaded T26860ppr_tylit
Follow up to ddf1434ff9bb08cfef3c93f23de6b83ec698aa27
- - - - -
f108a972 by Arnaud Spiwack at 2026-02-27T12:53:01-05:00
Make list comprehension completely non-linear
Fixes #25081
From the note:
The usefulness of list comprehension in conjunction with linear types is dubious.
After all, statements are made to be run many times, for instance in
```haskell
[u | y <- [0,1], stmts]
```
both `u` and `stmts` are going to be run several times.
In principle, though, there are some position in a monad comprehension
expression which could be considered linear. We could try and make it so that
these positions are considered linear by the typechecker, but in practice the
desugarer doesn't take enough care to ensure that these are indeed desugared to
linear sites. We tried in the past, and it turned out that we'd miss a
desugaring corner case (#25772).
Until there's a demand for this very specific improvement, let's instead be
conservative, and consider list comprehension to be completely non-linear.
- - - - -
ae799cab by Simon Jakobi at 2026-02-27T12:53:54-05:00
PmAltConSet: Use Data.Set instead of Data.Map
...to store `PmLit`s.
The Map was only used to map keys to themselves.
Changing the Map to a Set saves a Word of memory per entry.
Resolves #26756.
- - - - -
dcd7819c by Vladislav Zavialov at 2026-02-27T18:46:03-05:00
Drop HsTyLit in favor of HsLit (#26862, #25121)
This patch is a small step towards unification of HsExpr and HsType,
taking care of literals (HsLit) and type literals (HsTyLit).
Additionally, it improves error messages for unsupported type literals,
such as unboxed or fractional literals (test cases: T26862, T26862_th).
Changes to the AST:
* Use HsLit where HsTyLit was previously used
* Use HsChar where HsCharTy was previously used
* Use HsString where HsStrTy was previously used
* Use HsNatural (NEW) where HsNumTy was previously used
* Use HsDouble (NEW) to represent unsupported fractional type literals
Changes to logic:
* Parse unboxed and fractional type literals (to be rejected later)
* Drop the check for negative literals in the renamer (rnHsTyLit)
in favor of checking in the type checker (tc_hs_lit_ty)
* Check for invalid type literals in TH (repTyLit) and report
unrepresentable literals with ThUnsupportedTyLit
* Allow negative type literals in TH (numTyLit). This is fine as
these will be taken care of at splice time (test case: T8306_th)
- - - - -
c927954f by Vladislav Zavialov at 2026-02-27T18:46:50-05:00
Increase test coverage of diagnostics
Add test cases for the previously untested diagnostics:
[GHC-01239] PsErrIfInFunAppExpr
[GHC-04807] PsErrProcInFunAppExpr
[GHC-08195] PsErrInvalidRecordCon
[GHC-16863] PsErrUnsupportedBoxedSumPat
[GHC-18910] PsErrSemiColonsInCondCmd
[GHC-24737] PsErrInvalidWhereBindInPatSynDecl
[GHC-25037] PsErrCaseInFunAppExpr
[GHC-25078] PsErrPrecedenceOutOfRange
[GHC-28021] PsErrRecordSyntaxInPatSynDecl
[GHC-35827] TcRnNonOverloadedSpecialisePragma
[GHC-40845] PsErrUnpackDataCon
[GHC-45106] PsErrInvalidInfixHole
[GHC-50396] PsErrInvalidRuleActivationMarker
[GHC-63930] MultiWayIfWithoutAlts
[GHC-65536] PsErrNoSingleWhereBindInPatSynDecl
[GHC-67630] PsErrMDoInFunAppExpr
[GHC-70526] PsErrLetCmdInFunAppCmd
[GHC-77808] PsErrDoCmdInFunAppCmd
[GHC-86934] ClassPE
[GHC-90355] PsErrLetInFunAppExpr
[GHC-91745] CasesExprWithoutAlts
[GHC-92971] PsErrCaseCmdInFunAppCmd
[GHC-95644] PsErrBangPatWithoutSpace
[GHC-97005] PsErrIfCmdInFunAppCmd
Remove unused error constructors:
[GHC-44524] PsErrExpectedHyphen
[GHC-91382] TcRnIllegalKindSignature
- - - - -
3a9470fd by Torsten Schmits at 2026-02-27T18:47:34-05:00
Avoid expensive computation for debug logging in `mergeDatabases` when log level is low
This computed and traversed a set intersection for every single
dependency unconditionally.
- - - - -
ea4c2cbd by Brandon Chinn at 2026-02-27T16:22:38-08:00
Implement QualifiedStrings (#26503)
See Note [Implementation of QualifiedStrings]
- - - - -
08bc245b by sheaf at 2026-03-01T11:11:54-05:00
Clean up join points, casts & ticks
This commit shores up the logic dealing with casts and ticks occurring
in between a join point binding and a jump.
Fixes #26642 #26929 #26693
Makes progress on #14610 #26157 #26422
Changes:
- Remove 'GHC.Types.Tickish.TickishScoping' in favour of simpler
predicates 'tickishHasNoScope'/'tickishHasSoftScope', as things were
before commit 993975d3. This makes the code easier to read and
document (fewer indirections).
- Introduce 'canCollectArgsThroughTick' for consistent handling of
ticks around PrimOps and other 'Id's that cannot be eta-reduced.
See overhauled Note [Ticks and mandatory eta expansion].
- New Note [JoinId vs TailCallInfo] in GHC.Core.SimpleOpt that explains
robustness of JoinId vs fragility of TailCallInfo.
- Allow casts/non-soft-scoped ticks to occur in between a join point
binder and a jump, but only in Core Prep.
See Note [Join points, casts, and ticks] and
Note [Join points, casts, and ticks... in Core Prep]
in GHC.Core.Opt.Simplify.Iteration.
Also update Core Lint to account for this.
See Note [Linting join points with casts or ticks] in GHC.Core.Lint.
- Update 'GHC.Core.Utils.mergeCaseAlts' to avoid pushing a cast in
between a join point binding and its jumps. This fixes #26642.
See the new (MC5) and (MC6) in Note [Merge Nested Cases].
- Update float out to properly handle source note ticks. They are now
properly floated out instead of being discarded.
This increases the number of ticks in certain tests with -g.
Test cases: T26642 and TrickyJoins.
Metric increase due to more source note ticks with -g:
-------------------------
Metric Increase:
libdir
size_hello_artifact
size_hello_unicode
-------------------------
- - - - -
476c4cdf by Sean D. Gillespie at 2026-03-02T10:14:37-05:00
Add SIMD absolute value on x86 and LLVM
On x86, absolute value of 32 bits or less is implemented with
PABSB/PABSW/PABSD if SSSE3 is available. Otherwise, there is a fallback
for SSE2. For 64 bit integers it uses VPABSQ, required by AVX-512VL,
with fallbacks for SSE4.2 and SSE2.
There is no dedicated instruction for floating point absolute value on
x86, so it is simulated using bitwise AND.
Absolute value for signed integers and floats are implemented by the
"llvm.abs/llvm.fabs" standard library intrinsics. This implementation
uses MachOps constructors, unlike non-vector floating point absolute
value, which uses CallishMachOps.
- - - - -
709448c0 by Sean D. Gillespie at 2026-03-02T10:14:46-05:00
Add SIMD floating point square root
On x86, this is implemented with the SQRTPS and SQRTPD instructions. On
LLVM, it uses the sqrt library intrinstic.
- - - - -
0deadf66 by Sean D. Gillespie at 2026-03-02T10:14:47-05:00
Improve error message for SIMD on aarch64
When encountering vector literals on aarch64, previously it would
throw:
<no location info>: error:
panic! (the 'impossible' happened)
GHC version 9.15.20251219:
getRegister' (CmmLit:CmmVec):
Now it is more consistent with the other vector operations:
<no location info>: error:
sorry! (unimplemented feature or known bug)
GHC version 9.15.20251219:
SIMD operations on AArch64 currently require the LLVM backend
- - - - -
7d64031b by Vladislav Zavialov at 2026-03-03T11:09:28-05:00
Replace maybeAddSpace with spaceIfSingleQuote
Simplify pretty-printing of HsTypes by using spaceIfSingleQuote.
This allows us to drop the unwieldy lhsTypeHasLeadingPromotionQuote
helper function.
Follow-up to 178c1fd830c78377ef5d338406a41e1d8eb5f0da
- - - - -
598db847 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Correct `hIsReadable` and `hIsWritable` for duplex handles
This contribution implements CLC proposal #371. It changes `hIsReadable`
and `hIsWritable` such that they always throw a respective exception
when encountering a closed or semi-closed handle, not just in the case
of a file handle.
- - - - -
b90201e5 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Document `SemiClosedHandle`
- - - - -
c9df72b5 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Tell users what “semi-closed” means for duplex handles
- - - - -
a8aa1868 by Ilias Tsitsimpis at 2026-03-06T06:26:29-05:00
Fix determinism of linker arguments
The switch from Data.Map to UniqMap in 3b5be05ac29 introduced
non-determinism in the order of packages passed to the linker.
This resulted in non-reproducible builds where the DT_NEEDED entries in
dynamic libraries were ordered differently across builds.
Fix the regression by explicitly sorting the package list derived from
UniqMap.
Fixes #26838
- - - - -
9b64ad3a by Matthew Pickering at 2026-03-06T06:27:16-05:00
determinism: Use a deterministic renaming when writing bytecode files
Now when writing the bytecode file, a counter and substitution are used
to provide deterministic keys to local variables (rather than relying on
uniques). This change ensures that `.gbc` are produced
deterministically.
Fixes #26499
- - - - -
d29800e0 by Teo Camarasu at 2026-03-06T06:28:46-05:00
ghc-internal: delete Version hs-boot loop
Version has a Read instance which needs Unicode but part of the Unicode interface is the unicode version. This is easy to resolve. We simply don't re-export the version from the Unicode module.
Resolves #26940
- - - - -
ad25af90 by Sylvain Henry at 2026-03-06T06:30:33-05:00
Linker: implement support for COMMON symbols (#6107)
Add some support for COMMON symbols. We don't support common symbols
having different sizes where the larger one is allocated after the
smaller one. The linker will fail with an appropriate error message if
it happens.
- - - - -
3b59f158 by Cheng Shao at 2026-03-06T06:31:16-05:00
compiler: fix redundant import of GHC.Hs.Lit
This patch removes a redundant import of `GHC.Hs.Lit` which causes a
ghc build failure with validate flavours when bootstrapping from 9.14.
Fixes #26972.
- - - - -
148d36f3 by Cheng Shao at 2026-03-06T06:32:01-05:00
compiler: avoid unneeded traversals in GHC.Unit.State
Following !15591, this patch avoids unneeded traversals in
`reportCycles`/`reportUnusable` when log verbosity is below given
threshold. Also applies `logVerbAtLeast` when appropriate.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
7e31367c by Cheng Shao at 2026-03-06T06:32:46-05:00
ghc-internal: fix redundant import in GHC.Internal.Event.Windows.ManagedThreadPool
This patch fixes redundant import in
`GHC.Internal.Event.Windows.ManagedThreadPool` that causes a
compilation error when building windows target with validate flavours
and bootstrapping from 9.14. Fixes #26976.
- - - - -
fc8b8e27 by sheaf at 2026-03-06T06:33:28-05:00
System.Info.fullCompilerVersion: add 'since' annot
Fixes #26973
- - - - -
c8238375 by Sylvain Henry at 2026-03-06T06:34:23-05:00
Hadrian: deprecate --bignum and automatically enable +native_bignum for JS
Deprecate --bignum=... to select the bignum backend. It's only used to
select the native backend, and this can be done with the +native_bignum
flavour transformer.
Additionally, we automatically enable +native_bignum for the JS target
because the GMP backend isn't supported.
- - - - -
a3ac7074 by Sylvain Henry at 2026-03-06T06:35:17-05:00
JS: fix putEnum/fromEnum (#24593)
Don't go through Word16 when serializing Enums.
- - - - -
0b36e96c by Andreas Klebinger at 2026-03-06T06:35:58-05:00
Docs: Document -fworker-wrapper-cbv default setting.
Fixes #26841
- - - - -
eca445e7 by mangoiv at 2026-03-07T05:02:36-05:00
drop deb9/10 from CI, add deb13
debian 9 and 10 are end of life, hence we drop them
from our CI, but we do add debian 13. Jobs that were
previously run on 9 and 10 run on 13, too, jobs that
were run on 10, are run on 11 now. Jobs that were
previously run on debian 12 are run on debian 13 now.
This MR also updates hadrian's bootstrap plans for that
reason.
Metric Decrease:
T9872d
- - - - -
12f8b829 by Luite Stegeman at 2026-03-07T05:03:33-05:00
Fix GHC.Internal.Prim haddock
Haddock used to parse Haskell source to generate documentation,
but switched to using interface files instead. This broke documentation
of the GHC.Internal.Prim module, since it's a wired-in interface that
didn't provide a document structure.
This patch adds the missing document structure and updates genprimopcode
to make the section headers and descriptions available.
fixes #26954
- - - - -
f87e5e57 by Luite Stegeman at 2026-03-07T05:03:33-05:00
Remove obsolete --make-haskell-source from genprimopcode
Now that haddock uses the wired-in interface for GHC.Internal.Prim,
the generated Haskell source file is no longer needed. Remove the
--make-haskell-source code generator from genprimopcode and replace
the generated GHC/Internal/Prim.hs with a minimal static source file.
- - - - -
4a7ddc7b by Sylvain Henry at 2026-03-07T05:04:59-05:00
JS: fix linking of exposed but non-preload units (#24886)
Units exposed in the unit database but not explicitly passed on the
command-line were not considered by the JS linker. This isn't an issue
for cabal which passes every unit explicitly but it is an issue when
using GHC directly (cf T24886 test).
- - - - -
689aafcd by mangoiv at 2026-03-07T05:05:52-05:00
testsuite: double foundation timeout multiplier
The runtime timeout in the foundation test was regularly hit by code
generated by the wasm backend - we increase the timout since the high
runtime is expected on the wasm backend for this rather complex test.
Resolves #26938
- - - - -
f2bfed15 by Apoorv Ingle at 2026-03-08T16:08:46-05:00
Work for #25001
Notes added [Error Context Stack] [Typechecking by expansion: overview]
Notes updated Note [Expanding HsDo with XXExprGhcRn]
-------------------------
Metric Decrease:
T9020
-------------------------
* Streamlines implementations of `tcExpr` and `tcXExpr` to work on `XExpr`
* Kills `VACtxt` (and its associated `VAExpansion` and `VACall`) datatype, it is subsumed by simply a `SrcSpan`.
* Kills the function `addHeadCtxt` as it is now mearly setting a location
* The function `tcValArgs` does its own argument number management
* Makes `splitHsApps` not look through `XExpr`
* `tcExprSigma` is called if the head of the expression after calling `splitHsApps` turns out to be an `XExpr`
* Removes location information from `OrigPat` payload
* Removes special case of tcBody from `tcLambdaMatches`
* Removes special case of `dsExpr` for `ExpandedThingTc`
* Rename `HsThingRn` to `SrcCodeCtxt`
* Kills `tcl_in_gen_code` and `tcl_err_ctxt`. It is subsumed by `ErrCtxtStack`
* Kills `ExpectedFunTyOrig`. It is subsumed by `CtOrigin`
* Fixes `CtOrigin` for `HsProjection` case in `exprCtOrigin`. It was previously assigned to be `SectionOrigin`. It is now just the expression
* Adds a new `CtOrigin.ExpansionOrigin` for storing the original syntax
* Adds a new `CtOrigin.ExpectedTySyntax` as a replacement for `ExpectedTySyntaxOp`. Cannot kill the former yet because of `ApplicativeDo`
* Renames `tcMonoExpr` -> `tcMonoLExpr`, `tcMonoExprNC` -> `tcMonoLExpr`
* Renames `EValArg`, `EValArgQL` fields: `ea_ctxt` -> `ea_loc_span` and `eaql_ctx` -> `eaql_loc_span`
* kill `PopErrCtxt` from `XXExprGhcRn`
* simplify `addArgCtxt` and push `setSrcSpan` inside `addLExprCtxt`. Make sure addExprCtxt is not called by itself
* fun_orig in tcApp depends on the SrcSpan of the head of the application chain (similar to addArgCtxt)
* rename fun_ctxt to fun_lspan, fun_orig passed in tcInstFun to default to app chain head if its user located, fall back to srcCodeOrigin if it's a generated location
* fix quickLookArg function to blame the correct application chain head. The arguments application chain head should be blamed, not the original head when we quick look arg
* Make sure only expression wrapped around generated src span are ignored while adding them to the error context stack
* `getDeepSubsumptionFlag_DataConHead` performs a non-trivial traversal if the expression passed to it is complex.
This traversal is necessary if the head of the function is an `XExpr` and `splitHsApps` does not look through them
- The deepsubsumption flag is stored in EVAlArgQL to reduce the need to call `getDeepSubsumptionFlag_DataConHead`
- `getDeepSubsumptionFlag_DataConHead` is called in `tcExprSigma` and `tcInferAppHead` to reduce AST traversals
* Make a new variant `GeneratedSrcSpan` in `SrcSpan` for HIEAst Nodes
* wrap `fromListN` with a generated src span with GeneratedSrcSpanDetails field to store the original srcspan
* remove `UnhelpfulGenerated` from `UnhelpfulSpanReason` and into new datatype `GeneratedSrcSpanDetails`
- - - - -
466e162c by Apoorv Ingle at 2026-03-08T16:11:02-05:00
trying to remove SrcCodeOrigin
- - - - -
2949e4c3 by Simon Peyton Jones at 2026-03-08T16:11:03-05:00
Improvements in ErrCtxt
- - - - -
5ed13f95 by Apoorv Ingle at 2026-03-08T16:11:04-05:00
ErrCtxtMsg to CtOrigin
- - - - -
b7beec74 by Apoorv Ingle at 2026-03-08T16:11:05-05:00
remove CtOrigin.ExpansionOrigin in favour of errCtxtCtOrigin, remove CtOrign from ErrMsgCtxt.FunTysCtxt
- - - - -
368 changed files:
- .gitlab-ci.yml
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- compiler/GHC.hs
- compiler/GHC/Builtin/PrimOps.hs
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/Builtin/Utils.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/Cmm/Node.hs
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/FloatIn.hs
- compiler/GHC/Core/Opt/FloatOut.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Hs/DocString.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Expr.hs-boot
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Pat.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Ext/Utils.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/HaddockLex.x
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/String.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/HsType.hs
- + compiler/GHC/Rename/Lit.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Interpreter/JS.hs
- compiler/GHC/StgToCmm/Expr.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/Object.hs
- compiler/GHC/StgToJS/Prim.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Utils.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- + compiler/GHC/Tc/Gen/App.hs-boot
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Do.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs-boot
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Match.hs-boot
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Class.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/BasicTypes.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/CtLoc.hs
- compiler/GHC/Tc/Types/ErrCtxt.hs
- compiler/GHC/Tc/Types/LclEnv.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Types/Origin.hs-boot
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcType.hs-boot
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Validity.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Error.hs
- + compiler/GHC/Types/Error.hs-boot
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/SourceText.hs
- compiler/GHC/Types/SrcLoc.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Unit/State.hs
- + compiler/GHC/Unit/State.hs-boot
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Error.hs
- compiler/GHC/Utils/Logger.hs
- compiler/Language/Haskell/Syntax/Expr.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- compiler/Language/Haskell/Syntax/Pat.hs
- compiler/Language/Haskell/Syntax/Type.hs
- compiler/ghc.cabal.in
- docs/users_guide/9.16.1-notes.rst
- + docs/users_guide/exts/qualified_strings.rst
- docs/users_guide/using-optimisation.rst
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Info.hs
- hadrian/README.md
- hadrian/bootstrap/generate_bootstrap_plans
- hadrian/bootstrap/plan-9_10_1.json
- hadrian/bootstrap/plan-9_10_2.json
- + hadrian/bootstrap/plan-9_10_3.json
- hadrian/bootstrap/plan-bootstrap-9_10_1.json
- hadrian/bootstrap/plan-bootstrap-9_10_2.json
- + hadrian/bootstrap/plan-bootstrap-9_10_3.json
- hadrian/src/CommandLine.hs
- hadrian/src/Main.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/GenPrimopCode.hs
- libraries/base/changelog.md
- libraries/base/src/GHC/Base.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/GHC/Unicode.hs
- libraries/base/src/System/Info.hs
- libraries/ghc-experimental/CHANGELOG.md
- libraries/ghc-internal/ghc-internal.cabal.in
- − libraries/ghc-internal/src/GHC/Internal/Data/Version.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/ManagedThreadPool.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Text.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Types.hs
- libraries/ghc-internal/src/GHC/Internal/LanguageExtensions.hs
- + libraries/ghc-internal/src/GHC/Internal/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Version.hs
- libraries/ghc-internal/tools/ucd2haskell/exe/UCD2Haskell/ModuleGenerators.hs
- rts/Linker.c
- rts/LinkerInternals.h
- rts/linker/Elf.c
- rts/linker/MachO.c
- rts/linker/PEi386.c
- testsuite/driver/perf_notes.py
- testsuite/tests/codeGen/should_compile/debug.stdout
- + testsuite/tests/dependent/should_fail/SelfDepCls.hs
- + testsuite/tests/dependent/should_fail/SelfDepCls.stderr
- testsuite/tests/dependent/should_fail/all.T
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/driver/T4437.hs
- testsuite/tests/ghc-api/annotations-literals/literals.stdout
- testsuite/tests/ghc-api/annotations-literals/parsed.hs
- testsuite/tests/ghci/should_run/all.T
- testsuite/tests/indexed-types/should_fail/T2693.stderr
- testsuite/tests/indexed-types/should_fail/T5439.stderr
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- + testsuite/tests/javascript/T24886.hs
- + testsuite/tests/javascript/T24886.stderr
- + testsuite/tests/javascript/T24886.stdout
- testsuite/tests/javascript/all.T
- − testsuite/tests/linear/should_compile/LinearListComprehension.hs
- testsuite/tests/linear/should_compile/all.T
- testsuite/tests/linear/should_fail/T25081.hs
- testsuite/tests/linear/should_fail/T25081.stderr
- testsuite/tests/module/all.T
- + testsuite/tests/module/mod70b.hs
- + testsuite/tests/module/mod70b.stderr
- testsuite/tests/numeric/should_run/all.T
- testsuite/tests/overloadedrecflds/should_compile/all.T
- testsuite/tests/overloadedrecflds/should_fail/T26480b.stderr
- testsuite/tests/overloadedrecflds/should_run/all.T
- + testsuite/tests/parser/should_fail/NoBlockArgumentsFail4.hs
- + testsuite/tests/parser/should_fail/NoBlockArgumentsFail4.stderr
- testsuite/tests/parser/should_fail/NoBlockArgumentsFailArrowCmds.hs
- testsuite/tests/parser/should_fail/NoBlockArgumentsFailArrowCmds.stderr
- + testsuite/tests/parser/should_fail/NoDoAndIfThenElseArrowCmds.hs
- + testsuite/tests/parser/should_fail/NoDoAndIfThenElseArrowCmds.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail10.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail11.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
- + testsuite/tests/parser/should_fail/T26860ppr_overloaded.hs
- + testsuite/tests/parser/should_fail/T26860ppr_overloaded.stderr
- + testsuite/tests/parser/should_fail/T26860ppr_tylit.hs
- + testsuite/tests/parser/should_fail/T26860ppr_tylit.stderr
- testsuite/tests/parser/should_fail/all.T
- + testsuite/tests/parser/should_fail/badRuleMarker.hs
- + testsuite/tests/parser/should_fail/badRuleMarker.stderr
- + testsuite/tests/parser/should_fail/patFail010.hs
- + testsuite/tests/parser/should_fail/patFail010.stderr
- + testsuite/tests/parser/should_fail/patFail011.hs
- + testsuite/tests/parser/should_fail/patFail011.stderr
- + testsuite/tests/parser/should_fail/precOutOfRange.hs
- + testsuite/tests/parser/should_fail/precOutOfRange.stderr
- + testsuite/tests/parser/should_fail/unpack_data_con.hs
- + testsuite/tests/parser/should_fail/unpack_data_con.stderr
- testsuite/tests/patsyn/should_fail/T10426.stderr
- testsuite/tests/patsyn/should_fail/all.T
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail1.hs
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail1.stderr
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail2.hs
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail2.stderr
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail3.hs
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail3.stderr
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail4.hs
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail4.stderr
- testsuite/tests/plugins/test-defaulting-plugin.stderr
- testsuite/tests/pmcheck/should_compile/T11303.hs
- testsuite/tests/printer/T17697.stderr
- + testsuite/tests/qualified-strings/Makefile
- + testsuite/tests/qualified-strings/should_compile/Example/Length.hs
- + testsuite/tests/qualified-strings/should_compile/all.T
- + testsuite/tests/qualified-strings/should_compile/qstrings_redundant_pattern.hs
- + testsuite/tests/qualified-strings/should_compile/qstrings_redundant_pattern.stderr
- + testsuite/tests/qualified-strings/should_fail/Example/Length.hs
- + testsuite/tests/qualified-strings/should_fail/Makefile
- + testsuite/tests/qualified-strings/should_fail/all.T
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_expr.hs
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_expr.stderr
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_pat.hs
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_pat.stderr
- + testsuite/tests/qualified-strings/should_fail/qstrings_multiline_no_ext.hs
- + testsuite/tests/qualified-strings/should_fail/qstrings_multiline_no_ext.stderr
- + testsuite/tests/qualified-strings/should_run/Example/ByteStringAscii.hs
- + testsuite/tests/qualified-strings/should_run/Example/ByteStringUtf8.hs
- + testsuite/tests/qualified-strings/should_run/Example/Text.hs
- + testsuite/tests/qualified-strings/should_run/Makefile
- + testsuite/tests/qualified-strings/should_run/all.T
- + testsuite/tests/qualified-strings/should_run/qstrings_expr.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_expr.stdout
- + testsuite/tests/qualified-strings/should_run/qstrings_pat.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_pat.stdout
- + testsuite/tests/qualified-strings/should_run/qstrings_th.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_th.stdout
- testsuite/tests/quasiquotation/qq005/test.T
- testsuite/tests/quasiquotation/qq006/test.T
- testsuite/tests/rebindable/rebindable6.stderr
- testsuite/tests/rep-poly/RepPolyDoBind.stderr
- testsuite/tests/rep-poly/RepPolyDoBody1.stderr
- testsuite/tests/rep-poly/RepPolyDoBody2.stderr
- testsuite/tests/rep-poly/RepPolyRecordUpdate.stderr
- testsuite/tests/rts/linker/Makefile
- + testsuite/tests/rts/linker/T6107.hs
- + testsuite/tests/rts/linker/T6107.stdout
- + testsuite/tests/rts/linker/T6107_sym1.s
- + testsuite/tests/rts/linker/T6107_sym2.s
- testsuite/tests/rts/linker/all.T
- testsuite/tests/saks/should_compile/all.T
- testsuite/tests/showIface/all.T
- testsuite/tests/simd/should_run/doublex2_arith.hs
- testsuite/tests/simd/should_run/doublex2_arith.stdout
- testsuite/tests/simd/should_run/doublex2_arith_baseline.hs
- testsuite/tests/simd/should_run/doublex2_arith_baseline.stdout
- testsuite/tests/simd/should_run/floatx4_arith.hs
- testsuite/tests/simd/should_run/floatx4_arith.stdout
- testsuite/tests/simd/should_run/floatx4_arith_baseline.hs
- testsuite/tests/simd/should_run/floatx4_arith_baseline.stdout
- testsuite/tests/simd/should_run/int16x8_arith.hs
- testsuite/tests/simd/should_run/int16x8_arith.stdout
- testsuite/tests/simd/should_run/int16x8_arith_baseline.hs
- testsuite/tests/simd/should_run/int16x8_arith_baseline.stdout
- testsuite/tests/simd/should_run/int32x4_arith.hs
- testsuite/tests/simd/should_run/int32x4_arith.stdout
- testsuite/tests/simd/should_run/int32x4_arith_baseline.hs
- testsuite/tests/simd/should_run/int32x4_arith_baseline.stdout
- testsuite/tests/simd/should_run/int64x2_arith.hs
- testsuite/tests/simd/should_run/int64x2_arith.stdout
- testsuite/tests/simd/should_run/int64x2_arith_baseline.hs
- testsuite/tests/simd/should_run/int64x2_arith_baseline.stdout
- testsuite/tests/simd/should_run/int8x16_arith.hs
- testsuite/tests/simd/should_run/int8x16_arith.stdout
- testsuite/tests/simd/should_run/int8x16_arith_baseline.hs
- testsuite/tests/simd/should_run/int8x16_arith_baseline.stdout
- + testsuite/tests/simplCore/should_compile/T26642.hs
- + testsuite/tests/simplCore/should_compile/TrickyJoins.hs
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/th/T26862_th.script
- + testsuite/tests/th/T26862_th.stderr
- + testsuite/tests/th/T8306_th.script
- + testsuite/tests/th/T8306_th.stderr
- + testsuite/tests/th/T8306_th.stdout
- testsuite/tests/th/T8412.stderr
- + testsuite/tests/th/TH_EmptyLamCases.hs
- + testsuite/tests/th/TH_EmptyLamCases.stderr
- + testsuite/tests/th/TH_EmptyMultiIf.hs
- + testsuite/tests/th/TH_EmptyMultiIf.stderr
- testsuite/tests/th/all.T
- + testsuite/tests/typecheck/should_compile/ExpansionQLIm.hs
- testsuite/tests/typecheck/should_compile/T14590.stderr
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/valid_hole_fits.stderr
- testsuite/tests/typecheck/should_fail/DoExpansion1.stderr
- testsuite/tests/typecheck/should_fail/DoExpansion2.stderr
- testsuite/tests/typecheck/should_fail/T10971d.stderr
- testsuite/tests/typecheck/should_fail/T13311.stderr
- + testsuite/tests/typecheck/should_fail/T26861.hs
- + testsuite/tests/typecheck/should_fail/T26861.stderr
- + testsuite/tests/typecheck/should_fail/T26862.hs
- + testsuite/tests/typecheck/should_fail/T26862.stderr
- testsuite/tests/typecheck/should_fail/T3323.stderr
- testsuite/tests/typecheck/should_fail/T3613.stderr
- testsuite/tests/typecheck/should_fail/T6069.stderr
- testsuite/tests/typecheck/should_fail/T7851.stderr
- testsuite/tests/typecheck/should_fail/T7857.stderr
- testsuite/tests/typecheck/should_fail/T8306.stderr
- testsuite/tests/typecheck/should_fail/T8603.stderr
- testsuite/tests/typecheck/should_fail/T9612.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail102.stderr
- testsuite/tests/typecheck/should_fail/tcfail128.stderr
- testsuite/tests/typecheck/should_fail/tcfail140.stderr
- testsuite/tests/typecheck/should_fail/tcfail181.stderr
- testsuite/tests/unboxedsums/all.T
- + testsuite/tests/unboxedsums/unboxedsums4p.hs
- + testsuite/tests/unboxedsums/unboxedsums4p.stderr
- testsuite/tests/vdq-rta/should_compile/all.T
- + testsuite/tests/warnings/should_compile/SpecMultipleTysMono.hs
- + testsuite/tests/warnings/should_compile/SpecMultipleTysMono.stderr
- testsuite/tests/warnings/should_compile/all.T
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Parsers.hs
- utils/check-exact/Transform.hs
- utils/check-exact/Utils.hs
- utils/genprimopcode/Main.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Parser.hs
- utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Utils.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f9ab1b23f2e2611bfd0a2a5d6c5fd7…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f9ab1b23f2e2611bfd0a2a5d6c5fd7…
You're receiving this email because of your account on gitlab.haskell.org.
1
0