[Git][ghc/ghc][wip/MR14410-9.14] 8 commits: gitlab-ci: Bump DOCKER_REV
by Ben Gamari (@bgamari) 11 Aug '25
by Ben Gamari (@bgamari) 11 Aug '25
11 Aug '25
Ben Gamari pushed to branch wip/MR14410-9.14 at Glasgow Haskell Compiler / GHC
Commits:
70c0ad10 by Ben Gamari at 2025-08-11T14:55:06-04:00
gitlab-ci: Bump DOCKER_REV
- - - - -
71cd8990 by Andreas Klebinger at 2025-08-11T15:03:00-04:00
Specialise: Improve specialisation by refactoring interestingDict
This MR addresses #26051, which concerns missed type-class specialisation.
The main payload of the MR is to completely refactor the key function
`interestingDict` in GHC.Core.Opt.Specialise
The main change is that we now also look at the structure of the
dictionary we consider specializing on, rather than only the type.
See the big `Note [Interesting dictionary arguments]`
(cherry picked from commit f707bab4936fee2d8e2edd17512b18dfa98f56da)
- - - - -
bd0502a9 by Simon Peyton Jones at 2025-08-11T15:03:00-04:00
Renaming around predicate types
.. we were (as it turned out) abstracting over
type-class selectors in SPECIALISATION rules!
Wibble isEqPred
(cherry picked from commit a49eca26796851d0a63f4a7fa4afe562247b8074)
- - - - -
695fc5d2 by Simon Peyton Jones at 2025-08-11T15:03:00-04:00
Refactor of Specialise.hs
This patch just tidies up `specHeader` a bit, removing one
of its many results, and adding some comments.
No change in behaviour.
Also add a few more `HasDebugCallStack` contexts.
(cherry picked from commit f80375dd4945350a1d784e436975b48b9c736eaf)
- - - - -
c5eff1de by Simon Peyton Jones at 2025-08-11T15:03:00-04:00
Improve treatment of SPECIALISE pragmas -- again!
This MR does another major refactor of the way that SPECIALISE
pragmas work, to fix #26115, #26116, #26117.
* We now /always/ solve forall-constraints in an all-or-nothing way.
See Note [Solving a Wanted forall-constraint] in GHC.Tc.Solver.Solve
This means we might have unsolved quantified constraints, which need
to be reported. See `inert_insts` in `getUnsolvedInerts`.
* I refactored the short-cut solver for type classes to work by
recursively calling the solver rather than by having a little baby
solver that kept being not clever enough.
See Note [Shortcut solving] in GHC.Tc.Solver.Dict
* I totally rewrote the desugaring of SPECIALISE pragmas, again.
The new story is in Note [Desugaring new-form SPECIALISE pragmas]
in GHC.HsToCore.Binds
Both old-form and new-form SPECIALISE pragmas now route through the same
function `dsSpec_help`. The tricky function `decomposeRuleLhs` is now used only
for user-written RULES, not for SPECIALISE pragmas.
* I improved `solveOneFromTheOther` to account for rewriter sets. Previously
it would solve a non-rewritten dict from a rewritten one. For equalities
we were already dealing with this, in
Some incidental refactoring
* A small refactor: `ebv_tcvs` in `EvBindsBar` now has a list of coercions, rather
than a set of tyvars. We just delay taking the free vars.
* GHC.Core.FVs.exprFVs now returns /all/ free vars.
Use `exprLocalFVs` for Local vars.
Reason: I wanted another variant for /evidence/ variables.
* Ues `EvId` in preference to `EvVar`. (Evidence variables are always Ids.)
Rename `isEvVar` to `isEvId`.
* I moved `inert_safehask` out of `InertCans` and into `InertSet` where it
more properly belongs.
Compiler-perf changes:
* There was a palpable bug (#26117) which this MR fixes in
newWantedEvVar, which bypassed all the subtle overlapping-Given
and shortcutting logic. (See the new `newWantedEvVar`.) Fixing this
but leads to extra dictionary bindings; they are optimised away quickly
but they made CoOpt_Read allocate 3.6% more.
* Hpapily T15164 improves.
* The net compiler-allocation change is 0.0%
Metric Decrease:
T15164
Metric Increase:
CoOpt_Read
T12425
(cherry picked from commit 1bd12371feacc52394a0e660ef9349f9e8ee1c06)
- - - - -
1c578310 by Simon Peyton Jones at 2025-08-11T15:03:01-04:00
Solve forall-constraints immediately, or not at all
This MR refactors the constraint solver to solve forall-constraints immediately,
rather than emitting an implication constraint to be solved later.
The most immediate motivation was that when solving quantified constraints
in SPECIALISE pragmas, we really really don't want to leave behind half-
solved implications. Also it's in tune with the approach of the new
short-cut solver, which recursively invokes the solver.
It /also/ saves quite a bit of plumbing; e.g
- The `wl_implics` field of `WorkList` is gone,
- The types of `solveSimpleWanteds` and friends are simplified.
- An EvFun contains binding, rather than an EvBindsVar ref-cell that
will in the future contain bindings. That makes `evVarsOfTerm`
simpler. Much nicer.
It also improves error messages a bit.
All described in Note [Solving a Wanted forall-constraint] in
GHC.Tc.Solver.Solve.
One tiresome point: in the tricky case of `inferConstraintsCoerceBased`
we make a forall-constraint. This we /do/ want to partially solve, so
we can infer a suitable context. (I'd be quite happy to force the user to
write a context, bt I don't want to change behavior.) So we want to generate
an /implication/ constraint in `emitPredSpecConstraints` rather than a
/forall-constraint/ as we were doing before. Discussed in (WFA3) of
the above Note.
Incidental refactoring
* `GHC.Tc.Deriv.Infer.inferConstraints` was consulting the state monad for
the DerivEnv that the caller had just consulted. Nicer to pass it as an
argument I think, so I have done that. No change in behaviour.
(cherry picked from commit 953fd8f1dc080f1c56e3a60b4b7157456949be29)
- - - - -
af1f7422 by Simon Peyton Jones at 2025-08-11T15:03:01-04:00
Remove duplicated code in Ast.hs for evTermFreeVars
This is just a tidy up.
(cherry picked from commit 6921ab42925cee4e922ec6ee8e1e509092d43918)
- - - - -
33331570 by Simon Peyton Jones at 2025-08-11T15:03:01-04:00
Small tc-tracing changes only
(cherry picked from commit 1165f5871b0b065b23ff244f054ddd13ef7113e7)
- - - - -
85 changed files:
- .gitlab-ci.yml
- compiler/GHC/Core.hs
- compiler/GHC/Core/FVs.hs
- compiler/GHC/Core/Make.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/Subst.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/Unfold/Make.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Infer.hs
- compiler/GHC/Tc/Deriv/Utils.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Rewrite.hs
- compiler/GHC/Tc/Solver/Solve.hs
- + compiler/GHC/Tc/Solver/Solve.hs-boot
- compiler/GHC/Tc/Solver/Types.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Validity.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/Types/Var.hs
- testsuite/tests/deriving/should_compile/T20815.hs
- testsuite/tests/deriving/should_fail/T12768.stderr
- testsuite/tests/deriving/should_fail/T1496.stderr
- testsuite/tests/deriving/should_fail/T5498.stderr
- testsuite/tests/deriving/should_fail/T7148.stderr
- testsuite/tests/deriving/should_fail/T7148a.stderr
- testsuite/tests/hiefile/should_run/HieQueries.stdout
- testsuite/tests/impredicative/T17332.stderr
- + testsuite/tests/perf/should_run/SpecTyFamRun.hs
- + testsuite/tests/perf/should_run/SpecTyFamRun.stdout
- + testsuite/tests/perf/should_run/SpecTyFam_Import.hs
- testsuite/tests/perf/should_run/all.T
- testsuite/tests/quantified-constraints/T15290a.stderr
- testsuite/tests/quantified-constraints/T19690.stderr
- testsuite/tests/quantified-constraints/T19921.stderr
- testsuite/tests/quantified-constraints/T21006.stderr
- testsuite/tests/roles/should_fail/RolesIArray.stderr
- + testsuite/tests/simplCore/should_compile/T26051.hs
- + testsuite/tests/simplCore/should_compile/T26051.stderr
- + testsuite/tests/simplCore/should_compile/T26051_Import.hs
- + testsuite/tests/simplCore/should_compile/T26115.hs
- + testsuite/tests/simplCore/should_compile/T26115.stderr
- + testsuite/tests/simplCore/should_compile/T26116.hs
- + testsuite/tests/simplCore/should_compile/T26116.stderr
- + testsuite/tests/simplCore/should_compile/T26117.hs
- + testsuite/tests/simplCore/should_compile/T26117.stderr
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/typecheck/should_compile/T12427a.stderr
- testsuite/tests/typecheck/should_compile/T23171.hs
- testsuite/tests/typecheck/should_compile/TcSpecPragmas.stderr
- testsuite/tests/typecheck/should_fail/T14605.hs
- testsuite/tests/typecheck/should_fail/T14605.stderr
- testsuite/tests/typecheck/should_fail/T15801.stderr
- testsuite/tests/typecheck/should_fail/T18640a.stderr
- testsuite/tests/typecheck/should_fail/T18640b.stderr
- testsuite/tests/typecheck/should_fail/T19627.stderr
- testsuite/tests/typecheck/should_fail/T21530b.stderr
- testsuite/tests/typecheck/should_fail/T22912.stderr
- testsuite/tests/typecheck/should_fail/tcfail174.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9091ff4087d0f03f52969be7a23485…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9091ff4087d0f03f52969be7a23485…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
11 Aug '25
Ben Gamari pushed new branch wip/bump-docker-9.14 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/bump-docker-9.14
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: Take more care in zonkEqTypes on AppTy/AppTy
by Marge Bot (@marge-bot) 11 Aug '25
by Marge Bot (@marge-bot) 11 Aug '25
11 Aug '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
18036d52 by Simon Peyton Jones at 2025-08-11T11:31:20-04:00
Take more care in zonkEqTypes on AppTy/AppTy
This patch fixes #26256.
See Note [zonkEqTypes and the PKTI] in GHC.Tc.Solver.Equality
- - - - -
c8d76a29 by Zubin Duggal at 2025-08-11T11:32:02-04:00
ci: upgrade bootstrap compiler on windows to 9.10.1
- - - - -
7feeedf2 by sheaf at 2025-08-11T14:39:26-04:00
Improve deep subsumption
This commit improves the DeepSubsumption sub-typing implementation
in GHC.Tc.Utils.Unify.tc_sub_type_deep by being less eager to fall back
to unification.
For example, we now are properly able to prove the subtyping relationship
((∀ a. a->a) -> Int) -> Bool <= β[tau] Bool
for an unfilled metavariable β. In this case (with an AppTy on the right),
we used to fall back to unification. No longer: now, given that the LHS
is a FunTy and that the RHS is a deep rho type (does not need any instantiation),
we try to make the RHS into a FunTy, viz.
β := (->) γ
We can then continue using covariance & contravariance of the function
arrow, which allows us to prove the subtyping relationship, instead of
trying to unify which would cause us to error out with:
Couldn't match expected type ‘β’ with actual type ‘(->) ((∀ a. a -> a) -> Int)
See Note [FunTy vs non-FunTy case in tc_sub_type_deep] in GHC.Tc.Utils.Unify.
The other main improvement in this patch concerns type inference.
The main subsumption logic happens (before & after this patch) in
GHC.Tc.Gen.App.checkResultTy. However, before this patch, all of the
DeepSubsumption logic only kicked in in 'check' mode, not in 'infer' mode.
This patch adds deep instantiation in the 'infer' mode of checkResultTy
when we are doing deep subsumption, which allows us to accept programs
such as:
f :: Int -> (forall a. a->a)
g :: Int -> Bool -> Bool
test1 b =
case b of
True -> f
False -> g
test2 b =
case b of
True -> g
False -> f
See Note [Deeply instantiate in checkResultTy when inferring].
Finally, we add representation-polymorphism checks to ensure that the
lambda abstractions we introduce when doing subsumption obey the
representation polymorphism invariants of Note [Representation polymorphism invariants]
in GHC.Core. See Note [FunTy vs FunTy case in tc_sub_type_deep].
This is accompanied by a courtesy change to `(<.>) :: HsWrapper -> HsWrapper -> HsWrapper`,
adding the equation:
WpCast c1 <.> WpCast c2 = WpCast (c1 `mkTransCo` c2)
This is useful because mkWpFun does not introduce an eta-expansion when
both of the argument & result wrappers are casts; so this change allows
us to avoid introducing lambda abstractions when casts suffice.
Fixes #26225
- - - - -
46ebc712 by Sylvain Henry at 2025-08-11T14:39:50-04:00
Add regression test for #18619
- - - - -
36 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/GHC/Builtin/PrimOps/Ids.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Concrete.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Types/Id/Make.hs
- testsuite/tests/corelint/LintEtaExpand.stderr
- testsuite/tests/indexed-types/should_fail/T5439.stderr
- + testsuite/tests/numeric/should_run/T18619.hs
- + testsuite/tests/numeric/should_run/T18619.stderr
- testsuite/tests/numeric/should_run/all.T
- testsuite/tests/partial-sigs/should_compile/T10403.stderr
- + testsuite/tests/partial-sigs/should_compile/T26256.hs
- + testsuite/tests/partial-sigs/should_compile/T26256.stderr
- testsuite/tests/partial-sigs/should_compile/all.T
- testsuite/tests/partial-sigs/should_fail/T10615.stderr
- + testsuite/tests/rep-poly/NoEtaRequired.hs
- testsuite/tests/rep-poly/T21906.stderr
- testsuite/tests/rep-poly/all.T
- + testsuite/tests/typecheck/should_compile/T26225.hs
- + testsuite/tests/typecheck/should_compile/T26225b.hs
- + testsuite/tests/typecheck/should_compile/T26256a.hs
- testsuite/tests/typecheck/should_compile/all.T
- − testsuite/tests/typecheck/should_fail/T12563.stderr
- testsuite/tests/typecheck/should_fail/T14618.stderr
- testsuite/tests/typecheck/should_fail/T6022.stderr
- testsuite/tests/typecheck/should_fail/T8883.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail140.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e7755f73eb5b8d4593576a27e689e1…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e7755f73eb5b8d4593576a27e689e1…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
11 Aug '25
Ben Gamari pushed to branch wip/T26268 at Glasgow Haskell Compiler / GHC
Commits:
99817947 by Ben Gamari at 2025-08-11T13:39:40-04:00
Bump time submodule to 1.15
Also required bumps of Cabal, directory, and hpc.
- - - - -
7 changed files:
- compiler/ghc.cabal.in
- ghc/ghc-bin.cabal.in
- libraries/Cabal
- libraries/directory
- libraries/hpc
- libraries/time
- libraries/unix
Changes:
=====================================
compiler/ghc.cabal.in
=====================================
@@ -120,7 +120,7 @@ Library
process >= 1 && < 1.7,
bytestring >= 0.11 && < 0.13,
binary == 0.8.*,
- time >= 1.4 && < 1.15,
+ time >= 1.4 && < 1.16,
containers >= 0.6.2.1 && < 0.9,
array >= 0.1 && < 0.6,
filepath >= 1.5 && < 1.6,
=====================================
ghc/ghc-bin.cabal.in
=====================================
@@ -64,7 +64,7 @@ Executable ghc
ghci == @ProjectVersionMunged@,
haskeline == 0.8.*,
exceptions == 0.10.*,
- time >= 1.8 && < 1.15
+ time >= 1.8 && < 1.16
CPP-Options: -DHAVE_INTERNAL_INTERPRETER
Other-Modules:
GHCi.Leak
=====================================
libraries/Cabal
=====================================
@@ -1 +1 @@
-Subproject commit 703582f80f6d7f0c914ef4b885affcfc7b7b6ec8
+Subproject commit d9b0904b49dc84e0bfc79062daf2bbdf9d22a422
=====================================
libraries/directory
=====================================
@@ -1 +1 @@
-Subproject commit ffd4fc248ee36095ddec55598b0f8e3a9ac762a8
+Subproject commit 6442a3cf04f74d82cdf8c9213324313d52b23d28
=====================================
libraries/hpc
=====================================
@@ -1 +1 @@
-Subproject commit 7b7aed397cbe2bb36824d8627527fa4d5abffaa6
+Subproject commit 12675279dc5cbea4ade8b5157b080390d598f03f
=====================================
libraries/time
=====================================
@@ -1 +1 @@
-Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f
+Subproject commit 507f50844802f1469ba6cadfeefd4e3fecee0416
=====================================
libraries/unix
=====================================
@@ -1 +1 @@
-Subproject commit 1c3548c3906bb0d912eda5685968934183f4b51f
+Subproject commit c9b3e95b5c15b118e55522bd92963038c6a88160
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9981794703ed4cb82bef7eafc19c1ae…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9981794703ed4cb82bef7eafc19c1ae…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/kill-ioport] 33 commits: Update comments on `OptKind` to reflect the code reality
by Ben Gamari (@bgamari) 11 Aug '25
by Ben Gamari (@bgamari) 11 Aug '25
11 Aug '25
Ben Gamari pushed to branch wip/kill-ioport at Glasgow Haskell Compiler / GHC
Commits:
ee2dc248 by Simon Hengel at 2025-07-31T06:25:35-04:00
Update comments on `OptKind` to reflect the code reality
- - - - -
b029633a by Wen Kokke at 2025-07-31T06:26:21-04:00
rts: Disable --eventlog-flush-interval unless compiled with -threaded.
This commit fixes issue #26222:
Using --eventlog-flush-interval with the non-threaded RTS leads to eventlog corruption.
https://gitlab.haskell.org/ghc/ghc/-/issues/26222
This commit makes three changes when code is compiled against the non-threaded RTS:
1. It disables the --eventlog-flush-interval flag.
2. It disables the documentation for the --eventlog-flush-interval flag.
3. It disables the relevant state from RtsConfig and code from Timer.
4. It updates the entry for --eventlog-flush-interval in the users guide.
- - - - -
31159f1d by Wen Kokke at 2025-07-31T06:26:21-04:00
rts: Split T20006 into tests with and without -threaded
- - - - -
618687ef by Simon Hengel at 2025-07-31T06:27:03-04:00
docs/users_guide/win32-dlls.rst: Remove references to `readline`
- - - - -
083e40f1 by Rodrigo Mesquita at 2025-08-01T04:38:23-04:00
debugger: Uniquely identify breakpoints by internal id
Since b85b11994e0130ff2401dd4bbdf52330e0bcf776 (support inlining
breakpoints), a breakpoint has been identified at runtime by *two* pairs
of <module,index>.
- The first, aka a 'BreakpointId', uniquely identifies a breakpoint in
the source of a module by using the Tick index. A Tick index can index
into ModBreaks.modBreaks_xxx to fetch source-level information about
where that tick originated.
- When a user specifies e.g. a line breakpoint using :break, we'll reverse
engineer what a Tick index for that line
- We update the `BreakArray` of that module (got from the
LoaderState) at that tick index to `breakOn`.
- A BCO we can stop at is headed by a BRK_FUN instruction. This
instruction stores in an operand the `tick index` it is associated
to. We look it up in the associated `BreakArray` (also an operand)
and check wheter it was set to `breakOn`.
- The second, aka the `ibi_info_mod` + `ibi_info_ix` of the
`InternalBreakpointId`, uniquely index into the `imodBreaks_breakInfo`
-- the information we gathered during code generation about the
existing breakpoint *ocurrences*.
- Note that with optimisation there may be many occurrences of the
same source-tick-breakpoint across different modules. The
`ibi_info_ix` is unique per occurrence, but the `bi_tick_ix` may be
shared. See Note [Breakpoint identifiers] about this.
- Note that besides the tick ids, info ids are also stored in
`BRK_FUN` so the break handler can refer to the associated
`CgBreakInfo`.
In light of that, the driving changes come from the desire to have the
info_id uniquely identify the breakpoint at runtime, and the source tick
id being derived from it:
- An InternalBreakpointId should uniquely identify a breakpoint just
from the code-generation identifiers of `ibi_info_ix` and `ibi_info_mod`.
So we drop `ibi_tick_mod` and `ibi_tick_ix`.
- A BRK_FUN instruction need only record the "internal breakpoint id",
not the tick-level id.
So we drop the tick mod and tick index operands.
- A BreakArray should be indexed by InternalBreakpointId rather than
BreakpointId
That means we need to do some more work when setting a breakpoint.
Specifically, we need to figure out the internal ids (occurrences of a
breakpoint) from the source-level BreakpointId we want to set the
breakpoint at (recall :break refers to breaks at the source level).
Besides this change being an improvement to the handling of breakpoints
(it's clearer to have a single unique identifier than two competing
ones), it unlocks the possibility of generating "internal" breakpoints
during Cg (needed for #26042).
It should also be easier to introduce multi-threaded-aware `BreakArrays`
following this change (needed for #26064).
Se also the new Note [ModBreaks vs InternalModBreaks]
On i386-linux:
-------------------------
Metric Decrease:
interpreter_steplocal
-------------------------
- - - - -
bf03bbaa by Simon Hengel at 2025-08-01T04:39:05-04:00
Don't use MCDiagnostic for `ghcExit`
This changes the error message of `ghcExit` from
```
<no location info>: error:
Compilation had errors
```
to
```
Compilation had errors
```
- - - - -
a889ec75 by Simon Hengel at 2025-08-01T04:39:05-04:00
Respect `-fdiagnostics-as-json` for driver diagnostics (see #24113)
- - - - -
81577fe7 by Ben Gamari at 2025-08-02T04:29:39-04:00
configure: Allow override of CrossCompiling
As noted in #26236, the current inference logic is a bit simplistic. In
particular, there are many cases (e.g. building for a new libc) where
the target and host triples may differ yet we are still able to run the
produced artifacts as native code.
Closes #26236.
- - - - -
01136779 by Andreas Klebinger at 2025-08-02T04:30:20-04:00
rts: Support COFF BigObj files in archives.
- - - - -
1f9e4f54 by Stephen Morgan at 2025-08-03T15:14:08+10:00
refactor: Modify Data.List.sortOn to use (>) instead of compare. (#26184)
This lets a more efficient (>) operation be used if one exists.
This is technically a breaking change for malformed Ord instances, where
x > y is not equivalent to compare x y == GT.
Discussed by the CLC in issue #332: https://github.com/haskell/core-libraries-committee/issues/332
- - - - -
4f6bc9cf by fendor at 2025-08-04T17:50:06-04:00
Revert "base: Expose Backtraces constructor and fields"
This reverts commit 17db44c5b32fff82ea988fa4f1a233d1a27bdf57.
- - - - -
bcdec657 by Zubin Duggal at 2025-08-05T10:37:29+05:30
compiler: Export a version of `newNameCache` that is not prone to footguns.
`newNameCache` must be initialized with both a non-"reserved" unique tag, as well
as a list of known key names. Failing to do so results in hard to debug unique conflicts.
It is difficult for API users to tell which unique tags are safe to use. So instead of leaving
this up to the user to decide, we now export a version of `newNameCache` which uses a guaranteed
non-reserved unique tag. In fact, this is now the way the unique tag is initialized for all invocations
of the compiler.
The original version of `newNameCache` is now exported as `newNameCache'` for advanced users.
We also deprecate `initNameCache` as it is also prone to footguns and is completely subsumed in
functionality by `newNameCache` and `newNameCache'`.
Fixes #26135 and #26055
- - - - -
57d3b4a8 by Andrew Lelechenko at 2025-08-05T18:36:31-04:00
hadrian: bump Stackage snapshot to LTS 24.2 / GHC 9.10.2
In line with #25693 we should use GHC 9.10 as a boot compiler,
while Hadrian stack.yaml was stuck on GHC 9.6.
- - - - -
c2a78cea by Peng Fan at 2025-08-05T18:37:27-04:00
NCG/LA64: implement atomic write with finer-grained DBAR hints
Signed-off-by: Peng Fan <fanpeng(a)loongson.cn>
- - - - -
95231c8e by Teo Camarasu at 2025-08-06T08:35:58-04:00
CODEOWNERS: add CLC as codeowner of base
We also remove hvr, since I think he is no longer active
- - - - -
77df0ded by Andrew Lelechenko at 2025-08-06T08:36:39-04:00
Bump submodule text to 2.1.3
- - - - -
8af260d0 by Nikolaos Chatzikonstantinou at 2025-08-06T08:37:23-04:00
docs: fix internal import in getopt examples
This external-facing doc example shouldn't mention GHC internals when
using 'fromMaybe'.
- - - - -
69cc16ca by Marc Scholten at 2025-08-06T15:51:28-04:00
README: Add note on ghc.nix
- - - - -
93a2f450 by Daniel Díaz at 2025-08-06T15:52:14-04:00
Link to the "Strict Bindings" docs from the linear types docs
Strict Bidings are relevant for the kinds of multiplicity annotations
linear lets support.
- - - - -
246b7853 by Matthew Pickering at 2025-08-07T06:58:30-04:00
level imports: Check the level of exported identifiers
The level imports specification states that exported identifiers have to
be at level 0. This patch adds the requird level checks that all
explicitly mentioned identifiers occur at level 0.
For implicit export specifications (T(..) and module B), only level 0
identifiers are selected for re-export.
ghc-proposal: https://github.com/ghc-proposals/ghc-proposals/pull/705
Fixes #26090
- - - - -
358bc4fc by fendor at 2025-08-07T06:59:12-04:00
Bump GHC on darwin CI to 9.10.1
- - - - -
1903ae35 by Matthew Pickering at 2025-08-07T12:21:10+01:00
ipe: Place strings and metadata into specific .ipe section
By placing the .ipe metadata into a specific section it can be stripped
from the final binary if desired.
```
objcopy --remove-section .ipe <binary>
upx <binary>
```
Towards #21766
- - - - -
c80dd91c by Matthew Pickering at 2025-08-07T12:22:42+01:00
ipe: Place magic word at the start of entries in the .ipe section
The magic word "IPE\nIPE\n" is placed at the start of .ipe sections,
then if the section is stripped, we can check whether the section starts
with the magic word or not to determine whether there is metadata
present or not.
Towards #21766
- - - - -
cab42666 by Matthew Pickering at 2025-08-07T12:22:42+01:00
ipe: Use stable IDs for IPE entries
IPEs have historically been indexed and reported by their address.
This makes it impossible to compare profiles between runs, since the
addresses may change (due to ASLR) and also makes it tricky to separate
out the IPE map from the binary.
This small patch adds a stable identifier for each IPE entry.
The stable identifier is a single 64 bit word. The high-bits are a
per-module identifier and the low bits identify which entry in each
module.
1. When a node is added into the IPE buffer it is assigned a unique
identifier from an incrementing global counter.
2. Each entry already has an index by it's position in the
`IpeBufferListNode`.
The two are combined together by the `IPE_ENTRY_KEY` macro.
Info table profiling uses the stable identifier rather than the address
of the info table.
The benefits of this change are:
* Profiles from different runs can be easily compared
* The metadata can be extracted from the binary (via the eventlog for
example) and then stripped from the executable.
Fixes #21766
- - - - -
2860a9a5 by Simon Peyton Jones at 2025-08-07T20:29:18-04:00
In TcSShortCut, typechecker plugins should get empty Givens
Solving in TcShortCut mode means /ignoring the Givens/. So we
should not pass them to typechecker plugins!
Fixes #26258.
This is a fixup to the earlier MR:
commit 1bd12371feacc52394a0e660ef9349f9e8ee1c06
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Jul 21 10:04:49 2025 +0100
Improve treatment of SPECIALISE pragmas -- again!
- - - - -
2157db2d by sterni at 2025-08-08T15:32:39-04:00
hadrian: enable terminfo if --with-curses-* flags are given
The GHC make build system used to support WITH_TERMINFO in ghc.mk which
allowed controlling whether to build GHC with terminfo or not. hadrian
has replaced this with a system where this is effectively controlled by
the cross-compiling setting (the default WITH_TERMINFO value was bassed
on CrossCompiling, iirc).
This behavior is undesireable in some cases and there is not really a
good way to work around it. Especially for downstream packagers,
modifying this via UserSettings is not really feasible since such a
source file has to be kept in sync with Settings/Default.hs manually
since it can't import Settings.Default or any predefined Flavour
definitions.
To avoid having to add a new setting to cfg/system.config and/or a new
configure flag (though I'm happy to implement both if required), I've
chosen to take --with-curses-* being set explicitly as an indication
that the user wants to have terminfo enabled. This would work for
Nixpkgs which sets these flags [1] as well as haskell.nix [2] (which
goes to some extreme measures [3] [4] to force terminfo in all scenarios).
In general, I'm an advocate for making the GHC build be the same for
native and cross insofar it is possible since it makes packaging GHC and
Haskell related things while still supporting cross much less
compilicated. A more minimal GHC with reduced dependencies should
probably be a specific flavor, not the default.
Partially addresses #26288 by forcing terminfo to be built if the user
explicitly passes configure flags related to it. However, it isn't built
by default when cross-compiling yet nor is there an explicit way to
control the package being built.
[1]: https://github.com/NixOS/nixpkgs/blob/3a7266fcefcb9ce353df49ba3f292d0644376…
[2]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
[3]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
[4]: https://github.com/input-output-hk/haskell.nix/blob/6eaafcdf04bab7be745d1aa…
- - - - -
b3c31488 by David Feuer at 2025-08-08T15:33:21-04:00
Add default QuasiQuoters
Add `defaultQuasiQuoter` and `namedDefaultQuasiQuoter` to make it easier
to write `QuasiQuoters` that give helpful error messages when they're
used in inappropriate contexts.
Closes #24434.
- - - - -
03555ed8 by Sylvain Henry at 2025-08-10T22:20:57-04:00
Handle non-fractional CmmFloats in Cmm's CBE (#26229)
Since f8d9d016305be355f518c141f6c6d4826f2de9a2, toRational for Float and
Double converts float's infinity and NaN into Rational's infinity and
NaN (respectively 1%0 and 0%0).
Cmm CommonBlockEliminator hashing function needs to take these values
into account as they can appear as literals now. See added testcase.
- - - - -
6c956af3 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Fix extensions list in `DoAndIfThenElse` docs
- - - - -
6dc420b1 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Document status of `RelaxedPolyRec` extension
This adds a brief extension page explaining the status of the
`RelaxedPolyRec` extension. The behaviour of this mode is already
explained elsewhere, so this page is mainly for completeness so that
various lists of extensions have somewhere to point to for this flag.
Fixes #18630
- - - - -
18036d52 by Simon Peyton Jones at 2025-08-11T11:31:20-04:00
Take more care in zonkEqTypes on AppTy/AppTy
This patch fixes #26256.
See Note [zonkEqTypes and the PKTI] in GHC.Tc.Solver.Equality
- - - - -
c8d76a29 by Zubin Duggal at 2025-08-11T11:32:02-04:00
ci: upgrade bootstrap compiler on windows to 9.10.1
- - - - -
34fc50c1 by Ben Gamari at 2025-08-11T13:36:25-04:00
Kill IOPort#
This type is unnecessary, having been superceded by `MVar` and a rework
of WinIO's blocking logic.
See #20947.
See https://github.com/haskell/core-libraries-committee/issues/213.
- - - - -
141 changed files:
- .gitlab/darwin/toolchain.nix
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- CODEOWNERS
- README.md
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/Builtin/Types/Prim.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Linker.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm.hs
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/CmmToAsm/LA64/CodeGen.hs
- compiler/GHC/CmmToAsm/PPC/Ppr.hs
- compiler/GHC/CmmToAsm/Ppr.hs
- compiler/GHC/CmmToLlvm/Data.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Driver/CmdLine.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/InfoTableProv.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/Prim.hs
- compiler/GHC/SysTools/Tasks.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Utils/Error.hs
- configure.ac
- docs/users_guide/conf.py
- docs/users_guide/debug-info.rst
- docs/users_guide/expected-undocumented-flags.txt
- docs/users_guide/exts/doandifthenelse.rst
- docs/users_guide/exts/linear_types.rst
- + docs/users_guide/exts/relaxed_poly_rec.rst
- docs/users_guide/exts/strict.rst
- docs/users_guide/exts/types.rst
- docs/users_guide/runtime_control.rst
- docs/users_guide/win32-dlls.rst
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Monad.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- hadrian/stack.yaml
- hadrian/stack.yaml.lock
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- libraries/base/src/Control/Exception/Backtrace.hs
- libraries/base/src/Data/List/NonEmpty.hs
- libraries/base/src/GHC/Exts.hs
- − libraries/base/src/GHC/IOPort.hs
- libraries/base/src/System/Console/GetOpt.hs
- libraries/ghc-heap/GHC/Exts/Heap/Closures.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/Thread.hs
- libraries/ghc-internal/src/GHC/Internal/Exts.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Buffer.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Windows/Handle.hsc
- − libraries/ghc-internal/src/GHC/Internal/IOPort.hs
- libraries/ghc-internal/src/GHC/Internal/Prim/PtrEq.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- libraries/ghc-prim/changelog.md
- libraries/ghci/GHCi/Debugger.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/Run.hs
- libraries/template-haskell/Language/Haskell/TH/Quote.hs
- libraries/template-haskell/changelog.md
- libraries/text
- rts/Disassembler.c
- rts/Exception.cmm
- rts/IPE.c
- rts/Interpreter.c
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/ProfHeap.c
- rts/RtsFlags.c
- rts/RtsSymbols.c
- rts/Timer.c
- rts/eventlog/EventLog.c
- rts/external-symbols.list.in
- rts/include/rts/Flags.h
- rts/include/rts/IPE.h
- rts/include/stg/MiscClosures.h
- rts/include/stg/SMP.h
- rts/linker/LoadArchive.c
- rts/win32/AsyncWinIO.c
- rts/win32/libHSghc-internal.def
- testsuite/tests/corelint/T21115b.stderr
- testsuite/tests/hiefile/should_run/TestUtils.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- + testsuite/tests/numeric/should_compile/T26229.hs
- testsuite/tests/numeric/should_compile/all.T
- + testsuite/tests/partial-sigs/should_compile/T26256.hs
- + testsuite/tests/partial-sigs/should_compile/T26256.stderr
- testsuite/tests/partial-sigs/should_compile/all.T
- testsuite/tests/primops/should_run/UnliftedIOPort.hs
- testsuite/tests/primops/should_run/all.T
- testsuite/tests/rts/flags/all.T
- testsuite/tests/rts/ipe/ipeMap.c
- testsuite/tests/rts/ipe/ipe_lib.c
- + testsuite/tests/splice-imports/DodgyLevelExport.hs
- + testsuite/tests/splice-imports/DodgyLevelExport.stderr
- + testsuite/tests/splice-imports/DodgyLevelExportA.hs
- + testsuite/tests/splice-imports/LevelImportExports.hs
- + testsuite/tests/splice-imports/LevelImportExports.stdout
- + testsuite/tests/splice-imports/LevelImportExportsA.hs
- testsuite/tests/splice-imports/Makefile
- + testsuite/tests/splice-imports/ModuleExport.hs
- + testsuite/tests/splice-imports/ModuleExport.stderr
- + testsuite/tests/splice-imports/ModuleExportA.hs
- + testsuite/tests/splice-imports/ModuleExportB.hs
- + testsuite/tests/splice-imports/T26090.hs
- + testsuite/tests/splice-imports/T26090.stderr
- + testsuite/tests/splice-imports/T26090A.hs
- testsuite/tests/splice-imports/all.T
- + testsuite/tests/typecheck/should_compile/T26256a.hs
- testsuite/tests/typecheck/should_compile/all.T
- utils/genprimopcode/Main.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d51eeae6d95d73fdb4c03d8356cdbf…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d51eeae6d95d73fdb4c03d8356cdbf…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
11 Aug '25
Ben Gamari pushed to branch wip/T26268 at Glasgow Haskell Compiler / GHC
Commits:
4d5bc565 by Ben Gamari at 2025-08-11T13:33:48-04:00
Bump time submodule to 1.15
Also required bumps of Cabal, directory, and hpc.
- - - - -
6 changed files:
- compiler/ghc.cabal.in
- ghc/ghc-bin.cabal.in
- libraries/Cabal
- libraries/directory
- libraries/hpc
- libraries/time
Changes:
=====================================
compiler/ghc.cabal.in
=====================================
@@ -120,7 +120,7 @@ Library
process >= 1 && < 1.7,
bytestring >= 0.11 && < 0.13,
binary == 0.8.*,
- time >= 1.4 && < 1.15,
+ time >= 1.4 && < 1.16,
containers >= 0.6.2.1 && < 0.9,
array >= 0.1 && < 0.6,
filepath >= 1.5 && < 1.6,
=====================================
ghc/ghc-bin.cabal.in
=====================================
@@ -64,7 +64,7 @@ Executable ghc
ghci == @ProjectVersionMunged@,
haskeline == 0.8.*,
exceptions == 0.10.*,
- time >= 1.8 && < 1.15
+ time >= 1.8 && < 1.16
CPP-Options: -DHAVE_INTERNAL_INTERPRETER
Other-Modules:
GHCi.Leak
=====================================
libraries/Cabal
=====================================
@@ -1 +1 @@
-Subproject commit 703582f80f6d7f0c914ef4b885affcfc7b7b6ec8
+Subproject commit d9b0904b49dc84e0bfc79062daf2bbdf9d22a422
=====================================
libraries/directory
=====================================
@@ -1 +1 @@
-Subproject commit ffd4fc248ee36095ddec55598b0f8e3a9ac762a8
+Subproject commit 6442a3cf04f74d82cdf8c9213324313d52b23d28
=====================================
libraries/hpc
=====================================
@@ -1 +1 @@
-Subproject commit 7b7aed397cbe2bb36824d8627527fa4d5abffaa6
+Subproject commit 12675279dc5cbea4ade8b5157b080390d598f03f
=====================================
libraries/time
=====================================
@@ -1 +1 @@
-Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f
+Subproject commit 507f50844802f1469ba6cadfeefd4e3fecee0416
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4d5bc565d4e361047a8153005a80275…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4d5bc565d4e361047a8153005a80275…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/spj-apporv-Oct24] 6 commits: Handle non-fractional CmmFloats in Cmm's CBE (#26229)
by Apoorv Ingle (@ani) 11 Aug '25
by Apoorv Ingle (@ani) 11 Aug '25
11 Aug '25
Apoorv Ingle pushed to branch wip/spj-apporv-Oct24 at Glasgow Haskell Compiler / GHC
Commits:
03555ed8 by Sylvain Henry at 2025-08-10T22:20:57-04:00
Handle non-fractional CmmFloats in Cmm's CBE (#26229)
Since f8d9d016305be355f518c141f6c6d4826f2de9a2, toRational for Float and
Double converts float's infinity and NaN into Rational's infinity and
NaN (respectively 1%0 and 0%0).
Cmm CommonBlockEliminator hashing function needs to take these values
into account as they can appear as literals now. See added testcase.
- - - - -
6c956af3 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Fix extensions list in `DoAndIfThenElse` docs
- - - - -
6dc420b1 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Document status of `RelaxedPolyRec` extension
This adds a brief extension page explaining the status of the
`RelaxedPolyRec` extension. The behaviour of this mode is already
explained elsewhere, so this page is mainly for completeness so that
various lists of extensions have somewhere to point to for this flag.
Fixes #18630
- - - - -
18036d52 by Simon Peyton Jones at 2025-08-11T11:31:20-04:00
Take more care in zonkEqTypes on AppTy/AppTy
This patch fixes #26256.
See Note [zonkEqTypes and the PKTI] in GHC.Tc.Solver.Equality
- - - - -
c8d76a29 by Zubin Duggal at 2025-08-11T11:32:02-04:00
ci: upgrade bootstrap compiler on windows to 9.10.1
- - - - -
6d1a2dac by Apoorv Ingle at 2025-08-11T12:08:40-05:00
This commit:
- Streamlines implementations of `tcExpr` and `tcXExpr` to work on `XExpr`
Calls `setInGeneratedCode` everytime the typechecker goes over an `XExpr`
- Kills `VACtxt` (and its associated VAExpansion and VACall) datatype, it is subsumed by simply a SrcSpan.
- Kills the function `addHeadCtxt` as it is now mearly setting a location
- The function `tcValArgs` does its own argument number management
- Makes `splitHsApps` not look through `XExpr`
- `tcExprSigma` is called if the head of the expression after calling `splitHsApps` turns out to be an `XExpr`
- Removes location information from `OrigPat` payload
- Removes special case of tcBody from `tcLambdaMatches`
- Removes special case of `dsExpr` for `ExpandedThingTc`
- Moves `setQLInstLevel` inside `tcInstFun`
- Rename `HsThingRn` to `SrcCodeCtxt`
- Kills `tcl_in_gen_code` and `tcl_err_ctxt`. It is subsumed by `ErrCtxtStack`
- Kills `ExpectedFunTyOrig`. It is subsumed by `CtOrigin`
- Fixes `CtOrigin` for `HsProjection` case in `exprCtOrigin`. It was previously assigned to be `SectionOrigin`. It is now just the expression
- Adds a new `CtOrigin.ExpansionOrigin` for storing the original syntax
- Adds a new `CtOrigin.ExpectedTySyntax` as a replacement for `ExpectedTySyntaxOp`. Cannot kill the former yet because of `ApplicativeDo`
- Renames `tcMonoExpr` -> `tcMonoLExpr`, `tcMonoExprNC` -> `tcMonoLExpr`
- Renames `EValArg`, `EValArgQL` fields: `ea_ctxt` -> `ea_loc_span` and `eaql_ctx` -> `eaql_loc_span`
Notes added [Error Context Stack]
Notes updated Note [Expanding HsDo with XXExprGhcRn]
-------------------------
Metric Decrease:
T9020
-------------------------
- - - - -
69 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/Hs.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Gen/App.hs
- + compiler/GHC/Tc/Gen/App.hs-boot
- compiler/GHC/Tc/Gen/Do.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs-boot
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Types/ErrCtxt.hs
- compiler/GHC/Tc/Types/LclEnv.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/Unify.hs
- docs/users_guide/conf.py
- docs/users_guide/expected-undocumented-flags.txt
- docs/users_guide/exts/doandifthenelse.rst
- + docs/users_guide/exts/relaxed_poly_rec.rst
- docs/users_guide/exts/types.rst
- testsuite/tests/default/default-fail05.stderr
- testsuite/tests/indexed-types/should_fail/T2693.stderr
- testsuite/tests/indexed-types/should_fail/T5439.stderr
- + testsuite/tests/numeric/should_compile/T26229.hs
- testsuite/tests/numeric/should_compile/all.T
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail10.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail11.stderr
- + testsuite/tests/partial-sigs/should_compile/T26256.hs
- + testsuite/tests/partial-sigs/should_compile/T26256.stderr
- testsuite/tests/partial-sigs/should_compile/all.T
- testsuite/tests/plugins/test-defaulting-plugin.stderr
- testsuite/tests/polykinds/T13393.stderr
- testsuite/tests/printer/T17697.stderr
- testsuite/tests/rep-poly/RepPolyDoBind.stderr
- testsuite/tests/rep-poly/RepPolyDoBody1.stderr
- testsuite/tests/rep-poly/RepPolyDoBody2.stderr
- testsuite/tests/rep-poly/RepPolyRecordUpdate.stderr
- testsuite/tests/typecheck/should_compile/T14590.stderr
- + testsuite/tests/typecheck/should_compile/T26256a.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/valid_hole_fits.stderr
- testsuite/tests/typecheck/should_fail/DoExpansion1.stderr
- testsuite/tests/typecheck/should_fail/DoExpansion2.stderr
- testsuite/tests/typecheck/should_fail/T10971d.stderr
- testsuite/tests/typecheck/should_fail/T13311.stderr
- testsuite/tests/typecheck/should_fail/T24064.stderr
- testsuite/tests/typecheck/should_fail/T3323.stderr
- testsuite/tests/typecheck/should_fail/T3613.stderr
- testsuite/tests/typecheck/should_fail/T7851.stderr
- testsuite/tests/typecheck/should_fail/T8603.stderr
- testsuite/tests/typecheck/should_fail/T9612.stderr
- testsuite/tests/typecheck/should_fail/tcfail102.stderr
- testsuite/tests/typecheck/should_fail/tcfail128.stderr
- testsuite/tests/typecheck/should_fail/tcfail168.stderr
- testsuite/tests/warnings/should_fail/CaretDiagnostics1.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/90a013ab3a8b40d04513214b4bbf90…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/90a013ab3a8b40d04513214b4bbf90…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Ben Gamari pushed new branch wip/T26268 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T26268
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fix-26109] 6 commits: Handle non-fractional CmmFloats in Cmm's CBE (#26229)
by recursion-ninja (@recursion-ninja) 11 Aug '25
by recursion-ninja (@recursion-ninja) 11 Aug '25
11 Aug '25
recursion-ninja pushed to branch wip/fix-26109 at Glasgow Haskell Compiler / GHC
Commits:
03555ed8 by Sylvain Henry at 2025-08-10T22:20:57-04:00
Handle non-fractional CmmFloats in Cmm's CBE (#26229)
Since f8d9d016305be355f518c141f6c6d4826f2de9a2, toRational for Float and
Double converts float's infinity and NaN into Rational's infinity and
NaN (respectively 1%0 and 0%0).
Cmm CommonBlockEliminator hashing function needs to take these values
into account as they can appear as literals now. See added testcase.
- - - - -
6c956af3 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Fix extensions list in `DoAndIfThenElse` docs
- - - - -
6dc420b1 by J. Ryan Stinnett at 2025-08-10T22:21:42-04:00
Document status of `RelaxedPolyRec` extension
This adds a brief extension page explaining the status of the
`RelaxedPolyRec` extension. The behaviour of this mode is already
explained elsewhere, so this page is mainly for completeness so that
various lists of extensions have somewhere to point to for this flag.
Fixes #18630
- - - - -
18036d52 by Simon Peyton Jones at 2025-08-11T11:31:20-04:00
Take more care in zonkEqTypes on AppTy/AppTy
This patch fixes #26256.
See Note [zonkEqTypes and the PKTI] in GHC.Tc.Solver.Equality
- - - - -
c8d76a29 by Zubin Duggal at 2025-08-11T11:32:02-04:00
ci: upgrade bootstrap compiler on windows to 9.10.1
- - - - -
eb410f1b by Recursion Ninja at 2025-08-11T13:08:58-04:00
Resolving issues #20645 and #26109
Correctly sign extending and casting smaller bit width types for LLVM operations:
- bitReverse8#
- bitReverse16#
- bitReverse32#
- byteSwap16#
- byteSwap32#
- pdep8#
- pdep16#
- pext8#
- pext16#
- - - - -
29 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Tc/Solver/Equality.hs
- docs/users_guide/conf.py
- docs/users_guide/expected-undocumented-flags.txt
- docs/users_guide/exts/doandifthenelse.rst
- + docs/users_guide/exts/relaxed_poly_rec.rst
- docs/users_guide/exts/types.rst
- libraries/ghc-internal/cbits/pdep.c
- libraries/ghc-internal/cbits/pext.c
- + testsuite/tests/llvm/should_run/T20645.hs
- + testsuite/tests/llvm/should_run/T20645.stdout
- testsuite/tests/llvm/should_run/all.T
- + testsuite/tests/numeric/should_compile/T26229.hs
- testsuite/tests/numeric/should_compile/all.T
- testsuite/tests/numeric/should_run/foundation.hs
- + testsuite/tests/partial-sigs/should_compile/T26256.hs
- + testsuite/tests/partial-sigs/should_compile/T26256.stderr
- testsuite/tests/partial-sigs/should_compile/all.T
- + testsuite/tests/typecheck/should_compile/T26256a.hs
- testsuite/tests/typecheck/should_compile/all.T
- utils/genprimopcode/Lexer.x
- utils/genprimopcode/Main.hs
- utils/genprimopcode/Parser.y
- utils/genprimopcode/ParserM.hs
- utils/genprimopcode/Syntax.hs
Changes:
=====================================
.gitlab/generate-ci/gen_ci.hs
=====================================
@@ -478,7 +478,7 @@ opsysVariables _ (Windows {}) = mconcat
, "LANG" =: "en_US.UTF-8"
, "CABAL_INSTALL_VERSION" =: "3.10.2.0"
, "HADRIAN_ARGS" =: "--docs=no-sphinx-pdfs"
- , "GHC_VERSION" =: "9.6.4"
+ , "GHC_VERSION" =: "9.10.1"
]
opsysVariables _ _ = mempty
=====================================
.gitlab/jobs.yaml
=====================================
@@ -3698,7 +3698,7 @@
"BUILD_FLAVOUR": "validate",
"CABAL_INSTALL_VERSION": "3.10.2.0",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
- "GHC_VERSION": "9.6.4",
+ "GHC_VERSION": "9.10.1",
"HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"LANG": "en_US.UTF-8",
@@ -3761,7 +3761,7 @@
"BUILD_FLAVOUR": "validate",
"CABAL_INSTALL_VERSION": "3.10.2.0",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
- "GHC_VERSION": "9.6.4",
+ "GHC_VERSION": "9.10.1",
"HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"LANG": "en_US.UTF-8",
@@ -5579,7 +5579,7 @@
"BUILD_FLAVOUR": "release",
"CABAL_INSTALL_VERSION": "3.10.2.0",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
- "GHC_VERSION": "9.6.4",
+ "GHC_VERSION": "9.10.1",
"HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
"IGNORE_PERF_FAILURES": "all",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
@@ -5643,7 +5643,7 @@
"BUILD_FLAVOUR": "release",
"CABAL_INSTALL_VERSION": "3.10.2.0",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
- "GHC_VERSION": "9.6.4",
+ "GHC_VERSION": "9.10.1",
"HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
"IGNORE_PERF_FAILURES": "all",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
@@ -7982,7 +7982,7 @@
"BUILD_FLAVOUR": "validate",
"CABAL_INSTALL_VERSION": "3.10.2.0",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
- "GHC_VERSION": "9.6.4",
+ "GHC_VERSION": "9.10.1",
"HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"LANG": "en_US.UTF-8",
@@ -8044,7 +8044,7 @@
"BUILD_FLAVOUR": "validate",
"CABAL_INSTALL_VERSION": "3.10.2.0",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
- "GHC_VERSION": "9.6.4",
+ "GHC_VERSION": "9.10.1",
"HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"LANG": "en_US.UTF-8",
=====================================
compiler/GHC/Builtin/primops.txt.pp
=====================================
@@ -148,6 +148,7 @@ defaults
vector = []
deprecated_msg = {} -- A non-empty message indicates deprecation
div_like = False -- Second argument expected to be non zero - used for tests
+ defined_bits = Nothing -- The number of bits the operation is defined for (if not all bits)
-- Note [When do out-of-line primops go in primops.txt.pp]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1065,8 +1066,10 @@ primop CtzOp "ctz#" GenPrimOp Word# -> Word#
primop BSwap16Op "byteSwap16#" GenPrimOp Word# -> Word#
{Swap bytes in the lower 16 bits of a word. The higher bytes are undefined. }
+ with defined_bits = 16
primop BSwap32Op "byteSwap32#" GenPrimOp Word# -> Word#
{Swap bytes in the lower 32 bits of a word. The higher bytes are undefined. }
+ with defined_bits = 32
primop BSwap64Op "byteSwap64#" GenPrimOp Word64# -> Word64#
{Swap bytes in a 64 bits of a word.}
primop BSwapOp "byteSwap#" GenPrimOp Word# -> Word#
@@ -1074,10 +1077,13 @@ primop BSwapOp "byteSwap#" GenPrimOp Word# -> Word#
primop BRev8Op "bitReverse8#" GenPrimOp Word# -> Word#
{Reverse the order of the bits in a 8-bit word.}
+ with defined_bits = 8
primop BRev16Op "bitReverse16#" GenPrimOp Word# -> Word#
{Reverse the order of the bits in a 16-bit word.}
+ with defined_bits = 16
primop BRev32Op "bitReverse32#" GenPrimOp Word# -> Word#
{Reverse the order of the bits in a 32-bit word.}
+ with defined_bits = 32
primop BRev64Op "bitReverse64#" GenPrimOp Word64# -> Word64#
{Reverse the order of the bits in a 64-bit word.}
primop BRevOp "bitReverse#" GenPrimOp Word# -> Word#
=====================================
compiler/GHC/Cmm/CommonBlockElim.hs
=====================================
@@ -29,6 +29,7 @@ import GHC.Utils.Word64 (truncateWord64ToWord32)
import Control.Arrow (first, second)
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NE
+import GHC.Real (infinity,notANumber)
-- -----------------------------------------------------------------------------
-- Eliminate common blocks
@@ -167,7 +168,12 @@ hash_block block =
hash_lit :: CmmLit -> Word32
hash_lit (CmmInt i _) = fromInteger i
- hash_lit (CmmFloat r _) = truncate r
+ hash_lit (CmmFloat r _)
+ -- handle these special cases as `truncate` fails on non-fractional numbers (#26229)
+ | r == infinity = 9999999
+ | r == -infinity = 9999998
+ | r == notANumber = 6666666
+ | otherwise = truncate r
hash_lit (CmmVec ls) = hash_list hash_lit ls
hash_lit (CmmLabel _) = 119 -- ugh
hash_lit (CmmLabelOff _ i) = cvt $ 199 + i
=====================================
compiler/GHC/CmmToLlvm/CodeGen.hs
=====================================
@@ -230,23 +230,22 @@ genCall t@(PrimTarget (MO_Prefetch_Data localityInt)) [] args
statement $ Expr $ Call StdCall fptr (argVars' ++ argSuffix) []
| otherwise = panic $ "prefetch locality level integer must be between 0 and 3, given: " ++ (show localityInt)
--- Handle PopCnt, Clz, Ctz, and BSwap that need to only convert arg
--- and return types
-genCall t@(PrimTarget (MO_PopCnt w)) dsts args =
- genCallSimpleCast w t dsts args
-
-genCall t@(PrimTarget (MO_Pdep w)) dsts args =
- genCallSimpleCast2 w t dsts args
-genCall t@(PrimTarget (MO_Pext w)) dsts args =
- genCallSimpleCast2 w t dsts args
-genCall t@(PrimTarget (MO_Clz w)) dsts args =
- genCallSimpleCast w t dsts args
-genCall t@(PrimTarget (MO_Ctz w)) dsts args =
- genCallSimpleCast w t dsts args
-genCall t@(PrimTarget (MO_BSwap w)) dsts args =
- genCallSimpleCast w t dsts args
-genCall t@(PrimTarget (MO_BRev w)) dsts args =
- genCallSimpleCast w t dsts args
+-- Handle Clz, Ctz, BRev, BSwap, Pdep, Pext, and PopCnt that need to only
+-- convert arg and return types
+genCall (PrimTarget op@(MO_Clz w)) [dst] args =
+ genCallSimpleCast w op dst args
+genCall (PrimTarget op@(MO_Ctz w)) [dst] args =
+ genCallSimpleCast w op dst args
+genCall (PrimTarget op@(MO_BRev w)) [dst] args =
+ genCallSimpleCast w op dst args
+genCall (PrimTarget op@(MO_BSwap w)) [dst] args =
+ genCallSimpleCast w op dst args
+genCall (PrimTarget op@(MO_Pdep w)) [dst] args =
+ genCallSimpleCast w op dst args
+genCall (PrimTarget op@(MO_Pext w)) [dst] args =
+ genCallSimpleCast w op dst args
+genCall (PrimTarget op@(MO_PopCnt w)) [dst] args =
+ genCallSimpleCast w op dst args
genCall (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n] = runStmtsDecls $ do
addrVar <- exprToVarW addr
@@ -640,63 +639,28 @@ genCallExtract _ _ _ _ =
-- since GHC only really has i32 and i64 types and things like Word8 are backed
-- by an i32 and just present a logical i8 range. So we must handle conversions
-- from i32 to i8 explicitly as LLVM is strict about types.
-genCallSimpleCast :: Width -> ForeignTarget -> [CmmFormal] -> [CmmActual]
- -> LlvmM StmtData
-genCallSimpleCast w t@(PrimTarget op) [dst] args = do
- let width = widthToLlvmInt w
- dstTy = cmmToLlvmType $ localRegType dst
-
- fname <- cmmPrimOpFunctions op
- (fptr, _, top3) <- getInstrinct fname width [width]
-
- (dstV, _dst_ty) <- getCmmReg (CmmLocal dst)
-
- let (_, arg_hints) = foreignTargetHints t
- let args_hints = zip args arg_hints
- (argsV, stmts2, top2) <- arg_vars args_hints ([], nilOL, [])
- (argsV', stmts4) <- castVars Signed $ zip argsV [width]
- (retV, s1) <- doExpr width $ Call StdCall fptr argsV' []
- (retVs', stmts5) <- castVars (cmmPrimOpRetValSignage op) [(retV,dstTy)]
- let retV' = singletonPanic "genCallSimpleCast" retVs'
- let s2 = Store retV' dstV Nothing []
-
- let stmts = stmts2 `appOL` stmts4 `snocOL`
- s1 `appOL` stmts5 `snocOL` s2
- return (stmts, top2 ++ top3)
-genCallSimpleCast _ _ dsts _ =
- panic ("genCallSimpleCast: " ++ show (length dsts) ++ " dsts")
-
--- Handle simple function call that only need simple type casting, of the form:
--- truncate arg >>= \a -> call(a) >>= zext
---
--- since GHC only really has i32 and i64 types and things like Word8 are backed
--- by an i32 and just present a logical i8 range. So we must handle conversions
--- from i32 to i8 explicitly as LLVM is strict about types.
-genCallSimpleCast2 :: Width -> ForeignTarget -> [CmmFormal] -> [CmmActual]
- -> LlvmM StmtData
-genCallSimpleCast2 w t@(PrimTarget op) [dst] args = do
- let width = widthToLlvmInt w
- dstTy = cmmToLlvmType $ localRegType dst
-
- fname <- cmmPrimOpFunctions op
- (fptr, _, top3) <- getInstrinct fname width (const width <$> args)
-
- (dstV, _dst_ty) <- getCmmReg (CmmLocal dst)
-
- let (_, arg_hints) = foreignTargetHints t
- let args_hints = zip args arg_hints
- (argsV, stmts2, top2) <- arg_vars args_hints ([], nilOL, [])
- (argsV', stmts4) <- castVars Signed $ zip argsV (const width <$> argsV)
- (retV, s1) <- doExpr width $ Call StdCall fptr argsV' []
- (retVs', stmts5) <- castVars (cmmPrimOpRetValSignage op) [(retV,dstTy)]
- let retV' = singletonPanic "genCallSimpleCast2" retVs'
- let s2 = Store retV' dstV Nothing []
+genCallSimpleCast :: Width -> CallishMachOp -> CmmFormal -> [CmmActual]
+ -> LlvmM StmtData
+genCallSimpleCast specW op dst args = do
+ let width = widthToLlvmInt specW
+ argsW = const width <$> args
+ dstType = cmmToLlvmType $ localRegType dst
+ signage = cmmPrimOpRetValSignage op
+
+ fname <- cmmPrimOpFunctions op
+ (fptr, _, top3) <- getInstrinct fname width argsW
+ (dstV, _dst_ty) <- getCmmReg (CmmLocal dst)
+ let (_, arg_hints) = foreignTargetHints $ PrimTarget op
+ let args_hints = zip args arg_hints
+ (argsV, stmts2, top2) <- arg_vars args_hints ([], nilOL, [])
+ (argsV', stmts4) <- castVars signage $ zip argsV argsW
+ (retV, s1) <- doExpr width $ Call StdCall fptr argsV' []
+ (retV', stmts5) <- castVar signage retV dstType
+ let s2 = Store retV' dstV Nothing []
let stmts = stmts2 `appOL` stmts4 `snocOL`
- s1 `appOL` stmts5 `snocOL` s2
+ s1 `snocOL` stmts5 `snocOL` s2
return (stmts, top2 ++ top3)
-genCallSimpleCast2 _ _ dsts _ =
- panic ("genCallSimpleCast2: " ++ show (length dsts) ++ " dsts")
-- | Create a function pointer from a target.
getFunPtrW :: (LMString -> LlvmType) -> ForeignTarget
@@ -811,11 +775,47 @@ castVar signage v t | getVarType v == t
Signed -> LM_Sext
Unsigned -> LM_Zext
-
cmmPrimOpRetValSignage :: CallishMachOp -> Signage
cmmPrimOpRetValSignage mop = case mop of
- MO_Pdep _ -> Unsigned
- MO_Pext _ -> Unsigned
+ -- Some bit-wise operations /must/ always treat the input and output values
+ -- as 'Unsigned' in order to return the expected result values when pre/post-
+ -- operation bit-width truncation and/or extension occur. For example,
+ -- consider the Bit-Reverse operation:
+ --
+ -- If the result of a Bit-Reverse is treated as signed,
+ -- an positive input can result in an negative output, i.e.:
+ --
+ -- identity(0x03) = 0x03 = 00000011
+ -- breverse(0x03) = 0xC0 = 11000000
+ --
+ -- Now if an extension is performed after the operation to
+ -- promote a smaller bit-width value into a larger bit-width
+ -- type, it is expected that the /bit-wise/ operations will
+ -- not be treated /numerically/ as signed.
+ --
+ -- To illustrate the difference, consider how a signed extension
+ -- for the type i16 to i32 differs for out values above:
+ -- ext_zeroed(i32, breverse(0x03)) = 0x00C0 = 0000000011000000
+ -- ext_signed(i32, breverse(0x03)) = 0xFFC0 = 1111111111000000
+ --
+ -- Here we can see that the former output is the expected result
+ -- of a bit-wise operation which needs to be promoted to a larger
+ -- bit-width type. The latter output is not desirable when we must
+ -- constraining a value into a range of i16 within an i32 type.
+ --
+ -- Hence we always treat the "signage" as unsigned for Bit-Reverse!
+ --
+ -- The same reasoning applied to Bit-Reverse above applies to the other
+ -- bit-wise operations; do not sign extend a possibly negated number!
+ MO_BRev _ -> Unsigned
+ MO_BSwap _ -> Unsigned
+ MO_Clz _ -> Unsigned
+ MO_Ctz _ -> Unsigned
+ MO_Pdep _ -> Unsigned
+ MO_Pext _ -> Unsigned
+ MO_PopCnt _ -> Unsigned
+
+ -- All other cases, default to preserving the numeric sign when extending.
_ -> Signed
-- | Decide what C function to use to implement a CallishMachOp
=====================================
compiler/GHC/Tc/Solver/Equality.hs
=====================================
@@ -197,12 +197,8 @@ zonkEqTypes ev eq_rel ty1 ty2
then tycon tc1 tys1 tys2
else bale_out ty1 ty2
- go ty1 ty2
- | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1
- , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2
- = do { res_a <- go ty1a ty2a
- ; res_b <- go ty1b ty2b
- ; return $ combine_rev mkAppTy res_b res_a }
+ -- If you are temppted to add a case for AppTy/AppTy, be careful
+ -- See Note [zonkEqTypes and the PKTI]
go ty1@(LitTy lit1) (LitTy lit2)
| lit1 == lit2
@@ -278,6 +274,32 @@ zonkEqTypes ev eq_rel ty1 ty2
combine_rev f (Right tys) (Right ty) = Right (f ty tys)
+{- Note [zonkEqTypes and the PKTI]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Because `zonkEqTypes` does /partial/ zonking, we need to be very careful
+to maintain the Purely Kinded Type Invariant: see GHC.Tc.Gen/HsType
+HsNote [The Purely Kinded Type Invariant (PKTI)].
+
+In #26256 we try to solve this equality constraint:
+ Int :-> Maybe Char ~# k0 Int (m0 Char)
+where m0 and k0 are unification variables, and
+ m0 :: Type -> Type
+It happens that m0 was already unified
+ m0 := (w0 :: kappa)
+where kappa is another unification variable that is also already unified:
+ kappa := Type->Type.
+So the original type satisifed the PKTI, but a partially-zonked form
+ k0 Int (w0 Char)
+does not!! (This a bit reminiscent of Note [mkAppTyM].)
+
+The solution I have adopted is simply to make `zonkEqTypes` bale out on `AppTy`.
+After all, it's only supposed to be a quick hack to see if two types are already
+equal; if we bale out we'll just get into the "proper" canonicaliser.
+
+The only tricky thing about this approach is that it relies on /omitting/
+code -- for the AppTy/AppTy case! Hence this Note
+-}
+
{- *********************************************************************
* *
* canonicaliseEquality
=====================================
docs/users_guide/conf.py
=====================================
@@ -35,8 +35,6 @@ nitpick_ignore = [
("envvar", "TMPDIR"),
("c:type", "bool"),
-
- ("extension", "RelaxedPolyRec"),
]
rst_prolog = """
=====================================
docs/users_guide/expected-undocumented-flags.txt
=====================================
@@ -14,7 +14,6 @@
-XPolymorphicComponents
-XRecordPuns
-XRelaxedLayout
--XRelaxedPolyRec
-copy-libs-when-linking
-dannot-lint
-dppr-ticks
=====================================
docs/users_guide/exts/doandifthenelse.rst
=====================================
@@ -8,7 +8,7 @@ Do And If Then Else
:since: 7.0.1
- :status: Included in :extension:`Haskell2010`
+ :status: Included in :extension:`GHC2024`, :extension:`GHC2021`, :extension:`Haskell2010`
Allow semicolons in ``if`` expressions.
=====================================
docs/users_guide/exts/relaxed_poly_rec.rst
=====================================
@@ -0,0 +1,17 @@
+.. _relaxed-poly-rec:
+
+Generalised typing of mutually recursive bindings
+-------------------------------------------------
+
+.. extension:: RelaxedPolyRec
+ :shortdesc: Generalised typing of mutually recursive bindings.
+
+ :since: 6.8.1
+
+ :status: Included in :extension:`GHC2024`, :extension:`GHC2021`, :extension:`Haskell2010`
+
+See :ref:`infelicities-recursive-groups` for a description of this extension.
+This is a long-standing GHC extension. Around the time of GHC 7.6.3, this
+extension became required as part of a typechecker refactoring.
+The ``-XRelaxedPolyRec`` flag is now deprecated (since the feature is always
+enabled) and may be removed at some future time.
=====================================
docs/users_guide/exts/types.rst
=====================================
@@ -30,3 +30,4 @@ Types
type_errors
defer_type_errors
roles
+ relaxed_poly_rec
=====================================
libraries/ghc-internal/cbits/pdep.c
=====================================
@@ -24,20 +24,23 @@ hs_pdep64(StgWord64 src, StgWord64 mask)
return result;
}
+// When dealing with values of bit-width shorter than uint64_t, ensure to
+// cast the return value to correctly truncate the undefined upper bits.
+// This is *VERY* important when GHC is using the LLVM backend!
StgWord
hs_pdep32(StgWord src, StgWord mask)
{
- return hs_pdep64(src, mask);
+ return (StgWord) ((StgWord32) hs_pdep64(src, mask));
}
StgWord
hs_pdep16(StgWord src, StgWord mask)
{
- return hs_pdep64(src, mask);
+ return (StgWord) ((StgWord16) hs_pdep64(src, mask));
}
StgWord
hs_pdep8(StgWord src, StgWord mask)
{
- return hs_pdep64(src, mask);
+ return (StgWord) ((StgWord8) hs_pdep64(src, mask));
}
=====================================
libraries/ghc-internal/cbits/pext.c
=====================================
@@ -1,13 +1,13 @@
#include "Rts.h"
#include "MachDeps.h"
-StgWord64
-hs_pext64(StgWord64 src, StgWord64 mask)
+static StgWord64
+hs_pext(const unsigned char bit_width, const StgWord64 src, const StgWord64 mask)
{
uint64_t result = 0;
int offset = 0;
- for (int bit = 0; bit != sizeof(uint64_t) * 8; ++bit) {
+ for (int bit = 0; bit != bit_width; ++bit) {
const uint64_t src_bit = (src >> bit) & 1;
const uint64_t mask_bit = (mask >> bit) & 1;
@@ -20,20 +20,29 @@ hs_pext64(StgWord64 src, StgWord64 mask)
return result;
}
+StgWord64
+hs_pext64(const StgWord64 src, const StgWord64 mask)
+{
+ return hs_pext(64, src, mask);
+}
+
+// When dealing with values of bit-width shorter than uint64_t, ensure to
+// cast the return value to correctly truncate the undefined upper bits.
+// This is *VERY* important when GHC is using the LLVM backend!
StgWord
-hs_pext32(StgWord src, StgWord mask)
+hs_pext32(const StgWord src, const StgWord mask)
{
- return hs_pext64(src, mask);
+ return (StgWord) ((StgWord32) hs_pext(32, src, mask));
}
StgWord
-hs_pext16(StgWord src, StgWord mask)
+hs_pext16(const StgWord src, const StgWord mask)
{
- return hs_pext64(src, mask);
+ return (StgWord) ((StgWord16) hs_pext(16, src, mask));
}
StgWord
-hs_pext8(StgWord src, StgWord mask)
+hs_pext8(const StgWord src, const StgWord mask)
{
- return hs_pext64(src, mask);
+ return (StgWord) ((StgWord8) hs_pext(8, src, mask));
}
=====================================
testsuite/tests/llvm/should_run/T20645.hs
=====================================
@@ -0,0 +1,18 @@
+-- Minimal reproducer for https://gitlab.haskell.org/ghc/ghc/-/issues/20645
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE ExtendedLiterals #-}
+import GHC.Exts
+import GHC.Word
+import Numeric (showHex)
+
+opaqueInt8# :: Int8# -> Int8#
+opaqueInt8# x = x
+{-# OPAQUE opaqueInt8# #-}
+
+main :: IO ()
+main = let !x = opaqueInt8# 109#Int8
+ !y = opaqueInt8# 1#Int8
+ in putStrLn $ flip showHex "" (W# ( pext8#
+ (word8ToWord# (int8ToWord8# (0#Int8 `subInt8#` x )))
+ (word8ToWord# (int8ToWord8# (y `subInt8#` 4#Int8)))
+ ))
=====================================
testsuite/tests/llvm/should_run/T20645.stdout
=====================================
@@ -0,0 +1 @@
+49
=====================================
testsuite/tests/llvm/should_run/all.T
=====================================
@@ -17,3 +17,4 @@ test('T22487', [normal, normalise_errmsg_fun(ignore_llvm_and_vortex)], compile_a
test('T22033', [normal, normalise_errmsg_fun(ignore_llvm_and_vortex)], compile_and_run, [''])
test('T25730', [req_c, unless(arch('x86_64'), skip), normalise_errmsg_fun(ignore_llvm_and_vortex)], compile_and_run, ['T25730C.c'])
# T25730C.c contains Intel instrinsics, so only run this test on x86
+test('T20645', [normal, normalise_errmsg_fun(ignore_llvm_and_vortex), when(have_llvm(), extra_ways(["optllvm"]))], compile_and_run, [''])
=====================================
testsuite/tests/numeric/should_compile/T26229.hs
=====================================
@@ -0,0 +1,12 @@
+{-# LANGUAGE NegativeLiterals #-}
+
+module T26229 where
+
+sqrte2pqiq :: (Floating a, Ord a) => a -> a -> a
+sqrte2pqiq e qiq -- = sqrt (e*e + qiq)
+ | e < - 1.5097698010472593e153 = -(qiq/e) - e
+ | e < 5.582399551122541e57 = sqrt (e*e + qiq) -- test Infinity#
+ | e < -5.582399551122541e57 = -sqrt (e*e + qiq) -- test -Infinity#
+ | otherwise = (qiq/e) + e
+{-# SPECIALIZE sqrte2pqiq :: Double -> Double -> Double #-}
+{-# SPECIALIZE sqrte2pqiq :: Float -> Float -> Float #-}
=====================================
testsuite/tests/numeric/should_compile/all.T
=====================================
@@ -22,3 +22,4 @@ test('T15547', normal, compile, ['-ddump-simpl -O -dsuppress-all -dno-typeable-b
test('T23019', normal, compile, ['-O'])
test('T23907', [ when(wordsize(32), expect_broken(23908))], compile, ['-ddump-simpl -O2 -dsuppress-all -dno-typeable-binds -dsuppress-uniques'])
test('T24331', normal, compile, ['-O -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds'])
+test('T26229', normal, compile, ['-O2'])
=====================================
testsuite/tests/numeric/should_run/foundation.hs
=====================================
@@ -24,6 +24,7 @@ module Main
( main
) where
+import Data.Bits (Bits((.&.), bit))
import Data.Word
import Data.Int
import GHC.Natural
@@ -408,6 +409,33 @@ instance TestPrimop (Word# -> Int# -> Word#) where
testPrimop s l r = Property s $ \(uWord -> a1) (uInt -> a2) -> (wWord (l a1 a2)) === wWord (r a1 a2)
-}
+-- | A special data-type for representing functions where,
+-- since only some number of the lower bits are defined,
+-- testing for strict equality in the undefined upper bits is not appropriate!
+-- Without using this data-type, false-positive failures will be reported
+-- when the undefined bit regions do not match, even though the equality of bits
+-- in this undefined region has no bearing on correctness.
+data LowerBitsAreDefined =
+ LowerBitsAreDefined
+ { definedLowerWidth :: Word
+ -- ^ The (strictly-non-negative) number of least-significant bits
+ -- for which the attached function is defined.
+ , undefinedBehavior :: (Word# -> Word#)
+ -- ^ Function with undefined behavior for some of its most significant bits.
+ }
+
+instance TestPrimop LowerBitsAreDefined where
+ testPrimop s l r = Property s $ \ (uWord#-> x0) ->
+ let -- Create a mask to unset all bits in the undefined area,
+ -- leaving set bits only in the area of defined behavior.
+ -- Since the upper bits are undefined,
+ -- if the function defines behavior for the lower N bits,
+ -- then /only/ the lower N bits are preserved,
+ -- and the upper WORDSIZE - N bits are discarded.
+ mask = bit (fromEnum (definedLowerWidth r)) - 1
+ valL = wWord# (undefinedBehavior l x0) .&. mask
+ valR = wWord# (undefinedBehavior r x0) .&. mask
+ in valL === valR
twoNonZero :: (a -> a -> b) -> a -> NonZero a -> b
twoNonZero f x (NonZero y) = f x y
@@ -655,13 +683,13 @@ testPrimops = Group "primop"
, testPrimop "ctz32#" Primop.ctz32# Wrapper.ctz32#
, testPrimop "ctz64#" Primop.ctz64# Wrapper.ctz64#
, testPrimop "ctz#" Primop.ctz# Wrapper.ctz#
- , testPrimop "byteSwap16#" Primop.byteSwap16# Wrapper.byteSwap16#
- , testPrimop "byteSwap32#" Primop.byteSwap32# Wrapper.byteSwap32#
+ , testPrimop "byteSwap16#" (16 `LowerBitsAreDefined` Primop.byteSwap16#) (16 `LowerBitsAreDefined` Wrapper.byteSwap16#)
+ , testPrimop "byteSwap32#" (32 `LowerBitsAreDefined` Primop.byteSwap32#) (32 `LowerBitsAreDefined` Wrapper.byteSwap32#)
, testPrimop "byteSwap64#" Primop.byteSwap64# Wrapper.byteSwap64#
, testPrimop "byteSwap#" Primop.byteSwap# Wrapper.byteSwap#
- , testPrimop "bitReverse8#" Primop.bitReverse8# Wrapper.bitReverse8#
- , testPrimop "bitReverse16#" Primop.bitReverse16# Wrapper.bitReverse16#
- , testPrimop "bitReverse32#" Primop.bitReverse32# Wrapper.bitReverse32#
+ , testPrimop "bitReverse8#" (8 `LowerBitsAreDefined` Primop.bitReverse8#) (8 `LowerBitsAreDefined` Wrapper.bitReverse8#)
+ , testPrimop "bitReverse16#" (16 `LowerBitsAreDefined` Primop.bitReverse16#) (16 `LowerBitsAreDefined` Wrapper.bitReverse16#)
+ , testPrimop "bitReverse32#" (32 `LowerBitsAreDefined` Primop.bitReverse32#) (32 `LowerBitsAreDefined` Wrapper.bitReverse32#)
, testPrimop "bitReverse64#" Primop.bitReverse64# Wrapper.bitReverse64#
, testPrimop "bitReverse#" Primop.bitReverse# Wrapper.bitReverse#
, testPrimop "narrow8Int#" Primop.narrow8Int# Wrapper.narrow8Int#
=====================================
testsuite/tests/partial-sigs/should_compile/T26256.hs
=====================================
@@ -0,0 +1,23 @@
+{-# LANGUAGE GHC2021 #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PartialTypeSignatures #-}
+
+module M (go) where
+
+import Data.Kind
+
+type Apply :: (Type -> Type) -> Type
+data Apply m
+
+type (:->) :: Type -> Type -> Type
+type family (:->) where (:->) = (->)
+
+f :: forall (k :: Type -> Type -> Type) (m :: Type -> Type).
+ k Int (m Char) -> k Bool (Apply m)
+f = f
+
+x :: Int :-> Maybe Char
+x = x
+
+go :: Bool -> _ _
+go = f x
=====================================
testsuite/tests/partial-sigs/should_compile/T26256.stderr
=====================================
@@ -0,0 +1,8 @@
+T26256.hs:22:15: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)]
+ • Found type wildcard ‘_’ standing for ‘Apply :: (* -> *) -> *’
+ • In the type signature: go :: Bool -> _ _
+
+T26256.hs:22:17: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)]
+ • Found type wildcard ‘_’ standing for ‘Maybe :: * -> *’
+ • In the first argument of ‘_’, namely ‘_’
+ In the type signature: go :: Bool -> _ _
=====================================
testsuite/tests/partial-sigs/should_compile/all.T
=====================================
@@ -108,3 +108,4 @@ test('T21667', normal, compile, [''])
test('T22065', normal, compile, [''])
test('T16152', normal, compile, [''])
test('T20076', expect_broken(20076), compile, [''])
+test('T26256', normal, compile, [''])
=====================================
testsuite/tests/typecheck/should_compile/T26256a.hs
=====================================
@@ -0,0 +1,19 @@
+{-# LANGUAGE GHC2021 #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module T26256 (go) where
+
+import Data.Kind
+
+class Cat k where (<<<) :: k a b -> k x a -> k x b
+instance Cat (->) where (<<<) = (.)
+class Pro k p where pro :: k a b s t -> p a b -> p s t
+data Hiding o a b s t = forall e. Hiding (s -> o e a)
+newtype Apply e a = Apply (e a)
+
+type (:->) :: Type -> Type -> Type
+type family (:->) where
+ (:->) = (->)
+
+go :: (Pro (Hiding Apply) p) => (s :-> e a) -> p a b -> p s t
+go sea = pro (Hiding (Apply <<< sea))
=====================================
testsuite/tests/typecheck/should_compile/all.T
=====================================
@@ -940,3 +940,4 @@ test('T26020', normal, compile, [''])
test('T26020a', [extra_files(['T26020a_help.hs'])], multimod_compile, ['T26020a', '-v0'])
test('T25992', normal, compile, [''])
test('T14010', normal, compile, [''])
+test('T26256a', normal, compile, [''])
=====================================
utils/genprimopcode/Lexer.x
=====================================
@@ -56,6 +56,7 @@ words :-
<0> "CanFail" { mkT TCanFail }
<0> "ThrowsException" { mkT TThrowsException }
<0> "ReadWriteEffect" { mkT TReadWriteEffect }
+ <0> "defined_bits" { mkT TDefinedBits }
<0> "can_fail_warning" { mkT TCanFailWarnFlag }
<0> "DoNotWarnCanFail" { mkT TDoNotWarnCanFail }
<0> "WarnIfEffectIsCanFail" { mkT TWarnIfEffectIsCanFail }
=====================================
utils/genprimopcode/Main.hs
=====================================
@@ -10,6 +10,7 @@ module Main where
import Parser
import Syntax
+import Control.Applicative (asum)
import Data.Char
import Data.List (union, intersperse, intercalate, nub, sort)
import Data.Maybe ( catMaybes, mapMaybe )
@@ -116,9 +117,15 @@ desugarVectorSpec i = case vecOptions i of
main :: IO ()
main = getArgs >>= \args ->
if length args /= 1 || head args `notElem` known_args
- then error ("usage: genprimopcode command < primops.txt > ...\n"
+ then error ("Usage: genprimopcode command < primops.txt > ...\n"
++ " where command is one of\n"
++ unlines (map (" "++) known_args)
+ ++ unlines
+ [ ""
+ , "Nota Bene: Be sure to manually run primops.txt through the C Pre-Processor"
+ , " before sending the input stream to STDIN, i.e:"
+ , ""
+ , " cpp -P -w primops.txt | genprimopcode command" ]
)
else
do hSetEncoding stdin utf8 -- The input file is in UTF-8. Set the encoding explicitly.
@@ -312,6 +319,7 @@ gen_hs_source (Info defaults entries) =
opt (OptionVector _) = ""
opt (OptionFixity mf) = "fixity = " ++ show mf
opt (OptionEffect eff) = "effect = " ++ show eff
+ opt (OptionDefinedBits bc) = "defined_bits = " ++ show bc
opt (OptionCanFailWarnFlag wf) = "can_fail_warning = " ++ show wf
hdr s@(Section {}) = sec s
@@ -638,6 +646,7 @@ gen_switch_from_attribs attrib_name fn_name (Info defaults entries)
getAltRhs (OptionVector _) = "True"
getAltRhs (OptionFixity mf) = show mf
getAltRhs (OptionEffect eff) = show eff
+ getAltRhs (OptionDefinedBits bc) = show bc
getAltRhs (OptionCanFailWarnFlag wf) = show wf
mkAlt po
@@ -753,7 +762,12 @@ gen_foundation_tests (Info _ entries)
= let testPrimOpHow = if is_divLikeOp po
then "testPrimopDivLike"
else "testPrimop"
- in Just $ intercalate " " [testPrimOpHow, "\"" ++ poName ++ "\"", wrap "Primop" poName, wrap "Wrapper" poName]
+ qualOp qualification =
+ let qName = wrap qualification poName
+ in case mb_defined_bits po of
+ Nothing -> qName
+ Just bs -> concat ["(", show bs, " `LowerBitsAreDefined` ", qName, ")"]
+ in Just $ intercalate " " [testPrimOpHow, "\"" ++ poName ++ "\"", qualOp "Primop", qualOp "Wrapper"]
| otherwise = Nothing
@@ -771,6 +785,16 @@ gen_foundation_tests (Info _ entries)
divableTyCons = ["Int#", "Word#", "Word8#", "Word16#", "Word32#", "Word64#"
,"Int8#", "Int16#", "Int32#", "Int64#"]
+ mb_defined_bits :: Entry -> Maybe Word
+ mb_defined_bits op@(PrimOpSpec{}) =
+ let opOpts = opts op
+ getDefBits :: Option -> Maybe Word
+ getDefBits (OptionDefinedBits x) = x
+ getDefBits _ = Nothing
+ in asum $ getDefBits <$> opOpts
+ mb_defined_bits _ = Nothing
+
+
------------------------------------------------------------------
-- Create PrimOpInfo text from PrimOpSpecs -----------------------
------------------------------------------------------------------
=====================================
utils/genprimopcode/Parser.y
=====================================
@@ -50,6 +50,7 @@ import AccessOps
CanFail { TCanFail }
ThrowsException { TThrowsException }
ReadWriteEffect { TReadWriteEffect }
+ defined_bits { TDefinedBits }
can_fail_warning { TCanFailWarnFlag }
DoNotWarnCanFail { TDoNotWarnCanFail }
WarnIfEffectIsCanFail { TWarnIfEffectIsCanFail }
@@ -81,13 +82,14 @@ pOptions : pOption pOptions { $1 : $2 }
| {- empty -} { [] }
pOption :: { Option }
-pOption : lowerName '=' false { OptionFalse $1 }
- | lowerName '=' true { OptionTrue $1 }
- | lowerName '=' pStuffBetweenBraces { OptionString $1 $3 }
- | lowerName '=' integer { OptionInteger $1 $3 }
- | vector '=' pVectorTemplate { OptionVector $3 }
- | fixity '=' pInfix { OptionFixity $3 }
- | effect '=' pEffect { OptionEffect $3 }
+pOption : lowerName '=' false { OptionFalse $1 }
+ | lowerName '=' true { OptionTrue $1 }
+ | lowerName '=' pStuffBetweenBraces { OptionString $1 $3 }
+ | lowerName '=' integer { OptionInteger $1 $3 }
+ | vector '=' pVectorTemplate { OptionVector $3 }
+ | fixity '=' pInfix { OptionFixity $3 }
+ | effect '=' pEffect { OptionEffect $3 }
+ | defined_bits '=' pGoodBits { OptionDefinedBits $3 }
| can_fail_warning '=' pPrimOpCanFailWarnFlag { OptionCanFailWarnFlag $3 }
pInfix :: { Maybe Fixity }
@@ -102,6 +104,10 @@ pEffect : NoEffect { NoEffect }
| ThrowsException { ThrowsException }
| ReadWriteEffect { ReadWriteEffect }
+pGoodBits :: { Maybe Word }
+pGoodBits : integer { Just $ toEnum $1 }
+ | nothing { Nothing }
+
pPrimOpCanFailWarnFlag :: { PrimOpCanFailWarnFlag }
pPrimOpCanFailWarnFlag : DoNotWarnCanFail { DoNotWarnCanFail }
| WarnIfEffectIsCanFail { WarnIfEffectIsCanFail }
=====================================
utils/genprimopcode/ParserM.hs
=====================================
@@ -116,6 +116,7 @@ data Token = TEOF
| TCanFail
| TThrowsException
| TReadWriteEffect
+ | TDefinedBits
| TCanFailWarnFlag
| TDoNotWarnCanFail
| TWarnIfEffectIsCanFail
=====================================
utils/genprimopcode/Syntax.hs
=====================================
@@ -76,6 +76,7 @@ data Option
| OptionFixity (Maybe Fixity) -- fixity = infix{,l,r} <int> | Nothing
| OptionEffect PrimOpEffect -- effect = NoEffect | DoNotSpeculate | CanFail | ThrowsException | ReadWriteEffect | FallibleReadWriteEffect
| OptionCanFailWarnFlag PrimOpCanFailWarnFlag -- can_fail_warning = DoNotWarnCanFail | WarnIfEffectIsCanFail | YesWarnCanFail
+ | OptionDefinedBits (Maybe Word) -- defined_bits = Just 16 | Nothing
deriving Show
-- categorises primops
@@ -196,6 +197,7 @@ get_attrib_name (OptionVector _) = "vector"
get_attrib_name (OptionFixity _) = "fixity"
get_attrib_name (OptionEffect _) = "effect"
get_attrib_name (OptionCanFailWarnFlag _) = "can_fail_warning"
+get_attrib_name (OptionDefinedBits _) = "defined_bits"
lookup_attrib :: String -> [Option] -> Maybe Option
lookup_attrib _ [] = Nothing
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/01be20d3762af6fe8df718cb86788c…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/01be20d3762af6fe8df718cb86788c…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/spj-apporv-Oct24] 2 commits: notes and misc changes
by Apoorv Ingle (@ani) 11 Aug '25
by Apoorv Ingle (@ani) 11 Aug '25
11 Aug '25
Apoorv Ingle pushed to branch wip/spj-apporv-Oct24 at Glasgow Haskell Compiler / GHC
Commits:
f6b42024 by Apoorv Ingle at 2025-08-11T11:02:36-05:00
notes and misc changes
- - - - -
90a013ab by Apoorv Ingle at 2025-08-11T11:25:12-05:00
rename ea_ctxt -> ea_loc_span eaql_ctx -> eaql_loc_span
- - - - -
7 changed files:
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Do.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Types/LclEnv.hs
- compiler/GHC/Tc/Utils/Monad.hs
Changes:
=====================================
compiler/GHC/Hs/Expr.hs
=====================================
@@ -675,11 +675,11 @@ type instance XXExpr GhcTc = XXExprGhcTc
data SrcCodeOrigin
= OrigExpr (HsExpr GhcRn) -- ^ The source, user written, expression
| OrigStmt (ExprLStmt GhcRn) HsDoFlavour -- ^ which kind of do-block did this statement come from
- | OrigPat (Pat GhcRn) -- ^ Used for failable patterns that trigger MonadFail constraints
+ | OrigPat (Pat GhcRn) -- ^ Used for failable patterns that trigger MonadFail constraints
data XXExprGhcRn
- = ExpandedThingRn { xrn_orig :: SrcCodeOrigin -- The original source thing to be used for error messages
- , xrn_expanded :: HsExpr GhcRn -- The compiler generated expanded thing
+ = ExpandedThingRn { xrn_orig :: SrcCodeOrigin -- The original source thing to be used for error messages
+ , xrn_expanded :: HsExpr GhcRn -- The compiler generated, expanded thing
}
| PopErrCtxt -- A hint for typechecker to pop
=====================================
compiler/GHC/Tc/Gen/App.hs
=====================================
@@ -544,17 +544,18 @@ tcValArgs do_ql fun args = go do_ql 0 args
go do_ql pos (arg : args) =
do { arg' <- tcValArg do_ql pos' fun arg
; args' <- go do_ql pos' args
- ; return (arg' : args')
- }
+ ; return (arg' : args') }
where
-- increment position if the argument is user written type or value argument
pos' | EValArg{} <- arg
= pos + 1
| EValArgQL{} <- arg
= pos + 1
- | ETypeArg{ ea_ctxt = l } <- arg
- , not (isGeneratedSrcSpan l) = pos + 1
- | otherwise = pos
+ | ETypeArg{ ea_loc_span = l } <- arg
+ , not (isGeneratedSrcSpan l)
+ = pos + 1
+ | otherwise
+ = pos
tcValArg :: QLFlag -> Int -> HsExpr GhcRn -> HsExprArg 'TcpInst -- Actual argument
@@ -566,7 +567,7 @@ tcValArg do_ql _ _ (EWrap (EHsWrap w)) = do { whenQL do_ql $ qlMonoHsWrapper w
-- qlMonoHsWrapper: see Note [Monomorphise instantiation variables]
tcValArg _ _ _ (EWrap ew) = return (EWrap ew)
-tcValArg do_ql pos fun (EValArg { ea_ctxt = ctxt
+tcValArg do_ql pos fun (EValArg { ea_loc_span = ctxt
, ea_arg = larg@(L arg_loc arg)
, ea_arg_ty = sc_arg_ty })
= addArgCtxt pos fun larg $
@@ -594,20 +595,21 @@ tcValArg do_ql pos fun (EValArg { ea_ctxt = ctxt
tcPolyExpr arg (mkCheckExpType exp_arg_ty)
; traceTc "tcValArg" $ vcat [ ppr arg'
, text "}" ]
- ; return (EValArg { ea_ctxt = ctxt
+ ; return (EValArg { ea_loc_span = ctxt
, ea_arg = L arg_loc arg'
, ea_arg_ty = noExtField }) }
-tcValArg _ pos fun (EValArgQL { eaql_wanted = wanted
- , eaql_ctxt = ctxt
- , eaql_arg_ty = sc_arg_ty
- , eaql_larg = larg@(L arg_loc rn_expr)
- , eaql_tc_fun = tc_head
- , eaql_rn_fun = rn_fun
- , eaql_fun_ue = head_ue
- , eaql_args = inst_args
- , eaql_encl = arg_influences_enclosing_call
- , eaql_res_rho = app_res_rho })
+tcValArg _ pos fun (EValArgQL {
+ eaql_wanted = wanted
+ , eaql_loc_span = ctxt
+ , eaql_arg_ty = sc_arg_ty
+ , eaql_larg = larg@(L arg_loc rn_expr)
+ , eaql_tc_fun = tc_head
+ , eaql_rn_fun = rn_fun
+ , eaql_fun_ue = head_ue
+ , eaql_args = inst_args
+ , eaql_encl = arg_influences_enclosing_call
+ , eaql_res_rho = app_res_rho })
= addArgCtxt pos fun larg $
do { -- Expose QL results to tcSkolemise, as in EValArg case
Scaled mult exp_arg_ty <- liftZonkM $ zonkScaledTcType sc_arg_ty
@@ -644,7 +646,7 @@ tcValArg _ pos fun (EValArgQL { eaql_wanted = wanted
; traceTc "tcEValArgQL }" $
vcat [ text "app_res_rho:" <+> ppr app_res_rho ]
- ; return (EValArg { ea_ctxt = ctxt
+ ; return (EValArg { ea_loc_span = ctxt
, ea_arg = L arg_loc (mkHsWrap wrap arg')
, ea_arg_ty = noExtField }) }
@@ -814,10 +816,10 @@ tcInstFun do_ql inst_final fun_orig (tc_fun, rn_fun, fun_ctxt) fun_sigma rn_args
= go1 pos (EPrag sp prag : acc) fun_ty args
-- Rule ITYARG from Fig 4 of the QL paper
- go1 pos acc fun_ty ( ETypeArg { ea_ctxt = ctxt, ea_hs_ty = hs_ty }
+ go1 pos acc fun_ty ( ETypeArg { ea_loc_span = ctxt, ea_hs_ty = hs_ty }
: rest_args )
= do { (ty_arg, inst_ty) <- tcVTA fun_conc_tvs fun_ty hs_ty
- ; let arg' = ETypeArg { ea_ctxt = ctxt, ea_hs_ty = hs_ty, ea_ty_arg = ty_arg }
+ ; let arg' = ETypeArg { ea_loc_span = ctxt, ea_hs_ty = hs_ty, ea_ty_arg = ty_arg }
; go pos (arg' : acc) inst_ty rest_args }
-- Rule IVAR from Fig 4 of the QL paper:
@@ -857,7 +859,7 @@ tcInstFun do_ql inst_final fun_orig (tc_fun, rn_fun, fun_ctxt) fun_sigma rn_args
-- Rule IARG from Fig 4 of the QL paper:
go1 pos acc fun_ty
- (EValArg { ea_arg = arg, ea_ctxt = ctxt } : rest_args)
+ (EValArg { ea_arg = arg, ea_loc_span = ctxt } : rest_args)
= do { let herald = mk_herald tc_fun (unLoc arg)
; (wrap, arg_ty, res_ty) <-
-- NB: matchActualFunTy does the rep-poly check.
@@ -924,9 +926,9 @@ addArgCtxt :: Int -> HsExpr GhcRn -> LHsExpr GhcRn
-- There are 2 cases:
-- 1. In the normal case, we add an informative context
-- "In the third argument of f, namely blah"
--- 2. If we are deep inside generated code (`isGeneratedCode` is `True`)
+-- 2. If we are deep inside generated code (<=> `isGeneratedCode` is `True`)
-- "In the expression: arg"
--- If the arg is also a generated thing, i.e. arg_loc is generatedSrcSpan, we would print do nothing.
+-- If the arg is also a generated thing, i.e. `arg_loc` is `generatedSrcSpan`, we would print nothing.
-- See Note [Rebindable syntax and XXExprGhcRn] in GHC.Hs.Expr
-- See Note [Expanding HsDo with XXExprGhcRn] in GHC.Tc.Gen.Do
addArgCtxt arg_no fun (L arg_loc arg) thing_inside
@@ -1733,7 +1735,7 @@ quickLookArg DoQL pos ctxt fun larg orig_arg_ty
skipQuickLook :: SrcSpan -> LHsExpr GhcRn -> Scaled TcRhoType
-> TcM (HsExprArg 'TcpInst)
skipQuickLook ctxt larg arg_ty
- = return (EValArg { ea_ctxt = ctxt
+ = return (EValArg { ea_loc_span = ctxt
, ea_arg = larg
, ea_arg_ty = arg_ty })
@@ -1834,16 +1836,16 @@ quickLookArg1 pos ctxt fun larg@(L _ arg) sc_arg_ty@(Scaled _ orig_arg_rho)
; traceTc "quickLookArg done }" (ppr rn_fun)
- ; return (EValArgQL { eaql_ctxt = ctxt
- , eaql_arg_ty = sc_arg_ty
- , eaql_larg = larg
- , eaql_tc_fun = tc_head
- , eaql_rn_fun = rn_fun
- , eaql_fun_ue = fun_ue
- , eaql_args = inst_args
- , eaql_wanted = wanted
- , eaql_encl = arg_influences_enclosing_call
- , eaql_res_rho = app_res_rho }) }}}
+ ; return (EValArgQL { eaql_loc_span = ctxt
+ , eaql_arg_ty = sc_arg_ty
+ , eaql_larg = larg
+ , eaql_tc_fun = tc_head
+ , eaql_rn_fun = rn_fun
+ , eaql_fun_ue = fun_ue
+ , eaql_args = inst_args
+ , eaql_wanted = wanted
+ , eaql_encl = arg_influences_enclosing_call
+ , eaql_res_rho = app_res_rho }) }}}
{- *********************************************************************
* *
=====================================
compiler/GHC/Tc/Gen/Do.hs
=====================================
@@ -75,7 +75,7 @@ expand_do_stmts _ (stmt@(L _ (XStmtLR ApplicativeStmt{})): _) =
expand_do_stmts _ [] = pprPanic "expand_do_stmts: impossible happened. Empty stmts" empty
-expand_do_stmts flav [stmt@(L sloc (LastStmt _ body@(L body_loc _) _ ret_expr))]
+expand_do_stmts _flav [_stmt@(L _sloc (LastStmt _ body@(L body_loc _) _ ret_expr))]
-- See Note [Expanding HsDo with XXExprGhcRn] Equation (5) below
-- last statement of a list comprehension, needs to explicitly return it
-- See `checkLastStmt` and `Syntax.Expr.StmtLR.LastStmt`
@@ -83,7 +83,7 @@ expand_do_stmts flav [stmt@(L sloc (LastStmt _ body@(L body_loc _) _ ret_expr))]
-- Last statement is just body if we are not in ListComp context. See Syntax.Expr.LastStmt
-- = return $ L sloc (mkExpandedStmt stmt flav (HsPar noExtField body))
= return body
- | SyntaxExprRn ret <- ret_expr
+ | SyntaxExprRn ret <- ret_expr -- We have unfortunately lost the location on the return function :(
--
-- ------------------------------------------------
-- return e ~~> return e
@@ -230,7 +230,7 @@ mk_fail_block _ _ _ _ = pprPanic "mk_fail_block: impossible happened" empty
{- Note [Expanding HsDo with XXExprGhcRn]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We expand `do`-blocks before typechecking it, by re-using the existing `XXExprGhcRns` and `RebindableSyntax` machinery.
+We expand `do`-blocks before typechecking it, by re-using the existing `XXExprGhcRn` and `RebindableSyntax` machinery.
This is very similar to:
1. Expansions done in `GHC.Rename.Expr.rnHsIf` for expanding `HsIf`; and
2. `desugarRecordUpd` in `GHC.Tc.Gen.Expr.tcExpr` for expanding `RecordUpd`
@@ -275,14 +275,15 @@ They capture the essence of statement expansions as implemented in `expand_do_st
DO【 _ 】 maps a sequence of do statements and recursively converts them into expressions
- (1) DO【 s; ss 】 = ‹ExpansionStmt s›((>>) s (‹PopErrCtxt›DO【 ss 】))
+ (1) DO【 s; ss 】 = ‹ExpansionStmt s›((>>) (‹PopErrCtxt› s) (‹PopErrCtxt› DO【 ss 】))
(2) DO【 p <- e; ss 】 = if p is irrefutable
then ‹ExpansionStmt (p <- e)›
- (>>=) s ((\ p -> ‹PopExprCtxt› DO【 ss 】))
+ (>>=) (‹PopExprCtxt› s) ((\ p -> ‹PopExprCtxt› DO【 ss 】))
else ‹ExpansionStmt (p <- e)›
- (>>=) s ((\case p -> ‹PopExprCtxt› DO【 ss 】
- _ -> fail "pattern p failure"))
+ (>>=) (‹PopExprCtxt› s)
+ (\case p -> ‹PopExprCtxt› DO【 ss 】
+ _ -> fail "pattern p failure")
(3) DO【 let x = e; ss 】
= ‹ExpansionStmt (let x = e)› (let x = e in (‹PopErrCtxt›DO【 ss 】))
@@ -313,8 +314,8 @@ The expanded version (performed by `expand_do_stmts`) looks like:
{g2} (>>) ({l2} g p)
({l3} return p))
-The {l1} etc are location/source span information stored in the AST by the parser,
-{g1} are compiler generated source spans.
+The {l1}, {l2}, etc. are the location/source span information stored in the AST by the parser,
+{g1}, {g2}, etc. are the compiler generated source spans.
The 3 non-obvious points to consider are:
@@ -427,10 +428,10 @@ It stores the original statement (with location) and the expanded expression
‹ExpandedThingRn do { e1; e2; e3 }› -- Original Do Expression
-- Expanded Do Expression
(‹ExpandedThingRn e1› -- Original Statement
- ({(>>) e1} -- Expanded Expression
- ‹PopErrCtxt› (‹ExpandedThingRn e2›
- ({(>>) e2}
- ‹PopErrCtxt› (‹ExpandedThingRn e3› {e3})))))
+ ({(>>) ‹PopErrCtxt› e1} -- Expanded Expression
+ ‹PopErrCtxt› (‹ExpandedThingRn e2›
+ ({(>>) ‹PopErrCtxt› e2}
+ ‹PopErrCtxt› (‹ExpandedThingRn e3› {e3})))))
* Whenever the typechecker steps through an `ExpandedThingRn`,
we push the original statement in the error context, set the error location to the
@@ -445,7 +446,7 @@ It stores the original statement (with location) and the expanded expression
as precise as possible, and not just blame the complete `do`-block.
Thus, when we typecheck the application `(>>) e1`, we push the "In the stmt of do block e1" with
the source location of `e1` in the error context stack as we walk inside an `ExpandedThingRn`.
- See also Note [splitHsApps].
+ See also Note [splitHsApps] and Note [Error Context Stack]
* After the expanded expression of a `do`-statement is typechecked
and before moving to the next statement of the `do`-block, we need to first pop the top
=====================================
compiler/GHC/Tc/Gen/Expr.hs
=====================================
@@ -648,9 +648,9 @@ tcExpr expr@(RecordUpd { rupd_expr = record_expr
res_ty
= assert (notNull rbnds) $
do { -- Expand the record update. See Note [Record Updates].
- ; (ds_expr, ds_res_ty, err_ctxt)
+ ; (ds_expr, ds_res_ty, err_msg)
<- expandRecordUpd record_expr possible_parents rbnds res_ty
- ; addErrCtxt err_ctxt $
+ ; addErrCtxt err_msg $
setInGeneratedCode (OrigExpr expr) $
do { -- Typecheck the expanded expression.
expr' <- tcExpr ds_expr (Check ds_res_ty)
@@ -748,9 +748,11 @@ tcXExpr (PopErrCtxt e) res_ty
tcExpr e res_ty
tcXExpr (ExpandedThingRn o e) res_ty
- = mkExpandedTc o <$> -- necessary for breakpoints
- do setInGeneratedCode o $
- tcExpr e res_ty
+ = setInGeneratedCode o $
+ -- e is the expanded expression of o, so we need to set the error ctxt to generated
+ -- see Note [Error Context Stack] in `GHC.Tc.Type.LclEnv`
+ mkExpandedTc o <$> -- necessary for hpc ticks
+ tcExpr e res_ty
-- For record selection, same as HsVar case
tcXExpr xe res_ty = tcApp (XExpr xe) res_ty
@@ -1441,7 +1443,7 @@ expandRecordUpd record_expr possible_parents rbnds res_ty
-- STEP 2 (b): expand to HsCase, as per note [Record Updates]
; let ds_expr :: HsExpr GhcRn
- ds_expr = HsLet noExtField let_binds (L gen case_expr)
+ ds_expr = HsLet noExtField let_binds (wrapGenSpan case_expr)
case_expr :: HsExpr GhcRn
case_expr = HsCase RecUpd record_expr
@@ -1456,11 +1458,10 @@ expandRecordUpd record_expr possible_parents rbnds res_ty
upd_ids_lhs = [ (NonRecursive, [genSimpleFunBind (idName id) [] rhs])
| (_, (id, rhs)) <- upd_ids ]
mk_idSig :: (Name, (Id, LHsExpr GhcRn)) -> LSig GhcRn
- mk_idSig (_, (id, _)) = L gen $ XSig $ IdSig id
+ mk_idSig (_, (id, _)) = wrapGenSpan (XSig $ IdSig id)
-- We let-bind variables using 'IdSig' in order to accept
-- record updates involving higher-rank types.
-- See Wrinkle [Using IdSig] in Note [Record Updates].
- gen = noAnnSrcSpan generatedSrcSpan
; traceTc "expandRecordUpd" $
vcat [ text "relevant_con:" <+> ppr relevant_con
=====================================
compiler/GHC/Tc/Gen/Head.hs
=====================================
@@ -152,6 +152,7 @@ takes apart either an HsApp, or an infix OpApp, returning
innermost un-expanded head as the "error head".
* A list of HsExprArg, the arguments
+* We do not look through expanded expressions (except PopErrCtxt.)
-}
data TcPass = TcpRn -- Arguments decomposed
@@ -161,14 +162,14 @@ data TcPass = TcpRn -- Arguments decomposed
data HsExprArg (p :: TcPass) where -- See Note [HsExprArg]
-- Data constructor EValArg represents a value argument
- EValArg :: { ea_ctxt :: SrcSpan
+ EValArg :: { ea_loc_span :: SrcSpan
, ea_arg_ty :: !(XEVAType p)
, ea_arg :: LHsExpr (GhcPass (XPass p)) }
-> HsExprArg p
-- Data constructor EValArgQL represents an argument that has been
-- partly-type-checked by Quick Look; see Note [EValArgQL]
- EValArgQL :: { eaql_ctxt :: SrcSpan
+ EValArgQL :: { eaql_loc_span :: SrcSpan
, eaql_arg_ty :: Scaled TcSigmaType -- Argument type expected by function
, eaql_larg :: LHsExpr GhcRn -- Original application, for
-- location and error msgs
@@ -182,7 +183,7 @@ data HsExprArg (p :: TcPass) where -- See Note [HsExprArg]
, eaql_res_rho :: TcRhoType } -- Result type of the application
-> HsExprArg 'TcpInst -- Only exists in TcpInst phase
- ETypeArg :: { ea_ctxt :: SrcSpan
+ ETypeArg :: { ea_loc_span :: SrcSpan
, ea_hs_ty :: LHsWcType GhcRn -- The type arg
, ea_ty_arg :: !(XETAType p) } -- Kind-checked type arg
-> HsExprArg p
@@ -215,12 +216,12 @@ type family XPass (p :: TcPass) where
XPass 'TcpTc = 'Typechecked
mkEValArg :: SrcSpan -> LHsExpr GhcRn -> HsExprArg 'TcpRn
-mkEValArg ctxt e = EValArg { ea_arg = e, ea_ctxt = ctxt
+mkEValArg src_loc e = EValArg { ea_arg = e, ea_loc_span = src_loc
, ea_arg_ty = noExtField }
mkETypeArg :: SrcSpan -> LHsWcType GhcRn -> HsExprArg 'TcpRn
-mkETypeArg ctxt hs_ty =
- ETypeArg { ea_ctxt = ctxt
+mkETypeArg src_loc hs_ty =
+ ETypeArg { ea_loc_span = src_loc
, ea_hs_ty = hs_ty
, ea_ty_arg = noExtField }
@@ -291,9 +292,9 @@ rebuildHsApps :: (HsExpr GhcTc, SrcSpan)
rebuildHsApps (fun, _) [] = fun
rebuildHsApps (fun, sloc) (arg : args)
= case arg of
- EValArg { ea_arg = arg, ea_ctxt = sloc' }
+ EValArg { ea_arg = arg, ea_loc_span = sloc' }
-> rebuildHsApps (HsApp noExtField lfun arg, sloc') args
- ETypeArg { ea_hs_ty = hs_ty, ea_ty_arg = ty, ea_ctxt = sloc' }
+ ETypeArg { ea_hs_ty = hs_ty, ea_ty_arg = ty, ea_loc_span = sloc' }
-> rebuildHsApps (HsAppType ty lfun hs_ty, sloc') args
EPrag sloc' p
-> rebuildHsApps (HsPragE noExtField p lfun, sloc') args
@@ -330,7 +331,7 @@ instance OutputableBndrId (XPass p) => Outputable (HsExprArg p) where
ppr (EPrag _ p) = text "EPrag" <+> ppr p
ppr (ETypeArg { ea_hs_ty = hs_ty }) = char '@' <> ppr hs_ty
ppr (EWrap wrap) = ppr wrap
- ppr (EValArg { ea_arg = arg, ea_ctxt = sloc })
+ ppr (EValArg { ea_arg = arg, ea_loc_span = sloc })
= text "EValArg" <> braces (ppr sloc) <+> ppr arg
ppr (EValArgQL { eaql_tc_fun = fun, eaql_args = args, eaql_res_rho = ty})
= hang (text "EValArgQL" <+> ppr fun)
=====================================
compiler/GHC/Tc/Types/LclEnv.hs
=====================================
@@ -91,29 +91,54 @@ data TcLclEnv -- Changes as we move inside an expression
tcl_errs :: TcRef (Messages TcRnMessage) -- Place to accumulate diagnostics
}
+{-
+Note [Error Context Stack]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+This data structure keeps track of two things:
+1. Are we type checking a compiler generated/non-user written code.
+2. The trail of the error messages that have been added in route to the current expression
+
+* When the `ErrCtxtStack` is a `UserCodeCtxt`,
+ - the current expression being typechecked is user written
+* When the `ErrorCtxtStack` is a `GeneratedCodeCtxt`
+ - the current expression being typechecked is compiler generated;
+ - the original, possibly user written, source code thing is stored in `src_code_origin` field.
+ - the `src_code_origin` is what will be blamed in the error message
+
+-}
+
+-- See Note [Error Context Stack]
data ErrCtxtStack
- = UserCodeCtxt {err_ctxt :: [ErrCtxt]}
- | GeneratedCodeCtxt { src_code_origin :: SrcCodeOrigin
- , err_ctxt :: [ErrCtxt] }
+ = UserCodeCtxt { lcl_err_ctxt :: [ErrCtxt] } -- ^ Trail of error messages
+ | GeneratedCodeCtxt { src_code_origin :: SrcCodeOrigin -- ^ Original, user written code
+ , lcl_err_ctxt :: [ErrCtxt] } -- ^ Trail of error messages
+-- | Are we in a generated context?
isGeneratedCodeCtxt :: ErrCtxtStack -> Bool
isGeneratedCodeCtxt UserCodeCtxt{} = False
isGeneratedCodeCtxt _ = True
+-- | Get the original source code
get_src_code_origin :: ErrCtxtStack -> Maybe SrcCodeOrigin
get_src_code_origin (UserCodeCtxt{}) = Nothing
+ -- we are in user code, so blame the expression in hand
get_src_code_origin es = Just $ src_code_origin es
+ -- we are in generated code, so extract the original expression
+-- | Modify the error context stack
+-- N.B. If we are in a generated context, any updates to the context stack are ignored.
+-- We want to blame the errors that appear in a generated expression
+-- to the original, user written code
modify_err_ctxt_stack :: ([ErrCtxt] -> [ErrCtxt]) -> ErrCtxtStack -> ErrCtxtStack
modify_err_ctxt_stack f (UserCodeCtxt e) = UserCodeCtxt (f e)
-modify_err_ctxt_stack _ c = c -- any updates on the err context in generated context should be ignored
+modify_err_ctxt_stack _ c = c -- any updates on the err context in a generated context should be ignored
data TcLclCtxt
= TcLclCtxt {
tcl_loc :: RealSrcSpan, -- Source span
- tcl_ctxt :: ErrCtxtStack,
+ tcl_ctxt :: ErrCtxtStack, -- See Note [Error Context Stack]
tcl_tclvl :: TcLevel,
tcl_bndrs :: TcBinderStack, -- Used for reporting relevant bindings,
-- and for tidying type
@@ -178,7 +203,7 @@ getLclEnvLoc :: TcLclEnv -> RealSrcSpan
getLclEnvLoc = tcl_loc . tcl_lcl_ctxt
getLclEnvErrCtxt :: TcLclEnv -> [ErrCtxt]
-getLclEnvErrCtxt = err_ctxt . tcl_ctxt . tcl_lcl_ctxt
+getLclEnvErrCtxt = lcl_err_ctxt . tcl_ctxt . tcl_lcl_ctxt
setLclEnvErrCtxt :: [ErrCtxt] -> TcLclEnv -> TcLclEnv
setLclEnvErrCtxt ctxt = modifyLclCtxt (\env -> env { tcl_ctxt = modify_err_ctxt_stack (\ _ -> ctxt) (tcl_ctxt env) })
@@ -193,7 +218,7 @@ setLclEnvSrcCodeOrigin :: SrcCodeOrigin -> TcLclEnv -> TcLclEnv
setLclEnvSrcCodeOrigin o = modifyLclCtxt (setLclCtxtSrcCodeOrigin o)
setLclCtxtSrcCodeOrigin :: SrcCodeOrigin -> TcLclCtxt -> TcLclCtxt
-setLclCtxtSrcCodeOrigin o ctxt = ctxt { tcl_ctxt = GeneratedCodeCtxt o (err_ctxt $ tcl_ctxt ctxt) }
+setLclCtxtSrcCodeOrigin o ctxt = ctxt { tcl_ctxt = GeneratedCodeCtxt o (lcl_err_ctxt $ tcl_ctxt ctxt) }
lclCtxtInGeneratedCode :: TcLclCtxt -> Bool
lclCtxtInGeneratedCode = isGeneratedCodeCtxt . tcl_ctxt
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -974,9 +974,9 @@ inGeneratedCode = lclEnvInGeneratedCode <$> getLclEnv
setSrcSpan :: SrcSpan -> TcRn a -> TcRn a
-- See Note [Error contexts in generated code]
--- for the tcl_in_gen_code manipulation
setSrcSpan (RealSrcSpan loc _) thing_inside
- = updLclCtxt (\env -> env { tcl_loc = loc, tcl_ctxt = UserCodeCtxt (err_ctxt $ tcl_ctxt env)})
+ = updLclCtxt (\env -> env { tcl_loc = loc
+ , tcl_ctxt = UserCodeCtxt (lcl_err_ctxt $ tcl_ctxt env)})
thing_inside
setSrcSpan (UnhelpfulSpan _) thing_inside
@@ -988,6 +988,7 @@ getSrcCodeOrigin = getLclEnvSrcCodeOrigin <$> getLclEnv
-- | Mark the inner computation as being done inside generated code.
--
-- See Note [Error contexts in generated code]
+-- See Note [Error Context Stack]
setInGeneratedCode :: SrcCodeOrigin -> TcRn a -> TcRn a
setInGeneratedCode sco thing_inside =
updLclCtxt (setLclCtxtSrcCodeOrigin sco) thing_inside
@@ -1210,17 +1211,17 @@ problem.
Note [Error contexts in generated code]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* setSrcSpan sets tcl_in_gen_code to True if the SrcSpan is GeneratedSrcSpan,
- and back to False when we get a useful SrcSpan
+* If the `SrcSpan` is a `RealSrcSpan`, `setSrcSpan` updates the `tcl_loc`,
+ and makes the `ErrCtxStack` a `UserCodeCtxt`
+* it is a no-op otherwise
-* When tcl_in_gen_code is True, addErrCtxt becomes a no-op.
+So, it's better to do a `setSrcSpan` /before/ `addErrCtxt`.
-So typically it's better to do setSrcSpan /before/ addErrCtxt.
-
-See Note [Rebindable syntax and XXExprGhcRn] in GHC.Hs.Expr for
-more discussion of this fancy footwork, as well as
-Note [Generated code and pattern-match checking] in GHC.Types.Basic for the
-relation with pattern-match checks.
+- See Note [Rebindable syntax and XXExprGhcRn] in `GHC.Hs.Expr` for
+more discussion of this fancy footwork
+- See Note [Generated code and pattern-match checking] in `GHC.Types.Basic` for the
+relation with pattern-match checks
+- See Note [Error Context Stack] in `GHC.Tc.Types.LclEnv` for info about `ErrCtxtStack`
-}
getErrCtxt :: TcM [ErrCtxt]
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/35d5a38dc11ddbc6e4482d595de187…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/35d5a38dc11ddbc6e4482d595de187…
You're receiving this email because of your account on gitlab.haskell.org.
1
0