Opened 8 months ago

Last modified 8 weeks ago

#16181 new bug

ghc panic when using DerivingVia

Reported by: chessai Owned by:
Priority: normal Milestone:
Component: Compiler Version: 8.6.3
Keywords: deriving Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Compile-time crash or panic Test Case:
Blocked By: Blocking:
Related Tickets: #15831 Differential Rev(s):
Wiki Page:

Description

The following program results in a ghc panic:

{-# LANGUAGE DerivingVia #-}

import Data.Functor.Const (Const(..))
import Data.Functor.Classes

newtype FlipConst a b = FlipConst b
  deriving (Show1, Eq1) via (Const b)

Here is the output of the compile:

test/Spec/Contravariant.hs:52:13: error:
    • No instance for (Show b)
        arising from the 'deriving' clause of a data type declaration
      Possible fix:
        add (Show b) to the context of
          the deriving clause for ‘Show1 (FlipConst a)’
        or use a standalone 'deriving instance' declaration,
             so you can specify the instance context yourself
    • When deriving the instance for (Show1 (FlipConst a))
   |
52 |   deriving (Show1, Eq1) via (Const b)
   |             ^^^^^

test/Spec/Contravariant.hs:52:13: error:ghc: panic! (the 'impossible' happened)
  (GHC version 8.6.3 for x86_64-unknown-linux):
        No skolem info:
  [b_a3eO]
  Call stack:
      CallStack (from HasCallStack):
        callStackDoc, called at compiler/utils/Outputable.hs:1160:37 in ghc:Outputable
        pprPanic, called at compiler/typecheck/TcErrors.hs:2891:5 in ghc:TcErrors

Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

I'm using GHC 8.6.3

Change History (3)

comment:1 Changed 8 months ago by chessai

Keywords: derivingvia added
Type of failure: None/UnknownCompile-time crash or panic

comment:2 Changed 8 months ago by RyanGlScott

Keywords: deriving added; derivingvia removed

Great test case. I have a strong hunch that this is a symptom of #15831. When I get around to fixing that, I'll check whether that fixes this ticket as well.

comment:3 Changed 8 weeks ago by Marge Bot <ben+marge-bot@…>

In 30b6f39/ghc:

Banish reportFloatingViaTvs to the shadow realm (#15831, #16181)

GHC used to reject programs of this form:

```
newtype Age = MkAge Int
  deriving Eq via Const Int a
```

That's because an earlier implementation of `DerivingVia` would
generate the following instance:

```
instance Eq Age where
  (==) = coerce @(Const Int a -> Const Int a -> Bool)
                @(Age         -> Age         -> Bool)
                (==)
```

Note that the `a` in `Const Int a` is not bound anywhere, which
causes all sorts of issues. I figured that no one would ever want to
write code like this anyway, so I simply banned "floating" `via` type
variables like `a`, checking for their presence in the aptly named
`reportFloatingViaTvs` function.

`reportFloatingViaTvs` ended up being implemented in a subtly
incorrect way, as #15831 demonstrates. Following counsel with the
sage of gold fire, I decided to abandon `reportFloatingViaTvs`
entirely and opt for a different approach that would _accept_
the instance above. This is because GHC now generates this instance
instead:

```
instance forall a. Eq Age where
  (==) = coerce @(Const Int a -> Const Int a -> Bool)
                @(Age         -> Age         -> Bool)
                (==)
```

Notice that we now explicitly quantify the `a` in
`instance forall a. Eq Age`, so everything is peachy scoping-wise.
See `Note [Floating `via` type variables]` in `TcDeriv` for the full
scoop.

A pleasant benefit of this refactoring is that it made it much easier
to catch the problem observed in #16181, so this patch fixes that
issue too.

Fixes #15831. Fixes #16181.
Note: See TracTickets for help on using tickets.