
[Git][ghc/ghc][wip/splice-imports-2025] 20 commits: Refactor Handling of Multiple Default Declarations
by Matthew Pickering (@mpickering) 25 Apr '25
by Matthew Pickering (@mpickering) 25 Apr '25
25 Apr '25
Matthew Pickering pushed to branch wip/splice-imports-2025 at Glasgow Haskell Compiler / GHC
Commits:
e0f3ff11 by Patrick at 2025-04-17T04:31:12-04:00
Refactor Handling of Multiple Default Declarations
Fixes: #25912, #25914, #25934
Previously, GHC discarded all loaded defaults (tcg_default) when local
defaults were encountered during typechecking. According to the
exportable-named-default proposal (sections 2.4.2 and 2.4.3), local
defaults should be merged into tcg_default, retaining any defaults
already present while overriding where necessary.
Key Changes:
* Introduce DefaultProvenance to track the origin of default declarations
(local, imported, or built-in), replacing the original cd_module
in ClassDefaults with cd_provenance :: DefaultProvenance.
* Rename tcDefaults to tcDefaultDecls, limiting its responsibility to only
converting renamed class defaults into ClassDefaults.
* Add extendDefaultEnvWithLocalDefaults to merge local defaults into the
environment, with proper duplication checks:
- Duplicate local defaults for a class trigger an error.
- Local defaults override imported or built-in defaults.
* Update and add related notes: Note [Builtin class defaults],
Note [DefaultProvenance].
* Add regression tests: T25912, T25914, T25934.
Thanks sam and simon for the help on this patch.
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
386f1854 by Teo Camarasu at 2025-04-17T04:31:55-04:00
template-haskell: Remove `addrToByteArrayName` and `addrToByteArray`
These were part of the implementation of the `Lift ByteArray` instance and were errornously exported because this module lacked an explicit export list. They have no usages on Hackage.
Resolves #24782
- - - - -
b96e2f77 by Sylvain Henry at 2025-04-18T20:46:33-04:00
RTS: remove target info and fix host info (#24058)
The RTS isn't a compiler, hence it doesn't have a target and we remove
the reported target info displayed by "+RTS --info". We also fix the
host info displayed by "+RTS --info": the host of the RTS is the
RTS-building compiler's target, not the compiler's host (wrong when
doing cross-compilation).
- - - - -
6d9965f4 by Sylvain Henry at 2025-04-18T20:46:33-04:00
RTS: remove build info
As per the discussion in !13967, there is no reason to tag the RTS with
information about the build platform.
- - - - -
d52e9b3f by Vladislav Zavialov at 2025-04-18T20:47:15-04:00
Diagnostics: remove the KindMismatch constructor (#25957)
The KindMismatch constructor was only used as an intermediate
representation in pretty-printing.
Its removal addresses a problem detected by the "codes" test case:
[GHC-89223] is untested (constructor = KindMismatch)
In a concious deviation from the usual procedure, the error code
GHC-89223 is removed entirely rather than marked as Outdated.
The reason is that it never was user-facing in the first place.
- - - - -
e2f2f9d0 by Vladislav Zavialov at 2025-04-20T10:53:39-04:00
Add name for -Wunusable-unpack-pragmas
This warning had no name or flag and was triggered unconditionally.
Now it is part of -Wdefault.
In GHC.Tc.TyCl.tcTyClGroupsPass's strict mode, we now have to
force-enable this warning to ensure that detection of flawed groups
continues to work even if the user disables the warning with the
-Wno-unusable-unpack-pragmas option. Test case: T3990c
Also, the misnamed BackpackUnpackAbstractType is now called
UnusableUnpackPragma.
- - - - -
6caa6508 by Adam Gundry at 2025-04-20T10:54:22-04:00
Fix specialisation of incoherent instances (fixes #25883)
GHC normally assumes that class constraints are canonical, meaning that
the specialiser is allowed to replace one dictionary argument with another
provided that they have the same type. The `-fno-specialise-incoherents`
flag alters INCOHERENT instance definitions so that they will prevent
specialisation in some cases, by inserting `nospec`.
This commit fixes a bug in 7124e4ad76d98f1fc246ada4fd7bf64413ff2f2e, which
treated some INCOHERENT instance matches as if `-fno-specialise-incoherents`
was in effect, thereby unnecessarily preventing specialisation. In addition
it updates the relevant `Note [Rules for instance lookup]` and adds a new
`Note [Canonicity for incoherent matches]`.
- - - - -
0426fd6c by Adam Gundry at 2025-04-20T10:54:23-04:00
Add regression test for #23429
- - - - -
eec96527 by Adam Gundry at 2025-04-20T10:54:23-04:00
user's guide: update specification of overlapping/incoherent instances
The description of the instance resolution algorithm in the user's
guide was slightly out of date, because it mentioned in-scope given
constraints only at the end, whereas the implementation checks for
their presence before any of the other steps.
This also adds a warning to the user's guide about the impact of
incoherent instances on specialisation, and more clearly documents
some of the other effects of `-XIncoherentInstances`.
- - - - -
a00eeaec by Matthew Craven at 2025-04-20T10:55:03-04:00
Fix bytecode generation for `tagToEnum# <LITERAL>`
Fixes #25975.
- - - - -
2e204269 by Andreas Klebinger at 2025-04-22T12:20:41+02:00
Simplifier: Constant fold invald tagToEnum# calls to bottom expr.
When applying tagToEnum# to a out-of-range value it's best to simply
constant fold it to a bottom expression. That potentially allows more
dead code elimination and makes debugging easier.
Fixes #25976
- - - - -
7250fc0c by Matthew Pickering at 2025-04-22T16:24:04-04:00
Move -fno-code note into Downsweep module
This note was left behind when all the code which referred to it was
moved into the GHC.Driver.Downsweep module
- - - - -
d2dc89b4 by Matthew Pickering at 2025-04-22T16:24:04-04:00
Apply editing notes to Note [-fno-code mode] suggested by sheaf
These notes were suggested in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/14241
- - - - -
91564daf by Matthew Pickering at 2025-04-24T00:29:02-04:00
ghci: Use loadInterfaceForModule rather than loadSrcInterface in mkTopLevEnv
loadSrcInterface takes a user given `ModuleName` and resolves it to the
module which needs to be loaded (taking into account module
renaming/visibility etc).
loadInterfaceForModule takes a specific module and loads it.
The modules in `ImpDeclSpec` have already been resolved to the actual
module to get the information from during renaming. Therefore we just
need to fetch the precise interface from disk (and not attempt to rename
it again).
Fixes #25951
- - - - -
2e0c07ab by Simon Peyton Jones at 2025-04-24T00:29:43-04:00
Test for #23298
- - - - -
0eef99b0 by Sven Tennie at 2025-04-24T07:34:36-04:00
RV64: Introduce J instruction (non-local jumps) and don't deallocate stack slots for J_TBL (#25738)
J_TBL result in local jumps, there should not deallocate stack slots
(see Note [extra spill slots].)
J is for non-local jumps, these may need to deallocate stack slots.
- - - - -
1bd3d13e by fendor at 2025-04-24T07:35:17-04:00
Add `UnitId` to `EvalBreakpoint`
The `EvalBreakpoint` is used to communicate that a breakpoint was
encountered during code evaluation.
This `EvalBreakpoint` needs to be converted to an `InternalBreakpointId`
which stores a `Module` to uniquely find the correct `Module` in the
Home Package Table.
The `EvalBreakpoint` used to store only a `ModuleName` which is then
converted to a `Module` based on the currently active home unit.
This is incorrect in the face of multiple home units, the break point
could be in an entirely other home unit!
To fix this, we additionally store the `UnitId` of the `Module` in
`EvalBreakpoint` to later reconstruct the correct `Module`
All of the changes are the consequence of extending `EvalBreakpoint`
with the additional `ShortByteString` of the `UnitId`.
For performance reasons, we store the `ShortByteString` backing the
`UnitId` directly, avoiding marshalling overhead.
- - - - -
fe6ed8d9 by Sylvain Henry at 2025-04-24T18:04:12-04:00
Doc: add doc for JS interruptible calling convention (#24444)
- - - - -
6111c5e4 by Ben Gamari at 2025-04-24T18:04:53-04:00
compiler: Ensure that Panic.Plain.assertPanic' provides callstack
In 36cddd2ce1a3bc62ea8a1307d8bc6006d54109cf @alt-romes removed CallStack
output from `GHC.Utils.Panic.Plain.assertPanic'`. While this output is
redundant due to the exception backtrace proposal, we may be
bootstrapping with a compiler which does not yet include this machinery.
Reintroduce the output for now.
Fixes #25898.
- - - - -
b071c7a1 by Matthew Pickering at 2025-04-25T15:54:01+01:00
Implement Explicit Level Imports for Template Haskell
This commit introduces the `ExplicitLevelImports` and
`ImplicitStagePersistence` language extensions as proposed in GHC
Proposal #682.
Key Features
------------
- `ExplicitLevelImports` adds two new import modifiers - `splice` and
`quote` - allowing precise control over the level at which imported
identifiers are available
- `ImplicitStagePersistence` (enabled by default) preserves existing
path-based cross-stage persistence behavior
- `NoImplicitStagePersistence` disables implicit cross-stage
persistence, requiring explicit level imports
Benefits
--------
- Improved compilation performance by reducing unnecessary code generation
- Enhanced IDE experience with faster feedback in `-fno-code` mode
- Better dependency tracking by distinguishing compile-time and runtime dependencies
- Foundation for future cross-compilation improvements
This implementation enables the separation of modules needed at
compile-time from those needed at runtime, allowing for more efficient
compilation pipelines and clearer code organization in projects using
Template Haskell.
Implementation Notes
--------------------
The level which a name is availble at is stored in the 'GRE', in the normal
GlobalRdrEnv. The function `greLevels` returns the levels which a specific GRE
is imported at. The level information for a 'Name' is computed by `getCurrentAndBindLevel`.
The level validity is checked by `checkCrossLevelLifting`.
Instances are checked by `checkWellLevelledDFun`, which computes the level an
instance by calling `checkWellLevelledInstanceWhat`, which sees what is
available at by looking at the module graph.
Modifications to downsweep
--------------------------
Code generation is now only enabled for modules which are needed at
compile time.
See the Note [-fno-code mode] for more information.
Uniform error messages for level errors
---------------------------------------
All error messages to do with levels are now reported uniformly using
the `TcRnBadlyStaged` constructor.
Error messages are uniformly reported in terms of levels.
0 - top-level
1 - quote level
-1 - splice level
The only level hard-coded into the compiler is the top-level in
GHC.Types.ThLevelIndex.topLevelIndex.
Uniformly refer to levels and stages
------------------------------------
There was much confusion about levels vs stages in the compiler.
A level is a semantic concept, used by the typechecker to ensure a
program can be evaluated in a well-staged manner.
A stage is an operational construct, program evaluation proceeds in
stages.
Deprecate -Wbadly-staged-types
------------------------------
`-Wbadly-staged-types` is deprecated in favour of `-Wbadly-levelled-types`.
Lift derivation changed
-----------------------
Derived lift instances will now not generate code with expression
quotations.
Before:
```
data A = A Int deriving Lift
=>
lift (A x) = [| A $(lift x) |]
```
After:
```
lift (A x) = conE 'A `appE` (lift x)
```
This is because if you attempt to derive `Lift` in a module where
`NoImplicitStagePersistence` is enabled, you would get an infinite loop
where a constructor was attempted to be persisted using the instance you
are currently defining.
GHC API Changes
---------------
The ModuleGraph now contains additional information about the type of
the edges (normal, quote or splice) between modules. This is abstracted
using the `ModuleGraphEdge` data type.
Fixes #25828
-------------------------
Metric Increase:
MultiLayerModulesTH_Make
-------------------------
- - - - -
341 changed files:
- compiler/GHC.hs
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/Instr.hs
- compiler/GHC/CmmToAsm/RV64/Ppr.hs
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Core/Opt/ConstantFold.hs
- compiler/GHC/Data/Graph/Directed/Reachability.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/Header.hs
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/Runtime/Loader.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/Tc/Deriv/Generate.hs
- compiler/GHC/Tc/Deriv/Utils.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Default.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Plugin.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/LclEnv.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Types/TH.hs
- compiler/GHC/Tc/Utils/Backpack.hs
- compiler/GHC/Tc/Utils/Concrete.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/DefaultEnv.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/Name/Reader.hs
- + compiler/GHC/Types/ThLevelIndex.hs
- compiler/GHC/Unit/Home/PackageTable.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/Imported.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- + compiler/GHC/Unit/Module/Stage.hs
- compiler/GHC/Unit/Types.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/GHC/Utils/Panic/Plain.hs
- compiler/Language/Haskell/Syntax/ImpExp.hs
- + compiler/Language/Haskell/Syntax/ImpExp/IsBoot.hs
- compiler/ghc.cabal.in
- configure.ac
- docs/users_guide/9.14.1-notes.rst
- docs/users_guide/exts/control.rst
- docs/users_guide/exts/instances.rst
- docs/users_guide/exts/template_haskell.rst
- docs/users_guide/javascript.rst
- docs/users_guide/phases.rst
- docs/users_guide/using-warnings.rst
- ghc/GHCi/UI.hs
- hadrian/src/Settings/Packages.hs
- libraries/base/tests/IO/Makefile
- libraries/ghc-internal/src/GHC/Internal/LanguageExtensions.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/Run.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- libraries/template-haskell/changelog.md
- rts/Exception.cmm
- rts/Interpreter.c
- rts/RtsUtils.c
- testsuite/ghc-config/ghc-config.hs
- testsuite/tests/ado/ado004.stderr
- testsuite/tests/annotations/should_fail/annfail03.stderr
- testsuite/tests/annotations/should_fail/annfail04.stderr
- testsuite/tests/annotations/should_fail/annfail06.stderr
- testsuite/tests/annotations/should_fail/annfail09.stderr
- + testsuite/tests/bytecode/T25975.hs
- + testsuite/tests/bytecode/T25975.stdout
- testsuite/tests/bytecode/all.T
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/default/T25912.hs
- + testsuite/tests/default/T25912.stdout
- + testsuite/tests/default/T25912_helper.hs
- + testsuite/tests/default/T25914.hs
- + testsuite/tests/default/T25934.hs
- testsuite/tests/default/all.T
- testsuite/tests/default/default-fail03.stderr
- testsuite/tests/dependent/should_compile/T14729.stderr
- testsuite/tests/dependent/should_compile/T15743.stderr
- testsuite/tests/dependent/should_compile/T15743e.stderr
- testsuite/tests/deriving/should_compile/T14682.stderr
- testsuite/tests/determinism/determ021/determ021.stdout
- testsuite/tests/diagnostic-codes/codes.stdout
- + testsuite/tests/driver/T4437.stdout
- testsuite/tests/driver/json2.stderr
- testsuite/tests/gadt/T19847a.stderr
- + testsuite/tests/gadt/T23298.hs
- + testsuite/tests/gadt/T23298.stderr
- testsuite/tests/gadt/all.T
- testsuite/tests/ghc-api/fixed-nodes/FixedNodes.hs
- testsuite/tests/ghc-api/fixed-nodes/ModuleGraphInvariants.hs
- + testsuite/tests/ghci/scripts/GhciPackageRename.hs
- + testsuite/tests/ghci/scripts/GhciPackageRename.script
- + testsuite/tests/ghci/scripts/GhciPackageRename.stdout
- testsuite/tests/ghci/scripts/all.T
- testsuite/tests/indexed-types/should_compile/T15711.stderr
- testsuite/tests/indexed-types/should_compile/T15852.stderr
- testsuite/tests/indexed-types/should_compile/T3017.stderr
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- testsuite/tests/linters/notes.stdout
- testsuite/tests/module/mod185.stderr
- testsuite/tests/module/mod58.stderr
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/DumpSemis.stderr
- testsuite/tests/parser/should_compile/KindSigs.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/partial-sigs/should_compile/ADT.stderr
- testsuite/tests/partial-sigs/should_compile/AddAndOr1.stderr
- testsuite/tests/partial-sigs/should_compile/AddAndOr2.stderr
- testsuite/tests/partial-sigs/should_compile/AddAndOr3.stderr
- testsuite/tests/partial-sigs/should_compile/AddAndOr4.stderr
- testsuite/tests/partial-sigs/should_compile/AddAndOr5.stderr
- testsuite/tests/partial-sigs/should_compile/AddAndOr6.stderr
- testsuite/tests/partial-sigs/should_compile/BoolToBool.stderr
- testsuite/tests/partial-sigs/should_compile/DataFamilyInstanceLHS.stderr
- testsuite/tests/partial-sigs/should_compile/Defaulting1MROn.stderr
- testsuite/tests/partial-sigs/should_compile/Defaulting2MROff.stderr
- testsuite/tests/partial-sigs/should_compile/Defaulting2MROn.stderr
- testsuite/tests/partial-sigs/should_compile/Either.stderr
- testsuite/tests/partial-sigs/should_compile/EqualityConstraint.stderr
- testsuite/tests/partial-sigs/should_compile/Every.stderr
- testsuite/tests/partial-sigs/should_compile/EveryNamed.stderr
- testsuite/tests/partial-sigs/should_compile/ExpressionSig.stderr
- testsuite/tests/partial-sigs/should_compile/ExpressionSigNamed.stderr
- testsuite/tests/partial-sigs/should_compile/ExtraConstraints1.stderr
- testsuite/tests/partial-sigs/should_compile/ExtraConstraints2.stderr
- testsuite/tests/partial-sigs/should_compile/ExtraConstraints3.stderr
- testsuite/tests/partial-sigs/should_compile/ExtraNumAMROff.stderr
- testsuite/tests/partial-sigs/should_compile/ExtraNumAMROn.stderr
- testsuite/tests/partial-sigs/should_compile/Forall1.stderr
- testsuite/tests/partial-sigs/should_compile/GenNamed.stderr
- testsuite/tests/partial-sigs/should_compile/HigherRank1.stderr
- testsuite/tests/partial-sigs/should_compile/HigherRank2.stderr
- testsuite/tests/partial-sigs/should_compile/LocalDefinitionBug.stderr
- testsuite/tests/partial-sigs/should_compile/Meltdown.stderr
- testsuite/tests/partial-sigs/should_compile/MonoLocalBinds.stderr
- testsuite/tests/partial-sigs/should_compile/NamedTyVar.stderr
- testsuite/tests/partial-sigs/should_compile/NamedWildcardInDataFamilyInstanceLHS.stderr
- testsuite/tests/partial-sigs/should_compile/NamedWildcardInTypeFamilyInstanceLHS.stderr
- testsuite/tests/partial-sigs/should_compile/ParensAroundContext.stderr
- testsuite/tests/partial-sigs/should_compile/PatBind.stderr
- testsuite/tests/partial-sigs/should_compile/PatBind2.stderr
- testsuite/tests/partial-sigs/should_compile/PatternSig.stderr
- testsuite/tests/partial-sigs/should_compile/Recursive.stderr
- testsuite/tests/partial-sigs/should_compile/ScopedNamedWildcards.stderr
- testsuite/tests/partial-sigs/should_compile/ScopedNamedWildcardsGood.stderr
- testsuite/tests/partial-sigs/should_compile/ShowNamed.stderr
- testsuite/tests/partial-sigs/should_compile/SimpleGen.stderr
- testsuite/tests/partial-sigs/should_compile/SkipMany.stderr
- testsuite/tests/partial-sigs/should_compile/SomethingShowable.stderr
- testsuite/tests/partial-sigs/should_compile/TypeFamilyInstanceLHS.stderr
- testsuite/tests/partial-sigs/should_compile/Uncurry.stderr
- testsuite/tests/partial-sigs/should_compile/UncurryNamed.stderr
- testsuite/tests/partial-sigs/should_compile/WarningWildcardInstantiations.stderr
- testsuite/tests/polykinds/T15592.stderr
- testsuite/tests/polykinds/T15592b.stderr
- testsuite/tests/printer/T18052a.stderr
- testsuite/tests/quasiquotation/qq001/qq001.stderr
- testsuite/tests/quasiquotation/qq002/qq002.stderr
- testsuite/tests/quasiquotation/qq003/qq003.stderr
- testsuite/tests/quasiquotation/qq004/qq004.stderr
- + testsuite/tests/quotes/T5721.stderr
- testsuite/tests/roles/should_compile/Roles1.stderr
- testsuite/tests/roles/should_compile/Roles14.stderr
- testsuite/tests/roles/should_compile/Roles2.stderr
- testsuite/tests/roles/should_compile/Roles3.stderr
- testsuite/tests/roles/should_compile/Roles4.stderr
- testsuite/tests/roles/should_compile/T8958.stderr
- testsuite/tests/showIface/DocsInHiFile1.stdout
- testsuite/tests/showIface/DocsInHiFileTH.stdout
- testsuite/tests/showIface/HaddockIssue849.stdout
- testsuite/tests/showIface/HaddockOpts.stdout
- testsuite/tests/showIface/HaddockSpanIssueT24378.stdout
- testsuite/tests/showIface/LanguageExts.stdout
- testsuite/tests/showIface/MagicHashInHaddocks.stdout
- testsuite/tests/showIface/NoExportList.stdout
- testsuite/tests/showIface/PragmaDocs.stdout
- testsuite/tests/showIface/ReExports.stdout
- testsuite/tests/simplCore/should_compile/Makefile
- testsuite/tests/simplCore/should_compile/T23307c.stderr
- + testsuite/tests/simplCore/should_compile/T25883.hs
- + testsuite/tests/simplCore/should_compile/T25883.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883b.hs
- + testsuite/tests/simplCore/should_compile/T25883b.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883c.hs
- + testsuite/tests/simplCore/should_compile/T25883c.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883d.hs
- + testsuite/tests/simplCore/should_compile/T25883d.stderr
- + testsuite/tests/simplCore/should_compile/T25883d_import.hs
- + testsuite/tests/simplCore/should_compile/T25976.hs
- + testsuite/tests/simplCore/should_compile/T3990c.hs
- + testsuite/tests/simplCore/should_compile/T3990c.stdout
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_fail/T25672.stderr
- + testsuite/tests/simplCore/should_run/T23429.hs
- + testsuite/tests/simplCore/should_run/T23429.stdout
- testsuite/tests/simplCore/should_run/all.T
- + testsuite/tests/splice-imports/ClassA.hs
- + testsuite/tests/splice-imports/InstanceA.hs
- + testsuite/tests/splice-imports/Makefile
- + testsuite/tests/splice-imports/SI01.hs
- + testsuite/tests/splice-imports/SI01A.hs
- + testsuite/tests/splice-imports/SI02.hs
- + testsuite/tests/splice-imports/SI03.hs
- + testsuite/tests/splice-imports/SI03.stderr
- + testsuite/tests/splice-imports/SI04.hs
- + testsuite/tests/splice-imports/SI05.hs
- + testsuite/tests/splice-imports/SI05.stderr
- + testsuite/tests/splice-imports/SI05A.hs
- + testsuite/tests/splice-imports/SI06.hs
- + testsuite/tests/splice-imports/SI07.hs
- + testsuite/tests/splice-imports/SI07.stderr
- + testsuite/tests/splice-imports/SI07A.hs
- + testsuite/tests/splice-imports/SI08.hs
- + testsuite/tests/splice-imports/SI08.stderr
- + testsuite/tests/splice-imports/SI08_oneshot.stderr
- + testsuite/tests/splice-imports/SI09.hs
- + testsuite/tests/splice-imports/SI10.hs
- + testsuite/tests/splice-imports/SI13.hs
- + testsuite/tests/splice-imports/SI14.hs
- + testsuite/tests/splice-imports/SI14.stderr
- + testsuite/tests/splice-imports/SI15.hs
- + testsuite/tests/splice-imports/SI15.stderr
- + testsuite/tests/splice-imports/SI16.hs
- + testsuite/tests/splice-imports/SI16.stderr
- + testsuite/tests/splice-imports/SI17.hs
- + testsuite/tests/splice-imports/SI18.hs
- + testsuite/tests/splice-imports/SI18.stderr
- + testsuite/tests/splice-imports/SI19.hs
- + testsuite/tests/splice-imports/SI19A.hs
- + testsuite/tests/splice-imports/SI20.hs
- + testsuite/tests/splice-imports/SI20.stderr
- + testsuite/tests/splice-imports/SI21.hs
- + testsuite/tests/splice-imports/SI21.stderr
- + testsuite/tests/splice-imports/SI22.hs
- + testsuite/tests/splice-imports/SI22.stderr
- + testsuite/tests/splice-imports/SI23.hs
- + testsuite/tests/splice-imports/SI23A.hs
- + testsuite/tests/splice-imports/SI24.hs
- + testsuite/tests/splice-imports/SI25.hs
- + testsuite/tests/splice-imports/SI25.stderr
- + testsuite/tests/splice-imports/SI25Helper.hs
- + testsuite/tests/splice-imports/SI26.hs
- + testsuite/tests/splice-imports/SI27.hs
- + testsuite/tests/splice-imports/SI27.stderr
- + testsuite/tests/splice-imports/SI28.hs
- + testsuite/tests/splice-imports/SI28.stderr
- + testsuite/tests/splice-imports/SI29.hs
- + testsuite/tests/splice-imports/SI29.stderr
- + testsuite/tests/splice-imports/SI30.script
- + testsuite/tests/splice-imports/SI30.stdout
- + testsuite/tests/splice-imports/SI31.script
- + testsuite/tests/splice-imports/SI31.stderr
- + testsuite/tests/splice-imports/SI32.script
- + testsuite/tests/splice-imports/SI32.stdout
- + testsuite/tests/splice-imports/SI33.script
- + testsuite/tests/splice-imports/SI33.stdout
- + testsuite/tests/splice-imports/SI34.hs
- + testsuite/tests/splice-imports/SI34.stderr
- + testsuite/tests/splice-imports/SI34M1.hs
- + testsuite/tests/splice-imports/SI34M2.hs
- + testsuite/tests/splice-imports/SI35.hs
- + testsuite/tests/splice-imports/SI35A.hs
- + testsuite/tests/splice-imports/SI36.hs
- + testsuite/tests/splice-imports/SI36.stderr
- + testsuite/tests/splice-imports/SI36_A.hs
- + testsuite/tests/splice-imports/SI36_B1.hs
- + testsuite/tests/splice-imports/SI36_B2.hs
- + testsuite/tests/splice-imports/SI36_B3.hs
- + testsuite/tests/splice-imports/SI36_C1.hs
- + testsuite/tests/splice-imports/SI36_C2.hs
- + testsuite/tests/splice-imports/SI36_C3.hs
- + testsuite/tests/splice-imports/all.T
- testsuite/tests/th/T16976z.stderr
- testsuite/tests/th/T17820a.stderr
- testsuite/tests/th/T17820b.stderr
- testsuite/tests/th/T17820c.stderr
- testsuite/tests/th/T17820d.stderr
- testsuite/tests/th/T17820e.stderr
- testsuite/tests/th/T21547.stderr
- testsuite/tests/th/T23829_hasty.stderr
- testsuite/tests/th/T23829_hasty_b.stderr
- testsuite/tests/th/T23829_tardy.ghc.stderr
- testsuite/tests/th/T5795.stderr
- testsuite/tests/th/TH_Roles2.stderr
- testsuite/tests/typecheck/should_compile/T12763.stderr
- testsuite/tests/typecheck/should_compile/T18406b.stderr
- testsuite/tests/typecheck/should_compile/T18529.stderr
- testsuite/tests/typecheck/should_compile/T21023.stderr
- testsuite/tests/typecheck/should_compile/T7050.stderr
- testsuite/tests/typecheck/should_fail/T3966.stderr
- + testsuite/tests/typecheck/should_fail/T3966b.hs
- + testsuite/tests/typecheck/should_fail/T3966b.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/unboxedsums/unpack_sums_5.stderr
- utils/check-exact/ExactPrint.hs
- utils/count-deps/Main.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Parser.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/447f1a14c068e34699ad1d39a629d2…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/447f1a14c068e34699ad1d39a629d2…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/andreask/spec_tyfams] Dont make comment seem like haddock
by Andreas Klebinger (@AndreasK) 25 Apr '25
by Andreas Klebinger (@AndreasK) 25 Apr '25
25 Apr '25
Andreas Klebinger pushed to branch wip/andreask/spec_tyfams at Glasgow Haskell Compiler / GHC
Commits:
c9f54e65 by Andreas Klebinger at 2025-04-25T16:18:48+02:00
Dont make comment seem like haddock
- - - - -
1 changed file:
- compiler/GHC/Core/Opt/Specialise.hs
Changes:
=====================================
compiler/GHC/Core/Opt/Specialise.hs
=====================================
@@ -3179,7 +3179,7 @@ interestingDict :: CoreExpr -> Type -> Bool
interestingDict arg arg_ty
-- No benefit to specalizing for a ~# b I believe
| not (isEqPred arg_ty) = False
- -- | not (typeDeterminesValue arg_ty) = False -- See Note [Type determines value]
+ -- | not (typeDeterminesValue arg_ty) = False -- See Note [Type determines value]
| otherwise = go arg
where
go (Var v) = hasSomeUnfolding (idUnfolding v)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9f54e653bf638a76c6a9e246442aaa…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9f54e653bf638a76c6a9e246442aaa…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc] Pushed new branch wip/andreask/spec_tyfams
by Andreas Klebinger (@AndreasK) 25 Apr '25
by Andreas Klebinger (@AndreasK) 25 Apr '25
25 Apr '25
Andreas Klebinger pushed new branch wip/andreask/spec_tyfams at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/spec_tyfams
You're receiving this email because of your account on gitlab.haskell.org.
1
0

25 Apr '25
Brandon Chinn pushed to branch wip/T25937 at Glasgow Haskell Compiler / GHC
Commits:
37aa57a8 by Brandon Chinn at 2025-04-24T21:39:23-07:00
Fix lexing "\^\" (#25937)
This broke in the refactor in !13128, where the old code parsed escape
codes and collapsed string gaps at the same time, but the new code
collapsed gaps first, then resolved escape codes. The new code used a
naive heuristic to skip escaped backslashes, but didn't account for
"\^\".
- - - - -
6 changed files:
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/String.hs
- + testsuite/tests/parser/should_run/T25937.hs
- + testsuite/tests/parser/should_run/T25937.stdout
- testsuite/tests/parser/should_run/all.T
- + testsuite/tests/parser/should_run/parser_unit_tests.hs
Changes:
=====================================
compiler/GHC/Parser/Errors/Types.hs
=====================================
@@ -608,6 +608,7 @@ data LexErr
| LexUnterminatedComment -- ^ Unterminated `{-'
| LexUnterminatedOptions -- ^ Unterminated OPTIONS pragma
| LexUnterminatedQQ -- ^ Unterminated quasiquotation
+ deriving (Show,Eq,Ord)
-- | Errors from the Cmm parser
data CmmParserError
=====================================
compiler/GHC/Parser/String.hs
=====================================
@@ -36,6 +36,7 @@ import GHC.Utils.Panic (panic)
type BufPos = Int
data StringLexError = StringLexError LexErr BufPos
+ deriving (Show, Eq)
lexString :: Int -> StringBuffer -> Either StringLexError String
lexString = lexStringWith processChars processChars
@@ -122,20 +123,49 @@ bufferLocatedChars initialBuf len = go initialBuf
-- -----------------------------------------------------------------------------
-- Lexing phases
+-- | Collapse all string gaps in the given input.
+--
+-- Iterates through the input in `go` until we encounter a backslash. The
+-- @stringchar Alex regex only allows backslashes in two places: escape codes
+-- and string gaps.
+--
+-- * If the next character is a space, it has to be the start of a string gap
+-- AND it must end, since the @gap Alex regex will only match if it ends.
+-- Collapse the gap and continue the main iteration loop.
+--
+-- * Otherwise, this is an escape code. If it's an escape code, there are
+-- ONLY three possibilities (see the @escape Alex regex):
+-- 1. The escape code is "\\"
+-- 2. The escape code is "\^\"
+-- 3. The escape code does not have a backslash, other than the initial
+-- backslash
+--
+-- In the first two possibilities, just skip them and continue the main
+-- iteration loop ("skip" as in "keep in the list as-is"). In the last one,
+-- we can just skip the backslash, then continue the main iteration loop.
+-- the rest of the escape code will be skipped as normal characters in the
+-- string; no need to fully parse a proper escape code.
collapseGaps :: HasChar c => [c] -> [c]
collapseGaps = go
where
go = \case
- c1@(Char '\\') : c2@(Char c) : cs
- -- #25784: string gaps are semantically equivalent to "\&"
+ -- Match the start of a string gap + drop gap
+ -- #25784: string gaps are semantically equivalent to "\&"
+ c1@(Char '\\') : Char c : cs
| is_space c -> c1 : setChar '&' c1 : go (dropGap cs)
- | otherwise -> c1 : c2 : go cs
+ -- Match all possible escape characters that include a backslash
+ c1@(Char '\\') : c2@(Char '\\') : cs
+ -> c1 : c2 : go cs
+ c1@(Char '\\') : c2@(Char '^') : c3@(Char '\\') : cs
+ -> c1 : c2 : c3 : go cs
+ -- Otherwise, just keep looping
c : cs -> c : go cs
[] -> []
dropGap = \case
Char '\\' : cs -> cs
_ : cs -> dropGap cs
+ -- Unreachable since gaps must end; see docstring
[] -> panic "gap unexpectedly ended"
resolveEscapes :: HasChar c => [c] -> Either (c, LexErr) [c]
=====================================
testsuite/tests/parser/should_run/T25937.hs
=====================================
@@ -0,0 +1,2 @@
+main :: IO ()
+main = print "\^\ "
=====================================
testsuite/tests/parser/should_run/T25937.stdout
=====================================
@@ -0,0 +1 @@
+"\FS "
=====================================
testsuite/tests/parser/should_run/all.T
=====================================
@@ -1,3 +1,8 @@
+test('parser_unit_tests',
+ normal,
+ compile_and_run,
+ ['-package ghc'])
+
test('readRun001', normal, compile_and_run, [''])
test('readRun002', normal, compile_and_run, [''])
test('readRun003', normal, compile_and_run, [''])
@@ -21,6 +26,7 @@ test('RecordDotSyntax3', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compil
test('RecordDotSyntax4', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compile_and_run, ['RecordDotSyntax4', ''])
test('RecordDotSyntax5', normal, compile_and_run, [''])
test('ListTuplePunsConstraints', extra_files(['ListTuplePunsConstraints.hs']), ghci_script, ['ListTuplePunsConstraints.script'])
+test('T25937', normal, compile_and_run, [''])
# Multiline strings
test('MultilineStrings', normal, compile_and_run, [''])
=====================================
testsuite/tests/parser/should_run/parser_unit_tests.hs
=====================================
@@ -0,0 +1,82 @@
+import GHC.Data.StringBuffer (stringToStringBuffer)
+import qualified GHC.Data.StringBuffer as StringBuffer (StringBuffer (..))
+import GHC.Parser.String (lexString, lexMultilineString)
+
+import qualified Control.Exception as E
+import Control.Monad (forM_, unless)
+
+main :: IO ()
+main = do
+ forM_ tests $ \(testName, test) -> do
+ result <- E.try test
+ case result of
+ Right () -> pure ()
+ Left (e :: E.SomeException)
+ | Just e' <- E.asyncExceptionFromException e -> do
+ E.throwIO (e' :: E.AsyncException)
+ | otherwise -> do
+ putStrLn $ ">>> FAIL: " ++ testName
+ putStrLn $ E.displayException e
+
+{----- Test infrastructure -----}
+
+data TestFailure = TestFailure String
+ deriving (Show)
+
+instance E.Exception TestFailure where
+ displayException (TestFailure msg) = "Test failure:\n" ++ msg
+
+testFailure :: String -> IO a
+testFailure = E.throwIO . TestFailure
+
+shouldBe :: (Eq a, Show a) => a -> a -> IO ()
+shouldBe actual expected =
+ unless (actual == expected) $
+ testFailure $
+ "Got: " ++ show actual ++ "\n" ++
+ "Expected: " ++ show expected
+
+type TestCase = (String, IO ())
+
+testCase :: String -> IO () -> TestCase
+testCase = (,)
+
+{----- Tests -----}
+
+tests :: [TestCase]
+tests = concat
+ [ stringTests
+ ]
+
+-- | Unit tests for GHC.Parser.String
+stringTests :: [TestCase]
+stringTests = concat
+ [ escapedBackslashTests
+ ]
+ where
+ withBuf f s = let buf = stringToStringBuffer s in f (StringBuffer.len buf) buf
+
+ -- Test all situations where backslashes can appear in escape characters (#25937)
+ escapedBackslashTests =
+ [ testCase label $ do
+ withBuf lexStr input `shouldBe` Right output
+ | (lexLabel, lexStr) <- [("strings", lexString), ("multiline strings", lexMultilineString)]
+ , (label, input, output) <-
+ [ ( "escaped backslashes in " ++ lexLabel ++ " not mistaken for string gaps"
+ , [' ', '\\', '\\', ' ', '\\', '\\', ' ']
+ , " \\ \\ "
+ )
+ , ( "escaped \\FS in " ++ lexLabel ++ " not mistaken for beginning of string gap"
+ , ['\\', '^', '\\']
+ , "\FS"
+ )
+ , ( "escaped \\FS in " ++ lexLabel ++ " not mistaken for unterminated string gap"
+ , ['\\', '^', '\\', ' ']
+ , "\FS "
+ )
+ , ( "escaped \\FS in " ++ lexLabel ++ " does not collapse mistaken string gap"
+ , ['\\', '^', '\\', ' ', '\\', 'n']
+ , "\FS \n"
+ )
+ ]
+ ]
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/37aa57a8c77151fbdf89b98bbaee2c5…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/37aa57a8c77151fbdf89b98bbaee2c5…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][master] compiler: Ensure that Panic.Plain.assertPanic' provides callstack
by Marge Bot (@marge-bot) 24 Apr '25
by Marge Bot (@marge-bot) 24 Apr '25
24 Apr '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
6111c5e4 by Ben Gamari at 2025-04-24T18:04:53-04:00
compiler: Ensure that Panic.Plain.assertPanic' provides callstack
In 36cddd2ce1a3bc62ea8a1307d8bc6006d54109cf @alt-romes removed CallStack
output from `GHC.Utils.Panic.Plain.assertPanic'`. While this output is
redundant due to the exception backtrace proposal, we may be
bootstrapping with a compiler which does not yet include this machinery.
Reintroduce the output for now.
Fixes #25898.
- - - - -
1 changed file:
- compiler/GHC/Utils/Panic/Plain.hs
Changes:
=====================================
compiler/GHC/Utils/Panic/Plain.hs
=====================================
@@ -116,9 +116,17 @@ assertPanic file line =
Exception.throw (Exception.AssertionFailed
("ASSERT failed! file " ++ file ++ ", line " ++ show line))
-
+-- | Throw a failed assertion exception taking the location information
+-- from 'HasCallStack' evidence.
assertPanic' :: HasCallStack => a
-assertPanic' = Exception.throw (Exception.AssertionFailed "ASSERT failed!")
+assertPanic' =
+ Exception.throw
+ $ Exception.AssertionFailed
+ $ "ASSERT failed!\n" ++ withFrozenCallStack doc
+ where
+ -- TODO: Drop CallStack when exception backtrace functionality
+ -- can be assumed of bootstrap compiler.
+ doc = unlines $ fmap (" "++) $ lines (prettyCallStack callStack)
assert :: HasCallStack => Bool -> a -> a
{-# INLINE assert #-}
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6111c5e4c4aad2f4e97af62ae304e96…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6111c5e4c4aad2f4e97af62ae304e96…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][master] Doc: add doc for JS interruptible calling convention (#24444)
by Marge Bot (@marge-bot) 24 Apr '25
by Marge Bot (@marge-bot) 24 Apr '25
24 Apr '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
fe6ed8d9 by Sylvain Henry at 2025-04-24T18:04:12-04:00
Doc: add doc for JS interruptible calling convention (#24444)
- - - - -
1 changed file:
- docs/users_guide/javascript.rst
Changes:
=====================================
docs/users_guide/javascript.rst
=====================================
@@ -60,6 +60,21 @@ for the Haskell `Bool` type:
foreign import javascript "((x) => { return 5; })"
type_error :: Bool -> Bool
+Interruptible calling convention
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A foreign import can be declared with the `interruptible` calling convention:
+
+.. code-block:: haskell
+
+ foreign import javascript interruptible "((i,cont) => { ...; return cont(17); })"
+ foo :: Int -> IO Int
+
+In this case the javascript function will be passed one additional argument in
+the final position (noted `cont` in the example): it is a continuation
+function that must be called from JavaScript to return a value from the foreign
+call and to resume the execution of the Haskell code.
+
JSVal
^^^^^
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe6ed8d91270c4acc4627f701707de8…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe6ed8d91270c4acc4627f701707de8…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/az/ghc-cpp] 114 commits: ghci: Use loadInterfaceForModule rather than loadSrcInterface in mkTopLevEnv
by Alan Zimmerman (@alanz) 24 Apr '25
by Alan Zimmerman (@alanz) 24 Apr '25
24 Apr '25
Alan Zimmerman pushed to branch wip/az/ghc-cpp at Glasgow Haskell Compiler / GHC
Commits:
91564daf by Matthew Pickering at 2025-04-24T00:29:02-04:00
ghci: Use loadInterfaceForModule rather than loadSrcInterface in mkTopLevEnv
loadSrcInterface takes a user given `ModuleName` and resolves it to the
module which needs to be loaded (taking into account module
renaming/visibility etc).
loadInterfaceForModule takes a specific module and loads it.
The modules in `ImpDeclSpec` have already been resolved to the actual
module to get the information from during renaming. Therefore we just
need to fetch the precise interface from disk (and not attempt to rename
it again).
Fixes #25951
- - - - -
2e0c07ab by Simon Peyton Jones at 2025-04-24T00:29:43-04:00
Test for #23298
- - - - -
0eef99b0 by Sven Tennie at 2025-04-24T07:34:36-04:00
RV64: Introduce J instruction (non-local jumps) and don't deallocate stack slots for J_TBL (#25738)
J_TBL result in local jumps, there should not deallocate stack slots
(see Note [extra spill slots].)
J is for non-local jumps, these may need to deallocate stack slots.
- - - - -
1bd3d13e by fendor at 2025-04-24T07:35:17-04:00
Add `UnitId` to `EvalBreakpoint`
The `EvalBreakpoint` is used to communicate that a breakpoint was
encountered during code evaluation.
This `EvalBreakpoint` needs to be converted to an `InternalBreakpointId`
which stores a `Module` to uniquely find the correct `Module` in the
Home Package Table.
The `EvalBreakpoint` used to store only a `ModuleName` which is then
converted to a `Module` based on the currently active home unit.
This is incorrect in the face of multiple home units, the break point
could be in an entirely other home unit!
To fix this, we additionally store the `UnitId` of the `Module` in
`EvalBreakpoint` to later reconstruct the correct `Module`
All of the changes are the consequence of extending `EvalBreakpoint`
with the additional `ShortByteString` of the `UnitId`.
For performance reasons, we store the `ShortByteString` backing the
`UnitId` directly, avoiding marshalling overhead.
- - - - -
0fc630f6 by Alan Zimmerman at 2025-04-24T18:16:55+01:00
GHC-CPP: first rough proof of concept
Processes
#define FOO
#ifdef FOO
x = 1
#endif
Into
[ITcppIgnored [L loc ITcppDefine]
,ITcppIgnored [L loc ITcppIfdef]
,ITvarid "x"
,ITequal
,ITinteger (IL {il_text = SourceText "1", il_neg = False, il_value = 1})
,ITcppIgnored [L loc ITcppEndif]
,ITeof]
In time, ITcppIgnored will be pushed into a comment
- - - - -
7b9e88bc by Alan Zimmerman at 2025-04-24T18:16:55+01:00
Tidy up before re-visiting the continuation mechanic
- - - - -
3122938c by Alan Zimmerman at 2025-04-24T18:16:55+01:00
Switch preprocessor to continuation passing style
Proof of concept, needs tidying up
- - - - -
681bef59 by Alan Zimmerman at 2025-04-24T18:16:55+01:00
Small cleanup
- - - - -
b440e634 by Alan Zimmerman at 2025-04-24T18:16:55+01:00
Get rid of some cruft
- - - - -
2b346c2a by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Starting to integrate.
Need to get the pragma recognised and set
- - - - -
6abe3815 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Make cppTokens extend to end of line, and process CPP comments
- - - - -
d31157a8 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Remove unused ITcppDefined
- - - - -
639208c3 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Allow spaces between # and keyword for preprocessor directive
- - - - -
854374dc by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Process CPP continuation lines
They are emited as separate ITcppContinue tokens.
Perhaps the processing should be more like a comment, and keep on
going to the end.
BUT, the last line needs to be slurped as a whole.
- - - - -
04450a85 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Accumulate CPP continuations, process when ready
Can be simplified further, we only need one CPP token
- - - - -
089bb023 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Simplify Lexer interface. Only ITcpp
We transfer directive lines through it, then parse them from scratch
in the preprocessor.
- - - - -
6f9a6183 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Deal with directive on last line, with no trailing \n
- - - - -
c392bba5 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Start parsing and processing the directives
- - - - -
13e86d1f by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Prepare for processing include files
- - - - -
757b978b by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Move PpState into PreProcess
And initParserState, initPragState too
- - - - -
2aba7f93 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Process nested include files
Also move PpState out of Lexer.x, so it is easy to evolve it in a ghci
session, loading utils/check-cpp/Main.hs
- - - - -
d545db1d by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Split into separate files
- - - - -
5869fc35 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Starting on expression parser.
But it hangs. Time for Text.Parsec.Expr
- - - - -
370fff2e by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Start integrating the ghc-cpp work
From https://github.com/alanz/ghc-cpp
- - - - -
c85df867 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
WIP
- - - - -
b8896b47 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Fixup after rebase
- - - - -
fef967e6 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
WIP
- - - - -
847dd6b3 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Fixup after rebase, including all tests pass
- - - - -
fdc130da by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Change pragma usage to GHC_CPP from GhcCPP
- - - - -
bf805566 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Some comments
- - - - -
4965a6cb by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Reformat
- - - - -
0b135bc4 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Delete unused file
- - - - -
368f0bac by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Rename module Parse to ParsePP
- - - - -
272b2ee6 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Clarify naming in the parser
- - - - -
77cc824f by Alan Zimmerman at 2025-04-24T18:16:56+01:00
WIP. Switching to alex/happy to be able to work in-tree
Since Parsec is not available
- - - - -
f8260f59 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Layering is now correct
- GHC lexer, emits CPP tokens
- accumulated in Preprocessor state
- Lexed by CPP lexer, CPP command extracted, tokens concated with
spaces (to get rid of token pasting via comments)
- if directive lexed and parsed by CPP lexer/parser, and evaluated
- - - - -
bcf6df38 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
First example working
Loading Example1.hs into ghci, getting the right results
```
{-# LANGUAGE GHC_CPP #-}
module Example1 where
y = 3
x =
"hello"
"bye now"
foo = putStrLn x
```
- - - - -
e21ff624 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Rebase, and all tests pass except whitespace for generated parser
- - - - -
d3b4779a by Alan Zimmerman at 2025-04-24T18:16:56+01:00
More plumbing. Ready for testing tomorrow.
- - - - -
cbce7b1d by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Proress. Renamed module State from Types
And at first blush it seems to handle preprocessor scopes properly.
- - - - -
4a3bc468 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Insert basic GHC version macros into parser
__GLASGOW_HASKELL__
__GLASGOW_HASKELL_FULL_VERSION__
__GLASGOW_HASKELL_PATCHLEVEL1__
__GLASGOW_HASKELL_PATCHLEVEL2__
- - - - -
302b8058 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Re-sync check-cpp for easy ghci work
- - - - -
ea0417b6 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Get rid of warnings
- - - - -
7614e4a2 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Rework macro processing, in check-cpp
Macros kept at the top level, looked up via name, multiple arity
versions per name can be stored
- - - - -
68c7ed44 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
WIP. Can crack arguments for #define
Next step it to crack out args in an expansion
- - - - -
dadcdb3a by Alan Zimmerman at 2025-04-24T18:16:56+01:00
WIP on arg parsing.
- - - - -
c7edf420 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Progress. Still screwing up nested parens.
- - - - -
375ed9f2 by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Seems to work, but has redundant code
- - - - -
268a487d by Alan Zimmerman at 2025-04-24T18:16:56+01:00
Remove redundant code
- - - - -
df6e5699 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Reformat
- - - - -
cd62f2c6 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Expand args, single pass
Still need to repeat until fixpoint
- - - - -
45ed9b02 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Fixed point expansion
- - - - -
9dc92747 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Sync the playground to compiler
- - - - -
161cc1c8 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Working on dumping the GHC_CPP result
But We need to keep the BufSpan in a comment
- - - - -
f1cd7c0a by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Keep BufSpan in queued comments in GHC.Parser.Lexer
- - - - -
aa3cde3f by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Getting close to being able to print the combined tokens
showing what is in and what is out
- - - - -
be2beb8d by Alan Zimmerman at 2025-04-24T18:16:57+01:00
First implementation of dumpGhcCpp.
Example output
First dumps all macros in the state, then the source, showing which
lines are in and which are out
------------------------------
- |#define FOO(A,B) A + B
- |#define FOO(A,B,C) A + B + C
- |#if FOO(1,FOO(3,4)) == 8
- |-- a comment
|x = 1
- |#else
- |x = 5
- |#endif
- - - - -
89a8f51e by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Clean up a bit
- - - - -
9437ebfb by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Add -ddump-ghc-cpp option and a test based on it
- - - - -
46818aef by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Restore Lexer.x rules, we need them for continuation lines
- - - - -
40e38ca8 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Lexer.x: trying to sort out the span for continuations
- We need to match on \n at the end of the line
- We cannot simply back up for it
- - - - -
77c1e125 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Inserts predefined macros. But does not dump properly
Because the cpp tokens have a trailing newline
- - - - -
e89df978 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Remove unnecessary LExer rules
We *need* the ones that explicitly match to the end of the line.
- - - - -
409ab214 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Generate correct span for ITcpp
Dump now works, except we do not render trailing `\` for continuation
lines. This is good enough for use in test output.
- - - - -
3e4b1f7a by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Reduce duplication in lexer
- - - - -
79f76357 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Tweaks
- - - - -
d2565e5c by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Insert min_version predefined macros into state
The mechanism now works. Still need to flesh out the full set.
- - - - -
46aa4cc8 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Trying my alternative pragma syntax.
It works, but dumpGhcCpp is broken, I suspect from the ITcpp token
span update.
- - - - -
5d0a14c3 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Pragma extraction now works, with both CPP and GHC_CPP
For the following
{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 913
{-# LANGUAGE GHC_CPP #-}
#endif
We will enable GHC_CPP only
- - - - -
da76d922 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Remove some tracing
- - - - -
4f2d0896 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Fix test exes for changes
- - - - -
8341fabd by Alan Zimmerman at 2025-04-24T18:16:57+01:00
For GHC_CPP tests, normalise config-time-based macros
- - - - -
4bd8826c by Alan Zimmerman at 2025-04-24T18:16:57+01:00
WIP
- - - - -
ac7411f9 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
WIP again. What is wrong?
- - - - -
bcc8bb13 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Revert to dynflags for normal not pragma lexing
- - - - -
e5b3514b by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Working on getting check-exact to work properly
- - - - -
f80cdcd2 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Passes CppCommentPlacement test
- - - - -
eafa436e by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Starting on exact printing with GHC_CPP
While overriding normal CPP
- - - - -
636ca98d by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Correctly store CPP ignored tokens as comments
By populating the lexeme string in it, based on the bufpos
- - - - -
fe0dc499 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
WIP
- - - - -
037cc151 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Simplifying
- - - - -
6bd2cedb by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Update the active state logic
- - - - -
bf9af1e4 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Work the new logic into the mainline code
- - - - -
2975b9f1 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Process `defined` operator
- - - - -
83e8470a by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Manage lexer state while skipping tokens
There is very intricate layout-related state used when lexing. If a
CPP directive blanks out some tokens, store this state when the
blanking starts, and restore it when they are no longer being blanked.
- - - - -
d960022a by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Track the last token buffer index, for ITCppIgnored
We need to attach the source being skipped in an ITCppIgnored token.
We cannot simply use its BufSpan as an index into the underlying
StringBuffer as it counts unicode chars, not bytes.
So we update the lexer state to store the starting StringBuffer
location for the last token, and use the already-stored length to
extract the correct portion of the StringBuffer being parsed.
- - - - -
a64e1ac7 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Process the ! operator in GHC_CPP expressions
- - - - -
20b34726 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Predefine a constant when GHC_CPP is being used.
- - - - -
0a1e66ca by Alan Zimmerman at 2025-04-24T18:16:57+01:00
WIP
- - - - -
dd94a679 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Skip lines directly in the lexer when required
- - - - -
1ec6f204 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Properly manage location when accepting tokens again
- - - - -
20a6be64 by Alan Zimmerman at 2025-04-24T18:16:57+01:00
Seems to be working now, for Example9
- - - - -
ac8b516b by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Remove tracing
- - - - -
9966dff9 by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Fix parsing '*' in block comments
Instead of replacing them with '-'
- - - - -
654e4220 by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Keep the trailing backslash in a ITcpp token
- - - - -
2b198253 by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Deal with only enabling one section of a group.
A group is an instance of a conditional introduced by
#if/#ifdef/#ifndef,
and ending at the final #endif, including intermediate #elsif sections
- - - - -
a0ceda9d by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Replace remaining identifiers with 0 when evaluating
As per the spec
- - - - -
7ab22a44 by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Snapshot before rebase
- - - - -
d6dba815 by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Skip non-processed lines starting with #
- - - - -
fdda605f by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Export generateMacros so we can use it in ghc-exactprint
- - - - -
31b6e62b by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Fix rebase
- - - - -
050470d3 by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Expose initParserStateWithMacrosString
- - - - -
d8b13d8b by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Fix buggy lexer cppSkip
It was skipping all lines, not just ones prefixed by #
- - - - -
e5927330 by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Fix evaluation of && to use the correct operator
- - - - -
b3234fc5 by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Deal with closing #-} at the start of a line
- - - - -
385e99fc by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Add the MIN_VERSION_GLASGOW_HASKELL predefined macro
- - - - -
eb2b6350 by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Include MIN_VERSION_GLASGOW_HASKELL in GhcCpp01.stderr
- - - - -
f006682e by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Use a strict map for macro defines
- - - - -
6f80071d by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Process TIdentifierLParen
Which only matters at the start of #define
- - - - -
be43707c by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Do not provide TIdentifierLParen paren twice
- - - - -
032f1174 by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Handle whitespace between identifier and '(' for directive only
- - - - -
a821b36d by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Expose some Lexer bitmap manipulation helpers
- - - - -
ae6f6b39 by Alan Zimmerman at 2025-04-24T18:16:58+01:00
Deal with line pragmas as tokens
Blows up for dumpGhcCpp though
- - - - -
cb0c0ee9 by Alan Zimmerman at 2025-04-24T21:41:38+01:00
Allow strings delimited by a single quote too
- - - - -
99 changed files:
- compiler/GHC.hs
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm/Lexer.x
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Cmm/Parser/Monad.hs
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/Instr.hs
- compiler/GHC/CmmToAsm/RV64/Ppr.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Config/Parser.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/Parser.hs-boot
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/HaddockLex.x
- compiler/GHC/Parser/Header.hs
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- + compiler/GHC/Parser/PreProcess.hs
- + compiler/GHC/Parser/PreProcess/Eval.hs
- + compiler/GHC/Parser/PreProcess/Lexer.x
- + compiler/GHC/Parser/PreProcess/Macro.hs
- + compiler/GHC/Parser/PreProcess/ParsePP.hs
- + compiler/GHC/Parser/PreProcess/Parser.y
- + compiler/GHC/Parser/PreProcess/ParserM.hs
- + compiler/GHC/Parser/PreProcess/State.hs
- compiler/GHC/Parser/Utils.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/ghc.cabal.in
- docs/users_guide/debugging.rst
- ghc/GHCi/UI.hs
- hadrian/src/Rules/SourceDist.hs
- hadrian/stack.yaml.lock
- libraries/ghc-internal/src/GHC/Internal/LanguageExtensions.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/Run.hs
- rts/Exception.cmm
- rts/Interpreter.c
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/driver/T4437.hs
- + testsuite/tests/gadt/T23298.hs
- + testsuite/tests/gadt/T23298.stderr
- testsuite/tests/gadt/all.T
- testsuite/tests/ghc-api/T11579.hs
- + testsuite/tests/ghc-cpp/GhcCpp01.hs
- + testsuite/tests/ghc-cpp/GhcCpp01.stderr
- + testsuite/tests/ghc-cpp/all.T
- + testsuite/tests/ghci/scripts/GhciPackageRename.hs
- + testsuite/tests/ghci/scripts/GhciPackageRename.script
- + testsuite/tests/ghci/scripts/GhciPackageRename.stdout
- testsuite/tests/ghci/scripts/all.T
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- + testsuite/tests/printer/CppCommentPlacement.hs
- + utils/check-cpp/.ghci
- + utils/check-cpp/.gitignore
- + utils/check-cpp/Eval.hs
- + utils/check-cpp/Example1.hs
- + utils/check-cpp/Example10.hs
- + utils/check-cpp/Example11.hs
- + utils/check-cpp/Example12.hs
- + utils/check-cpp/Example13.hs
- + utils/check-cpp/Example2.hs
- + utils/check-cpp/Example3.hs
- + utils/check-cpp/Example4.hs
- + utils/check-cpp/Example5.hs
- + utils/check-cpp/Example6.hs
- + utils/check-cpp/Example7.hs
- + utils/check-cpp/Example8.hs
- + utils/check-cpp/Example9.hs
- + utils/check-cpp/Lexer.x
- + utils/check-cpp/Macro.hs
- + utils/check-cpp/Main.hs
- + utils/check-cpp/ParsePP.hs
- + utils/check-cpp/ParseSimulate.hs
- + utils/check-cpp/Parser.y
- + utils/check-cpp/ParserM.hs
- + utils/check-cpp/PreProcess.hs
- + utils/check-cpp/README.md
- + utils/check-cpp/State.hs
- + utils/check-cpp/run.sh
- utils/check-exact/Main.hs
- utils/check-exact/Parsers.hs
- utils/check-exact/Preprocess.hs
- utils/check-exact/Utils.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Parser.hs
- utils/haddock/haddock-api/src/Haddock/Parser.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/557ec85d9a54ebd6cdf69e688ea701…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/557ec85d9a54ebd6cdf69e688ea701…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

24 Apr '25
Matthew Pickering pushed to branch wip/splice-imports-2025 at Glasgow Haskell Compiler / GHC
Commits:
447f1a14 by Matthew Pickering at 2025-04-24T20:45:27+01:00
fix
- - - - -
1 changed file:
- compiler/GHC/Types/Error/Codes.hs
Changes:
=====================================
compiler/GHC/Types/Error/Codes.hs
=====================================
@@ -700,7 +700,6 @@ type family GhcDiagnosticCode c = n | n -> c where
GhcDiagnosticCode "TcRnIllegalTypeExpr" = 35499
GhcDiagnosticCode "TcRnUnexpectedTypeSyntaxInTerms" = 31244
GhcDiagnosticCode "TcRnTypeApplicationsDisabled" = 23482
- GhcDiagnosticCode "TcRnDeriveLiftWithoutImplicitStagePersistence" = 87906
-- TcRnIllegalInvisibleTypePattern
GhcDiagnosticCode "InvisPatWithoutFlag" = 78249
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/447f1a14c068e34699ad1d39a629d20…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/447f1a14c068e34699ad1d39a629d20…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: RV64: Introduce J instruction (non-local jumps) and don't deallocate stack slots for J_TBL (#25738)
by Marge Bot (@marge-bot) 24 Apr '25
by Marge Bot (@marge-bot) 24 Apr '25
24 Apr '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
0eef99b0 by Sven Tennie at 2025-04-24T07:34:36-04:00
RV64: Introduce J instruction (non-local jumps) and don't deallocate stack slots for J_TBL (#25738)
J_TBL result in local jumps, there should not deallocate stack slots
(see Note [extra spill slots].)
J is for non-local jumps, these may need to deallocate stack slots.
- - - - -
1bd3d13e by fendor at 2025-04-24T07:35:17-04:00
Add `UnitId` to `EvalBreakpoint`
The `EvalBreakpoint` is used to communicate that a breakpoint was
encountered during code evaluation.
This `EvalBreakpoint` needs to be converted to an `InternalBreakpointId`
which stores a `Module` to uniquely find the correct `Module` in the
Home Package Table.
The `EvalBreakpoint` used to store only a `ModuleName` which is then
converted to a `Module` based on the currently active home unit.
This is incorrect in the face of multiple home units, the break point
could be in an entirely other home unit!
To fix this, we additionally store the `UnitId` of the `Module` in
`EvalBreakpoint` to later reconstruct the correct `Module`
All of the changes are the consequence of extending `EvalBreakpoint`
with the additional `ShortByteString` of the `UnitId`.
For performance reasons, we store the `ShortByteString` backing the
`UnitId` directly, avoiding marshalling overhead.
- - - - -
f32f430f by Sylvain Henry at 2025-04-24T14:13:43-04:00
Doc: add doc for JS interruptible calling convention (#24444)
- - - - -
271d4baa by Ben Gamari at 2025-04-24T14:13:44-04:00
compiler: Ensure that Panic.Plain.assertPanic' provides callstack
In 36cddd2ce1a3bc62ea8a1307d8bc6006d54109cf @alt-romes removed CallStack
output from `GHC.Utils.Panic.Plain.assertPanic'`. While this output is
redundant due to the exception backtrace proposal, we may be
bootstrapping with a compiler which does not yet include this machinery.
Reintroduce the output for now.
Fixes #25898.
- - - - -
16 changed files:
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/Instr.hs
- compiler/GHC/CmmToAsm/RV64/Ppr.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/Utils/Panic/Plain.hs
- docs/users_guide/javascript.rst
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/Run.hs
- rts/Exception.cmm
- rts/Interpreter.c
Changes:
=====================================
compiler/GHC/ByteCode/Asm.hs
=====================================
@@ -732,13 +732,16 @@ assembleI platform i = case i of
CCALL off m_addr i -> do np <- addr m_addr
emit_ bci_CCALL [wOp off, Op np, SmallOp i]
PRIMCALL -> emit_ bci_PRIMCALL []
- BRK_FUN arr tick_mod tickx info_mod infox cc ->
+ BRK_FUN arr tick_mod tick_mod_id tickx info_mod info_mod_id infox cc ->
do p1 <- ptr (BCOPtrBreakArray arr)
tick_addr <- addr tick_mod
+ tick_unitid_addr <- addr tick_mod_id
info_addr <- addr info_mod
+ info_unitid_addr <- addr info_mod_id
np <- addr cc
emit_ bci_BRK_FUN [ Op p1
, Op tick_addr, Op info_addr
+ , Op tick_unitid_addr, Op info_unitid_addr
, SmallOp tickx, SmallOp infox
, Op np
]
=====================================
compiler/GHC/ByteCode/Instr.hs
=====================================
@@ -37,6 +37,7 @@ import GHC.Stg.Syntax
import GHCi.BreakArray (BreakArray)
import Language.Haskell.Syntax.Module.Name (ModuleName)
import GHC.Types.Unique
+import GHC.Unit.Types (UnitId)
-- ----------------------------------------------------------------------------
-- Bytecode instructions
@@ -233,8 +234,10 @@ data BCInstr
-- Breakpoints
| BRK_FUN (ForeignRef BreakArray)
(RemotePtr ModuleName) -- breakpoint tick module
+ (RemotePtr UnitId) -- breakpoint tick module unit id
!Word16 -- breakpoint tick index
(RemotePtr ModuleName) -- breakpoint info module
+ (RemotePtr UnitId) -- breakpoint info module unit id
!Word16 -- breakpoint info index
(RemotePtr CostCentre)
@@ -403,10 +406,10 @@ instance Outputable BCInstr where
ppr ENTER = text "ENTER"
ppr (RETURN pk) = text "RETURN " <+> ppr pk
ppr (RETURN_TUPLE) = text "RETURN_TUPLE"
- ppr (BRK_FUN _ _tick_mod tickx _info_mod infox _)
+ ppr (BRK_FUN _ _tick_mod _tick_mod_id tickx _info_mod _info_mod_id infox _)
= text "BRK_FUN" <+> text "<breakarray>"
- <+> text "<tick_module>" <+> ppr tickx
- <+> text "<info_module>" <+> ppr infox
+ <+> text "<tick_module>" <+> text "<tick_module_unitid>" <+> ppr tickx
+ <+> text "<info_module>" <+> text "<info_module_unitid>" <+> ppr infox
<+> text "<cc>"
#if MIN_VERSION_rts(1,0,3)
ppr (BCO_NAME nm) = text "BCO_NAME" <+> text (show nm)
=====================================
compiler/GHC/ByteCode/Types.hs
=====================================
@@ -50,6 +50,7 @@ import GHC.Stack.CCS
import GHC.Cmm.Expr ( GlobalRegSet, emptyRegSet, regSetToList )
import GHC.Iface.Syntax
import Language.Haskell.Syntax.Module.Name (ModuleName)
+import GHC.Unit.Types (UnitId)
-- -----------------------------------------------------------------------------
-- Compiled Byte Code
@@ -263,6 +264,9 @@ data ModBreaks
, modBreaks_breakInfo :: IntMap CgBreakInfo
-- ^ info about each breakpoint from the bytecode generator
, modBreaks_module :: RemotePtr ModuleName
+ -- ^ info about the module in which we are setting the breakpoint
+ , modBreaks_module_unitid :: RemotePtr UnitId
+ -- ^ The 'UnitId' of the 'ModuleName'
}
seqModBreaks :: ModBreaks -> ()
@@ -273,7 +277,8 @@ seqModBreaks ModBreaks{..} =
rnf modBreaks_decls `seq`
rnf modBreaks_ccs `seq`
rnf (fmap seqCgBreakInfo modBreaks_breakInfo) `seq`
- rnf modBreaks_module
+ rnf modBreaks_module `seq`
+ rnf modBreaks_module_unitid
-- | Construct an empty ModBreaks
emptyModBreaks :: ModBreaks
@@ -286,6 +291,7 @@ emptyModBreaks = ModBreaks
, modBreaks_ccs = array (0,-1) []
, modBreaks_breakInfo = IntMap.empty
, modBreaks_module = toRemotePtr nullPtr
+ , modBreaks_module_unitid = toRemotePtr nullPtr
}
{-
=====================================
compiler/GHC/CmmToAsm/RV64/CodeGen.hs
=====================================
@@ -1481,7 +1481,7 @@ assignReg_FltCode = assignReg_IntCode
genJump :: CmmExpr {-the branch target-} -> NatM InstrBlock
genJump expr = do
(target, _format, code) <- getSomeReg expr
- return (code `appOL` unitOL (annExpr expr (B (TReg target))))
+ return (code `appOL` unitOL (annExpr expr (J (TReg target))))
-- -----------------------------------------------------------------------------
-- Unconditional branches
@@ -2226,5 +2226,6 @@ makeFarBranches {- only used when debugging -} _platform statics basic_blocks =
BCOND {} -> long_bc_jump_size
B (TBlock _) -> long_b_jump_size
B (TReg _) -> 1
+ J op -> instr_size (B op)
BL _ _ -> 1
J_TBL {} -> 1
=====================================
compiler/GHC/CmmToAsm/RV64/Instr.hs
=====================================
@@ -97,6 +97,7 @@ regUsageOfInstr platform instr = case instr of
ORI dst src1 _ -> usage (regOp src1, regOp dst)
XORI dst src1 _ -> usage (regOp src1, regOp dst)
J_TBL _ _ t -> usage ([t], [])
+ J t -> usage (regTarget t, [])
B t -> usage (regTarget t, [])
BCOND _ l r t -> usage (regTarget t ++ regOp l ++ regOp r, [])
BL t ps -> usage (t : ps, callerSavedRegisters)
@@ -195,6 +196,7 @@ patchRegsOfInstr instr env = case instr of
ORI o1 o2 o3 -> ORI (patchOp o1) (patchOp o2) (patchOp o3)
XORI o1 o2 o3 -> XORI (patchOp o1) (patchOp o2) (patchOp o3)
J_TBL ids mbLbl t -> J_TBL ids mbLbl (env t)
+ J t -> J (patchTarget t)
B t -> B (patchTarget t)
BL t ps -> BL (patchReg t) ps
BCOND c o1 o2 t -> BCOND c (patchOp o1) (patchOp o2) (patchTarget t)
@@ -235,6 +237,7 @@ isJumpishInstr :: Instr -> Bool
isJumpishInstr instr = case instr of
ANN _ i -> isJumpishInstr i
J_TBL {} -> True
+ J {} -> True
B {} -> True
BL {} -> True
BCOND {} -> True
@@ -243,6 +246,7 @@ isJumpishInstr instr = case instr of
canFallthroughTo :: Instr -> BlockId -> Bool
canFallthroughTo insn bid =
case insn of
+ J (TBlock target) -> bid == target
B (TBlock target) -> bid == target
BCOND _ _ _ (TBlock target) -> bid == target
J_TBL targets _ _ -> all isTargetBid targets
@@ -256,6 +260,7 @@ canFallthroughTo insn bid =
jumpDestsOfInstr :: Instr -> [BlockId]
jumpDestsOfInstr (ANN _ i) = jumpDestsOfInstr i
jumpDestsOfInstr (J_TBL ids _mbLbl _r) = catMaybes ids
+jumpDestsOfInstr (J t) = [id | TBlock id <- [t]]
jumpDestsOfInstr (B t) = [id | TBlock id <- [t]]
jumpDestsOfInstr (BCOND _ _ _ t) = [id | TBlock id <- [t]]
jumpDestsOfInstr _ = []
@@ -269,6 +274,7 @@ patchJumpInstr instr patchF =
case instr of
ANN d i -> ANN d (patchJumpInstr i patchF)
J_TBL ids mbLbl r -> J_TBL (map (fmap patchF) ids) mbLbl r
+ J (TBlock bid) -> J (TBlock (patchF bid))
B (TBlock bid) -> B (TBlock (patchF bid))
BCOND c o1 o2 (TBlock bid) -> BCOND c o1 o2 (TBlock (patchF bid))
_ -> panic $ "patchJumpInstr: " ++ instrCon instr
@@ -475,7 +481,7 @@ allocMoreStack platform slots proc@(CmmProc info lbl live (ListGraph code)) = do
block' = foldr insert_dealloc [] insns
insert_dealloc insn r = case insn of
- J_TBL {} -> dealloc ++ (insn : r)
+ J {} -> dealloc ++ (insn : r)
ANN _ e -> insert_dealloc e r
_other
| jumpDestsOfInstr insn /= [] ->
@@ -591,6 +597,8 @@ data Instr
--
-- @if(o2 cond o3) op <- 1 else op <- 0@
CSET Operand Operand Operand Cond
+ -- | Like B, but only used for non-local jumps. Used to distinguish genJumps from others.
+ | J Target
| -- | A jump instruction with data for switch/jump tables
J_TBL [Maybe BlockId] (Maybe CLabel) Reg
| -- | Unconditional jump (no linking)
@@ -663,6 +671,7 @@ instrCon i =
LDRU {} -> "LDRU"
CSET {} -> "CSET"
J_TBL {} -> "J_TBL"
+ J {} -> "J"
B {} -> "B"
BL {} -> "BL"
BCOND {} -> "BCOND"
=====================================
compiler/GHC/CmmToAsm/RV64/Ppr.hs
=====================================
@@ -543,6 +543,7 @@ pprInstr platform instr = case instr of
| otherwise -> op3 (text "\taddi") o1 o2 (OpImm (ImmInt 0))
ORI o1 o2 o3 -> op3 (text "\tori") o1 o2 o3
XORI o1 o2 o3 -> op3 (text "\txori") o1 o2 o3
+ J o1 -> pprInstr platform (B o1)
J_TBL _ _ r -> pprInstr platform (B (TReg r))
B l | isLabel l -> line $ text "\tjal" <+> pprOp platform x0 <> comma <+> getLabel platform l
B (TReg r) -> line $ text "\tjalr" <+> pprOp platform x0 <> comma <+> pprReg W64 r <> comma <+> text "0"
=====================================
compiler/GHC/HsToCore/Breakpoints.hs
=====================================
@@ -34,7 +34,7 @@ mkModBreaks interp mod extendedMixEntries
breakArray <- GHCi.newBreakArray interp count
ccs <- mkCCSArray interp mod count entries
- mod_ptr <- GHCi.newModuleName interp (moduleName mod)
+ (mod_ptr, mod_id_ptr) <- GHCi.newModule interp mod
let
locsTicks = listArray (0,count-1) [ tick_loc t | t <- entries ]
varsTicks = listArray (0,count-1) [ tick_ids t | t <- entries ]
@@ -46,6 +46,7 @@ mkModBreaks interp mod extendedMixEntries
, modBreaks_decls = declsTicks
, modBreaks_ccs = ccs
, modBreaks_module = mod_ptr
+ , modBreaks_module_unitid = mod_id_ptr
}
mkCCSArray
=====================================
compiler/GHC/Runtime/Eval.hs
=====================================
@@ -345,7 +345,7 @@ handleRunStatus step expr bindings final_ids status history0 = do
-- Just case: we stopped at a breakpoint
EvalBreak apStack_ref (Just eval_break) resume_ctxt ccs -> do
- ibi <- liftIO $ evalBreakpointToId (hsc_HPT hsc_env) eval_break
+ let ibi = evalBreakpointToId eval_break
tick_brks <- liftIO $ readModBreaks hsc_env (ibi_tick_mod ibi)
let
span = modBreaks_locs tick_brks ! ibi_tick_index ibi
=====================================
compiler/GHC/Runtime/Interpreter.hs
=====================================
@@ -21,7 +21,7 @@ module GHC.Runtime.Interpreter
, mkCostCentres
, costCentreStackInfo
, newBreakArray
- , newModuleName
+ , newModule
, storeBreakpoint
, breakpointStatus
, getBreakpointVar
@@ -93,9 +93,8 @@ import GHC.Utils.Outputable(brackets, ppr, showSDocUnsafe)
import GHC.Utils.Fingerprint
import GHC.Unit.Module
-import GHC.Unit.Module.ModIface
import GHC.Unit.Home.ModInfo
-import GHC.Unit.Home.PackageTable
+import GHC.Unit.Home.Graph (lookupHugByModule)
import GHC.Unit.Env
#if defined(HAVE_INTERNAL_INTERPRETER)
@@ -377,9 +376,13 @@ newBreakArray interp size = do
breakArray <- interpCmd interp (NewBreakArray size)
mkFinalizedHValue interp breakArray
-newModuleName :: Interp -> ModuleName -> IO (RemotePtr ModuleName)
-newModuleName interp mod_name =
- castRemotePtr <$> interpCmd interp (NewBreakModule (moduleNameString mod_name))
+newModule :: Interp -> Module -> IO (RemotePtr ModuleName, RemotePtr UnitId)
+newModule interp mod = do
+ let
+ mod_name = moduleNameString $ moduleName mod
+ mod_id = fastStringToShortByteString $ unitIdFS $ toUnitId $ moduleUnit mod
+ (mod_ptr, mod_id_ptr) <- interpCmd interp (NewBreakModule mod_name mod_id)
+ pure (castRemotePtr mod_ptr, castRemotePtr mod_id_ptr)
storeBreakpoint :: Interp -> ForeignRef BreakArray -> Int -> Int -> IO ()
storeBreakpoint interp ref ix cnt = do -- #19157
@@ -415,19 +418,21 @@ seqHValue interp unit_env ref =
status <- interpCmd interp (Seq hval)
handleSeqHValueStatus interp unit_env status
-evalBreakpointToId :: HomePackageTable -> EvalBreakpoint -> IO InternalBreakpointId
-evalBreakpointToId hpt eval_break =
- let load_mod x = mi_module . hm_iface . expectJust <$> lookupHpt hpt (mkModuleName x)
- in do
- tickl <- load_mod (eb_tick_mod eval_break)
- infol <- load_mod (eb_info_mod eval_break)
- return
- InternalBreakpointId
- { ibi_tick_mod = tickl
- , ibi_tick_index = eb_tick_index eval_break
- , ibi_info_mod = infol
- , ibi_info_index = eb_info_index eval_break
- }
+evalBreakpointToId :: EvalBreakpoint -> InternalBreakpointId
+evalBreakpointToId eval_break =
+ let
+ mkUnitId u = fsToUnit $ mkFastStringShortByteString u
+
+ toModule u n = mkModule (mkUnitId u) (mkModuleName n)
+ tickl = toModule (eb_tick_mod_unit eval_break) (eb_tick_mod eval_break)
+ infol = toModule (eb_info_mod_unit eval_break) (eb_info_mod eval_break)
+ in
+ InternalBreakpointId
+ { ibi_tick_mod = tickl
+ , ibi_tick_index = eb_tick_index eval_break
+ , ibi_info_mod = infol
+ , ibi_info_index = eb_info_index eval_break
+ }
-- | Process the result of a Seq or ResumeSeq message. #2950
handleSeqHValueStatus :: Interp -> UnitEnv -> EvalStatus () -> IO (EvalResult ())
@@ -447,12 +452,12 @@ handleSeqHValueStatus interp unit_env eval_status =
mkGeneralSrcSpan (fsLit "<unknown>")
Just break -> do
- bi <- evalBreakpointToId (ue_hpt unit_env) break
+ let bi = evalBreakpointToId break
-- Just case: Stopped at a breakpoint, extract SrcSpan information
-- from the breakpoint.
breaks_tick <- getModBreaks . expectJust <$>
- lookupHpt (ue_hpt unit_env) (moduleName (ibi_tick_mod bi))
+ lookupHugByModule (ibi_tick_mod bi) (ue_home_unit_graph unit_env)
put $ brackets . ppr $
(modBreaks_locs breaks_tick) ! ibi_tick_index bi
=====================================
compiler/GHC/StgToByteCode.hs
=====================================
@@ -416,7 +416,7 @@ schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_no fvs tick_mod) rhs) = do
Nothing -> pure code
Just current_mod_breaks -> break_info hsc_env tick_mod current_mod mb_current_mod_breaks >>= \case
Nothing -> pure code
- Just ModBreaks {modBreaks_flags = breaks, modBreaks_module = tick_mod_ptr, modBreaks_ccs = cc_arr} -> do
+ Just ModBreaks {modBreaks_flags = breaks, modBreaks_module = tick_mod_ptr, modBreaks_module_unitid = tick_mod_id_ptr, modBreaks_ccs = cc_arr} -> do
platform <- profilePlatform <$> getProfile
let idOffSets = getVarOffSets platform d p fvs
ty_vars = tyCoVarsOfTypesWellScoped (tick_ty:map idType fvs)
@@ -425,6 +425,7 @@ schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_no fvs tick_mod) rhs) = do
breakInfo = dehydrateCgBreakInfo ty_vars (map toWord idOffSets) tick_ty
let info_mod_ptr = modBreaks_module current_mod_breaks
+ info_mod_id_ptr = modBreaks_module_unitid current_mod_breaks
infox <- newBreakInfo breakInfo
let cc | Just interp <- hsc_interp hsc_env
@@ -437,7 +438,7 @@ schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_no fvs tick_mod) rhs) = do
in if fromIntegral r == x
then r
else pprPanic "schemeER_wrk: breakpoint tick/info index too large!" (ppr x)
- breakInstr = BRK_FUN breaks tick_mod_ptr (toW16 tick_no) info_mod_ptr (toW16 infox) cc
+ breakInstr = BRK_FUN breaks tick_mod_ptr tick_mod_id_ptr (toW16 tick_no) info_mod_ptr info_mod_id_ptr (toW16 infox) cc
return $ breakInstr `consOL` code
schemeER_wrk d p rhs = schemeE d 0 p rhs
=====================================
compiler/GHC/Utils/Panic/Plain.hs
=====================================
@@ -116,9 +116,17 @@ assertPanic file line =
Exception.throw (Exception.AssertionFailed
("ASSERT failed! file " ++ file ++ ", line " ++ show line))
-
+-- | Throw a failed assertion exception taking the location information
+-- from 'HasCallStack' evidence.
assertPanic' :: HasCallStack => a
-assertPanic' = Exception.throw (Exception.AssertionFailed "ASSERT failed!")
+assertPanic' =
+ Exception.throw
+ $ Exception.AssertionFailed
+ $ "ASSERT failed!\n" ++ withFrozenCallStack doc
+ where
+ -- TODO: Drop CallStack when exception backtrace functionality
+ -- can be assumed of bootstrap compiler.
+ doc = unlines $ fmap (" "++) $ lines (prettyCallStack callStack)
assert :: HasCallStack => Bool -> a -> a
{-# INLINE assert #-}
=====================================
docs/users_guide/javascript.rst
=====================================
@@ -60,6 +60,21 @@ for the Haskell `Bool` type:
foreign import javascript "((x) => { return 5; })"
type_error :: Bool -> Bool
+Interruptible calling convention
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A foreign import can be declared with the `interruptible` calling convention:
+
+.. code-block:: haskell
+
+ foreign import javascript interruptible "((i,cont) => { ...; return cont(17); })"
+ foo :: Int -> IO Int
+
+In this case the javascript function will be passed one additional argument in
+the final position (noted `cont` in the example): it is a continuation
+function that must be called from JavaScript to return a value from the foreign
+call and to resume the execution of the Haskell code.
+
JSVal
^^^^^
=====================================
libraries/ghci/GHCi/Message.hs
=====================================
@@ -23,6 +23,7 @@ module GHCi.Message
, getMessage, putMessage, getTHMessage, putTHMessage
, Pipe, mkPipeFromHandles, mkPipeFromContinuations, remoteCall, remoteTHCall, readPipe, writePipe
, BreakModule
+ , BreakUnitId
, LoadedDLL
) where
@@ -51,6 +52,7 @@ import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Builder as B
import qualified Data.ByteString.Lazy as LB
+import qualified Data.ByteString.Short as BS
import Data.Dynamic
import Data.Typeable (TypeRep)
import Data.IORef
@@ -245,8 +247,9 @@ data Message a where
-- | Allocate a string for a breakpoint module name.
-- This uses an empty dummy type because @ModuleName@ isn't available here.
NewBreakModule
- :: String
- -> Message (RemotePtr BreakModule)
+ :: String -- ^ @ModuleName@
+ -> BS.ShortByteString -- ^ @UnitId@ for the given @ModuleName@
+ -> Message (RemotePtr BreakModule, RemotePtr BreakUnitId)
deriving instance Show (Message a)
@@ -410,10 +413,12 @@ data EvalStatus_ a b
instance Binary a => Binary (EvalStatus_ a b)
data EvalBreakpoint = EvalBreakpoint
- { eb_tick_mod :: String -- ^ Breakpoint tick module
- , eb_tick_index :: Int -- ^ Breakpoint tick index
- , eb_info_mod :: String -- ^ Breakpoint info module
- , eb_info_index :: Int -- ^ Breakpoint info index
+ { eb_tick_mod :: String -- ^ Breakpoint tick module
+ , eb_tick_mod_unit :: BS.ShortByteString -- ^ Breakpoint tick module unit id
+ , eb_tick_index :: Int -- ^ Breakpoint tick index
+ , eb_info_mod :: String -- ^ Breakpoint info module
+ , eb_info_mod_unit :: BS.ShortByteString -- ^ Breakpoint tick module unit id
+ , eb_info_index :: Int -- ^ Breakpoint info index
}
deriving (Generic, Show)
@@ -430,6 +435,10 @@ instance Binary a => Binary (EvalResult a)
-- that type isn't available here.
data BreakModule
+-- | A dummy type that tags the pointer to a breakpoint's @UnitId@, because
+-- that type isn't available here.
+data BreakUnitId
+
-- | A dummy type that tags pointers returned by 'LoadDLL'.
data LoadedDLL
@@ -580,7 +589,7 @@ getMessage = do
36 -> Msg <$> (Seq <$> get)
37 -> Msg <$> return RtsRevertCAFs
38 -> Msg <$> (ResumeSeq <$> get)
- 39 -> Msg <$> (NewBreakModule <$> get)
+ 39 -> Msg <$> (NewBreakModule <$> get <*> get)
40 -> Msg <$> (LookupSymbolInDLL <$> get <*> get)
41 -> Msg <$> (WhereFrom <$> get)
_ -> error $ "Unknown Message code " ++ (show b)
@@ -627,7 +636,7 @@ putMessage m = case m of
Seq a -> putWord8 36 >> put a
RtsRevertCAFs -> putWord8 37
ResumeSeq a -> putWord8 38 >> put a
- NewBreakModule name -> putWord8 39 >> put name
+ NewBreakModule name unitid -> putWord8 39 >> put name >> put unitid
LookupSymbolInDLL dll str -> putWord8 40 >> put dll >> put str
WhereFrom a -> putWord8 41 >> put a
=====================================
libraries/ghci/GHCi/Run.hs
=====================================
@@ -33,6 +33,7 @@ import Control.DeepSeq
import Control.Exception
import Control.Monad
import Data.ByteString (ByteString)
+import qualified Data.ByteString.Short as BS
import qualified Data.ByteString.Unsafe as B
import GHC.Exts
import qualified GHC.Exts.Heap as Heap
@@ -95,7 +96,10 @@ run m = case m of
MkCostCentres mod ccs -> mkCostCentres mod ccs
CostCentreStackInfo ptr -> ccsToStrings (fromRemotePtr ptr)
NewBreakArray sz -> mkRemoteRef =<< newBreakArray sz
- NewBreakModule name -> newModuleName name
+ NewBreakModule name unitid -> do
+ namePtr <- newModuleName name
+ uidPtr <- newUnitId unitid
+ pure (namePtr, uidPtr)
SetupBreakpoint ref ix cnt -> do
arr <- localRef ref;
_ <- setupBreakpoint arr ix cnt
@@ -335,7 +339,7 @@ withBreakAction opts breakMVar statusMVar act
-- as soon as it is hit, or in resetBreakAction below.
onBreak :: BreakpointCallback
- onBreak tick_mod# tickx# info_mod# infox# is_exception apStack = do
+ onBreak tick_mod# tick_mod_uid# tickx# info_mod# info_mod_uid# infox# is_exception apStack = do
tid <- myThreadId
let resume = ResumeContext
{ resumeBreakMVar = breakMVar
@@ -349,8 +353,10 @@ withBreakAction opts breakMVar statusMVar act
then pure Nothing
else do
tick_mod <- peekCString (Ptr tick_mod#)
+ tick_mod_uid <- BS.packCString (Ptr tick_mod_uid#)
info_mod <- peekCString (Ptr info_mod#)
- pure (Just (EvalBreakpoint tick_mod (I# tickx#) info_mod (I# infox#)))
+ info_mod_uid <- BS.packCString (Ptr info_mod_uid#)
+ pure (Just (EvalBreakpoint tick_mod tick_mod_uid (I# tickx#) info_mod info_mod_uid (I# infox#)))
putMVar statusMVar $ EvalBreak apStack_r breakpoint resume_r ccs
takeMVar breakMVar
@@ -400,8 +406,10 @@ resetStepFlag = poke stepFlag 0
type BreakpointCallback
= Addr# -- pointer to the breakpoint tick module name
+ -> Addr# -- pointer to the breakpoint tick module unit id
-> Int# -- breakpoint tick index
-> Addr# -- pointer to the breakpoint info module name
+ -> Addr# -- pointer to the breakpoint info module unit id
-> Int# -- breakpoint info index
-> Bool -- exception?
-> HValue -- the AP_STACK, or exception
@@ -414,8 +422,8 @@ noBreakStablePtr :: StablePtr BreakpointCallback
noBreakStablePtr = unsafePerformIO $ newStablePtr noBreakAction
noBreakAction :: BreakpointCallback
-noBreakAction _ _ _ _ False _ = putStrLn "*** Ignoring breakpoint"
-noBreakAction _ _ _ _ True _ = return () -- exception: just continue
+noBreakAction _ _ _ _ _ _ False _ = putStrLn "*** Ignoring breakpoint"
+noBreakAction _ _ _ _ _ _ True _ = return () -- exception: just continue
-- Malloc and copy the bytes. We don't have any way to monitor the
-- lifetime of this memory, so it just leaks.
@@ -432,6 +440,13 @@ mkString0 bs = B.unsafeUseAsCStringLen bs $ \(cstr,len) -> do
pokeElemOff (ptr :: Ptr CChar) len 0
return (castRemotePtr (toRemotePtr ptr))
+mkShortByteString0 :: BS.ShortByteString -> IO (RemotePtr ())
+mkShortByteString0 bs = BS.useAsCStringLen bs $ \(cstr,len) -> do
+ ptr <- mallocBytes (len+1)
+ copyBytes ptr cstr len
+ pokeElemOff (ptr :: Ptr CChar) len 0
+ return (castRemotePtr (toRemotePtr ptr))
+
mkCostCentres :: String -> [(String,String)] -> IO [RemotePtr CostCentre]
#if defined(PROFILING)
mkCostCentres mod ccs = do
@@ -453,6 +468,10 @@ newModuleName :: String -> IO (RemotePtr BreakModule)
newModuleName name =
castRemotePtr . toRemotePtr <$> newCString name
+newUnitId :: BS.ShortByteString -> IO (RemotePtr BreakUnitId)
+newUnitId name =
+ castRemotePtr <$> mkShortByteString0 name
+
getIdValFromApStack :: HValue -> Int -> IO (Maybe HValue)
getIdValFromApStack apStack (I# stackDepth) = do
case getApStackVal# apStack stackDepth of
=====================================
rts/Exception.cmm
=====================================
@@ -535,12 +535,16 @@ retry_pop_stack:
// be per-thread.
CInt[rts_stop_on_exception] = 0;
("ptr" ioAction) = ccall deRefStablePtr (W_[rts_breakpoint_io_action] "ptr");
- Sp = Sp - WDS(13);
- Sp(12) = exception;
- Sp(11) = stg_raise_ret_info;
- Sp(10) = exception;
- Sp(9) = ghczminternal_GHCziInternalziTypes_True_closure; // True <=> an exception
- Sp(8) = stg_ap_ppv_info;
+ Sp = Sp - WDS(17);
+ Sp(16) = exception;
+ Sp(15) = stg_raise_ret_info;
+ Sp(14) = exception;
+ Sp(13) = ghczminternal_GHCziInternalziTypes_True_closure; // True <=> an exception
+ Sp(12) = stg_ap_ppv_info;
+ Sp(11) = 0;
+ Sp(10) = stg_ap_n_info;
+ Sp(9) = 0;
+ Sp(8) = stg_ap_n_info;
Sp(7) = 0;
Sp(6) = stg_ap_n_info;
Sp(5) = 0;
=====================================
rts/Interpreter.c
=====================================
@@ -1245,9 +1245,9 @@ run_BCO:
/* check for a breakpoint on the beginning of a let binding */
case bci_BRK_FUN:
{
- int arg1_brk_array, arg2_tick_mod, arg3_info_mod, arg4_tick_index, arg5_info_index;
+ int arg1_brk_array, arg2_tick_mod, arg3_info_mod, arg4_tick_mod_id, arg5_info_mod_id, arg6_tick_index, arg7_info_index;
#if defined(PROFILING)
- int arg6_cc;
+ int arg8_cc;
#endif
StgArrBytes *breakPoints;
int returning_from_break;
@@ -1264,10 +1264,12 @@ run_BCO:
arg1_brk_array = BCO_GET_LARGE_ARG;
arg2_tick_mod = BCO_GET_LARGE_ARG;
arg3_info_mod = BCO_GET_LARGE_ARG;
- arg4_tick_index = BCO_NEXT;
- arg5_info_index = BCO_NEXT;
+ arg4_tick_mod_id = BCO_GET_LARGE_ARG;
+ arg5_info_mod_id = BCO_GET_LARGE_ARG;
+ arg6_tick_index = BCO_NEXT;
+ arg7_info_index = BCO_NEXT;
#if defined(PROFILING)
- arg6_cc = BCO_GET_LARGE_ARG;
+ arg8_cc = BCO_GET_LARGE_ARG;
#else
BCO_GET_LARGE_ARG;
#endif
@@ -1280,7 +1282,7 @@ run_BCO:
#if defined(PROFILING)
cap->r.rCCCS = pushCostCentre(cap->r.rCCCS,
- (CostCentre*)BCO_LIT(arg6_cc));
+ (CostCentre*)BCO_LIT(arg8_cc));
#endif
// if we are returning from a break then skip this section
@@ -1292,11 +1294,11 @@ run_BCO:
// stop the current thread if either the
// "rts_stop_next_breakpoint" flag is true OR if the
// ignore count for this particular breakpoint is zero
- StgInt ignore_count = ((StgInt*)breakPoints->payload)[arg4_tick_index];
+ StgInt ignore_count = ((StgInt*)breakPoints->payload)[arg6_tick_index];
if (rts_stop_next_breakpoint == false && ignore_count > 0)
{
// decrement and write back ignore count
- ((StgInt*)breakPoints->payload)[arg4_tick_index] = --ignore_count;
+ ((StgInt*)breakPoints->payload)[arg6_tick_index] = --ignore_count;
}
else if (rts_stop_next_breakpoint == true || ignore_count == 0)
{
@@ -1330,8 +1332,10 @@ run_BCO:
// continue execution of this BCO when the IO action returns.
//
// ioAction :: Addr# -- the breakpoint tick module
+ // -> Addr# -- the breakpoint tick module unit id
// -> Int# -- the breakpoint tick index
// -> Addr# -- the breakpoint info module
+ // -> Addr# -- the breakpoint info module unit id
// -> Int# -- the breakpoint info index
// -> Bool -- exception?
// -> HValue -- the AP_STACK, or exception
@@ -1340,17 +1344,21 @@ run_BCO:
ioAction = (StgClosure *) deRefStablePtr (
rts_breakpoint_io_action);
- Sp_subW(15);
- SpW(14) = (W_)obj;
- SpW(13) = (W_)&stg_apply_interp_info;
- SpW(12) = (W_)new_aps;
- SpW(11) = (W_)False_closure; // True <=> an exception
- SpW(10) = (W_)&stg_ap_ppv_info;
- SpW(9) = (W_)arg5_info_index;
+ Sp_subW(19);
+ SpW(18) = (W_)obj;
+ SpW(17) = (W_)&stg_apply_interp_info;
+ SpW(16) = (W_)new_aps;
+ SpW(15) = (W_)False_closure; // True <=> an exception
+ SpW(14) = (W_)&stg_ap_ppv_info;
+ SpW(13) = (W_)arg7_info_index;
+ SpW(12) = (W_)&stg_ap_n_info;
+ SpW(11) = (W_)BCO_LIT(arg5_info_mod_id);
+ SpW(10) = (W_)&stg_ap_n_info;
+ SpW(9) = (W_)BCO_LIT(arg3_info_mod);
SpW(8) = (W_)&stg_ap_n_info;
- SpW(7) = (W_)BCO_LIT(arg3_info_mod);
+ SpW(7) = (W_)arg6_tick_index;
SpW(6) = (W_)&stg_ap_n_info;
- SpW(5) = (W_)arg4_tick_index;
+ SpW(5) = (W_)BCO_LIT(arg4_tick_mod_id);
SpW(4) = (W_)&stg_ap_n_info;
SpW(3) = (W_)BCO_LIT(arg2_tick_mod);
SpW(2) = (W_)&stg_ap_n_info;
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/52e76dbd79295e53c0383f3b53d827…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/52e76dbd79295e53c0383f3b53d827…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/T25968] Move Data ModuleName instance to Language.Haskell.Syntax.Module.Name
by Ben Gamari (@bgamari) 24 Apr '25
by Ben Gamari (@bgamari) 24 Apr '25
24 Apr '25
Ben Gamari pushed to branch wip/T25968 at Glasgow Haskell Compiler / GHC
Commits:
a31466b2 by Ben Gamari at 2025-04-24T13:51:47-04:00
Move Data ModuleName instance to Language.Haskell.Syntax.Module.Name
Fixes #25968.
- - - - -
2 changed files:
- compiler/GHC/Unit/Types.hs
- compiler/Language/Haskell/Syntax/Module/Name.hs
Changes:
=====================================
compiler/GHC/Unit/Types.hs
=====================================
@@ -96,7 +96,7 @@ import GHC.Utils.Misc
import GHC.Settings.Config (cProjectUnitId)
import Control.DeepSeq (NFData(..))
-import Data.Data
+import Data.Data (Data(..))
import Data.List (sortBy)
import Data.Function
import Data.Bifunctor
@@ -117,12 +117,6 @@ data GenModule unit = Module
}
deriving (Eq,Ord,Data,Functor)
-instance Data ModuleName where
- -- don't traverse?
- toConstr _ = abstractConstr "ModuleName"
- gunfold _ _ = error "gunfold"
- dataTypeOf _ = mkNoRepType "ModuleName"
-
-- | A Module is a pair of a 'Unit' and a 'ModuleName'.
type Module = GenModule Unit
=====================================
compiler/Language/Haskell/Syntax/Module/Name.hs
=====================================
@@ -3,6 +3,7 @@ module Language.Haskell.Syntax.Module.Name where
import Prelude
import Data.Char (isAlphaNum)
+import Data.Data
import Control.DeepSeq
import qualified Text.ParserCombinators.ReadP as Parse
import System.FilePath
@@ -12,6 +13,14 @@ import GHC.Data.FastString
-- | A ModuleName is essentially a simple string, e.g. @Data.List@.
newtype ModuleName = ModuleName FastString deriving (Show, Eq)
+instance Data ModuleName where
+ -- don't traverse?
+ toConstr x = constr
+ where
+ constr = mkConstr (datatypeOf x) "{abstract:ModuleName}" [] Prefix
+ gunfold _ _ = error "gunfold"
+ dataTypeOf _ = mkNoRepType "ModuleName"
+
instance Ord ModuleName where
nm1 `compare` nm2 = stableModuleNameCmp nm1 nm2
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a31466b2372c627de73da3a3372a171…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a31466b2372c627de73da3a3372a171…
You're receiving this email because of your account on gitlab.haskell.org.
1
0