White space only
[ghc-hetmet.git] / compiler / typecheck / TcDeriv.lhs
index 6934eb1..ba11079 100644 (file)
@@ -205,16 +205,18 @@ And then translate it to:
 %************************************************************************
 
 \begin{code}
-tcDeriving  :: [LTyClDecl Name]        -- All type constructors
+tcDeriving  :: [LTyClDecl Name]  -- All type constructors
+            -> [LInstDecl Name]  -- All instance declarations
             -> [LDerivDecl Name] -- All stand-alone deriving declarations
            -> TcM ([InstInfo],         -- The generated "instance decls"
                    HsValBinds Name)    -- Extra generated top-level bindings
 
-tcDeriving tycl_decls deriv_decls
+tcDeriving tycl_decls inst_decls deriv_decls
   = recoverM (returnM ([], emptyValBindsOut)) $
     do {       -- Fish the "deriving"-related information out of the TcEnv
                -- and make the necessary "equations".
-       ; (ordinary_eqns, newtype_inst_info) <- makeDerivEqns tycl_decls deriv_decls
+       ; (ordinary_eqns, newtype_inst_info) 
+                <- makeDerivEqns tycl_decls inst_decls deriv_decls
 
        ; (ordinary_inst_info, deriv_binds) 
                <- extendLocalInstEnv (map iSpec newtype_inst_info)  $
@@ -338,17 +340,24 @@ when the dict is constructed in TcInstDcls.tcInstDecl2
 
 \begin{code}
 makeDerivEqns :: [LTyClDecl Name] 
+              -> [LInstDecl Name]
              -> [LDerivDecl Name] 
              -> TcM ([DerivEqn],       -- Ordinary derivings
                      [InstInfo])       -- Special newtype derivings
 
-makeDerivEqns tycl_decls deriv_decls
+makeDerivEqns tycl_decls inst_decls deriv_decls
   = do { eqns1 <- mapM deriveTyData $
-                  [ (p,d) | d@(L _ (TyData {tcdDerivs = Just preds})) <- tycl_decls
-                          , p <- preds ]
+                     extractTyDataPreds tycl_decls ++
+                    [ pd                        -- traverse assoc data families
+                     | L _ (InstDecl _ _ _ ats) <- inst_decls
+                    , pd <- extractTyDataPreds ats ]
        ; eqns2 <- mapM deriveStandalone deriv_decls
        ; return ([eqn  | (Just eqn, _)  <- eqns1 ++ eqns2],
                  [inst | (_, Just inst) <- eqns1 ++ eqns2]) }
+  where
+    extractTyDataPreds decls =                    
+      [(p, d) | d@(L _ (TyData {tcdDerivs = Just preds})) <- decls, p <- preds]
+
 
 ------------------------------------------------------------------
 deriveStandalone :: LDerivDecl Name -> TcM (Maybe DerivEqn, Maybe InstInfo)
@@ -479,7 +488,8 @@ mk_data_eqn loc orig tvs cls tycon tc_args rep_tc rep_tc_args
        ; let ordinary_constraints
                = [ mkClassPred cls [arg_ty] 
                  | data_con <- tyConDataCons rep_tc,
-                   arg_ty   <- dataConInstOrigArgTys data_con rep_tc_args,
+                   arg_ty   <- ASSERT( isVanillaDataCon data_con )
+                               dataConInstOrigArgTys data_con rep_tc_args,
                    not (isUnLiftedType arg_ty) ] -- No constraints for unlifted types?
 
              tiresome_subst = zipTopTvSubst (tyConTyVars rep_tc) rep_tc_args
@@ -866,11 +876,11 @@ solveDerivEqns overlap_flag orig_eqns
     gen_soln :: DerivEqn -> TcM [PredType]
     gen_soln (loc, orig, _, tyvars, clas, inst_ty, deriv_rhs)
       = setSrcSpan loc $
+       addErrCtxt (derivInstCtxt clas [inst_ty]) $ 
        do { theta <- tcSimplifyDeriv orig tyvars deriv_rhs
-          ; addErrCtxt (derivInstCtxt theta clas [inst_ty]) $ 
-       do { checkNoErrs (checkValidInstance tyvars theta clas [inst_ty])
-               -- See Note [Deriving context]
-               -- If this fails, don't continue
+               -- checkValidInstance tyvars theta clas [inst_ty]
+               -- Not necessary; see Note [Exotic derived instance contexts]
+               --                in TcSimplify
 
                  -- Check for a bizarre corner case, when the derived instance decl should
                  -- have form  instance C a b => D (T a) where ...
@@ -884,7 +894,7 @@ solveDerivEqns overlap_flag orig_eqns
                -- Claim: the result instance declaration is guaranteed valid
                -- Hence no need to call:
                --   checkValidInstance tyvars theta clas inst_tys
-          ; return (sortLe (<=) theta) } }     -- Canonicalise before returning the solution
+          ; return (sortLe (<=) theta) }       -- Canonicalise before returning the solution
 
     ------------------------------------------------------------------
     mk_inst_spec :: DerivEqn -> DerivSoln -> Instance
@@ -903,25 +913,6 @@ extendLocalInstEnv dfuns thing_inside
       ; setGblEnv env' thing_inside }
 \end{code}
 
-Note [Deriving context]
-~~~~~~~~~~~~~~~~~~~~~~~
-With -fglasgow-exts, we allow things like (C Int a) in the simplified
-context for a derived instance declaration, because at a use of this
-instance, we might know that a=Bool, and have an instance for (C Int
-Bool)
-
-We nevertheless insist that each predicate meets the termination
-conditions. If not, the deriving mechanism generates larger and larger
-constraints.  Example:
-  data Succ a = S a
-  data Seq a = Cons a (Seq (Succ a)) | Nil deriving Show
-
-Note the lack of a Show instance for Succ.  First we'll generate
-  instance (Show (Succ a), Show a) => Show (Seq a)
-and then
-  instance (Show (Succ (Succ a)), Show (Succ a), Show a) => Show (Seq a)
-and so on.  Instead we want to complain of no instance for (Show (Succ a)).
-  
 
 %************************************************************************
 %*                                                                     *
@@ -1137,10 +1128,8 @@ derivingThingErr clas tys ty why
 standaloneCtxt :: LHsType Name -> SDoc
 standaloneCtxt ty = ptext SLIT("In the stand-alone deriving instance for") <+> quotes (ppr ty)
 
-derivInstCtxt theta clas inst_tys
-  = hang (ptext SLIT("In the derived instance:"))
-        2 (pprThetaArrow theta <+> pprClassPred clas inst_tys)
--- Used for the ...Thetas variants; all top level
+derivInstCtxt clas inst_tys
+  = ptext SLIT("When deriving the instance for") <+> parens (pprClassPred clas inst_tys)
 
 badDerivedPred pred
   = vcat [ptext SLIT("Can't derive instances where the instance context mentions"),