X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcDeriv.lhs;h=34baafb7a65bd19f00d88fc23e1e3407c9c2ab3f;hb=ff843f76541ab39ed30c050ae41c7c07c8980d3a;hp=b994a278298bce08f124cf378c463459bc613af5;hpb=92267aa26adb1ab5a6d8004a80fdf6aa06ea4e44;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcDeriv.lhs b/compiler/typecheck/TcDeriv.lhs index b994a27..34baafb 100644 --- a/compiler/typecheck/TcDeriv.lhs +++ b/compiler/typecheck/TcDeriv.lhs @@ -40,10 +40,13 @@ import Name import NameSet import TyCon import TcType +import BuildTyCl +import BasicTypes import Var import VarSet import PrelNames import SrcLoc +import UniqSupply import Util import ListSetOps import Outputable @@ -292,12 +295,14 @@ both of them. So we gather defs/uses from deriving just like anything else. tcDeriving :: [LTyClDecl Name] -- All type constructors -> [LInstDecl Name] -- All instance declarations -> [LDerivDecl Name] -- All stand-alone deriving declarations - -> TcM ([InstInfo Name], -- The generated "instance decls" - HsValBinds Name, -- Extra generated top-level bindings - DefUses) + -> TcM ([InstInfo Name] -- The generated "instance decls" + ,HsValBinds Name -- Extra generated top-level bindings + ,DefUses + ,[TyCon] -- Extra generated top-level types + ,[TyCon]) -- Extra generated type family instances tcDeriving tycl_decls inst_decls deriv_decls - = recoverM (return ([], emptyValBindsOut, emptyDUs)) $ + = recoverM (return ([], emptyValBindsOut, emptyDUs, [], [])) $ do { -- Fish the "deriving"-related information out of the TcEnv -- And make the necessary "equations". is_boot <- tcIsHsBoot @@ -313,19 +318,35 @@ tcDeriving tycl_decls inst_decls deriv_decls ; insts2 <- mapM (genInst False overlap_flag) final_specs - -- Generate the generic to/from functions from each type declaration - ; gen_binds <- mkGenericBinds is_boot tycl_decls - ; (inst_info, rn_binds, rn_dus) <- renameDeriv is_boot gen_binds (insts1 ++ insts2) + -- We no longer generate the old generic to/from functions + -- from each type declaration, so this is emptyBag + ; gen_binds <- return emptyBag -- mkGenericBinds is_boot tycl_decls + + -- Generate the generic Representable0 instances + -- from each type declaration + ; repInstsMeta <- genGenericRepBinds is_boot tycl_decls + + ; let repInsts = concat (map (\(a,_,_) -> a) repInstsMeta) + repMetaTys = map (\(_,b,_) -> b) repInstsMeta + repTyCons = map (\(_,_,c) -> c) repInstsMeta + + ; (inst_info, rn_binds, rn_dus) + <- renameDeriv is_boot gen_binds (insts1 ++ insts2 ++ repInsts) ; dflags <- getDOpts ; liftIO (dumpIfSet_dyn dflags Opt_D_dump_deriv "Derived instances" (ddump_deriving inst_info rn_binds)) - ; return (inst_info, rn_binds, rn_dus) } + ; when (not (null inst_info)) $ + dumpDerivingInfo (ddump_deriving inst_info rn_binds) + ; return ( inst_info, rn_binds, rn_dus + , concat (map metaTyCons2TyCons repMetaTys), repTyCons) } where ddump_deriving :: [InstInfo Name] -> HsValBinds Name -> SDoc ddump_deriving inst_infos extra_binds - = vcat (map pprInstInfoDetails inst_infos) $$ ppr extra_binds + = hang (ptext (sLit "Derived instances")) + 2 (vcat (map (\i -> pprInstInfoDetails i $$ text "") inst_infos) + $$ ppr extra_binds) renameDeriv :: Bool -> LHsBinds RdrName -> [(InstInfo RdrName, DerivAuxBinds)] @@ -373,19 +394,20 @@ renameDeriv is_boot gen_binds insts , mkFVs (map dataConName (tyConDataCons tc))) -- See Note [Newtype deriving and unused constructors] - rn_inst_info (InstInfo { iSpec = inst, iBinds = VanillaInst binds sigs standalone_deriv }) + rn_inst_info inst_info@(InstInfo { iSpec = inst, iBinds = VanillaInst binds sigs standalone_deriv }) = -- Bring the right type variables into -- scope (yuk), and rename the method binds ASSERT( null sigs ) bindLocalNames (map Var.varName tyvars) $ do { (rn_binds, fvs) <- rnMethodBinds clas_nm (\_ -> []) [] binds ; let binds' = VanillaInst rn_binds [] standalone_deriv - ; return (InstInfo { iSpec = inst, iBinds = binds' }, fvs) } + ; return (inst_info { iBinds = binds' }, fvs) } where (tyvars,_, clas,_) = instanceHead inst clas_nm = className clas ----------------------------------------- +{- Now unused mkGenericBinds :: Bool -> [LTyClDecl Name] -> TcM (LHsBinds RdrName) mkGenericBinds is_boot tycl_decls | is_boot @@ -398,6 +420,7 @@ mkGenericBinds is_boot tycl_decls -- We are only interested in the data type declarations, -- and then only in the ones whose 'has-generics' flag is on -- The predicate tyConHasGenerics finds both of these +-} \end{code} Note [Newtype deriving and unused constructors] @@ -467,12 +490,13 @@ deriveStandalone (L loc (DerivDecl deriv_ty)) = setSrcSpan loc $ addErrCtxt (standaloneCtxt deriv_ty) $ do { traceTc "Standalone deriving decl for" (ppr deriv_ty) - ; (tvs, theta, tau) <- tcHsInstHead deriv_ty + ; (tvs, theta, cls, inst_tys) <- tcHsInstHead deriv_ty ; traceTc "Standalone deriving;" $ vcat [ text "tvs:" <+> ppr tvs , text "theta:" <+> ppr theta - , text "tau:" <+> ppr tau ] - ; (cls, inst_tys) <- checkValidInstance deriv_ty tvs theta tau + , text "cls:" <+> ppr cls + , text "tys:" <+> ppr inst_tys ] + ; checkValidInstance deriv_ty tvs theta cls inst_tys -- C.f. TcInstDcls.tcLocalInstDecl1 ; let cls_tys = take (length inst_tys - 1) inst_tys @@ -595,32 +619,46 @@ mkEqnHelp :: CtOrigin -> [TyVar] -> Class -> [Type] -> Type mkEqnHelp orig tvs cls cls_tys tc_app mtheta | Just (tycon, tc_args) <- tcSplitTyConApp_maybe tc_app , isAlgTyCon tycon -- Check for functions, primitive types etc - = do { (rep_tc, rep_tc_args) <- tcLookupDataFamInst tycon tc_args - -- Be careful to test rep_tc here: in the case of families, - -- we want to check the instance tycon, not the family tycon - - -- For standalone deriving (mtheta /= Nothing), - -- check that all the data constructors are in scope. - -- No need for this when deriving Typeable, becuase we don't need - -- the constructors for that. - ; rdr_env <- getGlobalRdrEnv - ; let hidden_data_cons = isAbstractTyCon rep_tc || any not_in_scope (tyConDataCons rep_tc) - not_in_scope dc = null (lookupGRE_Name rdr_env (dataConName dc)) - ; checkTc (isNothing mtheta || - not hidden_data_cons || - className cls `elem` typeableClassNames) - (derivingHiddenErr tycon) - - ; dflags <- getDOpts - ; if isDataTyCon rep_tc then - mkDataTypeEqn orig dflags tvs cls cls_tys - tycon tc_args rep_tc rep_tc_args mtheta - else - mkNewTypeEqn orig dflags tvs cls cls_tys - tycon tc_args rep_tc rep_tc_args mtheta } + = mk_alg_eqn tycon tc_args | otherwise = failWithTc (derivingThingErr False cls cls_tys tc_app (ptext (sLit "The last argument of the instance must be a data or newtype application"))) + + where + bale_out msg = failWithTc (derivingThingErr False cls cls_tys tc_app msg) + + mk_alg_eqn tycon tc_args + | className cls `elem` typeableClassNames + = do { dflags <- getDOpts + ; case checkTypeableConditions (dflags, tycon) of + Just err -> bale_out err + Nothing -> mk_typeable_eqn orig tvs cls tycon tc_args mtheta } + + | isDataFamilyTyCon tycon + , length tc_args /= tyConArity tycon + = bale_out (ptext (sLit "Unsaturated data family application")) + + | otherwise + = do { (rep_tc, rep_tc_args) <- tcLookupDataFamInst tycon tc_args + -- Be careful to test rep_tc here: in the case of families, + -- we want to check the instance tycon, not the family tycon + + -- For standalone deriving (mtheta /= Nothing), + -- check that all the data constructors are in scope. + ; rdr_env <- getGlobalRdrEnv + ; let hidden_data_cons = isAbstractTyCon rep_tc || + any not_in_scope (tyConDataCons rep_tc) + not_in_scope dc = null (lookupGRE_Name rdr_env (dataConName dc)) + ; unless (isNothing mtheta || not hidden_data_cons) + (bale_out (derivingHiddenErr tycon)) + + ; dflags <- getDOpts + ; if isDataTyCon rep_tc then + mkDataTypeEqn orig dflags tvs cls cls_tys + tycon tc_args rep_tc rep_tc_args mtheta + else + mkNewTypeEqn orig dflags tvs cls cls_tys + tycon tc_args rep_tc rep_tc_args mtheta } \end{code} @@ -655,15 +693,10 @@ mkDataTypeEqn orig dflags tvs cls cls_tys go_for_it = mk_data_eqn orig tvs cls tycon tc_args rep_tc rep_tc_args mtheta bale_out msg = failWithTc (derivingThingErr False cls cls_tys (mkTyConApp tycon tc_args) msg) -mk_data_eqn, mk_typeable_eqn - :: CtOrigin -> [TyVar] -> Class - -> TyCon -> [TcType] -> TyCon -> [TcType] -> DerivContext - -> TcM EarlyDerivSpec +mk_data_eqn :: CtOrigin -> [TyVar] -> Class + -> TyCon -> [TcType] -> TyCon -> [TcType] -> DerivContext + -> TcM EarlyDerivSpec mk_data_eqn orig tvs cls tycon tc_args rep_tc rep_tc_args mtheta - | getName cls `elem` typeableClassNames - = mk_typeable_eqn orig tvs cls tycon tc_args rep_tc rep_tc_args mtheta - - | otherwise = do { dfun_name <- new_dfun_name cls tycon ; loc <- getSrcSpanM ; let inst_tys = [mkTyConApp tycon tc_args] @@ -678,7 +711,11 @@ mk_data_eqn orig tvs cls tycon tc_args rep_tc rep_tc_args mtheta ; return (if isJust mtheta then Right spec -- Specified context else Left spec) } -- Infer context -mk_typeable_eqn orig tvs cls tycon tc_args rep_tc rep_tc_args mtheta +---------------------- +mk_typeable_eqn :: CtOrigin -> [TyVar] -> Class + -> TyCon -> [TcType] -> DerivContext + -> TcM EarlyDerivSpec +mk_typeable_eqn orig tvs cls tycon tc_args mtheta -- The Typeable class is special in several ways -- data T a b = ... deriving( Typeable ) -- gives @@ -692,7 +729,7 @@ mk_typeable_eqn orig tvs cls tycon tc_args rep_tc rep_tc_args mtheta = do { checkTc (cls `hasKey` typeableClassKey) (ptext (sLit "Use deriving( Typeable ) on a data type declaration")) ; real_cls <- tcLookupClass (typeableClassNames !! tyConArity tycon) - ; mk_typeable_eqn orig tvs real_cls tycon [] rep_tc [] (Just []) } + ; mk_typeable_eqn orig tvs real_cls tycon [] (Just []) } | otherwise -- standaone deriving = do { checkTc (null tc_args) @@ -703,10 +740,10 @@ mk_typeable_eqn orig tvs cls tycon tc_args rep_tc rep_tc_args mtheta ; return (Right $ DS { ds_loc = loc, ds_orig = orig, ds_name = dfun_name, ds_tvs = [] , ds_cls = cls, ds_tys = [mkTyConApp tycon []] - , ds_tc = rep_tc, ds_tc_args = rep_tc_args + , ds_tc = tycon, ds_tc_args = [] , ds_theta = mtheta `orElse` [], ds_newtype = False }) } - +---------------------- inferConstraints :: [TyVar] -> Class -> [TcType] -> TyCon -> [TcType] -> ThetaType -- Generate a sufficiently large set of constraints that typechecking the -- generated method definitions should succeed. This set will be simplified @@ -735,7 +772,7 @@ inferConstraints _ cls inst_tys rep_tc rep_tc_args get_constrained_tys :: [Type] -> [Type] get_constrained_tys tys - | is_functor_like = concatMap (deepSubtypesContaining last_tv) tys + | is_functor_like = concatMap (deepSubtypesContaining last_tv) tys | otherwise = tys rep_tc_tvs = tyConTyVars rep_tc @@ -792,6 +829,9 @@ checkSideConditions dflags mtheta cls cls_tys rep_tc where ty_args_why = quotes (ppr (mkClassPred cls cls_tys)) <+> ptext (sLit "is not a class") +checkTypeableConditions :: Condition +checkTypeableConditions = checkFlag Opt_DeriveDataTypeable `andCond` cond_typeableOK + nonStdErr :: Class -> SDoc nonStdErr cls = quotes (ppr cls) <+> ptext (sLit "is not a derivable class") @@ -812,7 +852,6 @@ sideConditions mtheta cls cond_functorOK False) -- Functor/Fold/Trav works ok for rank-n types | cls_key == traversableClassKey = Just (checkFlag Opt_DeriveTraversable `andCond` cond_functorOK False) - | getName cls `elem` typeableClassNames = Just (checkFlag Opt_DeriveDataTypeable `andCond` cond_typeableOK) | otherwise = Nothing where cls_key = getUnique cls @@ -885,7 +924,7 @@ cond_isEnumeration (_, rep_tc) where why = sep [ quotes (pprSourceTyCon rep_tc) <+> ptext (sLit "is not an enumeration type") - , nest 2 $ ptext (sLit "(an enumeration consists of one or more nullary constructors)") ] + , ptext (sLit "(an enumeration consists of one or more nullary, non-GADT constructors)") ] -- See Note [Enumeration types] in TyCon cond_isProduct :: Condition @@ -900,20 +939,16 @@ cond_typeableOK :: Condition -- OK for Typeable class -- Currently: (a) args all of kind * -- (b) 7 or fewer args -cond_typeableOK (_, rep_tc) - | tyConArity rep_tc > 7 = Just too_many - | not (all (isSubArgTypeKind . tyVarKind) (tyConTyVars rep_tc)) - = Just bad_kind - | isFamInstTyCon rep_tc = Just fam_inst -- no Typable for family insts - | otherwise = Nothing +cond_typeableOK (_, tc) + | tyConArity tc > 7 = Just too_many + | not (all (isSubArgTypeKind . tyVarKind) (tyConTyVars tc)) + = Just bad_kind + | otherwise = Nothing where - too_many = quotes (pprSourceTyCon rep_tc) <+> + too_many = quotes (pprSourceTyCon tc) <+> ptext (sLit "has too many arguments") - bad_kind = quotes (pprSourceTyCon rep_tc) <+> + bad_kind = quotes (pprSourceTyCon tc) <+> ptext (sLit "has arguments of kind other than `*'") - fam_inst = quotes (pprSourceTyCon rep_tc) <+> - ptext (sLit "is a type family") - functorLikeClassKeys :: [Unique] functorLikeClassKeys = [functorClassKey, foldableClassKey, traversableClassKey] @@ -925,10 +960,7 @@ cond_functorOK :: Bool -> Condition -- (c) don't use argument in the wrong place, e.g. data T a = T (X a a) -- (d) optionally: don't use function types -- (e) no "stupid context" on data type -cond_functorOK allowFunctions (dflags, rep_tc) - | not (xopt Opt_DeriveFunctor dflags) - = Just (ptext (sLit "You need -XDeriveFunctor to derive an instance for this class")) - +cond_functorOK allowFunctions (_, rep_tc) | null tc_tvs = Just (ptext (sLit "Data type") <+> quotes (ppr rep_tc) <+> ptext (sLit "has no parameters")) @@ -1272,7 +1304,7 @@ inferInstanceContexts oflag infer_specs gen_soln (DS { ds_loc = loc, ds_orig = orig, ds_tvs = tyvars , ds_cls = clas, ds_tys = inst_tys, ds_theta = deriv_rhs }) = setSrcSpan loc $ - addErrCtxt (derivInstCtxt clas inst_tys) $ + addErrCtxt (derivInstCtxt the_pred) $ do { -- Check for a bizarre corner case, when the derived instance decl should -- have form instance C a b => D (T a) where ... -- Note that 'b' isn't a parameter of T. This gives rise to all sorts @@ -1287,7 +1319,7 @@ inferInstanceContexts oflag infer_specs , not (tyVarsOfPred pred `subVarSet` tv_set)] ; mapM_ (addErrTc . badDerivedPred) weird_preds - ; theta <- simplifyDeriv orig tyvars deriv_rhs + ; theta <- simplifyDeriv orig the_pred tyvars deriv_rhs -- checkValidInstance tyvars theta clas inst_tys -- Not necessary; see Note [Exotic derived instance contexts] -- in TcSimplify @@ -1297,6 +1329,8 @@ inferInstanceContexts oflag infer_specs -- Hence no need to call: -- checkValidInstance tyvars theta clas inst_tys ; return (sortLe (<=) theta) } -- Canonicalise before returning the solution + where + the_pred = mkClassPred clas inst_tys ------------------------------------------------------------------ mkInstance :: OverlapFlag -> ThetaType -> DerivSpec -> Instance @@ -1392,26 +1426,26 @@ the renamer. What a great hack! genInst :: Bool -- True <=> standalone deriving -> OverlapFlag -> DerivSpec -> TcM (InstInfo RdrName, DerivAuxBinds) -genInst standalone_deriv oflag spec - | ds_newtype spec - = return (InstInfo { iSpec = mkInstance oflag (ds_theta spec) spec - , iBinds = NewTypeDerived co rep_tycon }, []) +genInst standalone_deriv oflag + spec@(DS { ds_tc = rep_tycon, ds_tc_args = rep_tc_args + , ds_theta = theta, ds_newtype = is_newtype + , ds_name = name, ds_cls = clas }) + | is_newtype + = return (InstInfo { iSpec = inst_spec + , iBinds = NewTypeDerived co rep_tycon }, []) | otherwise - = do { let loc = getSrcSpan (ds_name spec) - inst = mkInstance oflag (ds_theta spec) spec - clas = ds_cls spec - - -- In case of a family instance, we need to use the representation - -- tycon (after all, it has the data constructors) - ; fix_env <- getFixityEnv - ; let (meth_binds, aux_binds) = genDerivBinds loc fix_env clas rep_tycon - binds = VanillaInst meth_binds [] standalone_deriv - ; return (InstInfo { iSpec = inst, iBinds = binds }, aux_binds) - } + = do { fix_env <- getFixityEnv + ; let loc = getSrcSpan name + (meth_binds, aux_binds) = genDerivBinds loc fix_env clas rep_tycon + -- In case of a family instance, we need to use the representation + -- tycon (after all, it has the data constructors) + + ; return (InstInfo { iSpec = inst_spec + , iBinds = VanillaInst meth_binds [] standalone_deriv } + , aux_binds) } where - rep_tycon = ds_tc spec - rep_tc_args = ds_tc_args spec + inst_spec = mkInstance oflag theta spec co1 = case tyConFamilyCoercion_maybe rep_tycon of Just co_con -> ACo (mkTyConApp co_con rep_tc_args) Nothing -> id_co @@ -1453,6 +1487,133 @@ genDerivBinds loc fix_env clas tycon ,(foldableClassKey, gen_Foldable_binds) ,(traversableClassKey, gen_Traversable_binds) ] + +-- Generate the binds for the generic representation +genGenericRepBinds :: Bool -> [LTyClDecl Name] + -> TcM [([(InstInfo RdrName, DerivAuxBinds)] + , MetaTyCons, TyCon)] +genGenericRepBinds isBoot tyclDecls + | isBoot = return [] + | otherwise = do + allTyDecls <- mapM tcLookupTyCon [ tcdName d | L _ d <- tyclDecls + , isDataDecl d ] + let tyDecls = filter tyConHasGenerics allTyDecls + inst1 <- mapM genGenericRepBind tyDecls + let (_repInsts, metaTyCons, _repTys) = unzip3 inst1 + metaInsts <- ASSERT (length tyDecls == length metaTyCons) + mapM genDtMeta (zip tyDecls metaTyCons) + return (ASSERT (length inst1 == length metaInsts) + [ (ri : mi, ms, rt) + | ((ri, ms, rt), mi) <- zip inst1 metaInsts ]) + +genGenericRepBind :: TyCon -> TcM ((InstInfo RdrName, DerivAuxBinds) + , MetaTyCons, TyCon) +genGenericRepBind tc = + do clas <- tcLookupClass rep0ClassName + uniqS <- newUniqueSupply + dfun_name <- new_dfun_name clas tc + let + -- Uniques for everyone + (uniqD:uniqs) = uniqsFromSupply uniqS + (uniqsC,us) = splitAt (length tc_cons) uniqs + uniqsS :: [[Unique]] -- Unique supply for the S datatypes + uniqsS = mkUniqsS tc_arits us + mkUniqsS [] _ = [] + mkUniqsS (n:t) us = case splitAt n us of + (us1,us2) -> us1 : mkUniqsS t us2 + + tc_name = tyConName tc + tc_cons = tyConDataCons tc + tc_arits = map dataConSourceArity tc_cons + + tc_occ = nameOccName tc_name + d_occ = mkGenD tc_occ + c_occ m = mkGenC tc_occ m + s_occ m n = mkGenS tc_occ m n + mod_name = nameModule (tyConName tc) + d_name = mkExternalName uniqD mod_name d_occ wiredInSrcSpan + c_names = [ mkExternalName u mod_name (c_occ m) wiredInSrcSpan + | (u,m) <- zip uniqsC [0..] ] + s_names = [ [ mkExternalName u mod_name (s_occ m n) wiredInSrcSpan + | (u,n) <- zip us [0..] ] | (us,m) <- zip uniqsS [0..] ] + tvs = tyConTyVars tc + tc_ty = mkTyConApp tc (mkTyVarTys tvs) + + mkTyCon name = ASSERT( isExternalName name ) + buildAlgTyCon name [] [] mkAbstractTyConRhs + NonRecursive False False NoParentTyCon Nothing + + metaDTyCon <- mkTyCon d_name + metaCTyCons <- sequence [ mkTyCon c_name | c_name <- c_names ] + metaSTyCons <- mapM sequence + [ [ mkTyCon s_name + | s_name <- s_namesC ] | s_namesC <- s_names ] + + let metaDts = MetaTyCons metaDTyCon metaCTyCons metaSTyCons + + rep0_tycon <- tc_mkRep0TyCon tc metaDts + + let + mkInstRep0 = (InstInfo { iSpec = inst, iBinds = binds } + , [ {- No DerivAuxBinds -} ]) + inst = mkLocalInstance dfun NoOverlap + binds = VanillaInst (mkBindsRep0 tc) [] False + + dfun = mkDictFunId dfun_name (tyConTyVars tc) [] clas [tc_ty] + return (mkInstRep0, metaDts, rep0_tycon) + +genDtMeta :: (TyCon, MetaTyCons) -> TcM [(InstInfo RdrName, DerivAuxBinds)] +genDtMeta (tc,metaDts) = + do dClas <- tcLookupClass datatypeClassName + d_dfun_name <- new_dfun_name dClas tc + cClas <- tcLookupClass constructorClassName + c_dfun_names <- sequence [ new_dfun_name cClas tc | _ <- metaC metaDts ] + sClas <- tcLookupClass selectorClassName + s_dfun_names <- sequence (map sequence [ [ new_dfun_name sClas tc + | _ <- x ] + | x <- metaS metaDts ]) + fix_env <- getFixityEnv + + let + (dBinds,cBinds,sBinds) = mkBindsMetaD fix_env tc + + -- Datatype + d_metaTycon = metaD metaDts + d_inst = mkLocalInstance d_dfun NoOverlap + d_binds = VanillaInst dBinds [] False + d_dfun = mkDictFunId d_dfun_name (tyConTyVars tc) [] dClas + [ mkTyConTy d_metaTycon ] + d_mkInst = (InstInfo { iSpec = d_inst, iBinds = d_binds }, []) + + -- Constructor + c_metaTycons = metaC metaDts + c_insts = [ mkLocalInstance (c_dfun c ds) NoOverlap + | (c, ds) <- myZip1 c_metaTycons c_dfun_names ] + c_binds = [ VanillaInst c [] False | c <- cBinds ] + c_dfun c dfun_name = mkDictFunId dfun_name (tyConTyVars tc) [] cClas + [ mkTyConTy c ] + c_mkInst = [ (InstInfo { iSpec = is, iBinds = bs }, []) + | (is,bs) <- myZip1 c_insts c_binds ] + + -- Selector + s_metaTycons = metaS metaDts + s_insts = map (map (\(s,ds) -> mkLocalInstance (s_dfun s ds) NoOverlap)) + (myZip2 s_metaTycons s_dfun_names) + s_binds = [ [ VanillaInst s [] False | s <- ss ] | ss <- sBinds ] + s_dfun s dfun_name = mkDictFunId dfun_name (tyConTyVars tc) [] sClas + [ mkTyConTy s ] + s_mkInst = map (map (\(is,bs) -> (InstInfo {iSpec=is, iBinds=bs}, []))) + (myZip2 s_insts s_binds) + + myZip1 :: [a] -> [b] -> [(a,b)] + myZip1 l1 l2 = ASSERT (length l1 == length l2) zip l1 l2 + + myZip2 :: [[a]] -> [[b]] -> [[(a,b)]] + myZip2 l1 l2 = + ASSERT (and (zipWith (>=) (map length l1) (map length l2))) + [ zip x1 x2 | (x1,x2) <- zip l1 l2 ] + + return (d_mkInst : c_mkInst ++ concat s_mkInst) \end{code} @@ -1501,9 +1662,9 @@ standaloneCtxt :: LHsType Name -> SDoc standaloneCtxt ty = hang (ptext (sLit "In the stand-alone deriving instance for")) 2 (quotes (ppr ty)) -derivInstCtxt :: Class -> [Type] -> Message -derivInstCtxt clas inst_tys - = ptext (sLit "When deriving the instance for") <+> parens (pprClassPred clas inst_tys) +derivInstCtxt :: PredType -> Message +derivInstCtxt pred + = ptext (sLit "When deriving the instance for") <+> parens (ppr pred) badDerivedPred :: PredType -> Message badDerivedPred pred