+ constraints = extra_constraints ++
+ [ mkClassPred clas [arg_ty]
+ | data_con <- tyConDataCons tycon,
+ arg_ty <- dataConRepArgTys data_con, -- dataConOrigArgTys???
+ -- Use the same type variables
+ -- as the type constructor,
+ -- hence no need to instantiate
+ not (isUnLiftedType arg_ty) -- No constraints for unlifted types?
+ ]
+
+ -- "extra_constraints": see note [Data decl contexts] above
+ extra_constraints = tyConTheta tycon
+
+ mk_eqn_help NewType tycon clas tys
+ = doptM Opt_GlasgowExts `thenM` \ gla_exts ->
+ if can_derive_via_isomorphism && (gla_exts || standard_instance) then
+ -- Go ahead and use the isomorphism
+ traceTc (text "newtype deriving:" <+> ppr tycon <+> ppr rep_tys) `thenM_`
+ new_dfun_name clas tycon `thenM` \ dfun_name ->
+ returnM (Nothing, Just (InstInfo { iDFunId = mk_dfun dfun_name,
+ iBinds = NewTypeDerived rep_tys }))
+ else
+ if standard_instance then
+ mk_eqn_help DataType tycon clas [] -- Go via bale-out route
+ else
+ -- Non-standard instance
+ if gla_exts then
+ -- Too hard
+ bale_out cant_derive_err
+ else
+ -- Just complain about being a non-std instance
+ bale_out non_std_err
+ where
+ -- Here is the plan for newtype derivings. We see
+ -- newtype T a1...an = T (t ak...an) deriving (.., C s1 .. sm, ...)
+ -- where aj...an do not occur free in t, and the (C s1 ... sm) is a
+ -- *partial applications* of class C with the last parameter missing
+ --
+ -- We generate the instances
+ -- instance C s1 .. sm (t ak...aj) => C s1 .. sm (T a1...aj)
+ -- where T a1...aj is the partial application of the LHS of the correct kind
+ --
+ -- Running example: newtype T s a = MkT (ST s a) deriving( Monad )
+ -- instance Monad (ST s) => Monad (T s) where
+ -- fail = coerce ... (fail @ ST s)
+
+ clas_tyvars = classTyVars clas
+ kind = tyVarKind (last clas_tyvars)
+ -- Kind of the thing we want to instance
+ -- e.g. argument kind of Monad, *->*
+
+ (arg_kinds, _) = tcSplitFunTys kind
+ n_args_to_drop = length arg_kinds
+ -- Want to drop 1 arg from (T s a) and (ST s a)
+ -- to get instance Monad (ST s) => Monad (T s)
+
+ -- Note [newtype representation]
+ -- We must not use newTyConRep to get the representation
+ -- type, because that looks through all intermediate newtypes
+ -- To get the RHS of *this* newtype, just look at the data
+ -- constructor. For example
+ -- newtype B = MkB Int
+ -- newtype A = MkA B deriving( Num )
+ -- We want the Num instance of B, *not* the Num instance of Int,
+ -- when making the Num instance of A!
+ tyvars = tyConTyVars tycon
+ rep_ty = head (dataConOrigArgTys (head (tyConDataCons tycon)))
+ (rep_fn, rep_ty_args) = tcSplitAppTys rep_ty
+
+ n_tyvars_to_keep = tyConArity tycon - n_args_to_drop
+ tyvars_to_drop = drop n_tyvars_to_keep tyvars
+ tyvars_to_keep = take n_tyvars_to_keep tyvars
+
+ n_args_to_keep = length rep_ty_args - n_args_to_drop
+ args_to_drop = drop n_args_to_keep rep_ty_args
+ args_to_keep = take n_args_to_keep rep_ty_args
+
+ rep_tys = tys ++ [mkAppTys rep_fn args_to_keep]
+ rep_pred = mkClassPred clas rep_tys
+ -- rep_pred is the representation dictionary, from where
+ -- we are gong to get all the methods for the newtype dictionary
+
+ inst_tys = (tys ++ [mkTyConApp tycon (mkTyVarTys tyvars_to_keep)])
+ -- The 'tys' here come from the partial application
+ -- in the deriving clause. The last arg is the new
+ -- instance type.
+
+ -- We must pass the superclasses; the newtype might be an instance
+ -- of them in a different way than the representation type
+ -- E.g. newtype Foo a = Foo a deriving( Show, Num, Eq )
+ -- Then the Show instance is not done via isomprphism; it shows
+ -- Foo 3 as "Foo 3"
+ -- The Num instance is derived via isomorphism, but the Show superclass
+ -- dictionary must the Show instance for Foo, *not* the Show dictionary
+ -- gotten from the Num dictionary. So we must build a whole new dictionary
+ -- not just use the Num one. The instance we want is something like:
+ -- instance (Num a, Show (Foo a), Eq (Foo a)) => Num (Foo a) where
+ -- (+) = ((+)@a)
+ -- ...etc...
+ -- There's no 'corece' needed because after the type checker newtypes
+ -- are transparent.
+
+ sc_theta = substTheta (mkTyVarSubst clas_tyvars inst_tys)
+ (classSCTheta clas)
+
+ -- If there are no tyvars, there's no need
+ -- to abstract over the dictionaries we need
+ dict_args | null tyvars = []
+ | otherwise = rep_pred : sc_theta
+
+ -- Finally! Here's where we build the dictionary Id
+ mk_dfun dfun_name = mkDictFunId dfun_name tyvars dict_args clas inst_tys
+
+ -------------------------------------------------------------------
+ -- Figuring out whether we can only do this newtype-deriving thing
+
+ standard_instance = null tys && classKey clas `elem` derivableClassKeys
+
+ can_derive_via_isomorphism
+ = not (clas `hasKey` readClassKey) -- Never derive Read,Show this way
+ && not (clas `hasKey` showClassKey)
+ && length tys + 1 == classArity clas -- Well kinded;
+ -- eg not: newtype T ... deriving( ST )
+ -- because ST needs *2* type params
+ && n_tyvars_to_keep >= 0 -- Well kinded;
+ -- eg not: newtype T = T Int deriving( Monad )
+ && n_args_to_keep >= 0 -- Well kinded:
+ -- eg not: newtype T a = T Int deriving( Monad )
+ && eta_ok -- Eta reduction works
+ && not (isRecursiveTyCon tycon) -- Does not work for recursive tycons:
+ -- newtype A = MkA [A]
+ -- Don't want
+ -- instance Eq [A] => Eq A !!
+
+ -- Check that eta reduction is OK
+ -- (a) the dropped-off args are identical
+ -- (b) the remaining type args mention
+ -- only the remaining type variables
+ eta_ok = (args_to_drop `tcEqTypes` mkTyVarTys tyvars_to_drop)
+ && (tyVarsOfTypes args_to_keep `subVarSet` mkVarSet tyvars_to_keep)
+
+ cant_derive_err = derivingThingErr clas tys tycon tyvars_to_keep
+ (vcat [ptext SLIT("too hard for cunning newtype deriving"),
+ ptext SLIT("debug info:") <+> ppr n_tyvars_to_keep <+>
+ ppr n_args_to_keep <+> ppr eta_ok <+>
+ ppr (isRecursiveTyCon tycon)
+ ])
+
+ non_std_err = derivingThingErr clas tys tycon tyvars_to_keep
+ (vcat [non_std_why clas,
+ ptext SLIT("Try -fglasgow-exts for GHC's newtype-deriving extension")])
+
+ bale_out err = addErrTc err `thenM_` returnM (Nothing, Nothing)