Commit 639e702b authored by Ryan Scott's avatar Ryan Scott
Browse files

Refactor DeriveAnyClass's instance context inference

Summary:
Currently, `DeriveAnyClass` has two glaring flaws:

* It only works on classes whose argument is of kind `*` or `* -> *` (#9821).
* The way it infers constraints makes no sense. It basically co-opts the
  algorithms used to infer contexts for `Eq` (for `*`-kinded arguments) or
  `Functor` (for `(* -> *)`-kinded arguments). This tends to produce overly
  constrained instances, which in extreme cases can lead to legitimate things
  failing to typecheck (#12594). Or even worse, it can trigger GHC panics
  (#12144 and #12423).

This completely reworks the way `DeriveAnyClass` infers constraints to fix
these two issues. It now uses the type signatures of the derived class's
methods to infer constraints (and to simplify them). A high-level description
of how this works is included in the GHC users' guide, and more technical notes
on what is going on can be found as comments (and a Note) in `TcDerivInfer`.

Fixes #9821, #12144, #12423, #12594.

Test Plan: ./validate

Reviewers: dfeuer, goldfire, simonpj, austin, bgamari

Subscribers: dfeuer, thomie

Differential Revision: https://phabricator.haskell.org/D2961
parent e79ef75d
......@@ -80,12 +80,12 @@ Overall plan
3. Add the derived bindings, generating InstInfos
-}
data EarlyDerivSpec = InferTheta (DerivSpec ThetaOrigin)
data EarlyDerivSpec = InferTheta (DerivSpec [ThetaOrigin])
| GivenTheta (DerivSpec ThetaType)
-- InferTheta ds => the context for the instance should be inferred
-- In this case ds_theta is the list of all the constraints
-- needed, such as (Eq [a], Eq a), together with a suitable CtLoc
-- to get good error messages.
-- In this case ds_theta is the list of all the sets of
-- constraints needed, such as (Eq [a], Eq a), together with a
-- suitable CtLoc to get good error messages.
-- The inference process is to reduce this to a
-- simpler form (e.g. Eq a)
--
......@@ -97,7 +97,8 @@ earlyDSLoc :: EarlyDerivSpec -> SrcSpan
earlyDSLoc (InferTheta spec) = ds_loc spec
earlyDSLoc (GivenTheta spec) = ds_loc spec
splitEarlyDerivSpec :: [EarlyDerivSpec] -> ([DerivSpec ThetaOrigin], [DerivSpec ThetaType])
splitEarlyDerivSpec :: [EarlyDerivSpec]
-> ([DerivSpec [ThetaOrigin]], [DerivSpec ThetaType])
splitEarlyDerivSpec [] = ([],[])
splitEarlyDerivSpec (InferTheta spec : specs) =
case splitEarlyDerivSpec specs of (is, gs) -> (spec : is, gs)
......@@ -980,8 +981,7 @@ mkDataTypeEqn dflags overlap_mode tvs cls cls_tys
= case deriv_strat of
Just StockStrategy -> mk_eqn_stock dflags mtheta cls cls_tys rep_tc
go_for_it bale_out
Just AnyclassStrategy -> mk_eqn_anyclass dflags rep_tc cls
go_for_it bale_out
Just AnyclassStrategy -> mk_eqn_anyclass dflags go_for_it bale_out
-- GeneralizedNewtypeDeriving makes no sense for non-newtypes
Just NewtypeStrategy -> bale_out gndNonNewtypeErr
-- Lacking a user-requested deriving strategy, we will try to pick
......@@ -1010,8 +1010,7 @@ mk_data_eqn overlap_mode tvs cls cls_tys tycon tc_args rep_tc rep_tc_args
dfun_name <- newDFunName' cls tycon
case mtheta of
Nothing -> -- Infer context
inferConstraints tvs cls cls_tys
inst_ty rep_tc rep_tc_args
inferConstraints tvs cls cls_tys inst_ty rep_tc rep_tc_args mechanism
$ \inferred_constraints tvs' inst_tys' ->
return $ InferTheta $ DS
{ ds_loc = loc
......@@ -1052,14 +1051,14 @@ mk_eqn_stock' cls go_for_it
Nothing ->
pprPanic "mk_eqn_stock': Not a stock class!" (ppr cls)
mk_eqn_anyclass :: DynFlags -> TyCon -> Class
mk_eqn_anyclass :: DynFlags
-> (DerivSpecMechanism -> TcRn EarlyDerivSpec)
-> (SDoc -> TcRn EarlyDerivSpec)
-> TcRn EarlyDerivSpec
mk_eqn_anyclass dflags rep_tc cls go_for_it bale_out
= case canDeriveAnyClass dflags rep_tc cls of
Nothing -> go_for_it DerivSpecAnyClass
Just msg -> bale_out msg
mk_eqn_anyclass dflags go_for_it bale_out
= case canDeriveAnyClass dflags of
IsValid -> go_for_it DerivSpecAnyClass
NotValid msg -> bale_out msg
mk_eqn_no_mechanism :: DynFlags -> TyCon -> DerivContext
-> Class -> [Type] -> TyCon
......@@ -1103,8 +1102,7 @@ mkNewTypeEqn dflags overlap_mode tvs
case deriv_strat of
Just StockStrategy -> mk_eqn_stock dflags mtheta cls cls_tys rep_tycon
go_for_it_other bale_out
Just AnyclassStrategy -> mk_eqn_anyclass dflags rep_tycon cls
go_for_it_other bale_out
Just AnyclassStrategy -> mk_eqn_anyclass dflags go_for_it_other bale_out
Just NewtypeStrategy ->
-- Since the user explicitly asked for GeneralizedNewtypeDeriving, we
-- don't need to perform all of the checks we normally would, such as
......@@ -1170,7 +1168,7 @@ mkNewTypeEqn dflags overlap_mode tvs
deriveAnyClass = xopt LangExt.DeriveAnyClass dflags
go_for_it_gnd = do
traceTc "newtype deriving:" $
ppr tycon <+> ppr rep_tys <+> ppr all_preds
ppr tycon <+> ppr rep_tys <+> ppr all_thetas
let mechanism = DerivSpecNewtype rep_inst_ty
doDerivInstErrorChecks1 cls cls_tys tycon tc_args rep_tycon mtheta
strat_used mechanism
......@@ -1190,7 +1188,7 @@ mkNewTypeEqn dflags overlap_mode tvs
, ds_name = dfun_name, ds_tvs = dfun_tvs
, ds_cls = cls, ds_tys = inst_tys
, ds_tc = rep_tycon
, ds_theta = all_preds
, ds_theta = all_thetas
, ds_overlap = overlap_mode
, ds_mechanism = mechanism }
go_for_it_other = mk_data_eqn overlap_mode tvs cls cls_tys tycon
......@@ -1258,12 +1256,12 @@ mkNewTypeEqn dflags overlap_mode tvs
-- Next we figure out what superclass dictionaries to use
-- See Note [Newtype deriving superclasses] above
sc_theta :: [PredOrigin]
sc_preds :: [PredOrigin]
cls_tyvars = classTyVars cls
dfun_tvs = tyCoVarsOfTypesWellScoped inst_tys
inst_ty = mkTyConApp tycon tc_args
inst_tys = cls_tys ++ [inst_ty]
sc_theta = mkThetaOrigin DerivOrigin TypeLevel $
sc_preds = map (mkPredOrigin DerivOrigin TypeLevel) $
substTheta (zipTvSubst cls_tyvars inst_tys) $
classSCTheta cls
......@@ -1271,9 +1269,9 @@ mkNewTypeEqn dflags overlap_mode tvs
-- If there are no methods, we don't need any constraints
-- Otherwise we need (C rep_ty), for the representation methods,
-- and constraints to coerce each individual method
meth_theta :: [PredOrigin]
meth_preds :: [PredOrigin]
meths = classMethods cls
meth_theta | null meths = [] -- No methods => no constraints
meth_preds | null meths = [] -- No methods => no constraints
-- (Trac #12814)
| otherwise = rep_pred_o : coercible_constraints
coercible_constraints
......@@ -1283,8 +1281,8 @@ mkNewTypeEqn dflags overlap_mode tvs
, let (Pair t1 t2) = mkCoerceClassMethEqn cls dfun_tvs
inst_tys rep_inst_ty meth ]
all_preds :: [PredOrigin]
all_preds = meth_theta ++ sc_theta
all_thetas :: [ThetaOrigin]
all_thetas = [mkThetaOriginFromPreds $ meth_preds ++ sc_preds]
-------------------------------------------------------------------
-- Figuring out whether we can only do this newtype-deriving thing
......@@ -1627,7 +1625,9 @@ genDerivStuff mechanism loc clas tycon inst_tys tyvars
mini_subst = mkTvSubst (mkInScopeSet (mkVarSet tyvars)) mini_env
dflags <- getDynFlags
tyfam_insts <-
ASSERT2( isNothing (canDeriveAnyClass dflags tycon clas)
-- canDeriveAnyClass should ensure that this code can't be reached
-- unless -XDeriveAnyClass is enabled.
ASSERT2( isValid (canDeriveAnyClass dflags)
, ppr "genDerivStuff: bad derived class" <+> ppr clas )
mapM (tcATDefault False loc mini_subst emptyNameSet)
(classATItems clas)
......
This diff is collapsed.
......@@ -13,8 +13,8 @@ module TcDerivUtils (
DerivSpecMechanism(..), isDerivSpecStock,
isDerivSpecNewtype, isDerivSpecAnyClass,
DerivContext, DerivStatus(..),
PredOrigin(..), ThetaOrigin, mkPredOrigin,
mkThetaOrigin, substPredOrigin, substThetaOrigin,
PredOrigin(..), ThetaOrigin(..), mkPredOrigin,
mkThetaOrigin, mkThetaOriginFromPreds, substPredOrigin,
checkSideConditions, hasStockDeriving,
canDeriveAnyClass,
std_class_via_coercible, non_coercible_class,
......@@ -151,24 +151,73 @@ data DerivStatus = CanDerive -- Stock class, can derive
-- | A 'PredType' annotated with the origin of the constraint 'CtOrigin',
-- and whether or the constraint deals in types or kinds.
data PredOrigin = PredOrigin PredType CtOrigin TypeOrKind
type ThetaOrigin = [PredOrigin]
-- | A list of wanted 'PredOrigin' constraints ('to_wanted_origins') alongside
-- any corresponding given constraints ('to_givens') and locally quantified
-- type variables ('to_tvs').
--
-- In most cases, 'to_givens' will be empty, as most deriving mechanisms (e.g.,
-- stock and newtype deriving) do not require given constraints. The exception
-- is @DeriveAnyClass@, which can involve given constraints. For example,
-- if you tried to derive an instance for the following class using
-- @DeriveAnyClass@:
--
-- @
-- class Foo a where
-- bar :: a -> b -> String
-- default bar :: (Show a, Ix b) => a -> b -> String
-- bar = show
--
-- baz :: Eq a => a -> a -> Bool
-- default baz :: Ord a => a -> a -> Bool
-- baz x y = compare x y == EQ
-- @
--
-- Then it would generate two 'ThetaOrigin's, one for each method:
--
-- @
-- [ ThetaOrigin { to_tvs = [b]
-- , to_givens = []
-- , to_wanted_origins = [Show a, Ix b] }
-- , ThetaOrigin { to_tvs = []
-- , to_givens = [Eq a]
-- , to_wanted_origins = [Ord a] }
-- ]
-- @
data ThetaOrigin
= ThetaOrigin { to_tvs :: [TyVar]
, to_givens :: ThetaType
, to_wanted_origins :: [PredOrigin] }
instance Outputable PredOrigin where
ppr (PredOrigin ty _ _) = ppr ty -- The origin is not so interesting when debugging
instance Outputable ThetaOrigin where
ppr (ThetaOrigin { to_tvs = tvs
, to_givens = givens
, to_wanted_origins = wanted_origins })
= hang (text "ThetaOrigin")
2 (vcat [ text "to_tvs =" <+> ppr tvs
, text "to_givens =" <+> ppr givens
, text "to_wanted_origins =" <+> ppr wanted_origins ])
mkPredOrigin :: CtOrigin -> TypeOrKind -> PredType -> PredOrigin
mkPredOrigin origin t_or_k pred = PredOrigin pred origin t_or_k
mkThetaOrigin :: CtOrigin -> TypeOrKind -> ThetaType -> ThetaOrigin
mkThetaOrigin origin t_or_k = map (mkPredOrigin origin t_or_k)
mkThetaOrigin :: CtOrigin -> TypeOrKind -> [TyVar] -> ThetaType -> ThetaType
-> ThetaOrigin
mkThetaOrigin origin t_or_k tvs givens
= ThetaOrigin tvs givens . map (mkPredOrigin origin t_or_k)
-- A common case where the ThetaOrigin only contains wanted constraints, with
-- no givens or locally scoped type variables.
mkThetaOriginFromPreds :: [PredOrigin] -> ThetaOrigin
mkThetaOriginFromPreds = ThetaOrigin [] []
substPredOrigin :: HasCallStack => TCvSubst -> PredOrigin -> PredOrigin
substPredOrigin subst (PredOrigin pred origin t_or_k)
= PredOrigin (substTy subst pred) origin t_or_k
substThetaOrigin :: HasCallStack => TCvSubst -> ThetaOrigin -> ThetaOrigin
substThetaOrigin subst = map (substPredOrigin subst)
{-
************************************************************************
* *
......@@ -270,7 +319,7 @@ checkSideConditions dflags mtheta cls cls_tys rep_tc
| otherwise -> DerivableClassError (classArgsErr cls cls_tys)
-- e.g. deriving( Eq s )
| Just err <- canDeriveAnyClass dflags rep_tc cls
| NotValid err <- canDeriveAnyClass dflags
= NonDerivableClass err -- DeriveAnyClass does not work
| otherwise
......@@ -324,27 +373,14 @@ sideConditions mtheta cls
cond_vanilla = cond_stdOK mtheta True -- Vanilla data constructors but
-- allow no data cons or polytype arguments
canDeriveAnyClass :: DynFlags -> TyCon -> Class -> Maybe SDoc
-- Nothing: we can (try to) derive it via an empty instance declaration
-- Just s: we can't, reason s
-- Precondition: the class is not one of the standard ones
canDeriveAnyClass dflags _tycon clas
canDeriveAnyClass :: DynFlags -> Validity
-- IsValid: we can (try to) derive it via an empty instance declaration
-- NotValid s: we can't, reason s
canDeriveAnyClass dflags
| not (xopt LangExt.DeriveAnyClass dflags)
= Just (text "Try enabling DeriveAnyClass")
| not (any (target_kind `tcEqKind`) [ liftedTypeKind, typeToTypeKind ])
= Just (text "The last argument of class" <+> quotes (ppr clas)
<+> text "does not have kind * or (* -> *)")
= NotValid (text "Try enabling DeriveAnyClass")
| otherwise
= Nothing -- OK!
where
-- We are making an instance (C t1 .. tn (T s1 .. sm))
-- and we can only do so if the kind of C's last argument
-- is * or (* -> *). Because only then can we make a reasonable
-- guess at the instance context
target_kind = tyVarKind (last (classTyVars clas))
typeToTypeKind :: Kind
typeToTypeKind = liftedTypeKind `mkFunTy` liftedTypeKind
= IsValid -- OK!
type Condition = DynFlags -> TyCon -> Validity
-- TyCon is the *representation* tycon if the data type is an indexed one
......
......@@ -11,7 +11,8 @@ module TcSimplify(
tcCheckSatisfiability,
-- For Rules we need these
solveWanteds, runTcSDeriveds
solveWanteds, solveWantedsAndDrop,
approximateWC, runTcSDeriveds
) where
#include "HsVersions.h"
......
......@@ -1817,12 +1817,12 @@ pickCapturedPreds qtvs theta
type PredWithSCs = (PredType, [PredType])
mkMinimalBySCs :: [PredType] -> [PredType]
-- Remove predicates that can be deduced from others by superclasses
-- Result is a subset of the input
-- Remove predicates that can be deduced from others by superclasses,
-- including duplicate predicates. The result is a subset of the input.
mkMinimalBySCs ptys = go preds_with_scs []
where
preds_with_scs :: [PredWithSCs]
preds_with_scs = [ (pred, transSuperClasses pred)
preds_with_scs = [ (pred, pred : transSuperClasses pred)
| pred <- ptys ]
go :: [PredWithSCs] -- Work list
......
......@@ -55,6 +55,17 @@ Compiler
class instance using the :ghc-flag:`-XDerivingStrategies` language extension
(see :ref:`deriving-strategies`).
- :ghc-flag:`-XDeriveAnyClass` is no longer limited to type classes whose
argument is of kind ``*`` or ``* -> *``.
- The means by which :ghc-flag:`-XDeriveAnyClass` infers instance contexts has
been completely overhauled. The instance context is now inferred using the
type signatures (and default type signatures) of the derived class's methods
instead of using the datatype's definition, which often led to
overconstrained instances or instances that didn't typecheck (or worse,
triggered GHC panics). See the section on
:ref:`DeriveAnyClass <derive-any-class>` for more details.
- GHC now allows standalone deriving using :ghc-flag:`-XDeriveAnyClass` on
any data type, even if its data constructors are not in scope. This is
consistent with the fact that this code (in the presence of
......
......@@ -4185,29 +4185,71 @@ Note the following details
class on a newtype, and :ghc-flag:`-XGeneralizedNewtypeDeriving` is also on,
:ghc-flag:`-XDeriveAnyClass` takes precedence.
- :ghc-flag:`-XDeriveAnyClass` is allowed only when the last argument of the class
has kind ``*`` or ``(* -> *)``. So this is not allowed: ::
- The instance context is determined by the type signatures of the derived
class's methods. For instance, if the class is: ::
data T a b = MkT a b deriving( Bifunctor )
class Foo a where
bar :: a -> String
default bar :: Show a => a -> String
bar = show
baz :: a -> a -> Bool
default baz :: Ord a => a -> a -> Bool
baz x y = compare x y == EQ
And you attempt to derive it using :ghc-flag:`-XDeriveAnyClass`: ::
instance Eq a => Eq (Option a) where ...
instance Ord a => Ord (Option a) where ...
instance Show a => Show (Option a) where ...
data Option a = None | Some a deriving Foo
Then the derived ``Foo`` instance will be: ::
instance (Show a, Ord a) => Foo (Option a)
Since the default type signatures for ``bar`` and ``baz`` require ``Show a``
and ``Ord a`` constraints, respectively.
Constraints on the non-default type signatures can play a role in inferring
the instance context as well. For example, if you have this class: ::
class HigherEq f where
(==#) :: f a -> f a -> Bool
default (==#) :: Eq (f a) => f a -> f a -> Bool
x ==# y = (x == y)
And you tried to derive an instance for it: ::
because the last argument of ``Bifunctor :: (* -> * -> *) -> Constraint``
has the wrong kind.
instance Eq a => Eq (Option a) where ...
data Option a = None | Some a deriving HigherEq
- The instance context will be generated according to the same rules
used when deriving ``Eq`` (if the kind of the type is ``*``), or
the rules for ``Functor`` (if the kind of the type is ``(* -> *)``).
For example ::
Then it will fail with an error to the effect of: ::
instance C a => C (a,b) where ...
No instance for (Eq a)
arising from the 'deriving' clause of a data type declaration
data T a b = MkT a (a,b) deriving( C )
That is because we require an ``Eq (Option a)`` instance from the default
type signature for ``(==#)``, which in turn requires an ``Eq a`` instance,
which we don't have in scope. But if you tweak the definition of
``HigherEq`` slightly: ::
The ``deriving`` clause will generate ::
class HigherEq f where
(==#) :: Eq a => f a -> f a -> Bool
default (==#) :: Eq (f a) => f a -> f a -> Bool
x ==# y = (x == y)
instance C a => C (T a b) where {}
Then it becomes possible to derive a ``HigherEq Option`` instance. Note that
the only difference is that now the non-default type signature for ``(==#)``
brings in an ``Eq a`` constraint. Constraints from non-default type
signatures never appear in the derived instance context itself, but they can
be used to discharge obligations that are demanded by the default type
signatures. In the example above, the default type signature demanded an
``Eq a`` instance, and the non-default signature was able to satisfy that
request, so the derived instance is simply: ::
The constraints `C a` and `C (a,b)` are generated from the data
constructor arguments, but the latter simplifies to `C a`.
instance HigherEq Option
- :ghc-flag:`-XDeriveAnyClass` can be used with partially applied classes,
such as ::
......
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE KindSignatures #-}
module T12144_1 where
class C (a :: * -> *)
data T a = MkT (a -> Int) deriving C
{-# LANGUAGE DeriveAnyClass #-}
module T12144_2 where
class C1 a
instance C1 a => C1 (Foo a)
class C1 a => C2 a where
c2 :: a -> String
c2 _ = "C2 default"
newtype Foo a = Foo a deriving C2
foo :: C1 a => Foo a -> String
foo = c2
{-# LANGUAGE DefaultSignatures, DeriveAnyClass #-}
module T12423 where
class Eq1 f where
(==#) :: Eq a => f a -> f a -> Bool
default (==#) :: Eq (f a) => f a -> f a -> Bool
(==#) = (==)
data Foo a = Foo (Either a a)
deriving (Eq, Eq1)
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators #-}
module T12594 where
import GHC.Generics
data Action = Action
class ToField a where
toField :: a -> Action
instance ToField Int where
-- Not the actual instance, but good enough for testing purposes
toField _ = Action
class ToRow a where
toRow :: a -> [Action]
default toRow :: (Generic a, GToRow (Rep a)) => a -> [Action]
toRow = gtoRow . from
class GToRow f where
gtoRow :: f p -> [Action]
instance GToRow f => GToRow (M1 c i f) where
gtoRow (M1 x) = gtoRow x
instance (GToRow f, GToRow g) => GToRow (f :*: g) where
gtoRow (f :*: g) = gtoRow f ++ gtoRow g
instance (ToField a) => GToRow (K1 R a) where
gtoRow (K1 a) = [toField a]
instance GToRow U1 where
gtoRow _ = []
data Foo = Foo { bar :: Int }
deriving (Generic, ToRow)
T9968a.hs:8:13: warning: [-Wmissing-methods (in -Wdefault)]
• No explicit implementation for
either ‘bimap’ or (‘first’ and ‘second’)
• In the instance declaration for ‘Bifunctor Blah’
......@@ -61,19 +61,24 @@ test('T10524', normal, compile, [''])
test('T11148', normal, run_command,
['$MAKE -s --no-print-directory T11148'])
test('T9968', normal, compile, [''])
test('T9968a', normal, compile, [''])
test('T11174', normal, compile, [''])
test('T11416', normal, compile, [''])
test('T11396', normal, compile, [''])
test('T11357', normal, compile, [''])
test('T11509_2', expect_fail, compile, [''])
test('T11509_2', normal, compile, [''])
test('T11509_3', normal, compile, [''])
test('T11732a', normal, compile, [''])
test('T11732b', normal, compile, [''])
test('T11732c', normal, compile, [''])
test('T11833', normal, compile, [''])
test('T12144_1', normal, compile, [''])
test('T12144_2', normal, compile, [''])
test('T12245', normal, compile, [''])
test('T12399', normal, compile, [''])
test('T12423', normal, compile, [''])
test('T12583', normal, compile, [''])
test('T12594', normal, compile, [''])
test('T12616', normal, compile, [''])
test('T12688', normal, compile, [''])
test('T12814', normal, compile, ['-Wredundant-constraints'])
......@@ -9,9 +9,3 @@ T10598_fail1.hs:10:40: error:
• Can't make a derived instance of ‘Num B’ with the stock strategy:
‘Num’ is not a stock derivable class (Eq, Show, etc.)
• In the newtype declaration for ‘B’
T10598_fail1.hs:11:41: error:
• Can't make a derived instance of
‘Z C’ with the anyclass strategy:
The last argument of class ‘Z’ does not have kind * or (* -> *)
• In the data declaration for ‘C’
T9968a.hs:8:13: error:
• Can't make a derived instance of ‘Bifunctor Blah’:
‘Bifunctor’ is not a stock derivable class (Eq, Show, etc.)
The last argument of class ‘Bifunctor’ does not have kind * or (* -> *)
• In the data declaration for ‘Blah’
......@@ -54,7 +54,6 @@ test('T9600-1', normal, compile_fail, [''])
test('T9687', normal, compile_fail, [''])
test('T8984', normal, compile_fail, [''])
test('T9968a', normal, compile_fail, [''])
test('T10598_fail1', normal, compile_fail, [''])
test('T10598_fail2', normal, compile_fail, [''])
test('T10598_fail3', normal, compile_fail, [''])
......
drvfail004.hs:8:12:
No instance for (Eq (Foo a b))
arising from the 'deriving' clause of a data type declaration
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Ord (Foo a b))
drvfail004.hs:8:12: error:
• Could not deduce (Eq (Foo a b))
arising from the 'deriving' clause of a data type declaration
from the context: (Ord b, Ord a)
bound by the deriving clause for ‘Ord (Foo a b)’
at drvfail004.hs:8:12-14
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
• When deriving the instance for (Ord (Foo a b))
drvfail012.hs:5:33:
No instance for (Eq (Ego a))
arising from the 'deriving' clause of a data type declaration
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Ord (Ego a))
drvfail012.hs:5:33: error:
• Could not deduce (Eq (Ego a))
arising from the 'deriving' clause of a data type declaration
from the context: Ord a
bound by the deriving clause for ‘Ord (Ego a)’
at drvfail012.hs:5:33-35
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
• When deriving the instance for (Ord (Ego a))
tcfail046.hs:10:50: error:
No instance for (Eq (Process a))
arising from the first field of ‘Do’ (type ‘Process a’)
(maybe you haven't applied a function to enough arguments?)
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Eq (Continuation a))
No instance for (Eq (Process a))