GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2020-04-06T06:28:11Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/16296OccurAnal should not break the linter assumptions2020-04-06T06:28:11ZArnaud SpiwackOccurAnal should not break the linter assumptionsAs discovered in #16288 (see in particular #16288\##16296), the implementation of the binder-swap transformation in the occurrence analysis sometimes produces terms which would be refused by the linter.
Specifically:
```hs
case A.x of ...As discovered in #16288 (see in particular #16288\##16296), the implementation of the binder-swap transformation in the occurrence analysis sometimes produces terms which would be refused by the linter.
Specifically:
```hs
case A.x of u { pat -> rhs }
```
Becomes
```hs
case A.x of u { pat -> let x = u in rhs }
```
Crucially, here, `A.x` (which is a global id) and `x` (which is a local id) *have the same unique*. This is so that `x` shadows `A.x` in `rhs` and captures all the occurrences of `A.x` in rhs. Which are now bound by `x`. But all these occurrences of `A.x` (which are now occurrences of `x`) are still marked as global ids. This is rejected by the linter.
The occurrence analysis is counting on the fact that there will be a simplifier step before the next linter fires, which will inline `x` and replace it by `u` everywhere.
As #16288 has shown, this is not always the case! (specifically, in #16288, occurrence analysis happens in an unfolding, but is not followed by a simplifier pass).
----
It's easy to fix such bugs: turn off binder-swap in occurrence analysis when not followed by the simplifier. But it is very fragile. So the longer term solution would be to never produce term which break the linter.
The entire reason for this `let x = u` is to avoid carrying a substitution in the occurrence analysis (and offload the work of actually doing the substitution to the simplifier). But the occurrence analysis will work through the entire `rhs` anyway. So it should be able to, at very little cost, propagate a substitution.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 8.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | monoidal, simonpj |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"OccurAnal should not break the linter assumptions","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["monoidal","simonpj"],"type":"Bug","description":"As discovered in #16288 (see in particular https://ghc.haskell.org/trac/ghc/ticket/16288#comment:2), the implementation of the binder-swap transformation in the occurrence analysis sometimes produces terms which would be refused by the linter.\r\n\r\nSpecifically:\r\n\r\n{{{#!hs\r\ncase A.x of u { pat -> rhs }\r\n}}}\r\n\r\nBecomes\r\n\r\n{{{#!hs\r\ncase A.x of u { pat -> let x = u in rhs }\r\n}}}\r\n\r\nCrucially, here, `A.x` (which is a global id) and `x` (which is a local id) ''have the same unique''. This is so that `x` shadows `A.x` in `rhs` and captures all the occurrences of `A.x` in rhs. Which are now bound by `x`. But all these occurrences of `A.x` (which are now occurrences of `x`) are still marked as global ids. This is rejected by the linter.\r\n\r\nThe occurrence analysis is counting on the fact that there will be a simplifier step before the next linter fires, which will inline `x` and replace it by `u` everywhere.\r\n\r\nAs #16288 has shown, this is not always the case! (specifically, in #16288, occurrence analysis happens in an unfolding, but is not followed by a simplifier pass).\r\n\r\n----\r\n\r\nIt's easy to fix such bugs: turn off binder-swap in occurrence analysis when not followed by the simplifier. But it is very fragile. So the longer term solution would be to never produce term which break the linter.\r\n\r\nThe entire reason for this `let x = u` is to avoid carrying a substitution in the occurrence analysis (and offload the work of actually doing the substitution to the simplifier). But the occurrence analysis will work through the entire `rhs` anyway. So it should be able to, at very little cost, propagate a substitution.","type_of_failure":"OtherFailure","blocking":[]} -->9.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/16295Enable cached builds with Hadrian2019-07-07T18:00:38ZAndrey MokhovEnable cached builds with HadrianAs Neil is working on turning Shake into Cloud Shake \[1\], Shake has got a new feature of "locally cached builds", making it possible to reuse build artefacts from previous builds on the same machine. This means, in particular, that a c...As Neil is working on turning Shake into Cloud Shake \[1\], Shake has got a new feature of "locally cached builds", making it possible to reuse build artefacts from previous builds on the same machine. This means, in particular, that a clean build could be finished very quickly if you've built GHC before from the same/similar sources. Hopefully, this could also help us speed up GHC's CI some day.
To enable cached builds, it is important to find and fix all instances of untracked dependencies in Hadrian, or at least record them using the `produces` feature of Shake \[2\], because otherwise Shake has no idea that these files are actually needed and should therefore be stored in the cache. Here are a couple of tickets related to untracked dependencies:
#16271
#16272
I am currently working this and hope to produce a patch soon. I marked this is a "bug", not a "feature request", since untracked dependencies are bugs, and they prevent us from using Shake's shiny new feature.
\[1\] See the Build Systems à la Carte paper: https://dl.acm.org/ft_gateway.cfm?id=3236774
\[2\] http://hackage.haskell.org/package/shake/docs/Development-Shake.html\#v:produceshttps://gitlab.haskell.org/ghc/ghc/-/issues/16294Code generation corrupts writes to Addr#2019-07-07T18:00:38ZAndrew MartinCode generation corrupts writes to Addr#This issue affects at least GHC 8.4.4 and GHC 8.6.3. Here is a somewhat minimal example:
```hs
{-# language BangPatterns #-}
{-# language MagicHash #-}
{-# language UnboxedTuples #-}
{-# options_ghc -Wall -Werror -O2 #-}
import Data.P...This issue affects at least GHC 8.4.4 and GHC 8.6.3. Here is a somewhat minimal example:
```hs
{-# language BangPatterns #-}
{-# language MagicHash #-}
{-# language UnboxedTuples #-}
{-# options_ghc -Wall -Werror -O2 #-}
import Data.Primitive
import Data.Void
import Data.Word
import Data.Monoid
import GHC.IO (IO(..))
import Foreign.Storable
import Numeric (showHex)
import qualified GHC.Exts as E
import qualified Data.Primitive as PM
main :: IO ()
main = do
arr <- compute 0xABCD 0x79
putStrLn (showString "raw packet: " . appEndo (foldMap (Endo . showHex) (E.toList arr)) $ "")
compute :: Word16 -> Word8 -> IO ByteArray
compute totlen prot = do
buf <- PM.newPinnedByteArray 28
PM.setByteArray buf 0 28 (0 :: Word8)
let !(Addr addr) = PM.mutableByteArrayContents buf
!ptr = E.Ptr addr :: E.Ptr Void
pokeByteOff ptr 0 (0x45 :: Word8)
pokeByteOff ptr 1 (0 :: Word8)
pokeByteOff ptr 2 (totlen :: Word16)
pokeByteOff ptr 4 (0 :: Word16)
pokeByteOff ptr 6 (0 :: Word16)
pokeByteOff ptr 8 (0x40 :: Word8)
pokeByteOff ptr 9 (prot :: Word8)
touchMutableByteArray buf
PM.unsafeFreezeByteArray buf
touchMutableByteArray :: MutableByteArray E.RealWorld -> IO ()
touchMutableByteArray (MutableByteArray x) = touchMutableByteArray# x
touchMutableByteArray# :: E.MutableByteArray# E.RealWorld -> IO ()
touchMutableByteArray# x = IO $ \s -> case E.touch# x s of s' -> (# s', () #)
```
For those curious about the particular interleaving of 8-bit and 16-bit writes, this was adapted from code that fills out an `iphdr` for use with raw sockets. The output will be dependent on your platform's endianness. On my little-endian architecture, I get:
```
raw packet: 450cdab00004079000000000000000000
```
As we expect, the `abcd` from the source gets flipped to `cdab` because of the little endian architecture this ran on. However, it starts in an unusual place. It's not even byte-aligned. Something, possible a cmm optimization or a codegen optimization, makes the `writeWord16OffAddr#` end up straddling three bytes.
Someone will probably want to write a more minimal example that eliminates the use of the `primitive` library.
Sorry to be the bearer of bad news :(
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | highest |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Code generation corrupts writes to Addr#","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This issue affects at least GHC 8.4.4 and GHC 8.6.3. Here is a somewhat minimal example:\r\n\r\n{{{#!hs\r\n{-# language BangPatterns #-}\r\n{-# language MagicHash #-}\r\n{-# language UnboxedTuples #-}\r\n\r\n{-# options_ghc -Wall -Werror -O2 #-}\r\n\r\nimport Data.Primitive\r\nimport Data.Void\r\nimport Data.Word\r\nimport Data.Monoid\r\nimport GHC.IO (IO(..))\r\nimport Foreign.Storable\r\nimport Numeric (showHex)\r\n\r\nimport qualified GHC.Exts as E\r\nimport qualified Data.Primitive as PM\r\n\r\nmain :: IO ()\r\nmain = do\r\n arr <- compute 0xABCD 0x79\r\n putStrLn (showString \"raw packet: \" . appEndo (foldMap (Endo . showHex) (E.toList arr)) $ \"\")\r\n\r\ncompute :: Word16 -> Word8 -> IO ByteArray \r\ncompute totlen prot = do\r\n buf <- PM.newPinnedByteArray 28\r\n PM.setByteArray buf 0 28 (0 :: Word8)\r\n let !(Addr addr) = PM.mutableByteArrayContents buf\r\n !ptr = E.Ptr addr :: E.Ptr Void\r\n pokeByteOff ptr 0 (0x45 :: Word8)\r\n pokeByteOff ptr 1 (0 :: Word8)\r\n pokeByteOff ptr 2 (totlen :: Word16)\r\n pokeByteOff ptr 4 (0 :: Word16)\r\n pokeByteOff ptr 6 (0 :: Word16)\r\n pokeByteOff ptr 8 (0x40 :: Word8)\r\n pokeByteOff ptr 9 (prot :: Word8)\r\n touchMutableByteArray buf\r\n PM.unsafeFreezeByteArray buf\r\n\r\ntouchMutableByteArray :: MutableByteArray E.RealWorld -> IO ()\r\ntouchMutableByteArray (MutableByteArray x) = touchMutableByteArray# x\r\n\r\ntouchMutableByteArray# :: E.MutableByteArray# E.RealWorld -> IO ()\r\ntouchMutableByteArray# x = IO $ \\s -> case E.touch# x s of s' -> (# s', () #)\r\n}}}\r\n\r\nFor those curious about the particular interleaving of 8-bit and 16-bit writes, this was adapted from code that fills out an `iphdr` for use with raw sockets. The output will be dependent on your platform's endianness. On my little-endian architecture, I get:\r\n\r\n{{{\r\nraw packet: 450cdab00004079000000000000000000\r\n}}}\r\n\r\nAs we expect, the `abcd` from the source gets flipped to `cdab` because of the little endian architecture this ran on. However, it starts in an unusual place. It's not even byte-aligned. Something, possible a cmm optimization or a codegen optimization, makes the `writeWord16OffAddr#` end up straddling three bytes.\r\n\r\nSomeone will probably want to write a more minimal example that eliminates the use of the `primitive` library.\r\n\r\nSorry to be the bearer of bad news :(","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16293Inconsistencies and oddities of Proxy#2019-07-07T18:00:38ZRyan ScottInconsistencies and oddities of Proxy#The `Proxy#` type has some downright strange properties that border on being bugs. Here are some of examples that I've discovered:
1. `Proxy#`, when reified with TH, gives a different arity that most other primitive type constructors:
...The `Proxy#` type has some downright strange properties that border on being bugs. Here are some of examples that I've discovered:
1. `Proxy#`, when reified with TH, gives a different arity that most other primitive type constructors:
```
λ> putStrLn $(reify ''Proxy# >>= stringE . show)
PrimTyConI GHC.Prim.Proxy# 2 True
```
> If this is to be believed, `Proxy#` has 2 arguments. But shouldn't that be 1? Compare this to the results of reifying `(->)`:
```
λ> putStrLn $(reify ''(->) >>= stringE . show)
PrimTyConI GHC.Prim.-> 2 False
```
> This correctly claims that it has 2 arguments. Moreover, since `(->)` actually has two invisible `RuntimeRep` arguments, this shows that `(->)` is deliberately not counting them as arguments for `PrimTyConI`'s purposes. It's just `Proxy#` that seems to count its kind argument towards its total.
1. `Proxy#` is nominally roled in its argument! That is to say, the following program typechecks:
```hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Data.Proxy
class C a where
metaData :: Proxy a -> Int
instance C Int where
metaData _ = 432432
newtype Age = MkAge Int deriving C
```
> But the this one does not!
```hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash #-}
import GHC.Exts
class C a where
metaData :: Proxy# a -> Int
instance C Int where
metaData _ = 432432
newtype Age = MkAge Int deriving C
```
```
$ /opt/ghc/8.6.3/bin/ghc Bug.hs
[1 of 1] Compiling Main ( Bug.hs, Bug.o )
Bug.hs:10:34: error:
• Couldn't match type ‘Int’ with ‘Age’
arising from the coercion of the method ‘metaData’
from type ‘Proxy# Int -> Int’ to type ‘Proxy# Age -> Int’
• When deriving the instance for (C Age)
|
10 | newtype Age = MkAge Int deriving C
| ^
```
> If `Proxy` is phantom-roled in its argument, then it feels like `Proxy#` out to be as well.
1. The types of `proxy#` and `Proxy` (the constructor) are subtly different. Compare:
```
λ> :type +v proxy#
proxy# :: forall k0 (a :: k0). Proxy# a
λ> :type +v Proxy
Proxy :: forall {k} (t :: k). Proxy t
```
> Notice that `proxy#` accepts //two// visible type arguments, whereas `Proxy` only accepts one! This means that you'd have to write `proxy# @_ @Int`, as opposed to the shorter `Proxy @Int`. I feel like `proxy#` and `Proxy`'s types ought to mirror each other in this respect.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"Inconsistencies and oddities of Proxy#","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The `Proxy#` type has some downright strange properties that border on being bugs. Here are some of examples that I've discovered:\r\n\r\n1. `Proxy#`, when reified with TH, gives a different arity that most other primitive type constructors:\r\n\r\n{{{\r\nλ> putStrLn $(reify ''Proxy# >>= stringE . show)\r\nPrimTyConI GHC.Prim.Proxy# 2 True\r\n}}}\r\n\r\n If this is to be believed, `Proxy#` has 2 arguments. But shouldn't that be 1? Compare this to the results of reifying `(->)`:\r\n\r\n{{{\r\nλ> putStrLn $(reify ''(->) >>= stringE . show)\r\nPrimTyConI GHC.Prim.-> 2 False\r\n}}}\r\n\r\n This correctly claims that it has 2 arguments. Moreover, since `(->)` actually has two invisible `RuntimeRep` arguments, this shows that `(->)` is deliberately not counting them as arguments for `PrimTyConI`'s purposes. It's just `Proxy#` that seems to count its kind argument towards its total.\r\n2. `Proxy#` is nominally roled in its argument! That is to say, the following program typechecks:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE GeneralizedNewtypeDeriving #-}\r\n\r\nimport Data.Proxy\r\n\r\nclass C a where\r\n metaData :: Proxy a -> Int\r\ninstance C Int where\r\n metaData _ = 432432\r\nnewtype Age = MkAge Int deriving C\r\n}}}\r\n\r\n But the this one does not!\r\n\r\n{{{#!hs\r\n{-# LANGUAGE GeneralizedNewtypeDeriving #-}\r\n{-# LANGUAGE MagicHash #-}\r\n\r\nimport GHC.Exts\r\n\r\nclass C a where\r\n metaData :: Proxy# a -> Int\r\ninstance C Int where\r\n metaData _ = 432432\r\nnewtype Age = MkAge Int deriving C\r\n}}}\r\n{{{\r\n$ /opt/ghc/8.6.3/bin/ghc Bug.hs\r\n[1 of 1] Compiling Main ( Bug.hs, Bug.o )\r\n\r\nBug.hs:10:34: error:\r\n • Couldn't match type ‘Int’ with ‘Age’\r\n arising from the coercion of the method ‘metaData’\r\n from type ‘Proxy# Int -> Int’ to type ‘Proxy# Age -> Int’\r\n • When deriving the instance for (C Age)\r\n |\r\n10 | newtype Age = MkAge Int deriving C\r\n | ^\r\n}}}\r\n\r\n If `Proxy` is phantom-roled in its argument, then it feels like `Proxy#` out to be as well.\r\n3. The types of `proxy#` and `Proxy` (the constructor) are subtly different. Compare:\r\n\r\n{{{\r\nλ> :type +v proxy#\r\nproxy# :: forall k0 (a :: k0). Proxy# a\r\nλ> :type +v Proxy\r\nProxy :: forall {k} (t :: k). Proxy t\r\n}}}\r\n\r\n Notice that `proxy#` accepts //two// visible type arguments, whereas `Proxy` only accepts one! This means that you'd have to write `proxy# @_ @Int`, as opposed to the shorter `Proxy @Int`. I feel like `proxy#` and `Proxy`'s types ought to mirror each other in this respect.","type_of_failure":"OtherFailure","blocking":[]} -->8.10.1https://gitlab.haskell.org/ghc/ghc/-/issues/16292Wildcards in visible kind application2020-06-05T13:28:30ZSimon Peyton JonesWildcards in visible kind application`TcHsType.tcInferApps` contains this terrible code
```
; ki_arg <- addErrCtxt (funAppCtxt orig_hs_ty hs_ki_arg n) $
unsetWOptM Opt_WarnPartialTypeSignatures $
setXOptM LangE...`TcHsType.tcInferApps` contains this terrible code
```
; ki_arg <- addErrCtxt (funAppCtxt orig_hs_ty hs_ki_arg n) $
unsetWOptM Opt_WarnPartialTypeSignatures $
setXOptM LangExt.PartialTypeSignatures $
-- Urgh! see Note [Wildcards in visible kind application]
-- ToDo: must kill this ridiculous messing with DynFlags
```
It's a knock-on from the Visible Kind Application patch -- see the Note referred to above.
But it's ghastly and we must fix it. There's a [GHC Proposal about this](https://github.com/ghc-proposals/ghc-proposals/pull/194), but it's relatively ambitious. Maybe there is a shorter term thing we can do here.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"Wildcards in visible kind application","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"`TcHsType.tcInferApps` contains this terrible code\r\n{{{\r\n ; ki_arg <- addErrCtxt (funAppCtxt orig_hs_ty hs_ki_arg n) $\r\n unsetWOptM Opt_WarnPartialTypeSignatures $\r\n setXOptM LangExt.PartialTypeSignatures $\r\n -- Urgh! see Note [Wildcards in visible kind application]\r\n -- ToDo: must kill this ridiculous messing with DynFlags\r\n}}}\r\nIt's a knock-on from the Visible Kind Application patch -- see the Note referred to above.\r\n\r\nBut it's ghastly and we must fix it. There's a [https://github.com/ghc-proposals/ghc-proposals/pull/194 GHC Proposal about this], but it's relatively ambitious. Maybe there is a shorter term thing we can do here.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16291Document or enable commented-out sanity check in checkStackChunk2019-07-07T18:00:39ZÖmer Sinan AğacanDocument or enable commented-out sanity check in checkStackChunk`checkStackChunk` is currently defined like this:
```c
void
checkStackChunk( StgPtr sp, StgPtr stack_end )
{
StgPtr p;
p = sp;
while (p < stack_end) {
p += checkStackFrame( p );
}
// ASSERT( p == stack_end )...`checkStackChunk` is currently defined like this:
```c
void
checkStackChunk( StgPtr sp, StgPtr stack_end )
{
StgPtr p;
p = sp;
while (p < stack_end) {
p += checkStackFrame( p );
}
// ASSERT( p == stack_end ); -- HWL
}
```
The commented-out assertion makes perfect sense to me, but I can't enable it
(causes test failures), and it's not documented why it should not be enabled. I
think this catches a bug that needs to be fixed.https://gitlab.haskell.org/ghc/ghc/-/issues/16290Export `noinline` function from `GHC.Exts`2020-06-26T05:47:22ZAlexander AltmanExport `noinline` function from `GHC.Exts`The other `id`s-with-special-behavior `inline`, `lazy`, and `oneShot` that are declared in `GHC.Magic` are re-exported from `GHC.Exts` (and thus made user-accessible), but `noinline` isn’t. This seems like an oversight.
<details><summar...The other `id`s-with-special-behavior `inline`, `lazy`, and `oneShot` that are declared in `GHC.Magic` are re-exported from `GHC.Exts` (and thus made user-accessible), but `noinline` isn’t. This seems like an oversight.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.3 |
| 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":"Export `noinline` function from `GHC.Exts`","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":["noinline"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"The other `id`s-with-special-behavior `inline`, `lazy`, and `oneShot` that are declared in `GHC.Magic` are re-exported from `GHC.Exts` (and thus made user-accessible), but `noinline` isn’t. This seems like an oversight.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16289GHC thinks pattern match is exhaustive2019-07-07T18:00:39ZdnspiesGHC thinks pattern match is exhaustive```
{-# OPTIONS_GHC -Werror #-}
module Lib where
data Value = Finite Integer | Infinity
deriving (Eq)
instance Num Value where
(+) = undefined
(*) = undefined
abs = undefined
signum = undefined
...```
{-# OPTIONS_GHC -Werror #-}
module Lib where
data Value = Finite Integer | Infinity
deriving (Eq)
instance Num Value where
(+) = undefined
(*) = undefined
abs = undefined
signum = undefined
negate = undefined
fromInteger = Finite
isSpecial :: Value -> Bool
isSpecial Infinity = True
isSpecial 0 = True
isSpecial 1 = True
isSpecial _ = False
```
```
> ghc Lib.hs
[1 of 1] Compiling Lib ( Lib.hs, Lib.o )
Lib.hs:19:1: error: [-Woverlapping-patterns, -Werror=overlapping-patterns]
Pattern match is redundant
In an equation for ‘isSpecial’: isSpecial 1 = ...
|
19 | isSpecial 1 = True
| ^^^^^^^^^^^^^^^^^^^^^^^^^
Lib.hs:20:1: error: [-Woverlapping-patterns, -Werror=overlapping-patterns]
Pattern match is redundant
In an equation for ‘isSpecial’: isSpecial _ = ...
|
20 | isSpecial _ = False
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"GHC thinks pattern match is exhaustive","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{\r\n{-# OPTIONS_GHC -Werror #-}\r\n\r\nmodule Lib where\r\n\r\ndata Value = Finite Integer | Infinity\r\n deriving (Eq)\r\n\r\ninstance Num Value where\r\n (+) = undefined\r\n (*) = undefined\r\n abs = undefined\r\n signum = undefined\r\n negate = undefined\r\n fromInteger = Finite\r\n\r\nisSpecial :: Value -> Bool\r\nisSpecial Infinity = True\r\nisSpecial 0 = True\r\nisSpecial 1 = True\r\nisSpecial _ = False\r\n\r\n}}}\r\n\r\n\r\n{{{\r\n> ghc Lib.hs\r\n[1 of 1] Compiling Lib ( Lib.hs, Lib.o )\r\n\r\nLib.hs:19:1: error: [-Woverlapping-patterns, -Werror=overlapping-patterns]\r\n Pattern match is redundant\r\n In an equation for ‘isSpecial’: isSpecial 1 = ...\r\n |\r\n19 | isSpecial 1 = True\r\n | ^^^^^^^^^^^^^^^^^^^^^^^^^\r\n\r\nLib.hs:20:1: error: [-Woverlapping-patterns, -Werror=overlapping-patterns]\r\n Pattern match is redundant\r\n In an equation for ‘isSpecial’: isSpecial _ = ...\r\n |\r\n20 | isSpecial _ = False\r\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->Sebastian GrafSebastian Grafhttps://gitlab.haskell.org/ghc/ghc/-/issues/16288Core Lint error: Occurrence is GlobalId, but binding is LocalId2020-01-16T20:05:04ZKrzysztof GogolewskiCore Lint error: Occurrence is GlobalId, but binding is LocalIdCompiling the following three modules causes a Core Lint error in HEAD. (This does not happen in 8.6 - the Lint check was introduced later.)
To reproduce: save the three files in `Repro/` directory and use `ghc-stage2 -dcore-lint -O Rep...Compiling the following three modules causes a Core Lint error in HEAD. (This does not happen in 8.6 - the Lint check was introduced later.)
To reproduce: save the three files in `Repro/` directory and use `ghc-stage2 -dcore-lint -O Repro/B.hs`. The reproduction code is minimized version of code from cabal and prettyprint libraries.
A.hs
```haskell
module Repro.A where
import Repro.C
data License
class Pretty a where
pretty :: a -> Doc
instance Pretty License where
pretty _ = pretV
bar :: (Pretty a) => a -> Doc
bar w = foo (pretty (u w w w w))
u :: a -> a -> a -> a -> a
u = u
```
B.hs
```haskell
module Repro.B where
import Repro.A
import Repro.C
bar2 :: License -> Doc
bar2 = bar
```
C.hs
```haskell
module Repro.C where
data Doc = Empty | Beside Doc
hcat :: Doc -> Doc
hcat Empty = Empty
hcat xs = hcat xs
pretV = hcat Empty
foo :: Doc -> Doc
foo Empty = hcat Empty
foo val = Beside val
```
The error:
```
*** Core Lint errors : in result of Simplifier ***
Repro/C.hs:9:1: warning:
[in body of letrec with binders pretV_r3 :: Doc]
Occurrence is GlobalId, but binding is LocalId
pretV :: Doc
[GblId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=False, ConLike=False,
WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}]
*** Offending Program ***
lvl_s1kN :: Doc
[LclId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=False, ConLike=False,
WorkFree=True, Expandable=False, Guidance=IF_ARGS [] 30 20}]
lvl_s1kN
= case pretV of wild_Xd {
Empty -> pretV;
Beside ipv_s105 -> Beside wild_Xd
}
$sbar_s1kL [InlPrag=NOUSERINLINE[2]] :: License -> Doc
[LclId,
Arity=1,
Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True)
Tmpl= \ _ [Occ=Dead] ->
case pretV of wild_Xd [Occ=Once*] {
Empty ->
let {
pretV_r3 :: Doc
[LclId]
pretV_r3 = wild_Xd } in
pretV;
Beside _ [Occ=Dead] -> Beside wild_Xd
}}]
$sbar_s1kL = \ _ [Occ=Dead] -> lvl_s1kN
$trModule_s1kE :: Addr#
[LclId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}]
$trModule_s1kE = "main"#
$trModule_s1kF :: TrName
[LclId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}]
$trModule_s1kF = TrNameS $trModule_s1kE
$trModule_s1kG :: Addr#
[LclId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}]
$trModule_s1kG = "Repro.B"#
$trModule_s1kH :: TrName
[LclId,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}]
$trModule_s1kH = TrNameS $trModule_s1kG
$trModule :: Module
[LclIdX,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}]
$trModule = Module $trModule_s1kF $trModule_s1kH
bar2 :: License -> Doc
[LclIdX,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 20}]
bar2
= \ _ [Occ=Dead] ->
case pretV of wild_Xd {
Empty -> pretV;
Beside ipv_s105 -> Beside wild_Xd
}
*** End of Offense ***
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.7 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | aspiwack |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Core Lint error: Occurrence is GlobalId, but binding is LocalId","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.7","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["aspiwack"],"type":"Bug","description":"Compiling the following three modules causes a Core Lint error in HEAD. (This does not happen in 8.6 - the Lint check was introduced later.)\r\n\r\nTo reproduce: save the three files in `Repro/` directory and use `ghc-stage2 -dcore-lint -O Repro/B.hs`. The reproduction code is minimized version of code from cabal and prettyprint libraries.\r\n\r\nA.hs\r\n\r\n{{{\r\n#!haskell\r\nmodule Repro.A where\r\n\r\nimport Repro.C\r\n\r\ndata License\r\n\r\nclass Pretty a where\r\n pretty :: a -> Doc\r\n\r\ninstance Pretty License where\r\n pretty _ = pretV\r\n\r\nbar :: (Pretty a) => a -> Doc\r\nbar w = foo (pretty (u w w w w))\r\n\r\nu :: a -> a -> a -> a -> a\r\nu = u\r\n}}}\r\n\r\nB.hs\r\n\r\n{{{\r\n#!haskell\r\nmodule Repro.B where\r\n\r\nimport Repro.A\r\nimport Repro.C\r\n\r\nbar2 :: License -> Doc\r\nbar2 = bar\r\n}}}\r\n\r\nC.hs\r\n\r\n{{{\r\n#!haskell\r\nmodule Repro.C where\r\n\r\ndata Doc = Empty | Beside Doc\r\n\r\nhcat :: Doc -> Doc\r\nhcat Empty = Empty\r\nhcat xs = hcat xs\r\n\r\npretV = hcat Empty\r\n\r\nfoo :: Doc -> Doc\r\nfoo Empty = hcat Empty\r\nfoo val = Beside val\r\n}}}\r\n\r\nThe error:\r\n\r\n{{{\r\n*** Core Lint errors : in result of Simplifier ***\r\nRepro/C.hs:9:1: warning:\r\n [in body of letrec with binders pretV_r3 :: Doc]\r\n Occurrence is GlobalId, but binding is LocalId\r\n pretV :: Doc\r\n [GblId,\r\n Unf=Unf{Src=<vanilla>, TopLvl=True, Value=False, ConLike=False,\r\n WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}]\r\n*** Offending Program ***\r\nlvl_s1kN :: Doc\r\n[LclId,\r\n Unf=Unf{Src=<vanilla>, TopLvl=True, Value=False, ConLike=False,\r\n WorkFree=True, Expandable=False, Guidance=IF_ARGS [] 30 20}]\r\nlvl_s1kN\r\n = case pretV of wild_Xd {\r\n Empty -> pretV;\r\n Beside ipv_s105 -> Beside wild_Xd\r\n }\r\n\r\n$sbar_s1kL [InlPrag=NOUSERINLINE[2]] :: License -> Doc\r\n[LclId,\r\n Arity=1,\r\n Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,\r\n WorkFree=True, Expandable=True,\r\n Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True)\r\n Tmpl= \\ _ [Occ=Dead] ->\r\n case pretV of wild_Xd [Occ=Once*] {\r\n Empty ->\r\n let {\r\n pretV_r3 :: Doc\r\n [LclId]\r\n pretV_r3 = wild_Xd } in\r\n pretV;\r\n Beside _ [Occ=Dead] -> Beside wild_Xd\r\n }}]\r\n$sbar_s1kL = \\ _ [Occ=Dead] -> lvl_s1kN\r\n\r\n$trModule_s1kE :: Addr#\r\n[LclId,\r\n Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,\r\n WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}]\r\n$trModule_s1kE = \"main\"#\r\n\r\n$trModule_s1kF :: TrName\r\n[LclId,\r\n Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,\r\n WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}]\r\n$trModule_s1kF = TrNameS $trModule_s1kE\r\n\r\n$trModule_s1kG :: Addr#\r\n[LclId,\r\n Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,\r\n WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}]\r\n$trModule_s1kG = \"Repro.B\"#\r\n\r\n$trModule_s1kH :: TrName\r\n[LclId,\r\n Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,\r\n WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}]\r\n$trModule_s1kH = TrNameS $trModule_s1kG\r\n\r\n$trModule :: Module\r\n[LclIdX,\r\n Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,\r\n WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}]\r\n$trModule = Module $trModule_s1kF $trModule_s1kH\r\n\r\nbar2 :: License -> Doc\r\n[LclIdX,\r\n Arity=1,\r\n Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,\r\n WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 20}]\r\nbar2\r\n = \\ _ [Occ=Dead] ->\r\n case pretV of wild_Xd {\r\n Empty -> pretV;\r\n Beside ipv_s105 -> Beside wild_Xd\r\n }\r\n\r\n*** End of Offense ***\r\n\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.8.2https://gitlab.haskell.org/ghc/ghc/-/issues/16287:kind accepts bogus type2019-07-07T18:00:40ZSimon Peyton Jones:kind accepts bogus typeConsider this (current HEAD)
```
ghci> type family F :: k
ghci> data T :: (forall k. k) -> Type
ghci> :kind T F
T F :: *
```
This is bogus. `F` has arity 1, and cannot appear unsaturated.
<details><summary>Trac metadata</summary>
| T...Consider this (current HEAD)
```
ghci> type family F :: k
ghci> data T :: (forall k. k) -> Type
ghci> :kind T F
T F :: *
```
This is bogus. `F` has arity 1, and cannot appear unsaturated.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":":kind accepts bogus type","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider this (current HEAD)\r\n{{{\r\nghci> type family F :: k\r\nghci> data T :: (forall k. k) -> Type\r\nghci> :kind T F\r\nT F :: *\r\n}}}\r\nThis is bogus. `F` has arity 1, and cannot appear unsaturated.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.8.1https://gitlab.haskell.org/ghc/ghc/-/issues/16286Continuations are not labelled in the binaries even with -g32019-09-02T10:56:21ZÖmer Sinan AğacanContinuations are not labelled in the binaries even with -g3Any program would work as a reproducer, but here's what I'm using currently:
```
{-# LANGUAGE StaticPointers #-}
module Main where
import Control.Concurrent
import System.Mem
nats :: [Int]
nats = [0 .. ]
main = do
let z = nats !! ...Any program would work as a reproducer, but here's what I'm using currently:
```
{-# LANGUAGE StaticPointers #-}
module Main where
import Control.Concurrent
import System.Mem
nats :: [Int]
nats = [0 .. ]
main = do
let z = nats !! 400
print z
performGC
threadDelay 1000000
print (nats !! 900)
```
If I do `printStack` every time the GC copies a stack I sometimes see stack frames like
```
RET_SMALL (0x535568)
```
but in gdb or objdump output I can't find a symbol at that address, even when the program is built with `-g3`. When I print the location as `StgInfoTable*` I can see that it's a valid info table so `0x535578` should be labelled as `foo_info`.
In the objdump output I see that the location is shown as this:
```
535563: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
...
535570: 1e (bad)
535571: 00 00 add %al,(%rax)
535573: 00 00 add %al,(%rax)
535575: 00 00 add %al,(%rax)
535577: 00 bb e9 e2 85 00 add %bh,0x85e2e9(%rbx)
53557d: 48 83 c5 08 add $0x8,%rbp
```
<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":"Continuations are not labelled in the binaries even with -g3","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Any program would work as a reproducer, but here's what I'm using currently:\r\n\r\n{{{\r\n{-# LANGUAGE StaticPointers #-}\r\n\r\nmodule Main where\r\n\r\nimport Control.Concurrent\r\nimport System.Mem\r\n\r\nnats :: [Int]\r\nnats = [0 .. ]\r\n\r\nmain = do\r\n let z = nats !! 400\r\n print z\r\n performGC\r\n threadDelay 1000000\r\n print (nats !! 900)\r\n}}}\r\n\r\nIf I do `printStack` every time the GC copies a stack I sometimes see stack frames like\r\n\r\n{{{\r\nRET_SMALL (0x535568)\r\n}}}\r\n\r\nbut in gdb or objdump output I can't find a symbol at that address, even when the program is built with `-g3`. When I print the location as `StgInfoTable*` I can see that it's a valid info table so `0x535578` should be labelled as `foo_info`. \r\n\r\nIn the objdump output I see that the location is shown as this:\r\n\r\n{{{\r\n 535563:\t0f 1f 44 00 00 \tnopl 0x0(%rax,%rax,1)\r\n\t...\r\n 535570:\t1e \t(bad) \r\n 535571:\t00 00 \tadd %al,(%rax)\r\n 535573:\t00 00 \tadd %al,(%rax)\r\n 535575:\t00 00 \tadd %al,(%rax)\r\n 535577:\t00 bb e9 e2 85 00 \tadd %bh,0x85e2e9(%rbx)\r\n 53557d:\t48 83 c5 08 \tadd $0x8,%rbp\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16285Hadrian fails to run the testsuite.2019-07-07T18:00:40ZAndreas KlebingerHadrian fails to run the testsuite.This is on windows with a tree based on the commit below.
```
commit a5373c1f (master)
Author: Simon Peyton Jones <simonpj@microsoft.com>
Date: Wed Jan 16 16:34:24 2019 +0000
Fix bogus worker for newtypes
```
Output as follows....This is on windows with a tree based on the commit below.
```
commit a5373c1f (master)
Author: Simon Peyton Jones <simonpj@microsoft.com>
Date: Wed Jan 16 16:34:24 2019 +0000
Fix bogus worker for newtypes
```
Output as follows.
```
$ hadrian/build.bat -c -j8 --flavour=quick test
Up to date
Up to date
hadrian: Encountered missing dependencies:
libiserv ==8.7
shakeArgsWith 0.001s 0%
Function shake 0.010s 0%
Database read 0.516s 13% ===
Database compression 0.074s 1%
With database 0.018s 0%
Running rules 3.280s 84% =========================
Total 3.900s 100%
Error when running Shake build system:
at src/Main.hs:58:30-42:
* Depends on: test
at src/Rules/Test.hs:90:5-17:
* Depends on: _build/stage1/lib/bin/ghc-iserv.exe
at src/Development/Shake/Internal/Rules/Oracle.hs:157:43-68:
* Depends on: OracleQ (ContextDataKey (Context {stage = Stage1, package = Package {pkgType = Program, pkgName = "iserv", pkgPath = "utils/iserv"}, way = v}))
at src/Hadrian/Haskell/Cabal/Parse.hs:202:5-36:
* Depends on: _build/stage1/utils/iserv/setup-config
* Raised the exception:
ExitFailure 1
```
Regular build with hadrian works.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------- |
| Version | 8.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown/Multiple |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Hadrian fails to run the testsuite.","status":"New","operating_system":"Unknown/Multiple","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This is on windows with a tree based on the commit below.\r\n\r\n\r\n{{{\r\ncommit a5373c1f (master)\r\nAuthor: Simon Peyton Jones <simonpj@microsoft.com>\r\nDate: Wed Jan 16 16:34:24 2019 +0000\r\n\r\n Fix bogus worker for newtypes\r\n\r\n}}}\r\n\r\nOutput as follows.\r\n{{{\r\n$ hadrian/build.bat -c -j8 --flavour=quick test\r\nUp to date\r\nUp to date\r\nhadrian: Encountered missing dependencies:\r\nlibiserv ==8.7\r\n\r\nshakeArgsWith 0.001s 0%\r\nFunction shake 0.010s 0%\r\nDatabase read 0.516s 13% ===\r\nDatabase compression 0.074s 1%\r\nWith database 0.018s 0%\r\nRunning rules 3.280s 84% =========================\r\nTotal 3.900s 100%\r\nError when running Shake build system:\r\n at src/Main.hs:58:30-42:\r\n* Depends on: test\r\n at src/Rules/Test.hs:90:5-17:\r\n* Depends on: _build/stage1/lib/bin/ghc-iserv.exe\r\n at src/Development/Shake/Internal/Rules/Oracle.hs:157:43-68:\r\n* Depends on: OracleQ (ContextDataKey (Context {stage = Stage1, package = Package {pkgType = Program, pkgName = \"iserv\", pkgPath = \"utils/iserv\"}, way = v}))\r\n at src/Hadrian/Haskell/Cabal/Parse.hs:202:5-36:\r\n* Depends on: _build/stage1/utils/iserv/setup-config\r\n* Raised the exception:\r\nExitFailure 1\r\n\r\n}}}\r\n\r\nRegular build with hadrian works.\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16284Abortion of fixed-point iteration in Demand Analyser discards sound results2019-07-24T13:42:46ZSebastian GrafAbortion of fixed-point iteration in Demand Analyser discards sound resultsConsider the following program:
```hs
-- Extracted from T4903
module Foo where
data Tree = Bin Tree Tree
tree :: Tree
tree = Bin tree tree
eq :: Tree -> Bool
eq (Bin l r) = eq l && eq r
```
`eq` amounts to the following Core:
```hs...Consider the following program:
```hs
-- Extracted from T4903
module Foo where
data Tree = Bin Tree Tree
tree :: Tree
tree = Bin tree tree
eq :: Tree -> Bool
eq (Bin l r) = eq l && eq r
```
`eq` amounts to the following Core:
```hs
eq
= \ (ds_d20O :: Tree) ->
case ds_d20O of { Bin l_aY8 r_aY9 ->
case eq l_aY8 of {
False -> False;
True -> eq r_aY9
}
}
```
It clearly diverges. That's also what pure strictness/termination/CPR analysis would find out. But because usage analysis can't find out in finite time (and that's fine) that `eq` uses its argument completely, we abort fixed-point iteration \[1\] and return `nopSig`, discarding useful and sound strictness information we found out along the way, like the fact that it diverges.
This isn't hard to fix: Just track which parts of the signature were still unsound during abortion and only zap them. I'm only recording this for posterity and as an argument in a discussion I'll maybe start in a few months of time...
\[1\] This is the ascending chain of demands on `ds_d20O` during fixed-point iteration:
```
H
U(1*H,1*H)
U(1*U(1*H,1*H),1*U(1*H,1*H))
...
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.3 |
| 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":"Abortion of fixed-point iteration in Demand Analyser discards sound results","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"⊥","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":["DemandAnalysis"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Consider the following program:\r\n\r\n{{{#!hs\r\n-- Extracted from T4903\r\nmodule Foo where\r\n\r\ndata Tree = Bin Tree Tree\r\n\r\ntree :: Tree\r\ntree = Bin tree tree\r\n\r\neq :: Tree -> Bool\r\neq (Bin l r) = eq l && eq r\r\n}}}\r\n\r\n`eq` amounts to the following Core:\r\n\r\n{{{#!hs\r\neq\r\n = \\ (ds_d20O :: Tree) ->\r\n case ds_d20O of { Bin l_aY8 r_aY9 ->\r\n case eq l_aY8 of {\r\n False -> False;\r\n True -> eq r_aY9\r\n }\r\n }\r\n}}}\r\n\r\nIt clearly diverges. That's also what pure strictness/termination/CPR analysis would find out. But because usage analysis can't find out in finite time (and that's fine) that `eq` uses its argument completely, we abort fixed-point iteration [1] and return `nopSig`, discarding useful and sound strictness information we found out along the way, like the fact that it diverges.\r\n\r\nThis isn't hard to fix: Just track which parts of the signature were still unsound during abortion and only zap them. I'm only recording this for posterity and as an argument in a discussion I'll maybe start in a few months of time...\r\n\r\n[1] This is the ascending chain of demands on `ds_d20O` during fixed-point iteration:\r\n{{{\r\nH\r\nU(1*H,1*H)\r\nU(1*U(1*H,1*H),1*U(1*H,1*H))\r\n...\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->⊥https://gitlab.haskell.org/ghc/ghc/-/issues/16283StaticPointers pragma changes generated code even when the feature is not used2021-08-09T15:32:20ZÖmer Sinan AğacanStaticPointers pragma changes generated code even when the feature is not usedTried with GHC HEAD. Program:
```
module Main where
import Control.Concurrent
import System.Mem
nats :: [Int]
nats = [0 .. ]
main = do
let z = nats !! 400
print z
performGC
threadDelay 1000000
print (nats !! 900)
```
Compi...Tried with GHC HEAD. Program:
```
module Main where
import Control.Concurrent
import System.Mem
nats :: [Int]
nats = [0 .. ]
main = do
let z = nats !! 400
print z
performGC
threadDelay 1000000
print (nats !! 900)
```
Compile without any flags:
```
==================== Tidy Core ====================
2019-02-04 09:16:26.121849511 UTC
Result size of Tidy Core
= {terms: 45, types: 26, coercions: 0, joins: 0/0}
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule1_r1zg :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule1_r1zg = "main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule2_r1zt :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule2_r1zt = GHC.Types.TrNameS $trModule1_r1zg
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule3_r1zu :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule3_r1zu = "Main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule4_r1zv :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule4_r1zv = GHC.Types.TrNameS $trModule3_r1zu
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
Main.$trModule :: GHC.Types.Module
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
Main.$trModule = GHC.Types.Module $trModule2_r1zt $trModule4_r1zv
-- RHS size: {terms: 4, types: 1, coercions: 0, joins: 0/0}
nats :: [Int]
[GblId]
nats = enumFrom @ Int GHC.Enum.$fEnumInt (GHC.Types.I# 0#)
-- RHS size: {terms: 22, types: 13, coercions: 0, joins: 0/0}
main :: IO ()
[GblId]
main
= >>
@ IO
GHC.Base.$fMonadIO
@ ()
@ ()
(print
@ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 400#)))
(>>
@ IO
GHC.Base.$fMonadIO
@ ()
@ ()
performGC
(>>
@ IO
GHC.Base.$fMonadIO
@ ()
@ ()
(threadDelay (GHC.Types.I# 1000000#))
(print
@ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 900#)))))
-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}
:Main.main :: IO ()
[GblId]
:Main.main = GHC.TopHandler.runMainIO @ () main
```
Compile with `-XStaticPointers`:
```
==================== Tidy Core ====================
2019-02-04 09:16:35.678350955 UTC
Result size of Tidy Core
= {terms: 67, types: 42, coercions: 0, joins: 0/0}
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule1_r1zg :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule1_r1zg = "main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule2_r1zF :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule2_r1zF = GHC.Types.TrNameS $trModule1_r1zg
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule3_r1zG :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule3_r1zG = "Main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule4_r1zH :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
$trModule4_r1zH = GHC.Types.TrNameS $trModule3_r1zG
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
Main.$trModule :: GHC.Types.Module
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
Main.$trModule = GHC.Types.Module $trModule2_r1zF $trModule4_r1zH
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
lvl_r1zI :: Int
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
lvl_r1zI = GHC.Types.I# 0#
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
nats :: [Int]
[GblId]
nats = enumFrom @ Int GHC.Enum.$fEnumInt lvl_r1zI
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
lvl1_r1zJ :: Int
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
lvl1_r1zJ = GHC.Types.I# 400#
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
lvl2_r1zK :: Int
[GblId]
lvl2_r1zK = !! @ Int nats lvl1_r1zJ
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
lvl3_r1zL :: IO ()
[GblId]
lvl3_r1zL = print @ Int GHC.Show.$fShowInt lvl2_r1zK
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
lvl4_r1zM :: Int
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
lvl4_r1zM = GHC.Types.I# 1000000#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
lvl5_r1zN :: IO ()
[GblId]
lvl5_r1zN = threadDelay lvl4_r1zM
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
lvl6_r1zO :: Int
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
lvl6_r1zO = GHC.Types.I# 900#
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
lvl7_r1zP :: Int
[GblId]
lvl7_r1zP = !! @ Int nats lvl6_r1zO
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
lvl8_r1zQ :: IO ()
[GblId]
lvl8_r1zQ = print @ Int GHC.Show.$fShowInt lvl7_r1zP
-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
lvl9_r1zR :: IO ()
[GblId]
lvl9_r1zR
= >> @ IO GHC.Base.$fMonadIO @ () @ () lvl5_r1zN lvl8_r1zQ
-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
lvl10_r1zS :: IO ()
[GblId]
lvl10_r1zS
= >> @ IO GHC.Base.$fMonadIO @ () @ () performGC lvl9_r1zR
-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
main :: IO ()
[GblId]
main = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl3_r1zL lvl10_r1zS
-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}
:Main.main :: IO ()
[GblId]
:Main.main = GHC.TopHandler.runMainIO @ () main
```
Diff:
```
--- no_static_ptrs/GcStaticPointers.dump-simpl 2019-02-04 12:16:26.120066655 +0300
+++ static_ptrs/GcStaticPointers.dump-simpl 2019-02-04 12:16:35.675924328 +0300
@@ -1,9 +1,9 @@
==================== Tidy Core ====================
-2019-02-04 09:16:26.121849511 UTC
+2019-02-04 09:16:35.678350955 UTC
Result size of Tidy Core
- = {terms: 45, types: 26, coercions: 0, joins: 0/0}
+ = {terms: 67, types: 42, coercions: 0, joins: 0/0}
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule1_r1zg :: GHC.Prim.Addr#
@@ -11,55 +11,91 @@
$trModule1_r1zg = "main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-$trModule2_r1zt :: GHC.Types.TrName
+$trModule2_r1zF :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
-$trModule2_r1zt = GHC.Types.TrNameS $trModule1_r1zg
+$trModule2_r1zF = GHC.Types.TrNameS $trModule1_r1zg
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
-$trModule3_r1zu :: GHC.Prim.Addr#
+$trModule3_r1zG :: GHC.Prim.Addr#
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
-$trModule3_r1zu = "Main"#
+$trModule3_r1zG = "Main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
-$trModule4_r1zv :: GHC.Types.TrName
+$trModule4_r1zH :: GHC.Types.TrName
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
-$trModule4_r1zv = GHC.Types.TrNameS $trModule3_r1zu
+$trModule4_r1zH = GHC.Types.TrNameS $trModule3_r1zG
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
Main.$trModule :: GHC.Types.Module
[GblId, Caf=NoCafRefs, Unf=OtherCon []]
-Main.$trModule = GHC.Types.Module $trModule2_r1zt $trModule4_r1zv
+Main.$trModule = GHC.Types.Module $trModule2_r1zF $trModule4_r1zH
--- RHS size: {terms: 4, types: 1, coercions: 0, joins: 0/0}
+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
+lvl_r1zI :: Int
+[GblId, Caf=NoCafRefs, Unf=OtherCon []]
+lvl_r1zI = GHC.Types.I# 0#
+
+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
nats :: [Int]
[GblId]
-nats = enumFrom @ Int GHC.Enum.$fEnumInt (GHC.Types.I# 0#)
+nats = enumFrom @ Int GHC.Enum.$fEnumInt lvl_r1zI
+
+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
+lvl1_r1zJ :: Int
+[GblId, Caf=NoCafRefs, Unf=OtherCon []]
+lvl1_r1zJ = GHC.Types.I# 400#
+
+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
+lvl2_r1zK :: Int
+[GblId]
+lvl2_r1zK = !! @ Int nats lvl1_r1zJ
+
+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
+lvl3_r1zL :: IO ()
+[GblId]
+lvl3_r1zL = print @ Int GHC.Show.$fShowInt lvl2_r1zK
+
+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
+lvl4_r1zM :: Int
+[GblId, Caf=NoCafRefs, Unf=OtherCon []]
+lvl4_r1zM = GHC.Types.I# 1000000#
+
+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
+lvl5_r1zN :: IO ()
+[GblId]
+lvl5_r1zN = threadDelay lvl4_r1zM
+
+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
+lvl6_r1zO :: Int
+[GblId, Caf=NoCafRefs, Unf=OtherCon []]
+lvl6_r1zO = GHC.Types.I# 900#
+
+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
+lvl7_r1zP :: Int
+[GblId]
+lvl7_r1zP = !! @ Int nats lvl6_r1zO
+
+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
+lvl8_r1zQ :: IO ()
+[GblId]
+lvl8_r1zQ = print @ Int GHC.Show.$fShowInt lvl7_r1zP
+
+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
+lvl9_r1zR :: IO ()
+[GblId]
+lvl9_r1zR
+ = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl5_r1zN lvl8_r1zQ
+
+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
+lvl10_r1zS :: IO ()
+[GblId]
+lvl10_r1zS
+ = >> @ IO GHC.Base.$fMonadIO @ () @ () performGC lvl9_r1zR
--- RHS size: {terms: 22, types: 13, coercions: 0, joins: 0/0}
+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}
main :: IO ()
[GblId]
-main
- = >>
- @ IO
- GHC.Base.$fMonadIO
- @ ()
- @ ()
- (print
- @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 400#)))
- (>>
- @ IO
- GHC.Base.$fMonadIO
- @ ()
- @ ()
- performGC
- (>>
- @ IO
- GHC.Base.$fMonadIO
- @ ()
- @ ()
- (threadDelay (GHC.Types.I# 1000000#))
- (print
- @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 900#)))))
+main = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl3_r1zL lvl10_r1zS
-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}
:Main.main :: IO ()
```
<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":"StaticPointers pragma changes generated code even when the feature is not used","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Tried with GHC HEAD. Program:\r\n\r\n{{{\r\nmodule Main where\r\n\r\nimport Control.Concurrent\r\nimport System.Mem\r\n\r\nnats :: [Int]\r\nnats = [0 .. ]\r\n\r\nmain = do\r\n let z = nats !! 400\r\n print z\r\n performGC\r\n threadDelay 1000000\r\n print (nats !! 900)\r\n}}}\r\n\r\nCompile without any flags:\r\n\r\n{{{\r\n==================== Tidy Core ====================\r\n2019-02-04 09:16:26.121849511 UTC\r\n\r\nResult size of Tidy Core\r\n = {terms: 45, types: 26, coercions: 0, joins: 0/0}\r\n\r\n-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n$trModule1_r1zg :: GHC.Prim.Addr#\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule1_r1zg = \"main\"#\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n$trModule2_r1zt :: GHC.Types.TrName\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule2_r1zt = GHC.Types.TrNameS $trModule1_r1zg\r\n\r\n-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n$trModule3_r1zu :: GHC.Prim.Addr#\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule3_r1zu = \"Main\"#\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n$trModule4_r1zv :: GHC.Types.TrName\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule4_r1zv = GHC.Types.TrNameS $trModule3_r1zu\r\n\r\n-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}\r\nMain.$trModule :: GHC.Types.Module\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nMain.$trModule = GHC.Types.Module $trModule2_r1zt $trModule4_r1zv\r\n\r\n-- RHS size: {terms: 4, types: 1, coercions: 0, joins: 0/0}\r\nnats :: [Int]\r\n[GblId]\r\nnats = enumFrom @ Int GHC.Enum.$fEnumInt (GHC.Types.I# 0#)\r\n\r\n-- RHS size: {terms: 22, types: 13, coercions: 0, joins: 0/0}\r\nmain :: IO ()\r\n[GblId]\r\nmain\r\n = >>\r\n @ IO\r\n GHC.Base.$fMonadIO\r\n @ ()\r\n @ ()\r\n (print\r\n @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 400#)))\r\n (>>\r\n @ IO\r\n GHC.Base.$fMonadIO\r\n @ ()\r\n @ ()\r\n performGC\r\n (>>\r\n @ IO\r\n GHC.Base.$fMonadIO\r\n @ ()\r\n @ ()\r\n (threadDelay (GHC.Types.I# 1000000#))\r\n (print\r\n @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 900#)))))\r\n\r\n-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}\r\n:Main.main :: IO ()\r\n[GblId]\r\n:Main.main = GHC.TopHandler.runMainIO @ () main\r\n}}}\r\n\r\nCompile with `-XStaticPointers`:\r\n\r\n{{{\r\n\r\n==================== Tidy Core ====================\r\n2019-02-04 09:16:35.678350955 UTC\r\n\r\nResult size of Tidy Core\r\n = {terms: 67, types: 42, coercions: 0, joins: 0/0}\r\n\r\n-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n$trModule1_r1zg :: GHC.Prim.Addr#\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule1_r1zg = \"main\"#\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n$trModule2_r1zF :: GHC.Types.TrName\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule2_r1zF = GHC.Types.TrNameS $trModule1_r1zg\r\n\r\n-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n$trModule3_r1zG :: GHC.Prim.Addr#\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule3_r1zG = \"Main\"#\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n$trModule4_r1zH :: GHC.Types.TrName\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n$trModule4_r1zH = GHC.Types.TrNameS $trModule3_r1zG\r\n\r\n-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}\r\nMain.$trModule :: GHC.Types.Module\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nMain.$trModule = GHC.Types.Module $trModule2_r1zF $trModule4_r1zH\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\nlvl_r1zI :: Int\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nlvl_r1zI = GHC.Types.I# 0#\r\n\r\n-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\nnats :: [Int]\r\n[GblId]\r\nnats = enumFrom @ Int GHC.Enum.$fEnumInt lvl_r1zI\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\nlvl1_r1zJ :: Int\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nlvl1_r1zJ = GHC.Types.I# 400#\r\n\r\n-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\nlvl2_r1zK :: Int\r\n[GblId]\r\nlvl2_r1zK = !! @ Int nats lvl1_r1zJ\r\n\r\n-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\nlvl3_r1zL :: IO ()\r\n[GblId]\r\nlvl3_r1zL = print @ Int GHC.Show.$fShowInt lvl2_r1zK\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\nlvl4_r1zM :: Int\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nlvl4_r1zM = GHC.Types.I# 1000000#\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\nlvl5_r1zN :: IO ()\r\n[GblId]\r\nlvl5_r1zN = threadDelay lvl4_r1zM\r\n\r\n-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\nlvl6_r1zO :: Int\r\n[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\nlvl6_r1zO = GHC.Types.I# 900#\r\n\r\n-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\nlvl7_r1zP :: Int\r\n[GblId]\r\nlvl7_r1zP = !! @ Int nats lvl6_r1zO\r\n\r\n-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\nlvl8_r1zQ :: IO ()\r\n[GblId]\r\nlvl8_r1zQ = print @ Int GHC.Show.$fShowInt lvl7_r1zP\r\n\r\n-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\nlvl9_r1zR :: IO ()\r\n[GblId]\r\nlvl9_r1zR\r\n = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl5_r1zN lvl8_r1zQ\r\n\r\n-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\nlvl10_r1zS :: IO ()\r\n[GblId]\r\nlvl10_r1zS\r\n = >> @ IO GHC.Base.$fMonadIO @ () @ () performGC lvl9_r1zR\r\n\r\n-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\nmain :: IO ()\r\n[GblId]\r\nmain = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl3_r1zL lvl10_r1zS\r\n\r\n-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}\r\n:Main.main :: IO ()\r\n[GblId]\r\n:Main.main = GHC.TopHandler.runMainIO @ () main\r\n}}}\r\n\r\nDiff:\r\n\r\n{{{\r\n--- no_static_ptrs/GcStaticPointers.dump-simpl\t2019-02-04 12:16:26.120066655 +0300\r\n+++ static_ptrs/GcStaticPointers.dump-simpl\t2019-02-04 12:16:35.675924328 +0300\r\n@@ -1,9 +1,9 @@\r\n \r\n ==================== Tidy Core ====================\r\n-2019-02-04 09:16:26.121849511 UTC\r\n+2019-02-04 09:16:35.678350955 UTC\r\n \r\n Result size of Tidy Core\r\n- = {terms: 45, types: 26, coercions: 0, joins: 0/0}\r\n+ = {terms: 67, types: 42, coercions: 0, joins: 0/0}\r\n \r\n -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n $trModule1_r1zg :: GHC.Prim.Addr#\r\n@@ -11,55 +11,91 @@\r\n $trModule1_r1zg = \"main\"#\r\n \r\n -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n-$trModule2_r1zt :: GHC.Types.TrName\r\n+$trModule2_r1zF :: GHC.Types.TrName\r\n [GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n-$trModule2_r1zt = GHC.Types.TrNameS $trModule1_r1zg\r\n+$trModule2_r1zF = GHC.Types.TrNameS $trModule1_r1zg\r\n \r\n -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\n-$trModule3_r1zu :: GHC.Prim.Addr#\r\n+$trModule3_r1zG :: GHC.Prim.Addr#\r\n [GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n-$trModule3_r1zu = \"Main\"#\r\n+$trModule3_r1zG = \"Main\"#\r\n \r\n -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n-$trModule4_r1zv :: GHC.Types.TrName\r\n+$trModule4_r1zH :: GHC.Types.TrName\r\n [GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n-$trModule4_r1zv = GHC.Types.TrNameS $trModule3_r1zu\r\n+$trModule4_r1zH = GHC.Types.TrNameS $trModule3_r1zG\r\n \r\n -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}\r\n Main.$trModule :: GHC.Types.Module\r\n [GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n-Main.$trModule = GHC.Types.Module $trModule2_r1zt $trModule4_r1zv\r\n+Main.$trModule = GHC.Types.Module $trModule2_r1zF $trModule4_r1zH\r\n \r\n--- RHS size: {terms: 4, types: 1, coercions: 0, joins: 0/0}\r\n+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n+lvl_r1zI :: Int\r\n+[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n+lvl_r1zI = GHC.Types.I# 0#\r\n+\r\n+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\n nats :: [Int]\r\n [GblId]\r\n-nats = enumFrom @ Int GHC.Enum.$fEnumInt (GHC.Types.I# 0#)\r\n+nats = enumFrom @ Int GHC.Enum.$fEnumInt lvl_r1zI\r\n+\r\n+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n+lvl1_r1zJ :: Int\r\n+[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n+lvl1_r1zJ = GHC.Types.I# 400#\r\n+\r\n+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\n+lvl2_r1zK :: Int\r\n+[GblId]\r\n+lvl2_r1zK = !! @ Int nats lvl1_r1zJ\r\n+\r\n+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\n+lvl3_r1zL :: IO ()\r\n+[GblId]\r\n+lvl3_r1zL = print @ Int GHC.Show.$fShowInt lvl2_r1zK\r\n+\r\n+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n+lvl4_r1zM :: Int\r\n+[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n+lvl4_r1zM = GHC.Types.I# 1000000#\r\n+\r\n+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n+lvl5_r1zN :: IO ()\r\n+[GblId]\r\n+lvl5_r1zN = threadDelay lvl4_r1zM\r\n+\r\n+-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}\r\n+lvl6_r1zO :: Int\r\n+[GblId, Caf=NoCafRefs, Unf=OtherCon []]\r\n+lvl6_r1zO = GHC.Types.I# 900#\r\n+\r\n+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\n+lvl7_r1zP :: Int\r\n+[GblId]\r\n+lvl7_r1zP = !! @ Int nats lvl6_r1zO\r\n+\r\n+-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}\r\n+lvl8_r1zQ :: IO ()\r\n+[GblId]\r\n+lvl8_r1zQ = print @ Int GHC.Show.$fShowInt lvl7_r1zP\r\n+\r\n+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\n+lvl9_r1zR :: IO ()\r\n+[GblId]\r\n+lvl9_r1zR\r\n+ = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl5_r1zN lvl8_r1zQ\r\n+\r\n+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\n+lvl10_r1zS :: IO ()\r\n+[GblId]\r\n+lvl10_r1zS\r\n+ = >> @ IO GHC.Base.$fMonadIO @ () @ () performGC lvl9_r1zR\r\n \r\n--- RHS size: {terms: 22, types: 13, coercions: 0, joins: 0/0}\r\n+-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0}\r\n main :: IO ()\r\n [GblId]\r\n-main\r\n- = >>\r\n- @ IO\r\n- GHC.Base.$fMonadIO\r\n- @ ()\r\n- @ ()\r\n- (print\r\n- @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 400#)))\r\n- (>>\r\n- @ IO\r\n- GHC.Base.$fMonadIO\r\n- @ ()\r\n- @ ()\r\n- performGC\r\n- (>>\r\n- @ IO\r\n- GHC.Base.$fMonadIO\r\n- @ ()\r\n- @ ()\r\n- (threadDelay (GHC.Types.I# 1000000#))\r\n- (print\r\n- @ Int GHC.Show.$fShowInt (!! @ Int nats (GHC.Types.I# 900#)))))\r\n+main = >> @ IO GHC.Base.$fMonadIO @ () @ () lvl3_r1zL lvl10_r1zS\r\n \r\n -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}\r\n :Main.main :: IO ()\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16282all-missed-specializations doesn't suggest warning2019-07-07T18:00:41ZEric Crockettall-missed-specializations doesn't suggest warning`-Weverything` turns on `-Wall-missed-specializations`. When most warnings print, they say, e.g.,
`warning: [-Wincomplete-uni-patterns]`
which is helpful because I can then easily suppress all warnings of that type with an `-fno-warn-*...`-Weverything` turns on `-Wall-missed-specializations`. When most warnings print, they say, e.g.,
`warning: [-Wincomplete-uni-patterns]`
which is helpful because I can then easily suppress all warnings of that type with an `-fno-warn-*`. But missed specializations do not show the warning flag:
```
Foo.hs: warning:
Could not specialise imported function `foo'
Probable fix: add INLINABLE pragma on `foo'
```
There is no indication of what warning flag triggered the warning.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"all-missed-specializations doesn't suggest warning","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"`-Weverything` turns on `-Wall-missed-specializations`. When most warnings print, they say, e.g.,\r\n\r\n`warning: [-Wincomplete-uni-patterns]`\r\n\r\nwhich is helpful because I can then easily suppress all warnings of that type with an `-fno-warn-*`. But missed specializations do not show the warning flag:\r\n\r\n{{{\r\nFoo.hs: warning:\r\n Could not specialise imported function `foo'\r\n Probable fix: add INLINABLE pragma on `foo'\r\n}}}\r\n\r\nThere is no indication of what warning flag triggered the warning.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16281PatternSynonyms doesn't accept non-prenex quantified functions, doesn't float...2019-07-07T18:00:41ZIcelandjackPatternSynonyms doesn't accept non-prenex quantified functions, doesn't float forallsThis works under GHC HEAD (8.7.20190115)
```hs
{-# Language RankNTypes #-}
{-# Language ViewPatterns #-}
{-# Language PatternSynonyms #-}
newtype Logic a = Logic (forall xx. (a -> (xx -> xx)) -> (xx -> xx))
runLogic :: Logic a...This works under GHC HEAD (8.7.20190115)
```hs
{-# Language RankNTypes #-}
{-# Language ViewPatterns #-}
{-# Language PatternSynonyms #-}
newtype Logic a = Logic (forall xx. (a -> (xx -> xx)) -> (xx -> xx))
runLogic :: Logic a -> forall xx. (a -> xx -> xx) -> (xx -> xx)
runLogic (Logic logic) = logic
pattern L :: (forall xx. (a -> xx -> xx) -> xx -> xx) -> Logic a
pattern L f <- (runLogic -> f)
```
I was under the impression that these would be equivalent
```hs
runLogic :: Logic a -> forall xx. (a -> xx -> xx) -> (xx -> xx)
runLogic :: Logic a -> (a -> xx -> xx) -> (xx -> xx)
```
apart from the order of visible type application and such, but it fails:
```hs
{-# Language RankNTypes #-}
{-# Language ViewPatterns #-}
{-# Language PatternSynonyms #-}
newtype Logic a = Logic (forall xx. (a -> (xx -> xx)) -> (xx -> xx))
runLogic :: Logic a -> (a -> xx -> xx) -> (xx -> xx)
runLogic (Logic logic) = logic
pattern L :: (forall xx. (a -> xx -> xx) -> xx -> xx) -> Logic a
pattern L f <- (runLogic -> f)
```
```
$ ... -ignore-dot-ghci 1022_bug.hs
GHCi, version 8.7.20190115: https://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( 1022_bug.hs, interpreted )
1022_bug.hs:11:29: error:
• Couldn't match expected type ‘forall xx.
(a -> xx -> xx) -> xx -> xx’
with actual type ‘(a -> xx0 -> xx0) -> xx0 -> xx0’
• In the declaration for pattern synonym ‘L’
• Relevant bindings include
f :: (a -> xx0 -> xx0) -> xx0 -> xx0 (bound at 1022_bug.hs:11:29)
|
11 | pattern L f <- (runLogic -> f)
| ^
Failed, no modules loaded.
Prelude>
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.7 |
| 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":"PatternSynonyms doesn't accept non-prenex quantified functions, doesn't float foralls","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.7","keywords":["PatternSynonyms"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This works under GHC HEAD (8.7.20190115)\r\n\r\n{{{#!hs\r\n{-# Language RankNTypes #-}\r\n{-# Language ViewPatterns #-}\r\n{-# Language PatternSynonyms #-}\r\n\r\nnewtype Logic a = Logic (forall xx. (a -> (xx -> xx)) -> (xx -> xx))\r\n\r\nrunLogic :: Logic a -> forall xx. (a -> xx -> xx) -> (xx -> xx)\r\nrunLogic (Logic logic) = logic\r\n\r\npattern L :: (forall xx. (a -> xx -> xx) -> xx -> xx) -> Logic a\r\npattern L f <- (runLogic -> f)\r\n}}}\r\n\r\nI was under the impression that these would be equivalent \r\n{{{#!hs\r\nrunLogic :: Logic a -> forall xx. (a -> xx -> xx) -> (xx -> xx)\r\nrunLogic :: Logic a -> (a -> xx -> xx) -> (xx -> xx)\r\n}}}\r\napart from the order of visible type application and such, but it fails:\r\n\r\n{{{#!hs\r\n{-# Language RankNTypes #-}\r\n{-# Language ViewPatterns #-}\r\n{-# Language PatternSynonyms #-}\r\n\r\nnewtype Logic a = Logic (forall xx. (a -> (xx -> xx)) -> (xx -> xx))\r\n\r\nrunLogic :: Logic a -> (a -> xx -> xx) -> (xx -> xx)\r\nrunLogic (Logic logic) = logic\r\n\r\npattern L :: (forall xx. (a -> xx -> xx) -> xx -> xx) -> Logic a\r\npattern L f <- (runLogic -> f)\r\n}}}\r\n\r\n{{{\r\n$ ... -ignore-dot-ghci 1022_bug.hs\r\nGHCi, version 8.7.20190115: https://www.haskell.org/ghc/ :? for help\r\n[1 of 1] Compiling Main ( 1022_bug.hs, interpreted )\r\n\r\n1022_bug.hs:11:29: error:\r\n • Couldn't match expected type ‘forall xx.\r\n (a -> xx -> xx) -> xx -> xx’\r\n with actual type ‘(a -> xx0 -> xx0) -> xx0 -> xx0’\r\n • In the declaration for pattern synonym ‘L’\r\n • Relevant bindings include\r\n f :: (a -> xx0 -> xx0) -> xx0 -> xx0 (bound at 1022_bug.hs:11:29)\r\n |\r\n11 | pattern L f <- (runLogic -> f)\r\n | ^\r\nFailed, no modules loaded.\r\nPrelude>\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16280Update Latest page of User's Guide to GHC 8.6.32019-07-07T18:00:42Zwataru86Update Latest page of User's Guide to GHC 8.6.3Latest version of GHC is 8.6.3.
However, latest page of User's Guide is 8.6.2(https://downloads.haskell.org/\~ghc/latest/docs/html/users_guide/index.html).
Please Update to GHC 8.6.3.
<details><summary>Trac metadata</summary>
| Trac f...Latest version of GHC is 8.6.3.
However, latest page of User's Guide is 8.6.2(https://downloads.haskell.org/\~ghc/latest/docs/html/users_guide/index.html).
Please Update to GHC 8.6.3.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.3 |
| 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":"Update Latest page of User's Guide to GHC 8.6.3","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Latest version of GHC is 8.6.3.\r\nHowever, latest page of User's Guide is 8.6.2(https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/index.html).\r\n\r\nPlease Update to GHC 8.6.3.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16279Lexer: Alternate Layout Rule injects actual not virtual braces2019-07-07T18:00:42ZAlan ZimmermanLexer: Alternate Layout Rule injects actual not virtual bracesWhen the alternate layout rule is activated via a pragma, it injects tokens for `{` and `}` to make sure that the source is parsed properly.
But it injects `ITocurly` and `ITccurly`, rather than their virtual counterparts `ITvocurly` an...When the alternate layout rule is activated via a pragma, it injects tokens for `{` and `}` to make sure that the source is parsed properly.
But it injects `ITocurly` and `ITccurly`, rather than their virtual counterparts `ITvocurly` and `ITvccurly`.
This causes problems for `ghc-exactprint`, which tries to print these.
Test case (the existing T13087.hs)
```hs
{-# LANGUAGE AlternativeLayoutRule #-}
{-# LANGUAGE LambdaCase #-}
isOne :: Int -> Bool
isOne = \case 1 -> True
_ -> False
main = return ()
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 8.6.3 |
| 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":"Lexer: Alternate Layout Rule injects actual not virtual braces","status":"New","operating_system":"","component":"Compiler (Parser)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When the alternate layout rule is activated via a pragma, it injects tokens for `{` and `}` to make sure that the source is parsed properly.\r\n\r\nBut it injects `ITocurly` and `ITccurly`, rather than their virtual counterparts `ITvocurly` and `ITvccurly`.\r\n\r\nThis causes problems for `ghc-exactprint`, which tries to print these.\r\n\r\nTest case (the existing T13087.hs)\r\n \r\n{{{#!hs\r\n{-# LANGUAGE AlternativeLayoutRule #-}\r\n{-# LANGUAGE LambdaCase #-}\r\n\r\nisOne :: Int -> Bool\r\nisOne = \\case 1 -> True\r\n _ -> False\r\n\r\nmain = return ()\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.8.1Alan ZimmermanAlan Zimmermanhttps://gitlab.haskell.org/ghc/ghc/-/issues/16278Exhaustivity checking GADT with free variables2022-09-20T17:28:38ZAndrew MartinExhaustivity checking GADT with free variablesConsider the following example:
```hs
{-# language DataKinds #-}
{-# language TypeFamilies #-}
{-# language GADTs #-}
{-# language KindSignatures #-}
{-# OPTIONS_GHC -Wall -fforce-recomp #-}
module GadtException where
import Data.Kin...Consider the following example:
```hs
{-# language DataKinds #-}
{-# language TypeFamilies #-}
{-# language GADTs #-}
{-# language KindSignatures #-}
{-# OPTIONS_GHC -Wall -fforce-recomp #-}
module GadtException where
import Data.Kind (Type)
import GHC.Exts
data Send = Send
data SocketException :: Send -> Type where
LocalShutdown :: SocketException 'Send
OutOfMemory :: SocketException a
someSocketException :: SocketException a
someSocketException = OutOfMemory
foo :: Int
foo = case someSocketException :: SocketException Any of
LocalShutdown -> 2
OutOfMemory -> 1
```
In `foo`, GHC's exhaustivity checker requires a pattern match on `LocalShutdown`. However, `LocalShutdown` is not an inhabitant of `SocketException Any`. What I would really like is for this to go one step further. I shouldn't even need to write the type annotation. That is, with the above code otherwise unchanged, GHC should recognize that
```hs
foo :: Int
foo = case someSocketException of
OutOfMemory -> 1
```
handles all possible cases. Since fully polymorphic type variables become `Any` at some point during typechecking, I would expect that if this worked with the `SocketException Any` type signature, it would work without it.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.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":"Exhaustivity checking GADT with free variables","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider the following example:\r\n\r\n{{{#!hs\r\n{-# language DataKinds #-}\r\n{-# language TypeFamilies #-}\r\n{-# language GADTs #-}\r\n{-# language KindSignatures #-}\r\n\r\n{-# OPTIONS_GHC -Wall -fforce-recomp #-}\r\n\r\nmodule GadtException where\r\n\r\nimport Data.Kind (Type)\r\nimport GHC.Exts\r\n\r\ndata Send = Send\r\n\r\ndata SocketException :: Send -> Type where \r\n LocalShutdown :: SocketException 'Send\r\n OutOfMemory :: SocketException a\r\n\r\nsomeSocketException :: SocketException a\r\nsomeSocketException = OutOfMemory\r\n\r\nfoo :: Int\r\nfoo = case someSocketException :: SocketException Any of\r\n LocalShutdown -> 2\r\n OutOfMemory -> 1\r\n}}}\r\n\r\nIn `foo`, GHC's exhaustivity checker requires a pattern match on `LocalShutdown`. However, `LocalShutdown` is not an inhabitant of `SocketException Any`. What I would really like is for this to go one step further. I shouldn't even need to write the type annotation. That is, with the above code otherwise unchanged, GHC should recognize that\r\n\r\n{{{#!hs\r\nfoo :: Int\r\nfoo = case someSocketException of\r\n OutOfMemory -> 1\r\n}}}\r\n\r\nhandles all possible cases. Since fully polymorphic type variables become `Any` at some point during typechecking, I would expect that if this worked with the `SocketException Any` type signature, it would work without it.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16277Make JUnit report stdout/stderr in more cases2019-07-07T18:00:42ZMatthew PickeringMake JUnit report stdout/stderr in more casesIn https://gitlab.haskell.org/ghc/ghc/merge_requests/210 we made a start to improve the junit output to
also include stderr/stdout when appropriate.
However, the patch only handles a few cases, it is reasonably straightforward to handle...In https://gitlab.haskell.org/ghc/ghc/merge_requests/210 we made a start to improve the junit output to
also include stderr/stdout when appropriate.
However, the patch only handles a few cases, it is reasonably straightforward to handle more cases but the refactoring was a bit more involved than I was prepared to do at the time.
To find more places, look in `testlib.py` and grep for `failBecause`. There are examples such as `bad stderr` and `bad stdout` which would also benefit from reporting the stderr.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.3 |
| 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":"Make JUnit report stdout/stderr in more cases","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":["newcomer"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"In https://gitlab.haskell.org/ghc/ghc/merge_requests/210 we made a start to improve the junit output to\r\nalso include stderr/stdout when appropriate. \r\n\r\nHowever, the patch only handles a few cases, it is reasonably straightforward to handle more cases but the refactoring was a bit more involved than I was prepared to do at the time. \r\n\r\nTo find more places, look in `testlib.py` and grep for `failBecause`. There are examples such as `bad stderr` and `bad stdout` which would also benefit from reporting the stderr. ","type_of_failure":"OtherFailure","blocking":[]} -->