GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2021-07-05T13:30:54Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/14777panic when using a function defined in terms of `error`2021-07-05T13:30:54ZZilin Chenzilin.chen@data61.csiro.aupanic when using a function defined in terms of `error`The error message I got from GHC was:
```
<no location info>: error:
ghc: panic! (the 'impossible' happened)
(GHC version 8.2.2 for x86_64-unknown-linux):
idInfo
t_XG0J
Call stack:
CallStack (from HasCallStack):
...The error message I got from GHC was:
```
<no location info>: error:
ghc: panic! (the 'impossible' happened)
(GHC version 8.2.2 for x86_64-unknown-linux):
idInfo
t_XG0J
Call stack:
CallStack (from HasCallStack):
prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable
callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable
pprPanic, called at compiler/basicTypes/Var.hs:526:34 in ghc:Var
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
How was it triggerred (in short):
There's function definition, `f x = undefined`. If I change it to `f x = __impossible "Oops!"`, ghc crashes. If I change it to `f x = error "Oops!"`, it's OK. The definition of `__impossible` is simply `__impossible s = error $ s ++ "some text"`.
The code can be found here: https://github.com/NICTA/cogent/blob/9420861128a8c445138aa6a48c62140d8c5f72eb/cogent/src/Cogent/Desugar.hs\#L482 and https://github.com/NICTA/cogent/blob/9420861128a8c445138aa6a48c62140d8c5f72eb/cogent/src/Cogent/Compiler.hs\#L30
It seems that this bug is not limited to 8.2.2; it also happened in 8.2.1.
I'm happy to provide more information, if someone can advice me what is needed. I'll also try to shrink it to a small test case.8.6.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/14263typeKind is quadratic2019-07-07T18:17:43ZRichard Eisenbergrae@richarde.devtypeKind is quadraticWhile pondering [D3998](https://phabricator.haskell.org/D3998), I realized that any computation of a type's kind should be careful in the presence of nested `AppTy`s. And, to my horror, I realized that GHC's very own `typeKind` isn't! Th...While pondering [D3998](https://phabricator.haskell.org/D3998), I realized that any computation of a type's kind should be careful in the presence of nested `AppTy`s. And, to my horror, I realized that GHC's very own `typeKind` isn't! That is, if you have the type `a b c d e`, GHC will take a quadratic (or worse -- haven't benchmarked) amount of time computing its kind.
This can be easily fixed by looking for nested `AppTy`s and using `piResultTys`, instead of repeated uses of `piResultTy` (as is currently done).
NB: This was not discovered through witnessing poor performance, but it does seem like very low-hanging compiler-performance fruit.
<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":"typeKind is quadratic","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":"While pondering Phab:D3998, I realized that any computation of a type's kind should be careful in the presence of nested `AppTy`s. And, to my horror, I realized that GHC's very own `typeKind` isn't! That is, if you have the type `a b c d e`, GHC will take a quadratic (or worse -- haven't benchmarked) amount of time computing its kind.\r\n\r\nThis can be easily fixed by looking for nested `AppTy`s and using `piResultTys`, instead of repeated uses of `piResultTy` (as is currently done).\r\n\r\nNB: This was not discovered through witnessing poor performance, but it does seem like very low-hanging compiler-performance fruit.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/10859Generated Eq instance associates && wrongly2019-07-14T05:09:54ZJoachim Breitnermail@joachim-breitner.deGenerated Eq instance associates && wronglyCurrently, we derive this code for `(==)`:
```
(==)
(ImportDecl a1_acXi
a2_acXj
a3_acXk
a4_acXl
a5_acXm
a6_acXn
a7_acX...Currently, we derive this code for `(==)`:
```
(==)
(ImportDecl a1_acXi
a2_acXj
a3_acXk
a4_acXl
a5_acXm
a6_acXn
a7_acXo
a8_acXp)
(ImportDecl b1_acXq
b2_acXr
b3_acXs
b4_acXt
b5_acXu
b6_acXv
b7_acXw
b8_acXx)
= (((((((((a1_acXi == b1_acXq)) && ((a2_acXj == b2_acXr)))
&& ((a3_acXk == b3_acXs)))
&& ((a4_acXl == b4_acXt)))
&& ((a5_acXm == b5_acXu)))
&& ((a6_acXn == b6_acXv)))
&& ((a7_acXo == b7_acXw)))
&& ((a8_acXp == b8_acXx)))
```
To me this looks wrongly associated: Since `&&` is strict in the left but lazy in the right argument, shouldn’t this be associated the other way around? The compiler might clean it up later, but why not produce it correctly right away?
The culprit is this line:
```
= foldl1 and_Expr (zipWith3Equal "nested_eq" nested_eq tys as bs)
```
and I was just about to change that ot `foldr1`, but then I did some git-archeology and found that Simon changed that deliberately from `foldr1` to `foldl1` in changeset:8de16184643ea3c2f9f30b5eaed18db6ef247760.
Simon, do you still recall what you were thinking when you applied this commit ... 18½years ago? :-)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.10.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Generated Eq instance associates && wrongly","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonpj"},"version":"7.10.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Currently, we derive this code for `(==)`:\r\n\r\n{{{\r\n (==)\r\n (ImportDecl a1_acXi\r\n a2_acXj\r\n a3_acXk\r\n a4_acXl\r\n a5_acXm\r\n a6_acXn\r\n a7_acXo\r\n a8_acXp)\r\n (ImportDecl b1_acXq\r\n b2_acXr\r\n b3_acXs\r\n b4_acXt\r\n b5_acXu\r\n b6_acXv\r\n b7_acXw\r\n b8_acXx)\r\n = (((((((((a1_acXi == b1_acXq)) && ((a2_acXj == b2_acXr)))\r\n && ((a3_acXk == b3_acXs)))\r\n && ((a4_acXl == b4_acXt)))\r\n && ((a5_acXm == b5_acXu)))\r\n && ((a6_acXn == b6_acXv)))\r\n && ((a7_acXo == b7_acXw)))\r\n && ((a8_acXp == b8_acXx)))\r\n}}}\r\n\r\nTo me this looks wrongly associated: Since `&&` is strict in the left but lazy in the right argument, shouldn’t this be associated the other way around? The compiler might clean it up later, but why not produce it correctly right away?\r\n\r\nThe culprit is this line:\r\n{{{\r\n = foldl1 and_Expr (zipWith3Equal \"nested_eq\" nested_eq tys as bs)\r\n}}}\r\nand I was just about to change that ot `foldr1`, but then I did some git-archeology and found that Simon changed that deliberately from `foldr1` to `foldl1` in changeset:8de16184643ea3c2f9f30b5eaed18db6ef247760.\r\n\r\nSimon, do you still recall what you were thinking when you applied this commit ... 18½years ago? :-)","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1Simon Peyton JonesSimon Peyton Jones