GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-07T18:59:41Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/4288Poor -fspec-constr-count=n warning messages2019-07-07T18:59:41ZIan Lynagh <igloo@earth.li>Poor -fspec-constr-count=n warning messagesThe attached file, compiled with
```
ghc -O2 -fspec-constr-count=5 -ddpr-debug -c q.hs
```
gives a number of messages like
```
SpecConstr
Function `$j_X1BO{v} [lid]'
has one call pattern, but the limit is 0
Use -fspec-co...The attached file, compiled with
```
ghc -O2 -fspec-constr-count=5 -ddpr-debug -c q.hs
```
gives a number of messages like
```
SpecConstr
Function `$j_X1BO{v} [lid]'
has one call pattern, but the limit is 0
Use -fspec-constr-count=n to set the bound
Use -dppr-debug to see specialisations
SpecConstr
Function `$j_X1BR{v} [lid]'
has two call patterns, but the limit is 1
Use -fspec-constr-count=n to set the bound
Use -dppr-debug to see specialisations
```
Note that the limit doesn't match the `spec-constr-count` we set.
The "limit" given is `sc_count`, but `decreaseSpecCount` changes `sc_count` from its default of `specConstrCount dflags`. However, if this was fixed then we would get even stranger messages like
```
has two call patterns, but the limit is 5
```8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/4176reject unary minus in infix left hand side function bindings that resolve dif...2019-07-07T19:00:15ZChristian Maederreject unary minus in infix left hand side function bindings that resolve differently as expressionsa program like:
```
infix 7 ##
(##) :: Int -> Int -> Int
- 1 ## 0 = 0
_ ## _ = 1
```
evaluates (unexpectedly) as
```
*Main> - 1 ## 0
-1
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| -----...a program like:
```
infix 7 ##
(##) :: Int -> Int -> Int
- 1 ## 0 = 0
_ ## _ = 1
```
evaluates (unexpectedly) as
```
*Main> - 1 ## 0
-1
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.12.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"reject unary minus in infix left hand side function bindings that resolve differently as expressions","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.12.3","keywords":["fixity","resolution"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"a program like:\r\n\r\n{{{\r\ninfix 7 ##\r\n\r\n(##) :: Int -> Int -> Int\r\n- 1 ## 0 = 0\r\n_ ## _ = 1\r\n}}}\r\n\r\nevaluates (unexpectedly) as\r\n{{{\r\n*Main> - 1 ## 0\r\n-1\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/4162GHC API messes up signal handlers2019-07-07T19:00:20ZDaniel GorĂnGHC API messes up signal handlersA side-effect of using the `runGhc` function is that some signal handlers are modified and not restored afterwards (see function `initGhcMonad`). In particular, the handler for `SIGINT` installed by ghc throws an exception to a thread st...A side-effect of using the `runGhc` function is that some signal handlers are modified and not restored afterwards (see function `initGhcMonad`). In particular, the handler for `SIGINT` installed by ghc throws an exception to a thread stored in a global variable, which initially corresponds to the thread from which `runGhc` was run.
This is a particularly problematic for programs that wish to run ghc "in the background" on its own thread. For example, consider this code:
```
import qualified GHC
import qualified MonadUtils as GHC
import qualified GHC.Paths as GHC
import Control.Concurrent ( forkIO, threadDelay )
main = do
putStrLn "waiting for 5 seconds..."
threadDelay $ 5 * 1000 * 1000
putStrLn "starting..."
forkIO $ GHC.runGhc (Just GHC.libdir) (GHC.liftIO $ putStrLn "hello")
putStrLn "waiting for 10 seconds"
threadDelay $ 10 * 1000 * 1000
putStrLn "exiting after final wait"
```
One can interrupt this program with Ctrl-C during the first five seconds of execution only.
It is not clear to me how one can safely workaround this problem. For instance, one could manually restore the program's original handlers at the beginning of execution, that is, transform:
```
runGhc action
```
into something like this:
```
runGhc $ (liftIO restoreProgramHandlers >> action)
```
but I don't know if this is safe (i.e., what happens if ghc is run without its own handlers installed).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.12.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHC API |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC API messes up signal handlers","status":"New","operating_system":"","component":"GHC API","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.12.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"A side-effect of using the {{{runGhc}}} function is that some signal handlers are modified and not restored afterwards (see function {{{initGhcMonad}}}). In particular, the handler for {{{SIGINT}}} installed by ghc throws an exception to a thread stored in a global variable, which initially corresponds to the thread from which {{{runGhc}}} was run.\r\n\r\nThis is a particularly problematic for programs that wish to run ghc \"in the background\" on its own thread. For example, consider this code:\r\n\r\n{{{\r\nimport qualified GHC\r\nimport qualified MonadUtils as GHC\r\nimport qualified GHC.Paths as GHC\r\n\r\nimport Control.Concurrent ( forkIO, threadDelay )\r\n\r\nmain = do\r\n putStrLn \"waiting for 5 seconds...\"\r\n threadDelay $ 5 * 1000 * 1000\r\n putStrLn \"starting...\"\r\n forkIO $ GHC.runGhc (Just GHC.libdir) (GHC.liftIO $ putStrLn \"hello\")\r\n putStrLn \"waiting for 10 seconds\"\r\n threadDelay $ 10 * 1000 * 1000\r\n putStrLn \"exiting after final wait\"\r\n}}}\r\n\r\nOne can interrupt this program with Ctrl-C during the first five seconds of execution only.\r\n\r\nIt is not clear to me how one can safely workaround this problem. For instance, one could manually restore the program's original handlers at the beginning of execution, that is, transform:\r\n\r\n{{{\r\nrunGhc action\r\n}}}\r\n\r\ninto something like this:\r\n\r\n{{{\r\nrunGhc $ (liftIO restoreProgramHandlers >> action)\r\n}}}\r\n\r\nbut I don't know if this is safe (i.e., what happens if ghc is run without its own handlers installed).\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/4105ffi005 fails on OS X2019-07-07T19:00:32ZIan Lynagh <igloo@earth.li>ffi005 fails on OS XThe ffi005 test is failing on OS X x86.
The test is only run the optc way, but we get other bad results when compiling in other ways.
normal:
```
{-# LANGUAGE ForeignFunctionInterface #-}
import Control.Monad
import Foreign.C
main :...The ffi005 test is failing on OS X x86.
The test is only run the optc way, but we get other bad results when compiling in other ways.
normal:
```
{-# LANGUAGE ForeignFunctionInterface #-}
import Control.Monad
import Foreign.C
main :: IO ()
main = doit sin mysin (encodeFloat 7926335344172077 (-54))
doit :: (CDouble -> CDouble) -> (CDouble -> CDouble) -> CDouble -> IO ()
doit f g x = do let fx = f x
gx = g x
when (fx /= gx) $ do print x
print (decodeFloat x)
print fx
print gx
print (fx - gx)
foreign import ccall "sin" mysin :: CDouble -> CDouble
```
```
$ ghc q.hs -o q; ./q
0.4400000000000002
(7926335344172077,-54)
0.4259394650659998
0.42593946506599983
-5.551115123125783e-17
```
optc:
```
{-# LANGUAGE ForeignFunctionInterface #-}
import Control.Monad
import Foreign
import Foreign.C
main :: IO ()
main = do sin_addr <- wrapId sin
doit sin (dyn_sin sin_addr) (encodeFloat 7926335344172077 (-54))
freeHaskellFunPtr sin_addr
doit :: (CDouble -> CDouble) -> (CDouble -> CDouble) -> CDouble -> IO ()
doit f g x = do let fx = f x
gx = g x
when (fx /= gx) $ do print x
print (decodeFloat x)
print fx
print gx
print (fx - gx)
foreign import ccall "wrapper" wrapId :: (CDouble -> CDouble) -> IO (FunPtr (CDouble -> CDouble))
foreign import ccall "dynamic" dyn_sin :: FunPtr (CDouble -> CDouble) -> (CDouble -> CDouble)
```
```
$ ghc w.hs -o w -fvia-c -O; ./w
0.4400000000000002
(7926335344172077,-54)
0.42593946506599983
0.4259394650659998
5.551115123125783e-17
```
optasm:
```
{-# LANGUAGE ForeignFunctionInterface #-}
import Control.Monad
import Foreign
import Foreign.C
main :: IO ()
main = do sin_addr <- wrapId sin
doit sin (dyn_sin sin_addr) (encodeFloat 7926335344172077 (-54))
freeHaskellFunPtr sin_addr
doit :: (CDouble -> CDouble) -> (CDouble -> CDouble) -> CDouble -> IO ()
doit f g x = do let fx = f x
gx = g x
when (fx /= gx) $ do print x
print (decodeFloat x)
print fx
print gx
print (decodeFloat fx)
print (decodeFloat gx)
print (fx == gx)
print (decodeFloat fx == decodeFloat gx)
print (fx - gx)
foreign import ccall "wrapper" wrapId :: (CDouble -> CDouble) -> IO (FunPtr (CDouble -> CDouble))
foreign import ccall "dynamic" dyn_sin :: FunPtr (CDouble -> CDouble) -> (CDouble -> CDouble)
```
```
$ ghc r.hs -o r -O; ./r
0.4400000000000002
(7926335344172077,-54)
0.4259394650659998
0.4259394650659998
(7673043264614500,-54)
(7673043264614500,-54)
False
True
0.0
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.12.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | ffi005 |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ffi005 fails on OS X","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"7.0.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.12.2","keywords":[],"differentials":[],"test_case":"ffi005","architecture":"","cc":[""],"type":"Bug","description":"The ffi005 test is failing on OS X x86.\r\n\r\nThe test is only run the optc way, but we get other bad results when compiling in other ways.\r\n\r\nnormal:\r\n{{{\r\n{-# LANGUAGE ForeignFunctionInterface #-}\r\n\r\nimport Control.Monad\r\nimport Foreign.C\r\n\r\nmain :: IO ()\r\nmain = doit sin mysin (encodeFloat 7926335344172077 (-54))\r\n\r\ndoit :: (CDouble -> CDouble) -> (CDouble -> CDouble) -> CDouble -> IO ()\r\ndoit f g x = do let fx = f x\r\n gx = g x\r\n when (fx /= gx) $ do print x\r\n print (decodeFloat x)\r\n print fx\r\n print gx\r\n print (fx - gx)\r\n\r\nforeign import ccall \"sin\" mysin :: CDouble -> CDouble\r\n}}}\r\n{{{\r\n$ ghc q.hs -o q; ./q\r\n0.4400000000000002\r\n(7926335344172077,-54)\r\n0.4259394650659998\r\n0.42593946506599983\r\n-5.551115123125783e-17\r\n}}}\r\noptc:\r\n{{{\r\n{-# LANGUAGE ForeignFunctionInterface #-}\r\n\r\nimport Control.Monad\r\nimport Foreign\r\nimport Foreign.C\r\n\r\nmain :: IO ()\r\nmain = do sin_addr <- wrapId sin\r\n doit sin (dyn_sin sin_addr) (encodeFloat 7926335344172077 (-54))\r\n freeHaskellFunPtr sin_addr\r\n\r\ndoit :: (CDouble -> CDouble) -> (CDouble -> CDouble) -> CDouble -> IO ()\r\ndoit f g x = do let fx = f x\r\n gx = g x\r\n when (fx /= gx) $ do print x\r\n print (decodeFloat x)\r\n print fx\r\n print gx\r\n print (fx - gx)\r\n\r\nforeign import ccall \"wrapper\" wrapId :: (CDouble -> CDouble) -> IO (FunPtr (CDouble -> CDouble))\r\nforeign import ccall \"dynamic\" dyn_sin :: FunPtr (CDouble -> CDouble) -> (CDouble -> CDouble)\r\n}}}\r\n{{{\r\n$ ghc w.hs -o w -fvia-c -O; ./w\r\n0.4400000000000002\r\n(7926335344172077,-54)\r\n0.42593946506599983\r\n0.4259394650659998\r\n5.551115123125783e-17\r\n}}}\r\noptasm:\r\n{{{\r\n{-# LANGUAGE ForeignFunctionInterface #-}\r\n\r\nimport Control.Monad\r\nimport Foreign\r\nimport Foreign.C\r\n\r\nmain :: IO ()\r\nmain = do sin_addr <- wrapId sin\r\n doit sin (dyn_sin sin_addr) (encodeFloat 7926335344172077 (-54))\r\n freeHaskellFunPtr sin_addr\r\n\r\ndoit :: (CDouble -> CDouble) -> (CDouble -> CDouble) -> CDouble -> IO ()\r\ndoit f g x = do let fx = f x\r\n gx = g x\r\n when (fx /= gx) $ do print x\r\n print (decodeFloat x)\r\n print fx\r\n print gx\r\n print (decodeFloat fx)\r\n print (decodeFloat gx)\r\n print (fx == gx)\r\n print (decodeFloat fx == decodeFloat gx)\r\n print (fx - gx)\r\n\r\nforeign import ccall \"wrapper\" wrapId :: (CDouble -> CDouble) -> IO (FunPtr (CDouble -> CDouble))\r\nforeign import ccall \"dynamic\" dyn_sin :: FunPtr (CDouble -> CDouble) -> (CDouble -> CDouble)\r\n}}}\r\n{{{\r\n$ ghc r.hs -o r -O; ./r\r\n0.4400000000000002\r\n(7926335344172077,-54)\r\n0.4259394650659998\r\n0.4259394650659998\r\n(7673043264614500,-54)\r\n(7673043264614500,-54)\r\nFalse\r\nTrue\r\n0.0\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/4101Primitive constant unfolding2019-07-07T19:00:33ZmaloshPrimitive constant unfoldingExamining the core generated by ghc with -O2 on a numerical code, I saw things like :
```
case GHC.Prim.<## x_aB9 (GHC.Prim.**## 2.0 -1021.0) of _ {...
```
This code being executed each time my code performs an addition ! GHC does not...Examining the core generated by ghc with -O2 on a numerical code, I saw things like :
```
case GHC.Prim.<## x_aB9 (GHC.Prim.**## 2.0 -1021.0) of _ {...
```
This code being executed each time my code performs an addition ! GHC does not seem to unfold the constants right with at least \*\*\#\#. By the way, it should definitely be possible to specify a Double\# constant in hexadecimal.8.0.1schylerschylerhttps://gitlab.haskell.org/ghc/ghc/-/issues/4081Strict constructor fields inspected in loop2021-04-07T16:27:51Zrl@cse.unsw.edu.auStrict constructor fields inspected in loopHere is a small example to illustrate the problem:
```
module T where
data S a b = S !a !b
class C a where
make :: a -> S a a
instance C Int where
{-# NOINLINE make #-}
make n = S n n
foo :: (C a, Num a) => a -> Int -> a
{-# INLI...Here is a small example to illustrate the problem:
```
module T where
data S a b = S !a !b
class C a where
make :: a -> S a a
instance C Int where
{-# NOINLINE make #-}
make n = S n n
foo :: (C a, Num a) => a -> Int -> a
{-# INLINE foo #-}
foo x k = k `seq` m `seq` go k 0
where
S m n = make x
go 0 i = i
go k i = go (k-1) (i + m)
```
```
module U where
import T
bar :: Int -> Int -> Int
bar s k = foo s k + 1
```
Relying on !LiberateCase seems to be the only way to unbox `m` outside of the loop in `bar`. The seq in `foo` doesn't help because it gets eliminated immediately.
GHC does have enough information to do this:
```
U.bar =
\ (s_aaw [Dmd=Just S(A)] :: GHC.Types.Int)
(k_aax [Dmd=Just U(L)] :: GHC.Types.Int) ->
case k_aax
of k1_ajh [Dmd=Just U(L)] { GHC.Types.I# ipv_ajj [Dmd=Just A] ->
case T.$fCInt_$cmake s_aaw of _ { T.S m_ajy [Dmd=Just U(T)] _ ->
...
```
Note the demand on `m`. If it was an argument instead of a local binding, it would be unboxed by w/w.
Also, the seq does help if we use lazy pairs instead of strict ones.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.13 |
| 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":"Strict constructor fields inspected in loop","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.13","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Here is a small example to illustrate the problem:\r\n\r\n{{{\r\nmodule T where\r\n\r\ndata S a b = S !a !b\r\n\r\nclass C a where\r\n make :: a -> S a a\r\n\r\ninstance C Int where\r\n {-# NOINLINE make #-}\r\n make n = S n n\r\n\r\nfoo :: (C a, Num a) => a -> Int -> a\r\n{-# INLINE foo #-}\r\nfoo x k = k `seq` m `seq` go k 0\r\n where\r\n S m n = make x\r\n\r\n go 0 i = i\r\n go k i = go (k-1) (i + m)\r\n}}}\r\n\r\n{{{\r\nmodule U where\r\n\r\nimport T\r\n\r\nbar :: Int -> Int -> Int\r\nbar s k = foo s k + 1\r\n}}}\r\n\r\nRelying on !LiberateCase seems to be the only way to unbox `m` outside of the loop in `bar`. The seq in `foo` doesn't help because it gets eliminated immediately.\r\n\r\nGHC does have enough information to do this:\r\n\r\n{{{\r\nU.bar =\r\n \\ (s_aaw [Dmd=Just S(A)] :: GHC.Types.Int)\r\n (k_aax [Dmd=Just U(L)] :: GHC.Types.Int) ->\r\n case k_aax\r\n of k1_ajh [Dmd=Just U(L)] { GHC.Types.I# ipv_ajj [Dmd=Just A] ->\r\n case T.$fCInt_$cmake s_aaw of _ { T.S m_ajy [Dmd=Just U(T)] _ ->\r\n ...\r\n}}}\r\n\r\nNote the demand on `m`. If it was an argument instead of a local binding, it would be unboxed by w/w.\r\n\r\nAlso, the seq does help if we use lazy pairs instead of strict ones.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1benlbenlhttps://gitlab.haskell.org/ghc/ghc/-/issues/4049Support for ABI versioning of C libraries2019-07-07T19:00:57ZmpiechotkaSupport for ABI versioning of C librariesCurrently the SO files can be versioned - like in libgtk-x11-2.0.so.0. However GHC provides no support for such versioning which may cause problems if the ABI of library will change.
Also it does not provide any support for ldscripts an...Currently the SO files can be versioned - like in libgtk-x11-2.0.so.0. However GHC provides no support for such versioning which may cause problems if the ABI of library will change.
Also it does not provide any support for ldscripts and fails if it seeks for libz.so and only found is ldscript.
More informations:
http://bugs.gentoo.org/show_bug.cgi?id=290974
http://bugs.gentoo.org/show_bug.cgi?id=311361
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.12.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Support for ldscripts and ABI versioning","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.12.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Currently the SO files can be versioned - like in libgtk-x11-2.0.so.0. However GHC provides no support for such versioning which may cause problems if the ABI of library will change.\r\n\r\nAlso it does not provide any support for ldscripts and fails if it seeks for libz.so and only found is ldscript.\r\n\r\nMore informations:\r\nhttp://bugs.gentoo.org/show_bug.cgi?id=290974\r\nhttp://bugs.gentoo.org/show_bug.cgi?id=311361","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/4048ghc-pkg should check for existence of extra-libraries2019-07-07T19:00:58ZSimon Marlowghc-pkg should check for existence of extra-librariesIn #3930 we decided that all `extra-libraries` should be found either on the system search path or the paths in the package's `library-dirs` field. We should make `ghc-pkg` check this when registering a package - it can use `gcc -print-s...In #3930 we decided that all `extra-libraries` should be found either on the system search path or the paths in the package's `library-dirs` field. We should make `ghc-pkg` check this when registering a package - it can use `gcc -print-search-dirs` to get the system search path.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.12.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Package system |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ghc-pkg should check for existence of extra-libraries","status":"New","operating_system":"","component":"Package system","related":[],"milestone":"7.0.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.12.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"In #3930 we decided that all `extra-libraries` should be found either on the system search path or the paths in the package's `library-dirs` field. We should make `ghc-pkg` check this when registering a package - it can use `gcc -print-search-dirs` to get the system search path.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3895"Fix" pervasive-but-unnecessary signedness in GHC.Prim2019-07-07T19:01:38Zpumpkin"Fix" pervasive-but-unnecessary signedness in GHC.PrimI'm talking about the array primitives in particular:
```
writeFloatArray# :: MutableByteArray# s -> Int# -> Float# -> State# s -> State# s
```
Conceptually, a Word\# makes more sense as the index for all the array functions. I'm not e...I'm talking about the array primitives in particular:
```
writeFloatArray# :: MutableByteArray# s -> Int# -> Float# -> State# s -> State# s
```
Conceptually, a Word\# makes more sense as the index for all the array functions. I'm not even sure what the semantics are if the Int\# is negative... is it checked? The three scenarios I can think of are:
Negativity is checked, and you get an exception.
Negativity is unchecked, and you get to write to memory that comes before your array.
Negativity is ignored, and the back-end treats the Int\# like a Word\# already.
I think the switch would be worthwhile in all of those cases, and could be hidden in higher-level APIs that still use Int for indexes with a simple int2Word\#. Eventually we might even migrate to Word-based APIs at that level?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"\"Fix\" pervasive-but-unnecessary signedness in GHC.Prim","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I'm talking about the array primitives in particular:\r\n\r\n{{{\r\nwriteFloatArray# :: MutableByteArray# s -> Int# -> Float# -> State# s -> State# s\r\n}}}\r\n\r\nConceptually, a Word# makes more sense as the index for all the array functions. I'm not even sure what the semantics are if the Int# is negative... is it checked? The three scenarios I can think of are:\r\n\r\nNegativity is checked, and you get an exception.\r\nNegativity is unchecked, and you get to write to memory that comes before your array.\r\nNegativity is ignored, and the back-end treats the Int# like a Word# already.\r\n\r\nI think the switch would be worthwhile in all of those cases, and could be hidden in higher-level APIs that still use Int for indexes with a simple int2Word#. Eventually we might even migrate to Word-based APIs at that level?","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3881section parse errors, e.g. ( let x=1 in x + )2019-07-07T19:01:42ZIan Lynagh <igloo@earth.li>section parse errors, e.g. ( let x=1 in x + )These parse errors were brought up on the Haskell' list: http://www.haskell.org/pipermail/haskell-prime/2010-February/003093.html
```
Prelude> :t ( let x=1 in x + )
<interactive>:1:18: parse error on input `)'
```
```
Prelude> :t ( if...These parse errors were brought up on the Haskell' list: http://www.haskell.org/pipermail/haskell-prime/2010-February/003093.html
```
Prelude> :t ( let x=1 in x + )
<interactive>:1:18: parse error on input `)'
```
```
Prelude> :t ( if True then 1 else 2 + )
<interactive>:1:27: parse error on input `)'
```
Milestoned for 6.16.1, as it sounds like the language definition may get changed in H'.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 6.12.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Parser) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"section parse errors, e.g. ( let x=1 in x + )","status":"New","operating_system":"","component":"Compiler (Parser)","related":[],"milestone":"7.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.12.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"These parse errors were brought up on the Haskell' list: http://www.haskell.org/pipermail/haskell-prime/2010-February/003093.html\r\n{{{\r\nPrelude> :t ( let x=1 in x + )\r\n\r\n<interactive>:1:18: parse error on input `)'\r\n}}}\r\n{{{\r\nPrelude> :t ( if True then 1 else 2 + )\r\n\r\n<interactive>:1:27: parse error on input `)'\r\n}}}\r\nMilestoned for 6.16.1, as it sounds like the language definition may get changed in H'.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3870Avoid Haddock-links to the Prelude2022-06-14T13:44:44ZwaernAvoid Haddock-links to the PreludeIf you're generating documenatation that links to the base package, you will see that some links to standard types go to the `Prelude` and some to the hierarchical libararies. For example, `Int` goes to `Prelude.Int`, while `Either` goes...If you're generating documenatation that links to the base package, you will see that some links to standard types go to the `Prelude` and some to the hierarchical libararies. For example, `Int` goes to `Prelude.Int`, while `Either` goes to `Data.Either.Either`.
This happens because the `Prelude` imports some types from the hierarchical libraries, while some are imported directly from internal GHC modules (e.g. `GHC.Base`). In the first case, the hierarchical module is choosen as the best place to link to since it's closer than the `Prelude` in the topological sort to the original module. In the latter case, the hierarchical module and the `Prelude` are of equal number of imports away from the original module, so none is considered a better place to link to. In this case one of the modules is arbitrarily chosen and it happens to be the `Prelude`.
I think it would be nice if the links would always go to the hierarchical libraries. Maybe the best way to achieve that would be to add `{-# OPTIONS_HADDOCK NotHome #-}` to the `Prelude`. This flag is not yet documented (I should get around to that). It tells Haddock to prefer linking to another module if one is available.
## Desired Home modules
<details><summary>Desired Home Modules</summary>
I'm using this format where NEW means the home module doesn't currently export this entity:
```
Desired.Home.Module
===================
a
b
NEW c
```
```
Control.Monad
=============
GHC.Base.=<<
Data.Bool
=========
GHC.Classes.&&
GHC.Classes.not
GHC.Classes.||
NEW Data.Bounded
=============
GHC.Enum.Bounded
{ GHC.Enum.maxBound
, GHC.Enum.minBound }
NEW Data.Enum
=========
GHC.Enum.Enum
{ GHC.Enum.enumFrom
, GHC.Enum.enumFromThen
, GHC.Enum.enumFromThenTo
, GHC.Enum.enumFromTo
, GHC.Enum.fromEnum
, GHC.Enum.pred
, GHC.Enum.succ
, GHC.Enum.toEnum }
NEW Data.Error
* Alternatively Control.Exception (for error, errorWithoutStackTrace, undefined)
==========
GHC.Err.error
GHC.Err.errorWithoutStackTrace
GHC.Err.undefined
Data.Function
=============
GHC.Base.($)
GHC.Base.(.)
GHC.Base.id
GHC.Base.flip
GHC.Base.const
NEW GHC.Base.($!)
* Similar to ($)
NEW GHC.Base.asTypeOf
* Similar to `const`
NEW GHC.Base.until
* Meets the modules description of being functions on pure functions.
Data.List
=========
GHC.Base.++
GHC.Base.map
GHC.List.!!
GHC.List.break
GHC.List.cycle
GHC.List.drop
GHC.List.dropWhile
GHC.List.filter
GHC.List.head
GHC.List.init
GHC.List.iterate
GHC.List.last
GHC.List.lookup
GHC.List.repeat
GHC.List.replicate
GHC.List.reverse
GHC.List.scanl
GHC.List.scanl1
GHC.List.scanr
GHC.List.scanr1
GHC.List.span
GHC.List.splitAt
GHC.List.tail
GHC.List.take
GHC.List.takeWhile
GHC.List.unzip
GHC.List.unzip3
GHC.List.zip
GHC.List.zip3
GHC.List.zipWith
GHC.List.zipWith3
NEW Data.Seq
* This module seems a bit too empty
=====================================
GHC.Prim.seq
NEW Numeric.Integral
* Why not Data.Integral?
==========================
GHC.Real.Integral
{ GHC.Real.div
, GHC.Real.divMod
, GHC.Real.mod
, GHC.Real.quot
, GHC.Real.quotRem
, GHC.Real.rem
, GHC.Real.toInteger }
GHC.Real.even
GHC.Real.gcd
GHC.Real.lcm
GHC.Real.odd
TODO pick a home module for these entities
==========================================
GHC.Base.Applicative{GHC.Base.*>, GHC.Base.<*, GHC.Base.<*>, GHC.Base.pure}
GHC.Base.Functor{GHC.Base.<$, GHC.Base.fmap}
GHC.Base.Monad{GHC.Base.>>, GHC.Base.>>=, GHC.Base.return}
GHC.Base.Monoid{GHC.Base.mappend, GHC.Base.mconcat, GHC.Base.mempty}
GHC.Base.otherwise
GHC.Base.Semigroup{GHC.Base.<>}
GHC.Base.String
GHC.Classes.Eq{GHC.Classes./=, GHC.Classes.==}
GHC.Classes.Ord{GHC.Classes.<, GHC.Classes.<=, GHC.Classes.>, GHC.Classes.>=, GHC.Classes.compare, GHC.Classes.max, GHC.Classes.min}
GHC.Float.Floating{GHC.Float.**, GHC.Float.acos, GHC.Float.acosh, GHC.Float.asin, GHC.Float.asinh, GHC.Float.atan, GHC.Float.atanh, GHC.Float.cos, GHC.Float.cosh, GHC.Float.exp, GHC.Float.log, GHC.Float.logBase, GHC.Float.pi, GHC.Float.sin, GHC.Float.sinh, GHC.Float.sqrt, GHC.Float.tan, GHC.Float.tanh}
GHC.Float.RealFloat{GHC.Float.atan2, GHC.Float.decodeFloat, GHC.Float.encodeFloat, GHC.Float.exponent, GHC.Float.floatDigits, GHC.Float.floatRadix, GHC.Float.floatRange, GHC.Float.isDenormalized, GHC.Float.isIEEE, GHC.Float.isInfinite, GHC.Float.isNaN, GHC.Float.isNegativeZero, GHC.Float.scaleFloat, GHC.Float.significand}
GHC.Integer.Type.Integer
GHC.IO.Exception.ioError
GHC.IO.Exception.IOError
GHC.IO.Exception.userError
GHC.IO.FilePath
GHC.Maybe.Maybe{GHC.Maybe.Just, GHC.Maybe.Nothing}
GHC.Num.Num{GHC.Num.*, GHC.Num.+, GHC.Num.-, GHC.Num.abs, GHC.Num.fromInteger, GHC.Num.negate, GHC.Num.signum}
GHC.Num.subtract
GHC.Read.lex
GHC.Read.Read{GHC.Read.readList, GHC.Read.readsPrec}
GHC.Read.readParen
GHC.Real.^
GHC.Real.^^
GHC.Real.Fractional{GHC.Real./, GHC.Real.fromRational, GHC.Real.recip}
GHC.Real.Integral{GHC.Real.div, GHC.Real.divMod, GHC.Real.mod, GHC.Real.quot, GHC.Real.quotRem, GHC.Real.rem, GHC.Real.toInteger}
GHC.Real.Rational
GHC.Real.Real{GHC.Real.toRational}
GHC.Real.RealFrac{GHC.Real.ceiling, GHC.Real.floor, GHC.Real.properFraction, GHC.Real.round, GHC.Real.truncate}
GHC.Real.realToFrac
GHC.Show.Show{GHC.Show.show, GHC.Show.showList, GHC.Show.showsPrec}
GHC.Show.showChar
GHC.Show.showParen
GHC.Show.shows
GHC.Show.ShowS
GHC.Show.showString
GHC.Types.Bool{GHC.Types.False, GHC.Types.True}
GHC.Types.Char
GHC.Types.Double
GHC.Types.Float
GHC.Types.Int
GHC.Types.IO
GHC.Types.Ordering{GHC.Types.EQ, GHC.Types.GT, GHC.Types.LT}
GHC.Types.Word
```
</details>
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------- |
| Version | 6.12.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Documentation |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Avoid Haddock-links to the Prelude","status":"New","operating_system":"","component":"Documentation","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.12.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"If you're generating documenatation that links to the base package, you will see that some links to standard types go to the `Prelude` and some to the hierarchical libararies. For example, `Int` goes to `Prelude.Int`, while `Either` goes to `Data.Either.Either`.\r\n\r\nThis happens because the `Prelude` imports some types from the hierarchical libraries, while some are imported directly from internal GHC modules (e.g. `GHC.Base`). In the first case, the hierarchical module is choosen as the best place to link to since it's closer than the `Prelude` in the topological sort to the original module. In the latter case, the hierarchical module and the `Prelude` are of equal number of imports away from the original module, so none is considered a better place to link to. In this case one of the modules is arbitrarily chosen and it happens to be the `Prelude`. \r\n\r\nI think it would be nice if the links would always go to the hierarchical libraries. Maybe the best way to achieve that would be to add `{-# OPTIONS_HADDOCK NotHome #-}` to the `Prelude`. This flag is not yet documented (I should get around to that). It tells Haddock to prefer linking to another module if one is available.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3767SpecConstr for join points2019-07-07T19:02:16ZSimon Peyton JonesSpecConstr for join pointsThe attached file `Spec.hs` has a case (from Roman's fusion code) where `SpecConstr` is not doing the right thing. Let's look at one of the mutually recursive loops that `SpecConstr` generates for foo:
```
lvl_rzY :: GHC.Types.Int
lvl_r...The attached file `Spec.hs` has a case (from Roman's fusion code) where `SpecConstr` is not doing the right thing. Let's look at one of the mutually recursive loops that `SpecConstr` generates for foo:
```
lvl_rzY :: GHC.Types.Int
lvl_rzY = GHC.Types.I# 2147483647
lvl1_rA0 :: Data.Either.Either GHC.Types.Int GHC.Types.Int
lvl1_rA0 = Data.Either.Left @ GHC.Types.Int @ GHC.Types.Int lvl_rzY
$s$wgo_szT :: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int#
$s$wgo_szT =
\ (sc_sz6 :: GHC.Prim.Int#) (sc1_sz7 :: GHC.Prim.Int#) ->
let {
$w$j_syG
:: GHC.Prim.Int#
-> Data.Either.Either GHC.Types.Int GHC.Types.Int
-> GHC.Prim.Int#
[LclId, Arity=2, Str=DmdType LS]
$w$j_syG =
\ (ww_sy6 :: GHC.Prim.Int#)
(w2_sy8 :: Data.Either.Either GHC.Types.Int GHC.Types.Int) ->
case GHC.Prim.<=# ww_sy6 0 of _ {
GHC.Bool.False -> $wgo_syE (GHC.Prim.+# sc_sz6 ww_sy6) w2_sy8;
GHC.Bool.True -> $wgo_syE sc_sz6 w2_sy8
} } in
case GHC.Prim.># sc1_sz7 0 of _ {
GHC.Bool.False -> $s$wgo1_szS sc_sz6 ipv_swo;
GHC.Bool.True ->
case sc1_sz7 of wild1_awb {
__DEFAULT ->
case GHC.Prim.remInt# wild1_awb 2 of _ {
__DEFAULT -> $s$wgo_szT sc_sz6 (GHC.Prim.-# wild1_awb 1);
0 ->
case w1_syr of _ { GHC.Types.I# ww_sy6 ->
$w$j_syG
ww_sy6
(Data.Either.Left
@ GHC.Types.Int
@ GHC.Types.Int
(GHC.Types.I# (GHC.Prim.-# wild1_awb 1)))
}
};
(-2147483648) ->
case w1_syr of _ { GHC.Types.I# ww_sy6 ->
$w$j_syG ww_sy6 lvl1_rA0
}
}
};
```
Note that the join point has an argument of type `(Either Int Int)` but it is always called with `(Left (I# <n>))`. This means that the recursive call in the join point is always of the form `($wgo_syE <m> (Left (I# <n>)))` and we have a specialisation for that. However the join point itself doesn't scrutinse its argument, and that means that GHC ignores the potential specialisation.
Simon
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.12.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":"SpecConstr for join points","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"6.14 branch","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.12.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The attached file `Spec.hs` has a case (from Roman's fusion code) where `SpecConstr` is not doing the right thing. Let's look at one of the mutually recursive loops that `SpecConstr` generates for foo:\r\n{{{\r\nlvl_rzY :: GHC.Types.Int\r\nlvl_rzY = GHC.Types.I# 2147483647\r\n\r\nlvl1_rA0 :: Data.Either.Either GHC.Types.Int GHC.Types.Int\r\nlvl1_rA0 = Data.Either.Left @ GHC.Types.Int @ GHC.Types.Int lvl_rzY\r\n\r\n$s$wgo_szT :: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int#\r\n$s$wgo_szT =\r\n \\ (sc_sz6 :: GHC.Prim.Int#) (sc1_sz7 :: GHC.Prim.Int#) ->\r\n let {\r\n $w$j_syG\r\n :: GHC.Prim.Int#\r\n -> Data.Either.Either GHC.Types.Int GHC.Types.Int\r\n -> GHC.Prim.Int#\r\n [LclId, Arity=2, Str=DmdType LS]\r\n $w$j_syG =\r\n \\ (ww_sy6 :: GHC.Prim.Int#)\r\n (w2_sy8 :: Data.Either.Either GHC.Types.Int GHC.Types.Int) ->\r\n case GHC.Prim.<=# ww_sy6 0 of _ {\r\n GHC.Bool.False -> $wgo_syE (GHC.Prim.+# sc_sz6 ww_sy6) w2_sy8;\r\n GHC.Bool.True -> $wgo_syE sc_sz6 w2_sy8\r\n } } in\r\n case GHC.Prim.># sc1_sz7 0 of _ {\r\n GHC.Bool.False -> $s$wgo1_szS sc_sz6 ipv_swo;\r\n GHC.Bool.True ->\r\n case sc1_sz7 of wild1_awb {\r\n __DEFAULT ->\r\n case GHC.Prim.remInt# wild1_awb 2 of _ {\r\n __DEFAULT -> $s$wgo_szT sc_sz6 (GHC.Prim.-# wild1_awb 1);\r\n 0 ->\r\n case w1_syr of _ { GHC.Types.I# ww_sy6 ->\r\n $w$j_syG\r\n ww_sy6\r\n (Data.Either.Left\r\n @ GHC.Types.Int\r\n @ GHC.Types.Int\r\n (GHC.Types.I# (GHC.Prim.-# wild1_awb 1)))\r\n }\r\n };\r\n (-2147483648) ->\r\n case w1_syr of _ { GHC.Types.I# ww_sy6 ->\r\n $w$j_syG ww_sy6 lvl1_rA0\r\n }\r\n }\r\n };\r\n}}}\r\nNote that the join point has an argument of type `(Either Int Int)` but it is always called with `(Left (I# <n>))`. This means that the recursive call in the join point is always of the form `($wgo_syE <m> (Left (I# <n>)))` and we have a specialisation for that. However the join point itself doesn't scrutinse its argument, and that means that GHC ignores the potential specialisation. \r\n\r\nSimon \r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3766Parsing of lambdas is not consistent with Haskell'98 report.2019-07-07T19:02:17ZlilacParsing of lambdas is not consistent with Haskell'98 report.Consider the following expression:
` (\x -> x :: Int . id)`
GHC (without any -X flags) currently reports a parse error:
> Illegal operator `.' in type `Int . id'\[\[br\]\] Use -XTypeOperators to allow operators in types
However, I ...Consider the following expression:
` (\x -> x :: Int . id)`
GHC (without any -X flags) currently reports a parse error:
> Illegal operator `.' in type `Int . id'\[\[br\]\] Use -XTypeOperators to allow operators in types
However, I think this expression is legal in Haskell'98 (and indeed still legal in Haskell 2010). The report gives an (ambiguous) expression grammar, which (unambiguously) parses the above as (\\x -\> (x :: Int)) . id. The report further says that lambdas extend as far as possible to the right, but the parse which GHC is using is not a possible parse according to the grammar, since infix operators (other than "-\>") are not allowed in the construction 'type'.
That said, I'd much rather see this fixed in the Haskell 2011 report than in GHC :)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 6.10.4 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Parser) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Parsing of lambdas is not consistent with Haskell'98 report.","status":"New","operating_system":"","component":"Compiler (Parser)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.4","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider the following expression:\r\n\r\n{{{ (\\x -> x :: Int . id)}}}\r\n\r\nGHC (without any -X flags) currently reports a parse error:\r\n\r\n Illegal operator `.' in type `Int . id'[[br]] Use -XTypeOperators to allow operators in types\r\n\r\nHowever, I think this expression is legal in Haskell'98 (and indeed still legal in Haskell 2010). The report gives an (ambiguous) expression grammar, which (unambiguously) parses the above as (\\x -> (x :: Int)) . id. The report further says that lambdas extend as far as possible to the right, but the parse which GHC is using is not a possible parse according to the grammar, since infix operators (other than \"->\") are not allowed in the construction 'type'.\r\n\r\nThat said, I'd much rather see this fixed in the Haskell 2011 report than in GHC :)","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3711Bad error reporting when calling a function in a module which depends on a DL...2019-07-07T19:02:40Ziampure@gmail.comBad error reporting when calling a function in a module which depends on a DLL on WindowsWhen you try to call a function which depends on a DLL, after the module has been loaded in ghci, you get:
Loading package Codec-Image-DevIL-0.1 ... can't load .so/.DLL for: ILU (addDLL: could not load DLL)
This error message is almost...When you try to call a function which depends on a DLL, after the module has been loaded in ghci, you get:
Loading package Codec-Image-DevIL-0.1 ... can't load .so/.DLL for: ILU (addDLL: could not load DLL)
This error message is almost completely useless. It should call GetLastError() and present this information to the user.
I don't know whether the error message for GetLastError is actually useful, but otherwise it should derive a real problem with the library, e.g. "we searched for it in the PATH, but we couldn't find it, or the library format is wrong(use Dependency walker to verify that this is a valid Windows DLL), etc.".
In general every error message should state what it tried and why it failed. In the same sense that type-error messages do (assuming no bugs in the type-inferencer ;) ).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------- |
| Version | 6.10.4 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown/Multiple |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Bad error reporting when calling a function in a module which depends on a DLL on Windows","status":"New","operating_system":"Unknown/Multiple","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.4","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When you try to call a function which depends on a DLL, after the module has been loaded in ghci, you get: \r\n\r\nLoading package Codec-Image-DevIL-0.1 ... can't load .so/.DLL for: ILU (addDLL: could not load DLL)\r\n\r\nThis error message is almost completely useless. It should call GetLastError() and present this information to the user. \r\n\r\nI don't know whether the error message for GetLastError is actually useful, but otherwise it should derive a real problem with the library, e.g. \"we searched for it in the PATH, but we couldn't find it, or the library format is wrong(use Dependency walker to verify that this is a valid Windows DLL), etc.\".\r\n\r\nIn general every error message should state what it tried and why it failed. In the same sense that type-error messages do (assuming no bugs in the type-inferencer ;) ). ","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3645Layout and pragmas2021-03-03T18:09:00ZIan Lynagh <igloo@earth.li>Layout and pragmasWith this module:
```
{-# LANGUAGE DeriveDataTypeable,
FlexibleContexts
#-}
module Foo where
```
GHC 6.12 says:
```
Cannot parse LANGUAGE pragma
Expecting comma-separated list of language options,
each starti...With this module:
```
{-# LANGUAGE DeriveDataTypeable,
FlexibleContexts
#-}
module Foo where
```
GHC 6.12 says:
```
Cannot parse LANGUAGE pragma
Expecting comma-separated list of language options,
each starting with a capital letter
E.g. {-# LANGUAGE RecordPuns, Generics #-}
```
but this should probably be allowed. See #3519, #3616.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 6.10.4 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Parser) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Layout and pragmas","status":"New","operating_system":"","component":"Compiler (Parser)","related":[],"milestone":"7.0.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.4","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"With this module:\r\n{{{\r\n{-# LANGUAGE DeriveDataTypeable,\r\n FlexibleContexts\r\n#-}\r\n\r\nmodule Foo where\r\n}}}\r\nGHC 6.12 says:\r\n{{{\r\n Cannot parse LANGUAGE pragma\r\n Expecting comma-separated list of language options,\r\n each starting with a capital letter\r\n E.g. {-# LANGUAGE RecordPuns, Generics #-}\r\n}}}\r\nbut this should probably be allowed. See #3519, #3616.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3606The Ord instance for unboxed arrays is very inefficient2021-11-02T09:27:33ZblarsenThe Ord instance for unboxed arrays is very inefficientThe Ord instance for unboxed arrays defined in `Data.Array.Base` results in code that makes lots of heap allocations and is very slow.
For the record, the `Ord` instance is defined as so in `Data.Array.Base`:
```hs
instance (Ix ix, Ord...The Ord instance for unboxed arrays defined in `Data.Array.Base` results in code that makes lots of heap allocations and is very slow.
For the record, the `Ord` instance is defined as so in `Data.Array.Base`:
```hs
instance (Ix ix, Ord e, IArray UArray e) => Ord (UArray ix e) where
compare = cmpUArray
{-# INLINE cmpUArray #-}
cmpUArray :: (IArray UArray e, Ix i, Ord e) => UArray i e -> UArray i e -> Ordering
cmpUArray arr1 arr2 = compare (assocs arr1) (assocs arr2)
```
The `assocs` calls don't appear to be deforested away, and hence, when using the `Ord` functions on unboxed arrays, the performance is bad to the point of making them unusable.
It seems reasonable to me that `compare` for unboxed arrays could be implemented strictly, in a tight loop, without any heap allocations at all.8.0.1Edward KmettEdward Kmetthttps://gitlab.haskell.org/ghc/ghc/-/issues/3588ghc -M should emit dependencies on CPP headers2019-07-07T19:03:14ZSimon Marlowghc -M should emit dependencies on CPP headersWhen using CPP, ghc -M should emit dependencies on header files that are `#included` into Haskell source code. It could do this by running `gcc -M`, perhaps.
<details><summary>Trac metadata</summary>
| Trac field | Value ...When using CPP, ghc -M should emit dependencies on header files that are `#included` into Haskell source code. It could do this by running `gcc -M`, perhaps.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.10.4 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ghc -M should emit dependencies on CPP headers","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"6.14 branch","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.4","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When using CPP, ghc -M should emit dependencies on header files that are `#included` into Haskell source code. It could do this by running `gcc -M`, perhaps.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3571Bizzarely bloated binaries2020-06-22T23:07:04ZguestBizzarely bloated binariesCompiling a trivial test program:
```
module Main where
main = print "Hello World"
```
Using GHC 6.10.4 produces a VERY suspicious PE file. (NB: this applies to DLL as well as EXE output).
The two problems that I have observed are:
...Compiling a trivial test program:
```
module Main where
main = print "Hello World"
```
Using GHC 6.10.4 produces a VERY suspicious PE file. (NB: this applies to DLL as well as EXE output).
The two problems that I have observed are:
1) The PE always contains a .stab and .stabstr section totalling 0x2A00 of debug data. Looking at the contents of stabstr, this appears to originate from a libffi object file. Perhaps we could disable stabs when building libffi to remove this bloat from output binaries.
2) The PE contains \*A LOT\* of trailing junk. My hello world program is 691K, and the PE contains 0x4FAFC = 318K of data which doesn't live in any section! Trimming this data appears to have no effect on the correctness of the program! The amount of junk grows proportionally to the amount of real code and data - I have observed e.g. 18Mb DLLs of which 9Mb are trailing junk.
To repeat: we could potentially \*halve\* GHC binary sizes by fixing this linker behaviour.
I'm not sure where exactly the fault lies - whether it is a GHC problem or some bug in Ld.
To test trimming your executables and DLLs, you can use this utility I whipped up. Usage is "trimpe \<file1\> ... \<fileN\>". It will trim useless data from the end of the files in place:
```
{-# LANGUAGE ScopedTypeVariables #-}
module Main (main) where
import Control.Monad
import Data.Binary
import Data.Binary.Get
import qualified Data.ByteString.Lazy as ByteString
import Data.Word
import System.Environment
import Debug.Trace
assertM :: Monad m => Bool -> m ()
assertM True = return ()
assertM False = fail "assertM"
newtype PEImageLength = PEImageLength Word32
-- http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
instance Binary PEImageLength where
get = do
-- Skip the MS DOS stub
skip 0x3c
pe_sig_offset <- getWord32le
-- Skip to the PE signature
skip (fromIntegral pe_sig_offset - (0x4 + 0x3c))
-- Read the PE signature itself
-- NB: this will always be the string "PE\0\0"
_sig <- getWord32le
assertM (_sig == 0x00004550)
-- Read COFF file header
_machine <- getWord16le
_no_of_sects <- getWord16le
_time_date_stamp <- getWord32le
_ptr_to_sym_tab <- getWord32le
_no_of_syms <- getWord32le
_size_of_opt_header <- getWord16le
assertM (_size_of_opt_header /= 0)
_characteristics <- getWord16le
-- Read the "optional" header
magic <- getWord16le
let pe32plus = magic == 0x20B
_maj_link_ver :: Word8 <- get
_min_link_ver :: Word8 <- get
_size_of_code <- getWord32le
_size_of_init_data <- getWord32le
_size_of_uninit_data <- getWord32le
_addr_of_entry_point <- getWord32le
_base_of_code <- getWord32le
when (not pe32plus) $ do _base_of_data <- getWord32le; return ()
-- Read the optional header Windows fields
if pe32plus
then do _image_base <- getWord64le; return ()
else do _image_base <- getWord32le; return ()
_sect_alignment <- getWord32le
_file_alignment <- getWord32le
_maj_os_version <- getWord16le
_min_os_version <- getWord16le
_maj_image_version <- getWord16le
_min_image_version <- getWord16le
_maj_subsys_version <- getWord16le
_min_subsys_version <- getWord16le
_win32_version <- getWord32le
size_of_image <- getWord32le
-- There is more stuff later, but I simply don't care about it
-- NB: we could trim a little more agressively if we interpreted
-- the sections as well...
return $ PEImageLength size_of_image
put = error "Binary PEImageLength: put"
main :: IO ()
main = do
files <- getArgs
forM_ files trimPEToImageSize
trimPEToImageSize :: FilePath -> IO ()
trimPEToImageSize file = do
putStrLn $ file
pe_contents <- ByteString.readFile file
let PEImageLength image_size = decode pe_contents
-- Force the file to close so that the write may succeed
(ByteString.last pe_contents) `seq` return ()
when (ByteString.length pe_contents > fromIntegral image_size) $ do
putStrLn $ "* Trimming to image size (" ++ show image_size ++ ")"
let pe_contents' = ByteString.take (fromIntegral image_size) pe_contents
ByteString.writeFile file pe_contents'
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------------------- |
| Version | 6.10.4 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | batterseapower@hotmail.com |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Bizzarely bloated binaries","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.4","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["batterseapower@hotmail.com"],"type":"Bug","description":"Compiling a trivial test program:\r\n\r\n{{{\r\nmodule Main where\r\n\r\nmain = print \"Hello World\"\r\n}}}\r\n\r\nUsing GHC 6.10.4 produces a VERY suspicious PE file. (NB: this applies to DLL as well as EXE output).\r\n\r\nThe two problems that I have observed are:\r\n\r\n 1) The PE always contains a .stab and .stabstr section totalling 0x2A00 of debug data. Looking at the contents of stabstr, this appears to originate from a libffi object file. Perhaps we could disable stabs when building libffi to remove this bloat from output binaries.\r\n\r\n 2) The PE contains *A LOT* of trailing junk. My hello world program is 691K, and the PE contains 0x4FAFC = 318K of data which doesn't live in any section! Trimming this data appears to have no effect on the correctness of the program! The amount of junk grows proportionally to the amount of real code and data - I have observed e.g. 18Mb DLLs of which 9Mb are trailing junk.\r\n\r\nTo repeat: we could potentially *halve* GHC binary sizes by fixing this linker behaviour.\r\n\r\nI'm not sure where exactly the fault lies - whether it is a GHC problem or some bug in Ld.\r\n\r\nTo test trimming your executables and DLLs, you can use this utility I whipped up. Usage is \"trimpe <file1> ... <fileN>\". It will trim useless data from the end of the files in place:\r\n\r\n{{{\r\n{-# LANGUAGE ScopedTypeVariables #-}\r\nmodule Main (main) where\r\n\r\nimport Control.Monad\r\n\r\nimport Data.Binary\r\nimport Data.Binary.Get\r\n\r\nimport qualified Data.ByteString.Lazy as ByteString\r\nimport Data.Word\r\n\r\nimport System.Environment\r\n\r\nimport Debug.Trace\r\n\r\n\r\nassertM :: Monad m => Bool -> m ()\r\nassertM True = return ()\r\nassertM False = fail \"assertM\"\r\n\r\nnewtype PEImageLength = PEImageLength Word32\r\n\r\n-- http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx\r\ninstance Binary PEImageLength where\r\n get = do\r\n -- Skip the MS DOS stub\r\n skip 0x3c\r\n pe_sig_offset <- getWord32le\r\n -- Skip to the PE signature\r\n skip (fromIntegral pe_sig_offset - (0x4 + 0x3c))\r\n -- Read the PE signature itself\r\n -- NB: this will always be the string \"PE\\0\\0\"\r\n _sig <- getWord32le\r\n assertM (_sig == 0x00004550)\r\n -- Read COFF file header\r\n _machine <- getWord16le\r\n _no_of_sects <- getWord16le\r\n _time_date_stamp <- getWord32le\r\n _ptr_to_sym_tab <- getWord32le\r\n _no_of_syms <- getWord32le\r\n _size_of_opt_header <- getWord16le\r\n assertM (_size_of_opt_header /= 0)\r\n _characteristics <- getWord16le\r\n -- Read the \"optional\" header\r\n magic <- getWord16le\r\n let pe32plus = magic == 0x20B\r\n _maj_link_ver :: Word8 <- get\r\n _min_link_ver :: Word8 <- get\r\n _size_of_code <- getWord32le\r\n _size_of_init_data <- getWord32le\r\n _size_of_uninit_data <- getWord32le\r\n _addr_of_entry_point <- getWord32le\r\n _base_of_code <- getWord32le\r\n when (not pe32plus) $ do _base_of_data <- getWord32le; return ()\r\n -- Read the optional header Windows fields\r\n if pe32plus\r\n then do _image_base <- getWord64le; return ()\r\n else do _image_base <- getWord32le; return ()\r\n _sect_alignment <- getWord32le\r\n _file_alignment <- getWord32le\r\n _maj_os_version <- getWord16le\r\n _min_os_version <- getWord16le\r\n _maj_image_version <- getWord16le\r\n _min_image_version <- getWord16le\r\n _maj_subsys_version <- getWord16le\r\n _min_subsys_version <- getWord16le\r\n _win32_version <- getWord32le\r\n size_of_image <- getWord32le\r\n -- There is more stuff later, but I simply don't care about it\r\n -- NB: we could trim a little more agressively if we interpreted\r\n -- the sections as well...\r\n return $ PEImageLength size_of_image\r\n \r\n put = error \"Binary PEImageLength: put\"\r\n\r\n\r\nmain :: IO ()\r\nmain = do\r\n files <- getArgs\r\n forM_ files trimPEToImageSize\r\n\r\ntrimPEToImageSize :: FilePath -> IO ()\r\ntrimPEToImageSize file = do\r\n putStrLn $ file\r\n pe_contents <- ByteString.readFile file\r\n let PEImageLength image_size = decode pe_contents\r\n \r\n -- Force the file to close so that the write may succeed\r\n (ByteString.last pe_contents) `seq` return ()\r\n \r\n when (ByteString.length pe_contents > fromIntegral image_size) $ do\r\n putStrLn $ \"* Trimming to image size (\" ++ show image_size ++ \")\"\r\n let pe_contents' = ByteString.take (fromIntegral image_size) pe_contents\r\n ByteString.writeFile file pe_contents'\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3351Generated ghc man page missing xrefs2019-07-07T19:04:17ZKari PahulaGenerated ghc man page missing xrefsThe man page for ghc is generated from xml files. Currently, this ignores xrefs, turning, for example
```
<entry>enable almost all warnings (details in <xref linkend="options-sanity"/>)</entry>
```
to
> enable almost all warnings (det...The man page for ghc is generated from xml files. Currently, this ignores xrefs, turning, for example
```
<entry>enable almost all warnings (details in <xref linkend="options-sanity"/>)</entry>
```
to
> enable almost all warnings (details in )
This leads to stunted sentences as well as missing information.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------- |
| Version | 6.10.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Documentation |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Generated ghc man page missing xrefs","status":"New","operating_system":"","component":"Documentation","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The man page for ghc is generated from xml files. Currently, this ignores xrefs, turning, for example\r\n\r\n{{{\r\n<entry>enable almost all warnings (details in <xref linkend=\"options-sanity\"/>)</entry>\r\n}}}\r\nto\r\n enable almost all warnings (details in )\r\n\r\nThis leads to stunted sentences as well as missing information.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3238CInt FFI exports do not use C int in _stub.h header file2019-07-07T19:04:46ZduncanCInt FFI exports do not use C int in _stub.h header fileIdeally if I have a FFI export like this:
```
foreign export ccall foo :: CInt -> CInt
```
Then the `_stub.h` file should look like:
```
#ifdef __cplusplus
extern "C" {
#endif
extern int foo(int a1);
#ifdef __cplusplus
}
#endif
```
B...Ideally if I have a FFI export like this:
```
foreign export ccall foo :: CInt -> CInt
```
Then the `_stub.h` file should look like:
```
#ifdef __cplusplus
extern "C" {
#endif
extern int foo(int a1);
#ifdef __cplusplus
}
#endif
```
But it actually looks like:
```
#include "HsFFI.h"
#ifdef __cplusplus
extern "C" {
#endif
extern HsInt32 foo(HsInt32 a1);
#ifdef __cplusplus
}
#endif
```
So what am I complaining about? Well, I specified an FFI export mentioning only C types but the header file uses `HsInt32`. I'd prefer an actual C `int`. I also do not want to `#include "HsFFI.h"` because then when using gcc to compile C code that uses this C function I have to know the full path to ghc's include dir so that gcc can find `HsFFI.h`.
The point here is about exporting C functions and trying to integrate into some bigger build system that will be using gcc not ghc to compile C code and link the system together.
I realise this isn't trivial to fix, because GHC defines things like CInt as newtypes for primitive types of known widths (like Int32). However, perhaps there should be a known mapping, even though within the Haskell world CInt is just a newtype. The set of FFI types is already hard-wired into the compiler (with some rules to allow newtype unwrapping etc) so why not extend that hard-wired knowledge to include the real C type (not just the ABI width). This only needs to be used when generating the export header files. An extra bit in the mapping can indicate if it's a C primitive type or if the export header file has to `#include "HsFFI.h"`.
This ticket is related to #2926 and the solution is almost certainly the same, but the motivation for this problem is slightly different.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.11 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (FFI) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"CInt FFI exports do not use C int in _stub.h header file","status":"New","operating_system":"","component":"Compiler (FFI)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.11","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Ideally if I have a FFI export like this:\r\n{{{\r\nforeign export ccall foo :: CInt -> CInt\r\n}}}\r\nThen the `_stub.h` file should look like:\r\n{{{\r\n#ifdef __cplusplus\r\nextern \"C\" {\r\n#endif\r\nextern int foo(int a1);\r\n#ifdef __cplusplus\r\n}\r\n#endif\r\n}}}\r\nBut it actually looks like:\r\n{{{\r\n#include \"HsFFI.h\"\r\n#ifdef __cplusplus\r\nextern \"C\" {\r\n#endif\r\nextern HsInt32 foo(HsInt32 a1);\r\n#ifdef __cplusplus\r\n}\r\n#endif\r\n}}}\r\n\r\nSo what am I complaining about? Well, I specified an FFI export mentioning only C types but the header file uses `HsInt32`. I'd prefer an actual C `int`. I also do not want to `#include \"HsFFI.h\"` because then when using gcc to compile C code that uses this C function I have to know the full path to ghc's include dir so that gcc can find `HsFFI.h`.\r\n\r\nThe point here is about exporting C functions and trying to integrate into some bigger build system that will be using gcc not ghc to compile C code and link the system together.\r\n\r\nI realise this isn't trivial to fix, because GHC defines things like CInt as newtypes for primitive types of known widths (like Int32). However, perhaps there should be a known mapping, even though within the Haskell world CInt is just a newtype. The set of FFI types is already hard-wired into the compiler (with some rules to allow newtype unwrapping etc) so why not extend that hard-wired knowledge to include the real C type (not just the ABI width). This only needs to be used when generating the export header files. An extra bit in the mapping can indicate if it's a C primitive type or if the export header file has to `#include \"HsFFI.h\"`.\r\n\r\nThis ticket is related to #2926 and the solution is almost certainly the same, but the motivation for this problem is slightly different.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1