GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2022-02-11T14:15:24Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/16314Improve confusing error message with MINIMAL pragma2022-02-11T14:15:24ZLevent ErkökImprove confusing error message with MINIMAL pragmaI got bitten by this recently, and while I can see GHC's reasoning, I wish it told me something different and more useful.
```hs
class X a where
foo :: a
{-# MINIMAL foo #-}
foo = undefined
instance X Int
```
For this program, ...I got bitten by this recently, and while I can see GHC's reasoning, I wish it told me something different and more useful.
```hs
class X a where
foo :: a
{-# MINIMAL foo #-}
foo = undefined
instance X Int
```
For this program, ghc says:
```
GHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( a.hs, interpreted )
a.hs:7:10: warning: [-Wmissing-methods]
• No explicit implementation for
‘foo’
• In the instance declaration for ‘X Int’
|
7 | instance X Int
| ^^^^^
```
This is arguably "correct", since I made `foo` part of `MINIMAL`; but it's very confusing, because I know I added a default definition.
I wish GHC instead said something like:
```
You made `foo` MINIMAL, but also gave an explicit definition for it.
```
I can see the logic behind the current error message, but it was rather confusing. The background is that my class had many other methods and a `MINIMAL` pragma. Much later I realized I could give a default definition of one of those methods but I forgot to remove it from the `MINIMAL` list. So, I had to puzzle a while at the error messages that were coming from far away modules that had nothing to do with the class definition itself.
This is not a showstopper by any means, but unless there are good reasons to do otherwise, it would be nice to get a warning right where the class is defined, as opposed to where it is instantiated.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.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":"Improve confusing error message with MINIMAL pragma","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"I got bitten by this recently, and while I can see GHC's reasoning, I wish it told me something different and more useful.\r\n\r\n{{{#!hs\r\nclass X a where\r\n foo :: a\r\n\r\n {-# MINIMAL foo #-}\r\n foo = undefined\r\n\r\ninstance X Int\r\n}}}\r\n\r\nFor this program, ghc says:\r\n\r\n{{{\r\nGHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help\r\n[1 of 1] Compiling Main ( a.hs, interpreted )\r\n\r\na.hs:7:10: warning: [-Wmissing-methods]\r\n • No explicit implementation for\r\n ‘foo’\r\n • In the instance declaration for ‘X Int’\r\n |\r\n7 | instance X Int\r\n | ^^^^^\r\n}}}\r\n\r\nThis is arguably \"correct\", since I made `foo` part of `MINIMAL`; but it's very confusing, because I know I added a default definition.\r\n\r\nI wish GHC instead said something like:\r\n\r\n{{{\r\nYou made `foo` MINIMAL, but also gave an explicit definition for it.\r\n}}}\r\n\r\nI can see the logic behind the current error message, but it was rather confusing. The background is that my class had many other methods and a `MINIMAL` pragma. Much later I realized I could give a default definition of one of those methods but I forgot to remove it from the `MINIMAL` list. So, I had to puzzle a while at the error messages that were coming from far away modules that had nothing to do with the class definition itself.\r\n\r\nThis is not a showstopper by any means, but unless there are good reasons to do otherwise, it would be nice to get a warning right where the class is defined, as opposed to where it is instantiated.\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16308testsuite driver is sensitive to registration of multiple boot package versions2019-07-07T18:00:35ZBen Gamaritestsuite driver is sensitive to registration of multiple boot package versionsCurrently `testsuite/tests/Makefile` generates the `--rootdir` flags to be passed by `runtests.py` by looking at the output of `ghc-pkg list`. In the case that the user has recently bumped their submodules this list may contain multiple ...Currently `testsuite/tests/Makefile` generates the `--rootdir` flags to be passed by `runtests.py` by looking at the output of `ghc-pkg list`. In the case that the user has recently bumped their submodules this list may contain multiple versions of the same package. This will then result in the same `library/$LIB/tests` directory being passed to the testsuite driver more than once. The testsuite driver will then squawk a "There are multiple tests with this name" warning. It took a few minutes for Simon and I to work out why this was.
We should do better here (at least in Hadrian). Either by:
- Teaching the testsuite driver to deduplicate the `--rootdir` list
- Using a more robust source for the list of tested packages
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"testsuite driver is sensitive to registration of multiple boot package versions","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Currently `testsuite/tests/Makefile` generates the `--rootdir` flags to be passed by `runtests.py` by looking at the output of `ghc-pkg list`. In the case that the user has recently bumped their submodules this list may contain multiple versions of the same package. This will then result in the same `library/$LIB/tests` directory being passed to the testsuite driver more than once. The testsuite driver will then squawk a \"There are multiple tests with this name\" warning. It took a few minutes for Simon and I to work out why this was.\r\n\r\nWe should do better here (at least in Hadrian). Either by:\r\n\r\n * Teaching the testsuite driver to deduplicate the `--rootdir` list\r\n * Using a more robust source for the list of tested packages","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16307gloss-examples' fluid program takes close to an eternity to compile2019-07-07T18:00:35ZBen Gamarigloss-examples' fluid program takes close to an eternity to compileIt has been over ten minutes and 16 GB of residency and `ghc` `master` still hasn't finished. We should investigate this; something seems very wrong.
https://github.com/bgamari/gloss/tree/d863394df7b5a9400f2c2fae08fdbb07c91c6822
<detai...It has been over ten minutes and 16 GB of residency and `ghc` `master` still hasn't finished. We should investigate this; something seems very wrong.
https://github.com/bgamari/gloss/tree/d863394df7b5a9400f2c2fae08fdbb07c91c6822
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.7 |
| 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":"gloss-examples' fluid program takes close to an eternity to compile","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.7","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"It has been over ten minutes and 16 GB of residency and `ghc` `master` still hasn't finished. We should investigate this; something seems very wrong.\r\n\r\nhttps://github.com/bgamari/gloss/tree/d863394df7b5a9400f2c2fae08fdbb07c91c6822","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16305When should -Wmissed-specializations fire?2022-03-21T19:16:53ZEric CrockettWhen should -Wmissed-specializations fire?While working on a fix for #16282, I noticed:
1. that `-Wmissed-specializations` doesn't fire when the docs say it should
1. that the "probable fix" suggested when a warning does fire is highly suspect
```
import Data.Map
main :: IO ()...While working on a fix for #16282, I noticed:
1. that `-Wmissed-specializations` doesn't fire when the docs say it should
1. that the "probable fix" suggested when a warning does fire is highly suspect
```
import Data.Map
main :: IO ()
main = do
let m = [] :: [Map String Bool]
mapM_ print m
```
With GHC 8.4.3, 8.6.3, and HEAD:
`ghc -O2 -Wmissed-specializations Main.hs` does \*not\* issue any warnings.
However, in 8.6.3 and HEAD, `ghc -O2 -Wall-missed-specializations Main.hs` \*does\* create a warning:
```
Main.hs: warning: [-Wall-missed-specialisations]
Could not specialise imported function ‘Data.Map.Internal.$w$cshowsPrec’
when specialising ‘Data.Map.Internal.$fShowMap_$cshowsPrec’
Probable fix: add INLINABLE pragma on ‘Data.Map.Internal.$w$cshowsPrec’
```
The docs for `-Wmissed-specializations` say, "warn when specialisation of an imported, overloaded function fails." Since `showsPrec` is an imported function, it seems that a warning should have been issued with `-Wmissed-specs`. My reading of the docs is that `-Wall-missed-specs` should output everything `-Wmissed-specs` does, along with any \*local\* overloaded and unspecialized functions.
Moreover, the "Probable fix" is suspect. A warning recommending an `INLINABLE` pragma is issued depending on the output of `warnMissedSpec` in specialise/Specialise.hs. For `-Wall-missed-specs`, `warnMissedSpec` doesn't check if an INLINABLE pragma is already present, so the fix could be redundant. For `-Wmissed-specs`, `warnMissedSpecs` \*only\* issues a warning if there \*is\* any inline pragma (of one sort of another) on all the callers, making the `probable fix` definitely redundant.https://gitlab.haskell.org/ghc/ghc/-/issues/16304Hadrian: refactor libffi and rts rules.2019-11-07T22:08:43ZdavideHadrian: refactor libffi and rts rules.The rts package depends on libffi. The hadrian rules around this are a bit hacky. The rts needs some specific header files, then the corresponding libffi rule takes on some unsolicited responsibilities, copying some important files into ...The rts package depends on libffi. The hadrian rules around this are a bit hacky. The rts needs some specific header files, then the corresponding libffi rule takes on some unsolicited responsibilities, copying some important files into the rts directory. Also see mpickering's [comment](https://gitlab.haskell.org/ghc/ghc/merge_requests/174#note_3288) on this:
> This whole copying the header files into the rts dir seemed very dodgy to me. Why do we not depend on libffi when building the rts and then copy the files we need in the rules for building the rts?
This is a hack implemented partly to get around the issue of not knowing the names of some libffi files until after building libffi. There surely is an idiomatic solution to this.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------------- |
| Version | 8.6.3 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Build System (Hadrian) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | alpmestan, mpickering |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Hadrian: refactor libffi and rts rules.","status":"New","operating_system":"","component":"Build System (Hadrian)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["alpmestan","mpickering"],"type":"Task","description":"The rts package depends on libffi. The hadrian rules around this are a bit hacky. The rts needs some specific header files, then the corresponding libffi rule takes on some unsolicited responsibilities, copying some important files into the rts directory. Also see mpickering's [https://gitlab.haskell.org/ghc/ghc/merge_requests/174#note_3288 comment] on this:\r\n\r\n This whole copying the header files into the rts dir seemed very dodgy to me. Why do we not depend on libffi when building the rts and then copy the files we need in the rules for building the rts?\r\n\r\nThis is a hack implemented partly to get around the issue of not knowing the names of some libffi files until after building libffi. There surely is an idiomatic solution to this.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16301Additions to Control.Exception: withException, displaySomeExceptionType2020-10-21T02:43:11ZdsfAdditions to Control.Exception: withException, displaySomeExceptionTypeRequires RankNTypes though.
```haskell
-- | Apply a function to whatever @Exception@ type is inside a
-- @SomeException@.
withException :: forall r. (forall e. Exception e => e -> r) -> SomeException -> r
withException f (SomeException ...Requires RankNTypes though.
```haskell
-- | Apply a function to whatever @Exception@ type is inside a
-- @SomeException@.
withException :: forall r. (forall e. Exception e => e -> r) -> SomeException -> r
withException f (SomeException e) = f e
-- | Use 'withException' to obtain the exception's type name.
displaySomeExceptionType :: SomeException -> String
displaySomeExceptionType = withException (show . typeOf)
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Additions to Control.Exception: withException, displaySomeExceptionType","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Requires RankNTypes though.\r\n\r\n{{{#!haskell\r\n-- | Apply a function to whatever @Exception@ type is inside a\r\n-- @SomeException@.\r\nwithException :: forall r. (forall e. Exception e => e -> r) -> SomeException -> r\r\nwithException f (SomeException e) = f e\r\n\r\n-- | Use 'withException' to obtain the exception's type name.\r\ndisplaySomeExceptionType :: SomeException -> String\r\ndisplaySomeExceptionType = withException (show . typeOf)\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16298Awful(?) code in AArch64 stg_BLACKHOLE entry code2019-07-07T18:00:37ZBen GamariAwful(?) code in AArch64 stg_BLACKHOLE entry codeIt's been a while since I've look at ARM assembler but this doesn't look right:
```
Dump of assembler code for function stg_BLACKHOLE_info$def:
0x0000ffffb66d6118 <+0>: mov x23, x22
0x0000ffffb66d611c <+4>: ldr x22...It's been a while since I've look at ARM assembler but this doesn't look right:
```
Dump of assembler code for function stg_BLACKHOLE_info$def:
0x0000ffffb66d6118 <+0>: mov x23, x22
0x0000ffffb66d611c <+4>: ldr x22, [x22, #8]
0x0000ffffb66d6120 <+8>: tst x22, #0x7
0x0000ffffb66d6124 <+12>: b.ne 0xffffb66d6224 <stg_BLACKHOLE_info$def+268> // b.any
0x0000ffffb66d6128 <+16>: adrp x25, 0xffffb66fb000
0x0000ffffb66d612c <+20>: adrp x26, 0xffffb66fb000
0x0000ffffb66d6130 <+24>: adrp x27, 0xffffb66fb000
0x0000ffffb66d6134 <+28>: adrp x29, 0xffffb66fb000
0x0000ffffb66d6138 <+32>: ldr x25, [x25, #3880]
0x0000ffffb66d613c <+36>: ldr x26, [x26, #3888]
0x0000ffffb66d6140 <+40>: ldr x27, [x27, #3896]
0x0000ffffb66d6144 <+44>: ldr x29, [x29, #3904]
0x0000ffffb66d6148 <+48>: sub x24, x19, #0x18
0x0000ffffb66d614c <+52>: ldr x8, [x22]
0x0000ffffb66d6150 <+56>: cmp x8, x25
...
```
Why do we `adrp` four times? Couldn't this be reused, with each `ldr` result going to a separate register?
This was generated by LLVM 7.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.7 |
| 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":"Awful(?) code in AArch64 stg_BLACKHOLE entry code","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.7","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"It's been a while since I've look at ARM assembler but this doesn't look right:\r\n\r\n{{{\r\nDump of assembler code for function stg_BLACKHOLE_info$def:\r\n 0x0000ffffb66d6118 <+0>: mov x23, x22\r\n 0x0000ffffb66d611c <+4>: ldr x22, [x22, #8]\r\n 0x0000ffffb66d6120 <+8>: tst x22, #0x7\r\n 0x0000ffffb66d6124 <+12>: b.ne 0xffffb66d6224 <stg_BLACKHOLE_info$def+268> // b.any\r\n 0x0000ffffb66d6128 <+16>: adrp x25, 0xffffb66fb000\r\n 0x0000ffffb66d612c <+20>: adrp x26, 0xffffb66fb000\r\n 0x0000ffffb66d6130 <+24>: adrp x27, 0xffffb66fb000\r\n 0x0000ffffb66d6134 <+28>: adrp x29, 0xffffb66fb000\r\n 0x0000ffffb66d6138 <+32>: ldr x25, [x25, #3880]\r\n 0x0000ffffb66d613c <+36>: ldr x26, [x26, #3888]\r\n 0x0000ffffb66d6140 <+40>: ldr x27, [x27, #3896]\r\n 0x0000ffffb66d6144 <+44>: ldr x29, [x29, #3904]\r\n 0x0000ffffb66d6148 <+48>: sub x24, x19, #0x18\r\n 0x0000ffffb66d614c <+52>: ldr x8, [x22]\r\n 0x0000ffffb66d6150 <+56>: cmp x8, x25\r\n...\r\n}}}\r\n\r\nWhy do we `adrp` four times? Couldn't this be reused, with each `ldr` result going to a separate register?\r\n\r\nThis was generated by LLVM 7.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16295Enable cached builds with Hadrian2019-07-07T18:00:38ZAndrey MokhovEnable cached builds with HadrianAs Neil is working on turning Shake into Cloud Shake \[1\], Shake has got a new feature of "locally cached builds", making it possible to reuse build artefacts from previous builds on the same machine. This means, in particular, that a c...As Neil is working on turning Shake into Cloud Shake \[1\], Shake has got a new feature of "locally cached builds", making it possible to reuse build artefacts from previous builds on the same machine. This means, in particular, that a clean build could be finished very quickly if you've built GHC before from the same/similar sources. Hopefully, this could also help us speed up GHC's CI some day.
To enable cached builds, it is important to find and fix all instances of untracked dependencies in Hadrian, or at least record them using the `produces` feature of Shake \[2\], because otherwise Shake has no idea that these files are actually needed and should therefore be stored in the cache. Here are a couple of tickets related to untracked dependencies:
#16271
#16272
I am currently working this and hope to produce a patch soon. I marked this is a "bug", not a "feature request", since untracked dependencies are bugs, and they prevent us from using Shake's shiny new feature.
\[1\] See the Build Systems à la Carte paper: https://dl.acm.org/ft_gateway.cfm?id=3236774
\[2\] http://hackage.haskell.org/package/shake/docs/Development-Shake.html\#v:produceshttps://gitlab.haskell.org/ghc/ghc/-/issues/16286Continuations are not labelled in the binaries even with -g32019-09-02T10:56:21ZÖmer Sinan AğacanContinuations are not labelled in the binaries even with -g3Any program would work as a reproducer, but here's what I'm using currently:
```
{-# LANGUAGE StaticPointers #-}
module Main where
import Control.Concurrent
import System.Mem
nats :: [Int]
nats = [0 .. ]
main = do
let z = nats !! ...Any program would work as a reproducer, but here's what I'm using currently:
```
{-# LANGUAGE StaticPointers #-}
module Main where
import Control.Concurrent
import System.Mem
nats :: [Int]
nats = [0 .. ]
main = do
let z = nats !! 400
print z
performGC
threadDelay 1000000
print (nats !! 900)
```
If I do `printStack` every time the GC copies a stack I sometimes see stack frames like
```
RET_SMALL (0x535568)
```
but in gdb or objdump output I can't find a symbol at that address, even when the program is built with `-g3`. When I print the location as `StgInfoTable*` I can see that it's a valid info table so `0x535578` should be labelled as `foo_info`.
In the objdump output I see that the location is shown as this:
```
535563: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
...
535570: 1e (bad)
535571: 00 00 add %al,(%rax)
535573: 00 00 add %al,(%rax)
535575: 00 00 add %al,(%rax)
535577: 00 bb e9 e2 85 00 add %bh,0x85e2e9(%rbx)
53557d: 48 83 c5 08 add $0x8,%rbp
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | |
| 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":"Continuations are not labelled in the binaries even with -g3","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Any program would work as a reproducer, but here's what I'm using currently:\r\n\r\n{{{\r\n{-# LANGUAGE StaticPointers #-}\r\n\r\nmodule Main where\r\n\r\nimport Control.Concurrent\r\nimport System.Mem\r\n\r\nnats :: [Int]\r\nnats = [0 .. ]\r\n\r\nmain = do\r\n let z = nats !! 400\r\n print z\r\n performGC\r\n threadDelay 1000000\r\n print (nats !! 900)\r\n}}}\r\n\r\nIf I do `printStack` every time the GC copies a stack I sometimes see stack frames like\r\n\r\n{{{\r\nRET_SMALL (0x535568)\r\n}}}\r\n\r\nbut in gdb or objdump output I can't find a symbol at that address, even when the program is built with `-g3`. When I print the location as `StgInfoTable*` I can see that it's a valid info table so `0x535578` should be labelled as `foo_info`. \r\n\r\nIn the objdump output I see that the location is shown as this:\r\n\r\n{{{\r\n 535563:\t0f 1f 44 00 00 \tnopl 0x0(%rax,%rax,1)\r\n\t...\r\n 535570:\t1e \t(bad) \r\n 535571:\t00 00 \tadd %al,(%rax)\r\n 535573:\t00 00 \tadd %al,(%rax)\r\n 535575:\t00 00 \tadd %al,(%rax)\r\n 535577:\t00 bb e9 e2 85 00 \tadd %bh,0x85e2e9(%rbx)\r\n 53557d:\t48 83 c5 08 \tadd $0x8,%rbp\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16285Hadrian fails to run the testsuite.2019-07-07T18:00:40ZAndreas KlebingerHadrian fails to run the testsuite.This is on windows with a tree based on the commit below.
```
commit a5373c1f (master)
Author: Simon Peyton Jones <simonpj@microsoft.com>
Date: Wed Jan 16 16:34:24 2019 +0000
Fix bogus worker for newtypes
```
Output as follows....This is on windows with a tree based on the commit below.
```
commit a5373c1f (master)
Author: Simon Peyton Jones <simonpj@microsoft.com>
Date: Wed Jan 16 16:34:24 2019 +0000
Fix bogus worker for newtypes
```
Output as follows.
```
$ hadrian/build.bat -c -j8 --flavour=quick test
Up to date
Up to date
hadrian: Encountered missing dependencies:
libiserv ==8.7
shakeArgsWith 0.001s 0%
Function shake 0.010s 0%
Database read 0.516s 13% ===
Database compression 0.074s 1%
With database 0.018s 0%
Running rules 3.280s 84% =========================
Total 3.900s 100%
Error when running Shake build system:
at src/Main.hs:58:30-42:
* Depends on: test
at src/Rules/Test.hs:90:5-17:
* Depends on: _build/stage1/lib/bin/ghc-iserv.exe
at src/Development/Shake/Internal/Rules/Oracle.hs:157:43-68:
* Depends on: OracleQ (ContextDataKey (Context {stage = Stage1, package = Package {pkgType = Program, pkgName = "iserv", pkgPath = "utils/iserv"}, way = v}))
at src/Hadrian/Haskell/Cabal/Parse.hs:202:5-36:
* Depends on: _build/stage1/utils/iserv/setup-config
* Raised the exception:
ExitFailure 1
```
Regular build with hadrian works.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------- |
| Version | 8.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown/Multiple |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Hadrian fails to run the testsuite.","status":"New","operating_system":"Unknown/Multiple","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This is on windows with a tree based on the commit below.\r\n\r\n\r\n{{{\r\ncommit a5373c1f (master)\r\nAuthor: Simon Peyton Jones <simonpj@microsoft.com>\r\nDate: Wed Jan 16 16:34:24 2019 +0000\r\n\r\n Fix bogus worker for newtypes\r\n\r\n}}}\r\n\r\nOutput as follows.\r\n{{{\r\n$ hadrian/build.bat -c -j8 --flavour=quick test\r\nUp to date\r\nUp to date\r\nhadrian: Encountered missing dependencies:\r\nlibiserv ==8.7\r\n\r\nshakeArgsWith 0.001s 0%\r\nFunction shake 0.010s 0%\r\nDatabase read 0.516s 13% ===\r\nDatabase compression 0.074s 1%\r\nWith database 0.018s 0%\r\nRunning rules 3.280s 84% =========================\r\nTotal 3.900s 100%\r\nError when running Shake build system:\r\n at src/Main.hs:58:30-42:\r\n* Depends on: test\r\n at src/Rules/Test.hs:90:5-17:\r\n* Depends on: _build/stage1/lib/bin/ghc-iserv.exe\r\n at src/Development/Shake/Internal/Rules/Oracle.hs:157:43-68:\r\n* Depends on: OracleQ (ContextDataKey (Context {stage = Stage1, package = Package {pkgType = Program, pkgName = \"iserv\", pkgPath = \"utils/iserv\"}, way = v}))\r\n at src/Hadrian/Haskell/Cabal/Parse.hs:202:5-36:\r\n* Depends on: _build/stage1/utils/iserv/setup-config\r\n* Raised the exception:\r\nExitFailure 1\r\n\r\n}}}\r\n\r\nRegular build with hadrian works.\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16284Abortion of fixed-point iteration in Demand Analyser discards sound results2019-07-24T13:42:46ZSebastian GrafAbortion of fixed-point iteration in Demand Analyser discards sound resultsConsider the following program:
```hs
-- Extracted from T4903
module Foo where
data Tree = Bin Tree Tree
tree :: Tree
tree = Bin tree tree
eq :: Tree -> Bool
eq (Bin l r) = eq l && eq r
```
`eq` amounts to the following Core:
```hs...Consider the following program:
```hs
-- Extracted from T4903
module Foo where
data Tree = Bin Tree Tree
tree :: Tree
tree = Bin tree tree
eq :: Tree -> Bool
eq (Bin l r) = eq l && eq r
```
`eq` amounts to the following Core:
```hs
eq
= \ (ds_d20O :: Tree) ->
case ds_d20O of { Bin l_aY8 r_aY9 ->
case eq l_aY8 of {
False -> False;
True -> eq r_aY9
}
}
```
It clearly diverges. That's also what pure strictness/termination/CPR analysis would find out. But because usage analysis can't find out in finite time (and that's fine) that `eq` uses its argument completely, we abort fixed-point iteration \[1\] and return `nopSig`, discarding useful and sound strictness information we found out along the way, like the fact that it diverges.
This isn't hard to fix: Just track which parts of the signature were still unsound during abortion and only zap them. I'm only recording this for posterity and as an argument in a discussion I'll maybe start in a few months of time...
\[1\] This is the ascending chain of demands on `ds_d20O` during fixed-point iteration:
```
H
U(1*H,1*H)
U(1*U(1*H,1*H),1*U(1*H,1*H))
...
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.3 |
| 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":"Abortion of fixed-point iteration in Demand Analyser discards sound results","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"⊥","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":["DemandAnalysis"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Consider the following program:\r\n\r\n{{{#!hs\r\n-- Extracted from T4903\r\nmodule Foo where\r\n\r\ndata Tree = Bin Tree Tree\r\n\r\ntree :: Tree\r\ntree = Bin tree tree\r\n\r\neq :: Tree -> Bool\r\neq (Bin l r) = eq l && eq r\r\n}}}\r\n\r\n`eq` amounts to the following Core:\r\n\r\n{{{#!hs\r\neq\r\n = \\ (ds_d20O :: Tree) ->\r\n case ds_d20O of { Bin l_aY8 r_aY9 ->\r\n case eq l_aY8 of {\r\n False -> False;\r\n True -> eq r_aY9\r\n }\r\n }\r\n}}}\r\n\r\nIt clearly diverges. That's also what pure strictness/termination/CPR analysis would find out. But because usage analysis can't find out in finite time (and that's fine) that `eq` uses its argument completely, we abort fixed-point iteration [1] and return `nopSig`, discarding useful and sound strictness information we found out along the way, like the fact that it diverges.\r\n\r\nThis isn't hard to fix: Just track which parts of the signature were still unsound during abortion and only zap them. I'm only recording this for posterity and as an argument in a discussion I'll maybe start in a few months of time...\r\n\r\n[1] This is the ascending chain of demands on `ds_d20O` during fixed-point iteration:\r\n{{{\r\nH\r\nU(1*H,1*H)\r\nU(1*U(1*H,1*H),1*U(1*H,1*H))\r\n...\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->⊥https://gitlab.haskell.org/ghc/ghc/-/issues/16283StaticPointers pragma changes generated code even when the feature is not used2021-08-09T15:32:20ZÖmer Sinan AğacanStaticPointers pragma changes generated code even when the feature is not usedTried with GHC HEAD. Program:
```
module Main where
import Control.Concurrent
import System.Mem
nats :: [Int]
nats = [0 .. ]
main = do
let z = nats !! 400
print z
performGC
threadDelay 1000000
print (nats !! 900)
```
Compi...Tried with GHC HEAD. Program:
```
module Main where
import Control.Concurrent
import System.Mem
nats :: [Int]
nats = [0 .. ]
main = do
let z = nats !! 400
print z
performGC
threadDelay 1000000
print (nats !! 900)
```
Compile without any flags:
```
==================== Tidy Core ====================
2019-02-04 09:16:26.121849511 UTC
Result size of Tidy Core
= {terms: 45, types: 26, coercions: 0, joins: 0/0}
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule1_r1zg :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule1_r1zg = "main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule2_r1zt :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule2_r1zt = GHC.Types.TrNameS $trModule1_r1zg
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule3_r1zu :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule3_r1zu = "Main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule4_r1zv :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule4_r1zv = GHC.Types.TrNameS $trModule3_r1zu
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
Main.$trModule :: GHC.Types.Module
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
Main.$trModule = GHC.Types.Module $trModule2_r1zt $trModule4_r1zv
-- RHS size: {terms: 4, types: 1, coercions: 0, joins: 0/0}
nats :: [Int]
[GblId]
nats = enumFrom @ Int GHC.Enum.$fEnumInt (GHC.Types.I# 0#)
-- RHS size: {terms: 22, types: 13, coercions: 0, joins: 0/0}
main :: IO ()
[GblId]
main
= >>
@ IO
GHC.Base.$fMonadIO
@ ()
@ ()
(print
@ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 400#)))
(>>
@ IO
GHC.Base.$fMonadIO
@ ()
@ ()
performGC
(>>
@ IO
GHC.Base.$fMonadIO
@ ()
@ ()
(threadDelay (GHC.Types.I# 1000000#))
(print
@ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 900#)))))
-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}
:Main.main :: IO ()
[GblId]
:Main.main = GHC.TopHandler.runMainIO @ () main
```
Compile with `-XStaticPointers`:
```
==================== Tidy Core ====================
2019-02-04 09:16:35.678350955 UTC
Result size of Tidy Core
= {terms: 67, types: 42, coercions: 0, joins: 0/0}
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule1_r1zg :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule1_r1zg = "main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule2_r1zF :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule2_r1zF = GHC.Types.TrNameS $trModule1_r1zg
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule3_r1zG :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule3_r1zG = "Main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule4_r1zH :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule4_r1zH = GHC.Types.TrNameS $trModule3_r1zG
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
Main.$trModule :: GHC.Types.Module
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
Main.$trModule = GHC.Types.Module $trModule2_r1zF $trModule4_r1zH
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
lvl_r1zI :: Int
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
lvl_r1zI = GHC.Types.I# 0#
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
nats :: [Int]
[GblId]
nats = enumFrom @ Int GHC.Enum.$fEnumInt lvl_r1zI
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
lvl1_r1zJ :: Int
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
lvl1_r1zJ = GHC.Types.I# 400#
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
lvl2_r1zK :: Int
[GblId]
lvl2_r1zK = !! @ Int nats lvl1_r1zJ
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
lvl3_r1zL :: IO ()
[GblId]
lvl3_r1zL = print @ Int GHC.Show.$fShowInt lvl2_r1zK
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
lvl4_r1zM :: Int
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
lvl4_r1zM = GHC.Types.I# 1000000#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
lvl5_r1zN :: IO ()
[GblId]
lvl5_r1zN = threadDelay lvl4_r1zM
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
lvl6_r1zO :: Int
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
lvl6_r1zO = GHC.Types.I# 900#
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
lvl7_r1zP :: Int
[GblId]
lvl7_r1zP = !! @ Int nats lvl6_r1zO
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
lvl8_r1zQ :: IO ()
[GblId]
lvl8_r1zQ = print @ Int GHC.Show.$fShowInt lvl7_r1zP
-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
lvl9_r1zR :: IO ()
[GblId]
lvl9_r1zR
= >> @ IO GHC.Base.$fMonadIO @ () @ () lvl5_r1zN lvl8_r1zQ
-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
lvl10_r1zS :: IO ()
[GblId]
lvl10_r1zS
= >> @ IO GHC.Base.$fMonadIO @ () @ () performGC lvl9_r1zR
-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
main :: IO ()
[GblId]
main = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl3_r1zL lvl10_r1zS
-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}
:Main.main :: IO ()
[GblId]
:Main.main = GHC.TopHandler.runMainIO @ () main
```
Diff:
```
--- no_static_ptrs/GcStaticPointers.dump-simpl 2019-02-04 12:16:26.120066655 +0300
+++ static_ptrs/GcStaticPointers.dump-simpl 2019-02-04 12:16:35.675924328 +0300
@@ -1,9 +1,9 @@
==================== Tidy Core ====================
-2019-02-04 09:16:26.121849511 UTC
+2019-02-04 09:16:35.678350955 UTC
Result size of Tidy Core
- = {terms: 45, types: 26, coercions: 0, joins: 0/0}
+ = {terms: 67, types: 42, coercions: 0, joins: 0/0}
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule1_r1zg :: GHC.Prim.Addr#
@@ -11,55 +11,91 @@
$trModule1_r1zg = "main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-$trModule2_r1zt :: GHC.Types.TrName
+$trModule2_r1zF :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
-$trModule2_r1zt = GHC.Types.TrNameS $trModule1_r1zg
+$trModule2_r1zF = GHC.Types.TrNameS $trModule1_r1zg
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-$trModule3_r1zu :: GHC.Prim.Addr#
+$trModule3_r1zG :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
-$trModule3_r1zu = "Main"#
+$trModule3_r1zG = "Main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-$trModule4_r1zv :: GHC.Types.TrName
+$trModule4_r1zH :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
-$trModule4_r1zv = GHC.Types.TrNameS $trModule3_r1zu
+$trModule4_r1zH = GHC.Types.TrNameS $trModule3_r1zG
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
Main.$trModule :: GHC.Types.Module
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
-Main.$trModule = GHC.Types.Module $trModule2_r1zt $trModule4_r1zv
+Main.$trModule = GHC.Types.Module $trModule2_r1zF $trModule4_r1zH
--- RHS size: {terms: 4, types: 1, coercions: 0, joins: 0/0}
+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
+lvl_r1zI :: Int
+[GblId, Caf=NoCafRefs, Unf=OtherCon []]
+lvl_r1zI = GHC.Types.I# 0#
+
+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
nats :: [Int]
[GblId]
-nats = enumFrom @ Int GHC.Enum.$fEnumInt (GHC.Types.I# 0#)
+nats = enumFrom @ Int GHC.Enum.$fEnumInt lvl_r1zI
+
+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
+lvl1_r1zJ :: Int
+[GblId, Caf=NoCafRefs, Unf=OtherCon []]
+lvl1_r1zJ = GHC.Types.I# 400#
+
+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
+lvl2_r1zK :: Int
+[GblId]
+lvl2_r1zK = !! @ Int nats lvl1_r1zJ
+
+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
+lvl3_r1zL :: IO ()
+[GblId]
+lvl3_r1zL = print @ Int GHC.Show.$fShowInt lvl2_r1zK
+
+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
+lvl4_r1zM :: Int
+[GblId, Caf=NoCafRefs, Unf=OtherCon []]
+lvl4_r1zM = GHC.Types.I# 1000000#
+
+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
+lvl5_r1zN :: IO ()
+[GblId]
+lvl5_r1zN = threadDelay lvl4_r1zM
+
+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
+lvl6_r1zO :: Int
+[GblId, Caf=NoCafRefs, Unf=OtherCon []]
+lvl6_r1zO = GHC.Types.I# 900#
+
+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
+lvl7_r1zP :: Int
+[GblId]
+lvl7_r1zP = !! @ Int nats lvl6_r1zO
+
+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
+lvl8_r1zQ :: IO ()
+[GblId]
+lvl8_r1zQ = print @ Int GHC.Show.$fShowInt lvl7_r1zP
+
+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
+lvl9_r1zR :: IO ()
+[GblId]
+lvl9_r1zR
+ = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl5_r1zN lvl8_r1zQ
+
+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
+lvl10_r1zS :: IO ()
+[GblId]
+lvl10_r1zS
+ = >> @ IO GHC.Base.$fMonadIO @ () @ () performGC lvl9_r1zR
--- RHS size: {terms: 22, types: 13, coercions: 0, joins: 0/0}
+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
main :: IO ()
[GblId]
-main
- = >>
- @ IO
- GHC.Base.$fMonadIO
- @ ()
- @ ()
- (print
- @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 400#)))
- (>>
- @ IO
- GHC.Base.$fMonadIO
- @ ()
- @ ()
- performGC
- (>>
- @ IO
- GHC.Base.$fMonadIO
- @ ()
- @ ()
- (threadDelay (GHC.Types.I# 1000000#))
- (print
- @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 900#)))))
+main = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl3_r1zL lvl10_r1zS
-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}
:Main.main :: IO ()
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | |
| 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":"StaticPointers pragma changes generated code even when the feature is not used","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Tried with GHC HEAD. Program:\r\n\r\n{{{\r\nmodule Main where\r\n\r\nimport Control.Concurrent\r\nimport System.Mem\r\n\r\nnats :: [Int]\r\nnats = [0 .. ]\r\n\r\nmain = do\r\n let z = nats !! 400\r\n print z\r\n performGC\r\n threadDelay 1000000\r\n print (nats !! 900)\r\n}}}\r\n\r\nCompile without any flags:\r\n\r\n{{{\r\n==================== Tidy Core ====================\r\n2019-02-04 09:16:26.121849511 UTC\r\n\r\nResult size of Tidy Core\r\n = {terms: 45, types: 26, coercions: 0, joins: 0/0}\r\n\r\n-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n$trModule1_r1zg :: GHC.Prim.Addr#\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule1_r1zg = \"main\"#\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n$trModule2_r1zt :: GHC.Types.TrName\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule2_r1zt = GHC.Types.TrNameS $trModule1_r1zg\r\n\r\n-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n$trModule3_r1zu :: GHC.Prim.Addr#\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule3_r1zu = \"Main\"#\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n$trModule4_r1zv :: GHC.Types.TrName\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule4_r1zv = GHC.Types.TrNameS $trModule3_r1zu\r\n\r\n-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}\r\nMain.$trModule :: GHC.Types.Module\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nMain.$trModule = GHC.Types.Module $trModule2_r1zt $trModule4_r1zv\r\n\r\n-- RHS size: {terms: 4, types: 1, coercions: 0, joins: 0/0}\r\nnats :: [Int]\r\n[GblId]\r\nnats = enumFrom @ Int GHC.Enum.$fEnumInt (GHC.Types.I# 0#)\r\n\r\n-- RHS size: {terms: 22, types: 13, coercions: 0, joins: 0/0}\r\nmain :: IO ()\r\n[GblId]\r\nmain\r\n = >>\r\n @ IO\r\n GHC.Base.$fMonadIO\r\n @ ()\r\n @ ()\r\n (print\r\n @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 400#)))\r\n (>>\r\n @ IO\r\n GHC.Base.$fMonadIO\r\n @ ()\r\n @ ()\r\n performGC\r\n (>>\r\n @ IO\r\n GHC.Base.$fMonadIO\r\n @ ()\r\n @ ()\r\n (threadDelay (GHC.Types.I# 1000000#))\r\n (print\r\n @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 900#)))))\r\n\r\n-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}\r\n:Main.main :: IO ()\r\n[GblId]\r\n:Main.main = GHC.TopHandler.runMainIO @ () main\r\n}}}\r\n\r\nCompile with `-XStaticPointers`:\r\n\r\n{{{\r\n\r\n==================== Tidy Core ====================\r\n2019-02-04 09:16:35.678350955 UTC\r\n\r\nResult size of Tidy Core\r\n = {terms: 67, types: 42, coercions: 0, joins: 0/0}\r\n\r\n-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n$trModule1_r1zg :: GHC.Prim.Addr#\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule1_r1zg = \"main\"#\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n$trModule2_r1zF :: GHC.Types.TrName\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule2_r1zF = GHC.Types.TrNameS $trModule1_r1zg\r\n\r\n-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n$trModule3_r1zG :: GHC.Prim.Addr#\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule3_r1zG = \"Main\"#\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n$trModule4_r1zH :: GHC.Types.TrName\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule4_r1zH = GHC.Types.TrNameS $trModule3_r1zG\r\n\r\n-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}\r\nMain.$trModule :: GHC.Types.Module\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nMain.$trModule = GHC.Types.Module $trModule2_r1zF $trModule4_r1zH\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\nlvl_r1zI :: Int\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nlvl_r1zI = GHC.Types.I# 0#\r\n\r\n-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\nnats :: [Int]\r\n[GblId]\r\nnats = enumFrom @ Int GHC.Enum.$fEnumInt lvl_r1zI\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\nlvl1_r1zJ :: Int\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nlvl1_r1zJ = GHC.Types.I# 400#\r\n\r\n-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\nlvl2_r1zK :: Int\r\n[GblId]\r\nlvl2_r1zK = !! @ Int nats lvl1_r1zJ\r\n\r\n-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\nlvl3_r1zL :: IO ()\r\n[GblId]\r\nlvl3_r1zL = print @ Int GHC.Show.$fShowInt lvl2_r1zK\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\nlvl4_r1zM :: Int\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nlvl4_r1zM = GHC.Types.I# 1000000#\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\nlvl5_r1zN :: IO ()\r\n[GblId]\r\nlvl5_r1zN = threadDelay lvl4_r1zM\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\nlvl6_r1zO :: Int\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nlvl6_r1zO = GHC.Types.I# 900#\r\n\r\n-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\nlvl7_r1zP :: Int\r\n[GblId]\r\nlvl7_r1zP = !! @ Int nats lvl6_r1zO\r\n\r\n-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\nlvl8_r1zQ :: IO ()\r\n[GblId]\r\nlvl8_r1zQ = print @ Int GHC.Show.$fShowInt lvl7_r1zP\r\n\r\n-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\nlvl9_r1zR :: IO ()\r\n[GblId]\r\nlvl9_r1zR\r\n = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl5_r1zN lvl8_r1zQ\r\n\r\n-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\nlvl10_r1zS :: IO ()\r\n[GblId]\r\nlvl10_r1zS\r\n = >> @ IO GHC.Base.$fMonadIO @ () @ () performGC lvl9_r1zR\r\n\r\n-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\nmain :: IO ()\r\n[GblId]\r\nmain = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl3_r1zL lvl10_r1zS\r\n\r\n-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}\r\n:Main.main :: IO ()\r\n[GblId]\r\n:Main.main = GHC.TopHandler.runMainIO @ () main\r\n}}}\r\n\r\nDiff:\r\n\r\n{{{\r\n--- no_static_ptrs/GcStaticPointers.dump-simpl\t2019-02-04 12:16:26.120066655 +0300\r\n+++ static_ptrs/GcStaticPointers.dump-simpl\t2019-02-04 12:16:35.675924328 +0300\r\n@@ -1,9 +1,9 @@\r\n \r\n ==================== Tidy Core ====================\r\n-2019-02-04 09:16:26.121849511 UTC\r\n+2019-02-04 09:16:35.678350955 UTC\r\n \r\n Result size of Tidy Core\r\n- = {terms: 45, types: 26, coercions: 0, joins: 0/0}\r\n+ = {terms: 67, types: 42, coercions: 0, joins: 0/0}\r\n \r\n -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n $trModule1_r1zg :: GHC.Prim.Addr#\r\n@@ -11,55 +11,91 @@\r\n $trModule1_r1zg = \"main\"#\r\n \r\n -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n-$trModule2_r1zt :: GHC.Types.TrName\r\n+$trModule2_r1zF :: GHC.Types.TrName\r\n [GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n-$trModule2_r1zt = GHC.Types.TrNameS $trModule1_r1zg\r\n+$trModule2_r1zF = GHC.Types.TrNameS $trModule1_r1zg\r\n \r\n -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n-$trModule3_r1zu :: GHC.Prim.Addr#\r\n+$trModule3_r1zG :: GHC.Prim.Addr#\r\n [GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n-$trModule3_r1zu = \"Main\"#\r\n+$trModule3_r1zG = \"Main\"#\r\n \r\n -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n-$trModule4_r1zv :: GHC.Types.TrName\r\n+$trModule4_r1zH :: GHC.Types.TrName\r\n [GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n-$trModule4_r1zv = GHC.Types.TrNameS $trModule3_r1zu\r\n+$trModule4_r1zH = GHC.Types.TrNameS $trModule3_r1zG\r\n \r\n -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}\r\n Main.$trModule :: GHC.Types.Module\r\n [GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n-Main.$trModule = GHC.Types.Module $trModule2_r1zt $trModule4_r1zv\r\n+Main.$trModule = GHC.Types.Module $trModule2_r1zF $trModule4_r1zH\r\n \r\n--- RHS size: {terms: 4, types: 1, coercions: 0, joins: 0/0}\r\n+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n+lvl_r1zI :: Int\r\n+[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n+lvl_r1zI = GHC.Types.I# 0#\r\n+\r\n+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\n nats :: [Int]\r\n [GblId]\r\n-nats = enumFrom @ Int GHC.Enum.$fEnumInt (GHC.Types.I# 0#)\r\n+nats = enumFrom @ Int GHC.Enum.$fEnumInt lvl_r1zI\r\n+\r\n+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n+lvl1_r1zJ :: Int\r\n+[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n+lvl1_r1zJ = GHC.Types.I# 400#\r\n+\r\n+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\n+lvl2_r1zK :: Int\r\n+[GblId]\r\n+lvl2_r1zK = !! @ Int nats lvl1_r1zJ\r\n+\r\n+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\n+lvl3_r1zL :: IO ()\r\n+[GblId]\r\n+lvl3_r1zL = print @ Int GHC.Show.$fShowInt lvl2_r1zK\r\n+\r\n+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n+lvl4_r1zM :: Int\r\n+[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n+lvl4_r1zM = GHC.Types.I# 1000000#\r\n+\r\n+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n+lvl5_r1zN :: IO ()\r\n+[GblId]\r\n+lvl5_r1zN = threadDelay lvl4_r1zM\r\n+\r\n+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n+lvl6_r1zO :: Int\r\n+[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n+lvl6_r1zO = GHC.Types.I# 900#\r\n+\r\n+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\n+lvl7_r1zP :: Int\r\n+[GblId]\r\n+lvl7_r1zP = !! @ Int nats lvl6_r1zO\r\n+\r\n+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\n+lvl8_r1zQ :: IO ()\r\n+[GblId]\r\n+lvl8_r1zQ = print @ Int GHC.Show.$fShowInt lvl7_r1zP\r\n+\r\n+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\n+lvl9_r1zR :: IO ()\r\n+[GblId]\r\n+lvl9_r1zR\r\n+ = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl5_r1zN lvl8_r1zQ\r\n+\r\n+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\n+lvl10_r1zS :: IO ()\r\n+[GblId]\r\n+lvl10_r1zS\r\n+ = >> @ IO GHC.Base.$fMonadIO @ () @ () performGC lvl9_r1zR\r\n \r\n--- RHS size: {terms: 22, types: 13, coercions: 0, joins: 0/0}\r\n+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\n main :: IO ()\r\n [GblId]\r\n-main\r\n- = >>\r\n- @ IO\r\n- GHC.Base.$fMonadIO\r\n- @ ()\r\n- @ ()\r\n- (print\r\n- @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 400#)))\r\n- (>>\r\n- @ IO\r\n- GHC.Base.$fMonadIO\r\n- @ ()\r\n- @ ()\r\n- performGC\r\n- (>>\r\n- @ IO\r\n- GHC.Base.$fMonadIO\r\n- @ ()\r\n- @ ()\r\n- (threadDelay (GHC.Types.I# 1000000#))\r\n- (print\r\n- @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 900#)))))\r\n+main = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl3_r1zL lvl10_r1zS\r\n \r\n -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}\r\n :Main.main :: IO ()\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16278Exhaustivity checking GADT with free variables2022-09-20T17:28:38ZAndrew MartinExhaustivity checking GADT with free variablesConsider the following example:
```hs
{-# language DataKinds #-}
{-# language TypeFamilies #-}
{-# language GADTs #-}
{-# language KindSignatures #-}
{-# OPTIONS_GHC -Wall -fforce-recomp #-}
module GadtException where
import Data.Kin...Consider the following example:
```hs
{-# language DataKinds #-}
{-# language TypeFamilies #-}
{-# language GADTs #-}
{-# language KindSignatures #-}
{-# OPTIONS_GHC -Wall -fforce-recomp #-}
module GadtException where
import Data.Kind (Type)
import GHC.Exts
data Send = Send
data SocketException :: Send -> Type where
LocalShutdown :: SocketException 'Send
OutOfMemory :: SocketException a
someSocketException :: SocketException a
someSocketException = OutOfMemory
foo :: Int
foo = case someSocketException :: SocketException Any of
LocalShutdown -> 2
OutOfMemory -> 1
```
In `foo`, GHC's exhaustivity checker requires a pattern match on `LocalShutdown`. However, `LocalShutdown` is not an inhabitant of `SocketException Any`. What I would really like is for this to go one step further. I shouldn't even need to write the type annotation. That is, with the above code otherwise unchanged, GHC should recognize that
```hs
foo :: Int
foo = case someSocketException of
OutOfMemory -> 1
```
handles all possible cases. Since fully polymorphic type variables become `Any` at some point during typechecking, I would expect that if this worked with the `SocketException Any` type signature, it would work without it.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"Exhaustivity checking GADT with free variables","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider the following example:\r\n\r\n{{{#!hs\r\n{-# language DataKinds #-}\r\n{-# language TypeFamilies #-}\r\n{-# language GADTs #-}\r\n{-# language KindSignatures #-}\r\n\r\n{-# OPTIONS_GHC -Wall -fforce-recomp #-}\r\n\r\nmodule GadtException where\r\n\r\nimport Data.Kind (Type)\r\nimport GHC.Exts\r\n\r\ndata Send = Send\r\n\r\ndata SocketException :: Send -> Type where \r\n LocalShutdown :: SocketException 'Send\r\n OutOfMemory :: SocketException a\r\n\r\nsomeSocketException :: SocketException a\r\nsomeSocketException = OutOfMemory\r\n\r\nfoo :: Int\r\nfoo = case someSocketException :: SocketException Any of\r\n LocalShutdown -> 2\r\n OutOfMemory -> 1\r\n}}}\r\n\r\nIn `foo`, GHC's exhaustivity checker requires a pattern match on `LocalShutdown`. However, `LocalShutdown` is not an inhabitant of `SocketException Any`. What I would really like is for this to go one step further. I shouldn't even need to write the type annotation. That is, with the above code otherwise unchanged, GHC should recognize that\r\n\r\n{{{#!hs\r\nfoo :: Int\r\nfoo = case someSocketException of\r\n OutOfMemory -> 1\r\n}}}\r\n\r\nhandles all possible cases. Since fully polymorphic type variables become `Any` at some point during typechecking, I would expect that if this worked with the `SocketException Any` type signature, it would work without it.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16277Make JUnit report stdout/stderr in more cases2019-07-07T18:00:42ZMatthew PickeringMake JUnit report stdout/stderr in more casesIn https://gitlab.haskell.org/ghc/ghc/merge_requests/210 we made a start to improve the junit output to
also include stderr/stdout when appropriate.
However, the patch only handles a few cases, it is reasonably straightforward to handle...In https://gitlab.haskell.org/ghc/ghc/merge_requests/210 we made a start to improve the junit output to
also include stderr/stdout when appropriate.
However, the patch only handles a few cases, it is reasonably straightforward to handle more cases but the refactoring was a bit more involved than I was prepared to do at the time.
To find more places, look in `testlib.py` and grep for `failBecause`. There are examples such as `bad stderr` and `bad stdout` which would also benefit from reporting the stderr.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.3 |
| 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":"Make JUnit report stdout/stderr in more cases","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":["newcomer"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"In https://gitlab.haskell.org/ghc/ghc/merge_requests/210 we made a start to improve the junit output to\r\nalso include stderr/stdout when appropriate. \r\n\r\nHowever, the patch only handles a few cases, it is reasonably straightforward to handle more cases but the refactoring was a bit more involved than I was prepared to do at the time. \r\n\r\nTo find more places, look in `testlib.py` and grep for `failBecause`. There are examples such as `bad stderr` and `bad stdout` which would also benefit from reporting the stderr. ","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16276Feature request: Polymorphic kinds in Data.Functor.Classes2019-07-07T18:00:42ZLangston BarrettFeature request: Polymorphic kinds in Data.Functor.ClassesThe classes in Data.Functor.Classes have a somewhat restrictive kind signature:
```
*Data.Functor.Classes> :k Eq1
Eq1 :: (* -> *) ...The classes in Data.Functor.Classes have a somewhat restrictive kind signature:
```
*Data.Functor.Classes> :k Eq1
Eq1 :: (* -> *) -> Constraint
```
As a result, we redefine \[1\] many of them in the [parameterized-utils](https://hackage.haskell.org/package/parameterized-utils-1.0.1/docs/Data-Parameterized-Classes.html) library. It would be quite easy to make more polymorphic (have kind "(k -\> \*) -\> Constraint"). If everyone thinks this is a good idea, I'm happy to submit a pull request.
\[1\]: To be precise, there are actually a few axes along which the classes in parameterized-utils vary from those in base. Some, like OrdF, require more type-level evidence. Others, like EqF, don't require their type parameter to have the corresponding instance. There are a lot of points in the design space here.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.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":"Feature request: Polymorphic kinds in Data.Functor.Classes","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":["polykinds"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"The classes in Data.Functor.Classes have a somewhat restrictive kind signature:\r\n{{{\r\n*Data.Functor.Classes> :k Eq1 \r\nEq1 :: (* -> *) -> Constraint \r\n}}}\r\n\r\nAs a result, we redefine [1] many of them in the [https://hackage.haskell.org/package/parameterized-utils-1.0.1/docs/Data-Parameterized-Classes.html parameterized-utils] library. It would be quite easy to make more polymorphic (have kind \"(k -> *) -> Constraint\"). If everyone thinks this is a good idea, I'm happy to submit a pull request. \r\n\r\n[1]: To be precise, there are actually a few axes along which the classes in parameterized-utils vary from those in base. Some, like OrdF, require more type-level evidence. Others, like EqF, don't require their type parameter to have the corresponding instance. There are a lot of points in the design space here. ","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16275type hole in hs-boot file triggers GHC internal error2019-07-07T18:00:43Zwaldmann@imn.htwk-leipzig.detype hole in hs-boot file triggers GHC internal errorPut each line in a separate file, the last one is B.hs-boot
```
module A where { import {-# SOURCE #-} B }
module B where { }
module B where { data T a ; foo :: T _ }
```
then
```
$ ghci A.hs
GHCi, version 8.6.3: http://www.haskel...Put each line in a separate file, the last one is B.hs-boot
```
module A where { import {-# SOURCE #-} B }
module B where { }
module B where { data T a ; foo :: T _ }
```
then
```
$ ghci A.hs
GHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help
[1 of 3] Compiling B[boot] ( B.hs-boot, interpreted )
B.hs-boot:1:38: error:
• GHC internal error: ‘_’ is not in scope during type checking, but it passed the renamer
tcl_env of environment: []
• In the first argument of ‘T’, namely ‘_’
In the type signature: foo :: T _
|
1 | module B where { data T a ; foo :: T _ }
| ^
```
I know the program is invalid (the hole has no valid instance) but still it should not produce an internal error?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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 hole in hs-boot file triggers GHC internal error","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Put each line in a separate file, the last one is B.hs-boot\r\n{{{\r\nmodule A where { import {-# SOURCE #-} B }\r\n\r\nmodule B where { }\r\n\r\nmodule B where { data T a ; foo :: T _ }\r\n}}}\r\nthen\r\n{{{\r\n$ ghci A.hs \r\n\r\nGHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help\r\n[1 of 3] Compiling B[boot] ( B.hs-boot, interpreted )\r\n\r\nB.hs-boot:1:38: error:\r\n • GHC internal error: ‘_’ is not in scope during type checking, but it passed the renamer\r\n tcl_env of environment: []\r\n • In the first argument of ‘T’, namely ‘_’\r\n In the type signature: foo :: T _\r\n |\r\n1 | module B where { data T a ; foo :: T _ }\r\n | ^\r\n}}}\r\nI know the program is invalid (the hole has no valid instance) but still it should not produce an internal error?\r\n\r\n\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16268Potential race condition in Hadrian?2019-07-07T18:00:44ZMatthew PickeringPotential race condition in Hadrian?It seems that sometimes CI jobs fail because of a race condition in Hadrian.
https://gitlab.haskell.org/ghc/ghc/-/jobs/20254
Here, array finishes before `deepseq` starts to be built but the configure step for `deepseq` fails to find th...It seems that sometimes CI jobs fail because of a race condition in Hadrian.
https://gitlab.haskell.org/ghc/ghc/-/jobs/20254
Here, array finishes before `deepseq` starts to be built but the configure step for `deepseq` fails to find the library.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"Potential race condition in Hadrian?","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"It seems that sometimes CI jobs fail because of a race condition in Hadrian.\r\n\r\nhttps://gitlab.haskell.org/ghc/ghc/-/jobs/20254\r\n\r\nHere, array finishes before `deepseq` starts to be built but the configure step for `deepseq` fails to find the library.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16266Allow definition of functions with absurd contexts2019-11-06T16:20:33ZSo8resAllow definition of functions with absurd contextsConsider the following code:
```hs
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# ...Consider the following code:
```hs
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
type family Head xxs where
Head (x ': xs) = x
type family Tail xxs where
Tail (x ': xs) = xs
class IsList xs where
isList :: (xs ~ '[] => r) -> ((xs ~ (Head xs ': Tail xs), IsList (Tail xs)) => r) -> r
instance IsList '[] where isList r _ = r
instance IsList xs => IsList (x ': xs) where isList _ r = r
nonEmptyListsAreNotEmpty :: (xs ~ '[], xs ~ (Head xs ': Tail xs)) => r
nonEmptyListsAreNotEmpty = error "you convinced GHC that '[] ~ (_ ': _)!"
sillyExample :: forall x xs. IsList (x ': xs) => ()
sillyExample = isList @(x ': xs) nonEmptyListsAreNotEmpty ()
```
In this code, we define a class IsList which serves as a proof that something is a type-level list, via the function isList. When using this, we may occasionally get into a situation where the types guarantee that we're working with a non-empty list, but we're asked to handle the empty-list case anyway. Suppose we want to define a nice little "absurd" function that serves as a reminder to readers that this code branch is impossible, in a way that GHC can verify. This function is named "nonEmptyListsAreNonEmpty" above.
Unfortunately, this code fails with
```
Main.hs:25:34: error:
• Couldn't match type ‘'[]’ with ‘Head '[] : Tail '[]’
arising from a use of ‘nonEmptyListsAreNotEmpty’
• In the second argument of ‘isList’, namely
‘nonEmptyListsAreNotEmpty’
In the expression: isList @(x : xs) nonEmptyListsAreNotEmpty ()
In an equation for ‘sillyExample’:
sillyExample = isList @(x : xs) nonEmptyListsAreNotEmpty ()
|
25 | sillyExample = isList @(x ': xs) nonEmptyListsAreNotEmpty ()
| ^^^^^^^^^^^^^^^^^^^^^^^^
```
And indeed, the fact that \[\] can't be matched against (_ : _) is in some sense the point. More generally, whenever I'm fooling around with this sort of Haskell code (in which classes are being used to provide runtime witnesses of type-level structure), I relatively regularly find myself in a branch of code where the context is obviously inconsistent, wishing that I had some way to say "search your heart, GHC; you know this case to be impossible". The fact that I can't even factor out this dead code into a function like nonEmptyListsAreNonEmpty just seems like insult added to injury.
This is a minor concern, to be sure. Nevertheless, it seems to me that we should be able to write this function somehow, especially given that there are various ways to trick GHC into accepting something analogous (by clever use of GADTs such as :\~:, perhaps).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.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":"Allow definition of functions with absurd contexts","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Consider the following code:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE AllowAmbiguousTypes #-}\r\n{-# LANGUAGE DataKinds #-}\r\n{-# LANGUAGE FlexibleContexts #-}\r\n{-# LANGUAGE RankNTypes #-}\r\n{-# LANGUAGE ScopedTypeVariables #-}\r\n{-# LANGUAGE TypeApplications #-}\r\n{-# LANGUAGE TypeFamilies #-}\r\n{-# LANGUAGE TypeOperators #-}\r\ntype family Head xxs where\r\n Head (x ': xs) = x\r\n\r\ntype family Tail xxs where\r\n Tail (x ': xs) = xs\r\n\r\nclass IsList xs where\r\n isList :: (xs ~ '[] => r) -> ((xs ~ (Head xs ': Tail xs), IsList (Tail xs)) => r) -> r\r\n\r\ninstance IsList '[] where isList r _ = r\r\ninstance IsList xs => IsList (x ': xs) where isList _ r = r\r\n\r\nnonEmptyListsAreNotEmpty :: (xs ~ '[], xs ~ (Head xs ': Tail xs)) => r\r\nnonEmptyListsAreNotEmpty = error \"you convinced GHC that '[] ~ (_ ': _)!\"\r\n\r\nsillyExample :: forall x xs. IsList (x ': xs) => ()\r\nsillyExample = isList @(x ': xs) nonEmptyListsAreNotEmpty ()\r\n}}}\r\n\r\nIn this code, we define a class IsList which serves as a proof that something is a type-level list, via the function isList. When using this, we may occasionally get into a situation where the types guarantee that we're working with a non-empty list, but we're asked to handle the empty-list case anyway. Suppose we want to define a nice little \"absurd\" function that serves as a reminder to readers that this code branch is impossible, in a way that GHC can verify. This function is named \"nonEmptyListsAreNonEmpty\" above.\r\n\r\nUnfortunately, this code fails with\r\n\r\n{{{\r\nMain.hs:25:34: error:\r\n • Couldn't match type ‘'[]’ with ‘Head '[] : Tail '[]’\r\n arising from a use of ‘nonEmptyListsAreNotEmpty’\r\n • In the second argument of ‘isList’, namely\r\n ‘nonEmptyListsAreNotEmpty’\r\n In the expression: isList @(x : xs) nonEmptyListsAreNotEmpty ()\r\n In an equation for ‘sillyExample’:\r\n sillyExample = isList @(x : xs) nonEmptyListsAreNotEmpty ()\r\n |\r\n25 | sillyExample = isList @(x ': xs) nonEmptyListsAreNotEmpty ()\r\n | ^^^^^^^^^^^^^^^^^^^^^^^^\r\n}}}\r\n\r\nAnd indeed, the fact that [] can't be matched against (_ : _) is in some sense the point. More generally, whenever I'm fooling around with this sort of Haskell code (in which classes are being used to provide runtime witnesses of type-level structure), I relatively regularly find myself in a branch of code where the context is obviously inconsistent, wishing that I had some way to say \"search your heart, GHC; you know this case to be impossible\". The fact that I can't even factor out this dead code into a function like nonEmptyListsAreNonEmpty just seems like insult added to injury.\r\n\r\nThis is a minor concern, to be sure. Nevertheless, it seems to me that we should be able to write this function somehow, especially given that there are various ways to trick GHC into accepting something analogous (by clever use of GADTs such as :~:, perhaps).","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16262Hadrian: respect dynamicGhcPrograms2019-07-07T18:00:46ZdavideHadrian: respect dynamicGhcProgramsWhile `dynamicGhcPrograms` exists in Hadrian, it is not used to the extent that it's make counter part is used (`DYNAMIC_GHC_PROGRAMS`). All relevant logic from make should be implemented in Hadrian as well. A simple search for `DYNAMIC_...While `dynamicGhcPrograms` exists in Hadrian, it is not used to the extent that it's make counter part is used (`DYNAMIC_GHC_PROGRAMS`). All relevant logic from make should be implemented in Hadrian as well. A simple search for `DYNAMIC_GHC_PROGRAMS` is a good place to start.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------------- |
| Version | 8.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Build System (Hadrian) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Hadrian: respect dynamicGhcPrograms","status":"New","operating_system":"","component":"Build System (Hadrian)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":["dynamic","ghc","hadrian","programs"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"While `dynamicGhcPrograms` exists in Hadrian, it is not used to the extent that it's make counter part is used (`DYNAMIC_GHC_PROGRAMS`). All relevant logic from make should be implemented in Hadrian as well. A simple search for `DYNAMIC_GHC_PROGRAMS` is a good place to start.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16257-fexternal-interpreter with external C shared library leads to undefined symb...2019-07-07T18:00:47ZGuillaume Bouchard-fexternal-interpreter with external C shared library leads to undefined symbol during template haskell phaseI'm building the following `Foo.hs` program using the `hmatrix-gsl` library:
```haskell
{-# LANGUAGE TemplateHaskell #-}
import Numeric.GSL.Integration
main = do
print $([| 10 |])
print $ integrateQNG 1 (\x -> x) 0 1
```
I observ...I'm building the following `Foo.hs` program using the `hmatrix-gsl` library:
```haskell
{-# LANGUAGE TemplateHaskell #-}
import Numeric.GSL.Integration
main = do
print $([| 10 |])
print $ integrateQNG 1 (\x -> x) 0 1
```
I observes undefined symbols during the template haskell phase when using `-fexternal-interpreter`:
Without `-fexternal-interpreter`:
```
$ ghc -package hmatrix-gsl Foo.hs
[1 of 1] Compiling Main ( Foo.hs, Foo.o )
Linking Foo ...
[nix-shell:~/bug_report_external]$ ./Foo
10
(0.5,5.551115123125783e-15)
```
But with `-fexternal-interpreter`:
```
$ ghc -fexternal-interpreter -package hmatrix-gsl Foo.hs
[1 of 1] Compiling Main ( Foo.hs, Foo.o )
<command line>: can't load .so/.DLL for: /nix/store/6dhcmmfgy5fa0p3d235yaz4qfx8jhpar-gsl-2.5/lib/libgsl.so (/nix/store/6dhcmmfgy5fa0p3d235yaz4qfx8jhpar-gsl-2.5/lib/libgsl.so: undefined symbol: cblas_ctrmv)
```
I suspect that it happen during the template haskell phase because I cannot observe this issue without template haskell.
I can observe this issue with a few other libraries, I used `hmatrix-gsl` in this example because it is on hackage. Actually, you can even reduce the file to:
```haskell
{-# LANGUAGE TemplateHaskell #-}
main = do
print $([| 10 |])
```
and get the same error as long as you have `-package hmatrix-gsl` in your command line.
I generate the build environment with this nix file:
```nix
with import (fetchTarball {
# 25/01/2019
url = https://github.com/nixos/nixpkgs/archive/11cf7d6e1ff.tar.gz;
sha256 = "0zcg4mgfdk3ryiqj1j5iv5bljjvsgi6q6j9z1vkq383c4g4clc72";
}) {};
mkShell {
buildInputs = [(haskellPackages.ghcWithPackages(p: [p.hmatrix-gsl]))];
}
```
It setups `ghc-8.6.3` with `hmatrix-gsl-0.19.0.1` (the latest on hackage).
Note that `hmatrix-gsl` depends on library `gsl` which have a weird symbol setup. The main library file `libgsl` does not contain the `cbal_ctrmv` symbol which is contained in another library `libgslcbal` which is not a dependency of the shared object `libgsl.so`.
library `gslcblas` is listed in `extra-libraries` of the `hmatrix-gsl` package:
```
ghc-pkg field hmatrix-gsl extra-libraries
extra-libraries:
gsl gslcblas m
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"-fexternal-interpreter with external C shared library leads to undefined symbol during template haskell phase","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I'm building the following `Foo.hs` program using the `hmatrix-gsl` library:\r\n\r\n{{{#!haskell\r\n{-# LANGUAGE TemplateHaskell #-}\r\n\r\nimport Numeric.GSL.Integration\r\n\r\nmain = do\r\n print $([| 10 |])\r\n print $ integrateQNG 1 (\\x -> x) 0 1\r\n}}}\r\n\r\nI observes undefined symbols during the template haskell phase when using `-fexternal-interpreter`:\r\n\r\nWithout `-fexternal-interpreter`:\r\n\r\n{{{\r\n$ ghc -package hmatrix-gsl Foo.hs\r\n[1 of 1] Compiling Main ( Foo.hs, Foo.o )\r\nLinking Foo ...\r\n\r\n[nix-shell:~/bug_report_external]$ ./Foo \r\n10\r\n(0.5,5.551115123125783e-15)\r\n}}}\r\n\r\nBut with `-fexternal-interpreter`:\r\n\r\n{{{\r\n$ ghc -fexternal-interpreter -package hmatrix-gsl Foo.hs\r\n[1 of 1] Compiling Main ( Foo.hs, Foo.o )\r\n<command line>: can't load .so/.DLL for: /nix/store/6dhcmmfgy5fa0p3d235yaz4qfx8jhpar-gsl-2.5/lib/libgsl.so (/nix/store/6dhcmmfgy5fa0p3d235yaz4qfx8jhpar-gsl-2.5/lib/libgsl.so: undefined symbol: cblas_ctrmv)\r\n}}}\r\n\r\nI suspect that it happen during the template haskell phase because I cannot observe this issue without template haskell.\r\n\r\nI can observe this issue with a few other libraries, I used `hmatrix-gsl` in this example because it is on hackage. Actually, you can even reduce the file to:\r\n\r\n{{{#!haskell\r\n{-# LANGUAGE TemplateHaskell #-}\r\n\r\nmain = do\r\n print $([| 10 |])\r\n}}}\r\n\r\nand get the same error as long as you have `-package hmatrix-gsl` in your command line.\r\n\r\nI generate the build environment with this nix file:\r\n\r\n{{{#!nix\r\nwith import (fetchTarball {\r\n # 25/01/2019\r\n url = https://github.com/nixos/nixpkgs/archive/11cf7d6e1ff.tar.gz;\r\n sha256 = \"0zcg4mgfdk3ryiqj1j5iv5bljjvsgi6q6j9z1vkq383c4g4clc72\";\r\n }) {};\r\nmkShell {\r\n buildInputs = [(haskellPackages.ghcWithPackages(p: [p.hmatrix-gsl]))];\r\n}\r\n}}}\r\n\r\nIt setups `ghc-8.6.3` with `hmatrix-gsl-0.19.0.1` (the latest on hackage).\r\n\r\nNote that `hmatrix-gsl` depends on library `gsl` which have a weird symbol setup. The main library file `libgsl` does not contain the `cbal_ctrmv` symbol which is contained in another library `libgslcbal` which is not a dependency of the shared object `libgsl.so`.\r\n\r\nlibrary `gslcblas` is listed in `extra-libraries` of the `hmatrix-gsl` package:\r\n\r\n{{{\r\nghc-pkg field hmatrix-gsl extra-libraries\r\nextra-libraries:\r\n gsl gslcblas m\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->