[commit: ghc] ghc-generics1: change cond_Representable1OK to treat (->) and tuples differently than does cond_FunctorOK (ba692b4)
José Pedro Magalhães
jpm at cs.uu.nl
Thu Jun 7 14:05:43 CEST 2012
Repository : ssh://darcs.haskell.org//srv/darcs/ghc
On branch : ghc-generics1
http://hackage.haskell.org/trac/ghc/changeset/ba692b44a8b64b499ada7145d4843c0cff2073bd
>---------------------------------------------------------------
commit ba692b44a8b64b499ada7145d4843c0cff2073bd
Author: Nicolas Frisby <nicolas.frisby at gmail.com>
Date: Tue Apr 24 23:14:57 2012 -0500
change cond_Representable1OK to treat (->) and tuples differently than does cond_FunctorOK
Signed-off-by: Jose Pedro Magalhaes <jpm at cs.ox.ac.uk>
>---------------------------------------------------------------
compiler/typecheck/TcDeriv.lhs | 3 +--
compiler/typecheck/TcGenGenerics.lhs | 27 ++++++++++++++++++---------
2 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/compiler/typecheck/TcDeriv.lhs b/compiler/typecheck/TcDeriv.lhs
index b5fdbc7..06d04f9 100644
--- a/compiler/typecheck/TcDeriv.lhs
+++ b/compiler/typecheck/TcDeriv.lhs
@@ -917,8 +917,7 @@ sideConditions mtheta cls
cond_functorOK False)
| cls_key == genClassKey = Just (cond_RepresentableOk `andCond`
checkFlag Opt_DeriveGeneric)
- | cls_key == gen1ClassKey = Just (cond_RepresentableOk `andCond`
- cond_Representable1Ok `andCond`
+ | cls_key == gen1ClassKey = Just (cond_Representable1Ok `andCond`
checkFlag Opt_DeriveGeneric)
| otherwise = Nothing
where
diff --git a/compiler/typecheck/TcGenGenerics.lhs b/compiler/typecheck/TcGenGenerics.lhs
index fbe6bc0..7389dfa 100644
--- a/compiler/typecheck/TcGenGenerics.lhs
+++ b/compiler/typecheck/TcGenGenerics.lhs
@@ -238,15 +238,14 @@ canDoGenerics1 :: TyCon -> Maybe SDoc
-- Nothing == yes
-- Just s == no, because of `s`
--- (derived from TcDeriv.cond_functorOK; will be checked only if canDoGenerics
--- passes)
+-- (derived from TcDeriv.cond_functorOK; also checks canDoGenerics)
-- OK for Generic1/Rep1
-- Currently: (a) at least one argument
-- (b) don't use argument contravariantly
-- (c) don't use argument in the wrong place, e.g. data T a = T (X a a)
-- (d) no "stupid context" on data type
-canDoGenerics1 = flip S.evalState [] . canDoGenerics1_w
+canDoGenerics1 t = canDoGenerics t `mplus` S.evalState (canDoGenerics1_w t) []
-- the state is which tycons we have entered; it avoids divergence when we
-- recur (robust against mutual recursion)
@@ -284,8 +283,18 @@ canDoGenerics1_w rep_tc
ft_check :: DataCon -> FFoldType (Bool, S.State [Name] (Maybe SDoc))
ft_check con = FT { ft_triv = bmzero, ft_var = (True, return Nothing)
, ft_co_var = (True, return $ Just $ bad con covariant)
- , ft_fun = bmplus
- , ft_tup = \_ -> foldr bmplus bmzero
+ -- NB foldDataConArgs caters to Functor/Foldable/etc,
+ -- which treat applications of functions and tuples
+ -- specially. But we just treat them like normal
+ -- applications, so we must compensate with extra logic
+ -- to ensure that the variable only occurs as the last
+ -- argument.
+ , ft_fun = \x y -> if fst x then (True, return $ Just $ bad con wrong_arg)
+ else x `bmplus` y
+ , ft_tup = \_ xs ->
+ if not (null xs) && any fst (init xs)
+ then (True, return $ Just $ bad con wrong_arg)
+ else foldr bmplus bmzero xs
, ft_ty_app = \ty x -> bmplus x $ (,) False $
if fst x then representable ty else return Nothing
, ft_bad_app = (True, return $ Just $ bad con wrong_arg)
@@ -311,10 +320,10 @@ canDoGenerics1_w rep_tc
Nothing -> canDoGenerics1_w tc
existential = (ptext . sLit) "must not have existential arguments"
- covariant = (ptext . sLit) "must not use the type variable in a function argument"
- wrong_arg = (ptext . sLit) "must use the type variable only as the last argument of a data type"
- bad_app tc = (ptext . sLit) "must not apply unrepresentable type constructors (such as" <+> ppr (tyConName tc)
- <> (ptext . sLit) ") to arguments that involve type parameters"
+ covariant = (ptext . sLit) "must not use the last type parameter in a function argument"
+ wrong_arg = (ptext . sLit) "must use the last type parameter only as the last argument of a data type, newtype, or (->)"
+ bad_app tc = (ptext . sLit) "must not apply type constructors that cannot be represented with `Rep1' (such as `" <> ppr (tyConName tc)
+ <> (ptext . sLit) "') to arguments that involve the last type parameter"
\end{code}
More information about the Cvs-ghc
mailing list