- = baleOut (derivingThingErr cls cls_tys (mkTyConApp tycon tc_args) err)
-
- | otherwise
- = ASSERT( null cls_tys )
- do { loc <- getSrcSpanM
- ; eqn <- mk_data_eqn loc orig tvs cls tycon tc_args rep_tc rep_tc_args
- ; return (Just eqn, Nothing) }
-
-mk_data_eqn :: SrcSpan -> InstOrigin -> [TyVar] -> Class
- -> TyCon -> [TcType] -> TyCon -> [TcType] -> TcM DerivEqn
-mk_data_eqn loc orig tvs cls tycon tc_args rep_tc rep_tc_args
- | cls `hasKey` typeableClassKey
- = -- The Typeable class is special in several ways
+ CanDerive -> mk_data_eqn orig tvs cls tycon tc_args rep_tc rep_tc_args mtheta
+ NonDerivableClass -> bale_out (nonStdErr cls)
+ DerivableClassError msg -> bale_out msg
+ where
+ bale_out msg = failWithTc (derivingThingErr cls cls_tys (mkTyConApp tycon tc_args) msg)
+
+mk_data_eqn, mk_typeable_eqn
+ :: InstOrigin -> [TyVar] -> Class
+ -> TyCon -> [TcType] -> TyCon -> [TcType] -> Maybe ThetaType
+ -> 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 ordinary_constraints
+ = [ mkClassPred cls [arg_ty]
+ | data_con <- tyConDataCons rep_tc,
+ arg_ty <- ASSERT( isVanillaDataCon data_con )
+ get_constrained_tys $
+ substTys subst $
+ dataConInstOrigArgTys data_con all_rep_tc_args,
+ not (isUnLiftedType arg_ty) ]
+ -- No constraints for unlifted types
+ -- Where they are legal we generate specilised function calls
+
+ -- For functor-like classes, two things are different
+ -- (a) We recurse over argument types to generate constraints
+ -- See Functor examples in TcGenDeriv
+ -- (b) The rep_tc_args will be one short
+ is_functor_like = getUnique cls `elem` functorLikeClassKeys
+
+ get_constrained_tys :: [Type] -> [Type]
+ get_constrained_tys tys
+ | is_functor_like = concatMap (deepSubtypesContaining last_tv) tys
+ | otherwise = tys
+
+ rep_tc_tvs = tyConTyVars rep_tc
+ last_tv = last rep_tc_tvs
+ all_rep_tc_args | is_functor_like = rep_tc_args ++ [mkTyVarTy last_tv]
+ | otherwise = rep_tc_args
+
+
+ -- See Note [Superclasses of derived instance]
+ sc_constraints = substTheta (zipOpenTvSubst (classTyVars cls) inst_tys)
+ (classSCTheta cls)
+ inst_tys = [mkTyConApp tycon tc_args]
+ subst = zipTopTvSubst rep_tc_tvs all_rep_tc_args
+ stupid_constraints = substTheta subst (tyConStupidTheta rep_tc)
+
+ all_constraints = stupid_constraints ++ sc_constraints ++ ordinary_constraints
+
+ spec = DS { ds_loc = loc, ds_orig = orig
+ , ds_name = dfun_name, ds_tvs = tvs
+ , ds_cls = cls, ds_tys = inst_tys
+ , ds_tc = rep_tc, ds_tc_args = rep_tc_args
+ , ds_theta = mtheta `orElse` all_constraints
+ , ds_newtype = False }
+
+ ; ASSERT2( equalLength rep_tc_tvs all_rep_tc_args, ppr cls <+> ppr tycon )
+ 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
+ -- The Typeable class is special in several ways