GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2024-03-09T14:39:42Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/24515Many profiling tests broken on Windows2024-03-09T14:39:42ZBen GamariMany profiling tests broken on WindowsIn the 9.10.1-alpha1 release job I found that many profiling-related tests are broken on Windows (see https://gitlab.haskell.org/ghc/ghc/-/jobs/1800492, https://gitlab.haskell.org/ghc/ghc/-/jobs/1800548):
```
Unexpected failures:
C:/G...In the 9.10.1-alpha1 release job I found that many profiling-related tests are broken on Windows (see https://gitlab.haskell.org/ghc/ghc/-/jobs/1800492, https://gitlab.haskell.org/ghc/ghc/-/jobs/1800548):
```
Unexpected failures:
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/caller-cc/CallerCc1.run CallerCc1 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/caller-cc/CallerCc1.run CallerCc1 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/caller-cc/CallerCc2.run CallerCc2 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/caller-cc/CallerCc2.run CallerCc2 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/caller-cc/CallerCc3.run CallerCc3 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/caller-cc/CallerCc3.run CallerCc3 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/ignore_scc.run ignore_scc [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/ignore_scc.run ignore_scc [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/ioprof.run ioprof [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/ioprof.run ioprof [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/prof-doc-fib.run prof-doc-fib [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/prof-doc-fib.run prof-doc-fib [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/prof-doc-last.run prof-doc-last [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/prof-doc-last.run prof-doc-last [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/profinline001.run profinline001 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/profinline001.run profinline001 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc-prof-overloaded-calls001.run scc-prof-overloaded-calls001 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc-prof-overloaded-calls001.run scc-prof-overloaded-calls001 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc-prof-overloaded-calls002.run scc-prof-overloaded-calls002 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc-prof-overloaded-calls002.run scc-prof-overloaded-calls002 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc-prof-overloaded001.run scc-prof-overloaded001 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc-prof-overloaded001.run scc-prof-overloaded001 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc-prof-overloaded002.run scc-prof-overloaded002 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc-prof-overloaded002.run scc-prof-overloaded002 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc001.run scc001 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc002.run scc002 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc002.run scc002 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc003.run scc003 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc003.run scc003 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc005.run scc005 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/scc005.run scc005 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/T12962.run T12962 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/T12962.run T12962 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/T2552.run T2552 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/T2552.run T2552 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/T5654-O0.run T5654-O0 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/T5654-O1.run T5654-O1 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/T5654b-O0.run T5654b-O0 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/T5654b-O1.run T5654b-O1 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/T680.run T680 [bad profile] (prof)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/T680.run T680 [bad profile] (profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/toplevel_scc_1.run toplevel_scc_1 [bad profile] (prof_no_auto)
```
It appears that the profile wasn't created in most of these cases, failing with output of the form:
```
*** unexpected failure for profinline001(profasm)
C:/GitLabRunner/builds/0/1800548/tmp/ghctest-m0rwyh7h/test spaces/testsuite/tests/profiling/should_run/profinline001.run/profinline001.exe.prof does not exist
```Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/24507Unsound optimization breaks pattern matching on sum type2024-03-23T22:14:54ZStefano DebenedettiUnsound optimization breaks pattern matching on sum type## Summary
Enabling `-O2` makes a case expression pattern match pick the 7th constructor of a sum type also when called with any constructor from the 2nd to the 6th.
The following factors seem to concur in triggering this behaviour (se...## Summary
Enabling `-O2` makes a case expression pattern match pick the 7th constructor of a sum type also when called with any constructor from the 2nd to the 6th.
The following factors seem to concur in triggering this behaviour (see the Expected behaviour section below for more details):
* `-O2`
* usage of the `streamly-core` library (I could not reproduce without it)
* a strictness annotation on the type used to hold the constructor to pass to the buggy function
* splitting the code into separate modules
On the other hand, using `Debug.Trace.trace` to examine the constructor before feeding it into the case expression fixes the issue, making it a Heisenbug.
## Steps to reproduce
```
$ git clone https://github.com/demaledetti/test-bug
$ cd test-bug
$ cabal clean && cabal build --ghc-options -v > cabal.log.ko 2>&1 && for i in {A..J}; do cabal run testbug -- $i; done
parser: A
testbug: src/TestBug/Parser.hs:(15,18)-(25,34): Non-exhaustive patterns in case
parser: B
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: C
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: D
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: E
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: F
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: G
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: H
OK
parser: I
OK
parser: J
testbug: src/TestBug/Parser.hs:(15,18)-(25,34): Non-exhaustive patterns in case
```
## Expected behaviour
With `-O1`:
```
$ cabal clean && cabal build -O1 --ghc-options -v > cabal.log.ok 2>&1 && for i in {A..J}; do cabal run -O1 testbug -- $i; done
parser: A
testbug: src/TestBug/Parser.hs:(15,18)-(25,34): Non-exhaustive patterns in case
parser: B
OK
parser: C
OK
parser: D
OK
parser: E
OK
parser: F
OK
parser: G
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: H
OK
parser: I
OK
parser: J
testbug: src/TestBug/Parser.hs:(15,18)-(25,34): Non-exhaustive patterns in case
```
For other ways to get the correct behaviour without lowering the optimization level, including the ones mentioned in the Summary section above, see these comments in the source code:
```
$ grep -rnI "the bug" src/ testbug/
src/TestBug/Data.hs:12: -- simplifying it away makes the bug disappear
src/TestBug/Parser.hs:5:-- makes the bug go away (making it a Heisenbug)
src/TestBug/Parser.hs:16: -- uncommenting the next line makes the bug disappear
src/TestBug/Parser.hs:26: -- uncommenting the next line makes the bug disappear
testbug/Main.hs:13:-- makes the bug go away
```
## Environment
* GHC version used: 9.8.2
Optional:
* Operating System:
* System Architecture:
```
$ uname -a
Linux eppere 6.7.5-gentoo #1 SMP Mon Feb 19 15:51:31 CET 2024 x86_64 Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz GenuineIntel GNU/Linux
```
Logs mentioned above:
[cabal.log.ko](/uploads/5c86dcaaac0efe1a297a3534d2e6b3a4/cabal.log.ko)
[cabal.log.ok](/uploads/aa5c0a45405cbf6e9fad05b1219dcd07/cabal.log.ok)
Log of build with `-O2` but removing the strictness annotation in `Main.hs` (commenting line 14, uncommenting line 15):
[cabal.log.lazy](/uploads/b63f0ae3c422538bb04ed7b623c49c50/cabal.log.lazy)
(easier to diff vs cabal.log.ko)9.8.3Andreas KlebingerAndreas Klebingerhttps://gitlab.haskell.org/ghc/ghc/-/issues/24505Instances getting incorrect IPE data2024-03-12T15:11:17ZFinley McIlwaineInstances getting incorrect IPE dataCode:
```haskell
{-# LANGUAGE AllowAmbiguousTypes #-}
module Main where
import GHC.InfoProv
import Unsafe.Coerce
-- Boilerplate to help us access the literal dictionaries
data Dict c where
Dict :: forall c. c => Dict c
data Bo...Code:
```haskell
{-# LANGUAGE AllowAmbiguousTypes #-}
module Main where
import GHC.InfoProv
import Unsafe.Coerce
-- Boilerplate to help us access the literal dictionaries
data Dict c where
Dict :: forall c. c => Dict c
data Box where
Box :: forall a. a -> Box
mkBox :: forall a. a => Box
mkBox = unsafeCoerce (Dict @a)
-- Interesting bit
data A = A
instance Eq A where
A == A = True
instance Ord A where
A <= A = undefined
main :: IO ()
main = do
(\(Box d) -> print =<< whereFrom d) $ mkBox @(Eq A)
(\(Box d) -> print =<< whereFrom d) $ mkBox @(Ord A)
```
This program prints the IPE data of the `Eq A` and `Ord A` dictionaries. The `Eq A` dictionary looks as we would expect, with `ipLabel = $fEqA`. The `Ord A` dictionary, however, gets the label `<`. Compile with:
```
ghc -O -fforce-recomp -finfo-table-map -fdistinct-constructor-tables Main.hs
```
The program outputs:
```
Just (InfoProv {ipName = "C:Eq_Main_0_con_info", ipDesc = CONSTR_2_0, ipTyDesc = "Eq", ipLabel = "$fEqA", ipMod = "Main", ipSrcFile = "Main.hs", ipSrcSpan = "23:10-13"})
Just (InfoProv {ipName = "C:Ord_Main_0_con_info", ipDesc = CONSTR, ipTyDesc = "Ord", ipLabel = "<", ipMod = "Main", ipSrcFile = "Main.hs", ipSrcSpan = "26:10-14"})
```
I would expect the `Ord` label to be `$fOrdA`, not `<`.
Interestingly, if we add more explicit definitions to the `Ord A` instance, the label changes. Changing the instance to:
```haskell
instance Ord A where
A <= A = undefined
compare = undefined
```
Changes the label to `>` instead of `<`:
```
Just (InfoProv {ipName = "C:Ord_Main_0_con_info", ipDesc = CONSTR, ipTyDesc = "Ord", ipLabel = ">", ipMod = "Main", ipSrcFile = "Main.hs", ipSrcSpan = "26:10-14"})
```https://gitlab.haskell.org/ghc/ghc/-/issues/24497JS: putStrLn is executed asynchronously in browser2024-03-05T14:47:50ZStefano DebenedettiJS: putStrLn is executed asynchronously in browser## Summary
The `console.log` generated by the JS backend for a `putStrLn` is executed asynchronously in browsers.
## Steps to reproduce
See attached repro case `Test.hs`.
```
$ rm -rf Test Test.hi Test.o Test.jsexe; javascript-unknow...## Summary
The `console.log` generated by the JS backend for a `putStrLn` is executed asynchronously in browsers.
## Steps to reproduce
See attached repro case `Test.hs`.
```
$ rm -rf Test Test.hi Test.o Test.jsexe; javascript-unknown-ghcjs-ghc-9.8.2 -v -dcore-lint Test.hs > ghc.log 2>&1 && ./Test
one
two
```
Loading `Test.jsexe/index.html` is a browser and opening the JS console log will show:
```
two all.js:44450:24
one all.js:8575:17
```
## Expected behavior
The `putStrLn` to be executed synchronously, as in the native backend and as interpreted by `nodejs`.
## Environment
* GHC version used: 9.8.2 JS backend
* Nodejs version used: v20.11.0
* Google Chrome version used: 121.0.6167.184 (Official build) (64 bit)
* Mozilla Firefox version used: 123.0 (64 bit)
Optional:
* Operating System:
* System Architecture:
```
$ uname -a
Linux abcde 6.7.5-gentoo #1 SMP Mon Feb 19 15:51:31 CET 2024 x86_64 Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz GenuineIntel GNU/Linux
```
[Test.hs](/uploads/9c99ee468d81f5bbe52db4dd3ed0ee90/Test.hs)
[ghc.log](/uploads/22b8f9f05f09e7d729fd17499c5b9a41/ghc.log)https://gitlab.haskell.org/ghc/ghc/-/issues/24495Javascript backend -O1 breaks referential transparency in a function having a...2024-03-26T16:52:40ZStefano DebenedettiJavascript backend -O1 breaks referential transparency in a function having a Double argument and doing String concatenation## Summary
A pure `String` value shows up as two different values when output via `putStrLn` and via `console.log`.
The following factors seem to concur in triggering this behaviour:
* The optimization level is `-O1` (does not happen ...## Summary
A pure `String` value shows up as two different values when output via `putStrLn` and via `console.log`.
The following factors seem to concur in triggering this behaviour:
* The optimization level is `-O1` (does not happen with `-O0` or `-O2`)
* The affected function has a `Double` argument (does not happen if the argument is `Int`, see the commented `testInt` function in the repro case)
* The `String` concatenation has certain characteristics (eg. does not happen for the commented `testDouble2` function in the repro case and for other similar tweaks to the `String` concatenation)
## Steps to reproduce
See attached repro case `Test.hs`.
```
$ for i in $(seq 0 2); do rm -rf Test Test.hi Test.o Test.jsexe; echo compiling with -O$i; javascript-unknown-ghcjs-ghc-9.8.2 -v -O$i -dcore-lint Test.hs > ghc.log.O$i 2>&1; echo results with -O$i; ./Test; done
compiling with -O0
results with -O0
1 ab bd
2 ab bd
compiling with -O1
results with -O1
1 ab bd
2 ab
compiling with -O2
results with -O2
1 ab bd
2 ab bd
```
Loading `index.html` in a web browser also exhibits the same behaviour in the JS console log.
## Expected behavior
The program's output to be identical regardless of the optimization level. The second part of the second line of the `-O1` results to be the same as the second part of the first line, i.e. `"ab bd"` instead of just `"ab "`.
## Environment
* GHC version used: 9.8.2 JS backend
* Nodejs version used: v20.11.0
* Google Chrome version used: 121.0.6167.184 (Official build) (64 bit)
Optional:
* Operating System:
* System Architecture:
```
$ uname -a
Linux abcde 6.7.5-gentoo #1 SMP Mon Feb 19 15:51:31 CET 2024 x86_64 Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz GenuineIntel GNU/Linux
```Sylvain HenrySylvain Henryhttps://gitlab.haskell.org/ghc/ghc/-/issues/24450Apparently deadlock in write to closed handle2024-02-18T18:50:57ZBen GamariApparently deadlock in write to closed handle@hvr reported that the following program non-deterministically hang:
```haskell
import System.IO
main :: IO ()
main = do
hPutChar stderr 'A' -- unbuffered
hPutChar stdout 'X' -- buffered -- will indeterministically cause delayed lo...@hvr reported that the following program non-deterministically hang:
```haskell
import System.IO
main :: IO ()
main = do
hPutChar stderr 'A' -- unbuffered
hPutChar stdout 'X' -- buffered -- will indeterministically cause delayed lock-ups
hPutChar stderr 'Z' -- unbuffered
hPutChar stderr '\n' -- unbuffered
```
```sh
$ ghc -threaded -O Main.hs
$ while :; do ./Main >&- ; done
AZ
AZ
*hang*
```
I can confirm that the program hangs almost immediately on Linux with GHC 9.2.8, 9.6.3, and 9.8.1. @hvr says that the issue may have been introduced in GHC 8.2.1.Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/24401fixIO can choke, and report a loop where there is none2024-02-06T15:13:14ZSimon Peyton JonesfixIO can choke, and report a loop where there is noneThis program was written by [Matthew Craven](https://github.com/haskell/core-libraries-committee/issues/242#issuecomment-1907226501):
```
import System.IO( fixIO )
import GHC.Exts (noinline)
main :: IO ()
main = do
r <- fixIO $ \p -> ...This program was written by [Matthew Craven](https://github.com/haskell/core-libraries-committee/issues/242#issuecomment-1907226501):
```
import System.IO( fixIO )
import GHC.Exts (noinline)
main :: IO ()
main = do
r <- fixIO $ \p -> let
{-# NOINLINE q #-}
q = noinline id p
in pure (True : q)
print $! case r of { _:v:_ -> v ; _ -> False }
```
For any law-abiding MonadFix instance, such a call to `mfix` should be semantically equivalent to `pure (repeat True)`. (Specifically, this follows from the 'Purity' law.)
So the `print` should work fine. But actually we get (with -O)
```
run-it: cyclic evaluation in fixIO
```
## Diagnosis
What is going on? Here is the code after optimisation:
```
Main.main1
= \ (s_aRX :: GHC.Prim.State# GHC.Prim.RealWorld) ->
case GHC.Prim.newMVar#
@GHC.Types.Lifted @GHC.Prim.RealWorld @[Bool] s_aRX
of
{ (# ipv_aUk, ipv1_aUl #) ->
case GHC.IO.Unsafe.unsafeDupableInterleaveIO1
@[Bool]
((\ (eta_aSp [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) ->
GHC.Prim.catch# @GHC.Types.LiftedRep @GHC.Types.Lifted @[Bool]
@GHC.Exception.Type.SomeException
(\ (eta1_aUj [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) ->
GHC.Prim.readMVar#
@GHC.Types.Lifted @GHC.Prim.RealWorld @[Bool] ipv1_aUl eta1_aUj)
(System.IO.fixIO2 @[Bool])
eta_aSp)
`cast` (Sym (GHC.Types.N:IO[0] <[Bool]>_R)
:: (GHC.Prim.State# GHC.Prim.RealWorld
-> (# GHC.Prim.State# GHC.Prim.RealWorld, [Bool] #))
~R# IO [Bool]))
ipv_aUk
of
{ (# ipv2_aUp, ipv3_aUq #) ->
let {
q_s1HX [InlPrag=NOINLINE, Dmd=SL] :: [Bool]
q_s1HX = noinline @(forall a. a -> a) id @[Bool] ipv3_aUq } in
case GHC.Prim.putMVar# @GHC.Types.Lifted @GHC.Prim.RealWorld @[Bool]
ipv1_aUl
(GHC.Types.: @Bool GHC.Types.True q_s1HX)
ipv2_aUp
of s2#_aUw
{ __DEFAULT ->
case q_s1HX of {
[] ->
GHC.IO.Handle.Text.hPutStr2
GHC.IO.Handle.FD.stdout
GHC.Show.$fShowBool5
GHC.Types.True
s2#_aUw;
: v_aJ6 ds2_dRE ->
case v_aJ6 of vx_aV1 { __DEFAULT ->
GHC.IO.Handle.Text.hPutStr2
GHC.IO.Handle.FD.stdout
(case vx_aV1 of {
False -> GHC.Show.$fShowBool5;
True -> GHC.Show.$fShowBool4
})
GHC.Types.True
s2#_aUw
} } } } }
```
* The MVar stuff is to "tie the knot" in `fixIO`.
* The `putMVar#` fills in the MVar
* The `unsafeDupableInterleaveIO1` call returns a thunk in `ipv3` which reads the MVar when forced.
Now, **alas** the strictness analyser works out that `q` i used strictly in the continuation, so
the binding for `q` is done with a `case` not a `let` (look at CorePrep output). So we force `ipv3` too
early, before the `putMVar#` has run.
## Cure
The code for `fixIO` is this:
```
fixIO :: (a -> IO a) -> IO a
fixIO k = do
m <- newEmptyMVar
ans <- unsafeDupableInterleaveIO
(readMVar m `catch` \BlockedIndefinitelyOnMVar ->
throwIO FixIOException)
result <- k ans
putMVar m result
return result
```
Why all this MVar stuff? See `Note [fixST]` in `base:Control.Monad.ST.Imp`.
(And [this comment](https://github.com/haskell/core-libraries-committee/issues/242#issuecomment-1902317732).)
Looking at this code it's clear that we must do the `putMVar` before evaluating `result`.
But if we inline `fixIO`, the consumer will consume the `return result`, and the consumer
may well be strict in `result`. Something like
```
do { result <- fixIO m
; f result } -- where f is strict
```
Two simple solutions
* Do not inline `fixIO`.
* Wrap the result of `fixIO` in `lazy`, thus
```
putMVar m restult
return (lazy result)
```
I am not sure which is best. But the `lazy` solution is the one adopted by `Note [unsafePerformIO and strictness]` in GHC.IO.Unsafe, for a very very similar problem.https://gitlab.haskell.org/ghc/ghc/-/issues/24358For Ratios, round produces incorrect results for some fixed-width signed inte...2024-01-23T17:55:25Zj6careyFor Ratios, round produces incorrect results for some fixed-width signed integer values## Summary
The implementation of "round" for a ratio of fixed-width signed
integers is incorrect when applied to extreme negative values.
## Steps to reproduce
```
GHCi, version 9.8.1: https://www.haskell.org/ghc/ :? for help
ghci> r...## Summary
The implementation of "round" for a ratio of fixed-width signed
integers is incorrect when applied to extreme negative values.
## Steps to reproduce
```
GHCi, version 9.8.1: https://www.haskell.org/ghc/ :? for help
ghci> round ((-128) Data.Ratio.% (-16 :: Integer))
8
ghci> round ((-128) Data.Ratio.% (-16 :: Data.Int.Int8))
-8
```
## Expected behavior
```
GHCi, version 9.8.1: https://www.haskell.org/ghc/ :? for help
ghci> round ((-128) Data.Ratio.% (-16 :: Integer))
8
ghci> round ((-128) Data.Ratio.% (-16 :: Data.Int.Int8))
8
```
## Environment
* GHC version used: 9.8.1, 9.4.7
* Operating System: Ubuntu 22.04.3 LTS
* System Architecture: x86_649.10.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/24345Concurrent GHC sessions clobber RTS linker state2024-02-02T17:24:01ZAlexis KingConcurrent GHC sessions clobber RTS linker stateThe following example program (derived from `T3372`) illustrates how concurrent GHC sessions can clobber each other’s RTS linker state:
```haskell
{-# LANGUAGE MagicHash #-}
module Main where
import Data.Foldable
import System.Environm...The following example program (derived from `T3372`) illustrates how concurrent GHC sessions can clobber each other’s RTS linker state:
```haskell
{-# LANGUAGE MagicHash #-}
module Main where
import Data.Foldable
import System.Environment
import GHC (Ghc)
import qualified GHC
import qualified GHC.Driver.Monad as GHC
import qualified GHC.Driver.Session as GHC
import qualified GHC.Platform.Ways as GHC
import qualified GHC.Exts
main :: IO ()
main = do
let test1 = "M1.hs"
let test2 = "M2.hs"
writeFile test1 "module M where x = 1"
writeFile test2 "module M where x = 2"
ghc_1 <- newGhcSession
ghc_2 <- newGhcSession
line "1" $ runInSession ghc_1 $ load (test1, "M")
line "2" $ runInSession ghc_2 $ load (test2, "M")
line "3" $ runInSession ghc_1 $ eval "x"
line "4" $ runInSession ghc_2 $ eval "x"
line "5" $ runInSession ghc_1 $ eval "x"
where
line n a = putStr (n ++ ": ") >> a
type ModuleName = String
newGhcSession :: IO GHC.Session
newGhcSession = do
(libdir:_) <- getArgs
session <- GHC.runGhc (Just libdir) (GHC.reifyGhc pure)
runInSession session $ do
df <- GHC.getSessionDynFlags
let platform = GHC.targetPlatform df
GHC.setSessionDynFlags $
foldl' (flip GHC.setGeneralFlag')
df{GHC.ghcMode = GHC.CompManager,
GHC.ghcLink = GHC.LinkInMemory,
GHC.targetWays_ = GHC.hostFullWays,
GHC.verbosity = 0}
(concatMap (GHC.wayGeneralFlags platform) GHC.hostFullWays)
pure session
runInSession :: GHC.Session -> Ghc a -> IO a
runInSession = flip GHC.reflectGhc
load :: (FilePath, ModuleName) -> Ghc ()
load (f, mn) = do
target <- GHC.guessTarget f Nothing Nothing
GHC.setTargets [target]
res <- GHC.load GHC.LoadAllTargets
GHC.liftIO $ putStrLn ("Load " ++ showSuccessFlag res)
GHC.setContext
[ GHC.IIDecl $ GHC.simpleImportDecl $ GHC.mkModuleName "Prelude"
, GHC.IIDecl $ GHC.simpleImportDecl $ GHC.mkModuleName mn ]
where
showSuccessFlag GHC.Succeeded = "succeeded"
showSuccessFlag GHC.Failed = "failed"
eval :: String -> Ghc ()
eval e = do
show_e <- GHC.compileExpr $ "(show ("++ e ++")) :: String"
GHC.liftIO $ putStrLn (GHC.Exts.unsafeCoerce# show_e)
```
Compiling and running this program yields the following output:
```haskell
$ ghc -dynamic -package ghc Main
[1 of 2] Compiling Main ( Main.hs, Main.o )
[2 of 2] Linking Main [Objects changed]
$ ./Main "$(ghc --print-libdir)"
1: Load succeeded
2: Load succeeded
3: 1
4: 2
5: 2
```
The final line of output is the bug; it should print `1`, but instead it prints `2`.
## Explanation
The above program creates two concurrent GHC sessions and loads a module into each one. The modules share the same name and export the same symbol, but the symbol has a different value in each module.
Since the backend is the NCG and the program is dynamically-linked, each GHC session compiles the loaded module to a `.o` file, then links the `.o` file into a `.so` file on demand. The first time the two sessions each evaluate a reference to the loaded symbol, the results are `1` and `2`, respectively, which is correct. However, when the symbol is evaluated in the first session a second time, the `2` value from the second session is printed, instead. In effect, the module loaded in the second session has overwritten the module loaded in the first session, which is quite surprising.
This symbol clobbering only affects symbols loaded from shared objects, and it only affects the symbols resolved from an interpreted context. Even if symbols are “overwritten” in this way, references from native code will still refer to the original, correct symbols. However, any references in newly-created bytecode will be incorrect, and references from existing bytecode objects will become incorrect if the bytecode objects are relinked. Note also that the clobbering is truly on a symbol-by-symbol basis: if the second module were to export some, but not all, of the first module’s symbols, the values of those symbols would be selectively clobbered, leaving the first session in an inconsistent state. If the replaced symbols’ types differ from their replacements, memory corruption or segfaults are likely to occur.
## Cause
Currently, the state of the RTS linker is process-global. This includes the RTS symbol table, the list of loaded code objects, and the list of loaded shared libraries. GHC generally expects that it is the exclusive client of the RTS linker, and this assumption is essentially always correct, but concurrent GHC sessions break this assumption, which can result in various misbehaviors.
When the RTS linker is used to load static `.o` files or `.a` archives, it does all the work of loading the objects itself, including maintaining its own symbol table. For this reason, if the above example is compiled without the `-dynamic` option, the outcome is quite different:
```
$ ghc -package ghc Main
[1 of 2] Compiling Main ( Main.hs, Main.o )
[2 of 2] Linking Main [Objects changed]
$ ./Main "$(ghc --print-libdir)"
1: Load succeeded
2: Load succeeded
3: 1
GHC runtime linker: fatal error: I found a duplicate definition for symbol
M_x_closure
whilst processing object file
/tmp/haskell/M2.o
The symbol was previously defined in
/tmp/haskell/M1.o
This could be caused by:
* Loading two different object files which export the same symbol
* Specifying the same object file twice on the GHCi command line
* An incorrect `package.conf' entry, causing some object to be
loaded twice.
4: Main: loadObj "/tmp/haskell/M2.o": failed
```
Since the RTS maintains its own symbol table in this configuration, it can detect the symbol collision and report the error. This behavior is arguably still wrong—there is no fundamental reason that the two sessions must share a symbol table, and other session state is kept separate—but it’s at least less mysterious.
In contrast, when the RTS loads a shared library, it defers the work to the system dynamic linker (via `dlopen` on Linux and macOS). System dynamic linkers do not provide APIs to obtain the full list of symbols provided by a shared library, so the RTS cannot possibly determine whether two libraries provide conflicting symbols. When a symbol is looked up, each library is tried in order until the symbol is found, starting from the library that was most recently loaded. Within a single interpreter session, this strategy provides the generally-desirable property that new symbols shadow old ones (since most symbol conflicts arise from loading a new version of the same code), but it is much less defensible if multiple sessions exist in the same process.https://gitlab.haskell.org/ghc/ghc/-/issues/24296Simplifier wrongly discards erroring function call2024-02-05T17:53:14ZMatthew Cravenclyring@gmail.comSimplifier wrongly discards erroring function call## Steps to reproduce
Compile with optimisations and run the following module:
```haskell
{-# LANGUAGE GHC2021, UnboxedTuples #-}
module Main (main) where
newtype Tricky = TrickyCon { unTrickyCon :: (# #) -> Tricky }
main :: IO ()
ma...## Steps to reproduce
Compile with optimisations and run the following module:
```haskell
{-# LANGUAGE GHC2021, UnboxedTuples #-}
module Main (main) where
newtype Tricky = TrickyCon { unTrickyCon :: (# #) -> Tricky }
main :: IO ()
main = do
let
tricky :: Tricky
{-# OPAQUE tricky #-}
tricky = TrickyCon $ \(# #) -> TrickyCon $ \(# #) ->
error "tricky called with at least two args"
applyToN :: Int -> Tricky -> Tricky
{-# OPAQUE applyToN #-}
applyToN n a | n == 0 = a
| otherwise = applyToN (n - 1) a `unTrickyCon` (# #)
case applyToN 12345 tricky of
!_ -> putStrLn "unreachable"
```
The function `tricky` is applied to far more than two args, so the error call in its body should be reached. But when run, the program prints "unreachable" and exits successfully instead of failing with "tricky called with at least two args". (This wrong behavior persists even with `-O -fpedantic-bottoms -fno-state-hack`.)
Inspecting the `-ddump-simpl` and `-dverbose-core2core` output suggests the simplifier is eliminating the `applyToN` stuff entirely.
## Environment
* GHC version used: 9.8.1Sebastian GrafSebastian Grafhttps://gitlab.haskell.org/ghc/ghc/-/issues/24295loopification non-sense around void args2024-02-08T17:32:06ZMatthew Cravenclyring@gmail.comloopification non-sense around void args## Summary
`Note [Void arguments in self-recursive tail calls]` looks extremely suspicious. I reproduce it here:
```
-- Note [Void arguments in self-recursive tail calls]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
-- Stat...## Summary
`Note [Void arguments in self-recursive tail calls]` looks extremely suspicious. I reproduce it here:
```
-- Note [Void arguments in self-recursive tail calls]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
-- State# tokens can get in the way of the loopification optimization as seen in
-- #11372. Consider this:
--
-- foo :: [a]
-- -> (a -> State# s -> (# State s, Bool #))
-- -> State# s
-- -> (# State# s, Maybe a #)
-- foo [] f s = (# s, Nothing #)
-- foo (x:xs) f s = case f x s of
-- (# s', b #) -> case b of
-- True -> (# s', Just x #)
-- False -> foo xs f s'
--
-- We would like to compile the call to foo as a local jump instead of a call
-- (see Note [Self-recursive tail calls]). However, the generated function has
-- an arity of 2 while we apply it to 3 arguments, one of them being of void
-- type. Thus, we mustn't count arguments of void type when checking whether
-- we can turn a call into a self-recursive jump.
--
```
Nowadays it's very clear that `foo` has a post-unarise arity of 3, and we call it with 3 arguments (one of which happens to be void). And indeed if `foo` tail-called itself with only two arguments (and no final void argument) it would be _utterly wrong_ to just jump to its body. (Of course, this sort of call is only type-correct in the presence of strange recursive newtypes.)
Here's a short program that demonstrates that we can in fact generate such bogus self-jumps today:
<details>
```haskell
module Main (main) where
import Data.IORef (newIORef, readIORef, writeIORef)
import Control.Exception (evaluate)
import GHC.Exts (noinline)
newtype Tricky = TrickyCon { unTrickyCon :: IO Tricky }
main :: IO ()
main = do
ref <- newIORef False
let
tricky :: Tricky
tricky = TrickyCon $ do
putStrLn "tricky call"
v <- readIORef ref
case v of
False -> writeIORef ref True >> evaluate (noinline tricky)
True -> putStrLn "this shouldn't be printed" >> pure tricky
() <$ unTrickyCon tricky
```
</details>
(Why does this reproducer uses the special handling of `evaluate`/`seq#` instead of a direct function call? ...as a work-around for other bugs. Ticket to follow...)
Compile with optimizations and run. The expected output is a single line "tricky call"; the actual output is as follows:
```
tricky call
tricky call
this shouldn't be printed
```
## Environment
* GHC version used: 9.8.1Matthew Cravenclyring@gmail.comMatthew Cravenclyring@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/24189Async exceptions ignored and reraised by `catch` still update enclosing thunks2023-11-14T15:36:53ZAlexis KingAsync exceptions ignored and reraised by `catch` still update enclosing thunksThe following program produces a surprising result:
```haskell
import Control.Concurrent
import Control.Exception
import System.IO.Unsafe
main :: IO ()
main = do
let io_thunk = unsafePerformIO $
catch (threadDelay 1000000 *> ...The following program produces a surprising result:
```haskell
import Control.Concurrent
import Control.Exception
import System.IO.Unsafe
main :: IO ()
main = do
let io_thunk = unsafePerformIO $
catch (threadDelay 1000000 *> pure True)
(\(_ :: ErrorCall) -> pure False)
eval_thread <- forkIO (evaluate io_thunk *> pure ())
threadDelay 500000
killThread eval_thread
print io_thunk
```
Intuitively, the use of `catch` should not affect the meaning of this program, as it only catches `ErrorCall` exceptions, which will never be raised. However, its presence *does* affect the program’s result, and quite substantially: it causes the program to terminate with an exception.
```
$ ghc A.hs
[1 of 2] Compiling Main ( A.hs, A.o )
[2 of 2] Linking A
$ ./A
A: thread killed
```
This is quite surprising, as the same program with the `catch` removed simply prints `True` and exits successfully.[^1]
## The cause of the bug
This behavior is an unfortunate consequence of the way `catch` and asynchronous exceptions interact. When an async exception is delivered to a thread, the RTS takes care to suspend the work of any thunks currently being evaluated as it unwinds the stack. However, as soon as the RTS encounters a `CATCH_FRAME`, the exception is effectively converted to a synchronous exception. From the perspective of the RTS, all such frames are interchangeable, as the `catch#` primop knows nothing about the `Exception` class and therefore always catches all exceptions; `catch` is implemented by simply examining the caught exception and reraising it if it is not of the desired type.
This implementation strategy for `catch` fundamentally prevents `io_thunk` from the above program from being suspended upon delivery of an async exception. When the RTS encounters the `CATCH_FRAME`, it must resume execution from that point, so the unwound portion of the current evaluation context can only be discarded.
## Workarounds
Technically, this bug can be avoided by simply uninterruptibly masking asynchronous exceptions whenever `catch` is used within `unsafePerformIO`. However, this is a very heavy hammer, and it is not particularly satisfying.
Given sufficiently deep knowledge of both the RTS and the implementation of `catch`, it is technically possible to implement a more complete workaround. The following variant of the above program behaves as desired:
```haskell
import Control.Concurrent
import Control.Exception
import System.IO.Unsafe
main :: IO ()
main = do
let io_thunk = unsafePerformIO $ mask $ \restore -> do
let body = unsafePerformIO $ threadDelay 1000000 *> pure True
go = restore $ catches (evaluate body)
[ Handler $ \(_ :: ErrorCall) -> pure False
, Handler $ \(exn :: SomeAsyncException) -> do
myself <- myThreadId
throwTo myself exn
go
]
go
eval_thread <- forkIO (evaluate io_thunk *> pure ())
threadDelay 500000
killThread eval_thread
print io_thunk
```
The details are remarkably subtle:
* The body of the `catch` must be split into a separate thunk to give the RTS a place to store the suspended evaluation context.
* When an async exception is raised, it must be explicitly caught and reraised using `throwTo`, which effectively suspends the outer thunk. When that thunk is resumed, it must continue by resuming evaluation of the inner thunk.
* `mask` must be used not because async exceptions must be masked, but because they must be *unmasked*: `catch` implicitly masks exceptions within each handler, so if exceptions were not explicitly unmasked, they would incorrectly remain masked during the recursive call to `go`.
In theory, this is not a perfect solution: catching `SomeAsyncException` is not actually guaranteed to catch all async exceptions. However, it is likely good enough in practice. Still, it is quite complex, and I expect few Haskell programmers would fully understand how it works or why/when it is needed. At the very least, the `Control.Exception` documentation ought to be clarified to warn about this pitfall.
[^1]: As of this writing, this difference can only be observed if the program is compiled. If evaluated in GHCi, the program *always* terminates with an exception whether the `catch` is present or not, which I’ve reported separately as #24187.https://gitlab.haskell.org/ghc/ghc/-/issues/24187Thunk is incorrectly updated on async exception in GHCi2023-11-14T15:38:34ZAlexis KingThunk is incorrectly updated on async exception in GHCiThe following program produces different results depending on whether it is compiled or interpreted:
```haskell
import Control.Concurrent
import Control.Exception
import System.IO.Unsafe
main :: IO ()
main = do
let io_thunk = unsafeP...The following program produces different results depending on whether it is compiled or interpreted:
```haskell
import Control.Concurrent
import Control.Exception
import System.IO.Unsafe
main :: IO ()
main = do
let io_thunk = unsafePerformIO $ threadDelay 1000000 *> pure ()
eval_thread <- forkIO (evaluate io_thunk *> pure ())
threadDelay 500000
killThread eval_thread
print io_thunk
```
When compiled, the program prints `()`, but when interpreted, it terminates with an exception:
```
$ ghc A.hs
[1 of 2] Compiling Main ( A.hs, A.o )
[2 of 2] Linking A
$ ./A
()
$ ghc --run A.hs
<interactive>: thread killed
```
It seems like `io_thunk` is somehow being incorrectly overwritten as if the async exception were in fact raised synchronously.https://gitlab.haskell.org/ghc/ghc/-/issues/24140Eventlog + Debugging flag order shows unexpected behaviour2023-11-22T14:27:43ZJavier SagredoEventlog + Debugging flag order shows unexpected behaviour## Summary
Order of debug options and eventlog result in unexpected behavior.
- `-Dm`: emits messages `-Dm` to stderr :white_check_mark:
- `-Dm -l`: emits messages `-Dm` to the eventlog :white_check_mark:
- `-l -Dm`: emits `-Dm` to s...## Summary
Order of debug options and eventlog result in unexpected behavior.
- `-Dm`: emits messages `-Dm` to stderr :white_check_mark:
- `-Dm -l`: emits messages `-Dm` to the eventlog :white_check_mark:
- `-l -Dm`: emits `-Dm` to stderr and **enables what I believe is `-Ds`** :warning:
## Steps to reproduce
Any program would suffice. I can provide this one:
```bash
$ cat A.hs
module Main where
{-# NOINLINE fib #-}
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
main = do
print (fib 30)
$ ghc A.hs -debug
[1 of 2] Compiling Main ( A.hs, A.o )
[2 of 2] Linking A [Objects changed]
$ ./A +RTS -Dm 2>&1 | head
STM: 0x5b0780 : lock_stm()
STM: stmPreGCHook
STM: 0x5b0780 : unlock_stm()
STM: 0x5b0780 : lock_stm()
STM: stmPreGCHook
STM: 0x5b0780 : unlock_stm()
STM: 0x5b0780 : lock_stm()
STM: stmPreGCHook
STM: 0x5b0780 : unlock_stm()
STM: 0x5b0780 : lock_stm()
$ ./A +RTS -l -Dm 2>&1 | head
created capset 0 of type 2
created capset 1 of type 3
cap 0: initialised
assigned cap 0 to capset 0
assigned cap 0 to capset 1
cap 0: created thread 1[""]
cap 0: running thread 1[""] (ThreadRunGHC)
cap 0: thread 1[""] stopped (stack overflow, size 104)
cap 0: running thread 1[""] (ThreadRunGHC)
cap 0: thread 1[""] stopped (yielding)
$ ./A +RTS -Dm -l 2>&1 | head
832040
```
## Expected behavior
I would expect `-Ds` not to be enabled by this combination of flags, and furthermore I though the order of the options should not modify the behaviour.
## Environment
* GHC version used: 9.6.3
Optional:
* Operating System: Ubuntu 23.10
* System Architecture: x86_64-linuxMatthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/24112Unregisterised build error since haddock bump2023-12-01T15:06:10ZStefan Schulze FrielinghausUnregisterised build error since haddock bump## Summary
Since commit 1578215fd24c8b50b9d7d6cfc35e274b71dcff1a building an unregisterised GHC on s390x leads to the following error:
```
Command line: _build/stage0/bin/ghc -Wall -Wcompat -dynamic-too -hisuf hi -osuf o -hcsuf hc -sta...## Summary
Since commit 1578215fd24c8b50b9d7d6cfc35e274b71dcff1a building an unregisterised GHC on s390x leads to the following error:
```
Command line: _build/stage0/bin/ghc -Wall -Wcompat -dynamic-too -hisuf hi -osuf o -hcsuf hc -static -hide-all-packages -no-user-package-db '-package-env -' '-package-db _build/stage1/inplace/package.conf.d' '-this-unit-id template-haskell-2.21.0.0-inplace' '-package-id base-4.19.0.0-inplace' '-package-id ghc-boot-th-9.9-inplace' '-package-id ghc-prim-0.10.0-inplace' '-package-id pretty-1.1.3.6-inplace' -i -i/devel/ghc/master/_build/stage1/libraries/template-haskell/build -i/devel/ghc/master/_build/stage1/libraries/template-haskell/build/autogen -i/devel/ghc/master/libraries/template-haskell/vendored-filepath -i/devel/ghc/master/libraries/template-haskell -Irts/include -I_build/stage1/libraries/template-haskell/build -I/devel/ghc/master/libraries/base/include -I/devel/ghc/master/_build/stage1/libraries/base/build/include -I/devel/ghc/master/libraries/ghc-bignum/include/ -I/devel/ghc/master/_build/stage1/libraries/ghc-bignum/build/include/ -I/devel/ghc/master/rts/include -I/devel/ghc/master/_build/stage1/rts/build/include -optP-include -optP_build/stage1/libraries/template-haskell/build/autogen/cabal_macros.h -outputdir _build/stage1/libraries/template-haskell/build -fdiagnostics-color=always -Wall -this-unit-id template-haskell -XHaskell2010 -XImplicitPrelude -no-global-package-db -package-db=/devel/ghc/master/_build/stage1/inplace/package.conf.d -ghcversion-file=rts/include/ghcversion.h -ghcversion-file=rts/include/ghcversion.h -Wnoncanonical-monad-instances -optc-Wno-error=inline -c libraries/template-haskell/Language/Haskell/TH/Syntax.hs -o _build/stage1/libraries/template-haskell/build/Language/Haskell/TH/Syntax.o -O2 -H32m -haddock -Wno-deprecated-flags
===> Command failed with error code: 1
<command line>: unknown unit: template-haskell
Command failed
Build failed.
```
Any idea what could have gone wrong?
## Steps to reproduce
```
./boot && ./configure --enable-unregisterised && ./hadrian/build -j
```
## Environment
* GHC version used: 9.4.4
Optional:
* Operating System: Fedora 37
* System Architecture: s390xhttps://gitlab.haskell.org/ghc/ghc/-/issues/23980Incorrect filesize and timestamps for JavaScript backend2023-10-05T21:41:48ZLuite StegemanIncorrect filesize and timestamps for JavaScript backendThe JavaScript backend still has some bugs when filling the `stat` data used in the `FileStatus` data structure:
Some issues I've found:
* the time fields (`st_atime`/`st_mtime`/`st_ctime`) fields are filled assuming that the size re...The JavaScript backend still has some bugs when filling the `stat` data used in the `FileStatus` data structure:
Some issues I've found:
* the time fields (`st_atime`/`st_mtime`/`st_ctime`) fields are filled assuming that the size reported by the `configure` script is for whole `timespec` struct, which results in 32 bit for the seconds + 32 bit for nanoseconds. In reality `stat.st_mtime` is actually defined to be `stat.st_mtim.tv_sec` and should be 64 bit.
* the large field `st_size` is filled in the wrong order, resulting in the wrong size being decoded.
I'm working on a fix and adding a test that tests these basic file properties so that we can find them in a simple test (instead in something strange going wrong in cabal/backpack tests)9.8.2Luite StegemanLuite Stegemanhttps://gitlab.haskell.org/ghc/ghc/-/issues/23923Possibly a variant of "Specialiser creates bogus specialisations" (#23109) th...2024-02-29T12:50:14ZMikolaj KonarskiPossibly a variant of "Specialiser creates bogus specialisations" (#23109) that reproduces with -fno-polymorphic-specialisation on GHC 9.8.1-alpha1[Edit: see https://gitlab.haskell.org/ghc/ghc/-/issues/23923#note_524660 for a slightly minimised repro.]
This looks like a repeat of #23109 but even with `-fno-polymorphic-specialisation` that was so far a sufficient workaround for it ...[Edit: see https://gitlab.haskell.org/ghc/ghc/-/issues/23923#note_524660 for a slightly minimised repro.]
This looks like a repeat of #23109 but even with `-fno-polymorphic-specialisation` that was so far a sufficient workaround for it (and is the default on 9.8 right now). It seems to follow the same pattern as with the other related issues: as I tweak the code and GHC options to force specializations to happen, tests errors start appearing and gradually appear in greater number.
Repro: with GHC 9.8.1-alpha1 and https://ghc.gitlab.haskell.org/head.hackage/ run (the -O1 or -O2 is essential; tests pass with -O0):
cabal test simplifiedOnlyTest -ftest_seq --enable-optimization --test-show-details=direct --test-options='-p 3concatBuild1'
on commit
https://github.com/Mikolaj/horde-ad/commit/a9ea6e930f3561d90237cf8a431b8aad24387c8e
The test should succeed, but it fails a runtime check (in an outside library) about ranks that the typing guarantees should agree:
```
3concatBuild1: FAIL
Exception: fromVector: rank mismatch (9,0)
CallStack (from HasCallStack):
error, called at ./Data/Array/Internal/RankedG.hs:152:45 in orthotope-0.1.6.0-479d70a92b172419adf0e1e7dd92abde8158cf52f3d7287680c06fc9bb693f0c:Data.Array.Internal.RankedG
fromVector, called at ./Data/Array/Internal/RankedS.hs:133:21 in orthotope-0.1.6.0-479d70a92b172419adf0e1e7dd92abde8158cf52f3d7287680c06fc9bb693f0c:Data.Array.Internal.RankedS
```
I can't compare with GHC 9.6.2 due to #23922, GHC 9.4.6 fails in exactly the same way (#23866), but it fails on several times more tests (after removing `--test-options`), so the root cause may be different, especially given that GHC 9.4.6 most probably doesn't manage to specialize as much as GHC 9.8.1-alpha1. Adding `-fdicts-cheap -flate-dmd-anal -O2` makes GHC 9.8.1-alpha1 fail on 6 instead of 3 tests. A few performance-improving commits ago it wasn't failing at all (but it was failing similarly with `-fpolymorphic-specialisation` (I don't recall if in exactly the same way)). GHC 9.2.7 is the only recent GHC version that passes this test (and the whole test suite; it compiles quickly and runs quite slowly). IIRC from toying with `inspection-testing`, GHC 9.2.7 specializes even less than the remaining GHCs.9.10.1https://gitlab.haskell.org/ghc/ghc/-/issues/23899Nightly primops test failed on Darwin2023-09-07T09:41:40ZBryan Rbryan@haskell.foundationNightly primops test failed on DarwinJob [#1649852](https://gitlab.haskell.org/ghc/test-primops/-/jobs/1649852) failed for test-primops@e7d5ce0be2f2a56fc2103ae3d2267101fcfc8f7f
Via nightly pipeline https://gitlab.haskell.org/ghc/ghc/-/pipelines/83410Job [#1649852](https://gitlab.haskell.org/ghc/test-primops/-/jobs/1649852) failed for test-primops@e7d5ce0be2f2a56fc2103ae3d2267101fcfc8f7f
Via nightly pipeline https://gitlab.haskell.org/ghc/ghc/-/pipelines/834109.8.2Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/23866Possibly a variant of "Specialiser creates bogus specialisations" (#23109) th...2023-09-01T13:08:35ZMikolaj KonarskiPossibly a variant of "Specialiser creates bogus specialisations" (#23109) that affects 9.4.6This looks like a repeat of #23109 but for GHC 9.4.6. GHC 9.2.8 is not affected (from the looks of it, GHC 9.2.8 doesn't manage to specialize as much in this case). `-O0` is not affected.
The following commit breaks things by making spe...This looks like a repeat of #23109 but for GHC 9.4.6. GHC 9.2.8 is not affected (from the looks of it, GHC 9.2.8 doesn't manage to specialize as much in this case). `-O0` is not affected.
The following commit breaks things by making specialization fire more often (as verified with https://hackage.haskell.org/package/inspection-testing)
https://github.com/Mikolaj/horde-ad/commit/85d7ecc5aaaf3775476ca90c049984b444a359d6
The commit doesn't do anything except tweaking `SPECIALIZE` pragmas. The unsoundess manifests similarly as in #23109, e.g., with
```
~/r/horde-ad$ cabal test simplifiedOnlyTest --test-options='-p 3concatBuild22' --enable-optimization -ftest_seq --ghc-options='-dcore-lint -dstg-lint -dcmm-lint -dtag-inference-checks'
Build profile: -w ghc-9.4.6 -O1
In order, the following will be built (use -v for more details):
- horde-ad-0.1.0.0 (test:simplifiedOnlyTest) (first run)
Preprocessing test suite 'simplifiedOnlyTest' for horde-ad-0.1.0.0..
Building test suite 'simplifiedOnlyTest' for horde-ad-0.1.0.0..
Running 1 test suites...
Test suite simplifiedOnlyTest: RUNNING...
Tests for simplified horde-ad
Short_tests
3concatBuild22: FAIL
Exception: fromVector: rank mismatch (9,0)
CallStack (from HasCallStack):
error, called at ./Data/Array/Internal/RankedG.hs:152:45 in orthotope-0.1.6.0-d5eafb3329d4001e31e883540011090b1202463d41446e08b8b1a45899a51b89:Data.Array.Internal.RankedG
fromVector, called at ./Data/Array/Internal/RankedS.hs:133:21 in orthotope-0.1.6.0-d5eafb3329d4001e31e883540011090b1202463d41446e08b8b1a45899a51b89:Data.Array.Internal.RankedS
```
The following commit reverts a half of the commit above and makes the problem go away.
https://github.com/Mikolaj/horde-ad/commit/eed4f96ddd72e8c97f958196721b42c9fba9e68c
I haven't made any more minimization. I haven't tested with the typing plugins versions that are not yet on Hackage. We don't have `-fno-polymorphic-specialisation` in GHC 9.4, so I couldn't test if it prevents the problem.
CC: @christiaanbZubinZubinhttps://gitlab.haskell.org/ghc/ghc/-/issues/23761ImplicitParams gives wrong result when used in a constraint tuple on GHC 9.8....2023-08-08T16:57:55ZChristiaan BaaijImplicitParams gives wrong result when used in a constraint tuple on GHC 9.8.1-alpha1## Summary
ImplicitParams returns the wrong result when the IP constraint is part of a constraint tuple.
This failure appeared in GHC 9.8.1-alpha1 and does not seem to be present in earlier versions of GHC.
## Steps to reproduce
The f...## Summary
ImplicitParams returns the wrong result when the IP constraint is part of a constraint tuple.
This failure appeared in GHC 9.8.1-alpha1 and does not seem to be present in earlier versions of GHC.
## Steps to reproduce
The following program returns the wrong result on GHC 9.8.1-alpha1
```haskell
{-# LANGUAGE ImplicitParams #-}
module Main where
type IPInt =
( ?ipInt :: Int
, (Int ~ Int) -- Comment this out and main prints 7 instead of 3
)
hasIPInt ::
IPInt =>
Int
hasIPInt = ?ipInt
addToIPInt
:: forall r
. IPInt
=> Int
-> (IPInt => r)
-> r
addToIPInt = \en f -> addToIPInt0 ?ipInt en f
where
addToIPInt0
:: Int
-> Int
-> (IPInt => r)
-> r
addToIPInt0 gen en f =
let ?ipInt = gen + en
in f
main :: IO ()
main = print (let ?ipInt = 3 in addToIPInt 4 hasIPInt)
```
## Expected behavior
The expected output is `7`, but the program returns `3`.
## Environment
* GHC version used: 9.8.1-alpha1
Optional:
* Operating System: Linux (Ubuntu 22.04.2 LTS)
* System Architecture: x86_649.8.1sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.com