GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2023-02-20T02:32:24Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/5926Add strict versions of modifyIORef and atomicModifyIORef2023-02-20T02:32:24ZjoeyadamsAdd strict versions of modifyIORef and atomicModifyIORefIt is easy to misuse modifyIORef and atomicModifyIORef due to their lack of strictness. For example, if you use an IORef as a counter, use modifyIORef to increment it, and never evaluate the value until the very end, your program will le...It is easy to misuse modifyIORef and atomicModifyIORef due to their lack of strictness. For example, if you use an IORef as a counter, use modifyIORef to increment it, and never evaluate the value until the very end, your program will leak memory, and you may even get a stack overflow:
```
ref <- newIORef 0
replicateM_ 1000000 $ modifyIORef ref (+1)
readIORef ref >>= print
```
Today, I found a [space leak in the tls package](https://github.com/vincenthz/hs-tls/pull/8). Repeatedly calling sendData would leak memory. It didn't take me long to find the cause once I noticed a module named "Measurement" used for gathering connection statistics. It used modifyIORef to update the Measurement structure. When I changed it to this:
```
x <- readIORef (ctxMeasurement ctx)
writeIORef (ctxMeasurement ctx) $! f x
```
the space leak went away.
A more subtle mistake can be made using atomicModifyIORef. Can you spot the problem with this code?
```
atomicModifyIORef ref (\_ -> (new_value, ()))
```
It's not incrementing anything, it's just replacing the value. However, it's still deferring evaluation of the function. This mistake was pointed out in [The Monad.Reader Issue 19](http://themonadreader.files.wordpress.com/2011/10/issue19.pdf), where they suggested the following idiom:
```
x <- atomicModifyIORef ref (\_ -> (new_value, ()))
x `seq` return ()
```
Thus, I believe there should be strict variants of modifyIORef and atomicModifyIORef, if only to warn programmers of these pitfalls.
`modifyIORef'` is pretty straightforward: force the result of applying the function:
```
modifyIORef' ref f = do
x <- readIORef ref
let x' = f x
x' `seq` writeIORef ref x'
```
The only question is: would it be better to force `x'` after `writeIORef` instead of before it, in case a caller is trying to share the IORef among threads (which they shouldn't be)?
`atomicModifyIORef` is less straightforward. Should we force the values themselves? It is possible to avoid the space leak above without forcing either the new value or the return value:
```
atomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b
atomicModifyIORef' ref f = do
p <- atomicModifyIORef ref (\a -> let p = f a in (fst p, p))
p `seq` return (snd p)
```
It also allows `f` to decide what to force. For example, with this definition of atomicModifyIORef', the following program prints 10000000 and does not leak memory:
```
ref <- newIORef 0
replicateM_ 10000000 $
atomicModifyIORef' ref
(\n -> let n' = n + 1
in n' `seq` (n', undefined))
readIORef ref >>= print
```
In the attached patch, I didn't implement atomicModifyIORef' this way. Instead, I made it force both the old and new values, and added a separate function called atomicWriteIORef that has the same signature as writeIORef, but is based on atomicModifyIORef.
I believe the real value of such functions is to warn programmers about these pitfalls.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.4.1 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Add strict versions of modifyIORef and atomicModifyIORef","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"It is easy to misuse modifyIORef and atomicModifyIORef due to their lack of strictness. For example, if you use an IORef as a counter, use modifyIORef to increment it, and never evaluate the value until the very end, your program will leak memory, and you may even get a stack overflow:\r\n\r\n{{{\r\nref <- newIORef 0\r\nreplicateM_ 1000000 $ modifyIORef ref (+1)\r\nreadIORef ref >>= print\r\n}}}\r\n\r\nToday, I found a [https://github.com/vincenthz/hs-tls/pull/8 space leak in the tls package]. Repeatedly calling sendData would leak memory. It didn't take me long to find the cause once I noticed a module named \"Measurement\" used for gathering connection statistics. It used modifyIORef to update the Measurement structure. When I changed it to this:\r\n\r\n{{{\r\nx <- readIORef (ctxMeasurement ctx)\r\nwriteIORef (ctxMeasurement ctx) $! f x\r\n}}}\r\n\r\nthe space leak went away.\r\n\r\nA more subtle mistake can be made using atomicModifyIORef. Can you spot the problem with this code?\r\n\r\n{{{\r\natomicModifyIORef ref (\\_ -> (new_value, ()))\r\n}}}\r\n\r\nIt's not incrementing anything, it's just replacing the value. However, it's still deferring evaluation of the function. This mistake was pointed out in [http://themonadreader.files.wordpress.com/2011/10/issue19.pdf The Monad.Reader Issue 19], where they suggested the following idiom:\r\n\r\n{{{\r\nx <- atomicModifyIORef ref (\\_ -> (new_value, ()))\r\nx `seq` return ()\r\n}}}\r\n\r\nThus, I believe there should be strict variants of modifyIORef and atomicModifyIORef, if only to warn programmers of these pitfalls.\r\n\r\n{{{modifyIORef'}}} is pretty straightforward: force the result of applying the function:\r\n\r\n{{{\r\nmodifyIORef' ref f = do\r\n x <- readIORef ref\r\n let x' = f x\r\n x' `seq` writeIORef ref x'\r\n}}}\r\n\r\nThe only question is: would it be better to force `x'` after `writeIORef` instead of before it, in case a caller is trying to share the IORef among threads (which they shouldn't be)?\r\n\r\n{{{atomicModifyIORef}}} is less straightforward. Should we force the values themselves? It is possible to avoid the space leak above without forcing either the new value or the return value:\r\n\r\n{{{\r\natomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b\r\natomicModifyIORef' ref f = do\r\n p <- atomicModifyIORef ref (\\a -> let p = f a in (fst p, p))\r\n p `seq` return (snd p)\r\n}}}\r\n\r\nIt also allows {{{f}}} to decide what to force. For example, with this definition of atomicModifyIORef', the following program prints 10000000 and does not leak memory:\r\n\r\n{{{\r\nref <- newIORef 0\r\nreplicateM_ 10000000 $\r\n atomicModifyIORef' ref\r\n (\\n -> let n' = n + 1\r\n in n' `seq` (n', undefined))\r\nreadIORef ref >>= print\r\n}}}\r\n\r\nIn the attached patch, I didn't implement atomicModifyIORef' this way. Instead, I made it force both the old and new values, and added a separate function called atomicWriteIORef that has the same signature as writeIORef, but is based on atomicModifyIORef.\r\n\r\nI believe the real value of such functions is to warn programmers about these pitfalls.","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/915Implement list fusion using streams instead of foldr/build2022-11-15T13:03:53ZSimon Peyton JonesImplement list fusion using streams instead of foldr/buildWe'd like to try using the stream-fusion idea of Don Stewart, Duncan Coutts and Roman Leshchinskiy, and replace the (somewhat fragile) foldr/build stuff.
See #876.
<details><summary>Trac metadata</summary>
| Trac field | V...We'd like to try using the stream-fusion idea of Don Stewart, Duncan Coutts and Roman Leshchinskiy, and replace the (somewhat fragile) foldr/build stuff.
See #876.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.4.2 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown |
| Architecture | Unknown |
</details>
<!-- {"blocked_by":[],"summary":"Implement list fusion using streams instead of foldr/build","status":"New","operating_system":"Unknown","component":"libraries/base","related":[],"milestone":"6.8 branch","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.4.2","keywords":[],"differentials":[],"test_case":"","architecture":"Unknown","cc":[""],"type":"Task","description":"We'd like to try using the stream-fusion idea of Don Stewart, Duncan Coutts and Roman Leshchinskiy, and replace the (somewhat fragile) foldr/build stuff.\r\n\r\nSee #876.","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/7094Irrefutable pattern failed for pattern Data.Maybe.Just2022-04-29T10:39:00ZpganelinIrrefutable pattern failed for pattern Data.Maybe.JustThe following invalid program causes ghc panic
```
-----------------------
--State-Monad.hs
data Term = Con Int
| Div Term Term
deriving (Show)
type M a = State -> (a,State)
type State =Int
instance Monad Int -> (a,Int) wh...The following invalid program causes ghc panic
```
-----------------------
--State-Monad.hs
data Term = Con Int
| Div Term Term
deriving (Show)
type M a = State -> (a,State)
type State =Int
instance Monad Int -> (a,Int) where
g >>= f = undefined
return = undefined
-------------------------------
```
```
D:\>"C:\Free\Haskell Platform\2012.2.0.0\bin\ghc.exe" D:\State-Monad.hs
[1 of 1] Compiling Main ( D:\State-Monad.hs, D:\State-Monad.o )
ghc.exe: panic! (the 'impossible' happened)
(GHC version 7.4.1 for i386-unknown-mingw32):
compiler\rename\RnSource.lhs:429:14-81: Irrefutable pattern failed for pattern Data.Maybe.Just (inst_tyvars,
_,
SrcLoc.L _ cls,
_)
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/5934ghc: panic! (the 'impossible' happened)2022-01-31T20:49:43Zguestghc: panic! (the 'impossible' happened)GHC asked me nicely to report this compile-time panic / crash.
Minimal code:
```
{-# LANGUAGE Rank2Types #-}
module Foo where
import System.Random.MWC (GenST)
run :: (forall s . GenST s) -> Int
run = 0
```
Output:
```
$ ghc Foo.hs
...GHC asked me nicely to report this compile-time panic / crash.
Minimal code:
```
{-# LANGUAGE Rank2Types #-}
module Foo where
import System.Random.MWC (GenST)
run :: (forall s . GenST s) -> Int
run = 0
```
Output:
```
$ ghc Foo.hs
[1 of 1] Compiling Foo ( Foo.hs, Foo.o )
ghc: panic! (the 'impossible' happened)
(GHC version 7.4.1 for x86_64-unknown-linux):
tcTyVarDetails
( s{tv a10F} [tv] :: ghc-prim:GHC.Prim.*{(w) tc 34d} )
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.4.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: panic! (the 'impossible' happened)","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"GHC asked me nicely to report this compile-time panic / crash.\r\n\r\nMinimal code:\r\n{{{\r\n{-# LANGUAGE Rank2Types #-}\r\n\r\nmodule Foo where\r\nimport System.Random.MWC (GenST)\r\nrun :: (forall s . GenST s) -> Int\r\nrun = 0\r\n}}}\r\n\r\nOutput:\r\n\r\n{{{\r\n$ ghc Foo.hs \r\n[1 of 1] Compiling Foo ( Foo.hs, Foo.o )\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 7.4.1 for x86_64-unknown-linux):\r\n\ttcTyVarDetails\r\n ( s{tv a10F} [tv] :: ghc-prim:GHC.Prim.*{(w) tc 34d} )\r\n\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n}}}\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/5165GHC doesn't optimize FP excess precision properly2020-09-26T19:15:02ZEdward Z. YangGHC doesn't optimize FP excess precision properlyjmcarthur helped in constructing the test case. Consider the following program:
```
module Main where
{-# NOINLINE x #-}
{-# NOINLINE y #-}
x, y :: Double
x = 3
y = 7
main = print $ x/y == (3/7 :: Double)
```
When run on 32-bit Linux...jmcarthur helped in constructing the test case. Consider the following program:
```
module Main where
{-# NOINLINE x #-}
{-# NOINLINE y #-}
x, y :: Double
x = 3
y = 7
main = print $ x/y == (3/7 :: Double)
```
When run on 32-bit Linux, we get the following results:
```
ezyang@javelin:~$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.0.3
ezyang@javelin:~$ ghc --make Bar.hs -o Bar -O0 -fforce-recomp && ./Bar
[1 of 1] Compiling Main ( Bar.hs, Bar.o )
Linking Bar ...
True
ezyang@javelin:~$ ghc --make Bar.hs -o Bar -O -fforce-recomp && ./Bar
[1 of 1] Compiling Main ( Bar.hs, Bar.o )
Linking Bar ...
False
```
The second result should be True (and only false if `-fexcess-precision` is specified). I also tested on a devel2 build of GHC HEAD and got similar results.
This appears to be a regression from 6.12.1:
```
ezyang@javelin:~$ /usr/bin/ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.12.1
ezyang@javelin:~$ /usr/bin/ghc --make Bar.hs -o Bar -O && ./Bar
True
```
I also kind of suspect `-fexcess-precision` doesn't do anything for the native codegen (based on source code surfing), but it's hard to tell with this current bug.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.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 doesn't optimize FP excess precision properly","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"jmcarthur helped in constructing the test case. Consider the following program:\r\n\r\n{{{\r\nmodule Main where\r\n\r\n{-# NOINLINE x #-}\r\n{-# NOINLINE y #-}\r\nx, y :: Double\r\nx = 3\r\ny = 7\r\n\r\nmain = print $ x/y == (3/7 :: Double)\r\n}}}\r\n\r\nWhen run on 32-bit Linux, we get the following results:\r\n\r\n{{{\r\nezyang@javelin:~$ ghc --version\r\nThe Glorious Glasgow Haskell Compilation System, version 7.0.3\r\nezyang@javelin:~$ ghc --make Bar.hs -o Bar -O0 -fforce-recomp && ./Bar\r\n[1 of 1] Compiling Main ( Bar.hs, Bar.o )\r\nLinking Bar ...\r\nTrue\r\nezyang@javelin:~$ ghc --make Bar.hs -o Bar -O -fforce-recomp && ./Bar\r\n[1 of 1] Compiling Main ( Bar.hs, Bar.o )\r\nLinking Bar ...\r\nFalse\r\n}}}\r\n\r\nThe second result should be True (and only false if `-fexcess-precision` is specified). I also tested on a devel2 build of GHC HEAD and got similar results.\r\n\r\nThis appears to be a regression from 6.12.1:\r\n\r\n{{{\r\nezyang@javelin:~$ /usr/bin/ghc --version\r\nThe Glorious Glasgow Haskell Compilation System, version 6.12.1\r\nezyang@javelin:~$ /usr/bin/ghc --make Bar.hs -o Bar -O && ./Bar\r\nTrue\r\n}}}\r\n\r\nI also kind of suspect `-fexcess-precision` doesn't do anything for the native codegen (based on source code surfing), but it's hard to tell with this current bug.","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/1161Clean up the library testing story2019-07-07T19:15:01ZSimon MarlowClean up the library testing storyOur story for testing libraries is in disarray, and needs cleaning up. Tests for libraries can now be placed in the repositories with the libraries themselves, and these tests are picked up when you say `make` in `testsuite/tests/ghc-reg...Our story for testing libraries is in disarray, and needs cleaning up. Tests for libraries can now be placed in the repositories with the libraries themselves, and these tests are picked up when you say `make` in `testsuite/tests/ghc-regress`.
The following tests need to be moved into their respective packages, and in some cases given appropriate .T scripts:
- everything in `testsuite/tests/libraries`
- everything in `testsuite/tests/ghc-regress/lib`
tests that are package-specific but are really GHC regression tests should stay in the testsuite, and use the `reqlib` option.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.7 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Test Suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown |
| Architecture | Unknown |
</details>
<!-- {"blocked_by":[],"summary":"Clean up the library testing story","status":"New","operating_system":"Unknown","component":"Test Suite","related":[],"milestone":"6.8 branch","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.7","keywords":[],"differentials":[],"test_case":"","architecture":"Unknown","cc":[""],"type":"Task","description":"Our story for testing libraries is in disarray, and needs cleaning up. Tests for libraries can now be placed in the repositories with the libraries themselves, and these tests are picked up when you say `make` in `testsuite/tests/ghc-regress`.\r\n\r\nThe following tests need to be moved into their respective packages, and in some cases given appropriate .T scripts:\r\n\r\n * everything in `testsuite/tests/libraries`\r\n * everything in `testsuite/tests/ghc-regress/lib`\r\n\r\ntests that are package-specific but are really GHC regression tests should stay in the testsuite, and use the `reqlib` option.","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1pcapriottipcapriottihttps://gitlab.haskell.org/ghc/ghc/-/issues/1816Add Data.Set.mapMaybe2019-07-07T19:11:36ZguestAdd Data.Set.mapMaybeThis function is also available for lists (from Data.Maybe) and Maps (Data.Set).
The semantics are straightforward:
```
mapMaybe f = fromList . catMaybes . map f . toList
```
<details><summary>Trac metadata</summary>
| Trac field ...This function is also available for lists (from Data.Maybe) and Maps (Data.Set).
The semantics are straightforward:
```
mapMaybe f = fromList . catMaybes . map f . toList
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.8 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown |
| Architecture | Unknown |
</details>
<!-- {"blocked_by":[],"summary":"Add Data.Set.mapMaybe","status":"New","operating_system":"Unknown","component":"libraries/base","related":[],"milestone":"Not GHC","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.8","keywords":[],"differentials":[],"test_case":"","architecture":"Unknown","cc":[""],"type":"Bug","description":"This function is also available for lists (from Data.Maybe) and Maps (Data.Set).\r\nThe semantics are straightforward:\r\n{{{\r\nmapMaybe f = fromList . catMaybes . map f . toList\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1milanmilanhttps://gitlab.haskell.org/ghc/ghc/-/issues/2021let ghc find framework header files and link with frameworks located in $HOME...2019-07-07T19:10:34ZChristian Maederlet ghc find framework header files and link with frameworks located in $HOME/Library/FrameworksAs described in ticket #1395 I want ghc to be able to work with my local frameworks. Therefore I've extended the file `compiler/main/DriverPipeline.hs`.
In my latest (attached) version I've also removed a few duplications.
I've conside...As described in ticket #1395 I want ghc to be able to work with my local frameworks. Therefore I've extended the file `compiler/main/DriverPipeline.hs`.
In my latest (attached) version I've also removed a few duplications.
I've considered to check if the directory `$HOME/Library/Frameworks` exists using `doesDirectoryExist`, but that's done anyway by gcc and ld on mac. I've also considered to only pass
`"-F$HOME/Library/Frameworks"` if there are `-framework` flags on the command line at all, but this did not work for `HsReadline_cbits.c`:
```
../../compiler/stage1/ghc-inplace -Iinclude -package base-3.0.1.0 -package process-1.0.0.0 -optc-O2 -odir dist/build -c HsReadline_cbits.c -o dist/build/HsReadline_cbits.o
In file included from HsReadline_cbits.c:1:0:
include/HsReadline.h:7:43:
error: GNUreadline/readline/readline.h: No such file or directory
include/HsReadline.h:8:42:
error: GNUreadline/readline/history.h: No such file or directory
HsReadline_cbits.c: In function 'hs_rl_message':
HsReadline_cbits.c:5:0:
warning: implicit declaration of function 'rl_message'
make[2]: *** [dist/build/HsReadline_cbits.o] Error 1
make[1]: *** [make.library.readline] Error 2
make: *** [stage1] Error 2
```
This (single) case may be fixed by passing "`-F$HOME/Library/Frameworks`" manually, but what is the risk of passing "`-F$HOME/Library/Frameworks`" always? Well, someone may have spoiled frameworks there, but even that is no problem as long as they are not used, because dylibs are used instead. Of course other C-compilers may not like the -F flag (in fact that is a problem if ghc is used as C-compiler and was actually bad for hsc2hs #1395).
Maybe configure should check if gcc understands -F on macs? What do others think? Would you commit my `DriverPipeline.hs` changes?
A `"diff -u -w"` currently looks as follows:
```
+++ compiler/main/DriverPipeline.hs 2008-01-07 14:39:12.000000000 +0100
@@ -822,6 +822,9 @@
let include_paths = foldr (\ x xs -> "-I" : x : xs) []
(cmdline_include_paths ++ pkg_include_dirs)
+#ifdef darwin_TARGET_OS
+ framework_path_opts <- getFrameworkPathOpts dflags pkgs
+#endif
let (md_c_flags, md_regd_c_flags) = machdepCCOpts dflags
gcc_extra_viac_flags <- getExtraViaCOpts dflags
let pic_c_flags = picCCOpts dflags
@@ -905,6 +908,9 @@
++ cc_opts
++ split_opt
++ include_paths
+#ifdef darwin_TARGET_OS
+ ++ framework_path_opts
+#endif
++ pkg_extra_cc_opts
))
@@ -1199,17 +1205,10 @@
pkg_link_opts <- getPackageLinkOpts dflags dep_packages
#ifdef darwin_TARGET_OS
- pkg_framework_paths <- getPackageFrameworkPath dflags dep_packages
- let pkg_framework_path_opts = map ("-F"++) pkg_framework_paths
-
- let framework_paths = frameworkPaths dflags
- framework_path_opts = map ("-F"++) framework_paths
-
+ framework_path_opts <- getFrameworkPathOpts dflags dep_packages
pkg_frameworks <- getPackageFrameworks dflags dep_packages
- let pkg_framework_opts = concat [ ["-framework", fw] | fw <- pkg_frameworks ]
-
- let frameworks = cmdlineFrameworks dflags
- framework_opts = concat [ ["-framework", fw] | fw <- reverse frameworks ]
+ let framework_opts = concat [ ["-framework", fw]
+ | fw <- pkg_frameworks ++ reverse (cmdlineFrameworks dflags) ]
-- reverse because they're added in reverse order from the cmd line
#endif
@@ -1264,10 +1263,6 @@
#endif
++ pkg_lib_path_opts
++ pkg_link_opts
-#ifdef darwin_TARGET_OS
- ++ pkg_framework_path_opts
- ++ pkg_framework_opts
-#endif
++ debug_opts
++ thread_opts
))
@@ -1278,6 +1273,15 @@
if success then return ()
else throwDyn (InstallationError ("cannot move binary to PVM dir")))
+-- options to pass to gcc and ld on macs only
+getFrameworkPathOpts :: DynFlags -> [PackageId] -> IO [String]
+getFrameworkPathOpts dflags pkgs = do
+ ps <- getPackageFrameworkPath dflags pkgs
+ let fps = ps ++ frameworkPaths dflags
+ eitherDir <- IO.try getHomeDirectory
+ return $ map ("-F" ++) $ case eitherDir of
+ Left _ -> fps
+ Right hdir -> (hdir ++ "/Library/Frameworks") : fps
exeFileName :: DynFlags -> FilePath
exeFileName dflags
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.8.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | Multiple |
</details>
<!-- {"blocked_by":[],"summary":"let ghc find framework header files and link with frameworks located in $HOME/Library/Frameworks","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"Multiple","cc":[""],"type":"FeatureRequest","description":"As described in ticket #1395 I want ghc to be able to work with my local frameworks. Therefore I've extended the file `compiler/main/DriverPipeline.hs`. \r\n\r\nIn my latest (attached) version I've also removed a few duplications.\r\n\r\nI've considered to check if the directory `$HOME/Library/Frameworks` exists using `doesDirectoryExist`, but that's done anyway by gcc and ld on mac. I've also considered to only pass \r\n`\"-F$HOME/Library/Frameworks\"` if there are `-framework` flags on the command line at all, but this did not work for `HsReadline_cbits.c`:\r\n\r\n{{{\r\n../../compiler/stage1/ghc-inplace -Iinclude -package base-3.0.1.0 -package process-1.0.0.0 -optc-O2 -odir dist/build -c HsReadline_cbits.c -o dist/build/HsReadline_cbits.o\r\n\r\nIn file included from HsReadline_cbits.c:1:0:\r\n\r\ninclude/HsReadline.h:7:43:\r\n error: GNUreadline/readline/readline.h: No such file or directory\r\n\r\ninclude/HsReadline.h:8:42:\r\n error: GNUreadline/readline/history.h: No such file or directory\r\nHsReadline_cbits.c: In function 'hs_rl_message':\r\n\r\nHsReadline_cbits.c:5:0:\r\n warning: implicit declaration of function 'rl_message'\r\nmake[2]: *** [dist/build/HsReadline_cbits.o] Error 1\r\nmake[1]: *** [make.library.readline] Error 2\r\nmake: *** [stage1] Error 2\r\n}}}\r\n\r\nThis (single) case may be fixed by passing \"`-F$HOME/Library/Frameworks`\" manually, but what is the risk of passing \"`-F$HOME/Library/Frameworks`\" always? Well, someone may have spoiled frameworks there, but even that is no problem as long as they are not used, because dylibs are used instead. Of course other C-compilers may not like the -F flag (in fact that is a problem if ghc is used as C-compiler and was actually bad for hsc2hs #1395). \r\n\r\nMaybe configure should check if gcc understands -F on macs? What do others think? Would you commit my `DriverPipeline.hs` changes?\r\n\r\nA `\"diff -u -w\"` currently looks as follows:\r\n{{{\r\n+++ compiler/main/DriverPipeline.hs 2008-01-07 14:39:12.000000000 +0100\r\n@@ -822,6 +822,9 @@\r\n let include_paths = foldr (\\ x xs -> \"-I\" : x : xs) []\r\n (cmdline_include_paths ++ pkg_include_dirs)\r\n\r\n+#ifdef darwin_TARGET_OS\r\n+ framework_path_opts <- getFrameworkPathOpts dflags pkgs\r\n+#endif\r\n let (md_c_flags, md_regd_c_flags) = machdepCCOpts dflags\r\n gcc_extra_viac_flags <- getExtraViaCOpts dflags\r\n let pic_c_flags = picCCOpts dflags\r\n@@ -905,6 +908,9 @@\r\n ++ cc_opts\r\n ++ split_opt\r\n ++ include_paths\r\n+#ifdef darwin_TARGET_OS\r\n+ ++ framework_path_opts\r\n+#endif\r\n ++ pkg_extra_cc_opts\r\n ))\r\n\r\n@@ -1199,17 +1205,10 @@\r\n pkg_link_opts <- getPackageLinkOpts dflags dep_packages\r\n\r\n #ifdef darwin_TARGET_OS\r\n- pkg_framework_paths <- getPackageFrameworkPath dflags dep_packages\r\n- let pkg_framework_path_opts = map (\"-F\"++) pkg_framework_paths\r\n-\r\n- let framework_paths = frameworkPaths dflags\r\n- framework_path_opts = map (\"-F\"++) framework_paths\r\n-\r\n+ framework_path_opts <- getFrameworkPathOpts dflags dep_packages\r\n pkg_frameworks <- getPackageFrameworks dflags dep_packages\r\n- let pkg_framework_opts = concat [ [\"-framework\", fw] | fw <- pkg_frameworks ]\r\n-\r\n- let frameworks = cmdlineFrameworks dflags\r\n- framework_opts = concat [ [\"-framework\", fw] | fw <- reverse frameworks ]\r\n+ let framework_opts = concat [ [\"-framework\", fw]\r\n+ | fw <- pkg_frameworks ++ reverse (cmdlineFrameworks dflags) ]\r\n -- reverse because they're added in reverse order from the cmd line\r\n #endif\r\n\r\n@@ -1264,10 +1263,6 @@\r\n #endif\r\n ++ pkg_lib_path_opts\r\n ++ pkg_link_opts\r\n-#ifdef darwin_TARGET_OS\r\n- ++ pkg_framework_path_opts\r\n- ++ pkg_framework_opts\r\n-#endif\r\n ++ debug_opts\r\n ++ thread_opts\r\n ))\r\n@@ -1278,6 +1273,15 @@\r\n if success then return ()\r\n else throwDyn (InstallationError (\"cannot move binary to PVM dir\")))\r\n\r\n+-- options to pass to gcc and ld on macs only\r\n+getFrameworkPathOpts :: DynFlags -> [PackageId] -> IO [String]\r\n+getFrameworkPathOpts dflags pkgs = do\r\n+ ps <- getPackageFrameworkPath dflags pkgs\r\n+ let fps = ps ++ frameworkPaths dflags\r\n+ eitherDir <- IO.try getHomeDirectory\r\n+ return $ map (\"-F\" ++) $ case eitherDir of\r\n+ Left _ -> fps\r\n+ Right hdir -> (hdir ++ \"/Library/Frameworks\") : fps\r\n\r\n exeFileName :: DynFlags -> FilePath\r\n exeFileName dflags\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/2078INLINE and strictness2019-07-07T19:10:18ZSimon Peyton JonesINLINE and strictnessConsider this code
```
module A where
{-# INLINE [0] foo #-}
{#- RULE foo (reverse xs) = xs #-}
foo xs = reverse $ xs
module B where
import A( foo )
g b ys = foo (case b of
True -> reverse ys
...Consider this code
```
module A where
{-# INLINE [0] foo #-}
{#- RULE foo (reverse xs) = xs #-}
foo xs = reverse $ xs
module B where
import A( foo )
g b ys = foo (case b of
True -> reverse ys
False -> ys)
h xs = map foo xs
```
At the moment the body of `foo` is not optimised at all, because it's going to be inlined. But that means that
- The `foo` executed by the `map` in `h` is very inefficient, because it actually calls `$` etc.
- The strictness analyser doesn't see that `foo` is strict, because again the `$` gets in the way. So the rule for `foo` does not match in the RHS of `g`. (If `foo` were strict, we'd push the call to `foo` inside the case branches.)
For both reasons it'd be better to
- Retain the original RHS of `foo` for inlining purposes
- But otherwise optimise `foo` normally, so that if it is not inlined, we get the efficient version, and so that strictness analysis does the right thing.
Hmm. Maybe INLINE should turn into a RULE, rather than (as now) a `Note` in Core?
Anyway, this ticket is to make sure I don't forget this point.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------- |
| Version | 6.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | ndp@cse.unsw.edu.au |
| Operating system | Unknown |
| Architecture | Unknown |
</details>
<!-- {"blocked_by":[],"summary":"INLINE and strictness","status":"New","operating_system":"Unknown","component":"Compiler","related":[],"milestone":"6.10 branch","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonpj"},"version":"6.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"Unknown","cc":["ndp@cse.unsw.edu.au"],"type":"Bug","description":"Consider this code \r\n{{{\r\nmodule A where\r\n {-# INLINE [0] foo #-}\r\n {#- RULE foo (reverse xs) = xs #-}\r\n foo xs = reverse $ xs\r\n\r\nmodule B where\r\n import A( foo )\r\n g b ys = foo (case b of \r\n True -> reverse ys\r\n False -> ys)\r\n\r\n h xs = map foo xs\r\n}}}\r\nAt the moment the body of `foo` is not optimised at all, because it's going to be inlined. But that means that\r\n\r\n * The `foo` executed by the `map` in `h` is very inefficient, because it actually calls `$` etc.\r\n\r\n * The strictness analyser doesn't see that `foo` is strict, because again the `$` gets in the way. So the rule for `foo` does not match in the RHS of `g`. (If `foo` were strict, we'd push the call to `foo` inside the case branches.)\r\n\r\nFor both reasons it'd be better to \r\n * Retain the original RHS of `foo` for inlining purposes\r\n * But otherwise optimise `foo` normally, so that if it is not inlined, we get the efficient version, and so that strictness analysis does the right thing.\r\n\r\nHmm. Maybe INLINE should turn into a RULE, rather than (as now) a `Note` in Core?\r\n\r\nAnyway, this ticket is to make sure I don't forget this point.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/2253Native code generator could do better2019-07-07T19:09:29ZdonsNative code generator could do betterAn example set of programs that came up in the ndp library, where the C backend outperforms
the current native code generator. Logging them here so we don't forget to check again with
the new backend.
## Program 1
```
import Data.Array...An example set of programs that came up in the ndp library, where the C backend outperforms
the current native code generator. Logging them here so we don't forget to check again with
the new backend.
## Program 1
```
import Data.Array.Vector
import Data.Bits
main = print . sumU $ zipWith3U (\x y z -> x * y * z)
(enumFromToU 1 (100000000 :: Int))
(enumFromToU 2 (100000001 :: Int))
(enumFromToU 7 (100000008 :: Int))
```
Core:
```
Main.$s$wfold =
\ (sc_sPH :: Int#)
(sc1_sPI :: Int#)
(sc2_sPJ :: Int#)
(sc3_sPK :: Int#) ->
case ># sc2_sPJ 100000000 of wild_aJo {
False ->
case ># sc1_sPI 100000001 of wild1_XK6 {
False ->
case ># sc_sPH 100000008 of wild2_XKd {
False ->
Main.$s$wfold
(+# sc_sPH 1)
(+# sc1_sPI 1)
(+# sc2_sPJ 1)
(+# sc3_sPK (*# (*# sc2_sPJ sc1_sPI) sc_sPH));
True -> sc3_sPK
};
True -> sc3_sPK
};
True -> sc3_sPK
}
```
}
Which is great.
C backend:
```
Main_zdszdwfold_info:
.text
.p2align 4,,15
.text
.align 8
.type Main_zdszdwfold_info, @function
cmpq $100000000, %r8
jg .L9
cmpq $100000001, %rdi
jg .L9
cmpq $100000008, %rsi
jg .L9
movq %r8, %rdx
incq %r8
imulq %rdi, %rdx
incq %rdi
imulq %rsi, %rdx
incq %rsi
addq %rdx, %r9
jmp Main_zdszdwfold_info
.L5:
.L7:
.p2align 6,,7
.L9:
movq %r9, %rbx
jmp *(%rbp)
```
Native code generator:
```
Main_zdszdwfold_info:
cmpq $100000000,%r8
jg .LcRP
cmpq $100000001,%rdi
jg .LcRR
cmpq $100000008,%rsi
jg .LcRU
movq %rdi,%rax
imulq %rsi,%rax
movq %r8,%rcx
imulq %rax,%rcx
movq %r9,%rax
addq %rcx,%rax
leaq 1(%r8),%rcx
leaq 1(%rdi),%rdx
incq %rsi
movq %rdx,%rdi
movq %rcx,%r8
movq %rax,%r9
jmp Main_zdszdwfold_info
.LcRP:
movq %r9,%rbx
jmp *(%rbp)
.LcRR:
movq %r9,%rbx
jmp *(%rbp)
.LcRU:
movq %r9,%rbx
jmp *(%rbp)
```
Runtime performance:
> C backend: 0.269
> Asm backend: 0.410s
## Program 2
Source:
```
import Data.Array.Vector
import Data.Bits
main = print . sumU . mapU (`shiftL` 2) $
appendU (replicateU 1000000000 (1::Int))
(replicateU 1000000000 (7::Int))
```
Core:
```
$s$wfold_rPr =
\ (sc_sOw :: Int#) (sc1_sOx :: Int#) ->
case sc_sOw of wild_X1j {
__DEFAULT -> $s$wfold_rPr (+# wild_X1j 1) (+# sc1_sOx 28);
1000000000 -> sc1_sOx
}
```
Runtime:
Native backend: 2.637
> C backend: 2.365
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------- |
| Version | 6.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (NCG) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | dons@galois.com |
| Operating system | Unknown |
| Architecture | x86_64 (amd64) |
</details>
<!-- {"blocked_by":[],"summary":"Native code generator could do better","status":"New","operating_system":"Unknown","component":"Compiler (NCG)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"x86_64 (amd64)","cc":["dons@galois.com"],"type":"Bug","description":"An example set of programs that came up in the ndp library, where the C backend outperforms\r\nthe current native code generator. Logging them here so we don't forget to check again with\r\nthe new backend.\r\n\r\n== Program 1 ==\r\n\r\n{{{\r\n\r\nimport Data.Array.Vector\r\nimport Data.Bits\r\nmain = print . sumU $ zipWith3U (\\x y z -> x * y * z)\r\n (enumFromToU 1 (100000000 :: Int))\r\n (enumFromToU 2 (100000001 :: Int))\r\n (enumFromToU 7 (100000008 :: Int))\r\n\r\n}}}\r\n\r\nCore:\r\n\r\n{{{\r\n\r\nMain.$s$wfold =\r\n \\ (sc_sPH :: Int#)\r\n (sc1_sPI :: Int#)\r\n (sc2_sPJ :: Int#)\r\n (sc3_sPK :: Int#) ->\r\n case ># sc2_sPJ 100000000 of wild_aJo {\r\n False ->\r\n case ># sc1_sPI 100000001 of wild1_XK6 {\r\n False ->\r\n case ># sc_sPH 100000008 of wild2_XKd {\r\n False ->\r\n Main.$s$wfold\r\n (+# sc_sPH 1)\r\n (+# sc1_sPI 1)\r\n (+# sc2_sPJ 1)\r\n (+# sc3_sPK (*# (*# sc2_sPJ sc1_sPI) sc_sPH));\r\n True -> sc3_sPK\r\n };\r\n True -> sc3_sPK\r\n };\r\n True -> sc3_sPK\r\n }\r\n\r\n}}}}\r\n\r\nWhich is great.\r\n\r\nC backend:\r\n\r\n{{{\r\n\r\nMain_zdszdwfold_info:\r\n .text\r\n .p2align 4,,15\r\n.text\r\n .align 8\r\n .type Main_zdszdwfold_info, @function\r\n cmpq $100000000, %r8\r\n jg .L9\r\n cmpq $100000001, %rdi\r\n jg .L9\r\n cmpq $100000008, %rsi\r\n jg .L9\r\n movq %r8, %rdx\r\n incq %r8\r\n imulq %rdi, %rdx\r\n incq %rdi\r\n imulq %rsi, %rdx\r\n incq %rsi\r\n addq %rdx, %r9\r\n jmp Main_zdszdwfold_info\r\n.L5:\r\n.L7:\r\n .p2align 6,,7\r\n.L9:\r\n movq %r9, %rbx\r\n jmp *(%rbp)\r\n\r\n\r\n}}}\r\n\r\n\r\nNative code generator:\r\n\r\n\r\n{{{\r\n\r\nMain_zdszdwfold_info:\r\n cmpq $100000000,%r8\r\n jg .LcRP\r\n cmpq $100000001,%rdi\r\n jg .LcRR\r\n cmpq $100000008,%rsi\r\n jg .LcRU\r\n movq %rdi,%rax\r\n imulq %rsi,%rax\r\n movq %r8,%rcx\r\n imulq %rax,%rcx\r\n movq %r9,%rax\r\n addq %rcx,%rax\r\n leaq 1(%r8),%rcx\r\n leaq 1(%rdi),%rdx\r\n incq %rsi\r\n movq %rdx,%rdi\r\n movq %rcx,%r8\r\n movq %rax,%r9\r\n jmp Main_zdszdwfold_info\r\n.LcRP:\r\n movq %r9,%rbx\r\n jmp *(%rbp)\r\n.LcRR:\r\n movq %r9,%rbx\r\n jmp *(%rbp)\r\n.LcRU:\r\n movq %r9,%rbx\r\n jmp *(%rbp)\r\n\r\n}}}\r\n\r\nRuntime performance:\r\n\r\n C backend: 0.269\r\n Asm backend: 0.410s\r\n\r\n\r\n== Program 2 ==\r\n\r\nSource:\r\n\r\n{{{\r\n\r\nimport Data.Array.Vector\r\nimport Data.Bits\r\nmain = print . sumU . mapU (`shiftL` 2) $\r\n appendU (replicateU 1000000000 (1::Int))\r\n (replicateU 1000000000 (7::Int))\r\n\r\n}}}\r\n\r\nCore:\r\n\r\n{{{\r\n\r\n$s$wfold_rPr =\r\n \\ (sc_sOw :: Int#) (sc1_sOx :: Int#) ->\r\n case sc_sOw of wild_X1j {\r\n __DEFAULT -> $s$wfold_rPr (+# wild_X1j 1) (+# sc1_sOx 28);\r\n 1000000000 -> sc1_sOx\r\n }\r\n}}}\r\n\r\nRuntime:\r\n\r\n Native backend: 2.637\r\n C backend: 2.365","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/2534Odd probable cause given by type checker2019-07-07T19:08:10Zred5_2@hotmail.comOdd probable cause given by type checkerIn the following code, a function has been applied to zero arguments, which the type checker suggests is too many.
```
Prelude> foldr (>>=) [] []
<interactive>:1:6:
Occurs check: cannot construct the infinite type: b = a -> b
P...In the following code, a function has been applied to zero arguments, which the type checker suggests is too many.
```
Prelude> foldr (>>=) [] []
<interactive>:1:6:
Occurs check: cannot construct the infinite type: b = a -> b
Probable cause: `>>=' is applied to too many arguments
In the first argument of `foldr', namely `(>>=)'
In the expression: foldr (>>=) [] []
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 6.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown |
| Architecture | Unknown |
</details>
<!-- {"blocked_by":[],"summary":"Odd probable cause given by type checker","status":"New","operating_system":"Unknown","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"Unknown","cc":[""],"type":"Bug","description":"In the following code, a function has been applied to zero arguments, which the type checker suggests is too many.\r\n\r\n{{{\r\nPrelude> foldr (>>=) [] []\r\n\r\n<interactive>:1:6:\r\n Occurs check: cannot construct the infinite type: b = a -> b\r\n Probable cause: `>>=' is applied to too many arguments\r\n In the first argument of `foldr', namely `(>>=)'\r\n In the expression: foldr (>>=) [] []\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/2892(threadDelay (-1)) hangs2019-07-07T19:06:23Zdancor(threadDelay (-1)) hangsthreadDelay silently hangs forever given a negative delay interval. It seems like this should at least be documented, but further is probably suboptimal magical behavior that leads to harder-to-find bugs; instead this should be an error....threadDelay silently hangs forever given a negative delay interval. It seems like this should at least be documented, but further is probably suboptimal magical behavior that leads to harder-to-find bugs; instead this should be an error. Conceivably threadDelay could take Maybe Int but that seems kind of out there.
Here is some discussion from \#haskell:
```
06:39 < dancor> do other ppl agree that (threadDelay (-1)) hanging silently is
bug?
06:39 < dancor> i guess you might want infinite hang, hm
06:39 < Cale> dancor: I think I might agree with that, though now that you
mention it, it's very handy.
06:39 < Cale> dancor: A lot of things which would cause a thread to block
forever will throw an exception and kill the thread.
06:40 < Cale> (an exception which you'd often wish were silent)
06:40 < Cale> But threadDelay is the wrong place for that
06:40 < b_jonas> dancor: yeah, the thread should just be garbage-collected
06:42 * quicksilver uses "forever (threadDelay maxBound)"
```
I'm on Debian lenny:
```
~ uname -a
Linux pima 2.6.26-1-686-bigmem #1 SMP Sat Nov 8 19:46:36 UTC 2008 i686 GNU/Linux
~ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.10.1
~ cat threadHang.hs
import Control.Concurrent
main = threadDelay (-1)
```7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/2947infix precedence of backtick functions defined in ghci is not reported by :info2019-07-07T19:06:11ZEyalLoteminfix precedence of backtick functions defined in ghci is not reported by :infoexcerpt from ghci:
```
Prelude> let infixr 9 `f` ; f = (+)
let infixr 9 `f` ; f = (+)
Prelude> 5 * 3 `f` 4
35
Prelude> :info f
f :: Integer -> Integer -> Integer
-- Defined at <interactive>:1:19
Prelude> :info `f`
f :: Integer -> Int...excerpt from ghci:
```
Prelude> let infixr 9 `f` ; f = (+)
let infixr 9 `f` ; f = (+)
Prelude> 5 * 3 `f` 4
35
Prelude> :info f
f :: Integer -> Integer -> Integer
-- Defined at <interactive>:1:19
Prelude> :info `f`
f :: Integer -> Integer -> Integer
-- Defined at <interactive>:1:19
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.10.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"infix precedence of backtick functions defined in ghci is not reported by :info","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"excerpt from ghci:\r\n{{{\r\nPrelude> let infixr 9 `f` ; f = (+)\r\nlet infixr 9 `f` ; f = (+)\r\nPrelude> 5 * 3 `f` 4\r\n35\r\nPrelude> :info f\r\nf :: Integer -> Integer -> Integer\r\n \t-- Defined at <interactive>:1:19\r\nPrelude> :info `f`\r\nf :: Integer -> Integer -> Integer\r\n \t-- Defined at <interactive>:1:19\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1pcapriottipcapriottihttps://gitlab.haskell.org/ghc/ghc/-/issues/2972ppc ghci segfaults at startup2019-07-07T19:06:04Zcemeyerppc ghci segfaults at startupGHCi works in 6.8.3, broken (segfaults on startup) in 6.10.1 on linux/ppc.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.10.1 ...GHCi works in 6.8.3, broken (segfaults on startup) in 6.10.1 on linux/ppc.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.10.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHCi broken in GHC 6.10.1","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"GHCi works in 6.8.3, broken (segfaults on startup) in 6.10.1 on linux/ppc.","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1pcapriottipcapriottihttps://gitlab.haskell.org/ghc/ghc/-/issues/2979better support for FFI C wrappers for macros in system headers2019-07-07T19:06:01Zduncanbetter support for FFI C wrappers for macros in system headersOften C functions get defined via macros on some systems. For example iconv gets munged and renamed by some silly macros on OSX. This messes up the iconv binding package (and haskeline which currently directly ffi imports iconv rather th...Often C functions get defined via macros on some systems. For example iconv gets munged and renamed by some silly macros on OSX. This messes up the iconv binding package (and haskeline which currently directly ffi imports iconv rather than using the Haskell iconv package).
Actually making wrapper functions is harder than it should be. For one thing one has to pick a single name for the wrapper function and this then prevents loading multiple versions of a Haskell package because their C symbols will clash. We have similar problems for C snippets in other packages like bytestring, so it's not constraint to FFI wrappers.
We should think about how to make this easier. We should think about where the best place to put improvements eg ghc, cabal, c2hs or hsc2hs.
Perhaps just a way to compile versioned C function names using a CPP define for the current package name and version. Eg in the .c file:
```
int HS_VERSIONED_SYMBOL(foo_wrapper) (int blah) {
...
}
```
And similar in the .hs file where we ffi import it.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.10.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":"better support for FFI C wrappers for macros in system headers","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Often C functions get defined via macros on some systems. For example iconv gets munged and renamed by some silly macros on OSX. This messes up the iconv binding package (and haskeline which currently directly ffi imports iconv rather than using the Haskell iconv package).\r\n\r\nActually making wrapper functions is harder than it should be. For one thing one has to pick a single name for the wrapper function and this then prevents loading multiple versions of a Haskell package because their C symbols will clash. We have similar problems for C snippets in other packages like bytestring, so it's not constraint to FFI wrappers.\r\n\r\nWe should think about how to make this easier. We should think about where the best place to put improvements eg ghc, cabal, c2hs or hsc2hs.\r\n\r\nPerhaps just a way to compile versioned C function names using a CPP define for the current package name and version. Eg in the .c file:\r\n\r\n{{{\r\nint HS_VERSIONED_SYMBOL(foo_wrapper) (int blah) {\r\n ...\r\n}\r\n}}}\r\n\r\nAnd similar in the .hs file where we ffi import it.","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/3090ghc-pkg update should fail if dependent packages might break2019-07-07T19:05:27ZSimon Marlowghc-pkg update should fail if dependent packages might breakIf a package is recompiled and re-installed, and other packages depend on it, those packages might be broken; e.g. see #3060.
Hence `ghc-pkg update` should refuse to perform the update, unless explicitly overridden with `--force`. Howev...If a package is recompiled and re-installed, and other packages depend on it, those packages might be broken; e.g. see #3060.
Hence `ghc-pkg update` should refuse to perform the update, unless explicitly overridden with `--force`. However, it's not quite as simple as that:
- The package might already have been installed over the top of the old one, and
it's too late to reverse that.
- `cabal-install` likes to build and install a bunch of packages at the same time,
using `ghc-pkg update` on each one. This will fail.
- The GHC build system uses `ghc-pkg update` to register packages, and this
breaks when packages are re-built (it's ok for a clean build, though).
I've attached a couple of patches to implement it, but let's hold these back until the above issues are sorted out.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.10.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-pkg update should fail if dependent packages might break","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"If a package is recompiled and re-installed, and other packages depend on it, those packages might be broken; e.g. see #3060.\r\n\r\nHence `ghc-pkg update` should refuse to perform the update, unless explicitly overridden with `--force`. However, it's not quite as simple as that:\r\n\r\n * The package might already have been installed over the top of the old one, and\r\n it's too late to reverse that.\r\n\r\n * `cabal-install` likes to build and install a bunch of packages at the same time,\r\n using `ghc-pkg update` on each one. This will fail.\r\n\r\n * The GHC build system uses `ghc-pkg update` to register packages, and this\r\n breaks when packages are re-built (it's ok for a clean build, though).\r\n\r\nI've attached a couple of patches to implement it, but let's hold these back until the above issues are sorted out.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/3108Do a better job of solving recursive type-class constraints with functional d...2019-07-07T19:05:21ZSimon Peyton JonesDo a better job of solving recursive type-class constraints with functional dependenciesThis ticket is just to track this interesting thread on the Haskell list, concerning recursive type-class constraints:
http://www.haskell.org/pipermail/haskell/2009-March/021115.html.
We might want to get back to this when the new constr...This ticket is just to track this interesting thread on the Haskell list, concerning recursive type-class constraints:
http://www.haskell.org/pipermail/haskell/2009-March/021115.html.
We might want to get back to this when the new constraint solver is in place.
The question concerns the interaction of solving recursive type-class constraints, where it is important to aggressively apply functional dependencies. Here's Tom Schrijvers's analysis of Ralf's example:
"The cyclic dictionaries approach is a bit fragile. The problem appears to
be here that GHC alternates exhaustive phases of constraint reduction and
functional dependency improvement. The problem is that in your example you
need both for detecting a cycle.
This can happen:
```
C1 Int
==> 3rd C1 inst
C2 Int y, C1 (y,Bool)
==> 1st C1 inst
C2 Int y, C1 y, C1 Bool
==> 2nd C1 inst
C2 Int y, C1 y
==> 3rd C1 inst
C2 Int y, C2 y z, C1 (z,Bool)
==>
...
```
where all the constraint are different because fresh variables are
introduced.
What you want to happen is:
```
C1 Int
==> 3rd C1 inst
C2 Int y, C1 (y,Bool)
==> 1st C1 inst
C2 Int y, C1 y, C1 Bool
==> 2nd C1 inst
C2 Int y, C1 y
==> C2 FD improvement {Int/y} <<<<
C2 Int Int, C1 Int
==> C1 Int cycle detected
C2 Int Int
==> C2 1st instance
{}
```
It seems that you want improvement to happen at a higher priority than GHC
does now."
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 6.10.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Do a better job of solving recursive type-class constraints with functional dependencies","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"6.12 branch","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This ticket is just to track this interesting thread on the Haskell list, concerning recursive type-class constraints:\r\nhttp://www.haskell.org/pipermail/haskell/2009-March/021115.html.\r\nWe might want to get back to this when the new constraint solver is in place.\r\n\r\nThe question concerns the interaction of solving recursive type-class constraints, where it is important to aggressively apply functional dependencies. Here's Tom Schrijvers's analysis of Ralf's example:\r\n\r\n\"The cyclic dictionaries approach is a bit fragile. The problem appears to\r\nbe here that GHC alternates exhaustive phases of constraint reduction and\r\nfunctional dependency improvement. The problem is that in your example you\r\nneed both for detecting a cycle.\r\n\r\nThis can happen:\r\n{{{\r\n C1 Int\r\n ==> 3rd C1 inst\r\n C2 Int y, C1 (y,Bool)\r\n ==> 1st C1 inst\r\n C2 Int y, C1 y, C1 Bool\r\n ==> 2nd C1 inst\r\n C2 Int y, C1 y\r\n ==> 3rd C1 inst\r\n C2 Int y, C2 y z, C1 (z,Bool)\r\n ==>\r\n ...\r\n}}}\r\nwhere all the constraint are different because fresh variables are\r\nintroduced.\r\n\r\nWhat you want to happen is:\r\n{{{\r\n C1 Int\r\n ==> 3rd C1 inst\r\n C2 Int y, C1 (y,Bool)\r\n ==> 1st C1 inst\r\n C2 Int y, C1 y, C1 Bool\r\n ==> 2nd C1 inst\r\n C2 Int y, C1 y\r\n ==> C2 FD improvement {Int/y} <<<<\r\n C2 Int Int, C1 Int\r\n ==> C1 Int cycle detected\r\n C2 Int Int\r\n ==> C2 1st instance\r\n {}\r\n}}}\r\nIt seems that you want improvement to happen at a higher priority than GHC\r\ndoes now.\"\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/3160No exception safety in Control.Concurrent.QSem QSemN and SampleVar2019-07-07T19:05:05ZChrisKuklewiczNo exception safety in Control.Concurrent.QSem QSemN and SampleVarLooking at the code for QSem, QSemN, and SampleVar shows they all use a "takeMVar" then "putMVar" programming idiom.
None of these are exception safe. An unlucky killThread will leave the MVar empty and cause the rest of the program to ...Looking at the code for QSem, QSemN, and SampleVar shows they all use a "takeMVar" then "putMVar" programming idiom.
None of these are exception safe. An unlucky killThread will leave the MVar empty and cause the rest of the program to malfunction.
The solution is to rewrite them using withMVar and modifyMVar(_) to prevent the MVar from being left empty in the event of an exception.
Note: QSem also needs the bugfix in #3159
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.10.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"No exception safety in Control.Concurrent.QSem QSemN and SampleVar","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Looking at the code for QSem, QSemN, and SampleVar shows they all use a \"takeMVar\" then \"putMVar\" programming idiom.\r\n\r\nNone of these are exception safe. An unlucky killThread will leave the MVar empty and cause the rest of the program to malfunction.\r\n\r\nThe solution is to rewrite them using withMVar and modifyMVar(_) to prevent the MVar from being left empty in the event of an exception.\r\n\r\nNote: QSem also needs the bugfix in #3159","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/3202Make XNoMonomorphismRestriction the default in GHCi2019-07-07T19:04:55ZYitzGaleMake XNoMonomorphismRestriction the default in GHCiWhile it has been a subject of debate whether the
Monomorphism Restriction is helpful in compiled code,
it is quite clear that MR is a major annoyance,
if not a bug, at the GHCi prompt.
MR at the GHCi prompt makes it inconvenient
to def...While it has been a subject of debate whether the
Monomorphism Restriction is helpful in compiled code,
it is quite clear that MR is a major annoyance,
if not a bug, at the GHCi prompt.
MR at the GHCi prompt makes it inconvenient
to define functions using `let` at the prompt. It also
unexpectedly assigns monomorphic types to
expressions entered interactively by the user -
in particular when it types numeric constants
as `Integer` when the user needs an `Int`.
None of the purported benefits of MR are relevant
in GHCi. The kinds of problems that MR might help
avoid are unlikely to arise during an interactive
session, since the structure of functions entered
at the prompt is on average far less complex than
functions in source files. Any problems that do
arise will become clear as the interactive session
continues - likely with a clearer error message
(in my personal experience).
MR at the GHCi prompt is one of the most
confusing aspects of GHCi for inexperienced
users, as evidenced by constant traffic on
haskell-cafe and \#haskell.
Disabling MR at the GHCi prompt would
not be a disruptive change. It would not
change the meaning of any program.
It would improve the GHCi workflow of
inexperienced users, and probably most
experienced users. If there are any
experienced users who feel that this
change disrupts their workflow, they can
easily revert to the current behavior
by adding a single line to their `.ghci`
file.
For reference, here is a long discussion about MR
that took place on haskell-cafe a few years ago:
http://www.haskell.org/pipermail/haskell-prime/2006-January/000038.html
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.10.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Make XNoMonomorphismRestriction the default in GHCi","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"While it has been a subject of debate whether the\r\nMonomorphism Restriction is helpful in compiled code,\r\nit is quite clear that MR is a major annoyance,\r\nif not a bug, at the GHCi prompt.\r\n\r\nMR at the GHCi prompt makes it inconvenient\r\nto define functions using {{{let}}} at the prompt. It also\r\nunexpectedly assigns monomorphic types to\r\nexpressions entered interactively by the user -\r\nin particular when it types numeric constants\r\nas {{{Integer}}} when the user needs an {{{Int}}}.\r\n\r\nNone of the purported benefits of MR are relevant\r\nin GHCi. The kinds of problems that MR might help\r\navoid are unlikely to arise during an interactive\r\nsession, since the structure of functions entered\r\nat the prompt is on average far less complex than\r\nfunctions in source files. Any problems that do\r\narise will become clear as the interactive session\r\ncontinues - likely with a clearer error message\r\n(in my personal experience).\r\n\r\nMR at the GHCi prompt is one of the most\r\nconfusing aspects of GHCi for inexperienced\r\nusers, as evidenced by constant traffic on\r\nhaskell-cafe and #haskell.\r\n\r\nDisabling MR at the GHCi prompt would\r\nnot be a disruptive change. It would not\r\nchange the meaning of any program.\r\nIt would improve the GHCi workflow of\r\ninexperienced users, and probably most\r\nexperienced users. If there are any\r\nexperienced users who feel that this\r\nchange disrupts their workflow, they can\r\neasily revert to the current behavior\r\nby adding a single line to their {{{.ghci}}}\r\nfile.\r\n\r\nFor reference, here is a long discussion about MR\r\nthat took place on haskell-cafe a few years ago:\r\n\r\nhttp://www.haskell.org/pipermail/haskell-prime/2006-January/000038.html\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1pcapriottipcapriottihttps://gitlab.haskell.org/ghc/ghc/-/issues/3222GLFW 0.3 build fails w/ SSE error in 6.10.3, works in 6.10.12019-07-07T19:04:50ZGregFrascadoreGLFW 0.3 build fails w/ SSE error in 6.10.3, works in 6.10.1Using GHC 6.10.3 to build GLFW 0.3 dies with:
```
/usr/lib/gcc/i686-apple-darwin9/4.0.1/include/xmmintrin.h:35:3:
error: #error "SSE instruction set not enabled"
```
on Mac OSX 10.5.6 (intel)
By downgrading to 6.10.1 the build wor...Using GHC 6.10.3 to build GLFW 0.3 dies with:
```
/usr/lib/gcc/i686-apple-darwin9/4.0.1/include/xmmintrin.h:35:3:
error: #error "SSE instruction set not enabled"
```
on Mac OSX 10.5.6 (intel)
By downgrading to 6.10.1 the build works.
I saw some IRC chat logs where others had this problem with 6.10.2.7.6.1