[GHC] #15928: Improve error message: Reduction stack overflow when using "coerce" (was: Reduction stack overflow when using "coerce")

GHC ghc-devs at haskell.org
Sun Nov 25 15:46:32 UTC 2018


#15928: Improve error message: Reduction stack overflow when using "coerce"
-------------------------------------+-------------------------------------
        Reporter:  harendra          |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:  8.6.3
       Component:  Compiler          |              Version:  8.6.2
      Resolution:                    |             Keywords:
Operating System:  MacOS X           |         Architecture:
 Type of failure:  Compile-time      |  Unknown/Multiple
  crash or panic                     |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Old description:

> Compiling the following snippet results in a  "Reduction stack overflow"
> error message:
>
> {{{#!hs
> {-# Language ScopedTypeVariables #-}
> {-# Language RankNTypes #-}
>
> import Data.Functor.Identity
> import Data.Coerce
>
> newtype Stream m a =
>     Stream {
>         unStream :: forall r. (Stream m a -> m r) -> m r
>     }
>
> newtype SerialT m a = SerialT (Stream m a)
>
> g :: SerialT Identity a -> Identity Bool
> g m = undefined
>
> idSerial :: SerialT Identity a -> SerialT Identity a
> idSerial = id
>
> f :: SerialT Identity a -> Identity Bool
> f = g . idSerial . coerce
>
> main = undefined
> }}}
>
> The following error message is produced on compiling this with ghc-8.6.2:
>
> {{{
> xy.hs:26:20: error:
>     • Reduction stack overflow; size = 201
>       When simplifying the following type:
>         Coercible
>           ((Stream Identity a -> Identity r) -> Identity r)
>           ((Stream Identity a0 -> Identity r) -> Identity r)
>       Use -freduction-depth=0 to disable this check
>       (any upper bound you could choose might fail unpredictably with
>        minor updates to GHC, so disabling the check is recommended if
>        you're sure that type checking should terminate)
>     • In the second argument of ‘(.)’, namely ‘coerce’
>       In the second argument of ‘(.)’, namely ‘idSerial . coerce’
>       In the expression: g . idSerial . coerce
>    |
> 26 | f = g . idSerial . coerce
>    |                    ^^^^^^
> }}}
>
> When I use an inline signature like this:
>
> {{{#!hs
> f :: SerialT Identity a -> Identity Bool
> f = g . (id :: SerialT Identity a -> SerialT Identity a) . coerce
>
> main = undefined
> }}}
>

> It again results in the same error:
>
> {{{
> xy.hs:18:60: error:
>     • Reduction stack overflow; size = 201
>       When simplifying the following type:
>         Coercible
>           ((Stream Identity a -> Identity r) -> Identity r)
>           ((Stream Identity a0 -> Identity r) -> Identity r)
>       Use -freduction-depth=0 to disable this check
>       (any upper bound you could choose might fail unpredictably with
>        minor updates to GHC, so disabling the check is recommended if
>        you're sure that type checking should terminate)
>     • In the second argument of ‘(.)’, namely ‘coerce’
>       In the second argument of ‘(.)’, namely
>         ‘(id :: SerialT Identity a -> SerialT Identity a) . coerce’
>       In the expression:
>         g . (id :: SerialT Identity a -> SerialT Identity a) . coerce
>    |
> 18 | f = g . (id :: SerialT Identity a -> SerialT Identity a) . coerce
>    |                                                            ^^^^^^
> }}}
>
> Everything works fine is I use an inline signature with a `forall`
> keyword like this:
>
> {{{#!hs
> f :: forall a. SerialT Identity a -> Identity Bool
> f = g . (id :: SerialT Identity a -> SerialT Identity a) . coerce
> }}}
>
> I have following questions:
>
> 1) Why the first version results in a panic? Is that a bug?
> 2) The second version might possibly be incorrect code because the types
> do not unify, but still it should not result in a panic, because of the
> panic I could not figure out what the problem is. It took a long time to
> isolate the code and then do some trial and error on it.

New description:

 EDIT: Executive summary: The error messages below are confusing and not
 perspicuous to users. We should fix. comment:2 has a concrete suggestion
 to use as a starting point, and comment:7 suggests we print out the role
 signature of any tycons involved.

 Compiling the following snippet results in a  "Reduction stack overflow"
 error message:

 {{{#!hs
 {-# Language ScopedTypeVariables #-}
 {-# Language RankNTypes #-}

 import Data.Functor.Identity
 import Data.Coerce

 newtype Stream m a =
     Stream {
         unStream :: forall r. (Stream m a -> m r) -> m r
     }

 newtype SerialT m a = SerialT (Stream m a)

 g :: SerialT Identity a -> Identity Bool
 g m = undefined

 idSerial :: SerialT Identity a -> SerialT Identity a
 idSerial = id

 f :: SerialT Identity a -> Identity Bool
 f = g . idSerial . coerce

 main = undefined
 }}}

 The following error message is produced on compiling this with ghc-8.6.2:

 {{{
 xy.hs:26:20: error:
     • Reduction stack overflow; size = 201
       When simplifying the following type:
         Coercible
           ((Stream Identity a -> Identity r) -> Identity r)
           ((Stream Identity a0 -> Identity r) -> Identity r)
       Use -freduction-depth=0 to disable this check
       (any upper bound you could choose might fail unpredictably with
        minor updates to GHC, so disabling the check is recommended if
        you're sure that type checking should terminate)
     • In the second argument of ‘(.)’, namely ‘coerce’
       In the second argument of ‘(.)’, namely ‘idSerial . coerce’
       In the expression: g . idSerial . coerce
    |
 26 | f = g . idSerial . coerce
    |                    ^^^^^^
 }}}

 When I use an inline signature like this:

 {{{#!hs
 f :: SerialT Identity a -> Identity Bool
 f = g . (id :: SerialT Identity a -> SerialT Identity a) . coerce

 main = undefined
 }}}


 It again results in the same error:

 {{{
 xy.hs:18:60: error:
     • Reduction stack overflow; size = 201
       When simplifying the following type:
         Coercible
           ((Stream Identity a -> Identity r) -> Identity r)
           ((Stream Identity a0 -> Identity r) -> Identity r)
       Use -freduction-depth=0 to disable this check
       (any upper bound you could choose might fail unpredictably with
        minor updates to GHC, so disabling the check is recommended if
        you're sure that type checking should terminate)
     • In the second argument of ‘(.)’, namely ‘coerce’
       In the second argument of ‘(.)’, namely
         ‘(id :: SerialT Identity a -> SerialT Identity a) . coerce’
       In the expression:
         g . (id :: SerialT Identity a -> SerialT Identity a) . coerce
    |
 18 | f = g . (id :: SerialT Identity a -> SerialT Identity a) . coerce
    |                                                            ^^^^^^
 }}}

 Everything works fine is I use an inline signature with a `forall` keyword
 like this:

 {{{#!hs
 f :: forall a. SerialT Identity a -> Identity Bool
 f = g . (id :: SerialT Identity a -> SerialT Identity a) . coerce
 }}}

 I have following questions:

 1) Why the first version results in a panic? Is that a bug?
 2) The second version might possibly be incorrect code because the types
 do not unify, but still it should not result in a panic, because of the
 panic I could not figure out what the problem is. It took a long time to
 isolate the code and then do some trial and error on it.

--

Comment (by goldfire):

 Yes, by all means we can improve that error message, and we should leave
 this ticket open as an opportunity to do so.

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15928#comment:8>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list