GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2021-03-02T16:58:07Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/14533Make GHC more robust against PC crashes by using atomic writes2021-03-02T16:58:07ZNiklas Hambüchenmail@nh2.meMake GHC more robust against PC crashes by using atomic writesYesterday my Windows machine crashed when ghc was building, left me with a lot of corrupted .hi files (and probably .o files as well).
That made me think if we should change ghc to write its output with atomic moves.
Discussion on `#gh...Yesterday my Windows machine crashed when ghc was building, left me with a lot of corrupted .hi files (and probably .o files as well).
That made me think if we should change ghc to write its output with atomic moves.
Discussion on `#ghc`:
```
bgamari:
nh2: well, perhaps
I'm not sure it's terribly common for compilers to take such precautions though
and if we were to do it for interface files then presumably we would also want to do it for object files
siarheit_:
that would be very nice
geekosaur:
compilers in general are happy to write out incomplete/garbage object files
bgamari:
it seems that way
nh2:
bgamari: right, if we wanted to do it we should do it for all files ghc writes.
Possible that other compilers can also write garbage, but maybe ghc can do better -- one less thing the developer has to think about
Phyx-:
most compilers also don't do the aggressive recompilation avoidance things we do either..
corrupt hi files wouldn't be an issue if the next time it would override them :)
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | nh2 |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Make GHC more robust against PC crashes by using atomic writes","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["nh2"],"type":"Bug","description":"Yesterday my Windows machine crashed when ghc was building, left me with a lot of corrupted .hi files (and probably .o files as well).\r\n\r\nThat made me think if we should change ghc to write its output with atomic moves.\r\n\r\nDiscussion on `#ghc`:\r\n\r\n{{{\r\nbgamari:\r\nnh2: well, perhaps\r\nI'm not sure it's terribly common for compilers to take such precautions though\r\nand if we were to do it for interface files then presumably we would also want to do it for object files\r\n\r\nsiarheit_:\r\nthat would be very nice\r\n\r\ngeekosaur:\r\ncompilers in general are happy to write out incomplete/garbage object files\r\n\r\nbgamari:\r\nit seems that way\r\n\r\nnh2:\r\nbgamari: right, if we wanted to do it we should do it for all files ghc writes.\r\nPossible that other compilers can also write garbage, but maybe ghc can do better -- one less thing the developer has to think about\r\n\r\nPhyx-:\r\nmost compilers also don't do the aggressive recompilation avoidance things we do either..\r\ncorrupt hi files wouldn't be an issue if the next time it would override them :)\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14527Warn on recursive bindings2020-05-23T17:01:16ZChris DoneWarn on recursive bindingsWhen you accidentally write something like `let x = .. x ...` it can take hours to realize where you made your mistake. This hits me once in a while, and my colleagues often.
I'd propose e.g. `-Wrecursive-bindings` that says:
```
warni...When you accidentally write something like `let x = .. x ...` it can take hours to realize where you made your mistake. This hits me once in a while, and my colleagues often.
I'd propose e.g. `-Wrecursive-bindings` that says:
```
warning: [-Wrecursive-bindings]
Recursive binding for `x` in
let x = length x
```
This applies to `let`, `where` and top-level pattern bindings.
I believe that in practice, I only actually use real recursive bindings once in a while. So I might be bold enough to encourage enabling it in `-Wall` for a future major GHC release.
With the compromise that if you have the warning enabled but in one specific place, you want a recursive binding, you can use the `~` tilde to say "I really mean it", e.g.
`let ~ones = 1 : ones`
That seems like a nice balance to say "I know what I'm doing in this case". So the warning could be more helpful, like:
```
warning: [-Wrecursive-bindings]
Recursive binding for `ones` in
let ones = length ones
If intentional, use the tilde marker on the name like this:
let ~ones = length ones
```
In Intero if I were to implement a prototype of this check, I'd probably do this, after renaming:
1. Use SYB to collect all variable bindings from the pattern.
1. Use SYB to listify all mentions of any of these variables in the RHS and any guards or where clauses.
If the list is non-empty, then trigger the error. A transformation function `[Name] -> Pat -> Pat` would provide the AST with the offending name(s) tilded as `~x` for use in the error message.
If there's general agreement, I could implement this change.
- \*EDIT\*\*: mutually recursive bindings apply here too. So `let x = y; y = x` by a regular occurs check.https://gitlab.haskell.org/ghc/ghc/-/issues/14523Confusing link error when specifying the same object repeatedly2020-06-16T07:51:49ZNeil MitchellConfusing link error when specifying the same object repeatedlyGiven `foo.hs` containing `main = print 1` and `foo.c` containing `void foo(){} `, if you run:
```
$ ghc foo.o foo.hs
C:\Neil\temp\dupe-name>ghc foo.hs foo.o
[1 of 1] Compiling Main ( foo.hs, foo.o )
Linking foo.exe ...
foo....Given `foo.hs` containing `main = print 1` and `foo.c` containing `void foo(){} `, if you run:
```
$ ghc foo.o foo.hs
C:\Neil\temp\dupe-name>ghc foo.hs foo.o
[1 of 1] Compiling Main ( foo.hs, foo.o )
Linking foo.exe ...
foo.o:fake:(.data+0x0): multiple definition of `__stginit_Main'
foo.o:fake:(.data+0x0): first defined here
foo.o:fake:(.data+0x10): multiple definition of `Main_main_closure'
foo.o:fake:(.data+0x10): first defined here
foo.o:fake:(.text+0x18): multiple definition of `Main_main_info'
foo.o:fake:(.text+0x18): first defined here
foo.o:fake:(.data+0x30): multiple definition of `ZCMain_main_closure'
foo.o:fake:(.data+0x30): first defined here
foo.o:fake:(.text+0x88): multiple definition of `ZCMain_main_info'
foo.o:fake:(.text+0x88): first defined here
foo.o:fake:(.data+0x70): multiple definition of `Main_zdtrModule_closure'
foo.o:fake:(.data+0x70): first defined here
collect2.exe: error: ld returned 1 exit status
`gcc.exe' failed in phase `Linker'. (Exit code: 1)
```
It seems GHC compiles both `foo.hs` and `foo.c` to `foo.o`, and then links `foo.o` twice. Sometimes `foo.hs` writes last, sometimes `foo.c` so the error can change. I found the error quite confusing, until I realised what it was doing.
One solution might be before linking `.o` files GHC does `canonicalizePath` on all the object files, and if any are duplicates, it raises a cleaner error. That check would also catch `ghc foo.hs bar.o bar.o` as well.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.1 |
| 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":"Confusing link error when specifying the same object repeatedly","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Given {{{foo.hs}}} containing {{{main = print 1}}} and {{{foo.c}}} containing {{{void foo(){} }}}, if you run:\r\n\r\n{{{\r\n$ ghc foo.o foo.hs\r\nC:\\Neil\\temp\\dupe-name>ghc foo.hs foo.o\r\n[1 of 1] Compiling Main ( foo.hs, foo.o )\r\nLinking foo.exe ...\r\nfoo.o:fake:(.data+0x0): multiple definition of `__stginit_Main'\r\nfoo.o:fake:(.data+0x0): first defined here\r\nfoo.o:fake:(.data+0x10): multiple definition of `Main_main_closure'\r\nfoo.o:fake:(.data+0x10): first defined here\r\nfoo.o:fake:(.text+0x18): multiple definition of `Main_main_info'\r\nfoo.o:fake:(.text+0x18): first defined here\r\nfoo.o:fake:(.data+0x30): multiple definition of `ZCMain_main_closure'\r\nfoo.o:fake:(.data+0x30): first defined here\r\nfoo.o:fake:(.text+0x88): multiple definition of `ZCMain_main_info'\r\nfoo.o:fake:(.text+0x88): first defined here\r\nfoo.o:fake:(.data+0x70): multiple definition of `Main_zdtrModule_closure'\r\nfoo.o:fake:(.data+0x70): first defined here\r\ncollect2.exe: error: ld returned 1 exit status\r\n`gcc.exe' failed in phase `Linker'. (Exit code: 1)\r\n}}}\r\n\r\nIt seems GHC compiles both {{{foo.hs}}} and {{{foo.c}}} to {{{foo.o}}}, and then links {{{foo.o}}} twice. Sometimes {{{foo.hs}}} writes last, sometimes {{{foo.c}}} so the error can change. I found the error quite confusing, until I realised what it was doing.\r\n\r\nOne solution might be before linking {{{.o}}} files GHC does {{{canonicalizePath}}} on all the object files, and if any are duplicates, it raises a cleaner error. That check would also catch {{{ghc foo.hs bar.o bar.o}}} as well.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14522GHC recompilation checker doesn't take account of deprecated pragmas2019-07-07T18:16:40ZNeil MitchellGHC recompilation checker doesn't take account of deprecated pragmasGiven the sources:
```hs
-- A.hs --------------------
module A
-- {-# DEPRECATED "bad" #-}
where
a = 1
```
```hs
-- B.hs --------------------
module B where
import A
```
I get the interactions:
```
$ ghc B
[1 of 2] Compiling A ...Given the sources:
```hs
-- A.hs --------------------
module A
-- {-# DEPRECATED "bad" #-}
where
a = 1
```
```hs
-- B.hs --------------------
module B where
import A
```
I get the interactions:
```
$ ghc B
[1 of 2] Compiling A ( A.hs, A.o )
[2 of 2] Compiling B ( B.hs, B.o )
$ manually edit A.hs to uncomment the deprecated line
$ ghc B
[1 of 2] Compiling A ( A.hs, A.o )
$ touch B.hs
$ ghc B
[2 of 2] Compiling B ( B.hs, B.o )
B.hs:2:1: warning: [-Wdeprecations] Module `A' is deprecated: bad
|
2 | import A
| ^^^^^^^^
```
Observe that after editing the deprecated pragma in `A.hs` GHC didn't recompile `B.hs`, meaning that the warning only appeared after I touch'd `B.hs`. Turning on `-Werror` turns the problem from one of incorrectly missing warnings to one of incorrect compilation results.
I was also got the same results when adding a deprecated pragma to an individual function.
My guess is whatever `.hi` hash you take for recompilation checking should include deprecated pragmas.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------------- |
| Version | 8.2.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | ndmitchell@gmail.com |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC recompilation checker doesn't take account of deprecated pragmas","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["ndmitchell@gmail.com"],"type":"Bug","description":"Given the sources:\r\n\r\n{{{#!hs\r\n-- A.hs --------------------\r\nmodule A\r\n-- {-# DEPRECATED \"bad\" #-}\r\n where\r\na = 1\r\n}}}\r\n\r\n{{{#!hs\r\n-- B.hs --------------------\r\nmodule B where\r\nimport A\r\n}}}\r\n\r\nI get the interactions:\r\n\r\n{{{\r\n$ ghc B\r\n[1 of 2] Compiling A ( A.hs, A.o )\r\n[2 of 2] Compiling B ( B.hs, B.o )\r\n\r\n$ manually edit A.hs to uncomment the deprecated line\r\n\r\n$ ghc B\r\n[1 of 2] Compiling A ( A.hs, A.o )\r\n\r\n$ touch B.hs\r\n\r\n$ ghc B\r\n[2 of 2] Compiling B ( B.hs, B.o )\r\n\r\nB.hs:2:1: warning: [-Wdeprecations] Module `A' is deprecated: bad\r\n |\r\n2 | import A\r\n | ^^^^^^^^\r\n}}}\r\n\r\nObserve that after editing the deprecated pragma in {{{A.hs}}} GHC didn't recompile {{{B.hs}}}, meaning that the warning only appeared after I touch'd {{{B.hs}}}. Turning on {{{-Werror}}} turns the problem from one of incorrectly missing warnings to one of incorrect compilation results.\r\n\r\nI was also got the same results when adding a deprecated pragma to an individual function.\r\n\r\nMy guess is whatever {{{.hi}}} hash you take for recompilation checking should include deprecated pragmas.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14514Error messages: suggest annotating with higher-rank kind2019-07-07T18:16:43ZIcelandjackError messages: suggest annotating with higher-rank kindThe ticket below was posted because of confusion around higher-rank kinds. [ticket:14514\#comment:145571](https://gitlab.haskell.org//ghc/ghc/issues/14514#note_145571) suggests an error-message improvement, which I (goldfire) think is fe...The ticket below was posted because of confusion around higher-rank kinds. [ticket:14514\#comment:145571](https://gitlab.haskell.org//ghc/ghc/issues/14514#note_145571) suggests an error-message improvement, which I (goldfire) think is feasible.
------------------------------------
Following code from [Richard's 2016 Haskell Implementors' Workshop talk](https://github.com/goldfirere/triptych/blob/2e21a6be4419873c77a02c9a198379c76947b94c/extensibility/Extensible6.hs) (/ [Trees That Grow](https://arxiv.org/abs/1610.04799)) works just fine
```hs
{-# Language RankNTypes, KindSignatures, DataKinds, TypeFamilyDependencies, TypeInType #-}
import Data.Kind
data TagTag = ETagTag | PTagTag
data ETag = VarTag
data PTag = VarPTag
type family
Tag (ttag::TagTag) = (res :: Type) | res -> ttag where
Tag ETagTag = ETag
Tag PTagTag = PTag
type WithAnyTag = forall tag. Tag tag -> Type
-- data Exp (ext::WithAnyTag) where
-- Var :: ext VarTag -> Exp ext
data Exp (ext::WithAnyTag) = Var (ext VarTag)
```
but replace `data Exp` with its commented-out GADT brethren and it stops working
```
$ ghci -ignore-dot-ghci Weird.hs
GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( Weird.hs, interpreted )
Weird.hs:17:28: error:
• Expected kind ‘WithAnyTag’, but ‘ext1’ has kind ‘ETag -> *’
• In the first argument of ‘Exp’, namely ‘ext’
In the type ‘Exp ext’
In the definition of data constructor ‘Var’
|
17 | Var :: ext VarTag -> Exp ext
| ^^^
Failed, 0 modules loaded.
Prelude>
```
The type synonym can be inlined, makes no difference.https://gitlab.haskell.org/ghc/ghc/-/issues/14512System-wide installed profile build cannot load libHSghc-prim.0.5.2.0.so2020-01-23T19:27:39ZTobias Dammerstdammers@gmail.comSystem-wide installed profile build cannot load libHSghc-prim.0.5.2.0.soSteps to reproduce:
1. Make a pristine git checkout
1. Follow the steps outlined in https://ghc.haskell.org/trac/ghc/wiki/Building/QuickStart, uncommenting the `BuildFlavour = prof` line in `build.mk`, to build and install ghc.
1. Check...Steps to reproduce:
1. Make a pristine git checkout
1. Follow the steps outlined in https://ghc.haskell.org/trac/ghc/wiki/Building/QuickStart, uncommenting the `BuildFlavour = prof` line in `build.mk`, to build and install ghc.
1. Check ghc version to verify that this ghc build is the one in `/usr/local/bin`
1. Try to compile the following `hello.hs`:
```hs
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
main = putStrLn $(litE (stringL "Hello"))
```
It should fail with an error message similar to:
```
<no location info>: error:
ghc: panic! (the 'impossible' happened)
(GHC version 8.3.20171120 for x86_64-unknown-linux):
Dynamic linker not initialised
CallStack (from -prof):
Linker.CAF (<entire-module>)
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
and:
```
<no location info>: error:
<command line>: can't load .so/.DLL for: libHSghc-prim-0.5.2.0.so (libHSghc-prim-0.5.2.0.so: cannot open shared object file: No such file or directory)
```
By contrast, the following do \*not\* trigger the error:
- Building GHC without uncommenting the `BuildFlavour` line in `build.mk`
- Compiling with the `inplace/bin/ghc-stage2` in the GHC source tree
- Compiling a `hello.hs` that does not use TemplateHaskell
Further system info:
- Debian 9
- Cabal version 1.24
- GHC 8.0.1
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 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":"System-wide installed profile build cannot load libHSghc-prim.0.5.2.0.so","status":"New","operating_system":"","component":"Build System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Steps to reproduce:\r\n\r\n1. Make a pristine git checkout\r\n2. Follow the steps outlined in https://ghc.haskell.org/trac/ghc/wiki/Building/QuickStart, uncommenting the `BuildFlavour = prof` line in `build.mk`, to build and install ghc.\r\n3. Check ghc version to verify that this ghc build is the one in `/usr/local/bin`\r\n4. Try to compile the following `hello.hs`:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE TemplateHaskell #-}\r\n\r\nimport Language.Haskell.TH\r\n\r\nmain = putStrLn $(litE (stringL \"Hello\"))\r\n}}}\r\n\r\nIt should fail with an error message similar to:\r\n\r\n{{{\r\n<no location info>: error:\r\n ghc: panic! (the 'impossible' happened)\r\n (GHC version 8.3.20171120 for x86_64-unknown-linux):\r\n\tDynamic linker not initialised\r\nCallStack (from -prof):\r\n Linker.CAF (<entire-module>)\r\n\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n}}}\r\n\r\nand:\r\n\r\n{{{\r\n<no location info>: error:\r\n <command line>: can't load .so/.DLL for: libHSghc-prim-0.5.2.0.so (libHSghc-prim-0.5.2.0.so: cannot open shared object file: No such file or directory)\r\n}}}\r\n\r\nBy contrast, the following do *not* trigger the error:\r\n\r\n- Building GHC without uncommenting the `BuildFlavour` line in `build.mk`\r\n- Compiling with the `inplace/bin/ghc-stage2` in the GHC source tree\r\n- Compiling a `hello.hs` that does not use TemplateHaskell\r\n\r\nFurther system info:\r\n\r\n- Debian 9\r\n- Cabal version 1.24\r\n- GHC 8.0.1\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14510GHC.ExecutionStack.showStackTrace broken2021-07-13T17:53:21ZDouglas Wilsondouglas@well-typed.comGHC.ExecutionStack.showStackTrace brokenWhen compiled with the dwarf bindist of 8.2.2 with
```
ghc --make -g testdwarf.hs
```
The following is output:
```
testdwarf: Failed to get stack frames of current process: no matching address range: Success
```
<details><summary>Tr...When compiled with the dwarf bindist of 8.2.2 with
```
ghc --make -g testdwarf.hs
```
The following is output:
```
testdwarf: Failed to get stack frames of current process: no matching address range: Success
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------- |
| Version | 8.2.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown/Multiple |
| Architecture | Unknown/Multiple |
</details>
<!-- {"blocked_by":[],"summary":"GHC.ExecutionStack.showStackTrace broken","status":"New","operating_system":"Unknown/Multiple","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.2","keywords":[],"differentials":[],"test_case":"","architecture":"Unknown/Multiple","cc":[""],"type":"Bug","description":"When compiled with the dwarf bindist of 8.2.2 with\r\n{{{\r\nghc --make -g testdwarf.hs \r\n}}}\r\nThe following is output:\r\n{{{\r\ntestdwarf: Failed to get stack frames of current process: no matching address range: Success\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14509Consider adding new stg_ap_* functions2020-01-23T19:27:39ZdobenourConsider adding new stg_ap_* functionsCurrently, the RTS has a fixed set of `stg_ap_*` functions. There are two problems with this:
1. All programs pay for these functions, even programs that don’t use them. Furthermore, it is not possible for new ones to be generated by GH...Currently, the RTS has a fixed set of `stg_ap_*` functions. There are two problems with this:
1. All programs pay for these functions, even programs that don’t use them. Furthermore, it is not possible for new ones to be generated by GHC for certain cases.
1. The set included in the RTS may not be optimal.
(1) is a lot of work, but dealing with (2) should be “just” a matter of hunting down which functions would be useful. I would start with ByteString, Text, and other highly optimized libraries, some of which (such as ByteString) are very widely used.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.2.1 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Consider adding new stg_ap_* functions","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Currently, the RTS has a fixed set of `stg_ap_*` functions. There are two problems with this:\r\n\r\n1. All programs pay for these functions, even programs that don’t use them. Furthermore, it is not possible for new ones to be generated by GHC for certain cases.\r\n2. The set included in the RTS may not be optimal.\r\n\r\n(1) is a lot of work, but dealing with (2) should be “just” a matter of hunting down which functions would be useful. I would start with ByteString, Text, and other highly optimized libraries, some of which (such as ByteString) are very widely used.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14503Killing a thread will block if there is another process reading from a handle2019-07-07T18:16:46ZdnadalesKilling a thread will block if there is another process reading from a handleWhen trying to kill a thread, the program (which uses a thread) hangs if there is another process trying to read from a handle. This bug can be reproduced with using [this sample code](https://github.com/capitanbatata/sandbox/tree/master...When trying to kill a thread, the program (which uses a thread) hangs if there is another process trying to read from a handle. This bug can be reproduced with using [this sample code](https://github.com/capitanbatata/sandbox/tree/master/dangling-connections). I'll explain the relevant details below.
I have the following Haskell code:
```hs
someFuncWithChans :: IO ()
someFuncWithChans = withSocketsDo $ do
h <- connectTo "localhost" (PortNumber 9090)
hSetBuffering h NoBuffering
ch <- newChan
putStrLn "Starting the handler reader"
readerTid <- forkIO $ handleReader h ch
cmdsHandler h ch
putStrLn "Killing the handler reader"
killThread readerTid
putStrLn "Closing the handle"
hClose h
cmdsHandler :: Handle -> Chan Action -> IO ()
cmdsHandler h ch = do
act <- readChan ch
case act of
Quit -> putStrLn "Bye bye"
Line line -> do
hPutStrLn h (reverse line)
cmdsHandler h ch
handleReader :: Handle -> Chan Action -> IO ()
handleReader h ch = forever $ do
line <- strip <$> hGetLine h
case line of
"quit" -> writeChan ch Quit
_ -> writeChan ch (Line line)
data Action = Quit | Line String
```
Is the function `someFuncWithChans` is run along with the following Java program, then the former will block while killing the handler reader (`readerTid`).
```java
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket serverSock = new ServerSocket(9090);
Socket sock = serverSock.accept();
InputStream inStream = sock.getInputStream();
BufferedReader sockIn = new BufferedReader(new InputStreamReader(inStream));
OutputStream outStream = sock.getOutputStream();
PrintWriter sockOut = new PrintWriter(new OutputStreamWriter(outStream));
while (true) {
Thread.sleep(1000);
System.out.println("Sending foo");
sockOut.println("foo");
sockOut.flush();
String s = sockIn.readLine();
System.out.println("Got " + s );
Thread.sleep(1000);
System.out.println("Sending bar");
sockOut.println("bar");
sockOut.flush();
s = sockIn.readLine();
System.out.println("Got " + s );
Thread.sleep(1000);
System.out.println("Sending quit");
sockOut.println("quit");
sockOut.flush();
// This will cause someFuncWithChans to block when killing the
// reader thread.
s = sockIn.readLine();
System.out.println("Got " + s );
}
}
```
If the `sockIn.readLine()` is commented out, then killing the thread will succeed. This problem appears only on my Windows machine (at work), whereas it does not on my personal Linux machine.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.0.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":"Killing a thread will block if there is another process reading from a handle","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When trying to kill a thread, the program (which uses a thread) hangs if there is another process trying to read from a handle. This bug can be reproduced with using [https://github.com/capitanbatata/sandbox/tree/master/dangling-connections this sample code]. I'll explain the relevant details below.\r\n\r\nI have the following Haskell code:\r\n\r\n{{{#!hs\r\nsomeFuncWithChans :: IO ()\r\nsomeFuncWithChans = withSocketsDo $ do\r\n h <- connectTo \"localhost\" (PortNumber 9090)\r\n hSetBuffering h NoBuffering\r\n ch <- newChan\r\n putStrLn \"Starting the handler reader\"\r\n readerTid <- forkIO $ handleReader h ch\r\n cmdsHandler h ch\r\n putStrLn \"Killing the handler reader\"\r\n killThread readerTid\r\n putStrLn \"Closing the handle\"\r\n hClose h\r\n\r\ncmdsHandler :: Handle -> Chan Action -> IO ()\r\ncmdsHandler h ch = do\r\n act <- readChan ch\r\n case act of\r\n Quit -> putStrLn \"Bye bye\"\r\n Line line -> do\r\n hPutStrLn h (reverse line)\r\n cmdsHandler h ch\r\n\r\nhandleReader :: Handle -> Chan Action -> IO ()\r\nhandleReader h ch = forever $ do\r\n line <- strip <$> hGetLine h\r\n case line of\r\n \"quit\" -> writeChan ch Quit\r\n _ -> writeChan ch (Line line)\r\n\r\ndata Action = Quit | Line String\r\n\r\n}}}\r\n\r\nIs the function `someFuncWithChans` is run along with the following Java program, then the former will block while killing the handler reader (`readerTid`).\r\n\r\n{{{#!java\r\n public static void main(String[] args) throws IOException, InterruptedException {\r\n\r\n ServerSocket serverSock = new ServerSocket(9090);\r\n\r\n Socket sock = serverSock.accept();\r\n\r\n InputStream inStream = sock.getInputStream();\r\n BufferedReader sockIn = new BufferedReader(new InputStreamReader(inStream));\r\n\r\n OutputStream outStream = sock.getOutputStream();\r\n PrintWriter sockOut = new PrintWriter(new OutputStreamWriter(outStream));\r\n\r\n\r\n\r\n while (true) {\r\n Thread.sleep(1000);\r\n System.out.println(\"Sending foo\");\r\n sockOut.println(\"foo\");\r\n sockOut.flush();\r\n String s = sockIn.readLine();\r\n System.out.println(\"Got \" + s );\r\n Thread.sleep(1000);\r\n System.out.println(\"Sending bar\");\r\n sockOut.println(\"bar\");\r\n sockOut.flush();\r\n s = sockIn.readLine();\r\n System.out.println(\"Got \" + s );\r\n Thread.sleep(1000);\r\n System.out.println(\"Sending quit\");\r\n sockOut.println(\"quit\");\r\n sockOut.flush();\r\n // This will cause someFuncWithChans to block when killing the\r\n // reader thread.\r\n s = sockIn.readLine();\r\n System.out.println(\"Got \" + s );\r\n }\r\n }\r\n}}}\r\n\r\nIf the `sockIn.readLine()` is commented out, then killing the thread will succeed. This problem appears only on my Windows machine (at work), whereas it does not on my personal Linux machine.","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1https://gitlab.haskell.org/ghc/ghc/-/issues/14502Build Alpine Linux binary distributions2020-01-23T19:27:39ZBen GamariBuild Alpine Linux binary distributionsAt least three people have come to me asking for Alpine Linux bindists. Given that Alpine is a fair bit different from most other distributions and can be useful in containers, this seems fairly reasonable to me.
Terrorjack has some use...At least three people have come to me asking for Alpine Linux bindists. Given that Alpine is a fair bit different from most other distributions and can be useful in containers, this seems fairly reasonable to me.
Terrorjack has some useful-looking automation at https://github.com/TerrorJack/meikyu.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------------- |
| Version | 8.2.1 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Continuous Integration |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | terrorjack, tuncer |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Build Alpine Linux binary distributions","status":"New","operating_system":"","component":"Continuous Integration","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"bgamari"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["terrorjack","tuncer"],"type":"Task","description":"At least three people have come to me asking for Alpine Linux bindists. Given that Alpine is a fair bit different from most other distributions and can be useful in containers, this seems fairly reasonable to me.\r\n\r\nTerrorjack has some useful-looking automation at https://github.com/TerrorJack/meikyu.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14482GHC -M mode fails to ensure that boot files are built before source files2022-02-24T14:59:33ZBen GamariGHC -M mode fails to ensure that boot files are built before source filesImagine we have a module with a boot file. In general it is necessary to ensure that we compile the boot file \*before\* the source file to ensure that the `hi-boot` file exists when we go to typecheck the module (triggering the behavior...Imagine we have a module with a boot file. In general it is necessary to ensure that we compile the boot file \*before\* the source file to ensure that the `hi-boot` file exists when we go to typecheck the module (triggering the behavior observed in #14481). However, `ghc -M` doesn't guarantee this.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.1 |
| 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 -M mode fails to ensure that boot files are built before source files","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Imagine we have a module with a boot file. In general it is necessary to ensure that we compile the boot file *before* the source file to ensure that the `hi-boot` file exists when we go to typecheck the module (triggering the behavior observed in #14481). However, `ghc -M` doesn't guarantee this.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14480Clean up tyConTYPE2019-07-07T18:16:52ZDavid FeuerClean up tyConTYPEPhab:4085 builds a `TyCon` representing `TYPE` by hand in `Data.Typeable.Internal`. This is pretty disgusting, but it was the only way I managed to smash the last of the mysterious loops. It would be very nice to find a cleaner way, but ...Phab:4085 builds a `TyCon` representing `TYPE` by hand in `Data.Typeable.Internal`. This is pretty disgusting, but it was the only way I managed to smash the last of the mysterious loops. It would be very nice to find a cleaner way, but we want to get that merged.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.2.1 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Core Libraries |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Clean up tyConTYPE","status":"New","operating_system":"","component":"Core Libraries","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["Typeable"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Phab:4085 builds a `TyCon` representing `TYPE` by hand in `Data.Typeable.Internal`. This is pretty disgusting, but it was the only way I managed to smash the last of the mysterious loops. It would be very nice to find a cleaner way, but we want to get that merged.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14478Abstract pattern synonyms (for hsig and hs-boot)2019-07-07T18:16:52ZEdward Z. YangAbstract pattern synonyms (for hsig and hs-boot)Most declaration forms (data types, values, type families, etc) support forward declaration in hs-boot/hsig files. However, pattern synonyms do not. This seems like a major omission!
Some problems to solve:
- The obvious syntax `patter...Most declaration forms (data types, values, type families, etc) support forward declaration in hs-boot/hsig files. However, pattern synonyms do not. This seems like a major omission!
Some problems to solve:
- The obvious syntax `pattern Foo :: pat_ty` is insufficient to specify whether or not a pattern is bidirectional or unidirectional. How should this be represented syntactically?
- What is the interaction with bundling? Should it be possible to export a bundle of abstract pattern synonyms, with the intent that this means an implementation must also have bundled them together
- See also #12717; abstract pattern synonym should be implementable with a plain old constructor
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.2.1 |
| 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":"Abstract pattern synonyms (for hsig and hs-boot)","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["backpack"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Most declaration forms (data types, values, type families, etc) support forward declaration in hs-boot/hsig files. However, pattern synonyms do not. This seems like a major omission!\r\n\r\nSome problems to solve:\r\n\r\n* The obvious syntax `pattern Foo :: pat_ty` is insufficient to specify whether or not a pattern is bidirectional or unidirectional. How should this be represented syntactically?\r\n* What is the interaction with bundling? Should it be possible to export a bundle of abstract pattern synonyms, with the intent that this means an implementation must also have bundled them together\r\n* See also #12717; abstract pattern synonym should be implementable with a plain old constructor","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14474reify RHS of "value" variable2019-11-05T21:08:02Zdailecticreify RHS of "value" variableAccording to the [documentation](https://hackage.haskell.org/package/template-haskell-2.12.0.0/docs/Language-Haskell-TH-Syntax.html#t:Info), when reifying value variables "returning the RHS has not yet been implemented because of lack of...According to the [documentation](https://hackage.haskell.org/package/template-haskell-2.12.0.0/docs/Language-Haskell-TH-Syntax.html#t:Info), when reifying value variables "returning the RHS has not yet been implemented because of lack of interest". I'd like to formally request interest since I don't see a ticket here (may have missed it).
My motivating example is to make source available for documentation and better error messages. Something like:
```hs
printSource :: Name -> Q Exp
printSource n = do
VarI _ _ (Just dec) <- reify n
lift $ pprint dec
foo x = x * 2
fooSource = $(printSource 'foo) -- === "\x_0 -> x_0 GHC.Num.* 2"
```
How significant of a change is this? I could take a pass at it if pointed to the relevant bits, having not contributed to GHC before.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------- |
| Version | 8.2.1 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Template Haskell |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"reify RHS of \"value\" variable","status":"New","operating_system":"","component":"Template Haskell","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"According to the [https://hackage.haskell.org/package/template-haskell-2.12.0.0/docs/Language-Haskell-TH-Syntax.html#t:Info documentation], when reifying value variables \"returning the RHS has not yet been implemented because of lack of interest\". I'd like to formally request interest since I don't see a ticket here (may have missed it).\r\n\r\nMy motivating example is to make source available for documentation and better error messages. Something like:\r\n\r\n{{{#!hs\r\nprintSource :: Name -> Q Exp\r\nprintSource n = do\r\n VarI _ _ (Just dec) <- reify n\r\n lift $ pprint dec\r\n\r\nfoo x = x * 2\r\nfooSource = $(printSource 'foo) -- === \"\\x_0 -> x_0 GHC.Num.* 2\"\r\n}}}\r\n\r\nHow significant of a change is this? I could take a pass at it if pointed to the relevant bits, having not contributed to GHC before.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14472error __STDC_VERSION__ does not advertise C99 or later2019-07-07T18:16:54Zkaldirogluerror __STDC_VERSION__ does not advertise C99 or laterHi,
I am using Mac OS highSierra 10.13.1 and downloaded and installed Haskell Platform 8.2.1 Full 64bit-signed.pkg. Then as a first program I created a file called Selam.hs that includes followng one line:
"main = putStrLn "Hello, worl...Hi,
I am using Mac OS highSierra 10.13.1 and downloaded and installed Haskell Platform 8.2.1 Full 64bit-signed.pkg. Then as a first program I created a file called Selam.hs that includes followng one line:
"main = putStrLn "Hello, world!""
When I compiled the code using ghc -o Selam Selam.hs at the linking phase I am having "error __STDC_VERSION__ does not advertise C99 or later" error.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.1 |
| 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":"error __STDC_VERSION__ does not advertise C99 or later","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Hi,\r\n\r\nI am using Mac OS highSierra 10.13.1 and downloaded and installed Haskell Platform 8.2.1 Full 64bit-signed.pkg. Then as a first program I created a file called Selam.hs that includes followng one line:\r\n\r\n\"main = putStrLn \"Hello, world!\"\"\r\n\r\nWhen I compiled the code using ghc -o Selam Selam.hs at the linking phase I am having \"error __STDC_VERSION__ does not advertise C99 or later\" error.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14469Rebuilding profiled stage2 after building stage3 is broken2020-01-23T19:27:39ZBen GamariRebuilding profiled stage2 after building stage3 is brokenThe following appears to break,
```
$ cat <<EOF >mk/build.mk
BuildFlavour = prof
ifneq "$(BuildFlavour)" ""
include mk/flavours/$(BuildFlavour).mk
endif
EOF
$ make stage=2
$ make stage=3
$ touch compiler/stage2/build/Simplify.*
$ make s...The following appears to break,
```
$ cat <<EOF >mk/build.mk
BuildFlavour = prof
ifneq "$(BuildFlavour)" ""
include mk/flavours/$(BuildFlavour).mk
endif
EOF
$ make stage=2
$ make stage=3
$ touch compiler/stage2/build/Simplify.*
$ make stage=2
...
ghc/GHCi/UI/Info.hs:43:1: error:
Could not find module ‘TcHsSyn’
Perhaps you haven't installed the profiling libraries for package ‘ghc-8.3’?
Locations searched:
ghc/./TcHsSyn.p_hi
ghc/./TcHsSyn.p_hi-boot
ghc/stage2/build/TcHsSyn.p_hi
ghc/stage2/build/TcHsSyn.p_hi-boot
ghc/stage2/build/ghc/autogen/TcHsSyn.p_hi
ghc/stage2/build/ghc/autogen/TcHsSyn.p_hi-boot
/mnt/work/ghc/ghc/compiler/stage3/build/TcHsSyn.p_hi
|
43 | import TcHsSyn
| ^^^^^^^^^^^^^^^^^^^^^^^^
```
The problem appears to be that the build system registers the stage3 `ghc`, which we didn't build in the profiled way, overwriting the stage2 registration. Hopefully Hadrian will do better here.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.1 |
| 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":"Rebuilding profiled stage2 after building stage3 is broken","status":"New","operating_system":"","component":"Build System","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The following appears to break,\r\n\r\n{{{\r\n$ cat <<EOF >mk/build.mk\r\nBuildFlavour = prof\r\nifneq \"$(BuildFlavour)\" \"\"\r\ninclude mk/flavours/$(BuildFlavour).mk\r\nendif\r\nEOF\r\n$ make stage=2\r\n$ make stage=3\r\n$ touch compiler/stage2/build/Simplify.*\r\n$ make stage=2\r\n...\r\nghc/GHCi/UI/Info.hs:43:1: error: \r\n Could not find module ‘TcHsSyn’ \r\n Perhaps you haven't installed the profiling libraries for package ‘ghc-8.3’? \r\n Locations searched: \r\n ghc/./TcHsSyn.p_hi \r\n ghc/./TcHsSyn.p_hi-boot \r\n ghc/stage2/build/TcHsSyn.p_hi \r\n ghc/stage2/build/TcHsSyn.p_hi-boot \r\n ghc/stage2/build/ghc/autogen/TcHsSyn.p_hi \r\n ghc/stage2/build/ghc/autogen/TcHsSyn.p_hi-boot \r\n /mnt/work/ghc/ghc/compiler/stage3/build/TcHsSyn.p_hi \r\n | \r\n43 | import TcHsSyn \r\n | ^^^^^^^^^^^^^^^^^^^^^^^^ \r\n \r\n}}}\r\n\r\nThe problem appears to be that the build system registers the stage3 `ghc`, which we didn't build in the profiled way, overwriting the stage2 registration. Hopefully Hadrian will do better here.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14461Reuse free variable lists through nested closures2024-02-09T09:11:56ZTobias Dammerstdammers@gmail.comReuse free variable lists through nested closuresConsider [NestedClosures](https://gitlab.haskell.org/ghc/ghc/-/wikis/nested-closures) and #7258; essentially, deeply nested closures exhibit quadratic compiler performance due to the fact that when allocating registers, each nesting leve...Consider [NestedClosures](https://gitlab.haskell.org/ghc/ghc/-/wikis/nested-closures) and #7258; essentially, deeply nested closures exhibit quadratic compiler performance due to the fact that when allocating registers, each nesting level will have the compiler unpack the entire parent closure and then re-pack the variables into the child closure.
To solve this, check if the parent closure can be carried along wholesale, and pull variables from there so that the repackaging can be bypassed.
This comment contains an interesting test case: https://gitlab.haskell.org/ghc/ghc/-/issues/7258#note_144932
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.1 |
| 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":"Reuse free variable lists through nested closures","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Consider [wiki:NestedClosures] and [ticket:7258]; essentially, deeply nested closures exhibit quadratic compiler performance due to the fact that when allocating registers, each nesting level will have the compiler unpack the entire parent closure and then re-pack the variables into the child closure.\r\n\r\nTo solve this, check if the parent closure can be carried along wholesale, and pull variables from there so that the repackaging can be bypassed.","type_of_failure":"OtherFailure","blocking":[]} -->Alex BiehlAlex Biehlhttps://gitlab.haskell.org/ghc/ghc/-/issues/14443Add a plugin phase that allows users to modify HsSyn before the desugarer2019-07-07T18:17:01ZOllie CharlesAdd a plugin phase that allows users to modify HsSyn before the desugarerI'm currently playing around with a little project that attempts to replicate py.test. For context about py.test, see https://docs.pytest.org/en/latest/example/reportingdemo.html\#tbreportdemo, but essentially it's a Python library that ...I'm currently playing around with a little project that attempts to replicate py.test. For context about py.test, see https://docs.pytest.org/en/latest/example/reportingdemo.html\#tbreportdemo, but essentially it's a Python library that provides an `assert :: Bool -> IO ()` function, with the magic that if the assertion fails, it shows you some context about the `Bool` expression:
```
def test_simple(self):
def f():
return 42
def g():
return 43
> assert f() == g()
E assert 42 == 43
```
For example, shows that `f()` evaluated to 42.
I'd like to do something like this for Haskell, and a GHC plugin seemed like the right place to do this. I first wrote a core-to-core plugin (https://github.com/ocharles/assert-explainer/blob/e6a669680cd214f23a4213e2f945f4468998fb1d/plugin/AssertExplainer.hs) which finds free variables and and attempts to `Show` them. This works, but I'd like to do more.
As an example of something I'd like to do, I would like to let my users write `assert (and [x > 0 | x <- [-1, 0])`. This is a failing assertion, and I would like to show a kind of evaluation trace, something like
```
and [x > 0 | x <- [-1, 0] = and [False, False] = False
```
To do this, I really need access to `HsSyn`, not `CoreExpr`. Template Haskell won't do, because I don't know what I can `Show` - I really need access to the type checker as well.
A plugin that fires right before the desugarer would be really nice for this kind of task.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.2.1 |
| 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 a plugin phase that allows users to modify HsSyn before the desugarer","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"I'm currently playing around with a little project that attempts to replicate py.test. For context about py.test, see https://docs.pytest.org/en/latest/example/reportingdemo.html#tbreportdemo, but essentially it's a Python library that provides an `assert :: Bool -> IO ()` function, with the magic that if the assertion fails, it shows you some context about the `Bool` expression:\r\n\r\n\r\n{{{\r\n def test_simple(self):\r\n def f():\r\n return 42\r\n def g():\r\n return 43\r\n\r\n> assert f() == g()\r\nE assert 42 == 43\r\n}}}\r\n\r\nFor example, shows that `f()` evaluated to 42.\r\n\r\nI'd like to do something like this for Haskell, and a GHC plugin seemed like the right place to do this. I first wrote a core-to-core plugin (https://github.com/ocharles/assert-explainer/blob/e6a669680cd214f23a4213e2f945f4468998fb1d/plugin/AssertExplainer.hs) which finds free variables and and attempts to `Show` them. This works, but I'd like to do more.\r\n\r\nAs an example of something I'd like to do, I would like to let my users write `assert (and [x > 0 | x <- [-1, 0])`. This is a failing assertion, and I would like to show a kind of evaluation trace, something like\r\n\r\n{{{\r\nand [x > 0 | x <- [-1, 0] = and [False, False] = False\r\n}}}\r\n\r\nTo do this, I really need access to `HsSyn`, not `CoreExpr`. Template Haskell won't do, because I don't know what I can `Show` - I really need access to the type checker as well.\r\n\r\nA plugin that fires right before the desugarer would be really nice for this kind of task.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14429Remove constraint types from HsExtension, post TTG2019-08-02T15:32:49ZAlan ZimmermanRemove constraint types from HsExtension, post TTGOnce Trees that Grow is landed on the hsSyn AST, remove the constraint types from `HsExtension.hs`
Hopefully `DataId`, `HasSourceText`, `OutputableX` etc can all go.
<details><summary>Trac metadata</summary>
| Trac field |...Once Trees that Grow is landed on the hsSyn AST, remove the constraint types from `HsExtension.hs`
Hopefully `DataId`, `HasSourceText`, `OutputableX` etc can all go.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.1 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | sh.najd |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Remove constraint types from HsExtension, post TTG","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["sh.najd"],"type":"Task","description":"Once Trees that Grow is landed on the hsSyn AST, remove the constraint types from `HsExtension.hs`\r\n\r\nHopefully `DataId`, `HasSourceText`, `OutputableX` etc can all go.","type_of_failure":"OtherFailure","blocking":[]} -->Alan ZimmermanAlan Zimmermanhttps://gitlab.haskell.org/ghc/ghc/-/issues/14428Rework HsValBindsLR2019-08-02T15:34:17ZAlan ZimmermanRework HsValBindsLROnce Trees that Grow has been applied to the hsSyn AST, rework `HsValBindsLR` to simplify it.
From a comment on https://phabricator.haskell.org/D4147
> Nothing here gives any clue that this is intended for the output of the renamer. An...Once Trees that Grow has been applied to the hsSyn AST, rework `HsValBindsLR` to simplify it.
From a comment on https://phabricator.haskell.org/D4147
> Nothing here gives any clue that this is intended for the output of the renamer. And typechecker I think.
> Plus I wonder if we'd be better served by
```hs
data HsValBindsLR idL idR
= ValBinds
[(RecFlag, LHsBindsLR idL idR)]
[LSig GhcRn]
```
> Then the parser can generate a giant singleton Rec and the renamer can sort it out. Less fuss.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.1 |
| 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":"Rework HsValBindsLR","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Once Trees that Grow has been applied to the hsSyn AST, rework `HsValBindsLR` to simplify it.\r\n\r\nFrom a comment on https://phabricator.haskell.org/D4147\r\n\r\n> Nothing here gives any clue that this is intended for the output of the renamer. And typechecker I think.\r\n\r\n> Plus I wonder if we'd be better served by\r\n\r\n{{{#!hs\r\ndata HsValBindsLR idL idR\r\n = ValBinds\r\n [(RecFlag, LHsBindsLR idL idR)]\r\n [LSig GhcRn]\r\n}}}\r\n\r\n> Then the parser can generate a giant singleton Rec and the renamer can sort it out. Less fuss.","type_of_failure":"OtherFailure","blocking":[]} -->Alan ZimmermanAlan Zimmerman