GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2020-01-23T19:38:55Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/16009Deprecate `optional` from Text.ParserCombinators.ReadP2020-01-23T19:38:55ZdbaynardDeprecate `optional` from Text.ParserCombinators.ReadPIt seems there is some disagreement on what the type of `optional` should be, within `base`.
`Control.Applicative` defines it as
```haskell
optional :: Alternative f => f a -> f (Maybe a)
```
By contrast, `Text.ParserCombinators.ReadP...It seems there is some disagreement on what the type of `optional` should be, within `base`.
`Control.Applicative` defines it as
```haskell
optional :: Alternative f => f a -> f (Maybe a)
```
By contrast, `Text.ParserCombinators.ReadP` defines it as
```haskell
optional :: ReadP a -> ReadP ()
```
Worse, ReadP implements `Alternative`. So it entirely possible to specialise
```haskell
optional :: ReadP a -> ReadP (Maybe a).
```
In the broader Haskell ecosystem (and beyond) there is further confusion. The `Applicative` definition is used by `parsers`, `megaparsec` and purescript's `Data.Maybe`. The `ReadP` definition is used by `Parsec` and purescript's `Text.Parsing.StringParser`. `Cabal`, like `base` defines both.
I propose to begin to deprecate `ReadP.optional` ASAP, following suggestions in https://www.reddit.com/r/haskell/comments/8cqgds/inconsistent_optional_definitions/. Code which used the old form may still compile; otherwise `void` should be applied.
There have been some suggestions for new names for the `ReadP` definition, such as `optionally` or `optional_`. It may be worth exporting this function directly from `Control.Applicative`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.2 |
| 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":"Deprecate `optional` from Text.ParserCombinators.ReadP","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":["Applicative,","Parsers,","ReadP"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"It seems there is some disagreement on what the type of `optional` should be, within `base`.\r\n\r\n`Control.Applicative` defines it as\r\n\r\n{{{#!haskell\r\noptional :: Alternative f => f a -> f (Maybe a)\r\n}}}\r\n\r\nBy contrast, `Text.ParserCombinators.ReadP` defines it as\r\n\r\n{{{#!haskell\r\noptional :: ReadP a -> ReadP ()\r\n}}}\r\n\r\nWorse, ReadP implements `Alternative`. So it entirely possible to specialise\r\n\r\n{{{#!haskell\r\noptional :: ReadP a -> ReadP (Maybe a).\r\n}}}\r\n\r\nIn the broader Haskell ecosystem (and beyond) there is further confusion. The `Applicative` definition is used by `parsers`, `megaparsec` and purescript's `Data.Maybe`. The `ReadP` definition is used by `Parsec` and purescript's `Text.Parsing.StringParser`. `Cabal`, like `base` defines both.\r\n\r\nI propose to begin to deprecate `ReadP.optional` ASAP, following suggestions in https://www.reddit.com/r/haskell/comments/8cqgds/inconsistent_optional_definitions/. Code which used the old form may still compile; otherwise `void` should be applied.\r\n\r\nThere have been some suggestions for new names for the `ReadP` definition, such as `optionally` or `optional_`. It may be worth exporting this function directly from `Control.Applicative`.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16007Implement `-Os`2019-07-07T18:02:03ZSebastian GrafImplement `-Os`Popular C compilers like GCC or clang allow to optimise for binary size.
Since there are multiple ways in which GHC trades code size for faster programs, it might make sense to follow suit. This ticket is for tracking which optimisation...Popular C compilers like GCC or clang allow to optimise for binary size.
Since there are multiple ways in which GHC trades code size for faster programs, it might make sense to follow suit. This ticket is for tracking which optimisations/hacks in the compiler might be affected.
Feel free to add items to the following list:
- potentially huge impact due to specialisation, liberate case and inlining
- potential of -0.9% due to a second run of common block elimination (#14226)
- +0.1% increase in code size due to known calls instead of re-using generic apply thunks in #16005
- -0.1% due to `-fstg-lift-lams` #9476⊥https://gitlab.haskell.org/ghc/ghc/-/issues/16004Vector performance regression in GHC 8.62019-07-07T18:02:04ZGuillaume BouchardVector performance regression in GHC 8.6Hello.
With the following code, I can observe a performance regression between ghc 8.4 and 8.6:
```haskell
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import qualified Data.Vector.Unboxed.Mutable as Vector
import qualified D...Hello.
With the following code, I can observe a performance regression between ghc 8.4 and 8.6:
```haskell
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import qualified Data.Vector.Unboxed.Mutable as Vector
import qualified Data.Vector.Unboxed as VectorU
import Data.Foldable (for_)
main :: IO ()
main = do
let n = 1000
let vUnmutable :: VectorU.Vector Double = VectorU.generate (n * n) (\i -> fromIntegral i)
v :: Vector.IOVector Double <- VectorU.unsafeThaw vUnmutable
for_ [0..(n - 1)] $ \k -> do
for_ [0..(n - 1)] $ \i -> do
for_ [0..(n - 1)] $ \j -> do
a <- Vector.unsafeRead v (i * n + k)
b <- Vector.unsafeRead v (k * n + j)
c <- Vector.unsafeRead v (i * n + j)
Vector.unsafeWrite v (i * n + j) (min (a + b) c)
```
Built with `-O2` and with / without `-fllvm`. I'm using `vector-0.12.0.1`. Here are the timing results:
GHC 8.2.2
> no llvm: 1.7s
> llvm: 1.0s
GHC 8.4.4
> no llvm: 1.6s
> llvm: 0.9s
GHC 8.6.2
> no llvm: 4.8s
> llvm: 4.3s
I'm using the following bash + nix script to gather theses timings:
```bash
nix-shell -p 'haskell.packages.ghc822.ghcWithPackages(p: [p.vector])' --run "ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp; time ./FloydBench"
nix-shell -p 'haskell.packages.ghc822.ghcWithPackages(p: [p.vector])' -p llvm_39 --run "ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp -fllvm; time ./FloydBench"
nix-shell -p 'haskell.packages.ghc844.ghcWithPackages(p: [p.vector])' --run "ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp; time ./FloydBench"
nix-shell -p 'haskell.packages.ghc844.ghcWithPackages(p: [p.vector])' -p llvm_5 --run "ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp -fllvm; time ./FloydBench"
nix-shell -p 'haskell.packages.ghc862.ghcWithPackages(p: [p.vector])' --run "ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp; time ./FloydBench"
nix-shell -p 'haskell.packages.ghc862.ghcWithPackages(p: [p.vector])' -p llvm_6 --run "ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp -fllvm; time ./FloydBench"
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"Vector performance regression in GHC 8.6","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Hello.\r\n\r\nWith the following code, I can observe a performance regression between ghc 8.4 and 8.6:\r\n\r\n\r\n{{{#!haskell\r\n{-# LANGUAGE ScopedTypeVariables #-}\r\nmodule Main where\r\nimport qualified Data.Vector.Unboxed.Mutable as Vector\r\nimport qualified Data.Vector.Unboxed as VectorU\r\n\r\nimport Data.Foldable (for_)\r\n\r\nmain :: IO ()\r\nmain = do\r\n let n = 1000\r\n\r\n let vUnmutable :: VectorU.Vector Double = VectorU.generate (n * n) (\\i -> fromIntegral i)\r\n v :: Vector.IOVector Double <- VectorU.unsafeThaw vUnmutable\r\n\r\n for_ [0..(n - 1)] $ \\k -> do\r\n for_ [0..(n - 1)] $ \\i -> do\r\n for_ [0..(n - 1)] $ \\j -> do\r\n a <- Vector.unsafeRead v (i * n + k)\r\n b <- Vector.unsafeRead v (k * n + j)\r\n c <- Vector.unsafeRead v (i * n + j)\r\n Vector.unsafeWrite v (i * n + j) (min (a + b) c)\r\n}}}\r\n\r\nBuilt with `-O2` and with / without `-fllvm`. I'm using `vector-0.12.0.1`. Here are the timing results:\r\n\r\nGHC 8.2.2\r\n no llvm: 1.7s\r\n llvm: 1.0s\r\nGHC 8.4.4\r\n no llvm: 1.6s\r\n llvm: 0.9s\r\nGHC 8.6.2\r\n no llvm: 4.8s\r\n llvm: 4.3s\r\n\r\nI'm using the following bash + nix script to gather theses timings:\r\n\r\n{{{#!bash\r\nnix-shell -p 'haskell.packages.ghc822.ghcWithPackages(p: [p.vector])' --run \"ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp; time ./FloydBench\"\r\nnix-shell -p 'haskell.packages.ghc822.ghcWithPackages(p: [p.vector])' -p llvm_39 --run \"ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp -fllvm; time ./FloydBench\"\r\nnix-shell -p 'haskell.packages.ghc844.ghcWithPackages(p: [p.vector])' --run \"ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp; time ./FloydBench\"\r\nnix-shell -p 'haskell.packages.ghc844.ghcWithPackages(p: [p.vector])' -p llvm_5 --run \"ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp -fllvm; time ./FloydBench\"\r\nnix-shell -p 'haskell.packages.ghc862.ghcWithPackages(p: [p.vector])' --run \"ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp; time ./FloydBench\"\r\nnix-shell -p 'haskell.packages.ghc862.ghcWithPackages(p: [p.vector])' -p llvm_6 --run \"ghc-pkg list | grep vector; ghc -O2 FloydBench.hs -Wall -fforce-recomp -fllvm; time ./FloydBench\"\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15998GHC.Event.Thread.eventManager has a lot of indirections2019-07-07T18:02:06ZchessaiGHC.Event.Thread.eventManager has a lot of indirectionsCurrent `eventManager`:
```hs
eventManager :: IORef (IOArray Int (Maybe (ThreadId, EventManager)))
eventManager = unsafePerformIO $ do
...
```
That's a lot of indirections just to grab your thread's event manager.
Consider the followi...Current `eventManager`:
```hs
eventManager :: IORef (IOArray Int (Maybe (ThreadId, EventManager)))
eventManager = unsafePerformIO $ do
...
```
That's a lot of indirections just to grab your thread's event manager.
Consider the following, which I believe would improve the performance of this:
```hs
data UnliftedIORef :: TYPE 'UnliftedRep -> Type where
UnliftedIORef :: MutVar# RealWorld a -> UnliftedIORef a
eventManager :: UnliftedIORef (MutableArray# RealWorld Things)
data Things = Things !ThreadId !EventManager
```
I think the Maybe can be eliminated. I'm unsure. What makes me think it can be is the following snippet:
```hs
getSystemEventManager :: IO (Maybe EventManager)
getSystemEventManager = do
t <- myThreadId
(cap, _) <- threadCapability t
eventManagerArray <- readIORef eventManager
mmgr <- readIOArray eventManagerArray cap
return $ fmap snd mmgr
getSystemEventManager_ :: IO EventManager
getSystemEventManager_ = do
Just mgr <- getSystemEventManager
return mgr
{-# INLINE getSystemEventManager_ #-}
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.2 |
| 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":"GHC.Event.Thread.eventManager has a lot of indirections","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Current `eventManager`:\r\n\r\n{{{#!hs\r\neventManager :: IORef (IOArray Int (Maybe (ThreadId, EventManager)))\r\neventManager = unsafePerformIO $ do\r\n...\r\n}}}\r\n\r\nThat's a lot of indirections just to grab your thread's event manager.\r\n\r\nConsider the following, which I believe would improve the performance of this:\r\n\r\n{{{#!hs\r\ndata UnliftedIORef :: TYPE 'UnliftedRep -> Type where\r\n UnliftedIORef :: MutVar# RealWorld a -> UnliftedIORef a\r\n\r\neventManager :: UnliftedIORef (MutableArray# RealWorld Things)\r\n\r\ndata Things = Things !ThreadId !EventManager\r\n}}}\r\n\r\nI think the Maybe can be eliminated. I'm unsure. What makes me think it can be is the following snippet:\r\n\r\n{{{#!hs\r\ngetSystemEventManager :: IO (Maybe EventManager)\r\ngetSystemEventManager = do\r\n t <- myThreadId\r\n (cap, _) <- threadCapability t\r\n eventManagerArray <- readIORef eventManager\r\n mmgr <- readIOArray eventManagerArray cap\r\n return $ fmap snd mmgr\r\n\r\ngetSystemEventManager_ :: IO EventManager\r\ngetSystemEventManager_ = do\r\n Just mgr <- getSystemEventManager\r\n return mgr\r\n{-# INLINE getSystemEventManager_ #-}\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15997EventManager could benefit from Data.Primitive.UnliftedArray2019-07-07T18:02:06ZchessaiEventManager could benefit from Data.Primitive.UnliftedArray```hs
-- | The event manager state.
data EventManager = EventManager
{ emBackend :: !Backend
, emFds :: {-# UNPACK #-} !(Array Int (MVar (IntTable [FdData])))
, emState :: {-# UNPACK #-} !(IORef State)
...```hs
-- | The event manager state.
data EventManager = EventManager
{ emBackend :: !Backend
, emFds :: {-# UNPACK #-} !(Array Int (MVar (IntTable [FdData])))
, emState :: {-# UNPACK #-} !(IORef State)
, emUniqueSource :: {-# UNPACK #-} !UniqueSource
, emControl :: {-# UNPACK #-} !Control
, emLock :: {-# UNPACK #-} !(MVar ())
}
```
the field in question is an `Array Int (MVar (IntTable [FdData]))`.
`EventManager` could instead be:
```hs
type MVarIO = MVar# RealWorld -- type synonym for brevity
-- | The event manager state.
data EventManager = EventManager
{ emBackend :: !Backend
, emFds :: {-# UNPACK #-} !(UnliftedArray (MVarIO (IntTable [FdData])))
, emState :: {-# UNPACK #-} !(IORef State)
, emUniqueSource :: {-# UNPACK #-} !UniqueSource
, emControl :: {-# UNPACK #-} !Control
, emLock :: {-# UNPACK #-} !(MVar ())
}
```
now the `UnliftedArray` contains non-thunks.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.2 |
| 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":"EventManager could benefit from Data.Primitive.UnliftedArray","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"{{{#!hs\r\n-- | The event manager state.\r\ndata EventManager = EventManager\r\n { emBackend :: !Backend\r\n , emFds :: {-# UNPACK #-} !(Array Int (MVar (IntTable [FdData])))\r\n , emState :: {-# UNPACK #-} !(IORef State)\r\n , emUniqueSource :: {-# UNPACK #-} !UniqueSource\r\n , emControl :: {-# UNPACK #-} !Control\r\n , emLock :: {-# UNPACK #-} !(MVar ())\r\n }\r\n}}}\r\n\r\nthe field in question is an `Array Int (MVar (IntTable [FdData]))`.\r\n\r\n`EventManager` could instead be:\r\n\r\n{{{#!hs\r\n\r\ntype MVarIO = MVar# RealWorld -- type synonym for brevity\r\n\r\n-- | The event manager state.\r\ndata EventManager = EventManager\r\n { emBackend :: !Backend\r\n , emFds :: {-# UNPACK #-} !(UnliftedArray (MVarIO (IntTable [FdData])))\r\n , emState :: {-# UNPACK #-} !(IORef State)\r\n , emUniqueSource :: {-# UNPACK #-} !UniqueSource\r\n , emControl :: {-# UNPACK #-} !Control\r\n , emLock :: {-# UNPACK #-} !(MVar ())\r\n }\r\n}}}\r\n\r\nnow the `UnliftedArray` contains non-thunks.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15996Add Unlifted List type to base2023-04-01T11:56:26ZchessaiAdd Unlifted List type to base```hs
data UList (a :: TYPE 'UnliftedRep) where
UNil :: UList a
UCons :: a -> UList a -> UList a
```
This would guarantee that values stored inside the list would not be thunks. It would likely live in something like GHC.List.Unlift...```hs
data UList (a :: TYPE 'UnliftedRep) where
UNil :: UList a
UCons :: a -> UList a -> UList a
```
This would guarantee that values stored inside the list would not be thunks. It would likely live in something like GHC.List.Unlifted, since it uses GHC-specific things.
An example of something it might improve is the implementation of Control.Concurrent.QSem.QSem:
```hs
data QSem = QSem !(MVar (Int, [MVar ()], [MVar ()]))
```
this could instead be:
```hs
type MVarIO = MVar# RealWorld -- type synonym for brevity
data QSem = QSem (MVarIO (Int, UList (MVarIO ()), UList (MVarIO ())))
```
Note that in this example the tuple inside the outermost `MVarIO` boxes the `Int` - this tuple could be represented as a datatype which ensures the unboxing on the `Int`.
The main idea here though is that now you can use `MVar#` inside of the `UList`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.2 |
| 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 Unlifted List type to base","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"{{{#!hs\r\ndata UList (a :: TYPE 'UnliftedRep) where\r\n UNil :: UList a\r\n UCons :: a -> UList a -> UList a\r\n}}}\r\n\r\nThis would guarantee that values stored inside the list would not be thunks. It would likely live in something like GHC.List.Unlifted, since it uses GHC-specific things.\r\n\r\nAn example of something it might improve is the implementation of Control.Concurrent.QSem.QSem:\r\n\r\n{{{#!hs\r\ndata QSem = QSem !(MVar (Int, [MVar ()], [MVar ()]))\r\n}}}\r\n\r\nthis could instead be:\r\n\r\n{{{#!hs\r\ntype MVarIO = MVar# RealWorld -- type synonym for brevity\r\n\r\ndata QSem = QSem (MVarIO (Int, UList (MVarIO ()), UList (MVarIO ())))\r\n}}}\r\n\r\nNote that in this example the tuple inside the outermost `MVarIO` boxes the `Int` - this tuple could be represented as a datatype which ensures the unboxing on the `Int`.\r\n\r\nThe main idea here though is that now you can use `MVar#` inside of the `UList`.\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15992Alternative instance for Data.Functor.Compose causes <<loop>>s with some types2019-07-07T18:02:07ZglaebhoerlAlternative instance for Data.Functor.Compose causes <<loop>>s with some types`many` and `some` are [omitted](http://hackage.haskell.org/package/base-4.12.0.0/docs/src/Data.Functor.Compose.html#line-119) and are filled in by their defaults from `Alternative`, instead of re-using the definitions provided for `f`; t...`many` and `some` are [omitted](http://hackage.haskell.org/package/base-4.12.0.0/docs/src/Data.Functor.Compose.html#line-119) and are filled in by their defaults from `Alternative`, instead of re-using the definitions provided for `f`; this manifests as infinite grammars being created in the case of the Earley parsing library, resulting in `<<loop>>` errors at runtime.
The fix is just to add:
```hs
many = Compose . fmap sequenceA . many . getCompose
some = Compose . fmap sequenceA . some . getCompose
```
Related twitter thread: https://twitter.com/ollfredo/status/1067498140100628480
(It seems like this bug has been around for some time: https://github.com/feuerbach/regex-applicative/issues/19)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.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":"Alternative instance for Data.Functor.Compose causes <<loop>>s with some types","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"`many` and `some` are [http://hackage.haskell.org/package/base-4.12.0.0/docs/src/Data.Functor.Compose.html#line-119 omitted] and are filled in by their defaults from `Alternative`, instead of re-using the definitions provided for `f`; this manifests as infinite grammars being created in the case of the Earley parsing library, resulting in `<<loop>>` errors at runtime.\r\n\r\nThe fix is just to add:\r\n\r\n{{{#!hs\r\n many = Compose . fmap sequenceA . many . getCompose\r\n some = Compose . fmap sequenceA . some . getCompose\r\n}}}\r\n\r\nRelated twitter thread: https://twitter.com/ollfredo/status/1067498140100628480\r\n\r\n(It seems like this bug has been around for some time: https://github.com/feuerbach/regex-applicative/issues/19)","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15991Regression in error message when attempting to let bind an existentially quan...2020-07-30T10:51:20ZmmailhotRegression in error message when attempting to let bind an existentially quantified typeWhen attempting to compile the following (invalid) program:
```hs
{-# LANGUAGE ExistentialQuantification #-}
data Foo = forall a. Foo a
main :: IO ()
main =
let Foo x = Foo 1 in
return ()
```
GHC 8.6.2.0 (and 8.6.1.0, 8.4.1.0...When attempting to compile the following (invalid) program:
```hs
{-# LANGUAGE ExistentialQuantification #-}
data Foo = forall a. Foo a
main :: IO ()
main =
let Foo x = Foo 1 in
return ()
```
GHC 8.6.2.0 (and 8.6.1.0, 8.4.1.0) gives the following complicated error message
```
Test.hs:7:13: error:
• Couldn't match expected type ‘p’ with actual type ‘a’
because type variable ‘a’ would escape its scope
This (rigid, skolem) type variable is bound by
a pattern with constructor: Foo :: forall a. a -> Foo,
in a pattern binding
at Test.hs:7:9-13
• In the pattern: Foo x
In a pattern binding: Foo x = Foo 1
In the expression: let Foo x = Foo 1 in return ()
|
7 | let Foo x = Foo 1 in
|
```
GHC 7.10.1.2 gave a much more helpful and direct error message
```
Test.hs:7:9:
My brain just exploded
I can't handle pattern bindings for existential or GADT data constructors.
Instead, use a case-expression, or do-notation, to unpack the constructor.
In the pattern: Foo x
In a pattern binding: Foo x = Foo 1
In the expression: let Foo x = Foo 1 in return ()
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.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":"Regression in error message when attempting to let bind an existentially quantified type","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When attempting to compile the following (invalid) program:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE ExistentialQuantification #-}\r\n\r\ndata Foo = forall a. Foo a\r\n\r\nmain :: IO ()\r\nmain =\r\n let Foo x = Foo 1 in\r\n return ()\r\n}}}\r\n\r\nGHC 8.6.2.0 (and 8.6.1.0, 8.4.1.0) gives the following complicated error message\r\n\r\n{{{\r\n\r\nTest.hs:7:13: error:\r\n • Couldn't match expected type ‘p’ with actual type ‘a’\r\n because type variable ‘a’ would escape its scope\r\n This (rigid, skolem) type variable is bound by\r\n a pattern with constructor: Foo :: forall a. a -> Foo,\r\n in a pattern binding\r\n at Test.hs:7:9-13\r\n • In the pattern: Foo x\r\n In a pattern binding: Foo x = Foo 1\r\n In the expression: let Foo x = Foo 1 in return ()\r\n |\r\n7 | let Foo x = Foo 1 in\r\n | \r\n}}}\r\n\r\nGHC 7.10.1.2 gave a much more helpful and direct error message\r\n\r\n{{{\r\nTest.hs:7:9:\r\n My brain just exploded\r\n I can't handle pattern bindings for existential or GADT data constructors.\r\n Instead, use a case-expression, or do-notation, to unpack the constructor.\r\n In the pattern: Foo x\r\n In a pattern binding: Foo x = Foo 1\r\n In the expression: let Foo x = Foo 1 in return ()\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15989Adding extra quantified constraints leads to resolution failure2019-07-07T18:02:08ZerorAdding extra quantified constraints leads to resolution failure```
{-# LANGUAGE QuantifiedConstraints, FlexibleContexts #-}
import Control.Monad.Reader
data T x = T
ok :: ( forall x x'. MonadReader (T x) (m x') )
=> m y Bool
ok = fmap not (pure True)
bad :: ( forall x x'. MonadReader (T x) (...```
{-# LANGUAGE QuantifiedConstraints, FlexibleContexts #-}
import Control.Monad.Reader
data T x = T
ok :: ( forall x x'. MonadReader (T x) (m x') )
=> m y Bool
ok = fmap not (pure True)
bad :: ( forall x x'. MonadReader (T x) (m x')
, forall x. Monad (m x) )
=> m y Bool
bad = fmap not (pure True)
better :: ( forall x x'. MonadReader (T x) (m x')
, forall x. Applicative (m x)
, forall x. Functor (m x) )
=> m y Bool
better = fmap not (pure True)
```
`ok` and `better` compile, but `bad` fails to resolve, despite having strictly more in the context than `ok`:
```
BadQC.hs:15:7: error:
• Could not deduce (Functor (m y)) arising from a use of ‘fmap’
from the context: (forall x x'. MonadReader (T x) (m x'),
forall x. Monad (m x))
bound by the type signature for:
bad :: forall (m :: * -> * -> *) y.
(forall x x'. MonadReader (T x) (m x'), forall x. Monad (m x)) =>
m y Bool
at BadQC.hs:(12,1)-(14,15)
• In the expression: fmap not (pure True)
In an equation for ‘bad’: bad = fmap not (pure True)
|
15 | bad = fmap not (pure True)
| ^^^^^^^^^^^^^^^^^^^^
BadQC.hs:15:17: error:
• Could not deduce (Applicative (m y)) arising from a use of ‘pure’
from the context: (forall x x'. MonadReader (T x) (m x'),
forall x. Monad (m x))
bound by the type signature for:
bad :: forall (m :: * -> * -> *) y.
(forall x x'. MonadReader (T x) (m x'), forall x. Monad (m x)) =>
m y Bool
at BadQC.hs:(12,1)-(14,15)
• In the second argument of ‘fmap’, namely ‘(pure True)’
In the expression: fmap not (pure True)
In an equation for ‘bad’: bad = fmap not (pure True)
|
15 | bad = fmap not (pure True)
| ^^^^^^^^^
Failed, no modules loaded.
```
Also:
- `( forall x. MonadReader (T x) (m x), forall x. Monad (m x) )` compiles — the error seems to require two quantified type variables
- `( forall x x'. Monad (m x), forall x. Monad (m x) )` reports an ambiguity error on the constraint, which makes sense; if I turn on `AllowAmbiguousTypes`, it fails with the same error as above — the error isn't caused by MPTCs, and it doesn't matter that `x'` is unused
- `( forall x x'. Foldable (m x), forall x. Monad (m x) )` and `( forall x x'. Monad (m x), forall x. Foldable (m x) )` compile — being in the same class hierarchy matters
- `( forall x x'. Applicative (m x), forall x. Monad (m x) )` fails on `fmap` (but not `pure`) — which is the superclass doesn't seem to matter8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15988Remove Text.Printf and System.Console.GetOpt from base2019-07-07T18:02:08ZAndrew MartinRemove Text.Printf and System.Console.GetOpt from baseThis was touched on in brief in a recent mailing list thread found at https://mail.haskell.org/pipermail/libraries/2018-October/029012.html. I propose removing `Text.Printf` and `System.Console.GetOpt` from `base` and moving them into th...This was touched on in brief in a recent mailing list thread found at https://mail.haskell.org/pipermail/libraries/2018-October/029012.html. I propose removing `Text.Printf` and `System.Console.GetOpt` from `base` and moving them into their own packages named `printf` and `getopt` that would be managed by the haskell github organization. These two libraries, when built against newer versions of base, would provide the modules. When built against old versions of base, they would simply reexport the modules. There would be breakage from doing this, but libraries and applications that use these APIs would only need to add a single line to `build-depends` to continue being compatible with all versions of `base`.
The benefits of doing this are small. As a matter of principle, it seems unfair that these two APIs are blessed by being a part of base when the would likely struggle to compete if they were in ordinary libraries. In particular, `printf` is less idiomatic and performs worse that the functions from `Numeric` (like `showFFloat`), but its prominent position in `base` encourages users to overlook the more type-safe options available for formatting numbers.
More practically, the size of base does occassionally cause problems. In https://github.com/haskell/primitive/issues/218\#issuecomment-443534850, Carter writes
> base getting bigger actually hurts folk, eg, base recently got big enough that dwarf data gnerated by ghc at -g1 is now sooo much that you can't do a dwarf annotated build of base on mac OS X! anymore
Moving these APIs out of `base` makes a small step toward addressing this problem.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.2 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Remove Text.Printf and System.Console.GetOpt from base","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"This was touched on in brief in a recent mailing list thread found at https://mail.haskell.org/pipermail/libraries/2018-October/029012.html. I propose removing `Text.Printf` and `System.Console.GetOpt` from `base` and moving them into their own packages named `printf` and `getopt` that would be managed by the haskell github organization. These two libraries, when built against newer versions of base, would provide the modules. When built against old versions of base, they would simply reexport the modules. There would be breakage from doing this, but libraries and applications that use these APIs would only need to add a single line to `build-depends` to continue being compatible with all versions of `base`.\r\n\r\nThe benefits of doing this are small. As a matter of principle, it seems unfair that these two APIs are blessed by being a part of base when the would likely struggle to compete if they were in ordinary libraries. In particular, `printf` is less idiomatic and performs worse that the functions from `Numeric` (like `showFFloat`), but its prominent position in `base` encourages users to overlook the more type-safe options available for formatting numbers.\r\n\r\nMore practically, the size of base does occassionally cause problems. In https://github.com/haskell/primitive/issues/218#issuecomment-443534850, Carter writes\r\n\r\n> base getting bigger actually hurts folk, eg, base recently got big enough that dwarf data gnerated by ghc at -g1 is now sooo much that you can't do a dwarf annotated build of base on mac OS X! anymore\r\n\r\nMoving these APIs out of `base` makes a small step toward addressing this problem.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15984Backpack accepts ill-kinded instantiations. Can cause GHC panic2019-07-07T18:02:09ZaaronvargoBackpack accepts ill-kinded instantiations. Can cause GHC panicGiven the following:
```hs
{-# language KindSignatures #-}
signature A where
data A :: *
```
```hs
module Foo where
import A
foo :: A -> A
foo = id
```
```hs
module IllKindedA where
type A = Maybe
```
GHC allows the signature `A`...Given the following:
```hs
{-# language KindSignatures #-}
signature A where
data A :: *
```
```hs
module Foo where
import A
foo :: A -> A
foo = id
```
```hs
module IllKindedA where
type A = Maybe
```
GHC allows the signature `A` to be instantiated with `IllKindedA`:
```
mixins: foo (Foo as Bug) requires (A as IllKindedA)
```
Using the resulting module can cause odd errors or a panic. E.g. the following causes a panic:
```hs
module Bar where
import Bug
bar = foo
```
```
ghc: panic! (the 'impossible' happened)
(GHC version 8.6.2 for x86_64-unknown-linux):
getRuntimeRep
A :: * -> *
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/utils/Outputable.hs:1160:37 in ghc:Outputable
pprPanic, called at compiler/types/Type.hs:2049:18 in ghc:Type
```8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15983Built-in support for half-floats2019-07-07T18:02:09ZLevent ErkökBuilt-in support for half-floatsHalf-floats (16-bit floating point values with 1-bit sign, 5-bits of exponent, and 10 bits of mantissa) are becoming more and more common in this new era of data-centric programming: Almost all GPUs have native support, and most CPU's ar...Half-floats (16-bit floating point values with 1-bit sign, 5-bits of exponent, and 10 bits of mantissa) are becoming more and more common in this new era of data-centric programming: Almost all GPUs have native support, and most CPU's are starting to support them natively in their instruction set.
It would be great if GHC can lead the way and have half-floats as a natively supported data-type as well, just like Float and Double.
I'm aware of Edward's http://hackage.haskell.org/package/half package; so that could be a starting point; though we'd eventually want GHC to generate native code. Note that LLVM does support half-floats, so a viable path can be using LLVM when available and software-FFI/implementation otherwise. Eventually the native code generator can add support as well.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.2 |
| 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":"Built-in support for half-floats","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Half-floats (16-bit floating point values with 1-bit sign, 5-bits of exponent, and 10 bits of mantissa) are becoming more and more common in this new era of data-centric programming: Almost all GPUs have native support, and most CPU's are starting to support them natively in their instruction set.\r\n\r\nIt would be great if GHC can lead the way and have half-floats as a natively supported data-type as well, just like Float and Double.\r\n\r\nI'm aware of Edward's http://hackage.haskell.org/package/half package; so that could be a starting point; though we'd eventually want GHC to generate native code. Note that LLVM does support half-floats, so a viable path can be using LLVM when available and software-FFI/implementation otherwise. Eventually the native code generator can add support as well.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15979Core Lint error with LiberalTypeSynonyms2022-12-08T17:36:30ZRyan ScottCore Lint error with LiberalTypeSynonymsSee main ticket #22063
```hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LiberalTypeSynonyms #-}
{-# LANGUAGE PolyKinds #-}
{-# OPTIONS_GHC -dcore-lint #-}
module Bug where
import Data.Kind
type KindOf (a :: k) = k
wat :: KindOf (forall...See main ticket #22063
```hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LiberalTypeSynonyms #-}
{-# LANGUAGE PolyKinds #-}
{-# OPTIONS_GHC -dcore-lint #-}
module Bug where
import Data.Kind
type KindOf (a :: k) = k
wat :: KindOf (forall (a :: ()). a)
wat = ()
```
```
$ /opt/ghc/8.6.2/bin/ghc Bug.hs
[1 of 1] Compiling Bug ( Bug.hs, Bug.o )
*** Core Lint errors : in result of Desugar (before optimization) ***
<no location info>: warning:
In the type ‘KindOf (forall (a :: ()). a)’
Non-*-like kind when *-like expected: ()
when checking the body of forall: forall (a :: ()). a
*** Offending Program ***
Rec {
$trModule :: Module
[LclIdX]
$trModule = Module (TrNameS "main"#) (TrNameS "Bug"#)
wat :: KindOf (forall (a :: ()). a)
[LclIdX]
wat = ()
end Rec }
*** End of Offense ***
<no location info>: error:
Compilation had errors
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"Core Lint error with LiberalTypeSynonyms","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.8.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{#!hs\r\n{-# LANGUAGE DataKinds #-}\r\n{-# LANGUAGE LiberalTypeSynonyms #-}\r\n{-# LANGUAGE PolyKinds #-}\r\n{-# OPTIONS_GHC -dcore-lint #-}\r\nmodule Bug where\r\n\r\nimport Data.Kind\r\n\r\ntype KindOf (a :: k) = k\r\n\r\nwat :: KindOf (forall (a :: ()). a)\r\nwat = ()\r\n}}}\r\n{{{\r\n$ /opt/ghc/8.6.2/bin/ghc Bug.hs\r\n[1 of 1] Compiling Bug ( Bug.hs, Bug.o )\r\n*** Core Lint errors : in result of Desugar (before optimization) ***\r\n<no location info>: warning:\r\n In the type ‘KindOf (forall (a :: ()). a)’\r\n Non-*-like kind when *-like expected: ()\r\n when checking the body of forall: forall (a :: ()). a\r\n*** Offending Program ***\r\nRec {\r\n$trModule :: Module\r\n[LclIdX]\r\n$trModule = Module (TrNameS \"main\"#) (TrNameS \"Bug\"#)\r\n\r\nwat :: KindOf (forall (a :: ()). a)\r\n[LclIdX]\r\nwat = ()\r\nend Rec }\r\n\r\n*** End of Offense ***\r\n\r\n\r\n<no location info>: error: \r\nCompilation had errors\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/15977Restructure typechecking modules2019-07-07T18:02:11ZRichard Eisenbergrae@richarde.devRestructure typechecking modulesSome of the kind-checking and type-checking modules have become unruly.
Simon and I propose the new structure:
- KcTyClsDecls will handle kind-checking and generalization of datatype declarations. (That is, `kcTyClGroup` and children, ...Some of the kind-checking and type-checking modules have become unruly.
Simon and I propose the new structure:
- KcTyClsDecls will handle kind-checking and generalization of datatype declarations. (That is, `kcTyClGroup` and children, including related functions in TcHsType)
- TcInstBinds will handle `tcInstDecls2` and children
- TcTyConValidity will handle `checkValidTyCon` and children
- Fold the rest of TcInstDecls (essentially, `tcInstDecls1`) into what's left of TcTyClsDecls. TcInstDecls is removed.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.2 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Restructure typechecking modules","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Some of the kind-checking and type-checking modules have become unruly.\r\n\r\nSimon and I propose the new structure:\r\n\r\n- KcTyClsDecls will handle kind-checking and generalization of datatype declarations. (That is, `kcTyClGroup` and children, including related functions in TcHsType)\r\n\r\n- TcInstBinds will handle `tcInstDecls2` and children\r\n\r\n- TcTyConValidity will handle `checkValidTyCon` and children\r\n\r\n- Fold the rest of TcInstDecls (essentially, `tcInstDecls1`) into what's left of TcTyClsDecls. TcInstDecls is removed.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15976Can't run nofib in parallel2019-07-07T18:02:11ZSebastian GrafCan't run nofib in parallelI was under the impression that `make -j$n` within `nofib` would run benchmarks in parallel, but it doesn't. The following warning is indicative:
```
make[1]: warning: -jN forced in submake: disabling jobserver mode.
```
Whenever `make...I was under the impression that `make -j$n` within `nofib` would run benchmarks in parallel, but it doesn't. The following warning is indicative:
```
make[1]: warning: -jN forced in submake: disabling jobserver mode.
```
Whenever `make` is called recursively, any `-j` flags will lead to this warning and consequently disable parallelisation (which would lead to a number of jobs exponential in the depth of recursive calls).
Parallel benchmarks are useful to get deterministic metrics such as allocations or counted instructions really fast.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------------- |
| Version | |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | NoFib benchmark suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Can't run nofib in parallel","status":"New","operating_system":"","component":"NoFib benchmark suite","related":[],"milestone":"⊥","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I was under the impression that `make -j$n` within `nofib` would run benchmarks in parallel, but it doesn't. The following warning is indicative:\r\n\r\n{{{\r\nmake[1]: warning: -jN forced in submake: disabling jobserver mode.\r\n}}}\r\n\r\nWhenever `make` is called recursively, any `-j` flags will lead to this warning and consequently disable parallelisation (which would lead to a number of jobs exponential in the depth of recursive calls).\r\n\r\nParallel benchmarks are useful to get deterministic metrics such as allocations or counted instructions really fast.","type_of_failure":"OtherFailure","blocking":[]} -->⊥https://gitlab.haskell.org/ghc/ghc/-/issues/15975semantics of concurrent program depends on -O level, -f[no-]omit-yields2023-05-09T23:14:05Zwaldmann@imn.htwk-leipzig.desemantics of concurrent program depends on -O level, -f[no-]omit-yieldsI am surprised by the behaviour of the program below
(the interesting property is whether it will output "foo").
Behaviours (plural) actually: it seems to depend
on optimisation level, on omit-yields,
and on very small changes in the so...I am surprised by the behaviour of the program below
(the interesting property is whether it will output "foo").
Behaviours (plural) actually: it seems to depend
on optimisation level, on omit-yields,
and on very small changes in the source code:
It does print (mostly), when compiled with -O0.
It does not, when compiled with -O2.
With -O2 -fno-omit-yields, it will print.
With -O0 -fno-omit-yields, and when I remove the two newTVar
in the beginning, it will mostly not print.
How come?
These differences already occur with the
last two lines replaced by "forever $ return ()",
so the STM stuff may be inessential here.
But that's the context where I came across the problem.
See also discussion at https://mail.haskell.org/pipermail/haskell-cafe/2018-November/130274.html
```
import Control.Concurrent.STM
import Control.Concurrent ( forkIO )
import Control.Monad ( forever )
import System.IO
main = do
atomically $ newTVar "bar"
atomically $ newTVar False
forkIO $ putStrLn "foo"
x <- atomically $ newTVar False
forever $ atomically $ writeTVar x True
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"semantics of concurrent program depends on -O level, -f[no-]omit-yields","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"Research needed","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I am surprised by the behaviour of the program below\r\n(the interesting property is whether it will output \"foo\").\r\n\r\nBehaviours (plural) actually: it seems to depend\r\non optimisation level, on omit-yields,\r\nand on very small changes in the source code:\r\n\r\nIt does print (mostly), when compiled with -O0.\r\nIt does not, when compiled with -O2.\r\nWith -O2 -fno-omit-yields, it will print.\r\nWith -O0 -fno-omit-yields, and when I remove the two newTVar\r\nin the beginning, it will mostly not print.\r\n\r\nHow come?\r\n\r\nThese differences already occur with the\r\nlast two lines replaced by \"forever $ return ()\",\r\nso the STM stuff may be inessential here.\r\nBut that's the context where I came across the problem.\r\n\r\n\r\nSee also discussion at https://mail.haskell.org/pipermail/haskell-cafe/2018-November/130274.html\r\n\r\n\r\n{{{\r\nimport Control.Concurrent.STM\r\nimport Control.Concurrent ( forkIO )\r\nimport Control.Monad ( forever )\r\nimport System.IO\r\n\r\nmain = do\r\n\r\n atomically $ newTVar \"bar\"\r\n atomically $ newTVar False\r\n\r\n forkIO $ putStrLn \"foo\"\r\n\r\n x <- atomically $ newTVar False\r\n forever $ atomically $ writeTVar x True\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/15973Int used to represent target integer literals2019-07-07T18:02:12ZBen GamariInt used to represent target integer literalsThere are numerous places within GHC where we use `Int` to represent a constant literal for the target. For instance, `CmmUtils` has the following:
```hs
-- XXX: should really be Integer, since Int doesn't necessarily cover
-- the full ...There are numerous places within GHC where we use `Int` to represent a constant literal for the target. For instance, `CmmUtils` has the following:
```hs
-- XXX: should really be Integer, since Int doesn't necessarily cover
-- the full range of target Ints.
mkIntCLit :: DynFlags -> Int -> CmmLit
mkIntCLit dflags i = CmmInt (toInteger i) (wordWidth dflags)
```
This could go very wrong when cross-compiling from a 32-bit machine to a 64-bit target.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"Int used to represent target integer literals","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":["newcomer"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"There are numerous places within GHC where we use `Int` to represent a constant literal for the target. For instance, `CmmUtils` has the following:\r\n{{{#!hs\r\n-- XXX: should really be Integer, since Int doesn't necessarily cover\r\n-- the full range of target Ints.\r\nmkIntCLit :: DynFlags -> Int -> CmmLit\r\nmkIntCLit dflags i = CmmInt (toInteger i) (wordWidth dflags)\r\n}}}\r\nThis could go very wrong when cross-compiling from a 32-bit machine to a 64-bit target.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15969Generic1 deriving should use more coercions2022-06-19T21:04:37ZDavid FeuerGeneric1 deriving should use more coercionsConsider
```hs
newtype Foo a = Foo (Maybe [a]) deriving (Generic1)
```
This produces some rather unsatisfactory Core:
```
-- to1 worker
Travv.$fGeneric1Foo1 :: forall a. Rep1 Foo a -> Maybe [a]
Travv.$fGeneric1Foo1
= \ (@ a_a7RL) (d...Consider
```hs
newtype Foo a = Foo (Maybe [a]) deriving (Generic1)
```
This produces some rather unsatisfactory Core:
```
-- to1 worker
Travv.$fGeneric1Foo1 :: forall a. Rep1 Foo a -> Maybe [a]
Travv.$fGeneric1Foo1
= \ (@ a_a7RL) (ds_d9dZ :: Rep1 Foo a_a7RL) ->
case ds_d9dZ `cast` <Co:103> of {
Nothing -> GHC.Maybe.Nothing @ [a_a7RL];
Just a1_a9fD -> GHC.Maybe.Just @ [a_a7RL] (a1_a9fD `cast` <Co:5>)
}
-- from1 worker
Travv.$fGeneric1Foo2 :: forall a. Foo a -> Maybe (Rec1 [] a)
Travv.$fGeneric1Foo2
= \ (@ a_a7R6) (x_a7GJ :: Foo a_a7R6) ->
case x_a7GJ `cast` <Co:2> of {
Nothing -> GHC.Maybe.Nothing @ (Rec1 [] a_a7R6);
Just a1_a9fD ->
GHC.Maybe.Just @ (Rec1 [] a_a7R6) (a1_a9fD `cast` <Co:6>)
}
```
Both of these functions could be implemented as safe coercions, but neither of them is! Similarly, if I define
```hs
data Bar a = Bar (Maybe [a]) deriving Generic1
```
I get a `to1` worker that looks like
```
Travv.$fGeneric1Bar_$cto1 :: forall a. Rep1 Bar a -> Bar a
Travv.$fGeneric1Bar_$cto1
= \ (@ a_a7UA) (ds_d9ho :: Rep1 Bar a_a7UA) ->
Travv.Bar
@ a_a7UA
(case ds_d9ho `cast` <Co:103> of {
Nothing -> GHC.Maybe.Nothing @ [a_a7UA];
Just a1_a9iK -> GHC.Maybe.Just @ [a_a7UA] (a1_a9iK `cast` <Co:5>)
})
```
That `case` expression should really just be a cast.
I think the basic trick is probably to inspect the role of the type argument of each type in a composition, using that to work out whether to coerce that step.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | RyanGlScott |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Generic1 deriving should use more coercions","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.8.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":["Generics"],"differentials":[],"test_case":"","architecture":"","cc":["RyanGlScott"],"type":"Bug","description":"Consider\r\n\r\n{{{#!hs\r\nnewtype Foo a = Foo (Maybe [a]) deriving (Generic1)\r\n}}}\r\n\r\nThis produces some rather unsatisfactory Core:\r\n\r\n{{{\r\n-- to1 worker\r\nTravv.$fGeneric1Foo1 :: forall a. Rep1 Foo a -> Maybe [a]\r\nTravv.$fGeneric1Foo1\r\n = \\ (@ a_a7RL) (ds_d9dZ :: Rep1 Foo a_a7RL) ->\r\n case ds_d9dZ `cast` <Co:103> of {\r\n Nothing -> GHC.Maybe.Nothing @ [a_a7RL];\r\n Just a1_a9fD -> GHC.Maybe.Just @ [a_a7RL] (a1_a9fD `cast` <Co:5>)\r\n}\r\n\r\n-- from1 worker\r\nTravv.$fGeneric1Foo2 :: forall a. Foo a -> Maybe (Rec1 [] a)\r\nTravv.$fGeneric1Foo2\r\n = \\ (@ a_a7R6) (x_a7GJ :: Foo a_a7R6) ->\r\n case x_a7GJ `cast` <Co:2> of {\r\n Nothing -> GHC.Maybe.Nothing @ (Rec1 [] a_a7R6);\r\n Just a1_a9fD ->\r\n GHC.Maybe.Just @ (Rec1 [] a_a7R6) (a1_a9fD `cast` <Co:6>)\r\n }\r\n}}}\r\n\r\nBoth of these functions could be implemented as safe coercions, but neither of them is! Similarly, if I define\r\n\r\n{{{#!hs\r\ndata Bar a = Bar (Maybe [a]) deriving Generic1\r\n}}}\r\n\r\nI get a `to1` worker that looks like\r\n\r\n{{{\r\nTravv.$fGeneric1Bar_$cto1 :: forall a. Rep1 Bar a -> Bar a\r\nTravv.$fGeneric1Bar_$cto1\r\n = \\ (@ a_a7UA) (ds_d9ho :: Rep1 Bar a_a7UA) ->\r\n Travv.Bar\r\n @ a_a7UA\r\n (case ds_d9ho `cast` <Co:103> of {\r\n Nothing -> GHC.Maybe.Nothing @ [a_a7UA];\r\n Just a1_a9iK -> GHC.Maybe.Just @ [a_a7UA] (a1_a9iK `cast` <Co:5>)\r\n })\r\n}}}\r\n\r\nThat `case` expression should really just be a cast.\r\n\r\nI think the basic trick is probably to inspect the role of the type argument of each type in a composition, using that to work out whether to coerce that step.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/15966panic when using RebindableSyntax2023-06-05T10:38:31ZMatthew Pickeringpanic when using RebindableSyntaxhttps://gist.github.com/mpickering/216ecdd9d8766dce2ff1080a17f77a0e
```haskell
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-...https://gist.github.com/mpickering/216ecdd9d8766dce2ff1080a17f77a0e
```haskell
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE RebindableSyntax #-}
{-# OPTIONS_GHC -Wall -Wno-missing-signatures -Wno-unticked-promoted-constructors
-Wno-name-shadowing -fwarn-partial-type-signatures -Wno-partial-type-signatures #-}
module Repro(main) where
import Prelude hiding (Monad(..))
import Control.Applicative
data E (a :: * -> *) (n :: *) where
VarE :: a n -> E a n
instance IMonad E where
return :: a n -> E a n
return = VarE
(>>=) :: E a n -> (forall n . a n -> E b n) -> E b n
VarE x >>= f = f x
class IMonad (m :: (* -> *) -> (* -> *)) where
return :: forall a n . a n -> m a n
(>>=) :: m a n -> (forall n . a n -> m b n) -> m b n
one :: Const Int n
one = (Const 1)
example_4 :: E (Const Int) n
example_4 = do
x <- (return one)
return x
main = example_4 `seq` ()
```
Compiling this file with GHC leads to a StgCmmEnv panic.
```
ghc: panic! (the 'impossible' happened)
(GHC version 8.6.2 for x86_64-unknown-linux):
StgCmmEnv: variable not found
$dIMonad_a1lY
local binds for:
return
>>=
$tc'VarE
$tcE
$tcIMonad
$trModule
$tc'VarE1_r1oI
$tc'VarE2_r1ps
$krep_r1pt
$krep1_r1pu
$krep2_r1pv
$krep3_r1pw
$krep4_r1px
$tcE1_r1py
$tcE2_r1pz
$tcIMonad1_r1pA
$tcIMonad2_r1pB
$krep5_r1pC
$krep6_r1pD
$krep7_r1pE
$trModule1_r1pF
$trModule2_r1pG
$trModule3_r1pH
$trModule4_r1pI
$krep8_r1pJ
$krep9_r1pK
sat_s1rG
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/utils/Outputable.hs:1160:37 in ghc:Outputable
pprPanic, called at compiler/codeGen/StgCmmEnv.hs:149:9 in ghc:StgCmmEnv
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
Loading the file into GHCi succeeds but then when the `main` function is invoked, a `nameModule` panic occurs.
```
*Repro> main
ghc: panic! (the 'impossible' happened)
(GHC version 8.6.2 for x86_64-unknown-linux):
nameModule
system $dIMonad_a1LV
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/utils/Outputable.hs:1160:37 in ghc:Outputable
pprPanic, called at compiler/basicTypes/Name.hs:240:3 in ghc:Name
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
Reproduced on 8.6.{2,1} 8.4.4 8.2.2
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"panic when using RebindableSyntax","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"https://gist.github.com/mpickering/216ecdd9d8766dce2ff1080a17f77a0e\r\n\r\n{{{\r\n{-# LANGUAGE NoImplicitPrelude #-}\r\n{-# LANGUAGE GADTs #-}\r\n{-# LANGUAGE KindSignatures #-}\r\n{-# LANGUAGE RankNTypes #-}\r\n{-# LANGUAGE ScopedTypeVariables #-}\r\n{-# LANGUAGE InstanceSigs #-}\r\n{-# LANGUAGE RebindableSyntax #-}\r\n\r\n{-# OPTIONS_GHC -Wall -Wno-missing-signatures -Wno-unticked-promoted-constructors\r\n -Wno-name-shadowing -fwarn-partial-type-signatures -Wno-partial-type-signatures #-}\r\nmodule Repro(main) where\r\n\r\nimport Prelude hiding (Monad(..))\r\nimport Control.Applicative\r\n\r\ndata E (a :: * -> *) (n :: *) where\r\n VarE :: a n -> E a n\r\n\r\ninstance IMonad E where\r\n return :: a n -> E a n\r\n return = VarE\r\n\r\n (>>=) :: E a n -> (forall n . a n -> E b n) -> E b n\r\n VarE x >>= f = f x\r\n\r\nclass IMonad (m :: (* -> *) -> (* -> *)) where\r\n return :: forall a n . a n -> m a n\r\n (>>=) :: m a n -> (forall n . a n -> m b n) -> m b n\r\n\r\none :: Const Int n\r\none = (Const 1)\r\n\r\nexample_4 :: E (Const Int) n\r\nexample_4 = do\r\n x <- (return one)\r\n return x\r\n\r\nmain = example_4 `seq` ()\r\n}}}\r\n\r\nCompiling this file with GHC leads to a StgCmmEnv panic.\r\n\r\n{{{\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 8.6.2 for x86_64-unknown-linux):\r\n\tStgCmmEnv: variable not found\r\n $dIMonad_a1lY\r\n local binds for:\r\n return\r\n >>=\r\n $tc'VarE\r\n $tcE\r\n $tcIMonad\r\n $trModule\r\n $tc'VarE1_r1oI\r\n $tc'VarE2_r1ps\r\n $krep_r1pt\r\n $krep1_r1pu\r\n $krep2_r1pv\r\n $krep3_r1pw\r\n $krep4_r1px\r\n $tcE1_r1py\r\n $tcE2_r1pz\r\n $tcIMonad1_r1pA\r\n $tcIMonad2_r1pB\r\n $krep5_r1pC\r\n $krep6_r1pD\r\n $krep7_r1pE\r\n $trModule1_r1pF\r\n $trModule2_r1pG\r\n $trModule3_r1pH\r\n $trModule4_r1pI\r\n $krep8_r1pJ\r\n $krep9_r1pK\r\n sat_s1rG\r\n Call stack:\r\n CallStack (from HasCallStack):\r\n callStackDoc, called at compiler/utils/Outputable.hs:1160:37 in ghc:Outputable\r\n pprPanic, called at compiler/codeGen/StgCmmEnv.hs:149:9 in ghc:StgCmmEnv\r\n\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n}}}\r\n\r\nLoading the file into GHCi succeeds but then when the `main` function is invoked, a `nameModule` panic occurs.\r\n\r\n{{{\r\n*Repro> main\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 8.6.2 for x86_64-unknown-linux):\r\n\tnameModule\r\n system $dIMonad_a1LV\r\n Call stack:\r\n CallStack (from HasCallStack):\r\n callStackDoc, called at compiler/utils/Outputable.hs:1160:37 in ghc:Outputable\r\n pprPanic, called at compiler/basicTypes/Name.hs:240:3 in ghc:Name\r\n\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n}}}\r\n\r\nReproduced on 8.6.{2,1} 8.4.4 8.2.2","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3https://gitlab.haskell.org/ghc/ghc/-/issues/15965readv and pread support2020-01-23T19:38:55ZBen Gamarireadv and pread supportdcoutts mentioned that `readv` and `pread` are supported by Windows and all modern BSDs, and even POSIX. Perhaps we should expose this in `base`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| -...dcoutts mentioned that `readv` and `pread` are supported by Windows and all modern BSDs, and even POSIX. Perhaps we should expose this in `base`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.2 |
| 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":"readv and pread support","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"8.10.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"dcoutts mentioned that `readv` and `pread` are supported by Windows and all modern BSDs, and even POSIX. Perhaps we should expose this in `base`.","type_of_failure":"OtherFailure","blocking":[]} -->