Attached file `Factorize.hs`

($1235).

PanicForO2

Attached file `HaskellBug.hs`

($1199).

Small example with similar behavior

Attached file `TestTypeSynonyms.hs`

($1196).

Test file in which it takes really long to expand type synonyms (in ghc-8.0.1-rc4)

Attached file `DataMap.hs`

(download).

added the unionWithMaybe function

Attached file `wrongError.hs`

($864).

The file that produces exactly (and only) the error message in the ticket

Attached file `loop.hs`

($755).

Script for ghci to see the looping behavior

We have several work-arounds for now: using an old GHC version, turning off optimisations, and using other code without this behavior, so I'm fine right now. From your analysis, I should be able to come up with a no-inline pragma too. I only raised the priority to increase the visibility: didn't want this to go unnoticed before the next release, so thank you for taking a look at it!

Regards, Sebastiaan (PS: Stef is my dad)

Trac field | Value |
---|---|

Priority | high → highest |

Trac field | Value |
---|---|

TypeOfFailure | OtherFailure → CompileTimeCrash |

Priority | normal → high |

I'm getting a panic! in GHC 8.0.1 and in 8.1.20161028

```
sjoosten:ghcCompileBug sjc$ ghc-8.1.20161028 --make Factorize.hs -O2
[1 of 2] Compiling Factorize ( Factorize.hs, Factorize.o )
ghc: panic! (the 'impossible' happened)
(GHC version 8.1.20161028 for x86_64-apple-darwin):
Simplifier ticks exhausted
When trying UnfoldingDone $slast_s_s1IU
To increase the limit, use -fsimpl-tick-factor=N (default 100)
If you need to do this, let GHC HQ know, and what factor you needed
To see detailed counts use -ddump-simpl-stats
Total ticks: 18241
Call stack:
CallStack (from HasCallStack):
prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1076:58 in ghc:Outputable
callStackDoc, called at compiler/utils/Outputable.hs:1080:37 in ghc:Outputable
pprPanic, called at compiler/simplCore/SimplMonad.hs:199:31 in ghc:SimplMonad
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```

Attached is some code which I tried to make as small as possible (it therefore does not make sense, but it reproduces the panic). The panic! only occurs with -O2 (I need the -O2 switch to optimise the automatically generated Haskell code).

I ran into this too, I'm not sure whether it is the same bug, but I managed to reproduce the same GHC internal error in a very small example. Based on what the two examples have in common, I would say this has something to do with the TypeFamilies switch (without it, ghc works as expected).

Attached script is a reason to not have it on by default. The example code takes long enough to notice a delay but still see a result; changing the T12 and S12 into something like T15 S15 makes it take 'forever'. I don't know if this will occur in practice – it's hard to measure since all of hackage seems to type-check, but it's a reason to keep the switch off by default (as it is in rc-4).

How about a program that would turn a sequence of characters into a sequence of space-characters of the same length? Such a program could be written as part of a pretty-printer or other template-like code.

`asIndentation chars = do{_<-chars;return ' '}::Seq Char`

This particular example would benefit asymptotically from replacing `(\_ -> pure ' ') <$>`

with `pure ' ' <$`

.

On a side note, I ran into this strange (but understandable) behavior, not sure if it should be considered a bug:

```
Prelude Data.Sequence> :t (\x -> do{_ <- x; return x})
(\x -> do{_ <- x; return x}) :: Functor f => f t -> f (f t)
Prelude Data.Sequence> :t (\x -> do{_ <- x; pure x})
(\x -> do{_ <- x; pure x}) :: Monad m => m a -> m (m a)
Prelude Data.Sequence> :t (\x -> do{pure x})
(\x -> do{pure x}) :: Applicative f => a -> f a
Prelude Data.Sequence> :t (\x -> do{return x})
(\x -> do{return x}) :: Monad m => a -> m a
```

I already emailed this comment, but it did not show up in trac, so I am adding it again (sorry for cross-posting)

I agree that there is no bug.

To follow up on writing a simpler version (your version does not work, because it does not map "foo"), it can be done using impredicative types, and the helper function "bar":

```
bar :: (forall x. [Phantom x]) -> [forall x. Phantom x]
bar [] = []
bar lst = help h ++ bar tl
where (h:tl) = lst
help :: (forall x. Phantom x) -> [forall x. Phantom x]
help (Phantom x) = [Phantom x]
typeAnnotatedMap3 :: forall y. (forall x. [Phantom x])
-> [Phantom y]
typeAnnotatedMap3 lst = map foo (bar lst)
```

I don't use Impredicative types because I do not understand them. For example, I don't get why this won't typecheck (bar does the same):

```
bar2 :: (forall x. [Phantom x]) -> [forall x. Phantom x]
bar2 [] = []
bar2 lst = help h : bar2 tl
where (h:tl) = lst
help :: (forall x. Phantom x) -> forall x. Phantom x
help (Phantom x) = Phantom x
```

Since we're improving error messages in this ticket, I would really like to know why the skolemn variable `x0`

(probably arising from `forall x. Phantom x`

) could not be matched to `forall x. Phantom x`

, but the only error I got was:

```
Couldn't match expected type ‘forall x. Phantom x’
with actual type ‘Phantom x0’
In the first argument of ‘(:)’, namely ‘help h’
In the expression: help h : bar tl
```

Trac field | Value |
---|---|

Type | Bug → Task |

When pattern matching, "let/where" and "case" have different behaviours.

Currently, this is accepted (a version using 'where' instead of 'let' type-checks too):

```
{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
module Main where
data Phantom x = Phantom Int deriving Show
foo :: forall y. (forall x. (Phantom x)) -> Phantom y
foo (Phantom x) = Phantom (x+1)
-- trying to map foo over a list, this is the only way I can get it to work
typeAnnotatedMap :: (forall x. [Phantom x])
-> [Phantom y]
typeAnnotatedMap intList = case intList of
[] -> []
_ -> let (phead:ptail) = intList
in foo phead : typeAnnotatedMap ptail
```

The following are not accepted:

```
typeAnnotatedMap1 :: (forall x. [Phantom x])
-> [Phantom y]
typeAnnotatedMap1 intList = case intList of
[] -> []
(phead:ptail) -> foo phead : typeAnnotatedMap1 ptail
typeAnnotatedMap2 :: (forall x. [Phantom x])
-> [Phantom y]
typeAnnotatedMap2 [] = []
typeAnnotatedMap2 (phead:ptail) = foo phead : typeAnnotatedMap2 ptail
```

The current type error is something like:

```
Couldn't match type ‘x0’ with ‘x’
because type variable ‘x’ would escape its scope
This (rigid, skolem) type variable is bound by
a type expected by the context: [Phantom x]
```

More helpful would be something like:

```
Your pattern match bound the following types to a shared skolem variable:
ptail :: [Phantom x0] (bound at rankNtest.hs:11:25)
phead :: Phantom x0 (bound at rankNtest.hs:11:19)
You may have intended to use a "let" or "where" pattern-match instead.
```

for Data.Map, I needed a "unionWithMaybe" function for my sparse system of linear equations (unionWithMaybe :: Ord k => (a -> a -> Maybe a) -> Map k a -> Map k a -> Map k a). My usage: (.+.) = Map.unionWithMaybe (\a b->case a+b of {0->Nothing;s->Just s}) (I do not think Map.unionWithMaybe can be expressed in terms of other functions without loosing performance, so I recon it would be a nice addition to the library.)

I built this function myself by modifying the Data.Map implementation, but it would be nice to see it in the official version of Data.Map. Here is the file including the modifications I made to it. Feel free to use it, I will agree to whatever license you need to make it public.

(PS: this is the first time I return modified source code to the maintainer, feel free to instruct me on how to do this in the future.)

Trac field | Value |
---|---|

Version | 7.6.3 |

Type | FeatureRequest |

TypeOfFailure | OtherFailure |

Priority | normal |

Resolution | Unresolved |

Component | libraries/base |

Test case | |

Differential revisions | |

BlockedBy | |

Related | |

Blocking | |

CC | |

Operating system | |

Architecture |

This type-incorrect program gives a wrong error message:

```
main = tmp "hello"
where tmp :: String -> IO ()
tmp = sequence_ lst
lst = [putStrLn "hi"]
```

Namely:

```
Couldn't match expected type `IO ()' with actual type `()'
Expected type: String -> IO ()
Actual type: String -> ()
In the return type of a call of `sequence_'
In the expression: sequence_ lst
```

I would not expect the "actual type" to be "String -> ()", but rather "IO ()". Note: GHC expects that "(->) String" is a monad.

Trac field | Value |
---|---|

Version | 7.6.3 |

Type | FeatureRequest |

TypeOfFailure | OtherFailure |

Priority | normal |

Resolution | Unresolved |

Component | Compiler (Type checker) |

Test case | |

Differential revisions | |

BlockedBy | |

Related | |

Blocking | |

CC | |

Operating system | |

Architecture |

When patternmatching on (a,b), the variables a and b are sometimes evaluated eagerly, though they should not be. To see where this occurs, please try to evaluate f :

```
f = (1,error "this will not be evaluated!") .++. carefully f
(a,b) .++. (c,d) = (a+c,0)
carefully (a,b) = (1, a + b)
```

Note that the expected result here is (2,0). My workaround: the program works correctly if the last line is replaced by:

`carefully x = (1, fst x + snd x)`

Trac field | Value |
---|---|

Version | 7.4.1 |

Type | Bug |

TypeOfFailure | OtherFailure |

Priority | normal |

Resolution | Unresolved |

Component | Compiler |

Test case | |

Differential revisions | |

BlockedBy | |

Related | |

Blocking | |

CC | |

Operating system | |

Architecture |