GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2022-04-06T21:17:07Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/21276Don't make magicDict change breaking2022-04-06T21:17:07ZTom EllisDon't make magicDict change breakingHi folks, I was reading the 9.4 migration guide and it seems there is [a breaking change to `magicDict`](https://gitlab.haskell.org/ghc/ghc/-/wikis/migration/9.4#magicdict) slated. Is it actually necessary for this to be a breaking chan...Hi folks, I was reading the 9.4 migration guide and it seems there is [a breaking change to `magicDict`](https://gitlab.haskell.org/ghc/ghc/-/wikis/migration/9.4#magicdict) slated. Is it actually necessary for this to be a breaking change? Could `magicDict` be left where it is, with a warning that `withDict` should be preferred instead, or even a `{-# DEPRECATED ... #-}`? It would be nice not to break consumers unless absolutely necessary. If the removal of `magicDict` can be postponed by a year or two this will give a nice smooth upgrade path to `withDict`, rather than forcing consumers to support GHC >= 9.4 exclusive-or GHC < 9.4.
See also https://gitlab.haskell.org/ghc/ghc/-/issues/21277
cc @bgamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/21275Linear and non-linear data constructor types are printed identically2022-03-24T14:44:21ZJakob BrünkerLinear and non-linear data constructor types are printed identically## Summary
There seems to be no way to distinguish between linear and non-linear data constructors from the way GHCi prints them
## Steps to reproduce
```haskell
ghci> :set -XLinearTypes
ghci> import GHC.Types
ghci> data T1 a where M...## Summary
There seems to be no way to distinguish between linear and non-linear data constructors from the way GHCi prints them
## Steps to reproduce
```haskell
ghci> :set -XLinearTypes
ghci> import GHC.Types
ghci> data T1 a where MkT1 :: a %Many -> T1 a
ghci> :t MkT1
MkT1 :: a -> T1 a
ghci> dup :: T1 a %1 -> (a, a); dup (MkT1 x) = (x, x) -- to show it's really non-linear
<no error>
ghci> data T1 a where MkT1 :: a %1 -> T1 a
ghci> :t MkT1
MkT1 :: a -> T1 a
ghci> dup :: T1 a %1 -> (a, a); dup (MkT1 x) = (x, x) -- to show it's really linear
<interactive>:19:53: error:
* Couldn't match type 'Many with 'One
arising from multiplicity of `x'
* In the pattern: MkT1 x
In an equation for `dup': dup (MkT1 x) = (x, x)
```
As you can see, in both cases, the result of `:t MkT1` is the same.
## Expected behavior
Print one of them differently: Either explicitly show the multiplicity for the first one, or explicitly show it for the second one. (Probably explicitly show it for the linear version, since that is how :i does it.)
## Environment
* GHC version used: 9.3.20220319
Optional:
* Operating System: Arch
* System Architecture: x86_64Krzysztof GogolewskiKrzysztof Gogolewskihttps://gitlab.haskell.org/ghc/ghc/-/issues/21273-Winvalid-haddock should be enabled in HLS / hadrian/ghci2022-04-12T16:15:41ZMatthew Pickering-Winvalid-haddock should be enabled in HLS / hadrian/ghci`-Winvalid-haddock` will be enabled in the validate flavour in !7762 but we should also enable it in the developer targets.`-Winvalid-haddock` will be enabled in the validate flavour in !7762 but we should also enable it in the developer targets.ZubinZubinhttps://gitlab.haskell.org/ghc/ghc/-/issues/21272Can't unify `k -> Type` with visible dependent quantification that ignores it...2022-04-02T12:46:00ZIcelandjackCan't unify `k -> Type` with visible dependent quantification that ignores its quantifiee `forall (x :: k) -> Type`I'm making sure this is intended or not, it is possible to wrap `k -> Type` in a VDQ that ignores its argument `forall (x :: k) -> Type` (`Dep`).
But `Indep` fails to compile:
```haskell
{-# Language GADTs #-}
{-# La...I'm making sure this is intended or not, it is possible to wrap `k -> Type` in a VDQ that ignores its argument `forall (x :: k) -> Type` (`Dep`).
But `Indep` fails to compile:
```haskell
{-# Language GADTs #-}
{-# Language PolyKinds #-}
{-# Language RankNTypes #-}
{-# Language StandaloneKindSignatures #-}
import Data.Kind
type Dep :: (k -> Type) -> (forall (x :: k) -> Type)
newtype Dep f a where
Dep :: f a -> Dep f a
{-
• Expected kind ‘forall (x :: k0) -> Type’,
but ‘f’ has kind ‘k0 -> Type’
• In the first argument of ‘Indep’, namely ‘f’
In the type ‘Indep f a’
In the definition of data constructor ‘Indep’
-}
-- type Indep :: (forall (x :: k) -> Type) -> (k -> Type)
-- newtype Indep f a where
-- Indep :: f a -> Indep f a
```https://gitlab.haskell.org/ghc/ghc/-/issues/21271T21119 test output is not invariant between validate / perf flavours2022-03-26T17:38:24ZMatthew PickeringT21119 test output is not invariant between validate / perf flavoursSee https://gitlab.haskell.org/ghc/ghc/-/jobs/984016
```
T21119.$trModule:
T21119.get: <1!P(S!P(L),S!P(L))><1!P(L)><1L>
T21119.getIO: <1P(SL,L)><1L><ML><L>
-T21119.indexError: <S!P(SCS(C1(L)),1C1(L),B)><1!S><S!S><1!S>b
-T21119.throwI...See https://gitlab.haskell.org/ghc/ghc/-/jobs/984016
```
T21119.$trModule:
T21119.get: <1!P(S!P(L),S!P(L))><1!P(L)><1L>
T21119.getIO: <1P(SL,L)><1L><ML><L>
-T21119.indexError: <S!P(SCS(C1(L)),1C1(L),B)><1!S><S!S><1!S>b
-T21119.throwIndexError: <LP(LCL(C1(L)),MCM(L),A)><ML><L><ML><L>x
+T21119.indexError: <1!P(SCS(C1(C1(L))),1C1(L),B)><1!S><S!S><1!S>b
+T21119.throwIndexError: <MP(LCL(C1(C1(L))),MCM(L),A)><ML><L><ML><L>x
```
Can you advise about how to normalise the output @sgraf812 ?9.4.1Matthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/21270http://downloads.haskell.org/~ghc/latest/ contains GHC 9.2.1 instead of 9.2.22022-04-13T00:22:31ZSimon Jakobihttp://downloads.haskell.org/~ghc/latest/ contains GHC 9.2.1 instead of 9.2.2See http://downloads.haskell.org/~ghc/latest/.
It should be updated.See http://downloads.haskell.org/~ghc/latest/.
It should be updated.9.2.2Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/21268`-fno-code -dynamic-too` reports a `.dyn_o` file that is not generated2022-03-21T11:47:45ZAndreas Abel`-fno-code -dynamic-too` reports a `.dyn_o` file that is not generatedRunning `ghc-9.2.2`. E.g.
```
$ ghc -dynamic-too -fno-code Main.hs
[1 of 1] Compiling Main ( Main.hs, nothing, Main.dyn_o )
```
No file `Main.dyn_o` is generated, though.Running `ghc-9.2.2`. E.g.
```
$ ghc -dynamic-too -fno-code Main.hs
[1 of 1] Compiling Main ( Main.hs, nothing, Main.dyn_o )
```
No file `Main.dyn_o` is generated, though.https://gitlab.haskell.org/ghc/ghc/-/issues/21267Project doesn't build over multiple versions of GHC except ghc-8.10.72022-06-22T10:26:34ZJohn KyProject doesn't build over multiple versions of GHC except ghc-8.10.7## Summary
I have a build matrix that builds over multiple versions of GHC on Windows. They all fail except for ghc-8.10.7, which passes.
https://github.com/haskell-works/hw-rankselect-base/actions/runs/2011931807
I'm guessing this i...## Summary
I have a build matrix that builds over multiple versions of GHC on Windows. They all fail except for ghc-8.10.7, which passes.
https://github.com/haskell-works/hw-rankselect-base/actions/runs/2011931807
I'm guessing this is a `MAX_PATH` problem, but it is curious that it should work in `ghc-8.10.7`, but not all other versions of the compiler.
## Steps to reproduce
Fork the project and build it in CI.
## Expected behavior
The build should succeed on all versions of GHC.
## Environment
* GHC versions used: `8.4.4`, `8.6.5`, `8.10.7`, `9.0.2`, `9.2.2`
Optional:
* Operating System: Windows
* System Architecture: Intel9.4.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/21266Enlarging SmallMutableArray#s more efficiently2022-04-03T01:04:48ZSimon JakobiEnlarging SmallMutableArray#s more efficiently`resizeSmallMutableArray#` is currently implemented like this:
```haskell
resizeSmallMutableArray#
:: SmallMutableArray# s a -- ^ Array to resize
-> Int# -- ^ New size of array
-> a
-- ^ Newly created slots initialized to thi...`resizeSmallMutableArray#` is currently implemented like this:
```haskell
resizeSmallMutableArray#
:: SmallMutableArray# s a -- ^ Array to resize
-> Int# -- ^ New size of array
-> a
-- ^ Newly created slots initialized to this element.
-- Only used when array is grown.
-> State# s
-> (# State# s, SmallMutableArray# s a #)
resizeSmallMutableArray# arr0 szNew a s0 =
case getSizeofSmallMutableArray# arr0 s0 of
(# s1, szOld #) -> if isTrue# (szNew <# szOld)
then case shrinkSmallMutableArray# arr0 szNew s1 of
s2 -> (# s2, arr0 #)
else if isTrue# (szNew ># szOld)
then case newSmallArray# szNew a s1 of
(# s2, arr1 #) -> case copySmallMutableArray# arr0 0# arr1 0# szOld s2 of
s3 -> (# s3, arr1 #)
else (# s1, arr0 #)
```
Notably, in order to enlarge the array, a new array is allocated and initialized with a filler element (`a`), and then the contents from the old one are copied over.
I have two questions about this:
1. Why isn't the initialization with the filler element skipped for length of the original array? Or are these write operations optimized away somehow?
2. Why is there no attempt to use the slop at the end of the array that results from a previous use of `shrinkSmallMutableArray#`? This should make it unnecessary to allocate a fresh array in some cases, no?https://gitlab.haskell.org/ghc/ghc/-/issues/21265winery-1.3.2 panics on HEAD (expectJust isRecDataCon:go_tc_app)2022-03-26T17:38:23ZRyan Scottwinery-1.3.2 panics on HEAD (expectJust isRecDataCon:go_tc_app)_(Originally discovered in a `head.hackage` build [here](https://gitlab.haskell.org/RyanGlScott/head.hackage/-/jobs/983508#L4976).)_
The `winery-1.3.2` library on Hackage panics when compiled with GHC HEAD at commit bb779b90bb093274ccf7..._(Originally discovered in a `head.hackage` build [here](https://gitlab.haskell.org/RyanGlScott/head.hackage/-/jobs/983508#L4976).)_
The `winery-1.3.2` library on Hackage panics when compiled with GHC HEAD at commit bb779b90bb093274ccf7a8e5b19f6661f4925bde. Here is a minimized example:
```hs
{-# LANGUAGE RankNTypes #-}
module Codec.Winery.Class (extractorProduct') where
class GSerialiseProduct f where
dummy :: f x -> ()
productExtractor :: TransFusion [] ((->) Bool) (f Int)
extractorProduct' :: GSerialiseProduct f => Maybe (f Int)
extractorProduct' = unTransFusion productExtractor go
go :: f x -> Maybe (g x)
go _ = Nothing
newtype TransFusion f g a = TransFusion { unTransFusion :: forall h. Applicative h => (forall x. f x -> h (g x)) -> h a }
```
```
$ ~/Software/ghc-9.3.20220316/bin/ghc Bug.hs -O -fforce-recomp
[1 of 1] Compiling Codec.Winery.Class ( Bug.hs, Bug.o )
<no location info>: error:
expectJust isRecDataCon:go_tc_app
CallStack (from HasCallStack):
error, called at compiler/GHC/Data/Maybe.hs:71:27 in ghc:GHC.Data.Maybe
expectJust, called at compiler/GHC/Core/Opt/WorkWrap/Utils.hs:1348:25 in ghc:GHC.Core.Opt.WorkWrap.Utils
```
This regression was introduced in commit 8ff32124c8cd37050f3dc7cbb32b8d41711ebcaf (`DmdAnal: Don't unbox recursive data types`). cc @sgraf8129.4.1Sebastian GrafSebastian Grafhttps://gitlab.haskell.org/ghc/ghc/-/issues/21264Unused EpAnn across compiler phases2022-10-30T13:53:51ZRodrigo MesquitaUnused EpAnn across compiler phases@alanz mentioned elsewhere that the exact printing annotations weren't used when renaming, however, the TTG instances of many many AST constructors carry exact printing annotations thorough all phases (Ps, Rn, Tc).
I am wondering if it ...@alanz mentioned elsewhere that the exact printing annotations weren't used when renaming, however, the TTG instances of many many AST constructors carry exact printing annotations thorough all phases (Ps, Rn, Tc).
I am wondering if it would be better to have 3 distinct instances (Ps, Rn, Tc) instead of one instance with `GhcPass _`.
This would make the instances in the code larger, but it would save passing around ep annotations.
I am also wondering whether not carrying around the annotations would improve the compiler performance.
RE: "we're just using noAnn everywhere to instance EpAnn in other phases" -- even if removing all EpAnn doesn't better compiler performance, I still want to argue that having NoExtField instead of EpAnn is better semantically.
There is a considerably bigger "code cost" when pattern matching on methods that are polymorphic in the phase because we must pattern match against all phases individually (the extension is different for each...)
(for example in `pprSplice :: forall p. (OutputableBndrId p) => HsSplice (GhcPass p) -> SDoc`)
Let me know your thoughts on this,
~romeshttps://gitlab.haskell.org/ghc/ghc/-/issues/21262TTG follow-up: Outputable orphans2022-07-06T12:18:20ZRodrigo MesquitaTTG follow-up: Outputable orphansFollowup in cleaning-up after separating the AST from GHC-Pass !4778; regarding the orphan `Outputable` instances in `compiler/GHC/Hs/Expr.hs`
> It makes me wonder whether all the Outputable instances should be in GHC.Hs.Extension.GhcPa...Followup in cleaning-up after separating the AST from GHC-Pass !4778; regarding the orphan `Outputable` instances in `compiler/GHC/Hs/Expr.hs`
> It makes me wonder whether all the Outputable instances should be in GHC.Hs.Extension.GhcPass. I think they wouldn't be orphans there.
> After we add more TTG parameters to allow using non-GHC non-tie-the-know-oh-wait-hs-boots-everywhere, we can generalize these instances so they don't assume GhcPass.
> Outputable itself assumes some things about names and other GHC which would probably be lifted.
> So I don't know what's best in the short and medium terms, but I hope in the long term we can have some nice GHC-agnostic bring-your-own-configuration-record pretty printing. This will also help with #17957 and getting rid of the unsafe global cfg stuff.
https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4778#note_324909Rodrigo MesquitaRodrigo Mesquitahttps://gitlab.haskell.org/ghc/ghc/-/issues/21261Eta-reduction based on Demand2022-10-19T10:55:20ZSebastian GrafEta-reduction based on DemandThis is a play on #20040, although a bit simpler and thus well within reach without #21081. Consider
```hs
f :: (Int -> Int -> Int) -> Int
f c = c 1 2 + c 3 4
{-# NOINLINE f #-}
-- Demand signature of f : <SCS(C1(L))>
g :: (Int -> Int...This is a play on #20040, although a bit simpler and thus well within reach without #21081. Consider
```hs
f :: (Int -> Int -> Int) -> Int
f c = c 1 2 + c 3 4
{-# NOINLINE f #-}
-- Demand signature of f : <SCS(C1(L))>
g :: (Int -> Int -> Int) -> Int
g c = f (\x y -> c x y)
```
Today, we get the following Core for `g`:
```
g :: (Int -> Int -> Int) -> Int
[GblId, Arity=1, Unf=OtherCon []]
g = \ (c_awQ :: Int -> Int -> Int) ->
f (\ (x_awR :: Int) (y_awS :: Int) -> c_awQ x_awR y_awS)
```
E.g., the lambda `(\x y -> c x y)` is not eta-reduced, although in theory it could be: From `f`'s demand signature `<SCS(C1(L))>` we know that whenever `f` evaluates its parameter `g`, there is also at least one call to `g` with 2 arguments. Thus, eta-reducing to `c` is sound, even if evaluating `c` diverges, simply because the call to `f` would evaluate `c` either way.https://gitlab.haskell.org/ghc/ghc/-/issues/21260bitReverse... functions incorrectly documented as "Since: base-4.12.0.0".2022-03-22T15:26:06Zj6careybitReverse... functions incorrectly documented as "Since: base-4.12.0.0".## Summary
Starting with `base-4.14.0.0`, the Haddocks of `base` mention
the `bitReverse...` functions in `Data.Word` and in `GHC.Word`,
claiming "Since: base-4.12.0.0".
However, it appears these functions were new with
`base-4.14.0.0`...## Summary
Starting with `base-4.14.0.0`, the Haddocks of `base` mention
the `bitReverse...` functions in `Data.Word` and in `GHC.Word`,
claiming "Since: base-4.12.0.0".
However, it appears these functions were new with
`base-4.14.0.0`. They do not appear in the source
code for either GHC 8.8.4 or GHC 8.6.5, and they
do not appear in `base` documentation prior to
`base-4.14.0.0`.
## Proposed improvements or changes
The Haddocks for the `bitReverse...` functions in `Data.Word`
and in `GHC.Word` should state: "Since: base-4.14.0.0".
## Environment
* GHC 8.10+ with preprocessor conditionals to support GHC 8.8.4-9.0.3https://gitlab.haskell.org/ghc/ghc/-/issues/21259GHC's graph representations do not provide access to predecessors2022-11-11T05:27:08ZNorman RamseyGHC's graph representations do not provide access to predecessorsSome algorithms that operate on control-flow graphs---in particular, the "node-splitting" algorithm that converts an irreducible control-flow graph to a reducible control-flow graph---require access to the predecessors of a node. But GHC...Some algorithms that operate on control-flow graphs---in particular, the "node-splitting" algorithm that converts an irreducible control-flow graph to a reducible control-flow graph---require access to the predecessors of a node. But GHC's representations of graphs, such as the `CmmGraph` and the `Graph` type of `GHC.CmmToAsm.CFG.Dominators`, represent a graph as a finite map from each node to its successors. This representation provides fast access only to the successors of a node, not the predecessors.
When the graph in question is unchanging, as it is for some dominator and loop analyses, it is not too difficult to compute the successor relation and to invert it, providing fast access to the predecessors. But when the graph is changing, as is the case in the node splitter, maintaining the two relations can become a little awkward.
This issue could be addressed _ad hoc_ in every part of the compiler that needs to manipulate graphs, but a better solution might be to have a common representation that is already designed to deal with such issues. Such as, for example, the representation in Martin Erwig's Functional Graph Library.
(N.B. the issue is mentioned as one of the bullet points in #21200.)Norman RamseyNorman Ramseyhttps://gitlab.haskell.org/ghc/ghc/-/issues/21258GHC's build system is aware of only two possible OS platforms2022-11-10T00:30:13ZNorman RamseyGHC's build system is aware of only two possible OS platformsThe build system (as facing `rts`) currently assumes that the run-time system is built on one of two possible system APIs: POSIX or Win32. But on WebAssembly neither of these APIs is supported. The only system-like API available for We...The build system (as facing `rts`) currently assumes that the run-time system is built on one of two possible system APIs: POSIX or Win32. But on WebAssembly neither of these APIs is supported. The only system-like API available for WebAssembly is the [WebAssembly System Interface (WASI)](https://wasi.dev/). Porting the run-time system to WASI will require a great many changes (see #21200), but it needs to start by making the build system aware that there is a third possibility (WASI) in addition to POSIX and Win32.9.6.1Cheng ShaoCheng Shaohttps://gitlab.haskell.org/ghc/ghc/-/issues/21257DmdAnal: `dmdAnalStar` could yield better usage for trivial args and bindings2022-11-21T19:55:13ZSebastian GrafDmdAnal: `dmdAnalStar` could yield better usage for trivial args and bindingsConsider
```hs
f :: (Bool, Bool) -> (Bool, Bool)
f pr = (pr `seq` True, case pr of (a,b) -> a && b)
{-# NOINLINE f #-}
-- idDmdSig f = LP(1L,1L)
g :: (Bool, Bool) -> ()
g pr = f pr `seq` ()
-- idDmdSig g = L
```
`g` simply calls `f`, ...Consider
```hs
f :: (Bool, Bool) -> (Bool, Bool)
f pr = (pr `seq` True, case pr of (a,b) -> a && b)
{-# NOINLINE f #-}
-- idDmdSig f = LP(1L,1L)
g :: (Bool, Bool) -> ()
g pr = f pr `seq` ()
-- idDmdSig g = L
```
`g` simply calls `f`, yet `g` puts a worse demand on `pr` than `f`; it loses the information that `pr`'s components are only evaluated once.
That is due to `dmdAnalStar e (n :* sd)`, which is used when analysing the argument `pr` in the call `f pr` in demand `LP(1L,1L)`. That will
1. Call `dmdAnal "pr" "P(1L,1L)"`, as if `pr` was evaluated exactly once in sub-demand `P(1L,1L)`. We get back `[pr |-> 1P(1L,1L)]` (which of course is too optimistic).
2. Then it worsens the resulting demand type to account for `n=L`, by multiplying it with `L` via `multDmdType`. That ultimately calls `multDmd "L"` on the demand of `x`: `multDmd L 1P(1L,1L) === LP(LL,LL) === L`.
It's alright to turn the outer `1P(..)` into `LP(..)`, but we don't actually need to worsen the inner `P(1L,1L)`, because it is the exact demand that is put on the argument already.
NB: This ticket is specifically concerned with upper bounds. The `multDmd "L"` situation (with a used more than once upper boudn) only occurs when an arg `pr` is trivial (or if the RHS of a bindings is trivial). Otherwise, `dmdTransformThunkDmd` anticipates the memoisation of complex expressions and call `oneifyDmd` instead. So if we had a call like `f (x, True)` instead, then we'd get `dmdAnalStar "(x, True)" "1P(1L,1L)"`, e.g., with the oneified demand `1P(..)` and all will be well, as we ultimately get a demand of `1L` on `x`.Sebastian GrafSebastian Grafhttps://gitlab.haskell.org/ghc/ghc/-/issues/21256editing template-haskell2022-03-19T20:27:17ZGhost Userediting template-haskelllibraries/template-haskell/Language/Haskell/TH/Syntax.hs
clicking <kbd>Commit changes</kbd> after editing the file results in a banner appearing at the top
if someone else with write authority wants to commit the change feel free to p...libraries/template-haskell/Language/Haskell/TH/Syntax.hs
clicking <kbd>Commit changes</kbd> after editing the file results in a banner appearing at the top
if someone else with write authority wants to commit the change feel free to pursue that
```diff
- -- appropiately.
+ -- appropriately.
```
text from banner
Someone edited the file the same time you did. Please check out the file and make sure your changes will not unintentionally remove theirs.https://gitlab.haskell.org/ghc/ghc/-/issues/21255CoreTidy drops specialisations of exported functions2022-03-18T08:55:41ZSebastian GrafCoreTidy drops specialisations of exported functionsThis is `T7785`, from #7785:
```hs
{-# LANGUAGE TypeFamilies, ConstraintKinds #-}
module Foo( shared, foo, bar) where
import Data.Kind
type family Domain (f :: Type -> Type) a :: Constraint
type instance Domain [] a = ()
class MyFun...This is `T7785`, from #7785:
```hs
{-# LANGUAGE TypeFamilies, ConstraintKinds #-}
module Foo( shared, foo, bar) where
import Data.Kind
type family Domain (f :: Type -> Type) a :: Constraint
type instance Domain [] a = ()
class MyFunctor f where
myfmap :: (Domain f a, Domain f b) => (a -> b) -> f a -> f b
instance MyFunctor [] where
myfmap = map
shared :: (MyFunctor f, Domain f Int) => f Int -> f Int
shared = let
f = myfmap negate
in
f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f.
f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f.
f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f.
f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f.
f . f . f . f . f . f . f . f . f . f . f . f . f
foo, bar :: [Int] -> [Int]
foo xs = shared $ 0:xs
bar xs = 0:shared xs
```
The gist is that we have an exported, specialisable function `shared :: (MyFunctor f, Domain f Int) => f a -> f b`. There are two call sites `foo`, `bar` within the module that force a specialisation for `[]`, `$sshared`. We get a RULE attached to `shared` that rewrites `shared @[] $dMyFunctor = $sshared`. Ultimately, we want to see that rule (with `-ddump-rules`) exported and thus the specialisation `$sshared` kept alive. Indeed, the expected test output is
```
==================== Tidy Core rules ====================
"SPEC shared @[]"
forall ($dMyFunctor :: MyFunctor []) (irred :: Domain [] Int).
shared @[] $dMyFunctor irred
= bar_$sshared
```
But when I look at `-ddump-simpl` output, this RULE is announced as an IMP rule!
```
------ Local rules for imported ids --------
"SPEC shared @[]"
forall ($dMyFunctor :: MyFunctor []) (irred :: Domain [] Int).
shared @[] $dMyFunctor irred
= Foo.bar_$sshared
```
Which seems wrong. As it happens, the specialisation `$sshared` is only kept alive through the call site in `bar` (which I haven't shown), not through the RULE associated with the exported function `shared`.
Now !7788 comes up with a slightly different specialisation that causes `$sshared` to inline into that call site. Result: the RULE and `$sshared` are dropped completely and our specialisation work has been lost.
Question: Is there a reason why CoreTidy doesn't keep alive `$sshared` if its only occurrence is in the RHS of a RULE attached to the exported function `shared`?https://gitlab.haskell.org/ghc/ghc/-/issues/21254CallerCc[123] fail in ghci-ext-prof way with -debug RTS2022-03-26T17:38:23ZBen GamariCallerCc[123] fail in ghci-ext-prof way with -debug RTSCurrently the `CallerCc1`, `CallerCc2`, and `CallerCc3` tests fail with an assertion when run in the `ghci-ext-prof` way when `iserv` is built with the `-debug` RTS:
```
$ _build/stage1/bin/ghc --interactive -prof -fexternal-interpreter...Currently the `CallerCc1`, `CallerCc2`, and `CallerCc3` tests fail with an assertion when run in the `ghci-ext-prof` way when `iserv` is built with the `-debug` RTS:
```
$ _build/stage1/bin/ghc --interactive -prof -fexternal-interpreter testsuite/tests/profiling/should_run/caller-cc/Main.hs
GHCi, version 9.3.20220307: https://www.haskell.org/ghc/ :? for help
ghc-iserv-prof: internal error: ASSERTION FAILED: file rts/CheckUnload.c, line 345
Stack trace:
0x2213934 set_initial_registers (rts/Libdw.c:294.57)
0x7ff706298b08 dwfl_thread_getframes (/nix/store/z5mr2iqwvh8lpngrnxnqdvxw1dpw7ap7-elfutils-0.186/lib/libdw-0.186.so)
0x7ff70629863b get_one_thread_cb (/nix/store/z5mr2iqwvh8lpngrnxnqdvxw1dpw7ap7-elfutils-0.186/lib/libdw-0.186.so)
0x7ff706298972 dwfl_getthreads (/nix/store/z5mr2iqwvh8lpngrnxnqdvxw1dpw7ap7-elfutils-0.186/lib/libdw-0.186.so)
0x7ff706298eb7 dwfl_getthread_frames (/nix/store/z5mr2iqwvh8lpngrnxnqdvxw1dpw7ap7-elfutils-0.186/lib/libdw-0.186.so)
0x221381e libdwGetBacktrace (rts/Libdw.c:263.15)
0x21bfc92 rtsFatalInternalErrorFn (rts/RtsMessages.c:175.30)
0x21bf851 barf (rts/RtsMessages.c:49.4)
0x21bf8b4 errorBelch (rts/RtsMessages.c:68.5)
0x220fcbd findSectionIdx (rts/CheckUnload.c:347.5)
0x220fdfa findOC (rts/CheckUnload.c:373.74)
0x220ffbc markObjectCode (rts/CheckUnload.c:430.5)
0x21e3cd9 markCAFs (rts/sm/GCAux.c:156.9)
0x21e0ab4 GarbageCollect (rts/sm/GC.c:522.3)
0x21c5ce7 scheduleDoGC (rts/Schedule.c:1861.5)
0x21c5238 schedule (rts/Schedule.c:215.7)
0x21c672c scheduleWaitThread (rts/Schedule.c:2627.5)
0x221849f rts_evalLazyIO (rts/RtsAPI.c:567.5)
0x21bf6fd hs_main (rts/RtsMain.c:73.9)
0xbb1583 (null) (/home/ben/ghc/ghc-compare-1/_build/stage1/lib/bin/ghc-iserv-prof)
0x7ff706318790 __libc_start_main (/nix/store/4s21k8k7p1mfik0b33r2spq5hq7774k1-glibc-2.33-108/lib/libc-2.33.so)
0xbb30ba _start (../sysdeps/x86_64/start.S:122.0)
(GHC version 9.3.20220307 for x86_64_unknown_linux)
Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug
ghc: ghc-iserv terminated (-6)
```9.4.1Ben GamariBen Gamari