Skip to content

Derived Generic1 instance for GADT no longer compiles on HEAD

This code compiles on GHC 9.2 and earlier:

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
module Bug where

import Data.Kind
import GHC.Generics

data family DF (a :: Type)
data instance DF (b :: Type) where
  MkDF :: c -> DF c
  deriving Generic1

However, it fails with HEAD:

$ ~/Software/ghc-9.3.20220302/bin/ghc Bug.hs
[1 of 1] Compiling Bug              ( Bug.hs, Bug.o )

Bug.hs:10:15: error:
    • Couldn't match type ‘Par1’ with ‘K1 R c’
      Expected: Rep1 DF a
        Actual: M1
                  D
                  ('MetaData "DF" "Bug" "main" 'False)
                  (M1
                     C
                     ('MetaCons "MkDF" 'PrefixI 'False)
                     (M1
                        S
                        ('MetaSel
                           'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy)
                        Par1))
                  a
    • In the expression: M1 (case x of MkDF g1 -> M1 (M1 (Par1 g1)))
      In an equation for ‘from1’:
          from1 x = M1 (case x of MkDF g1 -> M1 (M1 (Par1 g1)))
      When typechecking the code for ‘from1’
        in a derived instance for ‘Generic1 DF’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘Generic1 DF’
   |
10 | data instance DF (b :: Type) where
   |               ^

Bug.hs:10:15: error:
    • Couldn't match type ‘Par1’ with ‘K1 R c’
      Expected: Rep1 DF a
        Actual: M1
                  D
                  ('MetaData "DF" "Bug" "main" 'False)
                  (M1
                     C
                     ('MetaCons "MkDF" 'PrefixI 'False)
                     (M1
                        S
                        ('MetaSel
                           'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy)
                        Par1))
                  a
    • In the pattern: M1 x
      In an equation for ‘to1’:
          to1 (M1 x) = case x of (M1 (M1 g1)) -> MkDF (unPar1 g1)
      When typechecking the code for ‘to1’
        in a derived instance for ‘Generic1 DF’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘Generic1 DF’
   |
10 | data instance DF (b :: Type) where
   |               ^

The -ddump-deriv output contains a clue as to why:

$ ~/Software/ghc-9.3.20220302/bin/ghc Bug.hs -ddump-deriv
[1 of 1] Compiling Bug              ( Bug.hs, Bug.o )

==================== Derived instances ====================
Derived class instances:
  instance GHC.Generics.Generic1 Bug.DF where
    GHC.Generics.from1 x_a1EC
      = GHC.Generics.M1
          (case x_a1EC of
             Bug.MkDF g1_a1ED
               -> GHC.Generics.M1 (GHC.Generics.M1 (GHC.Generics.Par1 g1_a1ED)))
    GHC.Generics.to1 (GHC.Generics.M1 x_a1EE)
      = case x_a1EE of
          (GHC.Generics.M1 (GHC.Generics.M1 g1_a1EF))
            -> Bug.MkDF (GHC.Generics.unPar1 g1_a1EF)
  

Derived type family instances:
  type GHC.Generics.Rep1 Bug.DF = GHC.Generics.D1
                                    ('GHC.Generics.MetaData "DF" "Bug" "main" 'GHC.Types.False)
                                    (GHC.Generics.C1
                                       ('GHC.Generics.MetaCons
                                          "MkDF" 'GHC.Generics.PrefixI 'GHC.Types.False)
                                       (GHC.Generics.S1
                                          ('GHC.Generics.MetaSel
                                             'GHC.Maybe.Nothing
                                             'GHC.Generics.NoSourceUnpackedness
                                             'GHC.Generics.NoSourceStrictness
                                             'GHC.Generics.DecidedLazy)
                                          (GHC.Generics.Rec0 c_a101)))

The Rep1 instance is using Rec0, even though it should actually be using Par1. If I had to guess what patch is responsible for the regression, I would bet on it being !6976 (closed). I'll take a look.

Edited by Ryan Scott
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information