GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-07T18:41:16Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/9232Stats file has wrong numbers2019-07-07T18:41:16Zlennart@augustsson.netStats file has wrong numbersThe summary numbers in the file generated with the -S flag cannot be right. Here's an example:
```
1,943,795,468 bytes allocated in the heap
17,587,189,232 bytes copied during GC
```
The corresponding numbers with ghc 7.2 are
```...The summary numbers in the file generated with the -S flag cannot be right. Here's an example:
```
1,943,795,468 bytes allocated in the heap
17,587,189,232 bytes copied during GC
```
The corresponding numbers with ghc 7.2 are
```
193,859,474,520 bytes allocated in the heap
17,766,908,288 bytes copied during GC
```
While it's theoretically possible that allocation has improved that much, I don't believe it.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonmar |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Stats file has wrong numbers","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonmar"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"Bug","description":"The summary numbers in the file generated with the -S flag cannot be right. Here's an example:\r\n{{{\r\n 1,943,795,468 bytes allocated in the heap\r\n 17,587,189,232 bytes copied during GC\r\n}}}\r\nThe corresponding numbers with ghc 7.2 are\r\n{{{\r\n 193,859,474,520 bytes allocated in the heap\r\n 17,766,908,288 bytes copied during GC\r\n}}}\r\nWhile it's theoretically possible that allocation has improved that much, I don't believe it.","type_of_failure":"OtherFailure","blocking":[]} -->Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/9235Simplifier ticks exhausted on recursive class method2023-09-18T10:01:18ZklaoSimplifier ticks exhausted on recursive class methodGHC 7.8 and HEAD panic on the following code:
```haskell
module C where
class C a where
c :: C a => a -> Int
c a = c a
{-# INLINE c #-}
instance C ()
x :: Int
x = c ()
```
Note that it's the coincidence of the 3 conditions tha...GHC 7.8 and HEAD panic on the following code:
```haskell
module C where
class C a where
c :: C a => a -> Int
c a = c a
{-# INLINE c #-}
instance C ()
x :: Int
x = c ()
```
Note that it's the coincidence of the 3 conditions that triggers this bug:
1. the `c` method has to be inlined (explicity or implicitly)
1. it has to be recursive (but, it doesn't have to be as dumbly recursive as in the example)
1. it has to have this weird, slightly mistaken type signature: `C a => a -> Int` instead of simply `a -> Int`.
But, when this incidentally happens (in my case, both 2. *and* 3. were unintentional), the user gets a very hard to debug issue. They don't even get an indication which module is responsible if `c` is used from a different module than the one with the class definition.
Also note that this happens even with a non-optimized build. And in this example `c` has to be explicitly marked NOINLINE to prevent it. (In the instance that I caught in the wild simply removing the INLINE annotation was enough.)
Finally, on a side note: shouldn't 3. by itself be an error? Or a warning at least?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Simplifier ticks exhausted on recursive class method","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"GHC 7.8 and HEAD panic on the following code:\r\n\r\n{{{#!haskell\r\nmodule C where\r\n\r\nclass C a where\r\n c :: C a => a -> Int\r\n c a = c a\r\n {-# INLINE c #-}\r\n\r\ninstance C ()\r\n\r\nx :: Int\r\nx = c ()\r\n}}}\r\n\r\nNote that it's the coincidence of the 3 conditions that triggers this bug:\r\n1. the `c` method has to be inlined (explicity or implicitly)\r\n2. it has to be recursive (but, it doesn't have to be as dumbly recursive as in the example)\r\n3. it has to have this weird, slightly mistaken type signature: `C a => a -> Int` instead of simply `a -> Int`.\r\n\r\nBut, when this incidentally happens (in my case, both 2. ''and'' 3. were unintentional), the user gets a very hard to debug issue. They don't even get an indication which module is responsible if `c` is used from a different module than the one with the class definition.\r\n\r\nAlso note that this happens even with a non-optimized build. And in this example `c` has to be explicitly marked NOINLINE to prevent it. (In the instance that I caught in the wild simply removing the INLINE annotation was enough.)\r\n\r\nFinally, on a side note: shouldn't 3. by itself be an error? Or a warning at least?","type_of_failure":"OtherFailure","blocking":[]} -->⊥https://gitlab.haskell.org/ghc/ghc/-/issues/9237GHC not recognizing INPUT(-llibrary) in linker scripts2019-07-07T18:41:14ZmmikolajczykGHC not recognizing INPUT(-llibrary) in linker scriptsI have tried to build accelerate-llvm package and encountered an invalid behaviour of linker. I am using Arch Linux and GHC 7.8.2.
I have installed llvm-general-3.4.2.2 and llvm-general-pure-3.4.2.2 from this branch: https://github.com/...I have tried to build accelerate-llvm package and encountered an invalid behaviour of linker. I am using Arch Linux and GHC 7.8.2.
I have installed llvm-general-3.4.2.2 and llvm-general-pure-3.4.2.2 from this branch: https://github.com/tvh/llvm-general/tree/curatedTargetMachine, and accelerate from HEAD to common sandbox. Then I tried to build accelerate-llvm using the sandbox and got this output during building:
```
Building accelerate-llvm-0.15.0.0...
Preprocessing library accelerate-llvm-0.15.0.0...
[ 1 of 30] Compiling Data.Range.Range ( Data/Range/Range.hs, dist/build/Data/Range/Range.o )
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package primitive-0.5.3.0 ... linking ... done.
Loading package array-0.5.0.0 ... linking ... done.
Loading package deepseq-1.3.0.2 ... linking ... done.
Loading package old-locale-1.0.0.6 ... linking ... done.
Loading package time-1.4.2 ... linking ... done.
Loading package vector-0.10.11.0 ... linking ... done.
Loading package mwc-random-0.13.1.2 ... linking ... done.
Loading package bytestring-0.10.4.0 ... linking ... done.
Loading package containers-0.5.5.1 ... linking ... done.
Loading package transformers-0.4.1.0 ... linking ... done.
Loading package mtl-2.2.1 ... linking ... done.
Loading package text-1.1.1.3 ... linking ... done.
Loading package parsec-3.1.5 ... linking ... done.
Loading package unix-2.7.0.1 ... linking ... done.
Loading package setenv-0.1.1.1 ... linking ... done.
Loading package pretty-1.1.1.1 ... linking ... done.
Loading package template-haskell ... linking ... done.
Loading package llvm-general-pure-3.4.2.2 ... linking ... done.
Loading package utf8-string-0.3.8 ... linking ... done.
Loading package llvm-general-3.4.2.2 ... <command line>: can't load .so/.DLL for: /usr/lib/libcurses.so (-lncursesw: cannot open shared object file: No such file or directory)
```
After some searching I narrowed down the issue to `/usr/lib/libcurses.so` file. In Arch, this file contains `INPUT(-lncursesw)`. If I change it to `INPUT(libncursesw.so)` or `INPUT(/usr/lib/libncursesw.so)` it works fine. Symlinking `/usr/lib/libcurses.so` to `/usr/lib/libncursesw.so` also works.
This bug seems to be connected to #2615. GHC still doesn't follow `INPUT` commands containing `-llibrary` form. Ld documentation allows this: `If you use `INPUT (-lfile)', ld will transform the name to libfile.a, as with the command line argument `-l'`. (https://sourceware.org/binutils/docs/ld/File-Commands.html)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------- |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | CompileTimeCrash |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown/Multiple |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC not recognizing \"-llibrary\" form in implicit linker scripts","status":"New","operating_system":"Unknown/Multiple","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I have tried to build accelerate-llvm package and encountered an invalid behaviour of linker. I am using Arch Linux and GHC 7.8.2.\r\n\r\nI have installed llvm-general-3.4.2.2 and llvm-general-pure-3.4.2.2 from this branch: https://github.com/tvh/llvm-general/tree/curatedTargetMachine, and accelerate from HEAD to common sandbox. Then I tried to build accelerate-llvm using the sandbox and got this output during building:\r\n\r\n{{{\r\nBuilding accelerate-llvm-0.15.0.0...\r\nPreprocessing library accelerate-llvm-0.15.0.0...\r\n[ 1 of 30] Compiling Data.Range.Range ( Data/Range/Range.hs, dist/build/Data/Range/Range.o )\r\nLoading package ghc-prim ... linking ... done.\r\nLoading package integer-gmp ... linking ... done.\r\nLoading package base ... linking ... done.\r\nLoading package primitive-0.5.3.0 ... linking ... done.\r\nLoading package array-0.5.0.0 ... linking ... done.\r\nLoading package deepseq-1.3.0.2 ... linking ... done.\r\nLoading package old-locale-1.0.0.6 ... linking ... done.\r\nLoading package time-1.4.2 ... linking ... done.\r\nLoading package vector-0.10.11.0 ... linking ... done.\r\nLoading package mwc-random-0.13.1.2 ... linking ... done.\r\nLoading package bytestring-0.10.4.0 ... linking ... done.\r\nLoading package containers-0.5.5.1 ... linking ... done.\r\nLoading package transformers-0.4.1.0 ... linking ... done.\r\nLoading package mtl-2.2.1 ... linking ... done.\r\nLoading package text-1.1.1.3 ... linking ... done.\r\nLoading package parsec-3.1.5 ... linking ... done.\r\nLoading package unix-2.7.0.1 ... linking ... done.\r\nLoading package setenv-0.1.1.1 ... linking ... done.\r\nLoading package pretty-1.1.1.1 ... linking ... done.\r\nLoading package template-haskell ... linking ... done.\r\nLoading package llvm-general-pure-3.4.2.2 ... linking ... done.\r\nLoading package utf8-string-0.3.8 ... linking ... done.\r\nLoading package llvm-general-3.4.2.2 ... <command line>: can't load .so/.DLL for: /usr/lib/libcurses.so (-lncursesw: cannot open shared object file: No such file or directory)\r\n}}}\r\n\r\nAfter some searching I narrowed down the issue to `/usr/lib/libcurses.so` file. In Arch, this file contains `INPUT(-lncursesw)`. If I change it to `INPUT(libncursesw.so)` or `INPUT(/usr/lib/libncursesw.so)` it works fine. Symlinking `/usr/lib/libcurses.so` to `/usr/lib/libncursesw.so` also works.\r\n\r\nThis bug seems to be connected to #2615. GHC still doesn't follow `INPUT` commands containing `-llibrary` form. Ld documentation allows this: {{{If you use `INPUT (-lfile)', ld will transform the name to libfile.a, as with the command line argument `-l'}}}. (https://sourceware.org/binutils/docs/ld/File-Commands.html)","type_of_failure":"CompileTimeCrash","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9244Compiler could warn about type variable shadowing, and hint about ScopedTypeV...2020-01-23T19:37:51ZstusmithCompiler could warn about type variable shadowing, and hint about ScopedTypeVariablesGHC already warns about variable shadowing:
```
$ cat test.hs
module Test where
timesTwoPlusOne x
= timesTwo x + 1
where timesTwo x = x * 2
$ ghc -fwarn-name-shadowing test.hs
...
Warning:
This binding for `x' shadows the ex...GHC already warns about variable shadowing:
```
$ cat test.hs
module Test where
timesTwoPlusOne x
= timesTwo x + 1
where timesTwo x = x * 2
$ ghc -fwarn-name-shadowing test.hs
...
Warning:
This binding for `x' shadows the existing binding
bound at <location>
```
However the similar warning doesn't happen for type variables.
```
$ cat T9244.hs
module T9244 where
import Control.Exception
tryMaybe :: IO a -> IO (Maybe a)
tryMaybe action = do
result <- (try action) :: IO (Either SomeException a)
return $ case result of
Left _ -> Nothing
Right v -> Just v
$ ghc -fwarn-name-shadowing T9244.hs
...
Couldn't match type `a' with `a1'
`a' is a rigid type variable bound by
the type signature for tryMaybe :: IO a -> IO (Maybe a)
at types.hs:<line>:13
`a1' is a rigid type variable bound by
an expression type signature: IO (Either SomeException a1)
at types.hs:<line>:15
Expected type: IO a1
Actual type: IO a
...
```
Here, I thought that the 'a' in the function's type declaration was the same 'a' in the expression type declaration. However in Haskell 98, they are completely different variables.
Suggestion: if a type variable is renamed by the compiler due to a clash with another type variable, issue a warning that the second shadows the first, and give a hint about using -XScopedTypeVariables and forall.
Alternative suggestion: if an error is displayed, where the error contains a renamed type variable, issue a hint that the second shadows the first, and give a hint about using -XScopedTypeVariables and forall.kanetwkanetwhttps://gitlab.haskell.org/ghc/ghc/-/issues/9246GHC generates poor code for repeated uses of min/max2021-06-28T01:36:48ZarotenbergGHC generates poor code for repeated uses of min/maxConsider the following module, which intends to implement a [branchless ray-AABB intersection test](http://tavianator.com/2011/05/fast-branchless-raybounding-box-intersections/):
```
module SimpleGeom where
data Vec3 = Vec3
{-# UNP...Consider the following module, which intends to implement a [branchless ray-AABB intersection test](http://tavianator.com/2011/05/fast-branchless-raybounding-box-intersections/):
```
module SimpleGeom where
data Vec3 = Vec3
{-# UNPACK #-} !Double
{-# UNPACK #-} !Double
{-# UNPACK #-} !Double
data Ray = Ray !Vec3 !Vec3 !Vec3
data AABB = AABB !Vec3 !Vec3
testRayAABBIntersection :: Ray -> AABB -> Bool
testRayAABBIntersection (Ray (Vec3 ox oy oz) _ (Vec3 invDx invDy invDz))
(AABB (Vec3 minX minY minZ) (Vec3 maxX maxY maxZ)) =
let tx1 = (minX - ox) * invDx
tx2 = (maxX - ox) * invDx
ty1 = (minY - oy) * invDy
ty2 = (maxY - oy) * invDy
tz1 = (minZ - oz) * invDz
tz2 = (maxZ - oz) * invDz
tmin = min tx1 tx2 `max` min ty1 ty2 `max` min tz1 tz2
tmax = max tx1 tx2 `min` max ty1 ty2 `min` max tz1 tz2
in tmax >= max 0 tmin
```
Everything is strict primitive operations, so GHC should generate very simple, fast code, right? But upon compiling with `ghc -O -ddump-simpl -ddump-to-file SimpleGeom`, I found a mess of nested local lambdas and similar performance-killing expression forms. (See the attached output file.)
There are two possible issues I can see here.
1. GHC is trying to expand out all of the branches recursively (I would presume via case-of-cases transformation), which is a bad idea in this instance compared to just performing the cases sequentially and storing their results.
1. GHC is generating branches for floating-point min/max. Instruction sets like SSE2 include non-branching floating-point min/max instructions, which is exactly what this algorithm was designed to exploit, but GHC does not generate code that could take advantage of these instructions.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Windows |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC generates poor code for repeated uses of min/max","status":"New","operating_system":"Windows","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider the following module, which intends to implement a [http://tavianator.com/2011/05/fast-branchless-raybounding-box-intersections/ branchless ray-AABB intersection test]:\r\n\r\n{{{\r\nmodule SimpleGeom where\r\n\r\ndata Vec3 = Vec3\r\n {-# UNPACK #-} !Double\r\n {-# UNPACK #-} !Double\r\n {-# UNPACK #-} !Double\r\ndata Ray = Ray !Vec3 !Vec3 !Vec3\r\ndata AABB = AABB !Vec3 !Vec3\r\n\r\ntestRayAABBIntersection :: Ray -> AABB -> Bool\r\ntestRayAABBIntersection (Ray (Vec3 ox oy oz) _ (Vec3 invDx invDy invDz))\r\n (AABB (Vec3 minX minY minZ) (Vec3 maxX maxY maxZ)) =\r\n let tx1 = (minX - ox) * invDx\r\n tx2 = (maxX - ox) * invDx\r\n ty1 = (minY - oy) * invDy\r\n ty2 = (maxY - oy) * invDy\r\n tz1 = (minZ - oz) * invDz\r\n tz2 = (maxZ - oz) * invDz\r\n tmin = min tx1 tx2 `max` min ty1 ty2 `max` min tz1 tz2\r\n tmax = max tx1 tx2 `min` max ty1 ty2 `min` max tz1 tz2\r\n in tmax >= max 0 tmin\r\n}}}\r\n\r\nEverything is strict primitive operations, so GHC should generate very simple, fast code, right? But upon compiling with {{{ghc -O -ddump-simpl -ddump-to-file SimpleGeom}}}, I found a mess of nested local lambdas and similar performance-killing expression forms. (See the attached output file.)\r\n\r\nThere are two possible issues I can see here.\r\n1. GHC is trying to expand out all of the branches recursively (I would presume via case-of-cases transformation), which is a bad idea in this instance compared to just performing the cases sequentially and storing their results.\r\n1. GHC is generating branches for floating-point min/max. Instruction sets like SSE2 include non-branching floating-point min/max instructions, which is exactly what this algorithm was designed to exploit, but GHC does not generate code that could take advantage of these instructions.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9249Link to "latest" user's guide2019-07-07T18:41:11ZRichard Eisenbergrae@richarde.devLink to "latest" user's guideWhen I search (say, on Google) for a GHC-related bit of documentation, I variously get referred to old manuals. There doesn't seem to a good way for us, the GHC devs, to avoid this. But, perhaps we can include some information in the hea...When I search (say, on Google) for a GHC-related bit of documentation, I variously get referred to old manuals. There doesn't seem to a good way for us, the GHC devs, to avoid this. But, perhaps we can include some information in the header of the pages to allow visitors to link to the latest manual, or perhaps to several versions. This header should also include the version number of the GHC that the page is documenting; currently, this info is only in the URL.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------- |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | Documentation |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Link to \"latest\" user's guide","status":"New","operating_system":"","component":"Documentation","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When I search (say, on Google) for a GHC-related bit of documentation, I variously get referred to old manuals. There doesn't seem to a good way for us, the GHC devs, to avoid this. But, perhaps we can include some information in the header of the pages to allow visitors to link to the latest manual, or perhaps to several versions. This header should also include the version number of the GHC that the page is documenting; currently, this info is only in the URL.","type_of_failure":"OtherFailure","blocking":[]} -->8.4.1https://gitlab.haskell.org/ghc/ghc/-/issues/9251ghc does not expose branchless max/min operations as primops2020-04-29T13:20:47ZCarter Schonwaldghc does not expose branchless max/min operations as primopsIt was pointed out in #9246 that GHC currently does not expose primops for Max and Min on various unlifted types such as Float\# and Double\# and Int\# and Word\#, but that on most modern CPU architectures there is instruction level supp...It was pointed out in #9246 that GHC currently does not expose primops for Max and Min on various unlifted types such as Float\# and Double\# and Int\# and Word\#, but that on most modern CPU architectures there is instruction level support for these operations. (Eg, Float\# and \#Double min and max can be provided on any 64bit x86 system pretty easily )
This ticket is to track doing that task. I'll probably do it one of the next two weekends to get back in the GHC hacking groove, or maybe this should be used as a "getting started" ticket for a new contributor?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ghc does not expose brancheless max/min operations as primops","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"7.10.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"carter"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"It was pointed out in #9246 that GHC currently does not expose primops for Max and Min on various unlifted types such as Float# and Double# and Int# and Word#, but that on most modern CPU architectures there is instruction level support for these operations. (Eg, Float# and #Double min and max can be provided on any 64bit x86 system pretty easily )\r\n\r\nThis ticket is to track doing that task. I'll probably do it one of the next two weekends to get back in the GHC hacking groove, or maybe this should be used as a \"getting started\" ticket for a new contributor? \r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9267Lack of type information in GHC error messages when the liberage coverage con...2019-07-07T18:41:07Zdanilo2Lack of type information in GHC error messages when the liberage coverage condition is unsatisfiedHello! The problem is not a bug related to proper code execution, but it affects the development in such way, we can treat it as a bug.
Lets think about such simple code (it can be further simplified of course):
> {{{\#!haskell
{-\# L...Hello! The problem is not a bug related to proper code execution, but it affects the development in such way, we can treat it as a bug.
Lets think about such simple code (it can be further simplified of course):
> {{{\#!haskell
{-\# LANGUAGE FunctionalDependencies \#-}
{-\# LANGUAGE FlexibleInstances \#-}
{-\# LANGUAGE ScopedTypeVariables \#-}
{-\# LANGUAGE UndecidableInstances \#-}
data UnsafeBase base err val = Value val
\| Error err
\| Other (base val)
> deriving (Show, Eq)
class MagicMerge m1 m2 \| m1 -\> m2 where
> magicMerge :: m1 a -\> m2 a
instance MagicMerge (UnsafeBase (UnsafeBase base err) err) (UnsafeBase base err) where
magicMerge ma = case ma of
Value a -\> Value a
Error e -\> Error e
> Other o -\> o
instance MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1) where
<table><tr><th>magicMerge (ma </th>
<td>UnsafeBase (UnsafeBase base err1) err2 a) = case ma of</td></tr>
<tr><td></td>
<td>Value a -\> Value a</td></tr>
<tr><th>Error e -\> Other $ magicMerge (Error e </th>
<td>UnsafeBase base err2 a)</td></tr>
<tr><td></td>
<td>Other o -\> case o of</td></tr>
<tr><th>Value a -\> Other $ magicMerge (Value a </th>
<td>UnsafeBase base err2 a)</td></tr>
<tr><td></td>
<td>Error e -\> Error e</td></tr>
<tr><th>Other o' -\> Other $ magicMerge (Other o' </th>
<td>UnsafeBase base err2 a)</td></tr></table>
main = print "help me world!"
> }}}
When trying to compile it using GHC-7.8, we get following error message:
> `
> Illegal instance declaration for
> ‘MagicMerge
> (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1)’
> The liberal coverage condition fails in class ‘MagicMerge’
> for functional dependency: ‘m1 -> m2’
> Reason: lhs type ‘UnsafeBase (UnsafeBase base err1) err2’
> does not determine rhs type ‘UnsafeBase dstBase err1’
> In the instance declaration for
> ‘MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1)’
> `
Which is of course right, but is completely unhelpfull! When we run the same program against GHC-7.6, we get another message:
> `
> No instance for (MagicMerge (UnsafeBase base err2) dstBase)
> arising from a use of `magicMerge'
> Possible fix:
> add an instance declaration for
> (MagicMerge (UnsafeBase base err2) dstBase)
> In the second argument of `($)', namely
> `magicMerge (Error e :: UnsafeBase base err2 a)'
> In the expression:
> Other $ magicMerge (Error e :: UnsafeBase base err2 a)
> In a case alternative:
> Error e -> Other $ magicMerge (Error e :: UnsafeBase base err2 a)
> `
And it contains a very helpfull information about inferred types. The information is very usefull, especialy when developing more complex instances.
It is VERY IMPORTANT to notice, that when we use the inferred context, the code compiles in both, GHC-7.8 and GHC-7.6! Right now I have to use both versions of GHC side by side, to be able to develop my instances faster.
So If we add the context inferred by GHC-7.6:
> {{{\#!haskell
{-\# LANGUAGE FunctionalDependencies \#-}
{-\# LANGUAGE FlexibleInstances \#-}
{-\# LANGUAGE ScopedTypeVariables \#-}
{-\# LANGUAGE UndecidableInstances \#-}
data UnsafeBase base err val = Value val
\| Error err
\| Other (base val)
> deriving (Show, Eq)
class MagicMerge m1 m2 \| m1 -\> m2 where
> magicMerge :: m1 a -\> m2 a
instance MagicMerge (UnsafeBase (UnsafeBase base err) err) (UnsafeBase base err) where
magicMerge ma = case ma of
Value a -\> Value a
Error e -\> Error e
> Other o -\> o
instance (MagicMerge (UnsafeBase base err2) dstBase) =\> MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1) where
<table><tr><th>magicMerge (ma </th>
<td>UnsafeBase (UnsafeBase base err1) err2 a) = case ma of</td></tr>
<tr><td></td>
<td>Value a -\> Value a</td></tr>
<tr><th>Error e -\> Other $ magicMerge (Error e </th>
<td>UnsafeBase base err2 a)</td></tr>
<tr><td></td>
<td>Other o -\> case o of</td></tr>
<tr><th>Value a -\> Other $ magicMerge (Value a </th>
<td>UnsafeBase base err2 a)</td></tr>
<tr><td></td>
<td>Error e -\> Error e</td></tr>
<tr><th>Other o' -\> Other $ magicMerge (Other o' </th>
<td>UnsafeBase base err2 a)</td></tr></table>
main = print "help me world!"
> }}}
The code compiles and works ok in both GHC-7.6 and GHC-7.8. In such cases, GHC-7.8 should inform about lacking premises.8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9269Type families returning quantified types2021-04-20T11:44:40ZpumpkinType families returning quantified typesIs there a fundamental reason for not being able to use quantification in a type family? I'd very much like to be able to do it, obviously turning on RankNTypes if necessary.
I'm looking for things like this:
```haskell
type family Foo...Is there a fundamental reason for not being able to use quantification in a type family? I'd very much like to be able to do it, obviously turning on RankNTypes if necessary.
I'm looking for things like this:
```haskell
type family Foo (x :: Bool) where
Foo True = forall a. [a]
Foo False = ()
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Type families returning quantified types","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Is there a fundamental reason for not being able to use quantification in a type family? I'd very much like to be able to do it, obviously turning on RankNTypes if necessary.\r\n\r\nI'm looking for things like this:\r\n\r\n{{{#!haskell\r\ntype family Foo (x :: Bool) where\r\n Foo True = forall a. [a]\r\n Foo False = ()\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9275Missing import statement in GHC.Event.Poll2019-07-07T18:41:05ZydewitMissing import statement in GHC.Event.PollSee the following section from base's GHC.Event.Poll module:
```
module GHC.Event.Poll
(
new
, available
) where
#include "EventConfig.h"
#if !defined(HAVE_POLL_H)
import GHC.Base
new :: IO E.Backend
new = error "Po...See the following section from base's GHC.Event.Poll module:
```
module GHC.Event.Poll
(
new
, available
) where
#include "EventConfig.h"
#if !defined(HAVE_POLL_H)
import GHC.Base
new :: IO E.Backend
new = error "Poll back end not implemented for this platform"
available :: Bool
available = False
{-# INLINE available #-}
#else
#include <poll.h>
import Control.Concurrent.MVar (MVar, newMVar, swapMVar)
import Control.Monad ((=<<), liftM, liftM2, unless)
import Data.Bits (Bits, FiniteBits, (.|.), (.&.))
import Data.Maybe (Maybe(..))
import Data.Monoid (Monoid(..))
import Data.Word
import Foreign.C.Types (CInt(..), CShort(..))
import Foreign.Ptr (Ptr)
import Foreign.Storable (Storable(..))
import GHC.Base
import GHC.Conc.Sync (withMVar)
import GHC.Enum (maxBound)
import GHC.Num (Num(..))
import GHC.Real (ceiling, fromIntegral)
import GHC.Show (Show)
import System.Posix.Types (Fd(..))
import qualified GHC.Event.Array as A
import qualified GHC.Event.Internal as E
```
Note how there is a missing `import qualified GHC.Event.Internal as E` when `HAVE_POLL_H` is not defined.
The same issue is present in master.
This is the error seen (note this is a custom haste build):
```
Building base-4.7.0.0...
Preprocessing library base-4.7.0.0...
hastec: setNumCapabilities: not supported in the non-threaded RTS
GHC/Event/Poll.hsc:18:11:
Not in scope: type constructor or class ‘E.Backend’
```rwbartonrwbartonhttps://gitlab.haskell.org/ghc/ghc/-/issues/9276audit ghc floating point support for IEEE (non)compliance2023-02-15T13:01:56ZCarter Schonwaldaudit ghc floating point support for IEEE (non)complianceAs best I can determine, ghc has never been closely audited for conformance to IEEE-754 (floating point) standard and currently is a bit far from providing a compliant implementation.
This impacts both a number of other tasks i wish to ...As best I can determine, ghc has never been closely audited for conformance to IEEE-754 (floating point) standard and currently is a bit far from providing a compliant implementation.
This impacts both a number of other tasks i wish to do for ghc \*\*and\*\* much of my own use of haskell is in a floating point heavy workloads, I will do a bit of leg work to:
> a) improve test suite support for checking for compliance
> b) write some patches to provide portable compliant primops for the operations which need compiler support
> c) try to determine how to allow ghc optimizer to be a bit more aggressive in a sound way in the presence of floating point.
(this may grow into a few subtickets, we'll see)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"audit ghc floating point support for IEEE (non)compliance","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"7.10.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"carter"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"As best I can determine, ghc has never been closely audited for conformance to IEEE-754 (floating point) standard and currently is a bit far from providing a compliant implementation.\r\n\r\nThis impacts both a number of other tasks i wish to do for ghc **and** much of my own use of haskell is in a floating point heavy workloads, I will do a bit of leg work to:\r\n\r\n a) improve test suite support for checking for compliance\r\n b) write some patches to provide portable compliant primops for the operations which need compiler support\r\n c) try to determine how to allow ghc optimizer to be a bit more aggressive in a sound way in the presence of floating point.\r\n\r\n(this may grow into a few subtickets, we'll see)","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1Carter SchonwaldCarter Schonwaldhttps://gitlab.haskell.org/ghc/ghc/-/issues/9277GHCi panic: Loading temp shared object failed: Symbol not found2019-07-07T18:41:05ZMiëtek BakGHCi panic: Loading temp shared object failed: Symbol not foundWhen given a Objective-C object file referencing a symbol available in a system framework, interactive GHCi 7.8.2 panics saying it can't find the symbol the object file relies on.
Start with an Objective-C source file, defining a functi...When given a Objective-C object file referencing a symbol available in a system framework, interactive GHCi 7.8.2 panics saying it can't find the symbol the object file relies on.
Start with an Objective-C source file, defining a function to be used via the FFI:
```
$ cat >foo.m <<EOF
#import <Foundation/Foundation.h>
BOOL is_main_thread()
{
return [NSThread isMainThread];
}
EOF
```
```
$ cat >Main.hs <<EOF
module Main where
foreign import ccall "is_main_thread" isMainThread :: IO Bool
main :: IO ()
main = do
mt <- isMainThread
print mt
EOF
```
Non-interactive GHC 7.8.2 works as expected:
```
$ clang -c -o foo.o foo.m
```
```
$ ghc -framework Foundation -o foo foo.o Main.hs
[1 of 1] Compiling Main ( Main.hs, Main.o )
Linking foo ...
```
```
$ ./foo
True
```
Interactive GHCi 7.8.2 panics:
```
$ ghci -v -framework Foundation foo.o Main.hs
GHCi, version 7.8.2: http://www.haskell.org/ghc/ :? for help
Glasgow Haskell Compiler, Version 7.8.2, stage 2 booted by GHC version 7.6.3
Using binary package database: /opt/ghc-7.8.2/lib/ghc-7.8.2/package.conf.d/package.cache
wired-in package ghc-prim mapped to ghc-prim-0.3.1.0-948744e1f99cc8bcc7c7d3ba60c7c2d8
wired-in package integer-gmp mapped to integer-gmp-0.5.1.0-dc47f6b546fc171f67a7f7d311684a99
wired-in package base mapped to base-4.7.0.0-a333addb6892f3cc2e6baa5ec782bd04
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.9.0.0-ed6ecfb467e6936688bb20f968f702e1
wired-in package dph-seq not found.
wired-in package dph-par not found.
Hsc static flags:
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
*** gcc:
/usr/bin/gcc -m64 -fno-stack-protector -DTABLES_NEXT_TO_CODE -L/opt/ghc-7.8.2/lib/ghc-7.8.2/base-4.7.0.0 --print-file-name libiconv.dylib
Loading package base ... linking ... done.
Loading object (static) foo.o ... Created temporary directory: /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc37622_0
*** Linker:
/usr/bin/gcc -m64 -fno-stack-protector -DTABLES_NEXT_TO_CODE -m64 -dynamiclib -o /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc37622_0/ghc37622_1.dylib foo.o -undefined dynamic_lookup -single_module -install_name '@rpath/ghc37622_1.dylib' -L/opt/ghc-7.8.2/lib/ghc-7.8.2/base-4.7.0.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/base-4.7.0.0 -L/opt/ghc-7.8.2/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -L/opt/ghc-7.8.2/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -L/opt/ghc-7.8.2/lib/ghc-7.8.2/rts-1.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/rts-1.0 -lHSbase-4.7.0.0-ghc7.8.2 -lHSinteger-gmp-0.5.1.0-ghc7.8.2 -lHSghc-prim-0.3.1.0-ghc7.8.2 -liconv
*** Deleting temp files:
Deleting: /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc37622_0/ghc37622_1.dylib
*** Deleting temp dirs:
Deleting: /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc37622_0
ghc: panic! (the 'impossible' happened)
(GHC version 7.8.2 for x86_64-apple-darwin):
Loading temp shared object failed: dlopen(/var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc37622_0/ghc37622_1.dylib, 9): Symbol not found: _OBJC_CLASS_$_NSThread
Referenced from: /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc37622_0/ghc37622_1.dylib
Expected in: flat namespace
in /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc37622_0/ghc37622_1.dylib
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
Omitting `-framework Foundation` makes no difference to the output.https://gitlab.haskell.org/ghc/ghc/-/issues/9278GHCi crash: selector _ for message _ does not match selector known to Objecti...2019-07-07T18:41:05ZMiëtek BakGHCi crash: selector _ for message _ does not match selector known to Objective C runtimeGiven an Objective-C object file referencing a symbol available in a system framework, interactive GHCi 7.6.3 crashes in an odd fashion.
Start with an Objective-C source file, defining a function to be used via the FFI:
```
$ cat >foo....Given an Objective-C object file referencing a symbol available in a system framework, interactive GHCi 7.6.3 crashes in an odd fashion.
Start with an Objective-C source file, defining a function to be used via the FFI:
```
$ cat >foo.m <<EOF
#import <Foundation/Foundation.h>
BOOL is_main_thread()
{
return [NSThread isMainThread];
}
EOF
```
```
$ cat >Main.hs <<EOF
module Main where
foreign import ccall "is_main_thread" isMainThread :: IO Bool
main :: IO ()
main = do
mt <- isMainThread
print mt
EOF
```
Non-interactive GHC 7.6.3 works as expected:
```
$ clang -c -o foo.o foo.m
```
```
$ ghc -framework Foundation -o foo foo.o Main.hs
[1 of 1] Compiling Main ( Main.hs, Main.o )
Linking foo ...
```
```
$ ./foo
True
```
Interactive GHCi 7.6.3 crashes:
```
$ ghci -framework Foundation foo.o Main.hs
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading object (static) foo.o ... done
Loading object (framework) Foundation ... done
final link ... done
Ok, modules loaded: Main.
> main
2014-07-07 12:28:21.811 ghc[37395:1103] *** NSForwarding: warning: selector (0x10ddef328) for message 'isMainThread' does not match selector known to Objective C runtime (0x7fff8ea15881)-- abort
2014-07-07 12:28:21.813 ghc[37395:1103] +[NSThread isMainThread]: unrecognized selector sent to class 0x7fff75535280
2014-07-07 12:28:21.814 ghc[37395:1103] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSThread isMainThread]: unrecognized selector sent to class 0x7fff75535280'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff8bb4825c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff85029e75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8bb4b02d +[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00007fff8baa6322 ___forwarding___ + 1010
4 CoreFoundation 0x00007fff8baa5ea8 _CF_forwarding_prep_0 + 120
5 ??? 0x000000010ddef31a 0x0 + 4527682330
6 ??? 0x000000010ddf02f5 0x0 + 4527686389
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Abort trap: 6
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHCi crash:","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":["crash,","dynamic","linking"],"differentials":[],"test_case":"","architecture":"","cc":["hvr"],"type":"Bug","description":"Given an Objective-C object file referencing a symbol available in a system framework, interactive GHCi 7.6.3 crashes in an odd fashion.\r\n\r\nStart with an Objective-C source file, defining a function to be used via the FFI:\r\n\r\n{{{\r\n$ cat >foo.m <<EOF\r\n#import <Foundation/Foundation.h>\r\n\r\nBOOL is_main_thread()\r\n{\r\n return [NSThread isMainThread];\r\n}\r\nEOF\r\n}}}\r\n{{{\r\n$ cat >Main.hs <<EOF\r\nmodule Main where\r\n\r\nforeign import ccall \"is_main_thread\" isMainThread :: IO Bool\r\n\r\nmain :: IO ()\r\nmain = do\r\n mt <- isMainThread\r\n print mt\r\nEOF\r\n}}}\r\n\r\nNon-interactive GHC 7.6.3 works as expected:\r\n\r\n{{{\r\n$ clang -c -o foo.o foo.m\r\n}}}\r\n{{{\r\n$ ghc -framework Foundation -o foo foo.o Main.hs\r\n[1 of 1] Compiling Main ( Main.hs, Main.o )\r\nLinking foo ...\r\n}}}\r\n{{{\r\n$ ./foo\r\nTrue\r\n}}}\r\n\r\nInteractive GHCi 7.6.3 crashes:\r\n\r\n{{{\r\n$ ghci -framework Foundation foo.o Main.hs\r\nGHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help\r\nLoading package ghc-prim ... linking ... done.\r\nLoading package integer-gmp ... linking ... done.\r\nLoading package base ... linking ... done.\r\nLoading object (static) foo.o ... done\r\nLoading object (framework) Foundation ... done\r\nfinal link ... done\r\nOk, modules loaded: Main.\r\n> main\r\n2014-07-07 12:28:21.811 ghc[37395:1103] *** NSForwarding: warning: selector (0x10ddef328) for message 'isMainThread' does not match selector known to Objective C runtime (0x7fff8ea15881)-- abort\r\n2014-07-07 12:28:21.813 ghc[37395:1103] +[NSThread isMainThread]: unrecognized selector sent to class 0x7fff75535280\r\n2014-07-07 12:28:21.814 ghc[37395:1103] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSThread isMainThread]: unrecognized selector sent to class 0x7fff75535280'\r\n*** First throw call stack:\r\n(\r\n\t0 CoreFoundation 0x00007fff8bb4825c __exceptionPreprocess + 172\r\n\t1 libobjc.A.dylib 0x00007fff85029e75 objc_exception_throw + 43\r\n\t2 CoreFoundation 0x00007fff8bb4b02d +[NSObject(NSObject) doesNotRecognizeSelector:] + 205\r\n\t3 CoreFoundation 0x00007fff8baa6322 ___forwarding___ + 1010\r\n\t4 CoreFoundation 0x00007fff8baa5ea8 _CF_forwarding_prep_0 + 120\r\n\t5 ??? 0x000000010ddef31a 0x0 + 4527682330\r\n\t6 ??? 0x000000010ddf02f5 0x0 + 4527686389\r\n)\r\nlibc++abi.dylib: terminating with uncaught exception of type NSException\r\nAbort trap: 6\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9279Local wrapper function remains in final program; result = extra closure alloc...2019-07-07T18:41:04ZSimon MarlowLocal wrapper function remains in final program; result = extra closure allocationI have a strange problem with a local function binding that is not being inlined. I've attached the repro code, build it like this:
```
$ ghc -O2 Haxl/Core/Monad.hs
```
There are several modules, but the one with the problem is `Haxl/C...I have a strange problem with a local function binding that is not being inlined. I've attached the repro code, build it like this:
```
$ ghc -O2 Haxl/Core/Monad.hs
```
There are several modules, but the one with the problem is `Haxl/Core/Monad.hs`. In particular `Haxl.Core.Monad.$fApplicativeGenHaxl2`, which contains this fragment:
```
let {
$wa4_s6YQ
$wa4_s6YQ =
\ w_s6YF _ ww1_s6YM _ _ w1_s6YI ->
case GHC.Prim.readMutVar# ipv7_X5Ne w1_s6YI
of _ { (# ipv10_X5QO, ipv11_X5QQ #) ->
case ipv11_X5QQ of _ {
Haxl.Core.Monad.IVarFull a2_a3kK -> case lvl6_r7qi of wild3_00 { };
Haxl.Core.Monad.IVarEmpty dt2_d4Vs ->
case GHC.Prim.writeMutVar#
ipv7_X5Ne (Haxl.Core.Monad.IVarFull w_s6YF) ipv10_X5QO
of s2#_a5OR { __DEFAULT ->
case GHC.Prim.readMutVar# dt2_d4Vs s2#_a5OR
of _ { (# ipv12_X5R0, ipv13_X5R2 #) ->
case GHC.Prim.readMutVar# ww1_s6YM ipv12_X5R0
of _ { (# ipv14_X5SS, ipv15_X5SU #) ->
letrec {
go_a5ti
go_a5ti =
\ ds10_a5tj ->
case ds10_a5tj of _ {
[] -> ipv15_X5SU;
: y_a5to ys_a5tp -> GHC.Types.: (y_a5to w_s6YF) (go_a5ti ys_a5tp)
}; } in
case go_a5ti ipv13_X5R2 of x'_a5P6 { __DEFAULT ->
case GHC.Prim.writeMutVar# ww1_s6YM x'_a5P6 ipv14_X5SS
of s2#1_a5P7 { __DEFAULT ->
(# s2#1_a5P7, Haxl.Core.Monad.cacheRequest6 #)
}
}
}
}
}
}
} } in
let {
a2_s6lH
a2_s6lH =
\ w_s6YF _ w2_s6YH w3_s6YI ->
case w2_s6YH
of _
{ Haxl.Core.Monad.SchedState ww1_s6YL ww2_s6YM ww3_s6YN ww4_s6YO ->
$wa4_s6YQ w_s6YF ww1_s6YL ww2_s6YM ww3_s6YN ww4_s6YO w3_s6YI
} } in
```
I want `$wa4` to be inlined at its single occurrence in `a2`. I believe the reason it is not being inlined is that `a2` is a wrapper, but the situation seems silly because the wrapper isn't going away either, so we have a redundant closure being built (this is in my inner loop).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Optimisation bug","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I have a strange problem with a local function binding that is not being inlined. I've attached the repro code, build it like this:\r\n\r\n{{{\r\n$ ghc -O2 Haxl/Core/Monad.hs\r\n}}}\r\n\r\nThere are several modules, but the one with the problem is `Haxl/Core/Monad.hs`. In particular `Haxl.Core.Monad.$fApplicativeGenHaxl2`, which contains this fragment:\r\n\r\n{{{\r\n let {\r\n $wa4_s6YQ\r\n $wa4_s6YQ =\r\n \\ w_s6YF _ ww1_s6YM _ _ w1_s6YI ->\r\n case GHC.Prim.readMutVar# ipv7_X5Ne w1_s6YI\r\n of _ { (# ipv10_X5QO, ipv11_X5QQ #) ->\r\n case ipv11_X5QQ of _ {\r\n Haxl.Core.Monad.IVarFull a2_a3kK -> case lvl6_r7qi of wild3_00 { };\r\n Haxl.Core.Monad.IVarEmpty dt2_d4Vs ->\r\n case GHC.Prim.writeMutVar#\r\n ipv7_X5Ne (Haxl.Core.Monad.IVarFull w_s6YF) ipv10_X5QO\r\n of s2#_a5OR { __DEFAULT ->\r\n case GHC.Prim.readMutVar# dt2_d4Vs s2#_a5OR\r\n of _ { (# ipv12_X5R0, ipv13_X5R2 #) ->\r\n case GHC.Prim.readMutVar# ww1_s6YM ipv12_X5R0\r\n of _ { (# ipv14_X5SS, ipv15_X5SU #) ->\r\n letrec {\r\n go_a5ti\r\n go_a5ti =\r\n \\ ds10_a5tj ->\r\n case ds10_a5tj of _ {\r\n [] -> ipv15_X5SU;\r\n : y_a5to ys_a5tp -> GHC.Types.: (y_a5to w_s6YF) (go_a5ti ys_a5tp)\r\n }; } in\r\n case go_a5ti ipv13_X5R2 of x'_a5P6 { __DEFAULT ->\r\n case GHC.Prim.writeMutVar# ww1_s6YM x'_a5P6 ipv14_X5SS\r\n of s2#1_a5P7 { __DEFAULT ->\r\n (# s2#1_a5P7, Haxl.Core.Monad.cacheRequest6 #)\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n } } in\r\n let {\r\n a2_s6lH\r\n a2_s6lH =\r\n \\ w_s6YF _ w2_s6YH w3_s6YI ->\r\n case w2_s6YH\r\n of _\r\n { Haxl.Core.Monad.SchedState ww1_s6YL ww2_s6YM ww3_s6YN ww4_s6YO ->\r\n $wa4_s6YQ w_s6YF ww1_s6YL ww2_s6YM ww3_s6YN ww4_s6YO w3_s6YI\r\n } } in\r\n}}}\r\n\r\nI want `$wa4` to be inlined at its single occurrence in `a2`. I believe the reason it is not being inlined is that `a2` is a wrapper, but the situation seems silly because the wrapper isn't going away either, so we have a redundant closure being built (this is in my inner loop).","type_of_failure":"OtherFailure","blocking":[]} -->Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/9280GHCi crash: illegal text-relocation to _ in _ from _ in _ for architecture x8...2019-07-07T18:41:04ZMiëtek BakGHCi crash: illegal text-relocation to _ in _ from _ in _ for architecture x86_64; relocation R_X86_64_PC32 against undefined symbol _ can not be used when making a shared objectGiven a statically-linked Haskell object file, interactive GHCi 7.8.2 crashes.
```
$ cat >Foo.hs <<EOF
module Foo where
foo :: IO ()
foo = print "Foo"
EOF
```
On OS X:
```
$ ghc -Wall -c -o Foo.o Foo.hs
```
```
$ ghci -v Foo.o
GHCi,...Given a statically-linked Haskell object file, interactive GHCi 7.8.2 crashes.
```
$ cat >Foo.hs <<EOF
module Foo where
foo :: IO ()
foo = print "Foo"
EOF
```
On OS X:
```
$ ghc -Wall -c -o Foo.o Foo.hs
```
```
$ ghci -v Foo.o
GHCi, version 7.8.2: http://www.haskell.org/ghc/ :? for help
Glasgow Haskell Compiler, Version 7.8.2, stage 2 booted by GHC version 7.6.3
Using binary package database: /opt/ghc-7.8.2/lib/ghc-7.8.2/package.conf.d/package.cache
wired-in package ghc-prim mapped to ghc-prim-0.3.1.0-948744e1f99cc8bcc7c7d3ba60c7c2d8
wired-in package integer-gmp mapped to integer-gmp-0.5.1.0-dc47f6b546fc171f67a7f7d311684a99
wired-in package base mapped to base-4.7.0.0-a333addb6892f3cc2e6baa5ec782bd04
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.9.0.0-ed6ecfb467e6936688bb20f968f702e1
wired-in package dph-seq not found.
wired-in package dph-par not found.
Hsc static flags:
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
*** gcc:
/usr/bin/gcc -m64 -fno-stack-protector -DTABLES_NEXT_TO_CODE -L/opt/ghc-7.8.2/lib/ghc-7.8.2/base-4.7.0.0 --print-file-name libiconv.dylib
Loading package base ... linking ... done.
Loading object (static) Foo.o ... Created temporary directory: /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc41409_0
*** Linker:
/usr/bin/gcc -m64 -fno-stack-protector -DTABLES_NEXT_TO_CODE -m64 -dynamiclib -o /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc41409_0/ghc41409_1.dylib Foo.o -undefined dynamic_lookup -single_module -install_name '@rpath/ghc41409_1.dylib' -L/opt/ghc-7.8.2/lib/ghc-7.8.2/base-4.7.0.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/base-4.7.0.0 -L/opt/ghc-7.8.2/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -L/opt/ghc-7.8.2/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -L/opt/ghc-7.8.2/lib/ghc-7.8.2/rts-1.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/rts-1.0 -lHSbase-4.7.0.0-ghc7.8.2 -lHSinteger-gmp-0.5.1.0-ghc7.8.2 -lHSghc-prim-0.3.1.0-ghc7.8.2 -liconv
ld: illegal text-relocation to '_ghczmprim_GHCziCString_unpackCStringzh_closure' in /opt/ghc-7.8.2/lib/ghc-7.8.2/ghc-prim-0.3.1.0/libHSghc-prim-0.3.1.0-ghc7.8.2.dylib from '_sVK_info' in Foo.o for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
*** Deleting temp files:
Deleting: /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc41409_0/ghc41409_1.dylib
Warning: deleting non-existent /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc41409_0/ghc41409_1.dylib
*** Deleting temp dirs:
Deleting: /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc41409_0
```
On Linux, without `-fPIC`:
```
$ ghc -Wall -c -o Foo.o Foo.hs
```
```
ghci -v Foo.o
GHCi, version 7.8.2: http://www.haskell.org/ghc/ :? for help
Glasgow Haskell Compiler, Version 7.8.2, stage 2 booted by GHC version 7.6.3
Using binary package database: /app/.halcyon/ghc/lib/ghc-7.8.2/package.conf.d/package.cache
wired-in package ghc-prim mapped to ghc-prim-0.3.1.0-948744e1f99cc8bcc7c7d3ba60c7c2d8
wired-in package integer-gmp mapped to integer-gmp-0.5.1.0-dc47f6b546fc171f67a7f7d311684a99
wired-in package base mapped to base-4.7.0.0-018311399e3b6350d5be3a16b144df9b
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.9.0.0-dcc8c210fb02937e104bc1784d7b0f06
wired-in package dph-seq not found.
wired-in package dph-par not found.
Hsc static flags:
Loading package ghc-prim ... linking ... done.
*** gcc:
/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -L/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 --print-file-name libgmp.so
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading object (static) Foo.o ... Created temporary directory: /tmp/ghc7203_0
*** Linker:
/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -o /tmp/ghc7203_0/ghc7203_1.so Foo.o -shared -Wl,-Bsymbolic -Wl,-h,ghc7203_1.so -L/app/.halcyon/ghc/lib/ghc-7.8.2/base-4.7.0.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/base-4.7.0.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/rts-1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/rts-1.0 -lHSbase-4.7.0.0-ghc7.8.2 -lHSinteger-gmp-0.5.1.0-ghc7.8.2 -lHSghc-prim-0.3.1.0-ghc7.8.2 -lgmp '-Wl,--hash-size=31' -Wl,--reduce-memory-overheads
/usr/bin/ld: Foo.o: relocation R_X86_64_32S against `stg_bh_upd_frame_info' can not be used when making a shared object; recompile with -fPIC
Foo.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
*** Deleting temp files:
Deleting: /tmp/ghc7203_0/ghc7203_1.so
Warning: deleting non-existent /tmp/ghc7203_0/ghc7203_1.so
*** Deleting temp dirs:
Deleting: /tmp/ghc7203_0
```
On Linux, with `-fPIC`:
```
$ ghc -Wall -c -fPIC -o Foo.o Foo.hs
```
```
$ ghci -v Foo.o
GHCi, version 7.8.2: http://www.haskell.org/ghc/ :? for help
Glasgow Haskell Compiler, Version 7.8.2, stage 2 booted by GHC version 7.6.3
Using binary package database: /app/.halcyon/ghc/lib/ghc-7.8.2/package.conf.d/package.cache
wired-in package ghc-prim mapped to ghc-prim-0.3.1.0-948744e1f99cc8bcc7c7d3ba60c7c2d8
wired-in package integer-gmp mapped to integer-gmp-0.5.1.0-dc47f6b546fc171f67a7f7d311684a99
wired-in package base mapped to base-4.7.0.0-018311399e3b6350d5be3a16b144df9b
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.9.0.0-dcc8c210fb02937e104bc1784d7b0f06
wired-in package dph-seq not found.
wired-in package dph-par not found.
Hsc static flags:
Loading package ghc-prim ... linking ... done.
*** gcc:
/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -L/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 --print-file-name libgmp.so
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading object (static) Foo.o ... Created temporary directory: /tmp/ghc7223_0
*** Linker:
/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -o /tmp/ghc7223_0/ghc7223_1.so Foo.o -shared -Wl,-Bsymbolic -Wl,-h,ghc7223_1.so -L/app/.halcyon/ghc/lib/ghc-7.8.2/base-4.7.0.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/base-4.7.0.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/rts-1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/rts-1.0 -lHSbase-4.7.0.0-ghc7.8.2 -lHSinteger-gmp-0.5.1.0-ghc7.8.2 -lHSghc-prim-0.3.1.0-ghc7.8.2 -lgmp '-Wl,--hash-size=31' -Wl,--reduce-memory-overheads
/usr/bin/ld: Foo.o: relocation R_X86_64_PC32 against undefined symbol `ghczmprim_GHCziCString_unpackCStringzh_closure' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status
*** Deleting temp files:
Deleting: /tmp/ghc7223_0/ghc7223_1.so
Warning: deleting non-existent /tmp/ghc7223_0/ghc7223_1.so
*** Deleting temp dirs:
Deleting: /tmp/ghc7223_0
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHCi crash:","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":["crash,","dynamic","linking"],"differentials":[],"test_case":"","architecture":"","cc":["hvr"],"type":"Bug","description":"Given a statically-linked Haskell object file, interactive GHCi 7.8.2 crashes.\r\n\r\n{{{\r\n$ cat >Foo.hs <<EOF\r\nmodule Foo where\r\n\r\nfoo :: IO ()\r\nfoo = print \"Foo\"\r\nEOF\r\n}}}\r\n\r\n\r\nOn OS X:\r\n\r\n{{{\r\n$ ghc -Wall -c -o Foo.o Foo.hs\r\n}}}\r\n{{{\r\n$ ghci -v Foo.o\r\nGHCi, version 7.8.2: http://www.haskell.org/ghc/ :? for help\r\nGlasgow Haskell Compiler, Version 7.8.2, stage 2 booted by GHC version 7.6.3\r\nUsing binary package database: /opt/ghc-7.8.2/lib/ghc-7.8.2/package.conf.d/package.cache\r\nwired-in package ghc-prim mapped to ghc-prim-0.3.1.0-948744e1f99cc8bcc7c7d3ba60c7c2d8\r\nwired-in package integer-gmp mapped to integer-gmp-0.5.1.0-dc47f6b546fc171f67a7f7d311684a99\r\nwired-in package base mapped to base-4.7.0.0-a333addb6892f3cc2e6baa5ec782bd04\r\nwired-in package rts mapped to builtin_rts\r\nwired-in package template-haskell mapped to template-haskell-2.9.0.0-ed6ecfb467e6936688bb20f968f702e1\r\nwired-in package dph-seq not found.\r\nwired-in package dph-par not found.\r\nHsc static flags: \r\nLoading package ghc-prim ... linking ... done.\r\nLoading package integer-gmp ... linking ... done.\r\n*** gcc:\r\n/usr/bin/gcc -m64 -fno-stack-protector -DTABLES_NEXT_TO_CODE -L/opt/ghc-7.8.2/lib/ghc-7.8.2/base-4.7.0.0 --print-file-name libiconv.dylib\r\nLoading package base ... linking ... done.\r\nLoading object (static) Foo.o ... Created temporary directory: /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc41409_0\r\n*** Linker:\r\n/usr/bin/gcc -m64 -fno-stack-protector -DTABLES_NEXT_TO_CODE -m64 -dynamiclib -o /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc41409_0/ghc41409_1.dylib Foo.o -undefined dynamic_lookup -single_module -install_name '@rpath/ghc41409_1.dylib' -L/opt/ghc-7.8.2/lib/ghc-7.8.2/base-4.7.0.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/base-4.7.0.0 -L/opt/ghc-7.8.2/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -L/opt/ghc-7.8.2/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -L/opt/ghc-7.8.2/lib/ghc-7.8.2/rts-1.0 -Wl,-rpath -Wl,/opt/ghc-7.8.2/lib/ghc-7.8.2/rts-1.0 -lHSbase-4.7.0.0-ghc7.8.2 -lHSinteger-gmp-0.5.1.0-ghc7.8.2 -lHSghc-prim-0.3.1.0-ghc7.8.2 -liconv\r\nld: illegal text-relocation to '_ghczmprim_GHCziCString_unpackCStringzh_closure' in /opt/ghc-7.8.2/lib/ghc-7.8.2/ghc-prim-0.3.1.0/libHSghc-prim-0.3.1.0-ghc7.8.2.dylib from '_sVK_info' in Foo.o for architecture x86_64\r\nclang: error: linker command failed with exit code 1 (use -v to see invocation)\r\n*** Deleting temp files:\r\nDeleting: /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc41409_0/ghc41409_1.dylib\r\nWarning: deleting non-existent /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc41409_0/ghc41409_1.dylib\r\n*** Deleting temp dirs:\r\nDeleting: /var/folders/26/0tzj1txn0vb_0061l4z4rsmr0000gn/T/ghc41409_0\r\n}}}\r\n\r\n\r\nOn Linux, without `-fPIC`:\r\n\r\n{{{\r\n$ ghc -Wall -c -o Foo.o Foo.hs\r\n}}}\r\n{{{\r\nghci -v Foo.o\r\nGHCi, version 7.8.2: http://www.haskell.org/ghc/ :? for help\r\nGlasgow Haskell Compiler, Version 7.8.2, stage 2 booted by GHC version 7.6.3\r\nUsing binary package database: /app/.halcyon/ghc/lib/ghc-7.8.2/package.conf.d/package.cache\r\nwired-in package ghc-prim mapped to ghc-prim-0.3.1.0-948744e1f99cc8bcc7c7d3ba60c7c2d8\r\nwired-in package integer-gmp mapped to integer-gmp-0.5.1.0-dc47f6b546fc171f67a7f7d311684a99\r\nwired-in package base mapped to base-4.7.0.0-018311399e3b6350d5be3a16b144df9b\r\nwired-in package rts mapped to builtin_rts\r\nwired-in package template-haskell mapped to template-haskell-2.9.0.0-dcc8c210fb02937e104bc1784d7b0f06\r\nwired-in package dph-seq not found.\r\nwired-in package dph-par not found.\r\nHsc static flags: \r\nLoading package ghc-prim ... linking ... done.\r\n*** gcc:\r\n/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -L/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 --print-file-name libgmp.so\r\nLoading package integer-gmp ... linking ... done.\r\nLoading package base ... linking ... done.\r\nLoading object (static) Foo.o ... Created temporary directory: /tmp/ghc7203_0\r\n*** Linker:\r\n/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -o /tmp/ghc7203_0/ghc7203_1.so Foo.o -shared -Wl,-Bsymbolic -Wl,-h,ghc7203_1.so -L/app/.halcyon/ghc/lib/ghc-7.8.2/base-4.7.0.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/base-4.7.0.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/rts-1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/rts-1.0 -lHSbase-4.7.0.0-ghc7.8.2 -lHSinteger-gmp-0.5.1.0-ghc7.8.2 -lHSghc-prim-0.3.1.0-ghc7.8.2 -lgmp '-Wl,--hash-size=31' -Wl,--reduce-memory-overheads\r\n/usr/bin/ld: Foo.o: relocation R_X86_64_32S against `stg_bh_upd_frame_info' can not be used when making a shared object; recompile with -fPIC\r\nFoo.o: could not read symbols: Bad value\r\ncollect2: ld returned 1 exit status\r\n*** Deleting temp files:\r\nDeleting: /tmp/ghc7203_0/ghc7203_1.so\r\nWarning: deleting non-existent /tmp/ghc7203_0/ghc7203_1.so\r\n*** Deleting temp dirs:\r\nDeleting: /tmp/ghc7203_0\r\n}}}\r\n\r\n\r\nOn Linux, with `-fPIC`:\r\n\r\n{{{\r\n$ ghc -Wall -c -fPIC -o Foo.o Foo.hs\r\n}}}\r\n{{{\r\n$ ghci -v Foo.o\r\nGHCi, version 7.8.2: http://www.haskell.org/ghc/ :? for help\r\nGlasgow Haskell Compiler, Version 7.8.2, stage 2 booted by GHC version 7.6.3\r\nUsing binary package database: /app/.halcyon/ghc/lib/ghc-7.8.2/package.conf.d/package.cache\r\nwired-in package ghc-prim mapped to ghc-prim-0.3.1.0-948744e1f99cc8bcc7c7d3ba60c7c2d8\r\nwired-in package integer-gmp mapped to integer-gmp-0.5.1.0-dc47f6b546fc171f67a7f7d311684a99\r\nwired-in package base mapped to base-4.7.0.0-018311399e3b6350d5be3a16b144df9b\r\nwired-in package rts mapped to builtin_rts\r\nwired-in package template-haskell mapped to template-haskell-2.9.0.0-dcc8c210fb02937e104bc1784d7b0f06\r\nwired-in package dph-seq not found.\r\nwired-in package dph-par not found.\r\nHsc static flags: \r\nLoading package ghc-prim ... linking ... done.\r\n*** gcc:\r\n/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -L/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 --print-file-name libgmp.so\r\nLoading package integer-gmp ... linking ... done.\r\nLoading package base ... linking ... done.\r\nLoading object (static) Foo.o ... Created temporary directory: /tmp/ghc7223_0\r\n*** Linker:\r\n/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -o /tmp/ghc7223_0/ghc7223_1.so Foo.o -shared -Wl,-Bsymbolic -Wl,-h,ghc7223_1.so -L/app/.halcyon/ghc/lib/ghc-7.8.2/base-4.7.0.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/base-4.7.0.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/integer-gmp-0.5.1.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/ghc-prim-0.3.1.0 -L/app/.halcyon/ghc/lib/ghc-7.8.2/rts-1.0 -Wl,-rpath -Wl,/app/.halcyon/ghc/lib/ghc-7.8.2/rts-1.0 -lHSbase-4.7.0.0-ghc7.8.2 -lHSinteger-gmp-0.5.1.0-ghc7.8.2 -lHSghc-prim-0.3.1.0-ghc7.8.2 -lgmp '-Wl,--hash-size=31' -Wl,--reduce-memory-overheads\r\n/usr/bin/ld: Foo.o: relocation R_X86_64_PC32 against undefined symbol `ghczmprim_GHCziCString_unpackCStringzh_closure' can not be used when making a shared object; recompile with -fPIC\r\n/usr/bin/ld: final link failed: Bad value\r\ncollect2: ld returned 1 exit status\r\n*** Deleting temp files:\r\nDeleting: /tmp/ghc7223_0/ghc7223_1.so\r\nWarning: deleting non-existent /tmp/ghc7223_0/ghc7223_1.so\r\n*** Deleting temp dirs:\r\nDeleting: /tmp/ghc7223_0\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9289add anyToAddr# :: (#a#)-> Addr# primop (inverse of addrToAny#)2019-07-07T18:41:02ZCarter Schonwaldadd anyToAddr# :: (#a#)-> Addr# primop (inverse of addrToAny#)I was talking with Reid Barton, and he pointed out that having a primop with type
```
anyToAddr# :: (#a#)-> Addr#
```
would help with a lot of performance hacking.
One use case would be running prefetch on lifted values without evalua...I was talking with Reid Barton, and he pointed out that having a primop with type
```
anyToAddr# :: (#a#)-> Addr#
```
would help with a lot of performance hacking.
One use case would be running prefetch on lifted values without evaluating them.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"add anyToAddr# :: (#a#)-> Addr# primop (inverse of addrToAny#)","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"7.10.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"I was talking with Reid Barton, and he pointed out that having a primop with type \r\n{{{\r\nanyToAddr# :: (#a#)-> Addr#\r\n}}}\r\n\r\nwould help with a lot of performance hacking.\r\n\r\nOne use case would be running prefetch on lifted values without evaluating them.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9292Race condition when multiple threads wait for a process2019-07-07T18:41:01ZMichael Snoymanmichael@snoyman.comRace condition when multiple threads wait for a processConsider the following code:
```
import System.Process
import Control.Concurrent.Async
main :: IO ()
main = do
(_, _, _, ph) <- createProcess $ shell "sleep 1"
let helper i = do
ec <- waitForProcess ph
p...Consider the following code:
```
import System.Process
import Control.Concurrent.Async
main :: IO ()
main = do
(_, _, _, ph) <- createProcess $ shell "sleep 1"
let helper i = do
ec <- waitForProcess ph
print (i :: Int, ec)
((), ()) <- concurrently (helper 1) (helper 2)
return ()
```
If I compile with the single threaded runtime, I get the output
```
(2,ExitSuccess)
(1,ExitSuccess)
```
But when compiling with the multithreaded runtime, I get:
```
bin: waitForProcess: does not exist (No child processes)
```
If you need to wait for a process from multiple threads, you can do so now by having a dedicated wait thread which writes to an MVar or TMVar, but the current default behavior can be surprising.
I discussed this in a [blog post](http://www.yesodweb.com/blog/2014/07/rfc-new-data-conduit-process), and there was some [conversation on Reddit](http://www.reddit.com/r/haskell/comments/2abmwu/rfc_new_dataconduitprocess/cithh69).
At the least, I think we need better documentation, but if there's a better solution, that would be best.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/process |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Race condition when multiple threads wait for a process","status":"New","operating_system":"","component":"libraries/process","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider the following code:\r\n\r\n\r\n{{{\r\nimport System.Process\r\nimport Control.Concurrent.Async\r\n\r\nmain :: IO ()\r\nmain = do\r\n (_, _, _, ph) <- createProcess $ shell \"sleep 1\"\r\n let helper i = do\r\n ec <- waitForProcess ph\r\n print (i :: Int, ec)\r\n ((), ()) <- concurrently (helper 1) (helper 2)\r\n return ()\r\n}}}\r\n\r\nIf I compile with the single threaded runtime, I get the output\r\n\r\n{{{\r\n(2,ExitSuccess)\r\n(1,ExitSuccess)\r\n}}}\r\n\r\nBut when compiling with the multithreaded runtime, I get:\r\n\r\n{{{\r\nbin: waitForProcess: does not exist (No child processes)\r\n}}}\r\n\r\nIf you need to wait for a process from multiple threads, you can do so now by having a dedicated wait thread which writes to an MVar or TMVar, but the current default behavior can be surprising.\r\n\r\nI discussed this in a [http://www.yesodweb.com/blog/2014/07/rfc-new-data-conduit-process blog post], and there was some [http://www.reddit.com/r/haskell/comments/2abmwu/rfc_new_dataconduitprocess/cithh69 conversation on Reddit].\r\n\r\nAt the least, I think we need better documentation, but if there's a better solution, that would be best.","type_of_failure":"OtherFailure","blocking":[]} -->Edward KmettEdward Kmetthttps://gitlab.haskell.org/ghc/ghc/-/issues/9307LLVM vs NCG: floating point numbers close to zero have different sign2019-07-07T18:40:56Zjrp2014LLVM vs NCG: floating point numbers close to zero have different signCompiling HEAD with perf-llvm, (3.4.2) and running the nofib suite fails at the wave4main case. It is not clear to me whether wave4main should always produce the same output (and so the test fails because it does not do so) or whether th...Compiling HEAD with perf-llvm, (3.4.2) and running the nofib suite fails at the wave4main case. It is not clear to me whether wave4main should always produce the same output (and so the test fails because it does not do so) or whether the numbers generated depend on some feature of the build settings, or OS.
```
HC = /Users/xxx/Projects/ghc/inplace/bin/ghc-stage2
HC_OPTS = -O2 -Rghc-timing -H32m -hisuf hi -cpp -fglasgow-exts -rtsopts
RUNTEST_OPTS = -ghc-timing
==nofib== wave4main: size of wave4main follows...
__TEXT __DATA __OBJC others dec hex
4091904 450560 0 4295947176 4300489640 1005443a8
==nofib== wave4main: time to run wave4main follows...
../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000;
real 0m0.217s
user 0m0.191s
sys 0m0.011s
././wave4main 4000 < /dev/null
expected stdout not matched by reality
--- wave4main.stdout 2014-07-08 20:57:14.000000000 +0100
+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest16932.1 2014-07-13 13:43:22.000000000 +0100
@@ -1 +1 @@
-69923/1465
+69096/1465
real 0m0.197s
user 0m0.186s
sys 0m0.008s
././wave4main 4000 < /dev/null
expected stdout not matched by reality
--- wave4main.stdout 2014-07-08 20:57:14.000000000 +0100
+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest16961.1 2014-07-13 13:43:22.000000000 +0100
@@ -1 +1 @@
-69923/1465
+69096/1465
real 0m0.201s
user 0m0.189s
sys 0m0.009s
././wave4main 4000 < /dev/null
expected stdout not matched by reality
--- wave4main.stdout 2014-07-08 20:57:14.000000000 +0100
+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17011.1 2014-07-13 13:43:22.000000000 +0100
@@ -1 +1 @@
-69923/1465
+69096/1465
real 0m0.201s
user 0m0.190s
sys 0m0.008s
././wave4main 4000 < /dev/null
expected stdout not matched by reality
--- wave4main.stdout 2014-07-08 20:57:14.000000000 +0100
+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17051.1 2014-07-13 13:43:23.000000000 +0100
@@ -1 +1 @@
-69923/1465
+69096/1465
real 0m0.200s
user 0m0.189s
sys 0m0.009s
././wave4main 4000 < /dev/null
expected stdout not matched by reality
--- wave4main.stdout 2014-07-08 20:57:14.000000000 +0100
+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17080.1 2014-07-13 13:43:23.000000000 +0100
@@ -1 +1 @@
-69923/1465
+69096/1465
make: *** [runtests] Error 1
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------------- |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | NoFib benchmark suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"wave4main in nofib fails","status":"New","operating_system":"","component":"NoFib benchmark suite","related":[],"milestone":"7.10.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["wave4main"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"\r\nCompiling HEAD with perf-llvm, (3.4.2) and running the nofib suite fails at the wave4main case. It is not clear to me whether wave4main should always produce the same output (and so the test fails because it does not do so) or whether the numbers generated depend on some feature of the build settings, or OS.\r\n\r\n\r\n{{{\r\nHC = /Users/xxx/Projects/ghc/inplace/bin/ghc-stage2\r\nHC_OPTS = -O2 -Rghc-timing -H32m -hisuf hi -cpp -fglasgow-exts -rtsopts\r\nRUNTEST_OPTS = -ghc-timing\r\n==nofib== wave4main: size of wave4main follows...\r\n__TEXT\t__DATA\t__OBJC\tothers\tdec\thex\r\n4091904\t450560\t0\t4295947176\t4300489640\t1005443a8\r\n==nofib== wave4main: time to run wave4main follows...\r\n../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000;\r\n\r\nreal\t0m0.217s\r\nuser\t0m0.191s\r\nsys\t0m0.011s\r\n././wave4main 4000 < /dev/null\r\nexpected stdout not matched by reality\r\n--- wave4main.stdout\t2014-07-08 20:57:14.000000000 +0100\r\n+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest16932.1\t2014-07-13 13:43:22.000000000 +0100\r\n@@ -1 +1 @@\r\n-69923/1465\r\n+69096/1465\r\n\r\nreal\t0m0.197s\r\nuser\t0m0.186s\r\nsys\t0m0.008s\r\n././wave4main 4000 < /dev/null\r\nexpected stdout not matched by reality\r\n--- wave4main.stdout\t2014-07-08 20:57:14.000000000 +0100\r\n+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest16961.1\t2014-07-13 13:43:22.000000000 +0100\r\n@@ -1 +1 @@\r\n-69923/1465\r\n+69096/1465\r\n\r\nreal\t0m0.201s\r\nuser\t0m0.189s\r\nsys\t0m0.009s\r\n././wave4main 4000 < /dev/null\r\nexpected stdout not matched by reality\r\n--- wave4main.stdout\t2014-07-08 20:57:14.000000000 +0100\r\n+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17011.1\t2014-07-13 13:43:22.000000000 +0100\r\n@@ -1 +1 @@\r\n-69923/1465\r\n+69096/1465\r\n\r\nreal\t0m0.201s\r\nuser\t0m0.190s\r\nsys\t0m0.008s\r\n././wave4main 4000 < /dev/null\r\nexpected stdout not matched by reality\r\n--- wave4main.stdout\t2014-07-08 20:57:14.000000000 +0100\r\n+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17051.1\t2014-07-13 13:43:23.000000000 +0100\r\n@@ -1 +1 @@\r\n-69923/1465\r\n+69096/1465\r\n\r\nreal\t0m0.200s\r\nuser\t0m0.189s\r\nsys\t0m0.009s\r\n././wave4main 4000 < /dev/null\r\nexpected stdout not matched by reality\r\n--- wave4main.stdout\t2014-07-08 20:57:14.000000000 +0100\r\n+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17080.1\t2014-07-13 13:43:23.000000000 +0100\r\n@@ -1 +1 @@\r\n-69923/1465\r\n+69096/1465\r\nmake: *** [runtests] Error 1\r\n\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9319nofib-analyze doesn’t provide per-benchmark compile time/alloc numbers2019-07-07T18:40:54ZJoachim Breitnermail@joachim-breitner.denofib-analyze doesn’t provide per-benchmark compile time/alloc numbersThe compile time and allocation numbers calculated by nofib are only available per module. While this is useful to find the cause of problems, it would be nice if these numbers were also accumulated for each benchmark, for easy of genera...The compile time and allocation numbers calculated by nofib are only available per module. While this is useful to find the cause of problems, it would be nice if these numbers were also accumulated for each benchmark, for easy of general analysis and uniformity, especially with automated monitoring of benchmark numbers.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------------- |
| Version | 7.8.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | NoFib benchmark suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"nofib-analyze doesn’t provide per-benchmark compile time/alloc numbers","status":"New","operating_system":"","component":"NoFib benchmark suite","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"The compile time and allocation numbers calculated by nofib are only available per module. While this is useful to find the cause of problems, it would be nice if these numbers were also accumulated for each benchmark, for easy of general analysis and uniformity, especially with automated monitoring of benchmark numbers.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9320Inlining regression/strangeness in 7.82020-10-07T00:33:49ZdolioInlining regression/strangeness in 7.8A couple days ago, it was reported to me that vector-algorithms had a significant performance regression (\~20x) on GHC 7.8.2. The problem stems from a lack of inlining and specialization of some of the functions that were previously han...A couple days ago, it was reported to me that vector-algorithms had a significant performance regression (\~20x) on GHC 7.8.2. The problem stems from a lack of inlining and specialization of some of the functions that were previously handled in 7.6 and earlier. The following is a reduced test case (the vector and primitive packages are required):
```
module A (test) where
import Control.Monad.ST
import Control.Monad
import Control.Monad.Primitive
import Data.Vector.Generic.Mutable as U
test :: (PrimMonad m, MVector v a, Num a) => Int -> v (PrimState m) a -> m a
-- test :: (MVector v a, Num a) => Int -> v s a -> ST s a
test 0 v = liftM (+1) $ unsafeRead v 0
test n v = do
long1 v
test (n-1) v
{-# INLINABLE test #-}
long1, long2, long3, long4 :: (PrimMonad m, MVector v a) => v (PrimState m) a -> m ()
long1 v = long2 v >> long2 v >> long2 v >> long2 v
long2 v = long3 v >> long3 v >> long3 v >> long3 v
long3 v = long4 v >> long4 v >> long4 v >> long4 v
long4 v = unsafeRead v 0 >>= unsafeWrite v 0
{-# INLINE long1 #-}
{-# INLINE long2 #-}
{-# INLINE long3 #-}
{-# INLINE long4 #-}
```
```
module Main (main) where
import Control.Monad.ST
import Data.Vector.Unboxed.Mutable as U hiding (read)
import System.Environment
import Unsafe.Coerce
import GHC.Prim
import A
test0 :: Int -> MVector s Int -> ST s Int
test0 n v = test n v
{-# NOINLINE test0 #-}
test1' :: Int -> MVector Any Int -> ST Any Int
test1' n v = test n v
{-# NOINLINE test1 #-}
test1 :: Int -> MVector a Int -> ST a Int
test1 = unsafeCoerce test1'
main = getArgs >>= \(n:b:_) ->
print $ runST $ do
v <- new 1
write v 0 0
(if read b then test0 else test1) (read n) v
```
Module `A` exports a single function, `test`. This function is engineered to be quite large, by inlining several other functions into it, and it is itself marked INLINABLE. Then the `Main` module uses this function in two different ways:
- `test0` uses `test` at a type that is compatible with `runST`
- `test1'` uses `test` at a completely monomorphic type, which is then coerced to a `runST` compatible type in `test1`
On 7.6 I believe (though have not checked) that there will be little or no performance difference between `test0` and `test1`. However, on 7.8.2 (and, I have been assured, 7.8.3), there is a massive speed pentalty for `test0`; about 70x on my machine. This seems to be due to no inining or specialization for its use of `test`, which can be seen from `-ddump-simpl`.
However, if one changes the type of `test` in `A` to be specific to `ST s` rather than using `PrimMonad`, there is no performance difference, even on 7.8.2. So, the choice to inline and specialize seems to hinge on the instantiation of all the class constraints to monomorphic types containing no variables, rather than just types that resolve all overloading. I myself did not notice this problem, because my benchmark suite uses `IO`, which is a concrete instantiation of the type, and doesn't exhibit this problem.
I have temporarily 'fixed' vector-algorithms by moving back to `INLINE` pragmas, but `INLINABLE` is actually preferable in that case, because it generates faster code than `INLINE` when the optimizations actually fire. My test case here does not illustrate that well, though.
Is it safe to assume that this was not an intentional change? It's a rather weird rule (to me) if it was.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Inlining regression/strangeness in 7.8","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"A couple days ago, it was reported to me that vector-algorithms had a significant performance regression (~20x) on GHC 7.8.2. The problem stems from a lack of inlining and specialization of some of the functions that were previously handled in 7.6 and earlier. The following is a reduced test case (the vector and primitive packages are required):\r\n\r\n{{{\r\nmodule A (test) where\r\n\r\nimport Control.Monad.ST\r\nimport Control.Monad\r\nimport Control.Monad.Primitive\r\nimport Data.Vector.Generic.Mutable as U\r\n\r\ntest :: (PrimMonad m, MVector v a, Num a) => Int -> v (PrimState m) a -> m a\r\n-- test :: (MVector v a, Num a) => Int -> v s a -> ST s a\r\ntest 0 v = liftM (+1) $ unsafeRead v 0\r\ntest n v = do\r\n long1 v\r\n test (n-1) v\r\n{-# INLINABLE test #-}\r\n\r\nlong1, long2, long3, long4 :: (PrimMonad m, MVector v a) => v (PrimState m) a -> m ()\r\n\r\nlong1 v = long2 v >> long2 v >> long2 v >> long2 v\r\nlong2 v = long3 v >> long3 v >> long3 v >> long3 v\r\nlong3 v = long4 v >> long4 v >> long4 v >> long4 v\r\nlong4 v = unsafeRead v 0 >>= unsafeWrite v 0\r\n\r\n{-# INLINE long1 #-}\r\n{-# INLINE long2 #-}\r\n{-# INLINE long3 #-}\r\n{-# INLINE long4 #-}\r\n}}}\r\n\r\n{{{\r\nmodule Main (main) where\r\n\r\nimport Control.Monad.ST\r\nimport Data.Vector.Unboxed.Mutable as U hiding (read)\r\nimport System.Environment\r\nimport Unsafe.Coerce\r\nimport GHC.Prim\r\n\r\nimport A\r\n\r\ntest0 :: Int -> MVector s Int -> ST s Int\r\ntest0 n v = test n v\r\n{-# NOINLINE test0 #-}\r\n\r\ntest1' :: Int -> MVector Any Int -> ST Any Int\r\ntest1' n v = test n v\r\n{-# NOINLINE test1 #-}\r\n\r\ntest1 :: Int -> MVector a Int -> ST a Int\r\ntest1 = unsafeCoerce test1'\r\n\r\nmain = getArgs >>= \\(n:b:_) ->\r\n print $ runST $ do\r\n v <- new 1\r\n write v 0 0\r\n (if read b then test0 else test1) (read n) v\r\n}}}\r\n\r\nModule `A` exports a single function, `test`. This function is engineered to be quite large, by inlining several other functions into it, and it is itself marked INLINABLE. Then the `Main` module uses this function in two different ways:\r\n\r\n* `test0` uses `test` at a type that is compatible with `runST`\r\n* `test1'` uses `test` at a completely monomorphic type, which is then coerced to a `runST` compatible type in `test1`\r\n\r\nOn 7.6 I believe (though have not checked) that there will be little or no performance difference between `test0` and `test1`. However, on 7.8.2 (and, I have been assured, 7.8.3), there is a massive speed pentalty for `test0`; about 70x on my machine. This seems to be due to no inining or specialization for its use of `test`, which can be seen from `-ddump-simpl`.\r\n\r\nHowever, if one changes the type of `test` in `A` to be specific to `ST s` rather than using `PrimMonad`, there is no performance difference, even on 7.8.2. So, the choice to inline and specialize seems to hinge on the instantiation of all the class constraints to monomorphic types containing no variables, rather than just types that resolve all overloading. I myself did not notice this problem, because my benchmark suite uses `IO`, which is a concrete instantiation of the type, and doesn't exhibit this problem.\r\n\r\nI have temporarily 'fixed' vector-algorithms by moving back to `INLINE` pragmas, but `INLINABLE` is actually preferable in that case, because it generates faster code than `INLINE` when the optimizations actually fire. My test case here does not illustrate that well, though.\r\n\r\nIs it safe to assume that this was not an intentional change? It's a rather weird rule (to me) if it was.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9321Support for waiting on multiple MVars2019-07-07T18:40:54ZschylerSupport for waiting on multiple MVarsA lot of code in servers uses MVars because they seem to have more desirable scalability characteristics than STM. Unfortunately, unlike STM which is composable (i.e. `readTChan chan1 <|> readTChan chan2`), `MVar`s often require extra in...A lot of code in servers uses MVars because they seem to have more desirable scalability characteristics than STM. Unfortunately, unlike STM which is composable (i.e. `readTChan chan1 <|> readTChan chan2`), `MVar`s often require extra inefficient intermediate steps to funnel many-to-one.
A common thing for people to do when they need to funnel N `MVar`s into one is to create 1 `MVar` and N forks where each fork attempts to read from its associated `MVar` and then writes it into the one `MVar` where another fork is waiting to process the data.
This is such a waste; it produces more forks and another `MVar` where contention can occur.
In some ways it would be better if the internal representation of an `MVar` had a pointer to the "next `MVar`" so that we could use a function like `eitherMVar` to merge two (or more) `MVar`s together into one which can be waited on and yield values from any of the containing `MVar`s.
(I believe) the runtime would need to provide appropriate support in the scheduler so that the list is traversed instead of only the single `MVar` checked. The overhead for code which does not use this feature would probably be only 1 branch, which is acceptable.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonmar |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Support for waiting on multiple MVars","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonmar"},"version":"7.8.3","keywords":["mvar"],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"FeatureRequest","description":"A lot of code in servers uses MVars because they seem to have more desirable scalability characteristics than STM. Unfortunately, unlike STM which is composable (i.e. `readTChan chan1 <|> readTChan chan2`), `MVar`s often require extra inefficient intermediate steps to funnel many-to-one.\r\n\r\nA common thing for people to do when they need to funnel N `MVar`s into one is to create 1 `MVar` and N forks where each fork attempts to read from its associated `MVar` and then writes it into the one `MVar` where another fork is waiting to process the data.\r\n\r\nThis is such a waste; it produces more forks and another `MVar` where contention can occur.\r\n\r\nIn some ways it would be better if the internal representation of an `MVar` had a pointer to the \"next `MVar`\" so that we could use a function like `eitherMVar` to merge two (or more) `MVar`s together into one which can be waited on and yield values from any of the containing `MVar`s.\r\n\r\n(I believe) the runtime would need to provide appropriate support in the scheduler so that the list is traversed instead of only the single `MVar` checked. The overhead for code which does not use this feature would probably be only 1 branch, which is acceptable.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/9328MINIMAL pragma should supprt negation2019-07-07T18:40:52Zlennart@augustsson.netMINIMAL pragma should supprt negationConsider this class declaration
```
class Conv a where
to :: Integer -> a
from :: a -> Integer
default to :: (Generic a) => Integer -> a
to i = ...
default from :: (Generic a) => a -> Integer
from a = ...
```
Th...Consider this class declaration
```
class Conv a where
to :: Integer -> a
from :: a -> Integer
default to :: (Generic a) => Integer -> a
to i = ...
default from :: (Generic a) => a -> Integer
from a = ...
```
The class provides default methods for the two methods using generics. An instance declaration for this type is likely to want to use the default for both methods or for none. So I'd like a MINIMAL pragma that can express this. E.g.
```
{-# MINIMAL (to, from) | (!to, !from) #-}
```
I've used ! for negation (following the lead set by the MINIMAL pragma using a non-Haskell OR operator), so this says: either implement 'to' and 'from' or don't implement neither 'to' nor 'from'.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"MINIMAL pragma should supprt negation","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Consider this class declaration\r\n{{{\r\nclass Conv a where\r\n to :: Integer -> a\r\n from :: a -> Integer\r\n default to :: (Generic a) => Integer -> a\r\n to i = ...\r\n default from :: (Generic a) => a -> Integer\r\n from a = ...\r\n}}}\r\nThe class provides default methods for the two methods using generics. An instance declaration for this type is likely to want to use the default for both methods or for none. So I'd like a MINIMAL pragma that can express this. E.g.\r\n{{{\r\n {-# MINIMAL (to, from) | (!to, !from) #-}\r\n}}}\r\nI've used ! for negation (following the lead set by the MINIMAL pragma using a non-Haskell OR operator), so this says: either implement 'to' and 'from' or don't implement neither 'to' nor 'from'.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9334Implement "instance chains"2019-07-07T18:40:51ZIavor S. DiatchkiImplement "instance chains"It would be useful to implement a version of "instance chains" \[1\] in GHC, which would eliminate the need for OVERLAPPING_INSTANCES in most (all practcial?) programs.
The idea is that programmers can explicitly group and order instanc...It would be useful to implement a version of "instance chains" \[1\] in GHC, which would eliminate the need for OVERLAPPING_INSTANCES in most (all practcial?) programs.
The idea is that programmers can explicitly group and order instances into an "instance chain". For example:
```
instance (Monad m) => StateM (StateT s m) s where ...
else (MonadTrans t, StateM m s) => StateM (t m) s where ...
```
When GHC searches for instances, the instances in a chain are considered together and in order, starting with the first one:
1. If the goal matches the current instance's head, then this instance is selected and the rest are ignored, as if they were not there;
1. If the goal does not match the current instance's head, AND it does not unify with the current instance's head, then we skip the instance and proceed to the next member of the chain;
1. If the goal does not match the current instance's head, but it does unify with it, then we cannot use this chain to solve the goal.
In summary: earlier instances in a chain "hide" later instances, and later instances can be reached only if we are sure that none of the previous instance will match.
\[1\] http://web.cecs.pdx.edu/\~mpj/pubs/instancechains.pdf
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.9 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Implement \"instance chains\"","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"diatchki"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"It would be useful to implement a version of \"instance chains\" [1] in GHC, which would eliminate the need for OVERLAPPING_INSTANCES in most (all practcial?) programs.\r\n\r\nThe idea is that programmers can explicitly group and order instances into an \"instance chain\". For example:\r\n{{{\r\ninstance (Monad m) => StateM (StateT s m) s where ...\r\nelse (MonadTrans t, StateM m s) => StateM (t m) s where ... \r\n}}}\r\n\r\nWhen GHC searches for instances, the instances in a chain are considered together and in order, starting with the first one:\r\n\r\n 1. If the goal matches the current instance's head, then this instance is selected and the rest are ignored, as if they were not there;\r\n\r\n 2. If the goal does not match the current instance's head, AND it does not unify with the current instance's head, then we skip the instance and proceed to the next member of the chain;\r\n\r\n 3. If the goal does not match the current instance's head, but it does unify with it, then we cannot use this chain to solve the goal.\r\n\r\nIn summary: earlier instances in a chain \"hide\" later instances, and later instances can be reached only if we are sure that none of the previous instance will match.\r\n\r\n\r\n[1] http://web.cecs.pdx.edu/~mpj/pubs/instancechains.pdf","type_of_failure":"OtherFailure","blocking":[]} -->Iavor S. DiatchkiIavor S. Diatchkihttps://gitlab.haskell.org/ghc/ghc/-/issues/9342Branchless arithmetic operations2020-10-27T13:18:50ZHerbert Valerio Riedelhvr@gnu.orgBranchless arithmetic operationsWhile working on #9281 I noticed sub-optimal code generation for common arithmetic operations on `Int`. Below are some examples of code generation, where the branchless versions may be desirable on modern CPUs:
# `abs`
```hs
-- base ve...While working on #9281 I noticed sub-optimal code generation for common arithmetic operations on `Int`. Below are some examples of code generation, where the branchless versions may be desirable on modern CPUs:
# `abs`
```hs
-- base version
absI# :: Int# -> Int#
absI# i# = i'#
where
!(I# i'#) = abs (I# i#)
-- optimized version
optAbsI# :: Int# -> Int#
optAbsI# i# = (i# `xorI#` nsign) -# nsign
where
-- nsign = i# <# 0#
nsign = uncheckedIShiftRA# i# (WORD_SIZE_IN_BITS# -# 1#)
```
results in
```asm
absI#_info:
_c1To:
testq %r14,%r14
jge _c1Tx
_c1Ty:
movq %r14,%rbx
negq %rbx
jmp *(%rbp)
_c1Tx:
movq %r14,%rbx
jmp *(%rbp)
optAbsI#_info:
_c1SX:
movq %r14,%rax
sarq $63,%rax
movq %r14,%rbx
xorq %rax,%rbx
subq %rax,%rbx
jmp *(%rbp)
```
# `signum`
```hs
sgnI# :: Int# -> Int#
sgnI# i# = i'#
where
!(I# i'#) = signum (I# i#)
optSgnI# :: Int# -> Int#
optSgnI# x# = (x# ># 0#) -# (x# <# 0#)
```
```asm
sgnI#_info:
_c27W:
testq %r14,%r14
jl _c283
_c284:
testq %r14,%r14
jne _c28a
_c28b:
xorl %ebx,%ebx
jmp *(%rbp)
_c283:
movq $-1,%rbx
jmp *(%rbp)
_c28a:
movl $1,%ebx
jmp *(%rbp)
optSgnI#_info:
_c26P:
testq %r14,%r14
setl %al
movzbl %al,%eax
testq %r14,%r14
setg %bl
movzbl %bl,%ebx
subq %rax,%rbx
jmp *(%rbp)
```
# `compare`
```hs
cmpI# :: Int# -> Int# -> Int#
cmpI# x# y# = dataToTag# (compare (I# x#) (I# y#))
-- returns 0, 1 or 2, can be fed to tagToEnum# :: Ordering
optCmpI# :: Int# -> Int# -> Int#
optCmpI# x# y# = 1# +# (x# ># y#) -# (x# <# y#)
```
```asm
cmpI#_info:
_c25s:
cmpq %rsi,%r14
jl _c25z
_c25A:
cmpq %rsi,%r14
je _c25M
_c25N:
movl $2,%ebx
jmp *(%rbp)
_c25z:
xorl %ebx,%ebx
jmp *(%rbp)
_c25M:
movl $1,%ebx
jmp *(%rbp)
optCmpI#_info:
_c24N:
cmpq %rsi,%r14
setl %al
movzbl %al,%eax
movl $1,%ebx
subq %rax,%rbx
cmpq %rsi,%r14
setg %al
movq %rbx,%rcx
movzbl %al,%ebx
addq %rcx,%rbx
jmp *(%rbp)
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------ |
| Version | 7.8.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (CodeGen) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonmar |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Branchless arithmetic operations","status":"New","operating_system":"","component":"Compiler (CodeGen)","related":[],"milestone":"7.10.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"FeatureRequest","description":"While working on #9281 I noticed sub-optimal code generation for common arithmetic operations on `Int`. Below are some examples of code generation, where the branchless versions may be desirable on modern CPUs:\r\n\r\n= `abs`\r\n\r\n{{{#!hs\r\n-- base version\r\nabsI# :: Int# -> Int#\r\nabsI# i# = i'#\r\n where\r\n !(I# i'#) = abs (I# i#)\r\n\r\n-- optimized version\r\noptAbsI# :: Int# -> Int#\r\noptAbsI# i# = (i# `xorI#` nsign) -# nsign\r\n where\r\n -- nsign = i# <# 0#\r\n nsign = uncheckedIShiftRA# i# (WORD_SIZE_IN_BITS# -# 1#)\r\n}}}\r\n\r\nresults in\r\n\r\n{{{#!asm\r\nabsI#_info:\r\n_c1To:\r\n\ttestq %r14,%r14\r\n\tjge _c1Tx\r\n_c1Ty:\r\n\tmovq %r14,%rbx\r\n\tnegq %rbx\r\n\tjmp *(%rbp)\r\n_c1Tx:\r\n\tmovq %r14,%rbx\r\n\tjmp *(%rbp)\r\n\r\n\r\noptAbsI#_info:\r\n_c1SX:\r\n\tmovq %r14,%rax\r\n\tsarq $63,%rax\r\n\tmovq %r14,%rbx\r\n\txorq %rax,%rbx\r\n\tsubq %rax,%rbx\r\n\tjmp *(%rbp)\r\n}}}\r\n \r\n= `signum`\r\n\r\n{{{#!hs\r\nsgnI# :: Int# -> Int#\r\nsgnI# i# = i'#\r\n where\r\n !(I# i'#) = signum (I# i#)\r\n\r\noptSgnI# :: Int# -> Int#\r\noptSgnI# x# = (x# ># 0#) -# (x# <# 0#)\r\n}}}\r\n\r\n{{{#!asm\r\nsgnI#_info:\r\n_c27W:\r\n testq %r14,%r14\r\n jl _c283\r\n_c284:\r\n testq %r14,%r14\r\n jne _c28a\r\n_c28b:\r\n xorl %ebx,%ebx\r\n jmp *(%rbp)\r\n_c283:\r\n movq $-1,%rbx\r\n jmp *(%rbp)\r\n_c28a:\r\n movl $1,%ebx\r\n jmp *(%rbp)\r\n\r\n\r\noptSgnI#_info:\r\n_c26P:\r\n testq %r14,%r14\r\n setl %al\r\n movzbl %al,%eax\r\n testq %r14,%r14\r\n setg %bl\r\n movzbl %bl,%ebx\r\n subq %rax,%rbx\r\n jmp *(%rbp)\r\n}}}\r\n\r\n= `compare`\r\n\r\n{{{#!hs\r\ncmpI# :: Int# -> Int# -> Int#\r\ncmpI# x# y# = dataToTag# (compare (I# x#) (I# y#))\r\n\r\n-- returns 0, 1 or 2, can be fed to tagToEnum# :: Ordering\r\noptCmpI# :: Int# -> Int# -> Int#\r\noptCmpI# x# y# = 1# +# (x# ># y#) -# (x# <# y#)\r\n}}}\r\n\r\n\r\n{{{#!asm\r\ncmpI#_info:\r\n_c25s:\r\n\tcmpq %rsi,%r14\r\n\tjl _c25z\r\n_c25A:\r\n\tcmpq %rsi,%r14\r\n\tje _c25M\r\n_c25N:\r\n\tmovl $2,%ebx\r\n\tjmp *(%rbp)\r\n_c25z:\r\n\txorl %ebx,%ebx\r\n\tjmp *(%rbp)\r\n_c25M:\r\n\tmovl $1,%ebx\r\n\tjmp *(%rbp)\r\n\r\n\r\noptCmpI#_info:\r\n_c24N:\r\n\tcmpq %rsi,%r14\r\n\tsetl %al\r\n\tmovzbl %al,%eax\r\n\tmovl $1,%ebx\r\n\tsubq %rax,%rbx\r\n\tcmpq %rsi,%r14\r\n\tsetg %al\r\n\tmovq %rbx,%rcx\r\n\tmovzbl %al,%ebx\r\n\taddq %rcx,%rbx\r\n\tjmp *(%rbp)\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9347forkProcess does not acquire global handle locks2019-07-07T18:40:47Zedsko@edsko.netforkProcess does not acquire global handle locksThe global I/O handles (`stdout`, `stdin`, `stderr`) all make use an `MVar` wrapping a `Handle__`, and many I/O functions temporarily take this `MVar` (for instance, functions such as `hPutStr` include a call to `wantWritableHandle`, whi...The global I/O handles (`stdout`, `stdin`, `stderr`) all make use an `MVar` wrapping a `Handle__`, and many I/O functions temporarily take this `MVar` (for instance, functions such as `hPutStr` include a call to `wantWritableHandle`, which uses `withHandle_'`, which involves taking the `MVar`, executing some operation, and then putting the `MVar` back).
Suppose we have a program consisting of two threads A and B, where thread A is doing I/O. If thread B does a call to `forkProcess` then it is possible that the `fork()` happens at the point that A has just taken, say, the `MVar` for `stdout`. If this happens, every use of `stdout` in the child process will now forever deadlock.
This is not a theoretical scenario. The example code reported by Michael Snoyman a few years ago
http://www.haskell.org/pipermail/haskell-cafe/2012-October/103922.html
exhibits precisely this behaviour: the child process deadlocks (not all the the time, but very frequently), exactly because of this problem.
In `forkProcess` we avoid this sort of situation for all of the global RTS locks by acquiring the lock just before the call to `fork()`, and then releasing the lock in the parent again and re-initializing the lock in the child. But there are no provisions for Haskell-land locks such as the above `MVar`.
In principle we can work around this problem entirely in user-land. Here is a modified version of Michael's code that does not deadlock (at least, it never has in my tests..), that basically takes the same acquire-release\*2 trick that `forkProcess` does for RTS locks in the lines marked `(*)`:
```
import System.Posix.Process (forkProcess, getProcessID)
import Control.Concurrent (forkIO, threadDelay)
import System.IO (hFlush, stdout)
import System.Posix.Signals (signalProcess, sigKILL)
import Control.Exception (finally)
import Control.Concurrent
import GHC.IO.Handle.Types
import System.IO
main :: IO ()
main = do
mapM_ spawnChild [1..9]
ioLock <- lockIO -- (*)
child <- forkProcess $ do
unlockIO ioLock -- (*)
putStrLn "starting child"
hFlush stdout
loop "child" 0
unlockIO ioLock -- (*)
print ("child pid", child)
hFlush stdout
-- I've commented out the "finally" so that the zombie process stays alive,
-- to prove that it was actually created.
loop "parent" 0 -- `finally` signalProcess sigKILL child
spawnChild :: Int -> IO ()
spawnChild i = do
_ <- forkIO $ loop ("spawnChild " ++ show i) 0
return ()
loop :: String -> Int -> IO ()
loop msg i = do
pid <- getProcessID
print (pid, msg, i)
hFlush stdout
threadDelay 1000000
loop msg (i + 1)
--------------------------------------------------------------------------------
lockIO :: IO Handle__
lockIO =
case stdout of
FileHandle _ m -> takeMVar m
unlockIO :: Handle__ -> IO ()
unlockIO hout =
case stdout of
FileHandle _ m -> putMVar m hout
```
I guess that _any_ global `MVar` or `TVar` is suspect when using `forkProcess`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"forkProcess does not acquire global handle locks","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The global I/O handles (`stdout`, `stdin`, `stderr`) all make use an `MVar` wrapping a `Handle__`, and many I/O functions temporarily take this `MVar` (for instance, functions such as `hPutStr` include a call to `wantWritableHandle`, which uses `withHandle_'`, which involves taking the `MVar`, executing some operation, and then putting the `MVar` back).\r\n\r\nSuppose we have a program consisting of two threads A and B, where thread A is doing I/O. If thread B does a call to `forkProcess` then it is possible that the `fork()` happens at the point that A has just taken, say, the `MVar` for `stdout`. If this happens, every use of `stdout` in the child process will now forever deadlock. \r\n\r\nThis is not a theoretical scenario. The example code reported by Michael Snoyman a few years ago\r\n\r\nhttp://www.haskell.org/pipermail/haskell-cafe/2012-October/103922.html\r\n\r\nexhibits precisely this behaviour: the child process deadlocks (not all the the time, but very frequently), exactly because of this problem. \r\n\r\nIn `forkProcess` we avoid this sort of situation for all of the global RTS locks by acquiring the lock just before the call to `fork()`, and then releasing the lock in the parent again and re-initializing the lock in the child. But there are no provisions for Haskell-land locks such as the above `MVar`.\r\n\r\nIn principle we can work around this problem entirely in user-land. Here is a modified version of Michael's code that does not deadlock (at least, it never has in my tests..), that basically takes the same acquire-release*2 trick that `forkProcess` does for RTS locks in the lines marked `(*)`:\r\n\r\n{{{\r\nimport System.Posix.Process (forkProcess, getProcessID)\r\nimport Control.Concurrent (forkIO, threadDelay)\r\nimport System.IO (hFlush, stdout)\r\nimport System.Posix.Signals (signalProcess, sigKILL)\r\nimport Control.Exception (finally)\r\n\r\nimport Control.Concurrent\r\nimport GHC.IO.Handle.Types\r\nimport System.IO\r\n\r\nmain :: IO ()\r\nmain = do\r\n mapM_ spawnChild [1..9]\r\n\r\n ioLock <- lockIO -- (*)\r\n child <- forkProcess $ do\r\n unlockIO ioLock -- (*)\r\n putStrLn \"starting child\"\r\n hFlush stdout\r\n loop \"child\" 0\r\n unlockIO ioLock -- (*)\r\n\r\n print (\"child pid\", child)\r\n hFlush stdout\r\n\r\n -- I've commented out the \"finally\" so that the zombie process stays alive,\r\n -- to prove that it was actually created.\r\n loop \"parent\" 0 -- `finally` signalProcess sigKILL child\r\n\r\nspawnChild :: Int -> IO ()\r\nspawnChild i = do\r\n _ <- forkIO $ loop (\"spawnChild \" ++ show i) 0\r\n return ()\r\n\r\nloop :: String -> Int -> IO ()\r\nloop msg i = do\r\n pid <- getProcessID\r\n print (pid, msg, i)\r\n hFlush stdout\r\n threadDelay 1000000\r\n loop msg (i + 1)\r\n\r\n--------------------------------------------------------------------------------\r\n\r\nlockIO :: IO Handle__ \r\nlockIO = \r\n case stdout of\r\n FileHandle _ m -> takeMVar m \r\n\r\nunlockIO :: Handle__ -> IO ()\r\nunlockIO hout = \r\n case stdout of\r\n FileHandle _ m -> putMVar m hout\r\n}}}\r\n\r\nI guess that _any_ global `MVar` or `TVar` is suspect when using `forkProcess`. ","type_of_failure":"OtherFailure","blocking":[]} -->Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/9349excessive inlining due to state hack2020-06-02T23:44:20Zrwbartonexcessive inlining due to state hackThe program at https://gist.github.com/jorendorff/a3005968adc8f054baf7 runs very slowly when compiled with `-O` or higher. It seems that `arr` and/or `rangeMap` is being inlined into the do block on lines 89-91 and recomputed for each it...The program at https://gist.github.com/jorendorff/a3005968adc8f054baf7 runs very slowly when compiled with `-O` or higher. It seems that `arr` and/or `rangeMap` is being inlined into the do block on lines 89-91 and recomputed for each iteration of the loop. The program runs nearly instantly when compiled with `-O0` or with `-O -fno-pre-inlining`. (Of course, this does not mean `-fpre-inlining` is necessary the culprit; it could be enabling some subsequent misoptimization.)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"excessive inlining with -fpre-inlining","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The program at https://gist.github.com/jorendorff/a3005968adc8f054baf7 runs very slowly when compiled with `-O` or higher. It seems that `arr` and/or `rangeMap` is being inlined into the do block on lines 89-91 and recomputed for each iteration of the loop. The program runs nearly instantly when compiled with `-O0` or with `-O -fno-pre-inlining`. (Of course, this does not mean `-fpre-inlining` is necessary the culprit; it could be enabling some subsequent misoptimization.)","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9350Consider using xchg instead of mfence for CS stores2019-07-07T18:40:46ZtibbeConsider using xchg instead of mfence for CS storesTo get sequential consistency for `atomicWriteIntArray#` we use an `mfence` instruction. An alternative is to use an `xchg` instruction (which has an implicit `lock` prefix), which might have lower latency. We should check what other com...To get sequential consistency for `atomicWriteIntArray#` we use an `mfence` instruction. An alternative is to use an `xchg` instruction (which has an implicit `lock` prefix), which might have lower latency. We should check what other compilers do.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.9 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Consider using xchg instead of mfence for CS stores","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"To get sequential consistency for `atomicWriteIntArray#` we use an `mfence` instruction. An alternative is to use an `xchg` instruction (which has an implicit `lock` prefix), which might have lower latency. We should check what other compilers do.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9351add ability to version symbols .c for packages with C code2019-07-07T18:40:46ZSergei Trofimovichadd ability to version symbols .c for packages with C codeLet's consider an example:
We have a haskell package with some C code imported in
haskell:
```
// a.h file
int get_something(void);
// a.c file
#include "a.h"
int get_something(void) { return 42; }
// M.hs file
module M where
foreig...Let's consider an example:
We have a haskell package with some C code imported in
haskell:
```
// a.h file
int get_something(void);
// a.c file
#include "a.h"
int get_something(void) { return 42; }
// M.hs file
module M where
foreign import ccall "a.h get_something" :: IO Int
```
The problem here is we can't mix that package with other
packages having global 'get_something' symbol.
Sometimes it happens when a package copies part of
implementation from another package with .c bits under different
haskell namespace. Haskell parts would coexist freely, but
not C symbols.
Would be great if ghc would export some unique
package identifier in a way C code could attach
it to all exported symbols making linking possible.
Something like that:
```
// a.h file
#include "HsFFI.h" /* #define FOR_HASKELL(__sym) package_id_##__sym */
int FOR_HASKELL(get_something)(void);
// a.c file
#include "a.h"
int FOR_HASKELL(get_something)(void) { return 42; }
// M.hs file
module M where
foreign import ccall-for-haskell "a.h get_something" :: IO Int
```
That way we explicitly mark symbol as inaccessible to
external plain C code.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"add ability to version symbols .c for packages with C code","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Let's consider an example:\r\n\r\nWe have a haskell package with some C code imported in\r\nhaskell:\r\n{{{\r\n// a.h file\r\nint get_something(void);\r\n\r\n// a.c file\r\n#include \"a.h\"\r\nint get_something(void) { return 42; }\r\n\r\n// M.hs file\r\nmodule M where\r\n\r\nforeign import ccall \"a.h get_something\" :: IO Int\r\n}}}\r\n\r\nThe problem here is we can't mix that package with other\r\npackages having global 'get_something' symbol.\r\n\r\nSometimes it happens when a package copies part of\r\nimplementation from another package with .c bits under different\r\nhaskell namespace. Haskell parts would coexist freely, but\r\nnot C symbols.\r\n\r\nWould be great if ghc would export some unique\r\npackage identifier in a way C code could attach\r\nit to all exported symbols making linking possible.\r\n\r\nSomething like that:\r\n{{{\r\n// a.h file\r\n#include \"HsFFI.h\" /* #define FOR_HASKELL(__sym) package_id_##__sym */\r\nint FOR_HASKELL(get_something)(void);\r\n\r\n// a.c file\r\n#include \"a.h\"\r\nint FOR_HASKELL(get_something)(void) { return 42; }\r\n\r\n// M.hs file\r\nmodule M where\r\n\r\nforeign import ccall-for-haskell \"a.h get_something\" :: IO Int\r\n}}}\r\n\r\nThat way we explicitly mark symbol as inaccessible to\r\nexternal plain C code.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9352Allow `State# s` argument/result types in `ccall` FFI imports2023-06-20T14:33:26ZHerbert Valerio Riedelhvr@gnu.orgAllow `State# s` argument/result types in `ccall` FFI importsThis ticket is to allowing code like
```hs
{-# LANGUAGE UnliftedFFITypes #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
module M where
import GHC.Exts
foreign import ccall unsafe "foo" c_foo :: Int# -> State# s -> Stat...This ticket is to allowing code like
```hs
{-# LANGUAGE UnliftedFFITypes #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
module M where
import GHC.Exts
foreign import ccall unsafe "foo" c_foo :: Int# -> State# s -> State# s
foreign import ccall unsafe "bar" c_foo :: Int# -> State# s -> (# State# s, Int# #)
```
See also discussion in #92818.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9353prefetch primops are not currently useful2020-01-14T21:19:35ZMikeIzbickiprefetch primops are not currently usefulI wanted to use GHC's new prefetch primops to speed up a cover tree data structure I've been working on. The current implementation, however, is insufficient. The pure primops do not work at all. I propose an alternative using a seq-like...I wanted to use GHC's new prefetch primops to speed up a cover tree data structure I've been working on. The current implementation, however, is insufficient. The pure primops do not work at all. I propose an alternative using a seq-like syntax.
-------
- \*The problem\*\*
Consider the function:
```
prefetchAddr3# :: Addr# -> Int# -> Addr#
```
It is used like:
```
-- addr# :: Addr#
let prefetchAddr# = prefetchAddr3# addr# 0
... do some stuff not involving addr#
doRealWork prefetchAddr#
```
The problem is that we want the prefetch operation to get inserted at the let statement before "do some stuff...", but it doesn't get inserted there. It gets inserted directly before the call to doRealWork. This doesn't give the prefetch enough time to actually put the memory in cache, and so we still get a cache miss. I made several attempts to get around this, but they all failed due to dead code elimination.
The `prefetchMutableByteArray#` functions solve this problem by incorporating an explicit state parameter. This forces the compiler to insert the prefetch operation at the location it is actually called in the code. This function, however, can only be used within the ST and IO monads, so it is of limited use.
------
- \* The solution\*\*
The solution is to restructure the pure primops to use a seq-like format. For example, the prefetchAddr3\# function above would become:
```
prefetchAddr3# :: Addr# -> Int# -> a -> a
```
Then we would call the function like:
```
prefetchAddr3# addr# someOtherOp
... do some stuff not involving addr#
doRealWork prefetchAddr#
```
This would correctly insert the prefetch instruction at the location it appears in the haskell code. In particular, the prefetch will occur whenever the second parameter is evaluated.
This format has the advantage that it can work in non-monadic code. In my cover tree structure, I've implemented searching the tree as a `fold` operation. Every time the fold branches, only one of the branches is guaranteed to be in the cache. So I get a cache miss when I go down the other branches. I want to use the prefetch primop to prefetch the next branch the fold will go down. The fold function is pure, and I don't want to have to wedge it into the ST monad just for prefetching.8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9358Improve flag description in the user guide2021-09-01T04:45:08ZJan Stolarekjan.stolarek@ed.ac.ukImprove flag description in the user guideThese flags are currently completely missing from the User's Guide:
-fbuilding-cabal-package
-fflat-cache
-fhpc-no-auto
-fkill-absence
-fkill-one-shot
-fsimple-list-literals
-fspecialise-aggressively
-fuse-rpaths
-fspe...These flags are currently completely missing from the User's Guide:
-fbuilding-cabal-package
-fflat-cache
-fhpc-no-auto
-fkill-absence
-fkill-one-shot
-fsimple-list-literals
-fspecialise-aggressively
-fuse-rpaths
-fspec-constr-recursive
-ffloat-lam-args
-ffloat-all-lams
If you can provide description for any of these flags please edit flags.xml and using.xml.
Following flags are listed in Flag Reference section (4.19) with a brief one sentence description but they don't have a detailed description in section 4.10 (using.xml):
-fcall-arity
-funfolding-fun-discount
-funfolding-dict-discount
-funfolding-keeness-factor
-frule-check (see #9776)
Following flags have a detailed description but it is confusing:
-fdo-eta-reduction
-fdo-lambda-eta-expansion
Following flags have a description but it is too brief. We should have more
details:
-fdicts-cheap
-fdicts-strict
-fdmd-tx-dict-sel
-fmax-inline-memcpy-insns
-fmax-inline-memset-insns
-fmax-worker-args
-fno-opt-coercion
-fno-pre-inlining
-fsimplifier-phases
-fspec-constr-threshold
-fspec-constr-count
-fstrictness-before
For these flags Flag Reference section provides the description of their -fno-\* version:
-fembed-manifest
-fgen-manifest
-fghci-history
-fghci-sandbox
-fpre-inlining
-fprint-bind-contents
-fprof-count-entries
-fshared-implib
This seems to go against our convention of describing the flags. Should we
revert to desribing their normal version (ie. ones that enable something, not disable)?
We should also make sure that documentation of remaining flags is up to date, especially the -d\* ones.8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9364GHCi (or haskeline?) confused by non-single-width characters2019-07-07T18:40:43ZcheaterGHCi (or haskeline?) confused by non-single-width charactersHi,
there's an issue in the GHCi prompt.
To reproduce:
1. Do everything in Linux (I don't have other operating systems); I'm using a version of the gnome 2 gnome-terminal.
1. Use the following to colourise the prompt in GHCi:
echo -e ...Hi,
there's an issue in the GHCi prompt.
To reproduce:
1. Do everything in Linux (I don't have other operating systems); I'm using a version of the gnome 2 gnome-terminal.
1. Use the following to colourise the prompt in GHCi:
echo -e :set prompt '"\\033\[32;1m%s\\033\[34;1m\>\\033\[0m "' \>\> \~/.ghc/ghci.conf
1. Import quite a few modules (say, 5 to 10 should be enough)
1. Give the prompt enough text that it wraps around. It's best if you start the text with -- so that it's a comment and doesn't produce any output. For example, say I entered "-- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", I now see the following:
- Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid\> -- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
(do note that the first set of b's is located on the same line as the prompt, and the second is located under the prompt)
1. Press Enter. You should now see:
- Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid\> -- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
- Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid\>
1. Press Ctrl-P or the up arrow key to select the previous history item. You will now see the following:
- Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid\> -- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
- Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid\> -- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
1. Press Ctrl-A or the Home cursor key to go to the beginning of the text entry, and then type X. You will now see the last prompt to be:
- Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid\> -- bbbbbbbbbbbbX-- bbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
1. If you press Enter, you will find out that prompt was actually (without line breaks):
X-- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
I tried resizing the terminal window to 45 chars to make the lines above shorter; I imported Data.Monoid and Data.Functor in a new GHCi. The prompt contained garbage, most likely badly wrapped escape codes. See attachment.
As both likely are a single bug in disguise, I include both reports in this ticket.
Creating a test case for whether things actually work in a terminal might be difficult, but creating test for whether things get wrapped correctly (and not testing how things work out in a terminal) should be simple if annoying.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHCi (or haskeline?) confused by non-single-width characters","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["color,","colour,","linux,","prompt","terminal,"],"differentials":[],"test_case":"","architecture":"","cc":["hvr"],"type":"Bug","description":"Hi,\r\nthere's an issue in the GHCi prompt.\r\n\r\nTo reproduce:\r\n\r\n1. Do everything in Linux (I don't have other operating systems); I'm using a version of the gnome 2 gnome-terminal.\r\n\r\n2. Use the following to colourise the prompt in GHCi:\r\n\r\necho -e :set prompt '\"\\033[32;1m%s\\033[34;1m>\\033[0m \"' >> ~/.ghc/ghci.conf\r\n\r\n3. Import quite a few modules (say, 5 to 10 should be enough)\r\n\r\n4. Give the prompt enough text that it wraps around. It's best if you start the text with -- so that it's a comment and doesn't produce any output. For example, say I entered \"-- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\", I now see the following:\r\n\r\n*Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid> -- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n\r\n(do note that the first set of b's is located on the same line as the prompt, and the second is located under the prompt)\r\n\r\n5. Press Enter. You should now see:\r\n\r\n*Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid> -- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n*Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid>\r\n\r\n6. Press Ctrl-P or the up arrow key to select the previous history item. You will now see the following:\r\n\r\n*Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid> -- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n*Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid> -- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n\r\n7. Press Ctrl-A or the Home cursor key to go to the beginning of the text entry, and then type X. You will now see the last prompt to be:\r\n\r\n*Types Control.Monad.Writer Control.Monad Data.Functor Control.Applicative Data.Monoid> -- bbbbbbbbbbbbX-- bbbbbbbbbbbbbbbbb\r\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n\r\n8. If you press Enter, you will find out that prompt was actually (without line breaks):\r\n\r\nX-- bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n\r\n\r\n\r\nI tried resizing the terminal window to 45 chars to make the lines above shorter; I imported Data.Monoid and Data.Functor in a new GHCi. The prompt contained garbage, most likely badly wrapped escape codes. See attachment.\r\n\r\nAs both likely are a single bug in disguise, I include both reports in this ticket.\r\n\r\nCreating a test case for whether things actually work in a terminal might be difficult, but creating test for whether things get wrapped correctly (and not testing how things work out in a terminal) should be simple if annoying.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9365Make command key in GHCi configurable2019-07-07T18:40:42ZcheaterMake command key in GHCi configurableHi,
GHCi rightly uses the Vim-style mode of entering commands, where prefixing the prompt with a special character makes it into an entry on a meta-level (i.e. a command to the interpreter shell, not to the interpreter itself). Unfortuna...Hi,
GHCi rightly uses the Vim-style mode of entering commands, where prefixing the prompt with a special character makes it into an entry on a meta-level (i.e. a command to the interpreter shell, not to the interpreter itself). Unfortunately, that character is fixed to be ':'.
Many Vim power users hate having to press Shift several times a second and so make ';' that character in Vim. It's a popular tip on the Vim Tips site:
http://vim.wikia.com/wiki/Map_semicolon_to_colon
and tells you to perform the following settings:
nnoremap ; :
nnoremap : ;
vnoremap ; :
vnoremap : ;
Having used Vim like this for much over ten years now, it's not even a habit or reflex any more to type the semicolon, therefore (for me at least) it's cumbersome and error prone to type the colon in GHCi.
I ask that a new GHCi setting be added, with the following UI:
:set command-chars "string"
where each character of "string" will start command mode. Multiple (at least two) characters should be available for people switching from their old setting to their new setting.
When command mode is started, even if you had done :set command-chars ";" and then have typed ';', the prompt should still start with ':', just like in Vim. This is to signify that you're in the command "mode".
Thank you!
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | cheater, hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Make command key in GHCi configurable","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["cheater","hvr"],"type":"FeatureRequest","description":"Hi,\r\nGHCi rightly uses the Vim-style mode of entering commands, where prefixing the prompt with a special character makes it into an entry on a meta-level (i.e. a command to the interpreter shell, not to the interpreter itself). Unfortunately, that character is fixed to be ':'.\r\n\r\nMany Vim power users hate having to press Shift several times a second and so make ';' that character in Vim. It's a popular tip on the Vim Tips site:\r\n\r\nhttp://vim.wikia.com/wiki/Map_semicolon_to_colon\r\n\r\nand tells you to perform the following settings:\r\n\r\nnnoremap ; : \r\nnnoremap : ; \r\nvnoremap ; : \r\nvnoremap : ; \r\n\r\n\r\nHaving used Vim like this for much over ten years now, it's not even a habit or reflex any more to type the semicolon, therefore (for me at least) it's cumbersome and error prone to type the colon in GHCi.\r\n\r\nI ask that a new GHCi setting be added, with the following UI:\r\n\r\n:set command-chars \"string\"\r\n\r\nwhere each character of \"string\" will start command mode. Multiple (at least two) characters should be available for people switching from their old setting to their new setting.\r\n\r\nWhen command mode is started, even if you had done :set command-chars \";\" and then have typed ';', the prompt should still start with ':', just like in Vim. This is to signify that you're in the command \"mode\".\r\n\r\nThank you!","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9370unfolding info as seen when building a module depends on flags in a previousl...2022-05-02T13:28:50ZCarter Schonwaldunfolding info as seen when building a module depends on flags in a previously-compiled moduleI've observed a blowup in ghc memory usage when invoked with parallel build flags.
to reproduce
```
cabal get xmlhtml-0.2.3.2
cabal install xmlhtml-0.2.3.2 --only-dependencies
cd xmlhtml-0.2.3.2
```
then
```
cabal clean ; cabal con...I've observed a blowup in ghc memory usage when invoked with parallel build flags.
to reproduce
```
cabal get xmlhtml-0.2.3.2
cabal install xmlhtml-0.2.3.2 --only-dependencies
cd xmlhtml-0.2.3.2
```
then
```
cabal clean ; cabal configure --ghc-options="-j4" ; time cabal build -j4 -v3
```
will take quite a while and use \> 1gb of ram
whereas
```
cabal clean ; cabal configure --ghc-options="-j1 ; time cabal build -j1 -v3
```
will use \< 150mb of ram.
Based upon the output of cabal build -j4 -v3, it looks like the parallel build is spending a lottt more time in the simplifier passes. I'm not sure what changes between the parallel and sequential builds to change this. I'll try to dig into this more in a few days, but recording this problem now before i forget. (though of course any insights would be appreciated)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"large blowup in memory usage and time when doing parallel build of xmlhtml package","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I've observed a blowup in ghc memory usage when invoked with parallel build flags.\r\n\r\nto reproduce \r\n\r\n{{{\r\ncabal get xmlhtml-0.2.3.2\r\ncabal install xmlhtml-0.2.3.2 --only-dependencies\r\ncd xmlhtml-0.2.3.2 \r\n}}}\r\n\r\nthen \r\n{{{\r\n cabal clean ; cabal configure --ghc-options=\"-j4\" ; time cabal build -j4 -v3\r\n}}}\r\nwill take quite a while and use > 1gb of ram\r\n\r\nwhereas \r\n\r\n{{{\r\n cabal clean ; cabal configure --ghc-options=\"-j1 ; time cabal build -j1 -v3\r\n\r\n}}}\r\n\r\nwill use < 150mb of ram.\r\n\r\nBased upon the output of cabal build -j4 -v3, it looks like the parallel build is spending a lottt more time in the simplifier passes. I'm not sure what changes between the parallel and sequential builds to change this. I'll try to dig into this more in a few days, but recording this problem now before i forget. (though of course any insights would be appreciated)","type_of_failure":"OtherFailure","blocking":[]} -->Matthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/9374Investigate Static Argument Transformation2021-05-21T09:54:21ZJan Stolarekjan.stolarek@ed.ac.ukInvestigate Static Argument TransformationAt the moment the Static Argument Transformation (SAT) optimisation is not run unless explicitly enabled with `-fstatic-argument-transformation`. There was a comment by Max Bolingbroke in DynFlags that said this (that comment is now remo...At the moment the Static Argument Transformation (SAT) optimisation is not run unless explicitly enabled with `-fstatic-argument-transformation`. There was a comment by Max Bolingbroke in DynFlags that said this (that comment is now removed and replaced with a reference to this ticket):
```
Max writes: I think it's probably best not to enable SAT with -O2 for the
6.10 release. The version of SAT in HEAD at the moment doesn't incorporate
several improvements to the heuristics, and I'm concerned that without
those changes SAT will interfere with some attempts to write "high
performance Haskell", as we saw in some posts on Haskell-Cafe earlier
this year. In particular, the version in HEAD lacks the tail call
criterion, so many things that look like reasonable loops will be
turned into functions with extra (unneccesary) thunk creation.
```
1. 10 was a long time ago. Has anything changed since then? Does it make sense to enable that optimisation now? What are the mentioned heuristics and were they finally implemented? Does anyone know what Haskell-cafe posts does Max refer to?https://gitlab.haskell.org/ghc/ghc/-/issues/9376More informative error messages when closed type families fail to simplify2019-07-07T18:40:39ZMikeIzbickiMore informative error messages when closed type families fail to simplifyIn the following code, I am getting strange compiler errors that I suspect has to do with the recursive application of the OrdRec type family:
```
import GHC.Prim
import Data.Proxy
import qualified Data.Set as Set
type family OrdRec (f...In the following code, I am getting strange compiler errors that I suspect has to do with the recursive application of the OrdRec type family:
```
import GHC.Prim
import Data.Proxy
import qualified Data.Set as Set
type family OrdRec (f :: * -> *) a b :: Constraint where
OrdRec f a (f b) = ( Ord a, Ord (f b), OrdRec f a b )
OrdRec f a b = ( Ord a, Ord b )
setmap :: OrdRec Set.Set a b => (a -> b) -> Set.Set a -> Set.Set b
setmap f set = Set.map f set
```
GHC gives the error message:
```
ClosedTypeFamilyRecursion.hs:11:16:
Could not deduce (Ord b) arising from a use of ‘Set.map’
from the context (OrdRec Set.Set a b)
bound by the type signature for
setmap :: (OrdRec Set.Set a b) =>
(a -> b) -> Set.Set a -> Set.Set b
at ClosedTypeFamilyRecursion.hs:10:11-66
Possible fix:
add (Ord b) to the context of
the type signature for
setmap :: (OrdRec Set.Set a b) =>
(a -> b) -> Set.Set a -> Set.Set b
In the expression: Set.map f set
In an equation for ‘setmap’: setmap f set = Set.map f set
Failed, modules loaded: none.
```
If we modify the OrdRec type family to remove the recursive application:
```
type family OrdRec (f :: * -> *) a b :: Constraint where
OrdRec f a (f b) = ( Ord a, Ord (f b) )
OrdRec f a b = ( Ord a, Ord b )
```
Then GHC is able to compile the file fine.
What's extra weird, though, is that ghci appears to be able to evaluate the recursive type family correctly. If we comment out the setmap function, then load into ghci, we can verify that the OrdRec type family is giving the correct Ord constraints:
```
ghci> :t Proxy :: Proxy (OrdRec [] Int Float)
Proxy :: Proxy (OrdRec [] Int Float) :: Proxy (Ord Int, Ord Float)
ghci> :t :t Proxy :: Proxy (OrdRec [] Int [Float])
Proxy :: Proxy (OrdRec [] Int [Float])
:: Proxy (Ord Int, Ord [Float], (Ord Int, Ord Float))
ghci> :t Proxy :: Proxy (OrdRec [] Int [[Float]])
Proxy :: Proxy (OrdRec [] Int [[Float]])
:: Proxy
(Ord Int,
Ord [[Float]],
(Ord Int, Ord [Float], (Ord Int, Ord Float)))
```
But if I try to define the setmap function interactively in ghci, I get the same error message:
```
ghci> > let setmap = (\f set -> Set.map f set) :: OrdRec Set.Set a b => (a -> b) -> Set.Set a -> Set.Set b
<interactive>:39:25:
Could not deduce (Ord b1) arising from a use of ‘Set.map’
from the context (OrdRec Set.Set a b)
bound by the inferred type of
setmap :: (OrdRec Set.Set a b) =>
(a -> b) -> Set.Set a -> Set.Set b
at <interactive>:39:5-98
or from (OrdRec Set.Set a1 b1)
bound by an expression type signature:
(OrdRec Set.Set a1 b1) => (a1 -> b1) -> Set.Set a1 -> Set.Set b1
at <interactive>:39:14-98
Possible fix:
add (Ord b1) to the context of
an expression type signature:
(OrdRec Set.Set a1 b1) => (a1 -> b1) -> Set.Set a1 -> Set.Set b1
or the inferred type of
setmap :: (OrdRec Set.Set a b) =>
(a -> b) -> Set.Set a -> Set.Set b
In the expression: Set.map f set
In the expression:
(\ f set -> Set.map f set) ::
OrdRec Set.Set a b => (a -> b) -> Set.Set a -> Set.Set b
In an equation for ‘setmap’:
setmap
= (\ f set -> Set.map f set) ::
OrdRec Set.Set a b => (a -> b) -> Set.Set a -> Set.Set b
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Recursive closed type families fails","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"\r\nIn the following code, I am getting strange compiler errors that I suspect has to do with the recursive application of the OrdRec type family:\r\n\r\n{{{\r\nimport GHC.Prim\r\nimport Data.Proxy\r\nimport qualified Data.Set as Set\r\n\r\ntype family OrdRec (f :: * -> *) a b :: Constraint where\r\n OrdRec f a (f b) = ( Ord a, Ord (f b), OrdRec f a b )\r\n OrdRec f a b = ( Ord a, Ord b ) \r\n\r\nsetmap :: OrdRec Set.Set a b => (a -> b) -> Set.Set a -> Set.Set b\r\nsetmap f set = Set.map f set\r\n}}}\r\n\r\nGHC gives the error message:\r\n\r\n{{{\r\nClosedTypeFamilyRecursion.hs:11:16:\r\n Could not deduce (Ord b) arising from a use of ‘Set.map’\r\n from the context (OrdRec Set.Set a b)\r\n bound by the type signature for\r\n setmap :: (OrdRec Set.Set a b) =>\r\n (a -> b) -> Set.Set a -> Set.Set b\r\n at ClosedTypeFamilyRecursion.hs:10:11-66\r\n Possible fix:\r\n add (Ord b) to the context of\r\n the type signature for\r\n setmap :: (OrdRec Set.Set a b) =>\r\n (a -> b) -> Set.Set a -> Set.Set b\r\n In the expression: Set.map f set\r\n In an equation for ‘setmap’: setmap f set = Set.map f set\r\nFailed, modules loaded: none.\r\n}}}\r\n\r\nIf we modify the OrdRec type family to remove the recursive application:\r\n\r\n{{{\r\ntype family OrdRec (f :: * -> *) a b :: Constraint where\r\n OrdRec f a (f b) = ( Ord a, Ord (f b) )\r\n OrdRec f a b = ( Ord a, Ord b ) \r\n}}}\r\n\r\nThen GHC is able to compile the file fine.\r\n\r\nWhat's extra weird, though, is that ghci appears to be able to evaluate the recursive type family correctly. If we comment out the setmap function, then load into ghci, we can verify that the OrdRec type family is giving the correct Ord constraints:\r\n\r\n{{{\r\nghci> :t Proxy :: Proxy (OrdRec [] Int Float)\r\nProxy :: Proxy (OrdRec [] Int Float) :: Proxy (Ord Int, Ord Float)\r\n\r\nghci> :t :t Proxy :: Proxy (OrdRec [] Int [Float])\r\nProxy :: Proxy (OrdRec [] Int [Float])\r\n :: Proxy (Ord Int, Ord [Float], (Ord Int, Ord Float))\r\n\r\nghci> :t Proxy :: Proxy (OrdRec [] Int [[Float]])\r\nProxy :: Proxy (OrdRec [] Int [[Float]])\r\n :: Proxy\r\n (Ord Int,\r\n Ord [[Float]],\r\n (Ord Int, Ord [Float], (Ord Int, Ord Float)))\r\n}}}\r\n\r\nBut if I try to define the setmap function interactively in ghci, I get the same error message:\r\n\r\n{{{\r\nghci> > let setmap = (\\f set -> Set.map f set) :: OrdRec Set.Set a b => (a -> b) -> Set.Set a -> Set.Set b\r\n\r\n<interactive>:39:25:\r\n Could not deduce (Ord b1) arising from a use of ‘Set.map’\r\n from the context (OrdRec Set.Set a b)\r\n bound by the inferred type of\r\n setmap :: (OrdRec Set.Set a b) =>\r\n (a -> b) -> Set.Set a -> Set.Set b\r\n at <interactive>:39:5-98\r\n or from (OrdRec Set.Set a1 b1)\r\n bound by an expression type signature:\r\n (OrdRec Set.Set a1 b1) => (a1 -> b1) -> Set.Set a1 -> Set.Set b1\r\n at <interactive>:39:14-98\r\n Possible fix:\r\n add (Ord b1) to the context of\r\n an expression type signature:\r\n (OrdRec Set.Set a1 b1) => (a1 -> b1) -> Set.Set a1 -> Set.Set b1\r\n or the inferred type of\r\n setmap :: (OrdRec Set.Set a b) =>\r\n (a -> b) -> Set.Set a -> Set.Set b\r\n In the expression: Set.map f set\r\n In the expression:\r\n (\\ f set -> Set.map f set) ::\r\n OrdRec Set.Set a b => (a -> b) -> Set.Set a -> Set.Set b\r\n In an equation for ‘setmap’:\r\n setmap\r\n = (\\ f set -> Set.map f set) ::\r\n OrdRec Set.Set a b => (a -> b) -> Set.Set a -> Set.Set b\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9386GHCi cannot load .so in ./2019-07-07T18:40:37ZEric CrockettGHCi cannot load .so in ./In my directory ./ I have an empty file Foo.hs and a shared object file mylib.so. From that directory in the shell,
$ ghci Foo \*.so
GHCi, version 7.8.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ...In my directory ./ I have an empty file Foo.hs and a shared object file mylib.so. From that directory in the shell,
$ ghci Foo \*.so
GHCi, version 7.8.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading object (dynamic) mylib.so ... failed.
\<command line\>: user specified .o/.so/.DLL could not be loaded (mylib.so: cannot open shared object file: No such file or directory)
Whilst trying to load: (dynamic) mylib.so
> Additional directories searched: (none)
It's interesting that GHCi searches ./ and identifies the correct object file, but then fails to load it. I have also tried the path ./\*.so, mylib.so and ./mylib.so for the GHCi option.
However, if I move mylib.so to a directory ./Temp,
> $ ghci Foo Temp/\*.so
loads without issue.https://gitlab.haskell.org/ghc/ghc/-/issues/9388Narrow the scope of the notorious "state hack"2022-12-13T14:10:50ZSimon Peyton JonesNarrow the scope of the notorious "state hack"The "state hack" has caused any number of bug reports (just search for that string), the most recent of which is #9349.
Here's an idea to make it less pervasive: (roughly) use the state hack only for top-level functions definitions.
Th...The "state hack" has caused any number of bug reports (just search for that string), the most recent of which is #9349.
Here's an idea to make it less pervasive: (roughly) use the state hack only for top-level functions definitions.
The idea is that for nested lambdas the context should give the one-shot-ness, now that we are equipped with cardinality analysis. For example, consider the call
```
replicatM_ 1000 (\(s :: RealWorld#) -> blah)
```
The lambda is 1000-shot, not one-shot, notwithstanding the type of the binder. Moreover `replicateM_`'s strictness/cardinality signature will say just that, and GHC already knows how to propagate that information onto the `\s`.
But for top level functions like
```
pr :: String -> IO ()
pr x = putStrLn (reverse x)
```
we get Core
```
pr = \x. let y = reverse x in
\ (s :: State# RealWorld). putStrLn y s
```
and, since we can't see all the callers of `pr`, we don't know if work is lost by pushing the `reverse` call inside, to get
```
pr = \x. (s :: State# RealWorld). putStrLn (reverse x) s
```
which is much more efficient. Indeed, this might not be so good if the calls looked like
```
... replicateM_ 1000 (pr "foo")...
```
because then "foo" will be reversed 1000 times. But arguably that's what the programmer expects anyway, looking at the code; and the efficiency hit from not eta-expanding all functions like `pr` (which are very very common) is significant.
The point is the that the only ones that need hacking are the top-level guys, and maybe even the top-level *exported* guys.
I have not fully thought this through, let alone tried it out, but I wanted to capture the thought. It would need some careful performance testing.
Simon
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Narrow the scope of the notorious \"state hack\"","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The \"state hack\" has caused any number of bug reports (just search for that string), the most recent of which is #9349.\r\n\r\nHere's an idea to make it less pervasive: (roughly) use the state hack only for top-level functions definitions.\r\n\r\nThe idea is that for nested lambdas the context should give the one-shot-ness, now that we are equipped with cardinality analysis. For example, consider the call\r\n{{{\r\n replicatM_ 1000 (\\(s :: RealWorld#) -> blah)\r\n}}}\r\nThe lambda is 1000-shot, not one-shot, notwithstanding the type of the binder. Moreover `replicateM_`'s strictness/cardinality signature will say just that, and GHC already knows how to propagate that information onto the `\\s`.\r\n\r\nBut for top level functions like\r\n{{{\r\npr :: String -> IO ()\r\npr x = putStrLn (reverse x)\r\n}}}\r\nwe get Core\r\n{{{\r\npr = \\x. let y = reverse x in\r\n \\ (s :: State# RealWorld). putStrLn y s\r\n}}}\r\nand, since we can't see all the callers of `pr`, we don't know if work is lost by pushing the `reverse` call inside, to get\r\n{{{\r\npr = \\x. (s :: State# RealWorld). putStrLn (reverse x) s\r\n}}}\r\nwhich is much more efficient. Indeed, this might not be so good if the calls looked like\r\n{{{\r\n ... replicateM_ 1000 (pr \"foo\")...\r\n}}}\r\nbecause then \"foo\" will be reversed 1000 times. But arguably that's what the programmer expects anyway, looking at the code; and the efficiency hit from not eta-expanding all functions like `pr` (which are very very common) is significant.\r\n\r\nThe point is the that the only ones that need hacking are the top-level guys, and maybe even the top-level ''exported'' guys.\r\n\r\nI have not fully thought this through, let alone tried it out, but I wanted to capture the thought. It would need some careful performance testing.\r\n\r\nSimon","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9392"\n" is displayed weirdly in error messages2019-07-07T18:40:36ZArtyom.Kazak"\n" is displayed weirdly in error messagesObserve:
```
Prelude> "a\nb" + ()
<interactive>:2:10:
Couldn't match expected type ‘[Char]’ with actual type ‘()’
In the second argument of ‘(+)’, namely ‘()’
In the expression:
"a\n\
\b"
+ ()
```
Moreove...Observe:
```
Prelude> "a\nb" + ()
<interactive>:2:10:
Couldn't match expected type ‘[Char]’ with actual type ‘()’
In the second argument of ‘(+)’, namely ‘()’
In the expression:
"a\n\
\b"
+ ()
```
Moreover, if “\\n” is at the end of the string, it simply gets eaten:
```
Prelude> "a\n" + ()
<interactive>:3:9:
Couldn't match expected type ‘[Char]’ with actual type ‘()’
In the second argument of ‘(+)’, namely ‘()’
In the expression: "a" + ()
```
It happens in GHC as well as GHCi. Tested on 7.8.3.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"\"\\n\" is displayed weirdly in error messages","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Observe:\r\n\r\n{{{\r\nPrelude> \"a\\nb\" + ()\r\n\r\n<interactive>:2:10:\r\n Couldn't match expected type ‘[Char]’ with actual type ‘()’\r\n In the second argument of ‘(+)’, namely ‘()’\r\n In the expression:\r\n \"a\\n\\\r\n \\b\"\r\n + ()\r\n}}}\r\n\r\nMoreover, if “\\n” is at the end of the string, it simply gets eaten:\r\n\r\n{{{\r\nPrelude> \"a\\n\" + ()\r\n\r\n<interactive>:3:9:\r\n Couldn't match expected type ‘[Char]’ with actual type ‘()’\r\n In the second argument of ‘(+)’, namely ‘()’\r\n In the expression: \"a\" + ()\r\n}}}\r\n\r\nIt happens in GHC as well as GHCi. Tested on 7.8.3.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9403Make --show-iface more human readable2019-07-07T18:40:32ZEdward Z. YangMake --show-iface more human readableRight now --show-iface is not particularly interpretable, even if you are looking at the Outputable instance for `ModIface`. The problem seems to be the output for `mi_deps`, `mi_usages`, `mi_decls`, `mi_insts`, `mi_fam_insts` and `mi_ru...Right now --show-iface is not particularly interpretable, even if you are looking at the Outputable instance for `ModIface`. The problem seems to be the output for `mi_deps`, `mi_usages`, `mi_decls`, `mi_insts`, `mi_fam_insts` and `mi_rules` is not clearly delimited, making it unclear (for example) what `import -/ base:Prelude HASH` refers to unless you already happen to know that this must be from `mi_usages`.
It should be relatively easy to improve this, but I want to make sure people who rely on this output aren't blindsided by the changes.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.9 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Make --show-iface more human readable","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ezyang"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Right now --show-iface is not particularly interpretable, even if you are looking at the Outputable instance for `ModIface`. The problem seems to be the output for `mi_deps`, `mi_usages`, `mi_decls`, `mi_insts`, `mi_fam_insts` and `mi_rules` is not clearly delimited, making it unclear (for example) what `import -/ base:Prelude HASH` refers to unless you already happen to know that this must be from `mi_usages`.\r\n\r\nIt should be relatively easy to improve this, but I want to make sure people who rely on this output aren't blindsided by the changes.","type_of_failure":"OtherFailure","blocking":[]} -->Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/9406unexpected failure for T7837(profasm)2019-07-07T18:40:31Zjrp2014unexpected failure for T7837(profasm)This may be a test suite configuration error as the normal case works (and indeed I get a lot of profiled case failures of other cases). When run with an llvm-perf build of the HEAD, I get:
```
=====> T7837(normal) 1395 of 4068 [0, 0, 0...This may be a test suite configuration error as the normal case works (and indeed I get a lot of profiled case failures of other cases). When run with an llvm-perf build of the HEAD, I get:
```
=====> T7837(normal) 1395 of 4068 [0, 0, 0]
cd ./indexed-types/should_compile && '/Users/jrp/Projects/haskell/ghc/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts -fno-ghci-history -c T7837.hs -O -ddump-rule-firings >T7837.comp.stderr 2>&1
=====> T7837(profasm) 1395 of 4068 [0, 0, 0]
cd ./indexed-types/should_compile && '/Users/jrp/Projects/haskell/ghc/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts -fno-ghci-history -c T7837.hs -O -prof -static -auto-all -O -ddump-rule-firings >T7837.comp.stderr 2>&1
Actual stderr output differs from expected:
--- ./indexed-types/should_compile/T7837.stderr 2014-08-03 11:36:53.000000000 +0100
+++ ./indexed-types/should_compile/T7837.comp.stderr 2014-08-04 23:16:34.000000000 +0100
@@ -1,3 +1,4 @@
Rule fired: Class op abs
Rule fired: Class op signum
Rule fired: normalize/Double
+Rule fired: Class op /
*** unexpected failure for T7837(profasm)
Unexpected results from:
TEST="T7837"
OVERALL SUMMARY for test run started at Mon Aug 4 23:16:32 2014 BST
0:00:02 spent to go through
4068 total tests, which gave rise to
19536 test cases, of which
19534 were skipped
0 had missing libraries
1 expected passes
0 expected failures
0 caused framework failures
0 unexpected passes
1 unexpected failures
Unexpected failures:
indexed-types/should_compile T7837 [stderr mismatch] (profasm)
```https://gitlab.haskell.org/ghc/ghc/-/issues/9418Warnings about "INLINE binder is (non-rule) loop breaker"2019-07-07T18:40:29ZSimon Peyton JonesWarnings about "INLINE binder is (non-rule) loop breaker"Gabor rightly complains: I see literally *thousands* of these warnings (in yesterday's and) today's bootstraps:
```
HC [stage 1] libraries/base/dist-install/build/GHC/Base.o
*** Core Lint warnings : in result of Desugar (after optimiz...Gabor rightly complains: I see literally *thousands* of these warnings (in yesterday's and) today's bootstraps:
```
HC [stage 1] libraries/base/dist-install/build/GHC/Base.o
*** Core Lint warnings : in result of Desugar (after optimization) *** {-# LINE 261 "libraries/base/GHC/Base.lhs #-}: Warning:
[RHS of $c>>_arr :: forall r_agf a_adQ b_adR.
(r_agf -> a_adQ) -> (r_agf -> b_adR) -> r_agf -> b_adR]
INLINE binder is (non-rule) loop breaker: $c>>_arr {-# LINE 632 "libraries/base/GHC/Base.lhs #-}: Warning:
[RHS of $c>>_apH :: forall a_adQ b_adR.
GHC.Types.IO a_adQ -> GHC.Types.IO b_adR -> GHC.Types.IO b_adR]
INLINE binder is (non-rule) loop breaker: $c>>_apH }}}
```
This is clearly unsatisfactory, because it is unsettling, and perhaps conceals more important warnings.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Warnings about \"INLINE binder is (non-rule) loop breaker\"","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Gabor rightly complains: I see literally ''thousands'' of these warnings (in yesterday's and) today's bootstraps:\r\n{{{\r\n HC [stage 1] libraries/base/dist-install/build/GHC/Base.o\r\n*** Core Lint warnings : in result of Desugar (after optimization) *** {-# LINE 261 \"libraries/base/GHC/Base.lhs #-}: Warning:\r\n [RHS of $c>>_arr :: forall r_agf a_adQ b_adR.\r\n (r_agf -> a_adQ) -> (r_agf -> b_adR) -> r_agf -> b_adR]\r\n INLINE binder is (non-rule) loop breaker: $c>>_arr {-# LINE 632 \"libraries/base/GHC/Base.lhs #-}: Warning:\r\n [RHS of $c>>_apH :: forall a_adQ b_adR.\r\n GHC.Types.IO a_adQ -> GHC.Types.IO b_adR -> GHC.Types.IO b_adR]\r\n INLINE binder is (non-rule) loop breaker: $c>>_apH }}}\r\n}}}\r\nThis is clearly unsatisfactory, because it is unsettling, and perhaps conceals more important warnings.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9427Do finer-grained dependency analysis to infer more general kinds on type/clas...2020-03-13T14:10:58ZRichard Eisenbergrae@richarde.devDo finer-grained dependency analysis to infer more general kinds on type/class declarationsIn the resolution to #9200, as detailed [here](https://gitlab.haskell.org/ghc/ghc/wikis/ghc-kinds/kind-inference/#a-possible-variation), we identified an area for improvement. This improvement was not implemented in the fix for #9200. Th...In the resolution to #9200, as detailed [here](https://gitlab.haskell.org/ghc/ghc/wikis/ghc-kinds/kind-inference/#a-possible-variation), we identified an area for improvement. This improvement was not implemented in the fix for #9200. This ticket will track just this improvement.
(In brief: we can do better dependency analysis on mutually recursive type/class declarations to allow more kinds to generalize earlier. This would lessen the burden on programmers to put in kind annotations. See the wiki page.)
A solid but unfinished attempt is [here](https://github.com/goldfirere/ghc/tree/re-sort-non-cusk-decls).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Do finer-grained dependency analysis to infer more general kinds on type/class declarations","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"In the resolution to #9200, as detailed [wiki:GhcKinds/KindInference#Apossiblevariation here], we identified an area for improvement. This improvement was not implemented in the fix for #9200. This ticket will track just this improvement.\r\n\r\n(In brief: we can do better dependency analysis on mutually recursive type/class declarations to allow more kinds to generalize earlier. This would lessen the burden on programmers to put in kind annotations. See the wiki page.)\r\n\r\nA solid but unfinished attempt is [https://github.com/goldfirere/ghc/tree/re-sort-non-cusk-decls here].","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9429Alternative to type family Any2019-07-07T18:40:27ZMathieu BoespflugAlternative to type family AnyIn GHC HEAD, `Any` is no longer a datatype. There are good reasons for this change, one of which was explained in #9097, the original ticket, and another in #9380. Unfortunately, a casualty of this change is that it is no longer easy to ...In GHC HEAD, `Any` is no longer a datatype. There are good reasons for this change, one of which was explained in #9097, the original ticket, and another in #9380. Unfortunately, a casualty of this change is that it is no longer easy to generalize the [rank1dynamic package](https://hackage.haskell.org/package/rank1dynamic) to rank-1 types with type variables of arbitrary kind (not just `*`). We submitted a way to do so [here](https://github.com/haskell-distributed/rank1dynamic/pull/6), that exploits the fact that `Any` has the very magical property of inhabiting \*all\* kinds, including closed ones.
This works for GHC 7.8, but won't work in HEAD, because we require that there exists a `Typeable` instance for `Any`, just as there are `Typeable` instances for any other type one wishes to have instances for. The reason is that now that `Any` is a type family, `Any` is no longer a legal instance head.
There are several possible solutions that I see:
- while it's clearly dangerous for the compiler to be inserting the old `Any` during typechecking from the moment that we have computation in types over closed kinds, we may still want the old `Any`, say under a different name, as a backdoor. It wouldn't be used by the compiler during type checking - only by packages such as rank1dynamic. I believe that furthermore, if we restrict the old `Any` to not inhabit closed kinds, then none of the problems cited in the above tickets arise.
- Instead of making the new `Any` a type family, keep it a datatype, but ban it from inhabiting closed kinds. I don't know if such an `Any` would be sufficient for the purposes of GHC, however.
- Hardwire a `Typeable` instance for the `Any` type family (not sure if this makes sense).https://gitlab.haskell.org/ghc/ghc/-/issues/9432IncoherentInstances are too restricted2019-07-07T18:40:25Zdanilo2IncoherentInstances are too restrictedHello! The reason behind using `IncoherentInstances`is that we want GHC to commit to a specific instance even if after instantiation of some variables, other instance could be more specific (http://www.haskell.org/ghc/docs/7.8.2/html/use...Hello! The reason behind using `IncoherentInstances`is that we want GHC to commit to a specific instance even if after instantiation of some variables, other instance could be more specific (http://www.haskell.org/ghc/docs/7.8.2/html/users_guide/type-class-extensions.html). There is one problem though. Let's consider following example (which could not make much sense, but shows the problem well):
```haskell
{-# OPTIONS_GHC -fno-warn-missing-methods #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE IncoherentInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Data.Typeable
--------------------------------------------------------------------------------
-- Type classes
--------------------------------------------------------------------------------
class InferType a where
inferType :: Proxy a -> Proxy a
inferType = undefined
--------------------------------------------------------------------------------
-- Proxy datatypes
--------------------------------------------------------------------------------
data Id0 = Id0 deriving (Show, Typeable)
data Id1 t1 = Id1 deriving (Show, Typeable)
data Id2 t1 t2 = Id2 deriving (Show, Typeable)
data Id3 t1 t2 t3 = Id3 deriving (Show, Typeable)
data Id4 t1 t2 t3 t4 = Id4 deriving (Show, Typeable)
data Id5 t1 t2 t3 t4 t5 = Id5 deriving (Show, Typeable)
--------------------------------------------------------------------------------
-- Instances
--------------------------------------------------------------------------------
instance InferType Int
instance (InferType m, InferType a) => InferType (m a)
instance (a~Id0) => InferType (a :: *)
instance (a~Id1) => InferType (a :: * -> *)
instance (a~Id2) => InferType (a :: * -> * -> *)
--------------------------------------------------------------------------------
-- Tests
--------------------------------------------------------------------------------
toProxy :: a -> Proxy a
toProxy _ = Proxy
--inferTypeBase :: a -> Proxy a
inferTypeBase a = inferType $ toProxy a
instance InferType Foo1
instance InferType Foo2
tm _ = 5
data Foo1 a = Foo1 a deriving (Show, Typeable)
data Foo2 a b = Foo2 a b deriving (Show, Typeable)
instance Monad Id1 -- dummy instances just for tests
instance Num Id0
main = do
print $ typeOf $ inferType $ toProxy $ (return (5))
print $ typeOf $ inferType $ toProxy $ (5)
print $ typeOf $ inferType $ toProxy $ (Foo1 (return 5))
print $ typeOf $ inferType $ toProxy $ (Foo2 (return 5) (return 5))
print "hello"
---- OUTPUT:
-- Proxy (Id1 Id0)
-- Proxy Id0
-- Proxy (Foo1 (Id1 Id0))
-- Proxy (Foo2 (Id1 Id0) (Id1 Id0))
-- "hello"
```
The idea is very simple - replace all unknown type variables with known ones. It works great, but the problem appears with the function `inferTypeBase`. It should have type of `a -> Proxy a`, but GHC claims it has got `Id0 -> Proxy Id0`. It is of course caused by enabled `-XIncoherentInstances` flag, but I think GHC should be more liberal here.
If it really cannot pick any instance (causing an error using only `OverlappingInstances`), the `IncoherentInstances` should allow it to pick matching one even if more specific could be available after instantianization. But If no error would occur while using `OverlappingInstances`, `IncoherentInstances` should not affect the way it resolves the instances. I think this would make `IncoherentInstances` much more useful than now. Maybe it would be good to just add some options to the flag?https://gitlab.haskell.org/ghc/ghc/-/issues/9434GHC.List.reverse does not fuse2019-07-07T18:40:25ZDavid FeuerGHC.List.reverse does not fuseAs Edward Kmett speculated could be the case a couple months ago, Joachim Breitner's call arity analysis makes the Prelude version of `reverse` better than GHC's version. It's less clear to me whether it's beneficial to wrap it in `build...As Edward Kmett speculated could be the case a couple months ago, Joachim Breitner's call arity analysis makes the Prelude version of `reverse` better than GHC's version. It's less clear to me whether it's beneficial to wrap it in `build`, but I think the answer is *probably* yes, based on the fact that doing so turns `foldr c n $ reverse xs` into `foldl (flip c) n xs`.
```hs
{-# INLINE reverse #-}
reverse :: [a] -> [a]
reverse xs = build $ \c n -> foldl (\a x -> x `c` a) n xs
```
This simplifies to
```hs
Rec {
poly_go_r2uL
poly_go_r2uL =
\ @ a_a2nn ds_a2xO eta_Xh ->
case ds_a2xO of _ {
[] -> eta_Xh;
: y_a2xT ys_a2xU -> poly_go_r2uL ys_a2xU (: y_a2xT eta_Xh)
}
end Rec }
reverse
reverse = \ @ a_a2nn eta_B1 -> poly_go_r2uL eta_B1 ([])
```
which looks about the same as the current version in GHC.List.
Behold the beauty when it is applied to an unfold (with a fusion-friendly version of `unfoldr`):
```hs
testReverseUnfoldr f q0 = reverse (unfoldr f q0)
```
simplifies to
```hs
testReverseUnfoldr
testReverseUnfoldr =
\ @ a_a2w3 @ b_a2w4 f_a2mn q0_a2mo ->
letrec {
go_a1QX
go_a1QX =
\ b1_a1Hy eta_B1 ->
case f_a2mn b1_a1Hy of _ {
Nothing -> eta_B1;
Just ds_d2d8 ->
case ds_d2d8 of _ { (a1_a1Hz, new_b_a1HA) ->
go_a1QX new_b_a1HA (: a1_a1Hz eta_B1)
}
}; } in
go_a1QX q0_a2mo ([])
```
This looks exactly like a hand-written `unfoldl`!
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.9 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | ekmett, hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC.List.reverse does not fuse","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["ekmett","hvr"],"type":"Bug","description":"As Edward Kmett speculated could be the case a couple months ago, Joachim Breitner's call arity analysis makes the Prelude version of `reverse` better than GHC's version. It's less clear to me whether it's beneficial to wrap it in `build`, but I think the answer is ''probably'' yes, based on the fact that doing so turns `foldr c n $ reverse xs` into `foldl (flip c) n xs`.\r\n\r\n{{{#!hs\r\n{-# INLINE reverse #-}\r\nreverse :: [a] -> [a]\r\nreverse xs = build $ \\c n -> foldl (\\a x -> x `c` a) n xs\r\n}}}\r\n\r\nThis simplifies to\r\n\r\n{{{#!hs\r\nRec {\r\npoly_go_r2uL\r\npoly_go_r2uL =\r\n \\ @ a_a2nn ds_a2xO eta_Xh ->\r\n case ds_a2xO of _ {\r\n [] -> eta_Xh;\r\n : y_a2xT ys_a2xU -> poly_go_r2uL ys_a2xU (: y_a2xT eta_Xh)\r\n }\r\nend Rec }\r\n\r\nreverse\r\nreverse = \\ @ a_a2nn eta_B1 -> poly_go_r2uL eta_B1 ([])\r\n}}}\r\n\r\nwhich looks about the same as the current version in GHC.List.\r\n\r\nBehold the beauty when it is applied to an unfold (with a fusion-friendly version of `unfoldr`):\r\n\r\n{{{#!hs\r\ntestReverseUnfoldr f q0 = reverse (unfoldr f q0)\r\n}}}\r\n\r\nsimplifies to\r\n\r\n{{{#!hs\r\ntestReverseUnfoldr\r\ntestReverseUnfoldr =\r\n \\ @ a_a2w3 @ b_a2w4 f_a2mn q0_a2mo ->\r\n letrec {\r\n go_a1QX\r\n go_a1QX =\r\n \\ b1_a1Hy eta_B1 ->\r\n case f_a2mn b1_a1Hy of _ {\r\n Nothing -> eta_B1;\r\n Just ds_d2d8 ->\r\n case ds_d2d8 of _ { (a1_a1Hz, new_b_a1HA) ->\r\n go_a1QX new_b_a1HA (: a1_a1Hz eta_B1)\r\n }\r\n }; } in\r\n go_a1QX q0_a2mo ([])\r\n}}}\r\n\r\nThis looks exactly like a hand-written `unfoldl`!","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9438Dynamic GHCi doesn't support static libraries2019-07-07T18:40:24ZeglDynamic GHCi doesn't support static librariesRunning
```
ghci -L/opt/local/lib -latlas
```
eventually leads to
```
Loading object (static archive) /opt/local/lib/libatlas.a ... ghc: panic! (the 'impossible' happened)
(GHC version 7.8.3 for x86_64-apple-darwin):
Loading archi...Running
```
ghci -L/opt/local/lib -latlas
```
eventually leads to
```
Loading object (static archive) /opt/local/lib/libatlas.a ... ghc: panic! (the 'impossible' happened)
(GHC version 7.8.3 for x86_64-apple-darwin):
Loading archives not supported
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
This looks similar to 8164 and 4828, which are marked closed.
Mac OSX 10.9.4
Xcode 5.1.1
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | MacOS X |
| Architecture | x86_64 (amd64) |
</details>
<!-- {"blocked_by":[],"summary":"panic: loading archives not supported","status":"New","operating_system":"MacOS X","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"x86_64 (amd64)","cc":[""],"type":"Bug","description":"Running\r\n{{{\r\nghci -L/opt/local/lib -latlas\r\n}}}\r\n eventually leads to\r\n{{{\r\nLoading object (static archive) /opt/local/lib/libatlas.a ... ghc: panic! (the 'impossible' happened)\r\n (GHC version 7.8.3 for x86_64-apple-darwin):\r\n\tLoading archives not supported\r\n\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n}}}\r\nThis looks similar to 8164 and 4828, which are marked closed.\r\n\r\nMac OSX 10.9.4\r\nXcode 5.1.1","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9445GHC Panic: Tick Exhausted with high factor2019-07-07T18:40:22ZAlfredo Di NapoliGHC Panic: Tick Exhausted with high factorHello guys,
this is an old bug which has been reported so many times that I'm not sure this will be noise or something useful.
In a nutshell I have been hit by this bug installing the library "SFML", which relies heavily on FFI.
The on...Hello guys,
this is an old bug which has been reported so many times that I'm not sure this will be noise or something useful.
In a nutshell I have been hit by this bug installing the library "SFML", which relies heavily on FFI.
The only interesting thing of this report is that it was necessary an very high simpl-factor to make the installation go through!
Pre-bump:
```
Resolving dependencies...
In order, the following will be installed:
SFML-0.2.0.0 (reinstall)
Warning: Note that reinstalls are always dangerous. Continuing anyway...
Configuring SFML-0.2.0.0...
Building SFML-0.2.0.0...
Preprocessing library SFML-0.2.0.0...
[...]
[34 of 71] Compiling SFML.Graphics.Transform ( dist/build/SFML/Graphics/Transform.hs, dist/build/SFML/Graphics/Transform.o )
ghc: panic! (the 'impossible' happened)
(GHC version 7.8.3 for x86_64-apple-darwin):
Simplifier ticks exhausted
When trying UnfoldingDone $j_sZQW{v} [lid]
To increase the limit, use -fsimpl-tick-factor=N (default 100)
If you need to do this, let GHC HQ know, and what factor you needed
To see detailed counts use -ddump-simpl-stats
Total ticks: 2655928
```
And this was the magic line:
```
cabal install SFML --ghc-option=-fsimpl-tick-factor=1630
```
HTH, it turns out it's quite an annoying one! And yes, "1630" was the smaller factor which made the installation possible.
Alfredo
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | #5539 |
| Blocking | |
| CC | aseipp |
| Operating system | MacOS X |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC Panic: Tick Exhausted with high factor","status":"New","operating_system":"MacOS X","component":"Compiler","related":[5539],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["panic"],"differentials":[],"test_case":"","architecture":"","cc":["aseipp"],"type":"Bug","description":"Hello guys,\r\n\r\nthis is an old bug which has been reported so many times that I'm not sure this will be noise or something useful.\r\n\r\nIn a nutshell I have been hit by this bug installing the library \"SFML\", which relies heavily on FFI.\r\nThe only interesting thing of this report is that it was necessary an very high simpl-factor to make the installation go through!\r\n\r\nPre-bump:\r\n\r\n{{{\r\nResolving dependencies...\r\nIn order, the following will be installed:\r\nSFML-0.2.0.0 (reinstall)\r\nWarning: Note that reinstalls are always dangerous. Continuing anyway...\r\nConfiguring SFML-0.2.0.0...\r\nBuilding SFML-0.2.0.0...\r\nPreprocessing library SFML-0.2.0.0...\r\n[...]\r\n[34 of 71] Compiling SFML.Graphics.Transform ( dist/build/SFML/Graphics/Transform.hs, dist/build/SFML/Graphics/Transform.o )\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 7.8.3 for x86_64-apple-darwin):\r\n Simplifier ticks exhausted\r\n When trying UnfoldingDone $j_sZQW{v} [lid]\r\n To increase the limit, use -fsimpl-tick-factor=N (default 100)\r\n If you need to do this, let GHC HQ know, and what factor you needed\r\n To see detailed counts use -ddump-simpl-stats\r\n Total ticks: 2655928\r\n}}}\r\n\r\nAnd this was the magic line:\r\n\r\n{{{\r\ncabal install SFML --ghc-option=-fsimpl-tick-factor=1630\r\n}}}\r\n\r\nHTH, it turns out it's quite an annoying one! And yes, \"1630\" was the smaller factor which made the installation possible.\r\n\r\nAlfredo","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9447Add support for resizing `MutableByteArray#`s2022-03-20T04:23:44ZHerbert Valerio Riedelhvr@gnu.orgAdd support for resizing `MutableByteArray#`sThis is motivated by #9281 which changes how memory is allocated, and gives rise to the need to be able to efficiently shrink or grow `MutableByteArray#`s before they're frozen into `ByteArray#` while retaining their original byte conten...This is motivated by #9281 which changes how memory is allocated, and gives rise to the need to be able to efficiently shrink or grow `MutableByteArray#`s before they're frozen into `ByteArray#` while retaining their original byte content to avoid a major bottle-neck.
This ticket is for tracking/documenting all changes related to this new facility.
Here's the current road-map:
1. Implement
* `shrinkMutableByteArray# :: MutableByteArray# s -> Int# -> State# s -> State# s`
* `resizeMutableByteArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, MutableByteArray# s #)`
(see [D133](https://phabricator.haskell.org/D133))
1. As suggested by Johan,
`
getSizeofMutableByteArray# :: MutableByteArray# s -> State# s -> (# State# s Int# #)
`
This is similar in spirit to `numCapabilities` and `getNumCapabilities`.
Add a deprecate pragma (or equivalent) for `sizeofMutableByteArray#`.
Add a note to `sizeofMutableByteArray#` stating that it's unsafe in the presence of calls to resize-operations on the same MBA.
1. Submit patches to upstream libraries replacing calls to `sizeofMutableByteArray#` with `getSizeofMutableByteArray#`
1. Investigate how to provide in-place (zero-copy) growing of MBAs (step 1. only implements in-place shrinking).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------------------------------------- |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | [D133](https://phabricator.haskell.org/D133) |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Add support for resizing `MutableByteArray#`s","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[133],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This is motivated by #9281 which changes how memory is allocated, and gives rise to the need to be able to efficiently shrink or grow `MutableByteArray#`s before they're frozen into `ByteArray#` while retaining their original byte content to avoid a major bottle-neck.\r\n\r\nThis ticket is for tracking/documenting all changes related to this new facility.\r\n\r\nHere's the current road-map:\r\n\r\n 1. Implement\r\n {{{#!hs\r\n shrinkMutableByteArray# :: MutableByteArray# s -> Int# -> State# s -> State# s\r\n resizeMutableByteArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, MutableByteArray# s #)\r\n }}}\r\n (see Phab:D133)\r\n\r\n 2. As suggested by Johan,\r\n {{{#!hs\r\n getSizeofMutableByteArray# :: MutableByteArray# s -> State# s -> (# State# s Int# #)\r\n }}}\r\n This is similar in spirit to `numCapabilities` and `getNumCapabilities`.\r\n Add a deprecate pragma (or equivalent) for `sizeofMutableByteArray#`.\r\n Add a note to `sizeofMutableByteArray#` stating that it's unsafe in the presence of calls to resize-operations on the same MBA.\r\n\r\n 3. Submit patches to upstream libraries replacing calls to `sizeofMutableByteArray#` with `getSizeofMutableByteArray#`\r\n\r\n 4. Investigate how to provide in-place (zero-copy) growing of MBAs (step 1. only implements in-place shrinking).","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9450GHC instantiates Data instances before checking hs-boot files2019-07-07T18:40:21ZAlan ZimmermanGHC instantiates Data instances before checking hs-boot filesWhen compiling a file with deriving instances in it and making use of boot files, it appears that the derivation is attempted before the boot files are checked for consistency.
This can lead to GHC panics, as when compiling GHC after th...When compiling a file with deriving instances in it and making use of boot files, it appears that the derivation is attempted before the boot files are checked for consistency.
This can lead to GHC panics, as when compiling GHC after this commit https://github.com/alanz/ghc/commit/c73182ca7345f0debba47d0b17a907bcac27c41f
In the attached files, if you try to load HsLit.lhs into ghci it will complain about the missing Data instance, not about the boot file inconsistency. If you remove the Data from the deriving clause of HsOverLit, it complains about the boot file inconsistency.
I have not managed to reproduce the original panic in this stripped down environment, but if it is needed to more fully understand the problem I can try again to do that.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC instantiates Data instances before checking hs-boot files","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["boot,deriving"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When compiling a file with deriving instances in it and making use of boot files, it appears that the derivation is attempted before the boot files are checked for consistency. \r\n\r\nThis can lead to GHC panics, as when compiling GHC after this commit https://github.com/alanz/ghc/commit/c73182ca7345f0debba47d0b17a907bcac27c41f\r\n\r\nIn the attached files, if you try to load HsLit.lhs into ghci it will complain about the missing Data instance, not about the boot file inconsistency. If you remove the Data from the deriving clause of HsOverLit, it complains about the boot file inconsistency.\r\n\r\nI have not managed to reproduce the original panic in this stripped down environment, but if it is needed to more fully understand the problem I can try again to do that.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9456Weird behavior with polymorphic function involving existential quantification...2019-07-07T18:40:20ZhaasnWeird behavior with polymorphic function involving existential quantification and GADTsThis program is rejected by GHC 7.8.2:
```
{-# LANGUAGE GADTs, ExistentialQuantification #-}
module Foo where
data Box = forall a. Box a
foo :: Monad m => m ()
foo = do
box <- return (Box ())
let f x =
let _ = Box x `asTy...This program is rejected by GHC 7.8.2:
```
{-# LANGUAGE GADTs, ExistentialQuantification #-}
module Foo where
data Box = forall a. Box a
foo :: Monad m => m ()
foo = do
box <- return (Box ())
let f x =
let _ = Box x `asTypeOf` box
in x
g :: a -> a
g = f
return ()
```
With the following type error:
```
foo.hs:15:11:
Couldn't match type ‘a0’ with ‘a’
because type variable ‘a’ would escape its scope
This (rigid, skolem) type variable is bound by
the type signature for g :: a -> a
at foo.hs:14:12-17
Expected type: a -> a
Actual type: a0 -> a0
Relevant bindings include
g :: a -> a (bound at foo.hs:15:7)
f :: a0 -> a0 (bound at foo.hs:10:7)
In the expression: f
In an equation for ‘g’: g = f
```
Perplexingly, however, you can get it to compile either by adding a type signature to f:
```
{-# LANGUAGE GADTs, ExistentialQuantification #-}
module Foo where
data Box = forall a. Box a
foo :: Monad m => m ()
foo = do
box <- return (Box ())
let f :: x -> x
f x =
let _ = Box x `asTypeOf` box
in x
g :: a -> a
g = f
return ()
```
Or by disabling the GADTs extension:
```
{-# LANGUAGE ExistentialQuantification #-}
module Foo where
data Box = forall a. Box a
foo :: Monad m => m ()
foo = do
box <- return (Box ())
let f x =
let _ = Box x `asTypeOf` box
in x
g :: a -> a
g = f
return ()
```
Or by getting rid of the asTypeOf:
```
{-# LANGUAGE GADTs, ExistentialQuantification #-}
module Foo where
data Box = forall a. Box a
foo :: Monad m => m ()
foo = do
box <- return (Box ())
let f x =
let _ = Box x
in x
g :: a -> a
g = f
return ()
```
Or by defining ‘box’ differently:
```
{-# LANGUAGE GADTs, ExistentialQuantification #-}
module Foo where
data Box = forall a. Box a
foo :: Monad m => m ()
foo = do
let box = Box ()
let f x =
let _ = Box x `asTypeOf` box
in x
g :: a -> a
g = f
return ()
```
And perhaps some other factors that I haven't tested yet.
It appears to me that all of these should be valid programs.
Real world source: https://github.com/andygill/io-reactive/blob/master/Control/Concurrent/Reactive.hs
It happens here due to the usage of “writeChan chan $ Req fun ret”, which makes the function requestit in line 77 not as polymorphic as it should be, unless you add a type signature. The putMVar serves the same role as the `asTypeOf` in my smaller example.https://gitlab.haskell.org/ghc/ghc/-/issues/9457hsc2hs breaks with `--cflag=-Werror` in cross-compilation mode2019-07-07T18:40:20Zrwbartonhsc2hs breaks with `--cflag=-Werror` in cross-compilation modeI would like to be able to do
```
config_args='--target=i386-unknown-linux --with-gcc=i386-unknown-linux-gcc' ./validate
```
to validate a 32-bit GHC on a 64-bit Linux system. (I don't know why I have to specify `--with-gcc` in additio...I would like to be able to do
```
config_args='--target=i386-unknown-linux --with-gcc=i386-unknown-linux-gcc' ./validate
```
to validate a 32-bit GHC on a 64-bit Linux system. (I don't know why I have to specify `--with-gcc` in addition to `--target`; an unrelated mystery.)
However `validate` sets `-Werror` and the C code that `hsc2hs` generates in cross-compilation mode is not always warning-free, e.g.,
```
Files.hsc: In function ‘_hsc2hs_test’:
Files.hsc:81:14: error: variable ‘test_array’ set but not used [-Werror=unused-but-set-variable]
cc1: all warnings being treated as errors
```
so `hsc2hs` draws incorrect conclusions from its tests.
Either the `hsc2hs`-generated C code should be made (and kept) warning-free, or perhaps `hsc2hs` should append `-Wwarn` to the options that it passes to the C compiler.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.9 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | hsc2hs |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"hsc2hs breaks with `--cflag=-Werror` in cross-compilation mode","status":"New","operating_system":"","component":"hsc2hs","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I would like to be able to do\r\n{{{\r\nconfig_args='--target=i386-unknown-linux --with-gcc=i386-unknown-linux-gcc' ./validate\r\n}}}\r\nto validate a 32-bit GHC on a 64-bit Linux system. (I don't know why I have to specify `--with-gcc` in addition to `--target`; an unrelated mystery.)\r\n\r\nHowever `validate` sets `-Werror` and the C code that `hsc2hs` generates in cross-compilation mode is not always warning-free, e.g.,\r\n{{{\r\nFiles.hsc: In function ‘_hsc2hs_test’:\r\nFiles.hsc:81:14: error: variable ‘test_array’ set but not used [-Werror=unused-but-set-variable]\r\ncc1: all warnings being treated as errors\r\n}}}\r\nso `hsc2hs` draws incorrect conclusions from its tests.\r\n\r\nEither the `hsc2hs`-generated C code should be made (and kept) warning-free, or perhaps `hsc2hs` should append `-Wwarn` to the options that it passes to the C compiler.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9468Internal error: resurrectThreads: thread blocked in a strange way: 102019-07-07T18:40:19ZNiklas Hambüchenmail@nh2.meInternal error: resurrectThreads: thread blocked in a strange way: 10When running this example program:
https://gist.github.com/nh2/0c68650b78b692e5f827\#file-forkprocess-problem-hs
I get the error:
```
% ghc --make -O forkProcess-problem.hs -threaded && ./forkProcess-problem +RTS -N8
[1 of 1] Compilin...When running this example program:
https://gist.github.com/nh2/0c68650b78b692e5f827\#file-forkprocess-problem-hs
I get the error:
```
% ghc --make -O forkProcess-problem.hs -threaded && ./forkProcess-problem +RTS -N8
[1 of 1] Compiling Main ( forkProcess-problem.hs, forkProcess-problem.o )
Linking forkProcess-problem ...
forkProcess-problem: internal error: resurrectThreads: thread blocked in a strange way: 10
(GHC version 7.8.3 for x86_64_unknown_linux)
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
Also happens for GHC 7.6.3. My machines are Ubuntu 12.04 and 14.04.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------- |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | edsko, simonmar |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Internal error: resurrectThreads: thread blocked in a strange way: 10","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonmar"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["edsko","simonmar"],"type":"Bug","description":"When running this example program:\r\n\r\nhttps://gist.github.com/nh2/0c68650b78b692e5f827#file-forkprocess-problem-hs\r\n\r\nI get the error:\r\n\r\n{{{\r\n% ghc --make -O forkProcess-problem.hs -threaded && ./forkProcess-problem +RTS -N8\r\n[1 of 1] Compiling Main ( forkProcess-problem.hs, forkProcess-problem.o )\r\nLinking forkProcess-problem ...\r\nforkProcess-problem: internal error: resurrectThreads: thread blocked in a strange way: 10\r\n(GHC version 7.8.3 for x86_64_unknown_linux)\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n}}}\r\n\r\nAlso happens for GHC 7.6.3. My machines are Ubuntu 12.04 and 14.04.","type_of_failure":"OtherFailure","blocking":[]} -->Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/9470forkProcess breaks in multiple ways with GHC 7.62019-07-07T18:40:19ZNiklas Hambüchenmail@nh2.meforkProcess breaks in multiple ways with GHC 7.6When I run this program using `forkProcess`
https://gist.github.com/nh2/0c68650b78b692e5f827\#file-forkprocess-problem-hs
in GHC 7.6.3 on Ubuntu 12.04 and 14.04 I get at 4 different issues. Three of them (1-3) crash the program, and ha...When I run this program using `forkProcess`
https://gist.github.com/nh2/0c68650b78b692e5f827\#file-forkprocess-problem-hs
in GHC 7.6.3 on Ubuntu 12.04 and 14.04 I get at 4 different issues. Three of them (1-3) crash the program, and happen only on some startups, the fourth one is the part for which I originally wrote this test case.
1. A segfault shortly after startup (probably in the GC)
1. `internal error: resurrectThreads: thread blocked in a strange way: 10` at startup
1. A glibc `corrupted double-linked list` shortly after startup
1. The `running, killing by SIGTERM` case inside my program
Now come the details for each of them:
1. I managed to get a gdb trace of it (https://gist.github.com/nh2/0c68650b78b692e5f827\#file-error-ghc-7-69468-3-linux-segfault-gdb-txt) and also a trace with the `-debug` runtime (https://gist.github.com/nh2/0c68650b78b692e5f827\#file-error-ghc-7-6-3-linux-debug-segfault-gdb-txt). They suggest that the segfault is in `evacuate()`, and the `-debug` one says it's in the `LOOKS_LIKE_CLOSURE_PTR` part.
1. This is the same as my newly reported #9468 and I have no clue what that's about. Output: https://gist.github.com/nh2/0c68650b78b692e5f827\#file-error-ghc-7-6-3-linux-threaded-resurrectthreads-txt
1. This one happens very rarely; might be related to 1? Output: https://gist.github.com/nh2/0c68650b78b692e5f827\#file-error-ghc-7-6-3-linux-glibc-txt
1. The problem here is the `Nothing` case: The child process didn't answer from the pipe, and that although it is still running, so it really should have answered. It seems that for every 20th fork or so, the child process just hangs.
All files, error outputs and IRC logs are also collected in this gist: https://gist.github.com/nh2/0c68650b78b692e5f827
For getting issues (1-3), you have to run them multiple times in order to reproduce; if they appear, they will appear within the first second after startup. Which of the issue appears is dependent on how many `_FORKS` you set (with a high number like the default 80, you mostly get issue 2; set down to 8 to make the other ones more probably) and with how many `+RTS -N` threads you run.
2 and 4 are definitely present in 7.8.3 as well.
For 1 and 3, it would be great if you could tell me whether these are known issues and are known to be fixed in 7.8.Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/9481Linker does not correctly resolve symbols in previously loaded objects2019-07-07T18:40:17Zedsko@edsko.netLinker does not correctly resolve symbols in previously loaded objects**Summary**: Given two object files (created from C files) A and B, where B refers to symbols defined in A, if we load B before A, calling `resolveObjs` after each object file, symbol resolution goes wrong. Full test case attached.
**De...**Summary**: Given two object files (created from C files) A and B, where B refers to symbols defined in A, if we load B before A, calling `resolveObjs` after each object file, symbol resolution goes wrong. Full test case attached.
**Detailed description**: Consider
```c
// a.c
#include <stdio.h>
void defined_in_A() {
printf("In A\n");
}
```
```c
// b.c
#include <stdio.h>
void defined_in_A();
void defined_in_B() {
printf("In B\n");
defined_in_A();
printf("In B\n");
}
```
and
```hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import System.IO
foreign import ccall "defined_in_B" defined_in_B :: IO ()
main :: IO ()
main = defined_in_B
```
and we use the GHC API to load the object files `a.o` and `b.o` (corresponding to `a.c` and `b.c`), calling `resolveObjs` after loading each object, and then load `Main` and call `Main.main`, everything works fine (the attached test case contains both `a.c`, `b.c` and `Main.hs` as well as the test program that calls into the GHC API).
However, if we load `b.o` *before* `a.o`, things go wrong. When we load `b.o` and call `resolveObjs` then `resolveObjs` (quite reasonably) complains that
```
lookupSymbol failed in relocateSection (relocate external)
b.o: unknown symbol `_defined_in_A'
```
since we haven't loaded `a.o` yet. But when we then load `a.o` and call `resolveObjs` again, `resolveObjs` reports okay, but something goes wrong because the program subsequently segfaults.
**A successful run**
I took a closer look at what happens exactly. First, let's consider the test run where we load A before B, and everything works fine, and let's look at the precise code that we actually execute when `Main.main` does the foreign call to `defined_in_B`:
```
# lldb Linkerbug
Current executable set to 'Linkerbug' (x86_64).
(lldb) breakpoint set -n ffi_call
Breakpoint 1: where = Linkerbug`ffi_call + 29 at ffi64.c:421, address = 0x0000000102be2eed
(lldb) run
Process 92361 launched: 'Linkerbug' (x86_64)
Loading object "a.o"
symbol resolution ok
Loading object "b.o"
symbol resolution ok
Loading Haskell module "Main.hs"
ok
Running "Main.main"
Process 92361 stopped
* thread #1: tid = 0x32048b, 0x0000000102be2eed Linkerbug`ffi_call(cif=0x000000010cc68500, fn=0x0000000104c6c210, rvalue=0x00007fff5fbff920, avalue=0x00007fff5fbff8c0) + 29 at ffi64.c:421, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000102be2eed Linkerbug`ffi_call(cif=0x000000010cc68500, fn=0x0000000104c6c210, rvalue=0x00007fff5fbff920, avalue=0x00007fff5fbff8c0) + 29 at ffi64.c:421
(lldb) disassemble -c 14 -s fn
0x104c6c210: pushq %rbp
0x104c6c211: movq %rsp, %rbp
0x104c6c214: pushq %rbx
0x104c6c215: pushq %rax
0x104c6c216: leaq 0x1d(%rip), %rbx
0x104c6c21d: movq %rbx, %rdi
0x104c6c220: callq 0x104c6c3c8
0x104c6c225: xorl %eax, %eax
0x104c6c227: callq 0x104c6b210
0x104c6c22c: movq %rbx, %rdi
0x104c6c22f: addq $0x8, %rsp
0x104c6c233: popq %rbx
0x104c6c234: popq %rbp
0x104c6c235: jmpq 0x104c6c3c8
```
This disassembly is the compiled code for B which, in order, does a call to `printf`, then to `defined_in_A`, and then back to `printf` (the last call is `jmpq` rather than `callq`: the C compiler did a tail call optimization). Let's make sure that this is actually true; the first call is a call to
```
(lldb) disassemble -c 2 -s 0x104c6c3c8
0x104c6c3c8: jmpq *-0xe(%rip)
0x104c6c3ce: addb %al, (%rax)
```
which is an indirect jump to
```
(lldb) memory read -f A -c 1 "0x104c6c3ce - 0xe"
0x104c6c3c0: 0x00007fff84fd5b9b libsystem_c.dylib`puts
```
to `puts`, okay, good. Seems an unnecessary level of indirection, but that's okay. The next call is to
```
(lldb) disassemble -c 5 -s 0x104c6b210
0x104c6b210: pushq %rbp
0x104c6b211: movq %rsp, %rbp
0x104c6b214: leaq 0x6(%rip), %rdi
0x104c6b21b: popq %rbp
0x104c6b21c: jmpq 0x104c6b370
```
which is the compiled code for `defined_in_A`, which should be just a call to `printf`. Let's confirm:
```
(lldb) disassemble -c 2 -s 0x104c6b370
0x104c6b370: jmpq *-0xe(%rip)
0x104c6b376: addb %al, (%rax)
(lldb) memory read -f A -c 1 "0x104c6b376 - 0xe"
0x104c6b368: 0x00007fff84fd5b9b libsystem_c.dylib`puts
```
Ok, all good.
**A failed run**
Now let's check what happens when we load the objects in the opposite order. The code that we execute is
```
(lldb) disassemble -c 14 -s fn
0x104c6b210: pushq %rbp
0x104c6b211: movq %rsp, %rbp
0x104c6b214: pushq %rbx
0x104c6b215: pushq %rax
0x104c6b216: leaq 0x1d(%rip), %rbx
0x104c6b21d: movq %rbx, %rdi
0x104c6b220: callq 0x104c6b3c8
0x104c6b225: xorl %eax, %eax
0x104c6b227: callq 0x104c6c210
0x104c6b22c: movq %rbx, %rdi
0x104c6b22f: addq $0x8, %rsp
0x104c6b233: popq %rbx
0x104c6b234: popq %rbp
0x104c6b235: jmpq 0x104c6b556
```
This immediately looks suspicious: the address of the `jmpq` (the second -- tail -- call to `printf`) is different from the first. The first `callq` is okay:
```
(lldb) disassemble -c 2 -s 0x104c6b3c8
0x104c6b3c8: jmpq *-0xe(%rip)
0x104c6b3ce: addb %al, (%rax)
(lldb) memory read -f A -c 1 "0x104c6b3ce - 0xe"
0x104c6b3c0: 0x00007fff84fd5b9b libsystem_c.dylib`puts
```
and the call to `defined_in_A`, as well as the code *for* `defined_in_A`, are both ok:
```
(lldb) disassemble -c 5 -s 0x104c6c210
0x104c6c210: pushq %rbp
0x104c6c211: movq %rsp, %rbp
0x104c6c214: leaq 0x6(%rip), %rdi
0x104c6c21b: popq %rbp
0x104c6c21c: jmpq 0x104c6c370
(lldb) disassemble -c 2 -s 0x104c6c370
0x104c6c370: jmpq *-0xe(%rip)
0x104c6c376: addb %al, (%rax)
(lldb) memory read -f A -c 1 "0x104c6c376 - 0xe"
0x104c6c368: 0x00007fff84fd5b9b libsystem_c.dylib`puts
```
However, that second call to `printf` (the `jmpq`) in `defined_in_B` is indeed wrong: it's jumping into nowhere:
```
(lldb) memory read -c 8 0x104c6b556
0x104c6b556: 00 00 00 00 00 00 00 00 ........
```
Note that somewhat surprisingly is it *not* the resolution of the symbol from `a.o` that is wrong; that *does* get resolved okay once we load `a.o`; rather, it is the jump to `puts` which is wrong (and then only the one of them).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------- |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonmar |
| Operating system | Unknown/Multiple |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Linker does not correctly resolve symbols in previously loaded objects","status":"New","operating_system":"Unknown/Multiple","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"Bug","description":"'''Summary''': Given two object files (created from C files) A and B, where B refers to symbols defined in A, if we load B before A, calling `resolveObjs` after each object file, symbol resolution goes wrong. Full test case attached.\r\n\r\n'''Detailed description''': Consider\r\n\r\n{{{#!c\r\n// a.c\r\n#include <stdio.h>\r\n\r\nvoid defined_in_A() {\r\n printf(\"In A\\n\");\r\n}\r\n}}}\r\n\r\n{{{#!c\r\n// b.c\r\n#include <stdio.h>\r\n\r\nvoid defined_in_A();\r\n\r\nvoid defined_in_B() {\r\n printf(\"In B\\n\");\r\n defined_in_A();\r\n printf(\"In B\\n\");\r\n}\r\n}}}\r\n\r\nand\r\n\r\n{{{#!hs\r\n{-# LANGUAGE ForeignFunctionInterface #-}\r\nmodule Main where\r\n\r\nimport System.IO\r\n\r\nforeign import ccall \"defined_in_B\" defined_in_B :: IO ()\r\n\r\nmain :: IO ()\r\nmain = defined_in_B\r\n}}}\r\n\r\nand we use the GHC API to load the object files `a.o` and `b.o` (corresponding to `a.c` and `b.c`), calling `resolveObjs` after loading each object, and then load `Main` and call `Main.main`, everything works fine (the attached test case contains both `a.c`, `b.c` and `Main.hs` as well as the test program that calls into the GHC API). \r\n\r\nHowever, if we load `b.o` ''before'' `a.o`, things go wrong. When we load `b.o` and call `resolveObjs` then `resolveObjs` (quite reasonably) complains that\r\n\r\n{{{\r\nlookupSymbol failed in relocateSection (relocate external)\r\nb.o: unknown symbol `_defined_in_A'\r\n}}}\r\n\r\nsince we haven't loaded `a.o` yet. But when we then load `a.o` and call `resolveObjs` again, `resolveObjs` reports okay, but something goes wrong because the program subsequently segfaults.\r\n\r\n'''A successful run'''\r\n\r\nI took a closer look at what happens exactly. First, let's consider the test run where we load A before B, and everything works fine, and let's look at the precise code that we actually execute when `Main.main` does the foreign call to `defined_in_B`:\r\n\r\n{{{\r\n# lldb Linkerbug\r\nCurrent executable set to 'Linkerbug' (x86_64).\r\n\r\n(lldb) breakpoint set -n ffi_call\r\nBreakpoint 1: where = Linkerbug`ffi_call + 29 at ffi64.c:421, address = 0x0000000102be2eed\r\n\r\n(lldb) run\r\nProcess 92361 launched: 'Linkerbug' (x86_64)\r\nLoading object \"a.o\"\r\n symbol resolution ok\r\nLoading object \"b.o\"\r\n symbol resolution ok\r\nLoading Haskell module \"Main.hs\"\r\n ok\r\nRunning \"Main.main\"\r\nProcess 92361 stopped\r\n* thread #1: tid = 0x32048b, 0x0000000102be2eed Linkerbug`ffi_call(cif=0x000000010cc68500, fn=0x0000000104c6c210, rvalue=0x00007fff5fbff920, avalue=0x00007fff5fbff8c0) + 29 at ffi64.c:421, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1\r\n frame #0: 0x0000000102be2eed Linkerbug`ffi_call(cif=0x000000010cc68500, fn=0x0000000104c6c210, rvalue=0x00007fff5fbff920, avalue=0x00007fff5fbff8c0) + 29 at ffi64.c:421\r\n\r\n(lldb) disassemble -c 14 -s fn\r\n 0x104c6c210: pushq %rbp\r\n 0x104c6c211: movq %rsp, %rbp\r\n 0x104c6c214: pushq %rbx\r\n 0x104c6c215: pushq %rax\r\n 0x104c6c216: leaq 0x1d(%rip), %rbx\r\n 0x104c6c21d: movq %rbx, %rdi\r\n 0x104c6c220: callq 0x104c6c3c8\r\n 0x104c6c225: xorl %eax, %eax\r\n 0x104c6c227: callq 0x104c6b210\r\n 0x104c6c22c: movq %rbx, %rdi\r\n 0x104c6c22f: addq $0x8, %rsp\r\n 0x104c6c233: popq %rbx\r\n 0x104c6c234: popq %rbp\r\n 0x104c6c235: jmpq 0x104c6c3c8\r\n}}}\r\n\r\nThis disassembly is the compiled code for B which, in order, does a call to `printf`, then to `defined_in_A`, and then back to `printf` (the last call is `jmpq` rather than `callq`: the C compiler did a tail call optimization). Let's make sure that this is actually true; the first call is a call to\r\n\r\n{{{\r\n(lldb) disassemble -c 2 -s 0x104c6c3c8\r\n 0x104c6c3c8: jmpq *-0xe(%rip)\r\n 0x104c6c3ce: addb %al, (%rax)\r\n}}}\r\n\r\nwhich is an indirect jump to\r\n\r\n{{{\r\n(lldb) memory read -f A -c 1 \"0x104c6c3ce - 0xe\"\r\n0x104c6c3c0: 0x00007fff84fd5b9b libsystem_c.dylib`puts\r\n}}}\r\n\r\nto `puts`, okay, good. Seems an unnecessary level of indirection, but that's okay. The next call is to\r\n\r\n{{{\r\n(lldb) disassemble -c 5 -s 0x104c6b210\r\n 0x104c6b210: pushq %rbp\r\n 0x104c6b211: movq %rsp, %rbp\r\n 0x104c6b214: leaq 0x6(%rip), %rdi\r\n 0x104c6b21b: popq %rbp\r\n 0x104c6b21c: jmpq 0x104c6b370\r\n}}}\r\n\r\nwhich is the compiled code for `defined_in_A`, which should be just a call to `printf`. Let's confirm:\r\n\r\n{{{\r\n(lldb) disassemble -c 2 -s 0x104c6b370\r\n 0x104c6b370: jmpq *-0xe(%rip)\r\n 0x104c6b376: addb %al, (%rax)\r\n\r\n(lldb) memory read -f A -c 1 \"0x104c6b376 - 0xe\"\r\n0x104c6b368: 0x00007fff84fd5b9b libsystem_c.dylib`puts\r\n}}}\r\n\r\nOk, all good. \r\n\r\n'''A failed run'''\r\n\r\nNow let's check what happens when we load the objects in the opposite order. The code that we execute is\r\n\r\n{{{\r\n(lldb) disassemble -c 14 -s fn\r\n 0x104c6b210: pushq %rbp\r\n 0x104c6b211: movq %rsp, %rbp\r\n 0x104c6b214: pushq %rbx\r\n 0x104c6b215: pushq %rax\r\n 0x104c6b216: leaq 0x1d(%rip), %rbx\r\n 0x104c6b21d: movq %rbx, %rdi\r\n 0x104c6b220: callq 0x104c6b3c8\r\n 0x104c6b225: xorl %eax, %eax\r\n 0x104c6b227: callq 0x104c6c210\r\n 0x104c6b22c: movq %rbx, %rdi\r\n 0x104c6b22f: addq $0x8, %rsp\r\n 0x104c6b233: popq %rbx\r\n 0x104c6b234: popq %rbp\r\n 0x104c6b235: jmpq 0x104c6b556\r\n}}}\r\n\r\nThis immediately looks suspicious: the address of the `jmpq` (the second -- tail -- call to `printf`) is different from the first. The first `callq` is okay:\r\n\r\n{{{\r\n(lldb) disassemble -c 2 -s 0x104c6b3c8\r\n 0x104c6b3c8: jmpq *-0xe(%rip)\r\n 0x104c6b3ce: addb %al, (%rax)\r\n\r\n(lldb) memory read -f A -c 1 \"0x104c6b3ce - 0xe\"\r\n0x104c6b3c0: 0x00007fff84fd5b9b libsystem_c.dylib`puts\r\n}}}\r\n\r\nand the call to `defined_in_A`, as well as the code ''for'' `defined_in_A`, are both ok:\r\n\r\n{{{\r\n(lldb) disassemble -c 5 -s 0x104c6c210\r\n 0x104c6c210: pushq %rbp\r\n 0x104c6c211: movq %rsp, %rbp\r\n 0x104c6c214: leaq 0x6(%rip), %rdi\r\n 0x104c6c21b: popq %rbp\r\n 0x104c6c21c: jmpq 0x104c6c370\r\n\r\n(lldb) disassemble -c 2 -s 0x104c6c370\r\n 0x104c6c370: jmpq *-0xe(%rip)\r\n 0x104c6c376: addb %al, (%rax)\r\n\r\n(lldb) memory read -f A -c 1 \"0x104c6c376 - 0xe\"\r\n0x104c6c368: 0x00007fff84fd5b9b libsystem_c.dylib`puts\r\n}}}\r\n\r\nHowever, that second call to `printf` (the `jmpq`) in `defined_in_B` is indeed wrong: it's jumping into nowhere:\r\n\r\n{{{\r\n(lldb) memory read -c 8 0x104c6b556\r\n0x104c6b556: 00 00 00 00 00 00 00 00 ........\r\n}}}\r\n\r\nNote that somewhat surprisingly is it ''not'' the resolution of the symbol from `a.o` that is wrong; that ''does'' get resolved okay once we load `a.o`; rather, it is the jump to `puts` which is wrong (and then only the one of them).","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9496Simplify primitives for short cut fusion2019-07-07T18:40:16ZDavid FeuerSimplify primitives for short cut fusionCurrently, there appear to be two production primitives, `build` and `augment` (although I may have missed some). There are multiple consumption primitives (at least: `foldr`, `head`, `and`, `or`, `any`, and `all`). The rule sets for som...Currently, there appear to be two production primitives, `build` and `augment` (although I may have missed some). There are multiple consumption primitives (at least: `foldr`, `head`, `and`, `or`, `any`, and `all`). The rule sets for some producers seem to forget to handle `augment`, and the `augment/augment` rule is omitted as "true, but not, I think, useful".
A number of other functions are instead rewritten into `foldr` forms, and then written back if they don't fuse.
## What to do:
Personally, I'd be very tempted to start by saying `build g = augment g []` (or *possibly* even `build g = extend [] g []` if I can ever get that idea to work) and cut the problem in half. The main problem I see with this is if other people are importing `GHC.Exts` or `GHC.Base`, writing things with `build`, and expecting them to fuse. One way to deal with this, perhaps, is to hack a special rule into the RULES compiler to recognize `GHC.Base.build` on the LHS of RULES and replace it with the appropriate `augment` form, emitting a warning.
Where to go after that: the question remains whether it's best in general to rewrite a form to `foldr` to make it fuse, or to fuse directly with `augment`. The answer presumably depends, at least in part, on whether there are additional `foldr`-based rules we may want to add that would take advantage of the effort put into the translation back from the `foldr` form. I would conjecture that most such rules we could want would go beyond what the RULES system actually can do. That said, if we can find a way to use `foldr` forms without the horrible pain of translating back from them, that would be a very good thing.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.3 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | ekmett, hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Simplify primitives for short cut fusion","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["fusion"],"differentials":[],"test_case":"","architecture":"","cc":["ekmett","hvr"],"type":"Task","description":"Currently, there appear to be two production primitives, `build` and `augment` (although I may have missed some). There are multiple consumption primitives (at least: `foldr`, `head`, `and`, `or`, `any`, and `all`). The rule sets for some producers seem to forget to handle `augment`, and the `augment/augment` rule is omitted as \"true, but not, I think, useful\".\r\n\r\nA number of other functions are instead rewritten into `foldr` forms, and then written back if they don't fuse. \r\n\r\n== What to do: ==\r\n\r\nPersonally, I'd be very tempted to start by saying `build g = augment g []` (or ''possibly'' even `build g = extend [] g []` if I can ever get that idea to work) and cut the problem in half. The main problem I see with this is if other people are importing `GHC.Exts` or `GHC.Base`, writing things with `build`, and expecting them to fuse. One way to deal with this, perhaps, is to hack a special rule into the RULES compiler to recognize `GHC.Base.build` on the LHS of RULES and replace it with the appropriate `augment` form, emitting a warning.\r\n\r\nWhere to go after that: the question remains whether it's best in general to rewrite a form to `foldr` to make it fuse, or to fuse directly with `augment`. The answer presumably depends, at least in part, on whether there are additional `foldr`-based rules we may want to add that would take advantage of the effort put into the translation back from the `foldr` form. I would conjecture that most such rules we could want would go beyond what the RULES system actually can do. That said, if we can find a way to use `foldr` forms without the horrible pain of translating back from them, that would be a very good thing.","type_of_failure":"OtherFailure","blocking":[]} -->⊥David FeuerDavid Feuerhttps://gitlab.haskell.org/ghc/ghc/-/issues/9498GHC links against unversioned .so files2019-12-02T17:01:14ZSven Bartschersven.bartscher@weltraumschlangen.deGHC links against unversioned .so filesGreetings,
GHC tries to load unversioned dynamic libraries instead of versioned (i.e. libfoo.so instead of libfoo.so.1.2.3).
This is a problem, since Distributions like Debian (I don't know about other distributions) don't include unver...Greetings,
GHC tries to load unversioned dynamic libraries instead of versioned (i.e. libfoo.so instead of libfoo.so.1.2.3).
This is a problem, since Distributions like Debian (I don't know about other distributions) don't include unversioned .SOs in their runtime packages and the unversioned are only available in the -dev packages as a symlink to the verioned ones.
This means FFI libraries depend on the -dev packages, even though they don't really need them.
It would be nice if GHC would try to load the versioned libraries as well.
Regards
Sven
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.6.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | Compiler (FFI) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC links against unversioned .so files","status":"New","operating_system":"","component":"Compiler (FFI)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":["Debian"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Greetings,\r\n\r\nGHC tries to load unversioned dynamic libraries instead of versioned (i.e. libfoo.so instead of libfoo.so.1.2.3).\r\nThis is a problem, since Distributions like Debian (I don't know about other distributions) don't include unversioned .SOs in their runtime packages and the unversioned are only available in the -dev packages as a symlink to the verioned ones.\r\nThis means FFI libraries depend on the -dev packages, even though they don't really need them.\r\nIt would be nice if GHC would try to load the versioned libraries as well.\r\n\r\nRegards\r\nSven","type_of_failure":"OtherFailure","blocking":[]} -->Peter Trommlerptrommler@acm.orgPeter Trommlerptrommler@acm.orghttps://gitlab.haskell.org/ghc/ghc/-/issues/9503Cross compiling with mingw uses wrong gcc2019-07-07T18:40:15ZSven Bartschersven.bartscher@weltraumschlangen.deCross compiling with mingw uses wrong gccGreetings,
I tried to cross compile a cross compiler ghc on Debian jessie Linux/GNU i386.
I configured with "./configure --target=x86_64-w64-mingw32" (log attached).
The configure script runs and then wants to use the native gcc (/usr/b...Greetings,
I tried to cross compile a cross compiler ghc on Debian jessie Linux/GNU i386.
I configured with "./configure --target=x86_64-w64-mingw32" (log attached).
The configure script runs and then wants to use the native gcc (/usr/bin/gcc) instead of the mingw one (/usr/bin//usr/bin/x86_64-w64-mingw32-gcc).
Thus the mingw headers (in /usr/x86_64-w64-mingw32/include/) aren't found, which leads to errors during compiling (relevant part attached).
Regards
Sven
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Build System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Cross compiling with mingw uses wrong gcc","status":"New","operating_system":"","component":"Build System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["Cross","compiling"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Greetings,\r\n\r\nI tried to cross compile a cross compiler ghc on Debian jessie Linux/GNU i386.\r\nI configured with \"./configure --target=x86_64-w64-mingw32\" (log attached).\r\nThe configure script runs and then wants to use the native gcc (/usr/bin/gcc) instead of the mingw one (/usr/bin//usr/bin/x86_64-w64-mingw32-gcc).\r\nThus the mingw headers (in /usr/x86_64-w64-mingw32/include/) aren't found, which leads to errors during compiling (relevant part attached).\r\n\r\nRegards\r\nSven","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9505Bounded instance for Word (and possibly others) uses explicitly unboxed literals2019-07-07T18:40:14ZschylerBounded instance for Word (and possibly others) uses explicitly unboxed literalsThere's a comment above saying GHC won't optimise. I think since 7.8 they are unboxed by default, so that comment and the explicit constructors can be removed.
<details><summary>Trac metadata</summary>
| Trac field | Value ...There's a comment above saying GHC won't optimise. I think since 7.8 they are unboxed by default, so that comment and the explicit constructors can be removed.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Bounded instance for Word (and possibly others) uses unboxed literals","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"There's a comment above saying GHC won't optimise. I think since 7.8 they are unboxed by default, so that comment and the explicit constructors can be removed.","type_of_failure":"OtherFailure","blocking":[]} -->⊥Edward KmettEdward Kmetthttps://gitlab.haskell.org/ghc/ghc/-/issues/9511Remove deprecated -fglasgow-exts from NoFib suite2019-07-07T18:40:13ZDavid FeuerRemove deprecated -fglasgow-exts from NoFib suiteSomeone on \#ghc noted that replacing -fglasgow-exts with only the necessary options in each case may change compile times, which may be undesirable. I think a reasonable workaround would be to just put all the options on the command lin...Someone on \#ghc noted that replacing -fglasgow-exts with only the necessary options in each case may change compile times, which may be undesirable. I think a reasonable workaround would be to just put all the options on the command line, whether necessary or not. This will increase the time needed to parse the command lines, but presumably by a trivial amount.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------------- |
| Version | 7.8.3 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | NoFib benchmark suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Remove deprecated -fglasgow-exts from NoFib suite","status":"New","operating_system":"","component":"NoFib benchmark suite","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Someone on #ghc noted that replacing -fglasgow-exts with only the necessary options in each case may change compile times, which may be undesirable. I think a reasonable workaround would be to just put all the options on the command line, whether necessary or not. This will increase the time needed to parse the command lines, but presumably by a trivial amount.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9512T9329 fails test on unregisterised i386, amd642019-07-07T18:40:13ZSergei TrofimovichT9329 fails test on unregisterised i386, amd64ghc-HEAD **./configure --enable-unregistersied** on i386-linux fails as:
```
=====> T9329(normal) 118 of 4091 [0, 0, 0]
cd ./codeGen/should_compile && '/root/ghc/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-...ghc-HEAD **./configure --enable-unregistersied** on i386-linux fails as:
```
=====> T9329(normal) 118 of 4091 [0, 0, 0]
cd ./codeGen/should_compile && '/root/ghc/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts -optc-fno-builtin -fno-ghci-history -c T9329.cmm -no-hs-main >T9329.comp.stderr 2>&1
Compile failed (status 256) errors were:
/tmp/ghc23160_0/ghc23160_2.hc: In function ‘foo’:
/tmp/ghc23160_0/ghc23160_2.hc:10:12:
error: ‘c0_info’ undeclared (first use in this function)
*Sp = (W_)&c0_info;
^
/tmp/ghc23160_0/ghc23160_2.hc:10:12:
note: each undeclared identifier is reported only once for each function it appears in
```
The generated C code is:
```
/* GHC_PACKAGES
*/
#include "Stg.h"
FN_(foo) {
FB_
_c0:
if ((W_)(((W_)Sp-4) < (W_)SpLim)) goto _c2; else goto _c3;
_c2:
*Sp = (W_)&c0_info;
JMP_((W_)&stg_gc_noregs);
_c3:
R1.w = 0x0;
JMP_(*((P_)(*Sp)));
FE_
}
```
while on UNREG x86_64 test does not fail and generates the following C:
```
/* GHC_PACKAGES
*/
#include "Stg.h"
FN_(foo) {
FB_
_c0:
goto _c3;
_c3:
R1.w = 0x0;
JMP_(*((P_)(*Sp)));
FE_
}
```
Looks like there is no stack check at all.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonmar |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"T9329 fails test on unregisterised i386","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"Bug","description":"ghc-HEAD '''./configure --enable-unregistersied''' on i386-linux fails as:\r\n\r\n{{{\r\n=====> T9329(normal) 118 of 4091 [0, 0, 0] \r\ncd ./codeGen/should_compile && '/root/ghc/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts -optc-fno-builtin -fno-ghci-history -c T9329.cmm -no-hs-main >T9329.comp.stderr 2>&1\r\nCompile failed (status 256) errors were:\r\n/tmp/ghc23160_0/ghc23160_2.hc: In function ‘foo’:\r\n\r\n/tmp/ghc23160_0/ghc23160_2.hc:10:12:\r\n error: ‘c0_info’ undeclared (first use in this function)\r\n *Sp = (W_)&c0_info;\r\n ^\r\n\r\n/tmp/ghc23160_0/ghc23160_2.hc:10:12:\r\n note: each undeclared identifier is reported only once for each function it appears in\r\n}}}\r\n\r\nThe generated C code is:\r\n{{{\r\n/* GHC_PACKAGES \r\n*/\r\n#include \"Stg.h\"\r\n\r\nFN_(foo) {\r\nFB_\r\n_c0:\r\nif ((W_)(((W_)Sp-4) < (W_)SpLim)) goto _c2; else goto _c3;\r\n_c2:\r\n*Sp = (W_)&c0_info;\r\nJMP_((W_)&stg_gc_noregs);\r\n_c3:\r\nR1.w = 0x0;\r\nJMP_(*((P_)(*Sp)));\r\nFE_\r\n}\r\n}}}\r\n\r\nwhile on UNREG x86_64 test does not fail and generates the following C:\r\n{{{\r\n/* GHC_PACKAGES \r\n*/\r\n#include \"Stg.h\"\r\n\r\nFN_(foo) {\r\nFB_\r\n_c0:\r\ngoto _c3;\r\n_c3:\r\nR1.w = 0x0;\r\nJMP_(*((P_)(*Sp)));\r\nFE_\r\n}\r\n}}}\r\n\r\nLooks like there is no stack check at all.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9518Improve error message for unacceptable role annotations2023-12-06T21:12:16ZdmccleanImprove error message for unacceptable role annotationsIt would be nice if this message:
```
Role mismatch on variable a:
Annotation says representational but role nominal is required
while checking a role annotation for `Point'
```
Could be extended to say where the requirement arises.
...It would be nice if this message:
```
Role mismatch on variable a:
Annotation says representational but role nominal is required
while checking a role annotation for `Point'
```
Could be extended to say where the requirement arises.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Improve error message for unacceptable role annotations","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"It would be nice if this message:\r\n\r\n{{{\r\nRole mismatch on variable a:\r\n Annotation says representational but role nominal is required\r\nwhile checking a role annotation for `Point'\r\n}}}\r\n\r\nCould be extended to say where the requirement arises.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9522SPECIALISE pragmas for derived instances2023-06-16T08:33:20ZSimon Peyton JonesSPECIALISE pragmas for derived instancesIn package `ghc-prim`, in `GHC.Classes` we have
```
instance (Eq a) => Eq [a] where
{-# SPECIALISE instance Eq [[Char]] #-}
{-# SPECIALISE instance Eq [Char] #-}
{-# SPECIALISE instance Eq [Int] #-}
[] == [] = Tr...In package `ghc-prim`, in `GHC.Classes` we have
```
instance (Eq a) => Eq [a] where
{-# SPECIALISE instance Eq [[Char]] #-}
{-# SPECIALISE instance Eq [Char] #-}
{-# SPECIALISE instance Eq [Int] #-}
[] == [] = True
(x:xs) == (y:ys) = x == y && xs == ys
_xs == _ys = False
```
The `SPECIALISE instance` pragmas instantiate the code for these commonly-used types.
But for tuples we use `deriving`:
```
deriving instance (Eq a, Eq b) => Eq (a, b)
```
and many more similar. There is no way to add a `SPECIALISE instance` pragma for a derived instance. This is bad, because they are heavily used.
You can see the lossage from messages lie
```
WARNING: file compiler/specialise/Specialise.lhs, line 673
specImport discarding:
GHC.Classes.$w$c== :: forall a b. (Eq a, Eq b) => a -> b -> a -> b -> Bool
@ Module.Module @ Module.Module Module.$fEqModule Module.$fEqModule
```
which says that we will end up calling `$w$c==` for pairs of modules, passing dictionaries to compare the modules for equality. These messages show up when compiling the libraries if you build your stage1 compiler with `-DDEBUG`.
It should probably be possible to have a top-level
```
{-# SPECIALISE instance Eq (Int, Bool) #-}
```
even in another module (as we can now do for functions. To do this right, we'd need to make the code for derived methods `INLINEALBE`.https://gitlab.haskell.org/ghc/ghc/-/issues/9534IEEE Standard 754 for Binary Floating-Point Arithmetic by Prof. W. Kahan, UCB2019-07-07T18:40:07Zjrp2014IEEE Standard 754 for Binary Floating-Point Arithmetic by Prof. W. Kahan, UCBThe attached is an implementation of the floating point accuracy test described in *The Baleful Influence of Benchmarks* section of http://www.eecs.berkeley.edu/\~wkahan/ieee754status/IEEE754.PDF
```
Results for Float:
r = 4098.0 produc...The attached is an implementation of the floating point accuracy test described in *The Baleful Influence of Benchmarks* section of http://www.eecs.berkeley.edu/\~wkahan/ieee754status/IEEE754.PDF
```
Results for Float:
r = 4098.0 produces 12.0 and 12.0 sig. bits
r = 4098.25 fails: root 0.99989897 isn't at least 1 <<<<
r = 4097.004 produces 12.0 and 11.999298 sig. bits
:
Worst accuracy is 11.999298 sig. bits
:
Results for Double:
r = 4098.0 produces Infinity and Infinity sig. bits
r = 4098.25 produces Infinity and 53.0 sig. bits
r = 4097.00390625 produces Infinity and 53.451178091541244 sig. bits
r = 1.6777218e7 produces Infinity and Infinity sig. bits
r = 1.677721825e7 produces Infinity and 75.0 sig. bits
r = 1.6777219e7 produces Infinity and 71.0 sig. bits
r = 9.4906267e7 produces 26.499999994288153 and 26.499999986733027 sig. bits
r = 9.490626725e7 fails: root 0.999999995635551 isn't at least 1 <<<
r = 2.684354505e8 produces 28.0 and 27.999999919383132 sig. bits
r = 2.684354515e8 produces 28.0 and 27.99999993013205 sig. bits
r = 2.68435458e8 produces 28.0 and 28.0 sig. bits
r = 2.6843545825e8 produces 28.0 and 28.00000000268723 sig. bits
r = 2.6843545700000006e8 produces 28.0 and 27.999999989251084 sig. bits
r = 4.294967298e9 produces 32.0 and 32.0 sig. bits
r = 4.29496729825e9 produces 32.0 and 32.00000000016795 sig. bits
Worst accuracy is 26.499999986733027 sig. bits
```
This seems to be comparable to a clang version, but seems to be fairly poor in comparison to some other machines, back in the day (1997).
**The attached could, possibly be turned into a testsuite test, by removing the QuickCheck tests that are included.**
Observations:
- There are a couple of failures (could be the implementation of sqrt or log).
- signum seems incorrect (signum Nan = -1.0)
- The prelude should have a copysign function
- min fails to produce the other argument if one argument is NaN
- The CFloat and CDouble variants seem to produce the same result as the native Float and Double versions
- The Haskell coding style could be improved to remove some boilerplate, make the code more idiomatic
- There may be a better way of entering the test values of r to ensure that they are accurate
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Test Suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"IEEE Standard 754 for Binary Floating-Point Arithmetic by Prof. W. Kahan, UCB","status":"New","operating_system":"","component":"Test Suite","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["IEEE754"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"The attached is an implementation of the floating point accuracy test described in ''The Baleful Influence of Benchmarks'' section of http://www.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF\r\n\r\n\r\n{{{\r\nResults for Float:\r\nr = 4098.0 produces 12.0 and 12.0 sig. bits\r\nr = 4098.25 fails: root 0.99989897 isn't at least 1 <<<<\r\nr = 4097.004 produces 12.0 and 11.999298 sig. bits\r\n:\r\nWorst accuracy is 11.999298 sig. bits\r\n\r\n:\r\n\r\nResults for Double:\r\nr = 4098.0 produces Infinity and Infinity sig. bits\r\nr = 4098.25 produces Infinity and 53.0 sig. bits\r\nr = 4097.00390625 produces Infinity and 53.451178091541244 sig. bits\r\nr = 1.6777218e7 produces Infinity and Infinity sig. bits\r\nr = 1.677721825e7 produces Infinity and 75.0 sig. bits\r\nr = 1.6777219e7 produces Infinity and 71.0 sig. bits\r\nr = 9.4906267e7 produces 26.499999994288153 and 26.499999986733027 sig. bits\r\nr = 9.490626725e7 fails: root 0.999999995635551 isn't at least 1 <<<\r\nr = 2.684354505e8 produces 28.0 and 27.999999919383132 sig. bits\r\nr = 2.684354515e8 produces 28.0 and 27.99999993013205 sig. bits\r\nr = 2.68435458e8 produces 28.0 and 28.0 sig. bits\r\nr = 2.6843545825e8 produces 28.0 and 28.00000000268723 sig. bits\r\nr = 2.6843545700000006e8 produces 28.0 and 27.999999989251084 sig. bits\r\nr = 4.294967298e9 produces 32.0 and 32.0 sig. bits\r\nr = 4.29496729825e9 produces 32.0 and 32.00000000016795 sig. bits\r\nWorst accuracy is 26.499999986733027 sig. bits\r\n}}}\r\n\r\nThis seems to be comparable to a clang version, but seems to be fairly poor in comparison to some other machines, back in the day (1997).\r\n\r\n'''The attached could, possibly be turned into a testsuite test, by removing the QuickCheck tests that are included.'''\r\n\r\nObservations:\r\n\r\n* There are a couple of failures (could be the implementation of sqrt or log). \r\n* signum seems incorrect (signum Nan = -1.0)\r\n* The prelude should have a copysign function\r\n* min fails to produce the other argument if one argument is NaN\r\n* The CFloat and CDouble variants seem to produce the same result as the native Float and Double versions\r\n* The Haskell coding style could be improved to remove some boilerplate, make the code more idiomatic\r\n* There may be a better way of entering the test values of r to ensure that they are accurate\r\n\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9539TQueue can lead to thread starvation2019-07-07T18:40:06ZjwlatoTQueue can lead to thread starvationFor background, please see [this SO question](http://stackoverflow.com/questions/25536604/huge-memory-consumption-for-simple-multithreaded-haskell/25560047#25560047)
When using TQueue, a sufficiently fast/persistent writer can result in...For background, please see [this SO question](http://stackoverflow.com/questions/25536604/huge-memory-consumption-for-simple-multithreaded-haskell/25560047#25560047)
When using TQueue, a sufficiently fast/persistent writer can result in the reader never getting scheduled, causing the queue to continually grow and lost concurrency.
I believe the issue is caused by the definition of readTQueue:
```
readTQueue :: TQueue a -> STM a
readTQueue (TQueue read write) = do
xs <- readTVar read
case xs of
(x:xs') -> do writeTVar read xs'
return x
[] -> do ys <- readTVar write
case ys of
[] -> retry
_ -> case reverse ys of
[] -> error "readTQueue"
(z:zs) -> do writeTVar write []
writeTVar read zs
return z
```
Note that the last `case` needs to traverse the write-end of the queue within the STM transaction. If the list is sufficiently large, a writer can commit a new transaction much more quickly, invalidating the read transaction. If threads continue to write to the queue, the reader will never get an opportunity to commit (and the list will grow, exacerbating the problem).
This alternative definition seems to fix the problem, but I don't know if there are other drawbacks to using it.
```
readTQueue' :: TQueue a -> STM a
readTQueue' (TQueue read write) = do
xs <- readTVar read
case xs of
(x:xs') -> do writeTVar read xs'
return x
[] -> do ys <- readTVar write
case ys of
[] -> retry
_ -> do writeTVar write []
let (z:zs) = reverse ys
writeTVar read zs
return z
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries (other) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"TQueue can lead to thread starvation","status":"New","operating_system":"","component":"libraries (other)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":["stm"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"For background, please see [http://stackoverflow.com/questions/25536604/huge-memory-consumption-for-simple-multithreaded-haskell/25560047#25560047 this SO question]\r\n\r\nWhen using TQueue, a sufficiently fast/persistent writer can result in the reader never getting scheduled, causing the queue to continually grow and lost concurrency.\r\n\r\nI believe the issue is caused by the definition of readTQueue:\r\n\r\n{{{\r\nreadTQueue :: TQueue a -> STM a\r\nreadTQueue (TQueue read write) = do\r\n xs <- readTVar read\r\n case xs of\r\n (x:xs') -> do writeTVar read xs'\r\n return x\r\n [] -> do ys <- readTVar write\r\n case ys of\r\n [] -> retry\r\n _ -> case reverse ys of\r\n [] -> error \"readTQueue\"\r\n (z:zs) -> do writeTVar write []\r\n writeTVar read zs\r\n return z\r\n}}}\r\n\r\nNote that the last `case` needs to traverse the write-end of the queue within the STM transaction. If the list is sufficiently large, a writer can commit a new transaction much more quickly, invalidating the read transaction. If threads continue to write to the queue, the reader will never get an opportunity to commit (and the list will grow, exacerbating the problem).\r\n\r\nThis alternative definition seems to fix the problem, but I don't know if there are other drawbacks to using it.\r\n\r\n{{{\r\nreadTQueue' :: TQueue a -> STM a\r\nreadTQueue' (TQueue read write) = do\r\n xs <- readTVar read\r\n case xs of\r\n (x:xs') -> do writeTVar read xs'\r\n return x\r\n [] -> do ys <- readTVar write\r\n case ys of\r\n [] -> retry\r\n _ -> do writeTVar write []\r\n let (z:zs) = reverse ys\r\n writeTVar read zs\r\n return z\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->Edward KmettEdward Kmetthttps://gitlab.haskell.org/ghc/ghc/-/issues/9542GHC-IO-Handle-Text.hPutStr' and writeBlocks look like they need refactoring2019-07-07T18:40:05ZDavid FeuerGHC-IO-Handle-Text.hPutStr' and writeBlocks look like they need refactoringThe boundary between `writeBlocks` and `hPutStr'` looks badly drawn, with pieces of buffering type on either side. I would also speculate that one or more CRLF-related helper functions may be in order.
<details><summary>Trac metadata</s...The boundary between `writeBlocks` and `hPutStr'` looks badly drawn, with pieces of buffering type on either side. I would also speculate that one or more CRLF-related helper functions may be in order.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.2 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | ekmett, hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC-IO-Handle-Text.hputStr' and writeBlocks look like they need refactoring","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["ekmett","hvr"],"type":"Task","description":"The boundary between `writeBlocks` and `hPutStr'` looks badly drawn, with pieces of buffering type on either side. I would also speculate that one or more CRLF-related helper functions may be in order.","type_of_failure":"OtherFailure","blocking":[]} -->Edward KmettEdward Kmetthttps://gitlab.haskell.org/ghc/ghc/-/issues/9547Empty constraint tuples are mis-kinded2023-03-31T13:27:24ZSimon Peyton JonesEmpty constraint tuples are mis-kindedSee #11621
Consider
```
-- If :: forall k. 'Bool -> k -> k -> k
type family If cond tru fls where
If True tru fls = tru
If False tru fls = fls
foo :: If True () (Eq a) => a -> a
foo = error "urk"
```
This should work fine. But...See #11621
Consider
```
-- If :: forall k. 'Bool -> k -> k -> k
type family If cond tru fls where
If True tru fls = tru
If False tru fls = fls
foo :: If True () (Eq a) => a -> a
foo = error "urk"
```
This should work fine. But we get
```
Foo.hs:8:21:
The third argument of `If' should have kind `*',
but `Eq a' has kind `Constraint'
In the type signature for `foo': foo :: If True () (Eq a) => a -> a
```
Reason: GHC is treating the `()` unit tuple as of kind `*`.
Reason is that in the `HsTupleTy` case of `tc_hs_type` in `TcHsType`, we see
```
-- In the [] case, it's not clear what the kind is, so guess *
```
And that guess is plain wrong in this case. Unfortunately I don't see an easy fix, but it's plain wrong as-is.
Simon
---
Edit by @sgraf812: Full reproducer with SAKS
```hs
{-# LANGUAGE DataKinds, TypeOperators, KindSignatures, MultiParamTypeClasses, TypeFamilies, StandaloneKindSignatures, RankNTypes, PolyKinds #-}
module T9547 where
import GHC.Exts
type If :: forall k. Bool -> k -> k -> k
type family If cond tru fls where
If True tru fls = tru
If False tru fls = fls
foo :: If True () (Eq a) => a -> a
foo = error "urk"
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Empty constraint tuples are mis-kinded","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider\r\n{{{\r\n-- If :: forall k. 'Bool -> k -> k -> k\r\ntype family If cond tru fls where\r\n If True tru fls = tru\r\n If False tru fls = fls\r\n\r\nfoo :: If True () (Eq a) => a -> a\r\nfoo = error \"urk\"\r\n}}}\r\nThis should work fine. But we get\r\n{{{\r\nFoo.hs:8:21:\r\n The third argument of `If' should have kind `*',\r\n but `Eq a' has kind `Constraint'\r\n In the type signature for `foo': foo :: If True () (Eq a) => a -> a\r\n}}}\r\nReason: GHC is treating the `()` unit tuple as of kind `*`. \r\n\r\nReason is that in the `HsTupleTy` case of `tc_hs_type` in `TcHsType`, we see\r\n{{{\r\n -- In the [] case, it's not clear what the kind is, so guess *\r\n}}}\r\nAnd that guess is plain wrong in this case. Unfortunately I don't see an easy fix, but it's plain wrong as-is.\r\n\r\nSimon","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9557Deriving instances is slow2022-01-13T18:16:05ZFeuerbachDeriving instances is slowLet's take [this file](https://raw.githubusercontent.com/haskell-suite/haskell-src-exts/8e0153d33b66add96fd5606614ce7938d2029510/src/Language/Haskell/Exts/Annotated/Syntax.hs) (from haskell-src-exts) and build it with -O0. On my machine ...Let's take [this file](https://raw.githubusercontent.com/haskell-suite/haskell-src-exts/8e0153d33b66add96fd5606614ce7938d2029510/src/Language/Haskell/Exts/Annotated/Syntax.hs) (from haskell-src-exts) and build it with -O0. On my machine it takes 55s.
If we remove deriving of all classes except Functor (which is the only one used by the module itself), the time will drop down to 4s.
Different classes vary in their compile-time cost, but there's no single culprit. Among the costly ones are Generic, Data, Show, Ord.
haskell-src-exts users are very annoyed by its long compile time, about 10 minutes, especially because we don't compile with -O0 by default. It would be nice to get this fixed.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Deriving instances is slow","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Let's take [https://raw.githubusercontent.com/haskell-suite/haskell-src-exts/8e0153d33b66add96fd5606614ce7938d2029510/src/Language/Haskell/Exts/Annotated/Syntax.hs this file] (from haskell-src-exts) and build it with -O0. On my machine it takes 55s.\r\n\r\nIf we remove deriving of all classes except Functor (which is the only one used by the module itself), the time will drop down to 4s.\r\n\r\nDifferent classes vary in their compile-time cost, but there's no single culprit. Among the costly ones are Generic, Data, Show, Ord.\r\n\r\nhaskell-src-exts users are very annoyed by its long compile time, about 10 minutes, especially because we don't compile with -O0 by default. It would be nice to get this fixed.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9562Type families + hs-boot files = unsafeCoerce2023-05-18T19:27:16ZRichard Eisenbergrae@richarde.devType families + hs-boot files = unsafeCoerceConsider the following bundle of modules:
A.hs:
```hs
{-# LANGUAGE TypeFamilies #-}
module A where
type family F a b
```
B.hs-boot:
```hs
module B where
import A
oops :: F a b -> a -> b
```
B.hs:
```hs
{-# LANGUAGE TypeFamilies...Consider the following bundle of modules:
A.hs:
```hs
{-# LANGUAGE TypeFamilies #-}
module A where
type family F a b
```
B.hs-boot:
```hs
module B where
import A
oops :: F a b -> a -> b
```
B.hs:
```hs
{-# LANGUAGE TypeFamilies #-}
module B where
import A
import C
type instance F a b = b
oops :: F a b -> a -> b
oops = const
```
C.hs:
```hs
module C (oops) where
import {-# SOURCE #-} B
```
D.hs:
```hs
{-# LANGUAGE TypeFamilies #-}
module D where
import A
import C
type instance F a b = a
unsafeCoerce :: a -> b
unsafeCoerce x = oops x x
```
Main.hs:
```hs
module Main where
import D ( unsafeCoerce )
main = print $ (unsafeCoerce True :: Int)
```
When loading these into GHCi, we quite reasonably get a type family instance overlap error. But, separate compilation leads to disaster:
```
rae:01:49:47 ~/temp/bug> ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.8.3
rae:01:49:49 ~/temp/bug> ghc -c A.hs
rae:01:49:53 ~/temp/bug> ghc -c B.hs-boot
rae:01:49:58 ~/temp/bug> ghc -c C.hs
rae:01:50:09 ~/temp/bug> ghc -c B.hs
rae:01:50:13 ~/temp/bug> ghc -c D.hs
rae:01:50:17 ~/temp/bug> ghc Main.hs -o Unsafe
[6 of 6] Compiling Main ( Main.hs, Main.o )
Linking Unsafe ...
rae:01:50:23 ~/temp/bug> ./Unsafe
2882303761534249061
```
Yikes!
Proposed (terrible) solution: hs-boot files **must** list all type instance declarations in the corresponding modules. It may also be a good idea to require all normal instance declarations in the hs-boot file as well, because this same trick can be used to introduce incoherence (I think -- haven't tested).
This bug persists even if `Main` declares that it is `Safe`.
I've attached a tarball of the files for ease of testing.
(Credit to Edward Yang and Geoff Mainland, whose discussion provoked the line of inquiry that led to this discovery.)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Type families + hs-boot files = unsafeCoerce","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider the following bundle of modules:\r\n\r\nA.hs:\r\n{{{#!hs\r\n{-# LANGUAGE TypeFamilies #-}\r\n\r\nmodule A where\r\n\r\ntype family F a b\r\n}}}\r\n\r\nB.hs-boot:\r\n{{{#!hs\r\nmodule B where\r\n\r\nimport A\r\n\r\noops :: F a b -> a -> b\r\n}}}\r\n\r\nB.hs:\r\n{{{#!hs\r\n{-# LANGUAGE TypeFamilies #-}\r\n\r\nmodule B where\r\n\r\nimport A\r\nimport C\r\n\r\ntype instance F a b = b\r\n\r\noops :: F a b -> a -> b\r\noops = const\r\n}}}\r\n\r\nC.hs:\r\n{{{#!hs\r\nmodule C (oops) where\r\n\r\nimport {-# SOURCE #-} B\r\n}}}\r\n\r\nD.hs:\r\n{{{#!hs\r\n{-# LANGUAGE TypeFamilies #-}\r\n\r\nmodule D where\r\n\r\nimport A\r\nimport C\r\n\r\ntype instance F a b = a\r\n\r\nunsafeCoerce :: a -> b\r\nunsafeCoerce x = oops x x\r\n}}}\r\n\r\nMain.hs:\r\n{{{#!hs\r\nmodule Main where\r\n\r\nimport D ( unsafeCoerce )\r\n\r\nmain = print $ (unsafeCoerce True :: Int)\r\n}}}\r\n\r\nWhen loading these into GHCi, we quite reasonably get a type family instance overlap error. But, separate compilation leads to disaster:\r\n\r\n{{{\r\nrae:01:49:47 ~/temp/bug> ghc --version\r\nThe Glorious Glasgow Haskell Compilation System, version 7.8.3\r\nrae:01:49:49 ~/temp/bug> ghc -c A.hs\r\nrae:01:49:53 ~/temp/bug> ghc -c B.hs-boot \r\nrae:01:49:58 ~/temp/bug> ghc -c C.hs\r\nrae:01:50:09 ~/temp/bug> ghc -c B.hs\r\nrae:01:50:13 ~/temp/bug> ghc -c D.hs\r\nrae:01:50:17 ~/temp/bug> ghc Main.hs -o Unsafe\r\n[6 of 6] Compiling Main ( Main.hs, Main.o )\r\nLinking Unsafe ...\r\nrae:01:50:23 ~/temp/bug> ./Unsafe\r\n2882303761534249061\r\n}}}\r\n\r\nYikes!\r\n\r\nProposed (terrible) solution: hs-boot files '''must''' list all type instance declarations in the corresponding modules. It may also be a good idea to require all normal instance declarations in the hs-boot file as well, because this same trick can be used to introduce incoherence (I think -- haven't tested).\r\n\r\nThis bug persists even if `Main` declares that it is `Safe`.\r\n\r\nI've attached a tarball of the files for ease of testing.\r\n\r\n(Credit to Edward Yang and Geoff Mainland, whose discussion provoked the line of inquiry that led to this discovery.)","type_of_failure":"OtherFailure","blocking":[]} -->Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/9570cryptarithm1 (normal) has bimodal runtime2019-07-07T18:39:58ZEdward Z. Yangcryptarithm1 (normal) has bimodal runtimeI was investigating performance numbers for cryptarithm1 in #8199, I noticed that the numbers for this benchmark were curiously bimodal. Here are two representative samples from both sides of the distribution.
```
../../runstdtest/runst...I was investigating performance numbers for cryptarithm1 in #8199, I noticed that the numbers for this benchmark were curiously bimodal. Here are two representative samples from both sides of the distribution.
```
../../runstdtest/runstdtest ./cryptarithm1 -o1 cryptarithm1.stdout -o1 cryptarithm1.stdout -ghc-timing ; ../../runstdtest/runstdtest ./cryptarithm1 -o1 cryptarithm1.stdout -o1 cryptarithm1.stdout -ghc-timing ; ../../runstdtest/runstdtest ./cryptarithm1 -o1 cryptarithm1.stdout -o1 cryptarithm1.stdout -ghc-timing ; ../../runstdtest/runstdtest ./cryptarithm1 -o1 cryptarithm1.stdout -o1 cryptarithm1.stdout -ghc-timing ; ../../runstdtest/runstdtest ./cryptarithm1 -o1 cryptarithm1.stdout -o1 cryptarithm1.stdout -ghc-timing ;
real 0m0.676s
user 0m0.660s
sys 0m0.013s
<<ghc: 2051819320 bytes, 3929 GCs (3927 + 2), 0/0 avg/max bytes residency (0 samples), 5221368 bytes GC work, 1M in use, 0.000 INIT (0.000 elapsed), 0.643 MUT (0.643 elapsed), 0.026 GC (0.026 elapsed), 0.026 GC(0) (0.025 elapsed), 0.000 GC(1) (0.000 elapsed), 1 balance :ghc>>
real 0m0.610s
user 0m0.603s
sys 0m0.007s
<<ghc: 2051819320 bytes, 3929 GCs (3927 + 2), 0/0 avg/max bytes residency (0 samples), 5221368 bytes GC work, 1M in use, 0.000 INIT (0.000 elapsed), 0.582 MUT (0.582 elapsed), 0.023 GC (0.023 elapsed), 0.023 GC(0) (0.023 elapsed), 0.000 GC(1) (0.000 elapsed), 1 balance :ghc>>
```
I don't have any further resolution on the problem yet.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------------- |
| Version | 7.9 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | NoFib benchmark suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"cryptarithm1 (normal) has bimodal runtime","status":"New","operating_system":"","component":"NoFib benchmark suite","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I was investigating performance numbers for cryptarithm1 in #8199, I noticed that the numbers for this benchmark were curiously bimodal. Here are two representative samples from both sides of the distribution.\r\n\r\n{{{\r\n../../runstdtest/runstdtest ./cryptarithm1 -o1 cryptarithm1.stdout -o1 cryptarithm1.stdout -ghc-timing ; ../../runstdtest/runstdtest ./cryptarithm1 -o1 cryptarithm1.stdout -o1 cryptarithm1.stdout -ghc-timing ; ../../runstdtest/runstdtest ./cryptarithm1 -o1 cryptarithm1.stdout -o1 cryptarithm1.stdout -ghc-timing ; ../../runstdtest/runstdtest ./cryptarithm1 -o1 cryptarithm1.stdout -o1 cryptarithm1.stdout -ghc-timing ; ../../runstdtest/runstdtest ./cryptarithm1 -o1 cryptarithm1.stdout -o1 cryptarithm1.stdout -ghc-timing ;\r\n\r\nreal 0m0.676s\r\nuser 0m0.660s\r\nsys 0m0.013s\r\n<<ghc: 2051819320 bytes, 3929 GCs (3927 + 2), 0/0 avg/max bytes residency (0 samples), 5221368 bytes GC work, 1M in use, 0.000 INIT (0.000 elapsed), 0.643 MUT (0.643 elapsed), 0.026 GC (0.026 elapsed), 0.026 GC(0) (0.025 elapsed), 0.000 GC(1) (0.000 elapsed), 1 balance :ghc>>\r\n\r\nreal 0m0.610s\r\nuser 0m0.603s\r\nsys 0m0.007s\r\n<<ghc: 2051819320 bytes, 3929 GCs (3927 + 2), 0/0 avg/max bytes residency (0 samples), 5221368 bytes GC work, 1M in use, 0.000 INIT (0.000 elapsed), 0.582 MUT (0.582 elapsed), 0.023 GC (0.023 elapsed), 0.023 GC(0) (0.023 elapsed), 0.000 GC(1) (0.000 elapsed), 1 balance :ghc>>\r\n}}}\r\n\r\nI don't have any further resolution on the problem yet.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9571nofib should use criterion-style bootstrapping/sampling2019-07-07T18:39:58ZEdward Z. Yangnofib should use criterion-style bootstrapping/samplingAs I discovered when investigating situations like #9570, in some cases, test-cases in nofib are giving nonsense, and it's hard to tell unless you run nofib several times and notice that percentage differences are fluctuating up and down...As I discovered when investigating situations like #9570, in some cases, test-cases in nofib are giving nonsense, and it's hard to tell unless you run nofib several times and notice that percentage differences are fluctuating up and down. The quality of the numbers we get for uninformed users would be better if we ran some statistical analysis to tell how many times to run the benchmark, and if there were lots of outliers (rather than just blindly summarizing all the runs using an average.)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------------- |
| Version | 7.9 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | NoFib benchmark suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"nofib should use criterion-style bootstrapping/sampling","status":"New","operating_system":"","component":"NoFib benchmark suite","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"As I discovered when investigating situations like #9570, in some cases, test-cases in nofib are giving nonsense, and it's hard to tell unless you run nofib several times and notice that percentage differences are fluctuating up and down. The quality of the numbers we get for uninformed users would be better if we ran some statistical analysis to tell how many times to run the benchmark, and if there were lots of outliers (rather than just blindly summarizing all the runs using an average.)","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9572nofib target for just building should be part of validate2019-07-07T18:39:58ZEdward Z. Yangnofib target for just building should be part of validatenofib is never run during validates, which makes it easy to bitrot (c.f. AMP changes). It would be better if:
1. We had a build target for just building nofib tests, not running them, (maybe optionally with optimizations turned off, or ...nofib is never run during validates, which makes it easy to bitrot (c.f. AMP changes). It would be better if:
1. We had a build target for just building nofib tests, not running them, (maybe optionally with optimizations turned off, or just `-fno-code`) and
1. This build target was executed during validates
This should strike a balance between wanting to avoid having to spend a lot of time running the benchmarks on validate, while still exercising the nofib tests to some degree.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------------- |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | NoFib benchmark suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"nofib target for just building should be part of validate","status":"New","operating_system":"","component":"NoFib benchmark suite","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"nofib is never run during validates, which makes it easy to bitrot (c.f. AMP changes). It would be better if:\r\n\r\n1. We had a build target for just building nofib tests, not running them, (maybe optionally with optimizations turned off, or just `-fno-code`) and\r\n2. This build target was executed during validates\r\n\r\nThis should strike a balance between wanting to avoid having to spend a lot of time running the benchmarks on validate, while still exercising the nofib tests to some degree.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9573Add warning for invalid digits in integer literals2019-07-07T18:39:58ZvlopezAdd warning for invalid digits in integer literalsIn its latest version, GHC can parse binary (with `-XBinaryLiterals`), octal and hexadecimal literals:
```hs
> 0b101010
> 0o52
> 0x2A
```
Currently, the parser/lexer reads digits from the input as long as they are valid for the specifi...In its latest version, GHC can parse binary (with `-XBinaryLiterals`), octal and hexadecimal literals:
```hs
> 0b101010
> 0o52
> 0x2A
```
Currently, the parser/lexer reads digits from the input as long as they are valid for the specified radix. All subsequent digits are interpreted as a new, separate token.
If the user uses a digit which isn't valid for the radix, it may be reported with a non-obvious error message, or interpreted in surprising ways:
```hs
> :t 0o567
0o576 :: Num a => a
> :t 0o5678
0o5678 :: (Num (a -> t), Num a) => t
> :t 0x1bfah
<interactive>:1:7: Not in scope: ‘h’
> replicate 0o5678
[8,8,8,8,8,8,8...
```
We suggest warning the user when a literal of this sort is written, while respecting any other error messages and the original behaviour.
More specifically, the parser or lexer would give a warning if a token starting with an alphanumeric character is found immediately after a numeric literal, without a blank between them.8.0.1vlopezvlopezhttps://gitlab.haskell.org/ghc/ghc/-/issues/9587Type checking with type functions introduces many type variables, which remai...2019-07-07T18:39:54ZolegType checking with type functions introduces many type variables, which remain ambiguous. The code no longer type checks.Before the type ambiguity check was introduced, I could write the following code
```
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- {-# LA...Before the type ambiguity check was introduced, I could write the following code
```
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- {-# LANGUAGE AllowAmbiguousTypes #-}
module T where
type family Arr (repr :: * -> *) (a :: *) (b :: *) :: *
class ESymantics repr where
int :: Int -> repr Int
add :: repr Int -> repr Int -> repr Int
lam :: (repr a -> repr b) -> repr (Arr repr a b)
app :: repr (Arr repr a b) -> repr a -> repr b
{-
te4 :: (Arr repr (Arr repr Int Int) (Arr repr Int Int)
~
Arr repr (Arr repr Int Int) (Arr repr Int b),
ESymantics repr) =>
repr b
-}
te4 = let c3 = lam (\f -> lam (\x -> f `app` (f `app` (f `app` x))))
in (c3 `app` (lam (\x -> x `add` int 14))) `app` (int 0)
-- t = lam (\f -> f `app` int 0)
newtype R a = R{unR :: a}
type instance Arr R a b = a -> b
instance ESymantics R where
int = R
add (R x) (R y) = R $ x + y
lam f = R $ unR . f . R
app (R f) (R x) = R $ f x
tR = unR te4
```
(This is a simple code abstracted from a longer code that for sure worked in 2010: I showed it in a SSGIP lecture at Oxford.) The inferred type of te4
is shown in comments. The type is not ideal but the best what can be done under circumstances. In tR, repr is instantiated to R and the type function Arr can finally be applied and the equality constraint resolved.
Since then, the type inference has changed and the code no longer type checks:
```
Could not deduce (Arr repr (Arr repr a0 b0) (Arr repr a2 b0)
~ Arr repr (Arr repr a b) (Arr repr a4 b))
from the context (ESymantics repr,
Arr repr a4 a3 ~ Arr repr a b,
Arr repr a3 a ~ Arr repr a b)
bound by the inferred type for ‘c3’:
(ESymantics repr, Arr repr a4 a3 ~ Arr repr a b,
Arr repr a3 a ~ Arr repr a b) =>
repr (Arr repr (Arr repr a b) (Arr repr a4 b))
```
What is worse, there does not appear to be \*any\* way to get the code to type check. No amount of type annotations helps. The code has to be dramatically re-written, or just given up.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Type checking with type functions introduces many type variables, which remain ambiguous. The code no longer type checks.","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["ambiguity","check","family,","type"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Before the type ambiguity check was introduced, I could write the following code\r\n\r\n{{{\r\n{-# LANGUAGE NoMonomorphismRestriction #-}\r\n{-# LANGUAGE TypeFamilies #-}\r\n{-# LANGUAGE KindSignatures #-}\r\n{-# LANGUAGE ScopedTypeVariables #-}\r\n-- {-# LANGUAGE AllowAmbiguousTypes #-}\r\n\r\nmodule T where\r\n\r\ntype family Arr (repr :: * -> *) (a :: *) (b :: *) :: *\r\n\r\nclass ESymantics repr where\r\n int :: Int -> repr Int\r\n add :: repr Int -> repr Int -> repr Int\r\n\r\n lam :: (repr a -> repr b) -> repr (Arr repr a b)\r\n app :: repr (Arr repr a b) -> repr a -> repr b\r\n\r\n{-\r\nte4 :: (Arr repr (Arr repr Int Int) (Arr repr Int Int)\r\n ~\r\n Arr repr (Arr repr Int Int) (Arr repr Int b),\r\n ESymantics repr) =>\r\n repr b\r\n-}\r\n\r\nte4 = let c3 = lam (\\f -> lam (\\x -> f `app` (f `app` (f `app` x))))\r\n in (c3 `app` (lam (\\x -> x `add` int 14))) `app` (int 0)\r\n\r\n-- t = lam (\\f -> f `app` int 0)\r\n\r\nnewtype R a = R{unR :: a}\r\ntype instance Arr R a b = a -> b\r\n\r\ninstance ESymantics R where\r\n int = R\r\n add (R x) (R y) = R $ x + y\r\n lam f = R $ unR . f . R\r\n app (R f) (R x) = R $ f x\r\n\r\ntR = unR te4\r\n\r\n}}}\r\n\r\n(This is a simple code abstracted from a longer code that for sure worked in 2010: I showed it in a SSGIP lecture at Oxford.) The inferred type of te4\r\nis shown in comments. The type is not ideal but the best what can be done under circumstances. In tR, repr is instantiated to R and the type function Arr can finally be applied and the equality constraint resolved.\r\n\r\nSince then, the type inference has changed and the code no longer type checks:\r\n{{{\r\n\r\nCould not deduce (Arr repr (Arr repr a0 b0) (Arr repr a2 b0)\r\n ~ Arr repr (Arr repr a b) (Arr repr a4 b))\r\n from the context (ESymantics repr,\r\n Arr repr a4 a3 ~ Arr repr a b,\r\n Arr repr a3 a ~ Arr repr a b)\r\n bound by the inferred type for ‘c3’:\r\n (ESymantics repr, Arr repr a4 a3 ~ Arr repr a b,\r\n Arr repr a3 a ~ Arr repr a b) =>\r\n repr (Arr repr (Arr repr a b) (Arr repr a4 b))\r\n}}}\r\n\r\nWhat is worse, there does not appear to be *any* way to get the code to type check. No amount of type annotations helps. The code has to be dramatically re-written, or just given up.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9588Add `MonadPlus (Either e)` and `Alternative (Either e)` instances2024-03-05T11:10:26ZHerbert Valerio Riedelhvr@gnu.orgAdd `MonadPlus (Either e)` and `Alternative (Either e)` instancesThe following 2 instances are currently Orphans in `transformers` but could be defined in `base` without instead:
```hs
instance Error e => MonadPlus (Either e)
instance Error e => Alterantive (Either e)
```
This would, however, requir...The following 2 instances are currently Orphans in `transformers` but could be defined in `base` without instead:
```hs
instance Error e => MonadPlus (Either e)
instance Error e => Alterantive (Either e)
```
This would, however, require us to move `Error` from `transformers` into base, which may be a controversial move.⊥Herbert Valerio Riedelhvr@gnu.orgHerbert Valerio Riedelhvr@gnu.orghttps://gitlab.haskell.org/ghc/ghc/-/issues/9601Make the rewrite rule system more powerful2019-07-07T18:39:51ZSophie TaylorMake the rewrite rule system more powerfulIt would be amazing if the current RULES system could be upgraded to include various predicates, or even into a full-on strategic programming system. This would allow far far more optimisations to be possible, rather than the current con...It would be amazing if the current RULES system could be upgraded to include various predicates, or even into a full-on strategic programming system. This would allow far far more optimisations to be possible, rather than the current conservative system where you have to make sure that the optimisations ALWAYS apply.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Make the rewrite rule system more powerful","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"7.10.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"It would be amazing if the current RULES system could be upgraded to include various predicates, or even into a full-on strategic programming system. This would allow far far more optimisations to be possible, rather than the current conservative system where you have to make sure that the optimisations ALWAYS apply.","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1https://gitlab.haskell.org/ghc/ghc/-/issues/9607Programs that require AllowAmbiguousTypes in 7.82019-07-07T18:39:50ZJan Stolarekjan.stolarek@ed.ac.ukPrograms that require AllowAmbiguousTypes in 7.8Jason McCarty [reported on Haskell-cafe](http://www.haskell.org/pipermail/haskell-cafe/2014-September/116076.html) that this code used to work with GHC 7.6 but in GHC 7.8 it requires `AllowAmbiguousTypes`:
```hs
-- The code below is sim...Jason McCarty [reported on Haskell-cafe](http://www.haskell.org/pipermail/haskell-cafe/2014-September/116076.html) that this code used to work with GHC 7.6 but in GHC 7.8 it requires `AllowAmbiguousTypes`:
```hs
-- The code below is simplified from code that computes a tensor product of
-- a tensor with an identity matrix whose size is determined from the
-- shapes of the input and output tensors.
{-# LANGUAGE DataKinds, KindSignatures, TypeFamilies, TypeOperators #-}
--{-# LANGUAGE AllowAmbiguousTypes #-}
module Tensors where
import GHC.TypeLits
type family (as :: [Nat]) ++ (bs :: [Nat]) :: [Nat]
type instance '[] ++ bs = bs
type instance (a ': as) ++ bs = a ': (as ++ bs)
data Tensor (s :: [Nat]) = Tensor -- content elided
-- apparently GHC reduces (++) enough to see that n is determined
leftUnit :: Tensor s -> Tensor ('[n, n] ++ s)
leftUnit Tensor = Tensor
-- accepted in 7.6, not accepted in 7.8 without AllowAmbiguousTypes
rightUnit :: Tensor s -> Tensor (s ++ '[n, n])
rightUnit Tensor = Tensor
-- also accepted without AllowAmbiguousTypes
outsideUnit :: Tensor s -> Tensor ('[n] ++ s ++ '[n])
outsideUnit Tensor = Tensor
useleftUnit :: Tensor '[1,1,2]
useleftUnit = leftUnit Tensor -- type of Tensor is inferred
userightUnit :: Tensor '[1,2,2]
userightUnit = rightUnit (Tensor :: Tensor '[1]) -- type must be provided
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Type checking regression between GHC 7.6 and 7.8","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Jason McCarty [http://www.haskell.org/pipermail/haskell-cafe/2014-September/116076.html reported on Haskell-cafe] that this code used to work with GHC 7.6 but in GHC 7.8 it requires `AllowAmbiguousTypes`:\r\n\r\n{{{#!hs\r\n-- The code below is simplified from code that computes a tensor product of\r\n-- a tensor with an identity matrix whose size is determined from the\r\n-- shapes of the input and output tensors.\r\n{-# LANGUAGE DataKinds, KindSignatures, TypeFamilies, TypeOperators #-}\r\n--{-# LANGUAGE AllowAmbiguousTypes #-}\r\nmodule Tensors where\r\nimport GHC.TypeLits\r\n\r\ntype family (as :: [Nat]) ++ (bs :: [Nat]) :: [Nat]\r\ntype instance '[] ++ bs = bs\r\ntype instance (a ': as) ++ bs = a ': (as ++ bs)\r\n\r\ndata Tensor (s :: [Nat]) = Tensor -- content elided\r\n\r\n-- apparently GHC reduces (++) enough to see that n is determined\r\nleftUnit :: Tensor s -> Tensor ('[n, n] ++ s)\r\nleftUnit Tensor = Tensor\r\n\r\n-- accepted in 7.6, not accepted in 7.8 without AllowAmbiguousTypes\r\nrightUnit :: Tensor s -> Tensor (s ++ '[n, n])\r\nrightUnit Tensor = Tensor\r\n\r\n-- also accepted without AllowAmbiguousTypes\r\noutsideUnit :: Tensor s -> Tensor ('[n] ++ s ++ '[n])\r\noutsideUnit Tensor = Tensor\r\n\r\nuseleftUnit :: Tensor '[1,1,2]\r\nuseleftUnit = leftUnit Tensor -- type of Tensor is inferred\r\n\r\nuserightUnit :: Tensor '[1,2,2]\r\nuserightUnit = rightUnit (Tensor :: Tensor '[1]) -- type must be provided\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9614ghc --print-(gcc|ld)-linker-flags broken2019-07-07T18:39:48Zrwbartonghc --print-(gcc|ld)-linker-flags broken```
rwbarton@morphism:~/ghc$ ghc --print-gcc-linker-flags
ghc: panic! (the 'impossible' happened)
(GHC version 7.8.3 for x86_64-unknown-linux):
Setting not found: "Gcc Linker flags"
Please report this as a GHC bug: http://www.haskel...```
rwbarton@morphism:~/ghc$ ghc --print-gcc-linker-flags
ghc: panic! (the 'impossible' happened)
(GHC version 7.8.3 for x86_64-unknown-linux):
Setting not found: "Gcc Linker flags"
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
rwbarton@morphism:~/ghc$ ghc --print-ld-linker-flags
ghc: panic! (the 'impossible' happened)
(GHC version 7.8.3 for x86_64-unknown-linux):
Setting not found: "Ld Linker flags"
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
In 2d2650bf65da3aede4e1c1ca4da623092b869dbe and subsequent commits (between 7.6 and 7.8) these settings fields became "C compiler link flags" and "ld flags". (I think, more or less.)
The real problem is that Cabal still looks for the settings fields "Gcc Linker flags" and "Ld Linker flags". I guess this should be updated on the Cabal side though. (They are empty on at least Linux x86_64, which I guess is why nobody noticed before.)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ghc --print-(gcc|ld)-linker-flags broken","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{\r\nrwbarton@morphism:~/ghc$ ghc --print-gcc-linker-flags\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 7.8.3 for x86_64-unknown-linux):\r\n\tSetting not found: \"Gcc Linker flags\"\r\n\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n\r\nrwbarton@morphism:~/ghc$ ghc --print-ld-linker-flags\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 7.8.3 for x86_64-unknown-linux):\r\n\tSetting not found: \"Ld Linker flags\"\r\n\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n}}}\r\n\r\nIn 2d2650bf65da3aede4e1c1ca4da623092b869dbe and subsequent commits (between 7.6 and 7.8) these settings fields became \"C compiler link flags\" and \"ld flags\". (I think, more or less.)\r\n\r\nThe real problem is that Cabal still looks for the settings fields \"Gcc Linker flags\" and \"Ld Linker flags\". I guess this should be updated on the Cabal side though. (They are empty on at least Linux x86_64, which I guess is why nobody noticed before.)","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/9617Implement `quot` and `rem` using `quotRem`; implement `div` and `mod` using `...2019-07-07T18:39:48ZDavid FeuerImplement `quot` and `rem` using `quotRem`; implement `div` and `mod` using `divMod`If I define
```hs
myquot x y = fst (quotRem x y)
myrem x y = snd (quotRem x y)
bob :: Int -> Int -> Int
bob x y = myquot x y + myrem x y
```
Then I get this beautiful thing with GHC 7.9 (I ''don't'' get anything beautiful in 7.8.3, so...If I define
```hs
myquot x y = fst (quotRem x y)
myrem x y = snd (quotRem x y)
bob :: Int -> Int -> Int
bob x y = myquot x y + myrem x y
```
Then I get this beautiful thing with GHC 7.9 (I ''don't'' get anything beautiful in 7.8.3, so great work, compiler gurus!):
```hs
bob :: Int -> Int -> Int
bob =
\ (w_sWx :: Int) (w1_sWy :: Int) ->
case w_sWx of _ { I# ww1_sWB ->
case w1_sWy of _ { I# ww3_sWF ->
case ww3_sWF of wild_aSo {
__DEFAULT ->
case quotRemInt# ww1_sWB wild_aSo of _ { (# ipv_aSr, ipv1_aSs #) ->
I# (+# ipv_aSr ipv1_aSs)
};
(-1) ->
case ww1_sWB of wild1_aSu {
__DEFAULT ->
case quotRemInt# wild1_aSu (-1) of _ { (# ipv_aSx, ipv1_aSy #) ->
I# (+# ipv_aSx ipv1_aSy)
};
(-9223372036854775808) -> case overflowError of wild2_00 { }
};
0 -> case divZeroError of wild1_00 { }
}
}
}
```
However, if I write
```
jones :: Int -> Int -> Int
jones x y = quot x y + rem x y
```
I don't get anything nice.
What I'm thinking (perhaps out of ignorance) is that we might be able to use the `myquot` and `myrem` definitions if it's possible to get some sort of dead code elimination to recognize when one or the other is not used, at which point it can replace the `quotRemInt#` with `quotInt#` or `remInt#`. Then we can quit the silly `quotRem` dance in user code and just write what we actually mean. Of course, exactly the same thing applies to `divMod`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.9 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Try to replace `quot` and `rem` with `quotRem` when possible","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"If I define\r\n\r\n{{{#!hs\r\nmyquot x y = fst (quotRem x y)\r\nmyrem x y = snd (quotRem x y)\r\n\r\nbob :: Int -> Int -> Int\r\nbob x y = myquot x y + myrem x y\r\n}}}\r\n\r\nThen I get this beautiful thing with GHC 7.9 (I ''don't'' get anything beautiful in 7.8.3, so great work, compiler gurus!):\r\n\r\n{{{#!hs\r\nbob :: Int -> Int -> Int\r\nbob =\r\n \\ (w_sWx :: Int) (w1_sWy :: Int) ->\r\n case w_sWx of _ { I# ww1_sWB ->\r\n case w1_sWy of _ { I# ww3_sWF ->\r\n case ww3_sWF of wild_aSo {\r\n __DEFAULT ->\r\n case quotRemInt# ww1_sWB wild_aSo of _ { (# ipv_aSr, ipv1_aSs #) ->\r\n I# (+# ipv_aSr ipv1_aSs)\r\n };\r\n (-1) ->\r\n case ww1_sWB of wild1_aSu {\r\n __DEFAULT ->\r\n case quotRemInt# wild1_aSu (-1) of _ { (# ipv_aSx, ipv1_aSy #) ->\r\n I# (+# ipv_aSx ipv1_aSy)\r\n };\r\n (-9223372036854775808) -> case overflowError of wild2_00 { }\r\n };\r\n 0 -> case divZeroError of wild1_00 { }\r\n }\r\n }\r\n }\r\n}}}\r\n\r\nHowever, if I write\r\n\r\n{{{\r\njones :: Int -> Int -> Int\r\njones x y = quot x y + rem x y\r\n}}}\r\n\r\nI don't get anything nice.\r\n\r\nWhat I'm thinking (perhaps out of ignorance) is that we might be able to use the `myquot` and `myrem` definitions if it's possible to get some sort of dead code elimination to recognize when one or the other is not used, at which point it can replace the `quotRemInt#` with `quotInt#` or `remInt#`. Then we can quit the silly `quotRem` dance in user code and just write what we actually mean. Of course, exactly the same thing applies to `divMod`.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9622GHCi command to solve a constraint2019-07-07T18:39:47ZKrzysztof GogolewskiGHCi command to solve a constraintIt would be nice to have a `:solve` command for ghci that took a class constraint and returned either its derivation or an error message. A possible interface could look like so:
```
ghci> :solve Eq (Maybe Type1, Bool)
1) Eq Type1 ...It would be nice to have a `:solve` command for ghci that took a class constraint and returned either its derivation or an error message. A possible interface could look like so:
```
ghci> :solve Eq (Maybe Type1, Bool)
1) Eq Type1 -- Defined in ‘MyModule’
2) Eq a => Eq (Maybe a) -- Defined in ‘GHC.Classes’
3) Eq (Maybe Type1) -- Put a ~ Int in 2) and use 1)
4) Eq Bool -- Defined in ‘GHC.Classes’
5) (Eq a, Eq b) => Eq (a,b) -- Defined in ‘GHC.Classes’
6) Eq (Maybe Type1, Bool) -- Put a ~ Maybe Type1, b ~ Bool in 5) and use 3), 4)
ghci> :solve Eq (Int -> Int)
No instance for Eq (Int -> Int)
```https://gitlab.haskell.org/ghc/ghc/-/issues/9624"Unlikely constraint" recognition2019-07-07T18:39:46ZDavid Feuer"Unlikely constraint" recognitionSome constraints or combinations are relatively unlikely to appear in correct code, or at least correct code written by beginners. A few tiny examples:
```hs
(Integral a, Fractional a) => -- Possible, but rare, in correct code.
(Integr...Some constraints or combinations are relatively unlikely to appear in correct code, or at least correct code written by beginners. A few tiny examples:
```hs
(Integral a, Fractional a) => -- Possible, but rare, in correct code.
(Integral a, RealFloat a) => -- Rather less possible in correct code.
(Num a, Foldable a) => -- Possible, but unlikely for a beginner.
(Fractional [a]) =>
(Show (A -> B)) =>
```
The current error messages when constraints like these are not satisfied does nothing to suggest that they are unlikely to be correct or to explain to a beginner what kinds of mistakes can lead to errors like this. I imagine some people who teach classes using Haskell will have an idea of which specific things are worth singling out for a special explanation.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.8.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"\"Unlikely constraint\" recognition","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Some constraints or combinations are relatively unlikely to appear in correct code, or at least correct code written by beginners. A few tiny examples:\r\n\r\n{{{#!hs\r\n(Integral a, Fractional a) => -- Possible, but rare, in correct code.\r\n(Integral a, RealFloat a) => -- Rather less possible in correct code.\r\n(Num a, Foldable a) => -- Possible, but unlikely for a beginner.\r\n(Fractional [a]) =>\r\n(Show (A -> B)) =>\r\n}}}\r\n\r\nThe current error messages when constraints like these are not satisfied does nothing to suggest that they are unlikely to be correct or to explain to a beginner what kinds of mistakes can lead to errors like this. I imagine some people who teach classes using Haskell will have an idea of which specific things are worth singling out for a special explanation.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9627Type error with functional dependencies2022-02-25T08:55:07Zlennart@augustsson.netType error with functional dependenciesThe attached file should compile. The types T1, T2, and T3 are all equivalent types (T1 and T2 normalize to T3), but with foo::T1 and bar::T2 there is a type error.
Rewriting the example using type families instead of FD makes it work.
...The attached file should compile. The types T1, T2, and T3 are all equivalent types (T1 and T2 normalize to T3), but with foo::T1 and bar::T2 there is a type error.
Rewriting the example using type families instead of FD makes it work.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Type error with functional dependencies","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The attached file should compile. The types T1, T2, and T3 are all equivalent types (T1 and T2 normalize to T3), but with foo::T1 and bar::T2 there is a type error.\r\n\r\nRewriting the example using type families instead of FD makes it work.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9631Comment in GHC.Base about GHC.Prim does not appear to be correct2021-07-26T07:33:12ZDavid FeuerComment in GHC.Base about GHC.Prim does not appear to be correctThe comment reads
```
GHC.Prim Has no implementation. It defines built-in things, and
by importing it you bring them into scope.
The source file is GHC.Prim.hi-boot, which is just
...The comment reads
```
GHC.Prim Has no implementation. It defines built-in things, and
by importing it you bring them into scope.
The source file is GHC.Prim.hi-boot, which is just
copied to make GHC.Prim.hi
```
It does not appear that any files by these names exist.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | ekmett, hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Comment in GHC.Base about GHC.Prim does not appear to be correct","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["ekmett","hvr"],"type":"Bug","description":"The comment reads\r\n\r\n{{{\r\nGHC.Prim Has no implementation. It defines built-in things, and\r\n by importing it you bring them into scope.\r\n The source file is GHC.Prim.hi-boot, which is just\r\n copied to make GHC.Prim.hi\r\n}}}\r\n\r\nIt does not appear that any files by these names exist.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1Edward KmettEdward Kmetthttps://gitlab.haskell.org/ghc/ghc/-/issues/9636Function with type error accepted2019-07-07T18:39:43Zlennart@augustsson.netFunction with type error acceptedThe following program is accepted by ghc even though it is clearly wrong.
The type family T is closed so T Bool cannot ever be reduced, so it must be a type error.
```hs
{-# LANGUAGE TypeFamilies #-}
module Err62 where
type family T a ...The following program is accepted by ghc even though it is clearly wrong.
The type family T is closed so T Bool cannot ever be reduced, so it must be a type error.
```hs
{-# LANGUAGE TypeFamilies #-}
module Err62 where
type family T a where
T Int = ()
x :: T Bool
x = undefined
f :: T Bool -> Bool
f _ = True
y :: Bool
y = f x
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Function with type error accepted","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The following program is accepted by ghc even though it is clearly wrong.\r\nThe type family T is closed so T Bool cannot ever be reduced, so it must be a type error.\r\n\r\n{{{#!hs\r\n{-# LANGUAGE TypeFamilies #-}\r\nmodule Err62 where\r\n\r\ntype family T a where\r\n T Int = ()\r\n\r\nx :: T Bool\r\nx = undefined\r\n\r\nf :: T Bool -> Bool\r\nf _ = True\r\n\r\ny :: Bool\r\ny = f x\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9642LANGUAGE pragma synonyms2019-07-07T18:39:41ZdreixelLANGUAGE pragma synonymsHere are the first 20 lines of a typical Haskell file of mine:
```
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE Lib...Here are the first 20 lines of a typical Haskell file of mine:
```
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LiberalTypeSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE AutoDeriveTypeable #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ConstraintKinds #-}
```
Over a couple of modules in a small package, I find myself copy-pasting these 20 lines, as either I will use these extensions, or they won't really cause any harm to the code I'm writing.
As a way to simplify this, and reduce code duplication, I propose introducing LANGUAGE pragma synonyms:
```
{-# LANGUAGE PedrosHaskell = EmptyDataDecls, FlexibleContexts, FlexibleInstances
, LiberalTypeSynonyms, ScopedTypeVariables
, RankNTypes, StandaloneDeriving, AutoDeriveTypeable
, DeriveDataTypeable, DeriveGeneric, DefaultSignatures
, OverlappingInstances, UndecidableInstances
, MultiParamTypeClasses, TypeOperators, TypeFamilies
, GADTs, DataKinds, PolyKinds, ConstraintKinds #-}
```
After writing this, in that same module or any module that imports it, I could just write:
```
{-# LANGUAGE PedrosHaskell #-}
```
And all the pragmas above would be enabled.
Besides making my life easier, I suspect this will also help increase modularity of certain packages. For example, packages could define a package-specific language pragma that should be enabled in order to use that package. Then, if the package maintainer upgrades one datatype to become a GADT, the pragma would be updated to include `GADTs`, and user code (that could now be requiring that pragma) would automatically enable `GADTs` too.
Furthermore, it can also make the language standardisation process simpler. After all,
```
{-# LANGUAGE Haskell2010 = PatternGuards, NoNPlusKPatterns, RelaxedPolyRec
, EmptyDataDecls, ForeignFunctionInterface #-}
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.9 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"LANGUAGE pragma synonyms","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Here are the first 20 lines of a typical Haskell file of mine:\r\n\r\n{{{\r\n{-# LANGUAGE EmptyDataDecls #-}\r\n{-# LANGUAGE FlexibleContexts #-}\r\n{-# LANGUAGE FlexibleInstances #-}\r\n{-# LANGUAGE LiberalTypeSynonyms #-}\r\n{-# LANGUAGE ScopedTypeVariables #-}\r\n{-# LANGUAGE RankNTypes #-}\r\n{-# LANGUAGE StandaloneDeriving #-}\r\n{-# LANGUAGE AutoDeriveTypeable #-}\r\n{-# LANGUAGE DeriveDataTypeable #-}\r\n{-# LANGUAGE DeriveGeneric #-}\r\n{-# LANGUAGE DefaultSignatures #-}\r\n{-# LANGUAGE OverlappingInstances #-}\r\n{-# LANGUAGE UndecidableInstances #-}\r\n{-# LANGUAGE MultiParamTypeClasses #-}\r\n{-# LANGUAGE TypeOperators #-}\r\n{-# LANGUAGE TypeFamilies #-}\r\n{-# LANGUAGE GADTs #-}\r\n{-# LANGUAGE DataKinds #-}\r\n{-# LANGUAGE PolyKinds #-}\r\n{-# LANGUAGE ConstraintKinds #-}\r\n}}}\r\n\r\nOver a couple of modules in a small package, I find myself copy-pasting these 20 lines, as either I will use these extensions, or they won't really cause any harm to the code I'm writing.\r\n\r\nAs a way to simplify this, and reduce code duplication, I propose introducing LANGUAGE pragma synonyms:\r\n{{{\r\n{-# LANGUAGE PedrosHaskell = EmptyDataDecls, FlexibleContexts, FlexibleInstances\r\n , LiberalTypeSynonyms, ScopedTypeVariables\r\n , RankNTypes, StandaloneDeriving, AutoDeriveTypeable\r\n , DeriveDataTypeable, DeriveGeneric, DefaultSignatures\r\n , OverlappingInstances, UndecidableInstances\r\n , MultiParamTypeClasses, TypeOperators, TypeFamilies\r\n , GADTs, DataKinds, PolyKinds, ConstraintKinds #-}\r\n}}}\r\n\r\nAfter writing this, in that same module or any module that imports it, I could just write:\r\n{{{\r\n{-# LANGUAGE PedrosHaskell #-}\r\n}}}\r\nAnd all the pragmas above would be enabled.\r\n\r\nBesides making my life easier, I suspect this will also help increase modularity of certain packages. For example, packages could define a package-specific language pragma that should be enabled in order to use that package. Then, if the package maintainer upgrades one datatype to become a GADT, the pragma would be updated to include `GADTs`, and user code (that could now be requiring that pragma) would automatically enable `GADTs` too.\r\n\r\nFurthermore, it can also make the language standardisation process simpler. After all, \r\n\r\n{{{ \r\n{-# LANGUAGE Haskell2010 = PatternGuards, NoNPlusKPatterns, RelaxedPolyRec\r\n , EmptyDataDecls, ForeignFunctionInterface #-}\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9643ghci must be restarted to use break point more than once?2019-07-07T18:39:41Zdsamperighci must be restarted to use break point more than once?When I set a break point (in main say) I stop there when I run
the function, but if I run the function again the break point is
ignored. Restarting ghci and resetting the break point makes it
effective again, but this seems strange. Is t...When I set a break point (in main say) I stop there when I run
the function, but if I run the function again the break point is
ignored. Restarting ghci and resetting the break point makes it
effective again, but this seems strange. Is this a bug or a feature?
Also, when I run :trace after stopping at a break point, the remainder of the function is run, and :back complains that I cannot go backwards because I am not at a break point.
Thanks,
Dominick
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ghci must be restarted to use break point more than once?","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["hvr"],"type":"Bug","description":"When I set a break point (in main say) I stop there when I run\r\nthe function, but if I run the function again the break point is\r\nignored. Restarting ghci and resetting the break point makes it\r\neffective again, but this seems strange. Is this a bug or a feature?\r\n\r\nAlso, when I run :trace after stopping at a break point, the remainder of the function is run, and :back complains that I cannot go backwards because I am not at a break point.\r\n\r\nThanks,\r\nDominick","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9645Optimize range checks for primitive types2019-07-07T18:39:40ZDavid FeuerOptimize range checks for primitive typesThis came up in the context of #9638.
A special case of Carter's recent suggestion that we try to find ways to automatically use branchless operators in some cases is to optimize the test
```hs
a <= x && x <= b
```
when `a` and `b` ar...This came up in the context of #9638.
A special case of Carter's recent suggestion that we try to find ways to automatically use branchless operators in some cases is to optimize the test
```hs
a <= x && x <= b
```
when `a` and `b` are statically known, along with minor variations that use strict comparisons.
The general pattern is that when `a` and `b` are statically known values that look sufficiently like machine integers (including primitive `Enum` values), `a <= x && x <= b` can be optimized either to `seq x False` (if `b < a`) or to `(fromIntegral (x - a) :: Word) <= (fromIntegral (b - a))` (if `a <= b`). This would almost always be a good thing, because at its worst, `x < a`, it's slower than the original expression by a single addition, but it avoids a potentially expensive conditional jump.
Of course, by the time it gets to the point where any such optimizations might take place, everything will have been converted to case expressions nested in some arbitrary fashion; if we're lucky, we'll get something we can recognize, like
```hs
case a <= x of
True -> case x <= b of
True -> e1
False -> e2
False -> e2
```
or
```hs
case x <= b of
True -> a <= x
False -> False
```
I don't know if we'll always be so lucky, but I think it may make sense to at least try to recognize these and similar forms.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------------------- |
| Version | 7.9 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | carter.schonwald@gmail.com |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Optimize range checks for primitive types","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["carter.schonwald@gmail.com"],"type":"FeatureRequest","description":"This came up in the context of #9638.\r\n\r\nA special case of Carter's recent suggestion that we try to find ways to automatically use branchless operators in some cases is to optimize the test\r\n\r\n{{{#!hs\r\na <= x && x <= b\r\n}}}\r\n\r\nwhen `a` and `b` are statically known, along with minor variations that use strict comparisons.\r\n\r\nThe general pattern is that when `a` and `b` are statically known values that look sufficiently like machine integers (including primitive `Enum` values), `a <= x && x <= b` can be optimized either to `seq x False` (if `b < a`) or to `(fromIntegral (x - a) :: Word) <= (fromIntegral (b - a))` (if `a <= b`). This would almost always be a good thing, because at its worst, `x < a`, it's slower than the original expression by a single addition, but it avoids a potentially expensive conditional jump.\r\n\r\nOf course, by the time it gets to the point where any such optimizations might take place, everything will have been converted to case expressions nested in some arbitrary fashion; if we're lucky, we'll get something we can recognize, like\r\n\r\n{{{#!hs\r\ncase a <= x of\r\n True -> case x <= b of\r\n True -> e1\r\n False -> e2\r\n False -> e2\r\n}}}\r\n\r\nor\r\n\r\n{{{#!hs\r\ncase x <= b of\r\n True -> a <= x\r\n False -> False\r\n}}}\r\n\r\nI don't know if we'll always be so lucky, but I think it may make sense to at least try to recognize these and similar forms.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9649symbols should/might be type level lists of chars2019-07-07T18:39:39Zibottysymbols should/might be type level lists of charsI thought I had seen that feature request in trac but did not find it. Sorry if I am wrong.
A simple use case might be a type safe routing framework, e.g.
```
get :: Route "/a/:id" $ do
idA <- param :: Param "idA"
...
```
I sp...I thought I had seen that feature request in trac but did not find it. Sorry if I am wrong.
A simple use case might be a type safe routing framework, e.g.
```
get :: Route "/a/:id" $ do
idA <- param :: Param "idA"
...
```
I spoke with pedro at hacberlin last weekend and he told me simonp and iavor might tell me where to start looking.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"symbols should/might be type level lists of chars","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"7.10.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ibotty"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"I thought I had seen that feature request in trac but did not find it. Sorry if I am wrong.\r\n\r\n\r\nA simple use case might be a type safe routing framework, e.g.\r\n\r\n{{{\r\nget :: Route \"/a/:id\" $ do\r\n idA <- param :: Param \"idA\"\r\n ...\r\n}}}\r\n\r\n\r\nI spoke with pedro at hacberlin last weekend and he told me simonp and iavor might tell me where to start looking.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1ibottyibottyhttps://gitlab.haskell.org/ghc/ghc/-/issues/9659Offer branchless conditional (CMOV) primop2024-02-27T13:56:52ZDavid FeuerOffer branchless conditional (CMOV) primopI'd like to see something similar to C's `?:`, like
```hs
ifI#, boolI# :: Int# -> Int# -> Int# -> Int#
```
We could then write things like
```hs
ifI# (x <# y) 12# (x +# 17#)
boolI# potato cannon (y ># 2)
```
When the value of the tes...I'd like to see something similar to C's `?:`, like
```hs
ifI#, boolI# :: Int# -> Int# -> Int# -> Int#
```
We could then write things like
```hs
ifI# (x <# y) 12# (x +# 17#)
boolI# potato cannon (y ># 2)
```
When the value of the test is difficult to predict, this would be better than the usual branching `if` or `case`.https://gitlab.haskell.org/ghc/ghc/-/issues/9660unnecessary indirect jump when returning a case scrutinee2021-03-16T14:38:51Zrwbartonunnecessary indirect jump when returning a case scrutineeI happened to be looking at the Cmm for this code (ghc 7.8.3, -O2)
```hs
f :: Int -> Int
f x = if x < 0 then x else x+1
```
and I noticed something a bit funny about it:
```
c12e:
if ((Sp + -8) < SpLim) goto c12z; el...I happened to be looking at the Cmm for this code (ghc 7.8.3, -O2)
```hs
f :: Int -> Int
f x = if x < 0 then x else x+1
```
and I noticed something a bit funny about it:
```
c12e:
if ((Sp + -8) < SpLim) goto c12z; else goto c12A;
c12z:
R2 = R2;
R1 = Test.f_closure;
call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;
c12A:
I64[Sp - 8] = c12b;
R1 = R2;
Sp = Sp - 8;
if (R1 & 7 != 0) goto c12b; else goto c12c;
c12c:
call (I64[R1])(R1) returns to c12b, args: 8, res: 8, upd: 8;
c12b:
Hp = Hp + 16;
if (Hp > HpLim) goto c12y; else goto c12x;
c12y:
HpAlloc = 16;
R1 = R1;
call stg_gc_unpt_r1(R1) returns to c12b, args: 8, res: 8, upd: 8;
c12x:
_s11Q::I64 = I64[R1 + 7];
if (%MO_S_Lt_W64(_s11Q::I64, 0)) goto c12u; else goto c12v;
c12u:
Hp = Hp - 16;
R1 = R1 & (-8); /* <--- */
Sp = Sp + 8;
call (I64[R1])(R1) args: 8, res: 0, upd: 8; /* <--- */
c12v:
I64[Hp - 8] = GHC.Types.I#_con_info;
I64[Hp] = _s11Q::I64 + 1;
R1 = Hp - 7;
Sp = Sp + 8;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
```
On the two marked lines, we untag R1 (which is `x`) and enter it. However, we know at this point that `x` is already in WHNF so we could simply return it by replacing the two lines with `call (P64[Sp])(R1)`, if I'm not mistaken. That will save a load and an indirect jump (which we actually know is to `I#_con_info`, which would just retag R1 and return to the address on the stack anyways).
I think the same optimization should be available any time we do an algebraic `case` and in a branch simply return the scrutinee.
I looked at what it would take to fix this. It looks almost easy: if we add a new `LambdaFormInfo` constructor `LFUnknownCon` meaning that we know the identifier is bound to a saturated application of an unknown constructor, then we could set the `cg_lf` of the case binder variable of an algebraic case statement to `LFUnknownCon`, and return `ReturnIt` for `LFUnknownCon` variables in `getCallMethod`. I think that would do it. Does that sound right? Is there a better way?
(In my original example we actually know the constructor has to be `I#`. But if the case was on a type with more than one constructor we wouldn't know statically which one we got, just that it has to be one of them.)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (CodeGen) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonmar |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"unnecessary indirect jump when returning a case scrutinee","status":"New","operating_system":"","component":"Compiler (CodeGen)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"Bug","description":"I happened to be looking at the Cmm for this code (ghc 7.8.3, -O2)\r\n\r\n{{{#!hs\r\nf :: Int -> Int\r\nf x = if x < 0 then x else x+1\r\n}}}\r\n\r\nand I noticed something a bit funny about it:\r\n\r\n\r\n{{{\r\n c12e:\r\n if ((Sp + -8) < SpLim) goto c12z; else goto c12A;\r\n c12z:\r\n R2 = R2;\r\n R1 = Test.f_closure;\r\n call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;\r\n c12A:\r\n I64[Sp - 8] = c12b;\r\n R1 = R2;\r\n Sp = Sp - 8;\r\n if (R1 & 7 != 0) goto c12b; else goto c12c;\r\n c12c:\r\n call (I64[R1])(R1) returns to c12b, args: 8, res: 8, upd: 8;\r\n c12b:\r\n Hp = Hp + 16;\r\n if (Hp > HpLim) goto c12y; else goto c12x;\r\n c12y:\r\n HpAlloc = 16;\r\n R1 = R1;\r\n call stg_gc_unpt_r1(R1) returns to c12b, args: 8, res: 8, upd: 8;\r\n c12x:\r\n _s11Q::I64 = I64[R1 + 7];\r\n if (%MO_S_Lt_W64(_s11Q::I64, 0)) goto c12u; else goto c12v;\r\n c12u:\r\n Hp = Hp - 16;\r\n R1 = R1 & (-8); /* <--- */\r\n Sp = Sp + 8;\r\n call (I64[R1])(R1) args: 8, res: 0, upd: 8; /* <--- */\r\n c12v:\r\n I64[Hp - 8] = GHC.Types.I#_con_info;\r\n I64[Hp] = _s11Q::I64 + 1;\r\n R1 = Hp - 7;\r\n Sp = Sp + 8;\r\n call (P64[Sp])(R1) args: 8, res: 0, upd: 8;\r\n}}}\r\n\r\nOn the two marked lines, we untag R1 (which is `x`) and enter it. However, we know at this point that `x` is already in WHNF so we could simply return it by replacing the two lines with `call (P64[Sp])(R1)`, if I'm not mistaken. That will save a load and an indirect jump (which we actually know is to `I#_con_info`, which would just retag R1 and return to the address on the stack anyways).\r\n\r\nI think the same optimization should be available any time we do an algebraic `case` and in a branch simply return the scrutinee.\r\n\r\nI looked at what it would take to fix this. It looks almost easy: if we add a new `LambdaFormInfo` constructor `LFUnknownCon` meaning that we know the identifier is bound to a saturated application of an unknown constructor, then we could set the `cg_lf` of the case binder variable of an algebraic case statement to `LFUnknownCon`, and return `ReturnIt` for `LFUnknownCon` variables in `getCallMethod`. I think that would do it. Does that sound right? Is there a better way?\r\n\r\n(In my original example we actually know the constructor has to be `I#`. But if the case was on a type with more than one constructor we wouldn't know statically which one we got, just that it has to be one of them.)","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9661Branchless ==# is compiled to branchy code2021-08-18T15:49:11ZDavid FeuerBranchless ==# is compiled to branchy codeThis started as a comment on #6135, but Jan Stolarek requested that I file a separate report. The branchless tests `<#`, `>#`, `<=#`, and `>=#`, and their wordy cousins, seem to work properly, but `==#` and `eqWord#` don't. If I write
`...This started as a comment on #6135, but Jan Stolarek requested that I file a separate report. The branchless tests `<#`, `>#`, `<=#`, and `>=#`, and their wordy cousins, seem to work properly, but `==#` and `eqWord#` don't. If I write
```hs
foo x = tagToEnum# ((x <# 3#) `orI#` (x ># 100#) `orI#`
(x ==# 12#) `orI#` (x ==# 15#))
```
I get (in 7.8.3 and in 7.9)
```hs
IsDigit.foo :: GHC.Prim.Int# -> GHC.Types.Bool
[GblId,
Arity=1,
Caf=NoCafRefs,
Str=DmdType <S,1*U>,
Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)
Tmpl= \ (x3_a2if [Occ=Once!] :: GHC.Prim.Int#) ->
case x3_a2if of wild_Xe {
__DEFAULT ->
GHC.Prim.tagToEnum#
@ GHC.Types.Bool
(GHC.Prim.orI# (GHC.Prim.<# wild_Xe 3) (GHC.Prim.># wild_Xe 100));
12 -> GHC.Types.True;
15 -> GHC.Types.True
}}]
IsDigit.foo =
\ (x3_a2if :: GHC.Prim.Int#) ->
case x3_a2if of wild_Xe {
__DEFAULT ->
GHC.Prim.tagToEnum#
@ GHC.Types.Bool
(GHC.Prim.orI# (GHC.Prim.<# wild_Xe 3) (GHC.Prim.># wild_Xe 100));
12 -> GHC.Types.True;
15 -> GHC.Types.True
```
and branching assembly to match. Jan Stolarek indicates this is probably a problem with constant folding.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.9 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | jstolarek |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Branchless ==# is compiled to branchy code","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["jstolarek"],"type":"Bug","description":"This started as a comment on #6135, but Jan Stolarek requested that I file a separate report. The branchless tests `<#`, `>#`, `<=#`, and `>=#`, and their wordy cousins, seem to work properly, but `==#` and `eqWord#` don't. If I write\r\n\r\n{{{#!hs\r\nfoo x = tagToEnum# ((x <# 3#) `orI#` (x ># 100#) `orI#`\r\n (x ==# 12#) `orI#` (x ==# 15#))\r\n}}}\r\n\r\nI get (in 7.8.3 and in 7.9)\r\n\r\n{{{#!hs\r\nIsDigit.foo :: GHC.Prim.Int# -> GHC.Types.Bool\r\n[GblId,\r\n Arity=1,\r\n Caf=NoCafRefs,\r\n Str=DmdType <S,1*U>,\r\n Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,\r\n WorkFree=True, Expandable=True,\r\n Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)\r\n Tmpl= \\ (x3_a2if [Occ=Once!] :: GHC.Prim.Int#) ->\r\n case x3_a2if of wild_Xe {\r\n __DEFAULT ->\r\n GHC.Prim.tagToEnum#\r\n @ GHC.Types.Bool\r\n (GHC.Prim.orI# (GHC.Prim.<# wild_Xe 3) (GHC.Prim.># wild_Xe 100));\r\n 12 -> GHC.Types.True;\r\n 15 -> GHC.Types.True\r\n }}]\r\nIsDigit.foo =\r\n \\ (x3_a2if :: GHC.Prim.Int#) ->\r\n case x3_a2if of wild_Xe {\r\n __DEFAULT ->\r\n GHC.Prim.tagToEnum#\r\n @ GHC.Types.Bool\r\n (GHC.Prim.orI# (GHC.Prim.<# wild_Xe 3) (GHC.Prim.># wild_Xe 100));\r\n 12 -> GHC.Types.True;\r\n 15 -> GHC.Types.True\r\n}}}\r\n\r\nand branching assembly to match. Jan Stolarek indicates this is probably a problem with constant folding.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9667Type inference is weaker for GADT than analogous Data Family2019-07-07T18:39:35ZCarter SchonwaldType inference is weaker for GADT than analogous Data FamilyI'm marking this as a Feature request rather than a bug (though it was unexpected behavior for me!)
In my code base i had the following types
```hs
data Prod = Pair Prod Prod | Unit
data VProd (vect :: * -> * ) (prd:: Prod ) val ...I'm marking this as a Feature request rather than a bug (though it was unexpected behavior for me!)
In my code base i had the following types
```hs
data Prod = Pair Prod Prod | Unit
data VProd (vect :: * -> * ) (prd:: Prod ) val where
VLeaf :: !(v a) -> VProd v Unit a
VPair :: !(VProd v pra a) -> !(VProd v prb b ) ->VProd v (Pair pra prb) (a,b)
data MVProd (vect :: * -> * -> * ) (prd:: Prod ) (st :: * ) val where
MVLeaf :: !(mv st a) -> MVProd mv Unit st a
MVPair :: !(MVProd mv pra st a) -> !(MVProd mv prb st b ) -> MVProd mv (Pair pra prb) st (a,b)
```
which are meant as a way of modeling vectors of tuples as tuples (err trees) of vectors
however, sometimes type inference would fail in explosive ways
like
```
*Numerical.Data.Vector.Pair Data.Vector VG> (VPair (VLeaf (va :: Vector Int)) (VLeaf (vb:: Vector Int))) <- return $ VG.fromList [(1::Int,2::Int),(3,5)] :: (VProd Vector (Pair Unit Unit) (Int,Int))
<interactive>:24:16:
Could not deduce (a ~ Int)
from the context (t1 ~ 'Pair pra prb, t2 ~ (a, b))
bound by a pattern with constructor
VPair :: forall (v :: * -> *) (pra :: Prod) a (prb :: Prod) b.
VProd v pra a -> VProd v prb b -> VProd v ('Pair pra prb) (a, b),
in a pattern binding in
interactive GHCi command
at <interactive>:24:2-59
or from (pra ~ 'Unit)
bound by a pattern with constructor
VLeaf :: forall (v :: * -> *) a. v a -> VProd v 'Unit a,
in a pattern binding in
interactive GHCi command
at <interactive>:24:9-32
‘a’ is a rigid type variable bound by
a pattern with constructor
VPair :: forall (v :: * -> *) (pra :: Prod) a (prb :: Prod) b.
VProd v pra a -> VProd v prb b -> VProd v ('Pair pra prb) (a, b),
in a pattern binding in
interactive GHCi command
at <interactive>:24:2
Expected type: t0 a
Actual type: Vector Int
In the pattern: va :: Vector Int
In the pattern: VLeaf (va :: Vector Int)
In the pattern:
VPair (VLeaf (va :: Vector Int)) (VLeaf (vb :: Vector Int))
<interactive>:24:43:
Could not deduce (b ~ Int)
from the context (t1 ~ 'Pair pra prb, t2 ~ (a, b))
bound by a pattern with constructor
VPair :: forall (v :: * -> *) (pra :: Prod) a (prb :: Prod) b.
VProd v pra a -> VProd v prb b -> VProd v ('Pair pra prb) (a, b),
in a pattern binding in
interactive GHCi command
at <interactive>:24:2-59
or from (pra ~ 'Unit)
bound by a pattern with constructor
VLeaf :: forall (v :: * -> *) a. v a -> VProd v 'Unit a,
in a pattern binding in
interactive GHCi command
at <interactive>:24:9-32
or from (prb ~ 'Unit)
bound by a pattern with constructor
VLeaf :: forall (v :: * -> *) a. v a -> VProd v 'Unit a,
in a pattern binding in
interactive GHCi command
at <interactive>:24:36-58
‘b’ is a rigid type variable bound by
a pattern with constructor
VPair :: forall (v :: * -> *) (pra :: Prod) a (prb :: Prod) b.
VProd v pra a -> VProd v prb b -> VProd v ('Pair pra prb) (a, b),
in a pattern binding in
interactive GHCi command
at <interactive>:24:2
Expected type: t0 b
Actual type: Vector Int
In the pattern: vb :: Vector Int
In the pattern: VLeaf (vb :: Vector Int)
In the pattern:
VPair (VLeaf (va :: Vector Int)) (VLeaf (vb :: Vector Int))
<interactive>:24:65:
Couldn't match type ‘(Int, Int)’ with ‘Int’
Expected type: VProd Vector ('Pair 'Unit 'Unit) (Int, Int)
Actual type: VProd Vector ('Pair 'Unit 'Unit) (Int, (Int, Int))
In the first argument of ‘GHC.GHCi.ghciStepIO ::
IO a_a5BR -> IO a_a5BR’, namely
‘return $ VG.fromList [(1 :: Int, 2 :: Int), (3, 5)] ::
VProd Vector (Pair Unit Unit) (Int, Int)’
In a stmt of an interactive GHCi command:
(VPair (VLeaf (va :: Vector Int))
(VLeaf (vb :: Vector Int))) <- GHC.GHCi.ghciStepIO ::
IO a_a5BR -> IO a_a5BR
(return $ VG.fromList [(1 :: Int, 2 :: Int), (3, 5)] ::
VProd Vector (Pair Unit Unit) (Int, Int))
<interactive>:24:65:
Couldn't match expected type ‘IO (VProd t0 t1 t2)’
with actual type ‘VProd Vector ('Pair 'Unit 'Unit) (Int, Int)’
In the first argument of ‘GHC.GHCi.ghciStepIO ::
IO a_a5BR -> IO a_a5BR’, namely
‘return $ VG.fromList [(1 :: Int, 2 :: Int), (3, 5)] ::
VProd Vector (Pair Unit Unit) (Int, Int)’
In a stmt of an interactive GHCi command:
(VPair (VLeaf (va :: Vector Int))
(VLeaf (vb :: Vector Int))) <- GHC.GHCi.ghciStepIO ::
IO a_a5BR -> IO a_a5BR
(return $ VG.fromList [(1 :: Int, 2 :: Int), (3, 5)] ::
VProd Vector (Pair Unit Unit) (Int, Int))
```
I then experimented with using Data Families instead
```hs
data Prod = Pair Prod Prod | Unit
data family VProd (vect :: * -> * ) (prd:: Prod ) val -- where
data instance VProd v Unit a where
VLeaf :: !(v a) -> VProd v Unit a
data instance VProd v (Pair pra prb ) (a,b) where
VPair :: !(VProd v pra a) -> !(VProd v prb b ) ->VProd v (Pair pra prb) (a,b)
data family MVProd (vect :: * -> * -> * ) (prd:: Prod ) (st :: * ) val -- where
data instance MVProd mv Unit st a where
MVLeaf :: !(mv st a) -> MVProd mv Unit st a
data instance MVProd mv (Pair pra prb) st (a,b) where
MVPair :: !(MVProd mv pra st a) -> !(MVProd mv prb st b ) -> MVProd mv (Pair pra prb) st (a,b)
```
and type inference would chug along quite happily on the same example.
Attached is the file needed to (somewhat minimally) reproduce this
I guess what I'm saying here is I've quite a funny tension, I'm writing a patently closed data type, which has a perfectly reasonable GADT definition, but I need to use an (Open!) data family definition to get good type inference in the use sites!
This seems like something where (roughly) when the GADT constructors satisfy something analogous to the no overlap condition of a valid data family, similarly strong type inference might be possible?
I'm not sure if this makes sense, so i'm posing it as a feature request because i'm Not quite sure what the implications would be within type inference, but it'd probably be quite nice for end users because they'd suddenly get much better type inference for a large class of GADTs (i think)https://gitlab.haskell.org/ghc/ghc/-/issues/9669Long compile time/high memory usage for modules with many deriving clauses2019-07-07T18:39:34ZMichael Snoymanmichael@snoyman.comLong compile time/high memory usage for modules with many deriving clausesI've seen many different people complain about this in various different contexts. One of the most common I personally see is when using Persistent with a large number of entities, which results in multi-minute build times for that singl...I've seen many different people complain about this in various different contexts. One of the most common I personally see is when using Persistent with a large number of entities, which results in multi-minute build times for that single module. Usually, these reports have come from private repositories, which makes for a difficult repro. Also, the usage of Template Haskell in those modules tends to confuse the issue.
So I'd like to report this issue from a completely separate project, with the guess that this represents an issue that is affecting many other users. Steps to reproduce:
- `cabal unpack fpco-api-1.2.0.1`
- `cd fpco-api-1.2.0.1`
- `cabal install`
- `ghc --make -isrc/library src/library/FP/API/Types.hs`
- `touch src/library/FP/API/Types.hs`
Then, to see the time and memory usage of compiling just the one module, run:
- `time ghc -O2 --make -isrc/library src/library/FP/API/Types.hs +RTS -s`
On my system (16GB RAM, quadcore i7), the results are:
```
$ time ghc -O2 --make -isrc/library src/library/FP/API/Types.hs +RTS -s
[3 of 3] Compiling FP.API.Types ( src/library/FP/API/Types.hs, src/library/FP/API/Types.o )
51,846,533,568 bytes allocated in the heap
6,799,246,288 bytes copied during GC
389,297,584 bytes maximum residency (22 sample(s))
11,330,472 bytes maximum slop
1041 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 2041 colls, 0 par 9.19s 9.19s 0.0045s 0.0998s
Gen 1 22 colls, 0 par 4.33s 4.33s 0.1969s 0.5436s
TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.00s ( 0.00s elapsed)
MUT time 34.21s ( 37.74s elapsed)
GC time 13.52s ( 13.53s elapsed)
EXIT time 0.07s ( 0.07s elapsed)
Total time 47.81s ( 51.34s elapsed)
Alloc rate 1,515,662,937 bytes per MUT second
Productivity 71.7% of total user, 66.8% of total elapsed
gc_alloc_block_sync: 0
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 0
real 0m51.375s
user 0m50.864s
sys 0m0.456s
```
By contrast, with optimizations turned off:
```
$ time ghc -O0 --make -isrc/library src/library/FP/API/Types.hs +RTS -s
[3 of 3] Compiling FP.API.Types ( src/library/FP/API/Types.hs, src/library/FP/API/Types.o )
12,767,593,936 bytes allocated in the heap
1,078,202,664 bytes copied during GC
179,551,768 bytes maximum residency (13 sample(s))
6,684,544 bytes maximum slop
439 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 623 colls, 0 par 1.24s 1.24s 0.0020s 0.0651s
Gen 1 13 colls, 0 par 0.76s 0.76s 0.0586s 0.2397s
TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.00s ( 0.00s elapsed)
MUT time 8.28s ( 9.23s elapsed)
GC time 2.00s ( 2.00s elapsed)
EXIT time 0.05s ( 0.05s elapsed)
Total time 10.34s ( 11.28s elapsed)
Alloc rate 1,542,443,897 bytes per MUT second
Productivity 80.6% of total user, 73.9% of total elapsed
gc_alloc_block_sync: 0
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 0
real 0m11.304s
user 0m11.108s
sys 0m0.172s
```
and -O1:
```
$ time ghc -O1 --make -isrc/library src/library/FP/API/Types.hs +RTS -s
[3 of 3] Compiling FP.API.Types ( src/library/FP/API/Types.hs, src/library/FP/API/Types.o )
45,550,443,664 bytes allocated in the heap
5,721,700,512 bytes copied during GC
358,036,456 bytes maximum residency (21 sample(s))
9,167,176 bytes maximum slop
906 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 1642 colls, 0 par 7.70s 7.70s 0.0047s 0.1031s
Gen 1 21 colls, 0 par 3.68s 3.69s 0.1756s 0.4968s
TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.00s ( 0.00s elapsed)
MUT time 30.21s ( 33.09s elapsed)
GC time 11.38s ( 11.39s elapsed)
EXIT time 0.07s ( 0.07s elapsed)
Total time 41.68s ( 44.55s elapsed)
Alloc rate 1,507,571,106 bytes per MUT second
Productivity 72.7% of total user, 68.0% of total elapsed
gc_alloc_block_sync: 0
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 0
real 0m44.577s
user 0m44.164s
sys 0m0.368s
```
Note that this module is essentially just 900 lines of data declarations, with a large number of derived classes, and a few manually written helper functions and instances.
This high memory usage hasn't just resulted in user complaints: automated Jenkins and Travis jobs will often times fail without optimizations disabled, which can be problematic for proper testing and production code. In the case of fpco-api, I've worked around this by adding `-O0` to the cabal file, but it would be much nicer to not have to do that.
For some other examples of complaints along these lines:
- https://groups.google.com/d/msg/yesodweb/MX1bnOFu8Hc/VLQXhnvpIkMJ
- https://groups.google.com/d/msg/yesodweb/XPWixNjuOnM/FN26bmkudgwJ
I believe there are a few other threads discussing this, if it would be helpful. I did my testing on GHC 7.8.3 64-bit, Ubuntu 12.04.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Long compile time/high memory usage for modules with many deriving clauses","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I've seen many different people complain about this in various different contexts. One of the most common I personally see is when using Persistent with a large number of entities, which results in multi-minute build times for that single module. Usually, these reports have come from private repositories, which makes for a difficult repro. Also, the usage of Template Haskell in those modules tends to confuse the issue.\r\n\r\nSo I'd like to report this issue from a completely separate project, with the guess that this represents an issue that is affecting many other users. Steps to reproduce:\r\n\r\n* `cabal unpack fpco-api-1.2.0.1`\r\n* `cd fpco-api-1.2.0.1`\r\n* `cabal install`\r\n* `ghc --make -isrc/library src/library/FP/API/Types.hs`\r\n* `touch src/library/FP/API/Types.hs`\r\n\r\nThen, to see the time and memory usage of compiling just the one module, run:\r\n\r\n* `time ghc -O2 --make -isrc/library src/library/FP/API/Types.hs +RTS -s`\r\n\r\nOn my system (16GB RAM, quadcore i7), the results are:\r\n\r\n{{{\r\n$ time ghc -O2 --make -isrc/library src/library/FP/API/Types.hs +RTS -s\r\n[3 of 3] Compiling FP.API.Types ( src/library/FP/API/Types.hs, src/library/FP/API/Types.o )\r\n 51,846,533,568 bytes allocated in the heap\r\n 6,799,246,288 bytes copied during GC\r\n 389,297,584 bytes maximum residency (22 sample(s))\r\n 11,330,472 bytes maximum slop\r\n 1041 MB total memory in use (0 MB lost due to fragmentation)\r\n\r\n Tot time (elapsed) Avg pause Max pause\r\n Gen 0 2041 colls, 0 par 9.19s 9.19s 0.0045s 0.0998s\r\n Gen 1 22 colls, 0 par 4.33s 4.33s 0.1969s 0.5436s\r\n\r\n TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1)\r\n\r\n SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)\r\n\r\n INIT time 0.00s ( 0.00s elapsed)\r\n MUT time 34.21s ( 37.74s elapsed)\r\n GC time 13.52s ( 13.53s elapsed)\r\n EXIT time 0.07s ( 0.07s elapsed)\r\n Total time 47.81s ( 51.34s elapsed)\r\n\r\n Alloc rate 1,515,662,937 bytes per MUT second\r\n\r\n Productivity 71.7% of total user, 66.8% of total elapsed\r\n\r\ngc_alloc_block_sync: 0\r\nwhitehole_spin: 0\r\ngen[0].sync: 0\r\ngen[1].sync: 0\r\n\r\nreal 0m51.375s\r\nuser 0m50.864s\r\nsys 0m0.456s\r\n}}}\r\n\r\nBy contrast, with optimizations turned off:\r\n\r\n{{{\r\n$ time ghc -O0 --make -isrc/library src/library/FP/API/Types.hs +RTS -s\r\n[3 of 3] Compiling FP.API.Types ( src/library/FP/API/Types.hs, src/library/FP/API/Types.o )\r\n 12,767,593,936 bytes allocated in the heap\r\n 1,078,202,664 bytes copied during GC\r\n 179,551,768 bytes maximum residency (13 sample(s))\r\n 6,684,544 bytes maximum slop\r\n 439 MB total memory in use (0 MB lost due to fragmentation)\r\n\r\n Tot time (elapsed) Avg pause Max pause\r\n Gen 0 623 colls, 0 par 1.24s 1.24s 0.0020s 0.0651s\r\n Gen 1 13 colls, 0 par 0.76s 0.76s 0.0586s 0.2397s\r\n\r\n TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1)\r\n\r\n SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)\r\n\r\n INIT time 0.00s ( 0.00s elapsed)\r\n MUT time 8.28s ( 9.23s elapsed)\r\n GC time 2.00s ( 2.00s elapsed)\r\n EXIT time 0.05s ( 0.05s elapsed)\r\n Total time 10.34s ( 11.28s elapsed)\r\n\r\n Alloc rate 1,542,443,897 bytes per MUT second\r\n\r\n Productivity 80.6% of total user, 73.9% of total elapsed\r\n\r\ngc_alloc_block_sync: 0\r\nwhitehole_spin: 0\r\ngen[0].sync: 0\r\ngen[1].sync: 0\r\n\r\nreal 0m11.304s\r\nuser 0m11.108s\r\nsys 0m0.172s\r\n}}}\r\n\r\nand -O1:\r\n\r\n{{{\r\n$ time ghc -O1 --make -isrc/library src/library/FP/API/Types.hs +RTS -s\r\n[3 of 3] Compiling FP.API.Types ( src/library/FP/API/Types.hs, src/library/FP/API/Types.o )\r\n 45,550,443,664 bytes allocated in the heap\r\n 5,721,700,512 bytes copied during GC\r\n 358,036,456 bytes maximum residency (21 sample(s))\r\n 9,167,176 bytes maximum slop\r\n 906 MB total memory in use (0 MB lost due to fragmentation)\r\n\r\n Tot time (elapsed) Avg pause Max pause\r\n Gen 0 1642 colls, 0 par 7.70s 7.70s 0.0047s 0.1031s\r\n Gen 1 21 colls, 0 par 3.68s 3.69s 0.1756s 0.4968s\r\n\r\n TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1)\r\n\r\n SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)\r\n\r\n INIT time 0.00s ( 0.00s elapsed)\r\n MUT time 30.21s ( 33.09s elapsed)\r\n GC time 11.38s ( 11.39s elapsed)\r\n EXIT time 0.07s ( 0.07s elapsed)\r\n Total time 41.68s ( 44.55s elapsed)\r\n\r\n Alloc rate 1,507,571,106 bytes per MUT second\r\n\r\n Productivity 72.7% of total user, 68.0% of total elapsed\r\n\r\ngc_alloc_block_sync: 0\r\nwhitehole_spin: 0\r\ngen[0].sync: 0\r\ngen[1].sync: 0\r\n\r\nreal 0m44.577s\r\nuser 0m44.164s\r\nsys 0m0.368s\r\n}}}\r\n\r\nNote that this module is essentially just 900 lines of data declarations, with a large number of derived classes, and a few manually written helper functions and instances.\r\n\r\nThis high memory usage hasn't just resulted in user complaints: automated Jenkins and Travis jobs will often times fail without optimizations disabled, which can be problematic for proper testing and production code. In the case of fpco-api, I've worked around this by adding `-O0` to the cabal file, but it would be much nicer to not have to do that.\r\n\r\nFor some other examples of complaints along these lines:\r\n\r\n* https://groups.google.com/d/msg/yesodweb/MX1bnOFu8Hc/VLQXhnvpIkMJ\r\n* https://groups.google.com/d/msg/yesodweb/XPWixNjuOnM/FN26bmkudgwJ\r\n\r\nI believe there are a few other threads discussing this, if it would be helpful. I did my testing on GHC 7.8.3 64-bit, Ubuntu 12.04.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9671Allow expressions in patterns2022-11-25T17:59:31ZIcelandjackAllow expressions in patternsI've outlined a proposal for extending pattern synonyms to depend on terms (PatternFamilies), the name is less than ideal but I'll keep the page under that name for now. The proposal's introduction has been rewritten.
The simplest use c...I've outlined a proposal for extending pattern synonyms to depend on terms (PatternFamilies), the name is less than ideal but I'll keep the page under that name for now. The proposal's introduction has been rewritten.
The simplest use case are patterns that matches only when a set contains an element (`IsMember`) or when a set does not contain an element (`NotMember`):
\[\[Image(wiki:PatternFamilies:member.png)\]\]
```hs
hasKeys :: Set Item -> IO ()
hasKeys (IsMember "keys") = leaveHouse
hasKeys (NotMember "keys") = findKeys >> leaveHouse
```
or a pattern that matches a map if the key exists:
\[\[Image(wiki:PatternFamilies:lookup.png)\]\]
used like this:
```hs
age :: Map Person Age -> String
age (Lookup "Alice" 60) = "Alice is 60 years old!"
age (Lookup "Alice" age) = "Alice is " ++ show age ++ "."
age (Lookup "Bob" _) = "No info on Alice but we know how old Bob is."
age _ = "..."
```
Further details and examples can be found here: PatternFamilies, I discussed it with several people ICFP 2014. This would not require a new extension but would extend PatternSynonyms. This feature can be quite useful, especially when working with deeply nested structures (ASTs, JSON, XML, ...).
If people are fine with it I will implement it.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Allow expressions in patterns","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"7.10.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":["pattern","patterns,","synonyms"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"I've outlined a proposal for extending pattern synonyms to depend on terms (PatternFamilies), the name is less than ideal but I'll keep the page under that name for now. The proposal's introduction has been rewritten.\r\n\r\nThe simplest use case are patterns that matches only when a set contains an element (`IsMember`) or when a set does not contain an element (`NotMember`):\r\n\r\n[[Image(wiki:PatternFamilies:member.png)]]\r\n\r\n{{{#!hs\r\n hasKeys :: Set Item -> IO ()\r\n hasKeys (IsMember \"keys\") = leaveHouse\r\n hasKeys (NotMember \"keys\") = findKeys >> leaveHouse\r\n}}}\r\n\r\nor a pattern that matches a map if the key exists:\r\n\r\n[[Image(wiki:PatternFamilies:lookup.png)]]\r\n\r\nused like this:\r\n\r\n{{{#!hs\r\n age :: Map Person Age -> String\r\n age (Lookup \"Alice\" 60) = \"Alice is 60 years old!\"\r\n age (Lookup \"Alice\" age) = \"Alice is \" ++ show age ++ \".\"\r\n age (Lookup \"Bob\" _) = \"No info on Alice but we know how old Bob is.\"\r\n age _ = \"...\"\r\n}}}\r\n\r\nFurther details and examples can be found here: PatternFamilies, I discussed it with several people ICFP 2014. This would not require a new extension but would extend PatternSynonyms. This feature can be quite useful, especially when working with deeply nested structures (ASTs, JSON, XML, ...).\r\n\r\nIf people are fine with it I will implement it.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9672Error message too long (full case statement printed)2019-07-07T18:39:33Zandreas.abelError message too long (full case statement printed)Imho, it does not make sense to print the other branches of a case when a type error is discovered in one branch. When you see the following example, you will agree with me.
```
src/full/Agda/TypeChecking/Errors.hs:540:35:
Couldn't ...Imho, it does not make sense to print the other branches of a case when a type error is discovered in one branch. When you see the following example, you will agree with me.
```
src/full/Agda/TypeChecking/Errors.hs:540:35:
Couldn't match type ‘[Char]’ with ‘TCMT IO Doc’
Expected type: TCM Doc
Actual type: [Char]
In the expression:
"Module cannot be imported since it has open interaction points"
In a case alternative:
SolvedButOpenHoles
-> "Module cannot be imported since it has open interaction points"
In a stmt of a 'do' block:
```
```hs
case err of {
InternalError s -> panic s
NotImplemented s -> fwords $ "Not implemented: " ++ s
NotSupported s -> fwords $ "Not supported: " ++ s
CompilationError s -> sep [fwords "Compilation error:", text s]
GenericError s -> fwords s
GenericDocError d -> return d
TerminationCheckFailed because
-> fwords
"Termination checking failed for the following functions:"
$$
(nest 2
$ fsep
$ punctuate comma
$ map (pretty . dropTopLevelModule)
$ concatMap termErrFunctions because)
$$ fwords "Problematic calls:"
$$
(nest 2
$ fmap (P.vcat . nub)
$ mapM prettyTCM
$ sortBy (compare `on` callInfoRange)
$ concatMap termErrCalls because)
PropMustBeSingleton
-> fwords
"Datatypes in Prop must have at most one constructor when proof irrelevance is enabled"
DataMustEndInSort t
-> fsep
$ pwords "The type of a datatype must end in a sort."
++ [prettyTCM t] ++ pwords "isn't a sort."
ShouldEndInApplicationOfTheDatatype t
-> fsep
$ pwords
"The target of a constructor must be the datatype applied to its parameters,"
++ [prettyTCM t] ++ pwords "isn't"
ShouldBeAppliedToTheDatatypeParameters s t
-> fsep
$ pwords "The target of the constructor should be"
++ [prettyTCM s] ++ pwords "instead of" ++ [prettyTCM t]
ShouldBeApplicationOf t q
-> fsep
$ pwords "The pattern constructs an element of"
++ [prettyTCM q] ++ pwords "which is not the right datatype"
ShouldBeRecordType t
-> fsep
$ pwords "Expected non-abstract record type, found "
++ [prettyTCM t]
ShouldBeRecordPattern p -> fsep $ pwords "Expected record pattern"
NotAProjectionPattern p
-> fsep
$ pwords "Not a valid projection for a copattern: " ++ [prettyA p]
DifferentArities
-> fwords
"The number of arguments in the defining equations differ"
WrongHidingInLHS -> do { fwords "Unexpected implicit argument" }
WrongHidingInLambda t
-> do { fwords
"Found an implicit lambda where an explicit lambda was expected" }
WrongIrrelevanceInLambda t
-> do { fwords
"Found an irrelevant lambda where a relevant lambda was expected" }
WrongNamedArgument a
-> fsep
$ pwords "Function does not accept argument " ++ [prettyTCM a]
WrongHidingInApplication t
-> do { fwords
"Found an implicit application where an explicit application was expected" }
HidingMismatch h h'
-> fwords
$ "Expected "
++
verbalize (Indefinite h')
++
" argument, but found " ++ verbalize (Indefinite h) ++ " argument"
RelevanceMismatch r r'
-> fwords
$ "Expected "
++
verbalize (Indefinite r')
++
" argument, but found " ++ verbalize (Indefinite r) ++ " argument"
ColorMismatch c c'
-> fsep
$ pwords "Expected argument color to be"
++ [prettyTCM c'] ++ pwords "but found color" ++ [prettyTCM c]
NotInductive t
-> fsep $ [prettyTCM t] ++ pwords "is not an inductive data type"
UninstantiatedDotPattern e
-> fsep $ pwords "Failed to infer the value of dotted pattern"
IlltypedPattern p a -> fsep $ pwords "Type mismatch"
IllformedProjectionPattern p
-> fsep $ pwords "Ill-formed projection pattern " ++ [prettyA p]
CannotEliminateWithPattern p a
-> do { let ...;
fsep
$ pwords "Cannot eliminate type"
++
prettyTCM a
: if isProj then
pwords "with projection pattern" ++ ...
else
pwords "with pattern"
++ prettyA p : pwords "(did you supply too many arguments?)" }
TooManyArgumentsInLHS a
-> fsep
$ pwords
"Left hand side gives too many arguments to a function of type"
++ [prettyTCM a]
WrongNumberOfConstructorArguments c expect given
-> fsep
$ pwords "The constructor"
++
[prettyTCM c]
++
pwords "expects"
++
[text (show expect)]
++
pwords "arguments (including hidden ones), but has been given"
++ [text (show given)] ++ pwords "(including hidden ones)"
CantResolveOverloadedConstructorsTargetingSameDatatype d cs
-> fsep
$ pwords
("Can't resolve overloaded constructors targeting the same datatype ("
++ show (qnameToConcrete d) ++ "):")
++ map pretty cs
DoesNotConstructAnElementOf c t
-> fsep
$ pwords "The constructor"
++
[prettyTCM c]
++ pwords "does not construct an element of" ++ [prettyTCM t]
ConstructorPatternInWrongDatatype c d
-> fsep
$ [prettyTCM c]
++ pwords "is not a constructor of the datatype" ++ [prettyTCM d]
IndicesNotConstructorApplications [i]
-> fwords "The index" $$ nest 2 (prettyTCM i)
$$
fsep
(pwords "is not a constructor (or literal) applied to variables"
++ pwords "(note that parameters count as constructor arguments)")
IndicesNotConstructorApplications is
-> fwords "The indices" $$ nest 2 (vcat $ map prettyTCM is)
$$
fsep
(pwords "are not constructors (or literals) applied to variables"
++ pwords "(note that parameters count as constructor arguments)")
IndexVariablesNotDistinct vs is
-> fwords "The variables"
$$ nest 2 (vcat $ map (\ v -> prettyTCM (I.Var v [])) vs)
$$ fwords "in the indices"
$$ nest 2 (vcat $ map prettyTCM is)
$$
fwords
"are not distinct (note that parameters count as constructor arguments)"
IndicesFreeInParameters vs indices pars
-> fwords "The variables"
$$ nest 2 (vcat $ map (\ v -> prettyTCM (I.Var v [])) vs)
$$
fwords
"which are used (perhaps as constructor parameters) in the index expressions"
$$ nest 2 (vcat $ map prettyTCM indices)
$$ fwords "are free in the parameters"
$$ nest 2 (vcat $ map prettyTCM pars)
ShadowedModule x []
-> (throwImpossible
(Impossible "src/full/Agda/TypeChecking/Errors.hs" 404))
ShadowedModule x ms@(m : _)
-> fsep
$ pwords "Duplicate definition of module"
++
[prettyTCM x <> text "."]
++
pwords "Previous definition of"
++
[help m]
++ pwords "module" ++ [prettyTCM x] ++ pwords "at" ++ [prettyTCM r]
where
help m = do { ... }
r = case ... of {
[] -> ...
r : _ -> ... }
defSiteOfLast [] = noRange
defSiteOfLast ns = nameBindingSite (last ns)
ModuleArityMismatch m EmptyTel args
-> fsep
$ pwords "The module"
++
[prettyTCM m]
++ pwords "is not parameterized, but is being applied to arguments"
ModuleArityMismatch m tel@(ExtendTel _ _) args
-> fsep
$ pwords "The arguments to "
++
[prettyTCM m]
++ pwords "does not fit the telescope" ++ [prettyTCM tel]
ShouldBeEmpty t []
-> fsep
$ [prettyTCM t]
++ pwords "should be empty, but that's not obvious to me"
ShouldBeEmpty t ps
-> fsep
([prettyTCM t]
++
pwords
"should be empty, but the following constructor patterns are valid:")
$$ nest 2 (vcat $ map (showPat 0) ps)
ShouldBeASort t
-> fsep $ [prettyTCM t] ++ pwords "should be a sort, but it isn't"
ShouldBePi t
-> fsep
$ [prettyTCM t] ++ pwords "should be a function type, but it isn't"
NotAProperTerm -> fwords "Found a malformed term"
SetOmegaNotValidType -> fwords "Set\969 is not a valid type"
InvalidType v
-> fsep $ [prettyTCM v] ++ pwords "is not a valid type"
SplitOnIrrelevant p t
-> fsep
$ pwords "Cannot pattern match"
++ [prettyA p] ++ pwords "against irrelevant type" ++ [prettyTCM t]
DefinitionIsIrrelevant x
-> fsep
$ text "Identifier"
: prettyTCM x
: pwords "is declared irrelevant, so it cannot be used here"
VariableIsIrrelevant x
-> fsep
$ text "Variable"
: prettyTCM x
: pwords "is declared irrelevant, so it cannot be used here"
UnequalBecauseOfUniverseConflict cmp s t
-> fsep $ [prettyTCM s, notCmp cmp, ....]
UnequalTerms cmp s t a
-> do { (d1, d2, d) <- prettyInEqual s t;
fsep $ [...] ++ pwords "of type" ++ [...] ++ [...] }
UnequalTypes cmp a b -> prettyUnequal a (notCmp cmp) b
UnequalColors a b -> error "TODO guilhem 4"
HeterogeneousEquality u a v b
-> fsep
$ pwords "Refuse to solve heterogeneous constraint"
++
[prettyTCM u]
++
pwords ":"
++
[prettyTCM a]
++ pwords "=?=" ++ [prettyTCM v] ++ pwords ":" ++ [prettyTCM b]
UnequalRelevance cmp a b
-> fsep
$ [prettyTCM a, notCmp cmp, ....]
++
pwords
"because one is a relevant function type and the other is an irrelevant function type"
UnequalHiding a b
-> fsep
$ [prettyTCM a, text "!=", ....]
++
pwords
"because one is an implicit function type and the other is an explicit function type"
UnequalSorts s1 s2 -> fsep $ [prettyTCM s1, text "!=", ....]
NotLeqSort s1 s2
-> fsep
$ pwords
"The type of the constructor does not fit in the sort of the datatype, since"
++
[prettyTCM s1]
++ pwords "is not less or equal than" ++ [prettyTCM s2]
TooFewFields r xs
-> fsep
$ pwords "Missing fields"
++
punctuate comma (map pretty xs)
++ pwords "in an element of the record" ++ [prettyTCM r]
TooManyFields r xs
-> fsep
$ pwords "The record type"
++
[prettyTCM r]
++
pwords "does not have the fields"
++ punctuate comma (map pretty xs)
DuplicateConstructors xs
-> fsep
$ pwords "Duplicate constructors"
++ punctuate comma (map pretty xs) ++ pwords "in datatype"
DuplicateFields xs
-> fsep
$ pwords "Duplicate fields"
++ punctuate comma (map pretty xs) ++ pwords "in record"
UnexpectedWithPatterns ps
-> fsep
$ pwords "Unexpected with patterns"
++ (punctuate (text " |") $ map prettyA ps)
WithClausePatternMismatch p q
-> fsep
$ pwords "With clause pattern "
++
[prettyA p]
++
pwords " is not an instance of its parent pattern "
++ [prettyTCM q]
MetaCannotDependOn m ps i
-> fsep
$ pwords "The metavariable"
++
[prettyTCM $ MetaV m []]
++
pwords "cannot depend on"
++ [pvar i] ++ pwords "because it" ++ deps
where
pvar = prettyTCM . var
deps
= case map pvar ps of {
[] -> ...
[x] -> ...
xs -> ... }
MetaOccursInItself m
-> fsep
$ pwords "Cannot construct infinite solution of metavariable"
++ [prettyTCM $ MetaV m []]
BuiltinMustBeConstructor s e
-> fsep
$ [prettyA e]
++
pwords "must be a constructor in the binding to builtin"
++ [text s]
NoSuchBuiltinName s
-> fsep $ pwords "There is no built-in thing called" ++ [text s]
DuplicateBuiltinBinding b x y
-> fsep
$ pwords "Duplicate binding for built-in thing"
++
[text b <> comma] ++ pwords "previous binding to" ++ [prettyTCM x]
NoBindingForBuiltin x
-> fsep
$ pwords "No binding for builtin thing"
++
[text x <> comma]
++
pwords
("use {-# BUILTIN " ++ x ++ " name #-} to bind it to 'name'")
NoSuchPrimitiveFunction x
-> fsep
$ pwords "There is no primitive function called" ++ [text x]
BuiltinInParameterisedModule x
-> fwords
$ "The BUILTIN pragma cannot appear inside a bound context "
++
"(for instance, in a parameterised module or as a local declaration)"
IllegalLetInTelescope tb
-> fsep
$ [pretty tb] ++ pwords " is not allowed in a telescope here."
NoRHSRequiresAbsurdPattern ps
-> fwords
$ "The right-hand side can only be omitted if there "
++ "is an absurd pattern, () or {}, in the left-hand side."
AbsurdPatternRequiresNoRHS ps
-> fwords
$ "The right-hand side must be omitted if there "
++ "is an absurd pattern, () or {}, in the left-hand side."
LocalVsImportedModuleClash m
-> fsep
$ pwords "The module"
++
[text $ show m]
++
pwords "can refer to either a local module or an imported module"
SolvedButOpenHoles
-> "Module cannot be imported since it has open interaction points"
UnsolvedMetas rs
-> fsep (pwords "Unsolved metas at the following locations:")
$$ nest 2 (vcat $ map prettyTCM rs)
UnsolvedConstraints cs
-> fsep (pwords "Failed to solve the following constraints:")
$$ nest 2 (vcat $ map prettyConstraint cs)
where
prettyConstraint :: ProblemConstraint -> TCM Doc
prettyConstraint c
= f (prettyTCM c)
where
r = ...
....
CyclicModuleDependency ms
-> fsep (pwords "cyclic module dependency:")
$$ nest 2 (vcat $ map pretty ms)
FileNotFound x files
-> fsep
(pwords "Failed to find source of module"
++ [pretty x] ++ pwords "in any of the following locations:")
$$ nest 2 (vcat $ map (text . filePath) files)
OverlappingProjects f m1 m2
-> fsep
(pwords "The file"
++
[text (filePath f)]
++
pwords "can be accessed via several project roots. Both"
++
[pretty m1]
++ pwords "and" ++ [pretty m2] ++ pwords "point to this file.")
AmbiguousTopLevelModuleName x files
-> fsep
(pwords "Ambiguous module name. The module name"
++
[pretty x] ++ pwords "could refer to any of the following files:")
$$ nest 2 (vcat $ map (text . filePath) files)
ClashingFileNamesFor x files
-> fsep
(pwords "Multiple possible sources for module"
++ [text $ show x] ++ pwords "found:")
$$ nest 2 (vcat $ map (text . filePath) files)
ModuleDefinedInOtherFile mod file file'
-> fsep
$ pwords "You tried to load"
++
[text (filePath file)]
++
pwords "which defines the module"
++
[pretty mod <> text "."]
++
pwords "However, according to the include path this module should"
++ pwords "be defined in" ++ [text (filePath file') <> text "."]
ModuleNameDoesntMatchFileName given files
-> fsep
(pwords
"The name of the top level module does not match the file name. The module"
++
[pretty given]
++ pwords "should be defined in one of the following files:")
$$ nest 2 (vcat $ map (text . filePath) files)
BothWithAndRHS -> fsep $ pwords "Unexpected right hand side"
NotInScope xs
-> fsep (pwords "Not in scope:") $$ nest 2 (vcat $ map name xs)
where
name x = fsep [...]
suggestion s
| elem ':' s = parens $ text "did you forget space around the ':'?"
| elem "->" two
= parens $ text "did you forget space around the '->'?"
| otherwise = empty
where
two = ...
NoSuchModule x -> fsep $ pwords "No such module" ++ [pretty x]
AmbiguousName x ys
-> vcat
[fsep
$ pwords "Ambiguous name"
++ [...] ++ pwords "It could refer to any one of",
nest 2 $ vcat $ map nameWithBinding ys, ....]
AmbiguousModule x ys
-> vcat
[fsep
$ pwords "Ambiguous module name"
++ [...] ++ pwords "It could refer to any one of",
nest 2 $ vcat $ map help ys, ....]
where
help :: ModuleName -> TCM Doc
help m = do { ... }
UninstantiatedModule x
-> fsep
(pwords "Cannot access the contents of the parameterised module"
++
[pretty x <> text "."]
++
pwords
"To do this the module first has to be instantiated. For instance:")
$$ nest 2 (hsep [text "module", pretty x <> text "'", ....])
ClashingDefinition x y
-> fsep
$ pwords "Multiple definitions of"
++
[pretty x <> text "."]
++
pwords "Previous definition at"
++ [prettyTCM $ nameBindingSite $ qnameName y]
ClashingModule m1 m2
-> fsep
$ pwords "The modules"
++ [prettyTCM m1, text "and", ....] ++ pwords "clash."
ClashingImport x y
-> fsep
$ pwords "Import clash between" ++ [pretty x, text "and", ....]
ClashingModuleImport x y
-> fsep
$ pwords "Module import clash between"
++ [pretty x, text "and", ....]
PatternShadowsConstructor x c
-> fsep
$ pwords "The pattern variable"
++
[prettyTCM x]
++ pwords "has the same name as the constructor" ++ [prettyTCM c]
DuplicateImports m xs
-> fsep
$ pwords "Ambiguous imports from module"
++ [pretty m] ++ pwords "for" ++ punctuate comma (map pretty xs)
ModuleDoesntExport m xs
-> fsep
$ pwords "The module"
++
[pretty m]
++
pwords "doesn't export the following:"
++ punctuate comma (map pretty xs)
NotAModuleExpr e
-> fsep
$ pwords
"The right-hand side of a module definition must have the form 'M e1 .. en'"
++
pwords "where M is a module name. The expression"
++ [pretty e, text "doesn't."]
FieldOutsideRecord
-> fsep $ pwords "Field appearing outside record declaration."
InvalidPattern p
-> fsep $ pretty p : pwords "is not a valid pattern"
RepeatedVariablesInPattern xs
-> fsep
$ pwords "Repeated variables in left hand side:" ++ map pretty xs
NotAnExpression e
-> fsep $ [pretty e] ++ pwords "is not a valid expression."
NotAValidLetBinding nd -> fwords $ "Not a valid let-declaration"
NothingAppliedToHiddenArg e
-> fsep
$ [pretty e]
++
pwords "cannot appear by itself. It needs to be the argument to"
++ pwords "a function expecting an implicit argument."
NothingAppliedToInstanceArg e
-> fsep
$ [pretty e]
++
pwords "cannot appear by itself. It needs to be the argument to"
++ pwords "a function expecting an instance argument."
NoParseForApplication es
-> fsep
$ pwords "Could not parse the application"
++ [pretty $ C.RawApp noRange es]
AmbiguousParseForApplication es es'
-> fsep
(pwords "Don't know how to parse"
++ [pretty_es <> (text ".")] ++ pwords "Could mean any one of:")
$$ nest 2 (vcat $ map pretty' es')
where
pretty_es :: TCM Doc
pretty_es = pretty $ C.RawApp noRange es
pretty' :: C.Expr -> TCM Doc
....
BadArgumentsToPatternSynonym x
-> fsep
$ pwords "Bad arguments to pattern synonym " ++ [prettyTCM x]
TooFewArgumentsToPatternSynonym x
-> fsep
$ pwords "Too few arguments to pattern synonym " ++ [prettyTCM x]
UnusedVariableInPatternSynonym
-> fsep $ pwords "Unused variable in pattern synonym."
NoParseForLHS IsLHS p
-> fsep $ pwords "Could not parse the left-hand side" ++ [pretty p]
NoParseForLHS IsPatSyn p
-> fsep
$ pwords "Could not parse the pattern synonym" ++ [pretty p]
AmbiguousParseForLHS lhsOrPatSyn p ps
-> fsep
(pwords "Don't know how to parse"
++ [pretty_p <> text "."] ++ pwords "Could mean any one of:")
$$ nest 2 (vcat $ map pretty' ps)
where
pretty_p :: TCM Doc
pretty_p = pretty p
pretty' :: C.Pattern -> TCM Doc
....
IncompletePatternMatching v args
-> fsep
$ pwords "Incomplete pattern matching for"
++
[prettyTCM v <> text "."]
++ pwords "No match for" ++ map prettyTCM args
UnreachableClauses f pss
-> fsep
$ pwords "Unreachable" ++ pwords (plural (length pss) "clause")
where
plural 1 thing = thing
plural n thing = thing ++ "s"
CoverageFailure f pss
-> fsep
(pwords "Incomplete pattern matching for"
++ [prettyTCM f <> text "."] ++ pwords "Missing cases:")
$$ nest 2 (vcat $ map display pss)
where
display ps = do { ... }
nicify f ps = do { ... }
CoverageCantSplitOn c tel cIxs gIxs
| length cIxs /= length gIxs
-> (throwImpossible
(Impossible "src/full/Agda/TypeChecking/Errors.hs" 750))
| otherwise
-> addCtxTel tel
$ vcat
([fsep
$ pwords
"I'm not sure if there should be a case for the constructor"
++
[...]
++
pwords "because I get stuck when trying to solve the following"
++
pwords
"unification problems (inferred index \8799 expected index):"]
++
zipWith
(\ c g -> nest 2 $ prettyTCM c <+> text "\8799" <+> prettyTCM g)
cIxs
gIxs)
CoverageCantSplitIrrelevantType a
-> fsep
$ pwords "Cannot split on argument of irrelevant datatype"
++ [prettyTCM a]
CoverageCantSplitType a
-> fsep
$ pwords "Cannot split on argument of non-datatype"
++ [prettyTCM a]
SplitError e -> prettyTCM e
WithoutKError a u v
-> fsep
$ pwords "Cannot eliminate reflexive equation"
++
[prettyTCM u]
++
pwords "="
++
[prettyTCM v]
++
pwords "of type"
++ [prettyTCM a] ++ pwords "because K has been disabled."
NotStrictlyPositive d ocs
-> fsep
$ pwords "The datatype"
++
[prettyTCM d]
++ pwords "is not strictly positive, because" ++ prettyOcc "it" ocs
where
prettyOcc _ [] = []
prettyOcc it (OccCon d c r : ocs) = concat [...]
prettyOcc it (OccClause f n r : ocs) = concat [...]
prettyR NonPositively = pwords "negatively"
prettyR (ArgumentTo i q)
= pwords "as the" ++ [...] ++ pwords "argument to" ++ [...]
th 0 = text "first"
th 1 = text "second"
th 2 = text "third"
th n = text (show $ n - 1) <> text "th"
....
IFSNoCandidateInScope t
-> fsep
$ pwords "No variable of type"
++ [prettyTCM t] ++ pwords "was found in scope."
SafeFlagPostulate e
-> fsep
$ pwords "Cannot postulate"
++ [pretty e] ++ pwords "with safe flag"
SafeFlagPragma xs
-> let
plural
| length xs == 1 = ...
| otherwise = ...
in
fsep
$ [fwords ("Cannot set OPTION pragma" ++ plural)]
++ map text xs ++ [fwords "with safe flag."]
SafeFlagNoTerminationCheck
-> fsep
(pwords "Cannot use NO_TERMINATION_CHECK pragma with safe flag.")
SafeFlagNonTerminating
-> fsep
(pwords "Cannot use NON_TERMINATING pragma with safe flag.")
SafeFlagTerminating
-> fsep (pwords "Cannot use TERMINATING pragma with safe flag.")
SafeFlagPrimTrustMe
-> fsep (pwords "Cannot use primTrustMe with safe flag")
NeedOptionCopatterns
-> fsep
(pwords
"Option --copatterns needed to enable destructor patterns") }
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Error message too long (full case statement printed)","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Imho, it does not make sense to print the other branches of a case when a type error is discovered in one branch. When you see the following example, you will agree with me.\r\n{{{\r\nsrc/full/Agda/TypeChecking/Errors.hs:540:35:\r\n Couldn't match type ‘[Char]’ with ‘TCMT IO Doc’\r\n Expected type: TCM Doc\r\n Actual type: [Char]\r\n In the expression:\r\n \"Module cannot be imported since it has open interaction points\"\r\n In a case alternative:\r\n SolvedButOpenHoles\r\n -> \"Module cannot be imported since it has open interaction points\"\r\n In a stmt of a 'do' block:\r\n}}}\r\n{{{#!hs\r\n case err of {\r\n InternalError s -> panic s\r\n NotImplemented s -> fwords $ \"Not implemented: \" ++ s\r\n NotSupported s -> fwords $ \"Not supported: \" ++ s\r\n CompilationError s -> sep [fwords \"Compilation error:\", text s]\r\n GenericError s -> fwords s\r\n GenericDocError d -> return d\r\n TerminationCheckFailed because\r\n -> fwords\r\n \"Termination checking failed for the following functions:\"\r\n $$\r\n (nest 2\r\n $ fsep\r\n $ punctuate comma\r\n $ map (pretty . dropTopLevelModule)\r\n $ concatMap termErrFunctions because)\r\n $$ fwords \"Problematic calls:\"\r\n $$\r\n (nest 2\r\n $ fmap (P.vcat . nub)\r\n $ mapM prettyTCM\r\n $ sortBy (compare `on` callInfoRange)\r\n $ concatMap termErrCalls because)\r\n PropMustBeSingleton\r\n -> fwords\r\n \"Datatypes in Prop must have at most one constructor when proof irrelevance is enabled\"\r\n DataMustEndInSort t\r\n -> fsep\r\n $ pwords \"The type of a datatype must end in a sort.\"\r\n ++ [prettyTCM t] ++ pwords \"isn't a sort.\"\r\n ShouldEndInApplicationOfTheDatatype t\r\n -> fsep\r\n $ pwords\r\n \"The target of a constructor must be the datatype applied to its parameters,\"\r\n ++ [prettyTCM t] ++ pwords \"isn't\"\r\n ShouldBeAppliedToTheDatatypeParameters s t\r\n -> fsep\r\n $ pwords \"The target of the constructor should be\"\r\n ++ [prettyTCM s] ++ pwords \"instead of\" ++ [prettyTCM t]\r\n ShouldBeApplicationOf t q\r\n -> fsep\r\n $ pwords \"The pattern constructs an element of\"\r\n ++ [prettyTCM q] ++ pwords \"which is not the right datatype\"\r\n ShouldBeRecordType t\r\n -> fsep\r\n $ pwords \"Expected non-abstract record type, found \"\r\n ++ [prettyTCM t]\r\n ShouldBeRecordPattern p -> fsep $ pwords \"Expected record pattern\"\r\n NotAProjectionPattern p\r\n -> fsep\r\n $ pwords \"Not a valid projection for a copattern: \" ++ [prettyA p]\r\n DifferentArities\r\n -> fwords\r\n \"The number of arguments in the defining equations differ\"\r\n WrongHidingInLHS -> do { fwords \"Unexpected implicit argument\" }\r\n WrongHidingInLambda t\r\n -> do { fwords\r\n \"Found an implicit lambda where an explicit lambda was expected\" }\r\n WrongIrrelevanceInLambda t\r\n -> do { fwords\r\n \"Found an irrelevant lambda where a relevant lambda was expected\" }\r\n WrongNamedArgument a\r\n -> fsep\r\n $ pwords \"Function does not accept argument \" ++ [prettyTCM a]\r\n WrongHidingInApplication t\r\n -> do { fwords\r\n \"Found an implicit application where an explicit application was expected\" }\r\n HidingMismatch h h'\r\n -> fwords\r\n $ \"Expected \"\r\n ++\r\n verbalize (Indefinite h')\r\n ++\r\n \" argument, but found \" ++ verbalize (Indefinite h) ++ \" argument\"\r\n RelevanceMismatch r r'\r\n -> fwords\r\n $ \"Expected \"\r\n ++\r\n verbalize (Indefinite r')\r\n ++\r\n \" argument, but found \" ++ verbalize (Indefinite r) ++ \" argument\"\r\n ColorMismatch c c'\r\n -> fsep\r\n $ pwords \"Expected argument color to be\"\r\n ++ [prettyTCM c'] ++ pwords \"but found color\" ++ [prettyTCM c]\r\n NotInductive t\r\n -> fsep $ [prettyTCM t] ++ pwords \"is not an inductive data type\"\r\n UninstantiatedDotPattern e\r\n -> fsep $ pwords \"Failed to infer the value of dotted pattern\"\r\n IlltypedPattern p a -> fsep $ pwords \"Type mismatch\"\r\n IllformedProjectionPattern p\r\n -> fsep $ pwords \"Ill-formed projection pattern \" ++ [prettyA p]\r\n CannotEliminateWithPattern p a\r\n -> do { let ...;\r\n fsep\r\n $ pwords \"Cannot eliminate type\"\r\n ++\r\n prettyTCM a\r\n : if isProj then\r\n pwords \"with projection pattern\" ++ ...\r\n else\r\n pwords \"with pattern\"\r\n ++ prettyA p : pwords \"(did you supply too many arguments?)\" }\r\n TooManyArgumentsInLHS a\r\n -> fsep\r\n $ pwords\r\n \"Left hand side gives too many arguments to a function of type\"\r\n ++ [prettyTCM a]\r\n WrongNumberOfConstructorArguments c expect given\r\n -> fsep\r\n $ pwords \"The constructor\"\r\n ++\r\n [prettyTCM c]\r\n ++\r\n pwords \"expects\"\r\n ++\r\n [text (show expect)]\r\n ++\r\n pwords \"arguments (including hidden ones), but has been given\"\r\n ++ [text (show given)] ++ pwords \"(including hidden ones)\"\r\n CantResolveOverloadedConstructorsTargetingSameDatatype d cs\r\n -> fsep\r\n $ pwords\r\n (\"Can't resolve overloaded constructors targeting the same datatype (\"\r\n ++ show (qnameToConcrete d) ++ \"):\")\r\n ++ map pretty cs\r\n DoesNotConstructAnElementOf c t\r\n -> fsep\r\n $ pwords \"The constructor\"\r\n ++\r\n [prettyTCM c]\r\n ++ pwords \"does not construct an element of\" ++ [prettyTCM t]\r\n ConstructorPatternInWrongDatatype c d\r\n -> fsep\r\n $ [prettyTCM c]\r\n ++ pwords \"is not a constructor of the datatype\" ++ [prettyTCM d]\r\n IndicesNotConstructorApplications [i]\r\n -> fwords \"The index\" $$ nest 2 (prettyTCM i)\r\n $$\r\n fsep\r\n (pwords \"is not a constructor (or literal) applied to variables\"\r\n ++ pwords \"(note that parameters count as constructor arguments)\")\r\n IndicesNotConstructorApplications is\r\n -> fwords \"The indices\" $$ nest 2 (vcat $ map prettyTCM is)\r\n $$\r\n fsep\r\n (pwords \"are not constructors (or literals) applied to variables\"\r\n ++ pwords \"(note that parameters count as constructor arguments)\")\r\n IndexVariablesNotDistinct vs is\r\n -> fwords \"The variables\"\r\n $$ nest 2 (vcat $ map (\\ v -> prettyTCM (I.Var v [])) vs)\r\n $$ fwords \"in the indices\"\r\n $$ nest 2 (vcat $ map prettyTCM is)\r\n $$\r\n fwords\r\n \"are not distinct (note that parameters count as constructor arguments)\"\r\n IndicesFreeInParameters vs indices pars\r\n -> fwords \"The variables\"\r\n $$ nest 2 (vcat $ map (\\ v -> prettyTCM (I.Var v [])) vs)\r\n $$\r\n fwords\r\n \"which are used (perhaps as constructor parameters) in the index expressions\"\r\n $$ nest 2 (vcat $ map prettyTCM indices)\r\n $$ fwords \"are free in the parameters\"\r\n $$ nest 2 (vcat $ map prettyTCM pars)\r\n ShadowedModule x []\r\n -> (throwImpossible\r\n (Impossible \"src/full/Agda/TypeChecking/Errors.hs\" 404))\r\n ShadowedModule x ms@(m : _)\r\n -> fsep\r\n $ pwords \"Duplicate definition of module\"\r\n ++\r\n [prettyTCM x <> text \".\"]\r\n ++\r\n pwords \"Previous definition of\"\r\n ++\r\n [help m]\r\n ++ pwords \"module\" ++ [prettyTCM x] ++ pwords \"at\" ++ [prettyTCM r]\r\n where\r\n help m = do { ... }\r\n r = case ... of {\r\n [] -> ...\r\n r : _ -> ... }\r\n defSiteOfLast [] = noRange\r\n defSiteOfLast ns = nameBindingSite (last ns)\r\n ModuleArityMismatch m EmptyTel args\r\n -> fsep\r\n $ pwords \"The module\"\r\n ++\r\n [prettyTCM m]\r\n ++ pwords \"is not parameterized, but is being applied to arguments\"\r\n ModuleArityMismatch m tel@(ExtendTel _ _) args\r\n -> fsep\r\n $ pwords \"The arguments to \"\r\n ++\r\n [prettyTCM m]\r\n ++ pwords \"does not fit the telescope\" ++ [prettyTCM tel]\r\n ShouldBeEmpty t []\r\n -> fsep\r\n $ [prettyTCM t]\r\n ++ pwords \"should be empty, but that's not obvious to me\"\r\n ShouldBeEmpty t ps\r\n -> fsep\r\n ([prettyTCM t]\r\n ++\r\n pwords\r\n \"should be empty, but the following constructor patterns are valid:\")\r\n $$ nest 2 (vcat $ map (showPat 0) ps)\r\n ShouldBeASort t\r\n -> fsep $ [prettyTCM t] ++ pwords \"should be a sort, but it isn't\"\r\n ShouldBePi t\r\n -> fsep\r\n $ [prettyTCM t] ++ pwords \"should be a function type, but it isn't\"\r\n NotAProperTerm -> fwords \"Found a malformed term\"\r\n SetOmegaNotValidType -> fwords \"Set\\969 is not a valid type\"\r\n InvalidType v\r\n -> fsep $ [prettyTCM v] ++ pwords \"is not a valid type\"\r\n SplitOnIrrelevant p t\r\n -> fsep\r\n $ pwords \"Cannot pattern match\"\r\n ++ [prettyA p] ++ pwords \"against irrelevant type\" ++ [prettyTCM t]\r\n DefinitionIsIrrelevant x\r\n -> fsep\r\n $ text \"Identifier\"\r\n : prettyTCM x\r\n : pwords \"is declared irrelevant, so it cannot be used here\"\r\n VariableIsIrrelevant x\r\n -> fsep\r\n $ text \"Variable\"\r\n : prettyTCM x\r\n : pwords \"is declared irrelevant, so it cannot be used here\"\r\n UnequalBecauseOfUniverseConflict cmp s t\r\n -> fsep $ [prettyTCM s, notCmp cmp, ....]\r\n UnequalTerms cmp s t a\r\n -> do { (d1, d2, d) <- prettyInEqual s t;\r\n fsep $ [...] ++ pwords \"of type\" ++ [...] ++ [...] }\r\n UnequalTypes cmp a b -> prettyUnequal a (notCmp cmp) b\r\n UnequalColors a b -> error \"TODO guilhem 4\"\r\n HeterogeneousEquality u a v b\r\n -> fsep\r\n $ pwords \"Refuse to solve heterogeneous constraint\"\r\n ++\r\n [prettyTCM u]\r\n ++\r\n pwords \":\"\r\n ++\r\n [prettyTCM a]\r\n ++ pwords \"=?=\" ++ [prettyTCM v] ++ pwords \":\" ++ [prettyTCM b]\r\n UnequalRelevance cmp a b\r\n -> fsep\r\n $ [prettyTCM a, notCmp cmp, ....]\r\n ++\r\n pwords\r\n \"because one is a relevant function type and the other is an irrelevant function type\"\r\n UnequalHiding a b\r\n -> fsep\r\n $ [prettyTCM a, text \"!=\", ....]\r\n ++\r\n pwords\r\n \"because one is an implicit function type and the other is an explicit function type\"\r\n UnequalSorts s1 s2 -> fsep $ [prettyTCM s1, text \"!=\", ....]\r\n NotLeqSort s1 s2\r\n -> fsep\r\n $ pwords\r\n \"The type of the constructor does not fit in the sort of the datatype, since\"\r\n ++\r\n [prettyTCM s1]\r\n ++ pwords \"is not less or equal than\" ++ [prettyTCM s2]\r\n TooFewFields r xs\r\n -> fsep\r\n $ pwords \"Missing fields\"\r\n ++\r\n punctuate comma (map pretty xs)\r\n ++ pwords \"in an element of the record\" ++ [prettyTCM r]\r\n TooManyFields r xs\r\n -> fsep\r\n $ pwords \"The record type\"\r\n ++\r\n [prettyTCM r]\r\n ++\r\n pwords \"does not have the fields\"\r\n ++ punctuate comma (map pretty xs)\r\n DuplicateConstructors xs\r\n -> fsep\r\n $ pwords \"Duplicate constructors\"\r\n ++ punctuate comma (map pretty xs) ++ pwords \"in datatype\"\r\n DuplicateFields xs\r\n -> fsep\r\n $ pwords \"Duplicate fields\"\r\n ++ punctuate comma (map pretty xs) ++ pwords \"in record\"\r\n UnexpectedWithPatterns ps\r\n -> fsep\r\n $ pwords \"Unexpected with patterns\"\r\n ++ (punctuate (text \" |\") $ map prettyA ps)\r\n WithClausePatternMismatch p q\r\n -> fsep\r\n $ pwords \"With clause pattern \"\r\n ++\r\n [prettyA p]\r\n ++\r\n pwords \" is not an instance of its parent pattern \"\r\n ++ [prettyTCM q]\r\n MetaCannotDependOn m ps i\r\n -> fsep\r\n $ pwords \"The metavariable\"\r\n ++\r\n [prettyTCM $ MetaV m []]\r\n ++\r\n pwords \"cannot depend on\"\r\n ++ [pvar i] ++ pwords \"because it\" ++ deps\r\n where\r\n pvar = prettyTCM . var\r\n deps\r\n = case map pvar ps of {\r\n [] -> ...\r\n [x] -> ...\r\n xs -> ... }\r\n MetaOccursInItself m\r\n -> fsep\r\n $ pwords \"Cannot construct infinite solution of metavariable\"\r\n ++ [prettyTCM $ MetaV m []]\r\n BuiltinMustBeConstructor s e\r\n -> fsep\r\n $ [prettyA e]\r\n ++\r\n pwords \"must be a constructor in the binding to builtin\"\r\n ++ [text s]\r\n NoSuchBuiltinName s\r\n -> fsep $ pwords \"There is no built-in thing called\" ++ [text s]\r\n DuplicateBuiltinBinding b x y\r\n -> fsep\r\n $ pwords \"Duplicate binding for built-in thing\"\r\n ++\r\n [text b <> comma] ++ pwords \"previous binding to\" ++ [prettyTCM x]\r\n NoBindingForBuiltin x\r\n -> fsep\r\n $ pwords \"No binding for builtin thing\"\r\n ++\r\n [text x <> comma]\r\n ++\r\n pwords\r\n (\"use {-# BUILTIN \" ++ x ++ \" name #-} to bind it to 'name'\")\r\n NoSuchPrimitiveFunction x\r\n -> fsep\r\n $ pwords \"There is no primitive function called\" ++ [text x]\r\n BuiltinInParameterisedModule x\r\n -> fwords\r\n $ \"The BUILTIN pragma cannot appear inside a bound context \"\r\n ++\r\n \"(for instance, in a parameterised module or as a local declaration)\"\r\n IllegalLetInTelescope tb\r\n -> fsep\r\n $ [pretty tb] ++ pwords \" is not allowed in a telescope here.\"\r\n NoRHSRequiresAbsurdPattern ps\r\n -> fwords\r\n $ \"The right-hand side can only be omitted if there \"\r\n ++ \"is an absurd pattern, () or {}, in the left-hand side.\"\r\n AbsurdPatternRequiresNoRHS ps\r\n -> fwords\r\n $ \"The right-hand side must be omitted if there \"\r\n ++ \"is an absurd pattern, () or {}, in the left-hand side.\"\r\n LocalVsImportedModuleClash m\r\n -> fsep\r\n $ pwords \"The module\"\r\n ++\r\n [text $ show m]\r\n ++\r\n pwords \"can refer to either a local module or an imported module\"\r\n SolvedButOpenHoles\r\n -> \"Module cannot be imported since it has open interaction points\"\r\n UnsolvedMetas rs\r\n -> fsep (pwords \"Unsolved metas at the following locations:\")\r\n $$ nest 2 (vcat $ map prettyTCM rs)\r\n UnsolvedConstraints cs\r\n -> fsep (pwords \"Failed to solve the following constraints:\")\r\n $$ nest 2 (vcat $ map prettyConstraint cs)\r\n where\r\n prettyConstraint :: ProblemConstraint -> TCM Doc\r\n prettyConstraint c\r\n = f (prettyTCM c)\r\n where\r\n r = ...\r\n ....\r\n CyclicModuleDependency ms\r\n -> fsep (pwords \"cyclic module dependency:\")\r\n $$ nest 2 (vcat $ map pretty ms)\r\n FileNotFound x files\r\n -> fsep\r\n (pwords \"Failed to find source of module\"\r\n ++ [pretty x] ++ pwords \"in any of the following locations:\")\r\n $$ nest 2 (vcat $ map (text . filePath) files)\r\n OverlappingProjects f m1 m2\r\n -> fsep\r\n (pwords \"The file\"\r\n ++\r\n [text (filePath f)]\r\n ++\r\n pwords \"can be accessed via several project roots. Both\"\r\n ++\r\n [pretty m1]\r\n ++ pwords \"and\" ++ [pretty m2] ++ pwords \"point to this file.\")\r\n AmbiguousTopLevelModuleName x files\r\n -> fsep\r\n (pwords \"Ambiguous module name. The module name\"\r\n ++\r\n [pretty x] ++ pwords \"could refer to any of the following files:\")\r\n $$ nest 2 (vcat $ map (text . filePath) files)\r\n ClashingFileNamesFor x files\r\n -> fsep\r\n (pwords \"Multiple possible sources for module\"\r\n ++ [text $ show x] ++ pwords \"found:\")\r\n $$ nest 2 (vcat $ map (text . filePath) files)\r\n ModuleDefinedInOtherFile mod file file'\r\n -> fsep\r\n $ pwords \"You tried to load\"\r\n ++\r\n [text (filePath file)]\r\n ++\r\n pwords \"which defines the module\"\r\n ++\r\n [pretty mod <> text \".\"]\r\n ++\r\n pwords \"However, according to the include path this module should\"\r\n ++ pwords \"be defined in\" ++ [text (filePath file') <> text \".\"]\r\n ModuleNameDoesntMatchFileName given files\r\n -> fsep\r\n (pwords\r\n \"The name of the top level module does not match the file name. The module\"\r\n ++\r\n [pretty given]\r\n ++ pwords \"should be defined in one of the following files:\")\r\n $$ nest 2 (vcat $ map (text . filePath) files)\r\n BothWithAndRHS -> fsep $ pwords \"Unexpected right hand side\"\r\n NotInScope xs\r\n -> fsep (pwords \"Not in scope:\") $$ nest 2 (vcat $ map name xs)\r\n where\r\n name x = fsep [...]\r\n suggestion s\r\n | elem ':' s = parens $ text \"did you forget space around the ':'?\"\r\n | elem \"->\" two\r\n = parens $ text \"did you forget space around the '->'?\"\r\n | otherwise = empty\r\n where\r\n two = ...\r\n NoSuchModule x -> fsep $ pwords \"No such module\" ++ [pretty x]\r\n AmbiguousName x ys\r\n -> vcat\r\n [fsep\r\n $ pwords \"Ambiguous name\"\r\n ++ [...] ++ pwords \"It could refer to any one of\",\r\n nest 2 $ vcat $ map nameWithBinding ys, ....]\r\n AmbiguousModule x ys\r\n -> vcat\r\n [fsep\r\n $ pwords \"Ambiguous module name\"\r\n ++ [...] ++ pwords \"It could refer to any one of\",\r\n nest 2 $ vcat $ map help ys, ....]\r\n where\r\n help :: ModuleName -> TCM Doc\r\n help m = do { ... }\r\n UninstantiatedModule x\r\n -> fsep\r\n (pwords \"Cannot access the contents of the parameterised module\"\r\n ++\r\n [pretty x <> text \".\"]\r\n ++\r\n pwords\r\n \"To do this the module first has to be instantiated. For instance:\")\r\n $$ nest 2 (hsep [text \"module\", pretty x <> text \"'\", ....])\r\n ClashingDefinition x y\r\n -> fsep\r\n $ pwords \"Multiple definitions of\"\r\n ++\r\n [pretty x <> text \".\"]\r\n ++\r\n pwords \"Previous definition at\"\r\n ++ [prettyTCM $ nameBindingSite $ qnameName y]\r\n ClashingModule m1 m2\r\n -> fsep\r\n $ pwords \"The modules\"\r\n ++ [prettyTCM m1, text \"and\", ....] ++ pwords \"clash.\"\r\n ClashingImport x y\r\n -> fsep\r\n $ pwords \"Import clash between\" ++ [pretty x, text \"and\", ....]\r\n ClashingModuleImport x y\r\n -> fsep\r\n $ pwords \"Module import clash between\"\r\n ++ [pretty x, text \"and\", ....]\r\n PatternShadowsConstructor x c\r\n -> fsep\r\n $ pwords \"The pattern variable\"\r\n ++\r\n [prettyTCM x]\r\n ++ pwords \"has the same name as the constructor\" ++ [prettyTCM c]\r\n DuplicateImports m xs\r\n -> fsep\r\n $ pwords \"Ambiguous imports from module\"\r\n ++ [pretty m] ++ pwords \"for\" ++ punctuate comma (map pretty xs)\r\n ModuleDoesntExport m xs\r\n -> fsep\r\n $ pwords \"The module\"\r\n ++\r\n [pretty m]\r\n ++\r\n pwords \"doesn't export the following:\"\r\n ++ punctuate comma (map pretty xs)\r\n NotAModuleExpr e\r\n -> fsep\r\n $ pwords\r\n \"The right-hand side of a module definition must have the form 'M e1 .. en'\"\r\n ++\r\n pwords \"where M is a module name. The expression\"\r\n ++ [pretty e, text \"doesn't.\"]\r\n FieldOutsideRecord\r\n -> fsep $ pwords \"Field appearing outside record declaration.\"\r\n InvalidPattern p\r\n -> fsep $ pretty p : pwords \"is not a valid pattern\"\r\n RepeatedVariablesInPattern xs\r\n -> fsep\r\n $ pwords \"Repeated variables in left hand side:\" ++ map pretty xs\r\n NotAnExpression e\r\n -> fsep $ [pretty e] ++ pwords \"is not a valid expression.\"\r\n NotAValidLetBinding nd -> fwords $ \"Not a valid let-declaration\"\r\n NothingAppliedToHiddenArg e\r\n -> fsep\r\n $ [pretty e]\r\n ++\r\n pwords \"cannot appear by itself. It needs to be the argument to\"\r\n ++ pwords \"a function expecting an implicit argument.\"\r\n NothingAppliedToInstanceArg e\r\n -> fsep\r\n $ [pretty e]\r\n ++\r\n pwords \"cannot appear by itself. It needs to be the argument to\"\r\n ++ pwords \"a function expecting an instance argument.\"\r\n NoParseForApplication es\r\n -> fsep\r\n $ pwords \"Could not parse the application\"\r\n ++ [pretty $ C.RawApp noRange es]\r\n AmbiguousParseForApplication es es'\r\n -> fsep\r\n (pwords \"Don't know how to parse\"\r\n ++ [pretty_es <> (text \".\")] ++ pwords \"Could mean any one of:\")\r\n $$ nest 2 (vcat $ map pretty' es')\r\n where\r\n pretty_es :: TCM Doc\r\n pretty_es = pretty $ C.RawApp noRange es\r\n pretty' :: C.Expr -> TCM Doc\r\n ....\r\n BadArgumentsToPatternSynonym x\r\n -> fsep\r\n $ pwords \"Bad arguments to pattern synonym \" ++ [prettyTCM x]\r\n TooFewArgumentsToPatternSynonym x\r\n -> fsep\r\n $ pwords \"Too few arguments to pattern synonym \" ++ [prettyTCM x]\r\n UnusedVariableInPatternSynonym\r\n -> fsep $ pwords \"Unused variable in pattern synonym.\"\r\n NoParseForLHS IsLHS p\r\n -> fsep $ pwords \"Could not parse the left-hand side\" ++ [pretty p]\r\n NoParseForLHS IsPatSyn p\r\n -> fsep\r\n $ pwords \"Could not parse the pattern synonym\" ++ [pretty p]\r\n AmbiguousParseForLHS lhsOrPatSyn p ps\r\n -> fsep\r\n (pwords \"Don't know how to parse\"\r\n ++ [pretty_p <> text \".\"] ++ pwords \"Could mean any one of:\")\r\n $$ nest 2 (vcat $ map pretty' ps)\r\n where\r\n pretty_p :: TCM Doc\r\n pretty_p = pretty p\r\n pretty' :: C.Pattern -> TCM Doc\r\n ....\r\n IncompletePatternMatching v args\r\n -> fsep\r\n $ pwords \"Incomplete pattern matching for\"\r\n ++\r\n [prettyTCM v <> text \".\"]\r\n ++ pwords \"No match for\" ++ map prettyTCM args\r\n UnreachableClauses f pss\r\n -> fsep\r\n $ pwords \"Unreachable\" ++ pwords (plural (length pss) \"clause\")\r\n where\r\n plural 1 thing = thing\r\n plural n thing = thing ++ \"s\"\r\n CoverageFailure f pss\r\n -> fsep\r\n (pwords \"Incomplete pattern matching for\"\r\n ++ [prettyTCM f <> text \".\"] ++ pwords \"Missing cases:\")\r\n $$ nest 2 (vcat $ map display pss)\r\n where\r\n display ps = do { ... }\r\n nicify f ps = do { ... }\r\n CoverageCantSplitOn c tel cIxs gIxs\r\n | length cIxs /= length gIxs\r\n -> (throwImpossible\r\n (Impossible \"src/full/Agda/TypeChecking/Errors.hs\" 750))\r\n | otherwise\r\n -> addCtxTel tel\r\n $ vcat\r\n ([fsep\r\n $ pwords\r\n \"I'm not sure if there should be a case for the constructor\"\r\n ++\r\n [...]\r\n ++\r\n pwords \"because I get stuck when trying to solve the following\"\r\n ++\r\n pwords\r\n \"unification problems (inferred index \\8799 expected index):\"]\r\n ++\r\n zipWith\r\n (\\ c g -> nest 2 $ prettyTCM c <+> text \"\\8799\" <+> prettyTCM g)\r\n cIxs\r\n gIxs)\r\n CoverageCantSplitIrrelevantType a\r\n -> fsep\r\n $ pwords \"Cannot split on argument of irrelevant datatype\"\r\n ++ [prettyTCM a]\r\n CoverageCantSplitType a\r\n -> fsep\r\n $ pwords \"Cannot split on argument of non-datatype\"\r\n ++ [prettyTCM a]\r\n SplitError e -> prettyTCM e\r\n WithoutKError a u v\r\n -> fsep\r\n $ pwords \"Cannot eliminate reflexive equation\"\r\n ++\r\n [prettyTCM u]\r\n ++\r\n pwords \"=\"\r\n ++\r\n [prettyTCM v]\r\n ++\r\n pwords \"of type\"\r\n ++ [prettyTCM a] ++ pwords \"because K has been disabled.\"\r\n NotStrictlyPositive d ocs\r\n -> fsep\r\n $ pwords \"The datatype\"\r\n ++\r\n [prettyTCM d]\r\n ++ pwords \"is not strictly positive, because\" ++ prettyOcc \"it\" ocs\r\n where\r\n prettyOcc _ [] = []\r\n prettyOcc it (OccCon d c r : ocs) = concat [...]\r\n prettyOcc it (OccClause f n r : ocs) = concat [...]\r\n prettyR NonPositively = pwords \"negatively\"\r\n prettyR (ArgumentTo i q)\r\n = pwords \"as the\" ++ [...] ++ pwords \"argument to\" ++ [...]\r\n th 0 = text \"first\"\r\n th 1 = text \"second\"\r\n th 2 = text \"third\"\r\n th n = text (show $ n - 1) <> text \"th\"\r\n ....\r\n IFSNoCandidateInScope t\r\n -> fsep\r\n $ pwords \"No variable of type\"\r\n ++ [prettyTCM t] ++ pwords \"was found in scope.\"\r\n SafeFlagPostulate e\r\n -> fsep\r\n $ pwords \"Cannot postulate\"\r\n ++ [pretty e] ++ pwords \"with safe flag\"\r\n SafeFlagPragma xs\r\n -> let\r\n plural\r\n | length xs == 1 = ...\r\n | otherwise = ...\r\n in\r\n fsep\r\n $ [fwords (\"Cannot set OPTION pragma\" ++ plural)]\r\n ++ map text xs ++ [fwords \"with safe flag.\"]\r\n SafeFlagNoTerminationCheck\r\n -> fsep\r\n (pwords \"Cannot use NO_TERMINATION_CHECK pragma with safe flag.\")\r\n SafeFlagNonTerminating\r\n -> fsep\r\n (pwords \"Cannot use NON_TERMINATING pragma with safe flag.\")\r\n SafeFlagTerminating\r\n -> fsep (pwords \"Cannot use TERMINATING pragma with safe flag.\")\r\n SafeFlagPrimTrustMe\r\n -> fsep (pwords \"Cannot use primTrustMe with safe flag\")\r\n NeedOptionCopatterns\r\n -> fsep\r\n (pwords\r\n \"Option --copatterns needed to enable destructor patterns\") }\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->nadinenadinehttps://gitlab.haskell.org/ghc/ghc/-/issues/9674Foldable doesn't have any laws2019-07-07T18:39:32ZDavid FeuerFoldable doesn't have any lawsThe documentation for `Foldable` doesn't list any laws. I don't know exactly what its laws may be, but there are, at least, several implicit in the default method definitions.
<details><summary>Trac metadata</summary>
| Trac field ...The documentation for `Foldable` doesn't list any laws. I don't know exactly what its laws may be, but there are, at least, several implicit in the default method definitions.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------------------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Core Libraries |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | core-libraries-committee@haskell.org |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Foldable doesn't have any laws","status":"New","operating_system":"","component":"Core Libraries","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"ekmett"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["core-libraries-committee@haskell.org"],"type":"Bug","description":"The documentation for `Foldable` doesn't list any laws. I don't know exactly what its laws may be, but there are, at least, several implicit in the default method definitions.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1Edward KmettEdward Kmetthttps://gitlab.haskell.org/ghc/ghc/-/issues/9675Unreasonable memory usage on large data structures2021-12-10T11:18:30ZPolarinaUnreasonable memory usage on large data structuresI have attached a file that, when compiled, results in very large amount of memory usage by GHC.
The memory used is in the order of tens of gigabytes, but I've not been able to successfully compile the file due to lack of physical memor...I have attached a file that, when compiled, results in very large amount of memory usage by GHC.
The memory used is in the order of tens of gigabytes, but I've not been able to successfully compile the file due to lack of physical memory.
This is on Debian GNU/Linux (Jessie) using Haskell Platform 2014.2.0.0 with GHC 7.8.3.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Unreasonable memory usage on large data structures","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I have attached a file that, when compiled, results in very large amount of memory usage by GHC.\r\n\r\nThe memory used is in the order of tens of gigabytes, but I've not been able to successfully compile the file due to lack of physical memory.\r\n\r\nThis is on Debian GNU/Linux (Jessie) using Haskell Platform 2014.2.0.0 with GHC 7.8.3.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9678Warning about __sync_fetch_and_nand semantics from gcc2023-09-21T07:15:21ZgintasWarning about __sync_fetch_and_nand semantics from gccWhen building ghc, I'm getting warnings about __sync_fetch_and_nand that the semantics have changed for gcc 4.4+. I'm building on Windows, but I don't think that matters.
Is this an indication of a problem or does that warning just need...When building ghc, I'm getting warnings about __sync_fetch_and_nand that the semantics have changed for gcc 4.4+. I'm building on Windows, but I don't think that matters.
Is this an indication of a problem or does that warning just need to be silenced?
I ran the build with gcc 4.8.3:
$ inplace/mingw/bin/gcc -v
Using built-in specs.
COLLECT_GCC=C:\\msys64\\home\\Gintas\\ghc\\inplace\\mingw\\bin\\gcc.exe
COLLECT_LTO_WRAPPER=C:/msys64/home/Gintas/ghc/inplace/mingw/bin/../libexec/gcc/x86_64-w64-mingw32/4.8.3/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-4.8.3/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw483/x86_64-483-posix-seh-rt_v3-rev0/mingw64 --with-gxx-include-dir=/mingw64/x86_64-w64-mingw32/include/c++ --enable-shared --enable-static --disable-multilib --enable-languages=ada,c,c++,fortran,objc,obj-c++,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-isl-version-check --disable-cloog-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw483/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw483/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw483/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw483/prerequisites/x86_64-w64-mingw32-static --with-cloog=/c/mingw483/prerequisites/x86_64-w64-mingw32-static --enable-cloog-backend=isl --with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -I/c/mingw483/x86_64-483-posix-seh-rt_v3-rev0/mingw64/opt/include -I/c/mingw483/prerequisites/x86_64-zlib-static/include -I/c/mingw483/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -I/c/mingw483/x86_64-483-posix-seh-rt_v3-rev0/mingw64/opt/include -I/c/mingw483/prerequisites/x86_64-zlib-static/include -I/c/mingw483/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS= LDFLAGS='-pipe -L/c/mingw483/x86_64-483-posix-seh-rt_v3-rev0/mingw64/opt/lib -L/c/mingw483/prerequisites/x86_64-zlib-static/lib -L/c/mingw483/prerequisites/x86_64-w64-mingw32-static/lib'
Thread model: posix
gcc version 4.8.3 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.9 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Build System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Warning about __sync_fetch_and_nand semantics from gcc","status":"New","operating_system":"","component":"Build System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When building ghc, I'm getting warnings about __sync_fetch_and_nand that the semantics have changed for gcc 4.4+. I'm building on Windows, but I don't think that matters.\r\n\r\nIs this an indication of a problem or does that warning just need to be silenced?\r\n\r\nI ran the build with gcc 4.8.3:\r\n\r\n$ inplace/mingw/bin/gcc -v\r\nUsing built-in specs.\r\nCOLLECT_GCC=C:\\msys64\\home\\Gintas\\ghc\\inplace\\mingw\\bin\\gcc.exe\r\nCOLLECT_LTO_WRAPPER=C:/msys64/home/Gintas/ghc/inplace/mingw/bin/../libexec/gcc/x86_64-w64-mingw32/4.8.3/lto-wrapper.exe\r\nTarget: x86_64-w64-mingw32\r\nConfigured with: ../../../src/gcc-4.8.3/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw483/x86_64-483-posix-seh-rt_v3-rev0/mingw64 --with-gxx-include-dir=/mingw64/x86_64-w64-mingw32/include/c++ --enable-shared --enable-static --disable-multilib --enable-languages=ada,c,c++,fortran,objc,obj-c++,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-isl-version-check --disable-cloog-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw483/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw483/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw483/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw483/prerequisites/x86_64-w64-mingw32-static --with-cloog=/c/mingw483/prerequisites/x86_64-w64-mingw32-static --enable-cloog-backend=isl --with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -I/c/mingw483/x86_64-483-posix-seh-rt_v3-rev0/mingw64/opt/include -I/c/mingw483/prerequisites/x86_64-zlib-static/include -I/c/mingw483/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -I/c/mingw483/x86_64-483-posix-seh-rt_v3-rev0/mingw64/opt/include -I/c/mingw483/prerequisites/x86_64-zlib-static/include -I/c/mingw483/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS= LDFLAGS='-pipe -L/c/mingw483/x86_64-483-posix-seh-rt_v3-rev0/mingw64/opt/lib -L/c/mingw483/prerequisites/x86_64-zlib-static/lib -L/c/mingw483/prerequisites/x86_64-w64-mingw32-static/lib'\r\nThread model: posix\r\ngcc version 4.8.3 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9685GHC fails to build with mingw32-make on Windows2019-07-07T18:39:30ZgintasGHC fails to build with mingw32-make on WindowsIt would be nice to be able to build ghc on Windows with mingw32-make which is bundled with the prebuilt gcc package that we are using for the ghc build. mingw32-make might be faster (due to less overhead associated with POSIX compatibil...It would be nice to be able to build ghc on Windows with mingw32-make which is bundled with the prebuilt gcc package that we are using for the ghc build. mingw32-make might be faster (due to less overhead associated with POSIX compatibility, forks etc.) and more reliable - msys2's make is a bit glitchy because it needs to fork off a lot of processes and sometimes runs into issues with fork(), which should not be a problem for mingw32-make.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.9 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Build System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC fails to build with mingw32-make on Windows","status":"New","operating_system":"","component":"Build System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"gintas"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"It would be nice to be able to build ghc on Windows with mingw32-make which is bundled with the prebuilt gcc package that we are using for the ghc build. mingw32-make might be faster (due to less overhead associated with POSIX compatibility, forks etc.) and more reliable - msys2's make is a bit glitchy because it needs to fork off a lot of processes and sometimes runs into issues with fork(), which should not be a problem for mingw32-make.","type_of_failure":"OtherFailure","blocking":[]} -->gintasgintashttps://gitlab.haskell.org/ghc/ghc/-/issues/9686Link option detection does not work for incremental builds on Windows2019-07-07T18:39:30ZgintasLink option detection does not work for incremental builds on Windowsghc on Linux embeds link options into the resulting binary in order to be able to tell when a binary needs to be recompiled because different link options have been passed in to ghc. This functionality is not present on Windows, forcing ...ghc on Linux embeds link options into the resulting binary in order to be able to tell when a binary needs to be recompiled because different link options have been passed in to ghc. This functionality is not present on Windows, forcing users to pass in -fforce-recomp.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.9 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Link option detection does not work for incremental builds on Windows","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"gintas"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"ghc on Linux embeds link options into the resulting binary in order to be able to tell when a binary needs to be recompiled because different link options have been passed in to ghc. This functionality is not present on Windows, forcing users to pass in -fforce-recomp.","type_of_failure":"OtherFailure","blocking":[]} -->gintasgintas