Skip to content

Standalone deriving for GADT data family instance now produces bogus case that results in type error

Summary

The following code

{-# LANGUAGE DataKinds
           , StandaloneDeriving
           , PolyKinds
           , StandaloneKindSignatures
           , TypeFamilies
           , GADTs
           , FlexibleInstances
#-}

import Data.Kind

type Sing :: k -> Type
data family Sing a

data instance Sing @(Maybe k) a where
  SJust :: Sing (a :: k) -> Sing (Just a)
  SNothing :: Sing Nothing

deriving instance Show (Sing Nothing)

worked fine in 8.11.20200824, producing the following instance (via -ddump-deriv):

  instance GHC.Show.Show (Main.Sing 'GHC.Maybe.Nothing) where
    GHC.Show.showsPrec _ Main.SNothing = GHC.Show.showString "SNothing"

In 9.0.0.20201227, however, GHC produces this instance:

  instance forall a.
           GHC.Show.Show (Main.Sing 'GHC.Maybe.Nothing) where
    GHC.Show.showsPrec a_a7Av (Main.SJust b1_a7Aw)
      = GHC.Show.showParen
          (a_a7Av GHC.Classes.>= 11)
          ((GHC.Base..)
             (GHC.Show.showString "SJust ") (GHC.Show.showsPrec 11 b1_a7Aw))
    GHC.Show.showsPrec _ Main.SNothing = GHC.Show.showString "SNothing"

As far as I understand, the SJust case can never occur, and indeed, with -fdefer-type-errors, this appears to behave like a perfectly valid instance, show SNothing works in GHCi. Yet without it, it produces this error:

Bug.hs:19:1: error:
    • Could not deduce (Show (Sing a1))
        arising from a use of ‘showsPrec’
      from the context: 'Nothing ~ 'Just a1
        bound by a pattern with constructor:
                   SJust :: forall k (a :: k). Sing a -> Sing ('Just a),
                 in an equation for ‘showsPrec’
        at Bug.hs:19:1-37
    • In the second argument of ‘(.)’, namely ‘(showsPrec 11 b1)’
      In the second argument of ‘showParen’, namely
        ‘((.) (showString "SJust ") (showsPrec 11 b1))’
      In the expression:
        showParen (a >= 11) ((.) (showString "SJust ") (showsPrec 11 b1))
      When typechecking the code for ‘showsPrec’
        in a derived instance for ‘Show (Sing 'Nothing)’:
        To see the code I am typechecking, use -ddump-deriv
   |
19 | deriving instance Show (Sing Nothing)
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expected behavior

It should work as it did in 8.11.

Environment

  • GHC version used: 9.0.0.20201227

Optional:

  • Operating System: Ubuntu inside WSL2 inside Windows 10
  • System Architecture: x86_64
Edited by Jakob Brünker
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information