Opened 2 years ago

Closed 2 years ago

Last modified 8 weeks ago

#10361 closed bug (fixed)

DeriveAnyClass does not fill in associated type defaults

Reported by: kosmikus Owned by: dreixel
Priority: normal Milestone: 8.0.1
Component: Compiler (Type checker) Version: 7.10.1
Keywords: Generics, deriving Cc: vagarenko
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: GHC rejects valid program Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s): Phab:D1283
Wiki Page:

Description

I would expect test1 and test2 below to typecheck.

This is a reduced test case from trying to use DeriveAnyClass on the Generic class of the generics-sop package, which unfortunately fails due to this bug.

{-# LANGUAGE DeriveAnyClass, StandaloneDeriving, TypeFamilies #-}
module Test where

class C1 a where
  type T1 a
  type instance T1 a = Char

class C2 a where -- equivalent to C1
  type T2 a
  type instance T2 a = Char

class C3 a where -- equivalent to C1, C2
  type T3 a
  type instance T3 a = Char

data A = B
  deriving C1

deriving instance C2 A

instance C3 A

-- fails
-- test1 :: T1 A
-- test1 = 'x'

-- fails
-- test2 :: T2 A
-- test2 = 'x'

-- succeeds
test3 :: T3 A
test3 = 'x'

Change History (11)

comment:1 Changed 2 years ago by kosmikus

Component: CompilerCompiler (Type checker)
Type of failure: None/UnknownGHC rejects valid program

comment:2 Changed 2 years ago by simonpj

Owner: set to dreixel

Pedro, this is your bag, right?

comment:3 Changed 2 years ago by dreixel

I agree that this is a bug, yes. Not entirely sure when I will have time to fix it, though.

comment:4 Changed 2 years ago by vagarenko

My case of this bug:

{-# LANGUAGE DefaultSignatures, TypeFamilies, TypeOperators, FlexibleContexts, DeriveGeneric, DeriveAnyClass #-}

module Bug where

import GHC.Generics

---------------------------------------------------------------------
class Convert a where
    type Result a
    type instance Result a = GResult (Rep a)

    convert :: a -> Result a
    default convert :: (Generic a, GConvert (Rep a)) => a -> GResult (Rep a)
    convert x = gconvert (from x)

instance Convert Float where
    type Result Float = Float
    convert = id

instance Convert Int where
    type Result Int = Int
    convert = id

---------------------------------------------------------------------
class GConvert f where
    type GResult f
    gconvert :: f p -> GResult f

instance (Convert c) => GConvert (K1 i c) where
    type GResult (K1 i c) = Result c
    gconvert (K1 x) = convert x

instance (GConvert f) => GConvert (M1 i t f) where
    type GResult (M1 i t f) = GResult f
    gconvert (M1 x) = gconvert x

instance (GConvert f, GConvert g) => GConvert (f :*: g) where
    type GResult (f :*: g) = (GResult f, GResult g)
    gconvert (x :*: y) = (gconvert x, gconvert y)

---------------------------------------------------------------------
-- This works:
data Data1 = Data1 Int Float
    deriving (Generic)

instance Convert Data1

val :: (Int, Float)
val = convert $ Data1 0 0.0

-- This doesn't:
data Data2 = Data2 Int Float
    deriving (Generic, Convert)
-- Couldn't match type `Result Data2' with `(Int, Float)'
--   Expected type: Data2 -> Result Data2
--     Actual type: Data2 -> GResult (Rep Data2)
--   In the expression: Bug.$gdmconvert
--   In an equation for `convert': convert = Bug.$gdmconvert
--   When typechecking the code for  `convert'
--     in a derived instance for `Convert Data2':
--     To see the code I am typechecking, use -ddump-deriv
Last edited 2 years ago by vagarenko (previous) (diff)

comment:5 Changed 2 years ago by vagarenko

Cc: vagarenko added

comment:6 Changed 2 years ago by RyanGlScott

Differential Rev(s): Phab:D1283

comment:7 Changed 2 years ago by Ben Gamari <ben@…>

In 2f74be9c/ghc:

Fill in associated type defaults with DeriveAnyClass

Summary:
Unlike `-XDefaultSignatures`, `-XDeriveAnyClass` would not fill in
associated type family defaults when deriving a class which contained
them.

In order to fix this properly, `tcATDefault` needed to be used from
`TcGenDeriv`. To avoid a module import cycle, `tcATDefault` was moved
from `TcInstDcls` to `TcClsDcl`.

Fixes #10361.

Test Plan: ./validate

Reviewers: kosmikus, dreixel, bgamari, austin, simonpj

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D1283

GHC Trac Issues: #10361

comment:8 Changed 2 years ago by bgamari

Resolution: fixed
Status: newclosed

Merged.

comment:9 Changed 21 months ago by simonpj

Keywords: Generics added

comment:10 Changed 21 months ago by thomie

Milestone: 8.0.1

comment:11 Changed 8 weeks ago by RyanGlScott

Keywords: deriving added
Note: See TracTickets for help on using tickets.