%
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section[TcInstDecls]{Typechecking instance declarations}
\begin{code}
-#include "HsVersions.h"
-
-module TcInstDcls (
- tcInstDecls1,
- tcInstDecls2
- ) where
+module TcInstDcls ( tcInstDecls1, tcInstDecls2 ) where
+#include "HsVersions.h"
-IMP_Ubiq()
-
-import HsSyn ( HsDecl(..), InstDecl(..), TyDecl, ClassDecl, DefaultDecl,
- FixityDecl, IfaceSig, Sig(..),
- SpecInstSig(..), HsBinds(..),
- MonoBinds(..), GRHSsAndBinds(..), GRHS(..), Match,
- InPat(..), OutPat(..), HsExpr(..), HsLit(..),
- Stmt, DoOrListComp, ArithSeqInfo, Fake, Fixity,
- HsType(..), HsTyVar,
- SYN_IE(RecFlag), recursive, nonRecursive, collectMonoBinders,
- andMonoBinds
- )
-import RnHsSyn ( SYN_IE(RenamedHsBinds), SYN_IE(RenamedMonoBinds),
- SYN_IE(RenamedInstDecl), SYN_IE(RenamedFixityDecl), SYN_IE(RenamedHsExpr),
- SYN_IE(RenamedSig), SYN_IE(RenamedSpecInstSig), SYN_IE(RenamedHsDecl)
- )
-import TcHsSyn ( SYN_IE(TcHsBinds),
- SYN_IE(TcMonoBinds), SYN_IE(TcExpr), tcIdType,
- mkHsTyLam, mkHsTyApp,
- mkHsDictLam, mkHsDictApp )
-
-import TcBinds ( tcPragmaSigs )
-import TcClassDcl ( tcMethodBind )
-import TcMonad
-import RnMonad ( SYN_IE(RnNameSupply) )
-import Inst ( Inst, InstOrigin(..), SYN_IE(InstanceMapper),
- instToId, newDicts, newMethod, SYN_IE(LIE), emptyLIE, plusLIE )
-import PragmaInfo ( PragmaInfo(..) )
+import HsSyn
+import TcBinds ( mkPragFun, tcPrags, badBootDeclErr )
+import TcClassDcl ( tcMethodBind, mkMethodBind, badMethodErr,
+ tcClassDecl2, getGenericInstances )
+import TcRnMonad
+import TcMType ( tcSkolSigType, checkValidTheta, checkValidInstHead,
+ checkInstTermination, instTypeErr,
+ checkAmbiguity, SourceTyCtxt(..) )
+import TcType ( mkClassPred, tyVarsOfType,
+ tcSplitSigmaTy, tcSplitDFunHead, mkTyVarTys,
+ SkolemInfo(InstSkol), tcSplitDFunTy, pprClassPred )
+import Inst ( tcInstClassOp, newDicts, instToId, showLIE,
+ getOverlapFlag, tcExtendLocalInstEnv )
+import InstEnv ( mkLocalInstance, instanceDFunId )
import TcDeriv ( tcDeriving )
-import TcEnv ( tcLookupClass, newLocalId, tcExtendGlobalTyVars, tcGetGlobalTyVars,
- tcExtendGlobalValEnv, tcAddImportedIdInfo
- )
-import SpecEnv ( SpecEnv )
-import TcGRHSs ( tcGRHSsAndBinds )
-import TcInstUtil ( InstInfo(..), mkInstanceRelatedIds, buildInstanceEnvs )
-import TcKind ( TcKind, unifyKind )
-import TcMatches ( tcMatchesFun )
-import TcMonoType ( tcTyVarScope, tcContext, tcHsTypeKind )
-import TcSimplify ( tcSimplifyAndCheck )
-import TcType ( TcIdOcc(..), SYN_IE(TcIdBndr), SYN_IE(TcType), SYN_IE(TcTyVar), SYN_IE(TcTyVarSet),
- tcInstSigTyVars, tcInstType, tcInstSigTcType,
- tcInstTheta, tcInstTcType, tcInstSigType
+import TcEnv ( InstInfo(..), InstBindings(..),
+ newDFunName, tcExtendIdEnv
)
-import Unify ( unifyTauTy, unifyTauTyLists )
-
-
-import Bag ( emptyBag, unitBag, unionBags, unionManyBags,
- concatBag, foldBag, bagToList, listToBag,
- Bag )
-import CmdLineOpts ( opt_GlasgowExts,
- opt_PprUserLength, opt_SpecialiseOverloaded,
- opt_WarnMissingMethods
- )
-import Class ( GenClass,
- classBigSig,
- classDefaultMethodId, SYN_IE(Class)
- )
-import Id ( GenId, idType, replacePragmaInfo,
- isNullaryDataCon, dataConArgTys, SYN_IE(Id) )
+import TcHsType ( kcHsSigType, tcHsKindedType )
+import TcUnify ( checkSigTyVars )
+import TcSimplify ( tcSimplifyCheck, tcSimplifySuperClasses )
+import Type ( zipOpenTvSubst, substTheta, substTys )
+import DataCon ( classDataCon )
+import Class ( classBigSig )
+import Var ( Id, idName, idType )
+import MkId ( mkDictFunId, rUNTIME_ERROR_ID )
+import FunDeps ( checkInstFDs )
+import Name ( Name, getSrcLoc )
+import Maybe ( catMaybes )
+import SrcLoc ( srcLocSpan, unLoc, noLoc, Located(..), srcSpanStart )
import ListSetOps ( minusList )
-import Maybes ( maybeToBool, expectJust, seqMaybe, catMaybes )
-import Name ( nameOccName, getSrcLoc, mkLocalName,
- isLocallyDefined, OccName, Name{--O only-}, SYN_IE(Module),
- NamedThing(..)
- )
-import PrelVals ( nO_EXPLICIT_METHOD_ERROR_ID, nO_DEFAULT_METHOD_ERROR_ID )
-import PprType ( GenType, GenTyVar, GenClass, TyCon,
- pprParendGenType
- )
import Outputable
-import SrcLoc ( SrcLoc, noSrcLoc )
-import Pretty
-import TyCon ( isSynTyCon, isDataTyCon, derivedClasses )
-import Type ( GenType(..), SYN_IE(ThetaType), mkTyVarTys, isPrimType,
- splitSigmaTy, splitAppTys, isTyVarTy, matchTy, mkSigmaTy,
- getTyCon_maybe, maybeAppTyCon, SYN_IE(Type), getTyVar,
- maybeBoxedPrimType, maybeAppDataTyCon, splitRhoTy, eqTy
- )
-import TyVar ( GenTyVar, SYN_IE(GenTyVarSet), tyVarSetToList,
- mkTyVarSet, unionTyVarSets, SYN_IE(TyVar) )
-import TysPrim ( byteArrayPrimTyCon, mutableByteArrayPrimTyCon )
-import TysWiredIn ( stringTy )
-import Unique ( Unique, cCallableClassKey, cReturnableClassKey, Uniquable(..) )
-import Util ( zipEqual, panic, pprPanic, pprTrace, removeDups, Ord3(..)
-#if __GLASGOW_HASKELL__ < 202
- , trace
-#endif
- )
+import Bag
+import BasicTypes ( Activation( AlwaysActive ), InlineSpec(..) )
+import FastString
\end{code}
Typechecking instance declarations is done in two passes. The first
and $dbinds_super$ bind the superclass dictionaries sd1 \ldots sdm.
\end{enumerate}
+
+%************************************************************************
+%* *
+\subsection{Extracting instance decls}
+%* *
+%************************************************************************
+
+Gather up the instance declarations from their various sources
+
\begin{code}
-tcInstDecls1 :: TcEnv s -- Contains IdInfo for dfun ids
- -> [RenamedHsDecl]
- -> Module -- module name for deriving
- -> RnNameSupply -- for renaming derivings
- -> TcM s (Bag InstInfo,
- RenamedHsBinds,
- PprStyle -> Doc)
-
-tcInstDecls1 unf_env decls mod_name rn_name_supply
- = -- Do the ordinary instance declarations
- mapNF_Tc (tcInstDecl1 unf_env mod_name)
- [inst_decl | InstD inst_decl <- decls] `thenNF_Tc` \ inst_info_bags ->
+tcInstDecls1 -- Deal with both source-code and imported instance decls
+ :: [LTyClDecl Name] -- For deriving stuff
+ -> [LInstDecl Name] -- Source code instance decls
+ -> TcM (TcGblEnv, -- The full inst env
+ [InstInfo], -- Source-code instance decls to process;
+ -- contains all dfuns for this module
+ HsValBinds Name) -- Supporting bindings for derived instances
+
+tcInstDecls1 tycl_decls inst_decls
+ = checkNoErrs $
+ -- Stop if addInstInfos etc discovers any errors
+ -- (they recover, so that we get more than one error each round)
+
+ -- (1) Do the ordinary instance declarations
+ mappM tcLocalInstDecl1 inst_decls `thenM` \ local_inst_infos ->
+
let
- decl_inst_info = unionManyBags inst_info_bags
+ local_inst_info = catMaybes local_inst_infos
+ clas_decls = filter (isClassDecl.unLoc) tycl_decls
in
- -- Handle "derived" instances; note that we only do derivings
- -- for things in this module; we ignore deriving decls from
- -- interfaces!
- tcDeriving mod_name rn_name_supply decl_inst_info
- `thenTc` \ (deriv_inst_info, deriv_binds, ddump_deriv) ->
+ -- (2) Instances from generic class declarations
+ getGenericInstances clas_decls `thenM` \ generic_inst_info ->
+
+ -- Next, construct the instance environment so far, consisting of
+ -- a) local instance decls
+ -- b) generic instances
+ addInsts local_inst_info $
+ addInsts generic_inst_info $
+
+ -- (3) Compute instances from "deriving" clauses;
+ -- This stuff computes a context for the derived instance decl, so it
+ -- needs to know about all the instances possible; hence inst_env4
+ tcDeriving tycl_decls `thenM` \ (deriv_inst_info, deriv_binds) ->
+ addInsts deriv_inst_info $
+
+ getGblEnv `thenM` \ gbl_env ->
+ returnM (gbl_env,
+ generic_inst_info ++ deriv_inst_info ++ local_inst_info,
+ deriv_binds)
+
+addInsts :: [InstInfo] -> TcM a -> TcM a
+addInsts infos thing_inside
+ = tcExtendLocalInstEnv (map iSpec infos) thing_inside
+\end{code}
+\begin{code}
+tcLocalInstDecl1 :: LInstDecl Name
+ -> TcM (Maybe InstInfo) -- Nothing if there was an error
+ -- A source-file instance declaration
+ -- Type-check all the stuff before the "where"
+ --
+ -- We check for respectable instance type, and context
+tcLocalInstDecl1 decl@(L loc (InstDecl poly_ty binds uprags))
+ = -- Prime error recovery, set source location
+ recoverM (returnM Nothing) $
+ setSrcSpan loc $
+ addErrCtxt (instDeclCtxt1 poly_ty) $
+
+ -- Typecheck the instance type itself. We can't use
+ -- tcHsSigType, because it's not a valid user type.
+ kcHsSigType poly_ty `thenM` \ kinded_ty ->
+ tcHsKindedType kinded_ty `thenM` \ poly_ty' ->
let
- full_inst_info = deriv_inst_info `unionBags` decl_inst_info
+ (tyvars, theta, tau) = tcSplitSigmaTy poly_ty'
+ in
+ checkValidTheta InstThetaCtxt theta `thenM_`
+ checkAmbiguity tyvars theta (tyVarsOfType tau) `thenM_`
+ checkValidInstHead tau `thenM` \ (clas,inst_tys) ->
+ checkInstTermination theta inst_tys `thenM_`
+ checkTc (checkInstFDs theta clas inst_tys)
+ (instTypeErr (pprClassPred clas inst_tys) msg) `thenM_`
+ newDFunName clas inst_tys (srcSpanStart loc) `thenM` \ dfun_name ->
+ getOverlapFlag `thenM` \ overlap_flag ->
+ let dfun = mkDictFunId dfun_name tyvars theta clas inst_tys
+ ispec = mkLocalInstance dfun overlap_flag
in
- returnTc (full_inst_info, deriv_binds, ddump_deriv)
-
-
-tcInstDecl1 :: TcEnv s -> Module -> RenamedInstDecl -> NF_TcM s (Bag InstInfo)
-
-tcInstDecl1 unf_env mod_name (InstDecl poly_ty binds uprags (Just dfun_name) src_loc)
- = -- Prime error recovery, set source location
- recoverNF_Tc (returnNF_Tc emptyBag) $
- tcAddSrcLoc src_loc $
-
- -- Look things up
- tcLookupClass class_name `thenTc` \ (clas_kind, clas) ->
-
- -- Typecheck the context and instance type
- tcTyVarScope tyvar_names (\ tyvars ->
- tcContext context `thenTc` \ theta ->
- tcHsTypeKind inst_ty `thenTc` \ (tau_kind, tau) ->
- unifyKind clas_kind tau_kind `thenTc_`
- returnTc (tyvars, theta, tau)
- ) `thenTc` \ (inst_tyvars, inst_theta, inst_tau) ->
- -- Check for respectable instance type
- scrutiniseInstanceType dfun_name clas inst_tau
- `thenTc` \ (inst_tycon,arg_tys) ->
+ tcIsHsBoot `thenM` \ is_boot ->
+ checkTc (not is_boot || (isEmptyLHsBinds binds && null uprags))
+ badBootDeclErr `thenM_`
- -- Make the dfun id and constant-method ids
- let
- (dfun_id, dfun_theta) = mkInstanceRelatedIds dfun_name
- clas inst_tyvars inst_tau inst_theta
- -- Add info from interface file
- final_dfun_id = tcAddImportedIdInfo unf_env dfun_id
- in
- returnTc (unitBag (InstInfo clas inst_tyvars inst_tau inst_theta
- dfun_theta final_dfun_id
- binds src_loc uprags))
+ returnM (Just (InstInfo { iSpec = ispec, iBinds = VanillaInst binds uprags }))
where
- (tyvar_names, context, dict_ty) = case poly_ty of
- HsForAllTy tvs cxt dict_ty -> (tvs, cxt, dict_ty)
- other -> ([], [], poly_ty)
- (class_name, inst_ty) = case dict_ty of
- MonoDictTy cls ty -> (cls,ty)
- other -> pprPanic "Malformed instance decl" (ppr PprDebug poly_ty)
+ msg = parens (ptext SLIT("the instance types do not agree with the functional dependencies of the class"))
\end{code}
%************************************************************************
\begin{code}
-tcInstDecls2 :: Bag InstInfo
- -> NF_TcM s (LIE s, TcMonoBinds s)
-
-tcInstDecls2 inst_decls
- = foldBag combine tcInstDecl2 (returnNF_Tc (emptyLIE, EmptyMonoBinds)) inst_decls
- where
- combine tc1 tc2 = tc1 `thenNF_Tc` \ (lie1, binds1) ->
- tc2 `thenNF_Tc` \ (lie2, binds2) ->
- returnNF_Tc (lie1 `plusLIE` lie2,
- binds1 `AndMonoBinds` binds2)
+tcInstDecls2 :: [LTyClDecl Name] -> [InstInfo]
+ -> TcM (LHsBinds Id, TcLclEnv)
+-- (a) From each class declaration,
+-- generate any default-method bindings
+-- (b) From each instance decl
+-- generate the dfun binding
+
+tcInstDecls2 tycl_decls inst_decls
+ = do { -- (a) Default methods from class decls
+ (dm_binds_s, dm_ids_s) <- mapAndUnzipM tcClassDecl2 $
+ filter (isClassDecl.unLoc) tycl_decls
+ ; tcExtendIdEnv (concat dm_ids_s) $ do
+
+ -- (b) instance declarations
+ ; inst_binds_s <- mappM tcInstDecl2 inst_decls
+
+ -- Done
+ ; let binds = unionManyBags dm_binds_s `unionBags`
+ unionManyBags inst_binds_s
+ ; tcl_env <- getLclEnv -- Default method Ids in here
+ ; returnM (binds, tcl_env) }
\end{code}
-
======= New documentation starts here (Sept 92) ==============
The main purpose of @tcInstDecl2@ is to return a @HsBinds@ which defines
First comes the easy case of a non-local instance decl.
+
\begin{code}
-tcInstDecl2 :: InstInfo -> NF_TcM s (LIE s, TcMonoBinds s)
-
-tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
- inst_decl_theta dfun_theta
- dfun_id monobinds
- locn uprags)
- | not (isLocallyDefined dfun_id)
- = returnNF_Tc (emptyLIE, EmptyMonoBinds)
-
-{-
- -- I deleted this "optimisation" because when importing these
- -- instance decls the renamer would look for the dfun bindings and they weren't there.
- -- This would be fixable, but it seems simpler just to produce a tiny void binding instead,
- -- even though it's never used.
-
- -- This case deals with CCallable etc, which don't need any bindings
- | isNoDictClass clas
- = returnNF_Tc (emptyLIE, EmptyBinds)
--}
-
- | otherwise
- = -- Prime error recovery
- recoverNF_Tc (returnNF_Tc (emptyLIE, EmptyMonoBinds)) $
- tcAddSrcLoc locn $
-
- -- Get the class signature
- tcInstSigTyVars inst_tyvars `thenNF_Tc` \ (inst_tyvars', _, tenv) ->
- let
- origin = InstanceDeclOrigin
- (class_tyvar,
- super_classes, sc_sel_ids,
- op_sel_ids, defm_ids) = classBigSig clas
+tcInstDecl2 :: InstInfo -> TcM (LHsBinds Id)
+
+tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = binds })
+ = let
+ dfun_id = instanceDFunId ispec
+ rigid_info = InstSkol dfun_id
+ inst_ty = idType dfun_id
in
- tcInstType tenv inst_ty `thenNF_Tc` \ inst_ty' ->
- tcInstTheta tenv dfun_theta `thenNF_Tc` \ dfun_theta' ->
- tcInstTheta tenv inst_decl_theta `thenNF_Tc` \ inst_decl_theta' ->
+ -- Prime error recovery
+ recoverM (returnM emptyLHsBinds) $
+ setSrcSpan (srcLocSpan (getSrcLoc dfun_id)) $
+ addErrCtxt (instDeclCtxt2 (idType dfun_id)) $
+
+ -- Instantiate the instance decl with skolem constants
+ tcSkolSigType rigid_info inst_ty `thenM` \ (inst_tyvars', dfun_theta', inst_head') ->
+ -- These inst_tyvars' scope over the 'where' part
+ -- Those tyvars are inside the dfun_id's type, which is a bit
+ -- bizarre, but OK so long as you realise it!
let
- sc_theta' = super_classes `zip` repeat inst_ty'
+ (clas, inst_tys') = tcSplitDFunHead inst_head'
+ (class_tyvars, sc_theta, _, op_items) = classBigSig clas
+
+ -- Instantiate the super-class context with inst_tys
+ sc_theta' = substTheta (zipOpenTvSubst class_tyvars inst_tys') sc_theta
+ origin = SigOrigin rigid_info
in
-- Create dictionary Ids from the specified instance contexts.
- newDicts origin sc_theta' `thenNF_Tc` \ (sc_dicts, sc_dict_ids) ->
- newDicts origin dfun_theta' `thenNF_Tc` \ (dfun_arg_dicts, dfun_arg_dicts_ids) ->
- newDicts origin inst_decl_theta' `thenNF_Tc` \ (inst_decl_dicts, _) ->
- newDicts origin [(clas,inst_ty')] `thenNF_Tc` \ (this_dict, [this_dict_id]) ->
-
- -- Now process any INLINE or SPECIALIZE pragmas for the methods
- -- ...[NB May 97; all ignored except INLINE]
- tcPragmaSigs uprags `thenTc` \ (prag_fn, spec_binds, spec_lie) ->
-
- -- Check the method bindings
- let
- inst_tyvars_set' = mkTyVarSet inst_tyvars'
- check_from_this_class (bndr, loc)
- | nameOccName bndr `elem` sel_names = returnTc ()
- | otherwise = recoverTc (returnTc ()) $
- tcAddSrcLoc loc $
- failTc (instBndrErr bndr clas)
- sel_names = map getOccName op_sel_ids
+ newDicts InstScOrigin sc_theta' `thenM` \ sc_dicts ->
+ newDicts origin dfun_theta' `thenM` \ dfun_arg_dicts ->
+ newDicts origin [mkClassPred clas inst_tys'] `thenM` \ [this_dict] ->
+ -- Default-method Ids may be mentioned in synthesised RHSs,
+ -- but they'll already be in the environment.
+
+ -- Typecheck the methods
+ let -- These insts are in scope; quite a few, eh?
+ avail_insts = [this_dict] ++ dfun_arg_dicts ++ sc_dicts
in
- mapTc check_from_this_class (bagToList (collectMonoBinders monobinds)) `thenTc_`
- tcExtendGlobalTyVars inst_tyvars_set' (
- tcExtendGlobalValEnv (catMaybes defm_ids) $
- -- Default-method Ids may be mentioned in synthesised RHSs
- mapAndUnzip3Tc (tcInstMethodBind clas inst_ty' monobinds)
- (op_sel_ids `zip` defm_ids)
- ) `thenTc` \ (method_binds_s, insts_needed_s, meth_lies_w_ids) ->
-
- -- Check the overloading constraints of the methods and superclasses
+ tcMethods origin clas inst_tyvars'
+ dfun_theta' inst_tys' avail_insts
+ op_items binds `thenM` \ (meth_ids, meth_binds) ->
+
+ -- Figure out bindings for the superclass context
+ -- Don't include this_dict in the 'givens', else
+ -- sc_dicts get bound by just selecting from this_dict!!
+ addErrCtxt superClassCtxt
+ (tcSimplifySuperClasses inst_tyvars'
+ dfun_arg_dicts
+ sc_dicts) `thenM` \ sc_binds ->
+
+ -- It's possible that the superclass stuff might unified one
+ -- of the inst_tyavars' with something in the envt
+ checkSigTyVars inst_tyvars' `thenM_`
+
+ -- Deal with 'SPECIALISE instance' pragmas
let
- (meth_lies, meth_ids) = unzip meth_lies_w_ids
- avail_insts -- These insts are in scope; quite a few, eh?
- = this_dict `plusLIE` dfun_arg_dicts `plusLIE` unionManyBags meth_lies
+ specs = case binds of
+ VanillaInst _ prags -> filter isSpecInstLSig prags
+ other -> []
in
- tcAddErrCtxt bindSigCtxt (
- tcSimplifyAndCheck
- inst_tyvars_set' -- Local tyvars
- avail_insts
- (sc_dicts `unionBags`
- unionManyBags insts_needed_s) -- Need to get defns for all these
- ) `thenTc` \ (const_lie, super_binds) ->
-
- -- Check that we *could* construct the superclass dictionaries,
- -- even though we are *actually* going to pass the superclass dicts in;
- -- the check ensures that the caller will never have a problem building
- -- them.
- tcAddErrCtxt superClassSigCtxt (
- tcSimplifyAndCheck
- inst_tyvars_set' -- Local tyvars
- inst_decl_dicts -- The instance dictionaries available
- sc_dicts -- The superclass dicationaries reqd
- ) `thenTc_`
- -- Ignore the result; we're only doing
- -- this to make sure it can be done.
-
+ tcPrags dfun_id specs `thenM` \ prags ->
+
-- Create the result bindings
let
- dict_bind = VarMonoBind this_dict_id (Dictionary sc_dict_ids meth_ids)
- method_binds = andMonoBinds method_binds_s
-
- main_bind
- = AbsBinds
- inst_tyvars'
- dfun_arg_dicts_ids
- [(inst_tyvars', RealId dfun_id, this_dict_id)]
- (super_binds `AndMonoBinds`
- method_binds `AndMonoBinds`
- dict_bind)
+ dict_constr = classDataCon clas
+ scs_and_meths = map instToId sc_dicts ++ meth_ids
+ this_dict_id = instToId this_dict
+ inline_prag | null dfun_arg_dicts = []
+ | otherwise = [InlinePrag (Inline AlwaysActive True)]
+ -- Always inline the dfun; this is an experimental decision
+ -- because it makes a big performance difference sometimes.
+ -- Often it means we can do the method selection, and then
+ -- inline the method as well. Marcin's idea; see comments below.
+ --
+ -- BUT: don't inline it if it's a constant dictionary;
+ -- we'll get all the benefit without inlining, and we get
+ -- a **lot** of code duplication if we inline it
+ --
+ -- See Note [Inline dfuns] below
+
+ dict_rhs
+ = mkHsConApp dict_constr inst_tys' (map HsVar scs_and_meths)
+ -- We don't produce a binding for the dict_constr; instead we
+ -- rely on the simplifier to unfold this saturated application
+ -- We do this rather than generate an HsCon directly, because
+ -- it means that the special cases (e.g. dictionary with only one
+ -- member) are dealt with by the common MkId.mkDataConWrapId code rather
+ -- than needing to be repeated here.
+
+ where
+ msg = "Compiler error: bad dictionary " ++ showSDoc (ppr clas)
+
+ dict_bind = noLoc (VarBind this_dict_id dict_rhs)
+ all_binds = dict_bind `consBag` (sc_binds `unionBags` meth_binds)
+
+ main_bind = noLoc $ AbsBinds
+ inst_tyvars'
+ (map instToId dfun_arg_dicts)
+ [(inst_tyvars', dfun_id, this_dict_id,
+ inline_prag ++ prags)]
+ all_binds
in
- returnTc (const_lie `plusLIE` spec_lie,
- main_bind `AndMonoBinds` spec_binds)
-\end{code}
+ showLIE (text "instance") `thenM_`
+ returnM (unitBag main_bind)
-%************************************************************************
-%* *
-\subsection{Processing each method}
-%* *
-%************************************************************************
-
-\begin{code}
-tcInstMethodBind
- :: Class
- -> TcType s -- Instance type
- -> RenamedMonoBinds -- Method binding
- -> (Id, Maybe Id) -- Selector id and default-method id
- -> TcM s (TcMonoBinds s, LIE s, (LIE s, TcIdOcc s))
-
-tcInstMethodBind clas inst_ty meth_binds (sel_id, maybe_dm_id)
- = tcGetSrcLoc `thenNF_Tc` \ loc ->
- tcGetUnique `thenNF_Tc` \ uniq ->
+tcMethods origin clas inst_tyvars' dfun_theta' inst_tys'
+ avail_insts op_items (VanillaInst monobinds uprags)
+ = -- Check that all the method bindings come from this class
let
- meth_occ = getOccName sel_id
- default_meth_name = mkLocalName uniq meth_occ loc
- maybe_meth_bind = find meth_occ meth_binds
- the_meth_bind = case maybe_meth_bind of
- Just stuff -> stuff
- Nothing -> mk_default_bind default_meth_name
+ sel_names = [idName sel_id | (sel_id, _) <- op_items]
+ bad_bndrs = collectHsBindBinders monobinds `minusList` sel_names
in
+ mappM (addErrTc . badMethodErr clas) bad_bndrs `thenM_`
- -- Warn if no method binding, only if -fwarn-missing-methods
-
- warnTc (opt_WarnMissingMethods &&
- not (maybeToBool maybe_meth_bind) &&
- not (maybeToBool maybe_dm_id))
- (omittedMethodWarn sel_id clas) `thenNF_Tc_`
-
- -- Typecheck the method binding
- tcMethodBind clas origin inst_ty sel_id the_meth_bind
- where
- origin = InstanceDeclOrigin -- Poor
-
- find occ EmptyMonoBinds = Nothing
- find occ (AndMonoBinds b1 b2) = find occ b1 `seqMaybe` find occ b2
-
- find occ b@(FunMonoBind op_name _ _ _) | nameOccName op_name == occ = Just b
- | otherwise = Nothing
- find occ b@(PatMonoBind (VarPatIn op_name) _ _) | nameOccName op_name == occ = Just b
- | otherwise = Nothing
- find occ other = panic "Urk! Bad instance method binding"
-
-
- mk_default_bind local_meth_name
- = PatMonoBind (VarPatIn local_meth_name)
- (GRHSsAndBindsIn [OtherwiseGRHS default_expr noSrcLoc] EmptyBinds)
- noSrcLoc
-
- default_expr = case maybe_dm_id of
- Just dm_id -> HsVar (getName dm_id) -- There's a default method
- Nothing -> error_expr -- No default method
-
- error_expr = HsApp (HsVar (getName nO_DEFAULT_METHOD_ERROR_ID))
- (HsLit (HsString (_PK_ error_msg)))
-
- error_msg = show (hcat [ppr (PprForUser opt_PprUserLength) (getSrcLoc sel_id), text "|",
- ppr (PprForUser opt_PprUserLength) sel_id
- ])
-\end{code}
-
-
-
-%************************************************************************
-%* *
-\subsection{Type-checking specialise instance pragmas}
-%* *
-%************************************************************************
-
-\begin{code}
-{- LATER
-tcSpecInstSigs :: E -> CE -> TCE
- -> Bag InstInfo -- inst decls seen (declared and derived)
- -> [RenamedSpecInstSig] -- specialise instance upragmas
- -> TcM (Bag InstInfo) -- new, overlapped, inst decls
-
-tcSpecInstSigs e ce tce inst_infos []
- = returnTc emptyBag
-
-tcSpecInstSigs e ce tce inst_infos sigs
- = buildInstanceEnvs inst_infos `thenTc` \ inst_mapper ->
- tc_inst_spec_sigs inst_mapper sigs `thenNF_Tc` \ spec_inst_infos ->
- returnTc spec_inst_infos
- where
- tc_inst_spec_sigs inst_mapper []
- = returnNF_Tc emptyBag
- tc_inst_spec_sigs inst_mapper (sig:sigs)
- = tcSpecInstSig e ce tce inst_infos inst_mapper sig `thenNF_Tc` \ info_sig ->
- tc_inst_spec_sigs inst_mapper sigs `thenNF_Tc` \ info_sigs ->
- returnNF_Tc (info_sig `unionBags` info_sigs)
-
-tcSpecInstSig :: E -> CE -> TCE
- -> Bag InstInfo
- -> InstanceMapper
- -> RenamedSpecInstSig
- -> NF_TcM (Bag InstInfo)
-
-tcSpecInstSig e ce tce inst_infos inst_mapper (SpecInstSig class_name ty src_loc)
- = recoverTc emptyBag (
- tcAddSrcLoc src_loc (
+ -- Make the method bindings
let
- clas = lookupCE ce class_name -- Renamer ensures this can't fail
-
- -- Make some new type variables, named as in the specialised instance type
- ty_names = extractHsTyNames ???is_tyvarish_name??? ty
- (tmpl_e,inst_tmpls,inst_tmpl_tys) = mkTVE ty_names
+ mk_method_bind = mkMethodBind origin clas inst_tys' monobinds
in
- babyTcMtoTcM (tcInstanceType ce tce tmpl_e True src_loc ty)
- `thenTc` \ inst_ty ->
+ mapAndUnzipM mk_method_bind op_items `thenM` \ (meth_insts, meth_infos) ->
+
+ -- And type check them
+ -- It's really worth making meth_insts available to the tcMethodBind
+ -- Consider instance Monad (ST s) where
+ -- {-# INLINE (>>) #-}
+ -- (>>) = ...(>>=)...
+ -- If we don't include meth_insts, we end up with bindings like this:
+ -- rec { dict = MkD then bind ...
+ -- then = inline_me (... (GHC.Base.>>= dict) ...)
+ -- bind = ... }
+ -- The trouble is that (a) 'then' and 'dict' are mutually recursive,
+ -- and (b) the inline_me prevents us inlining the >>= selector, which
+ -- would unravel the loop. Result: (>>) ends up as a loop breaker, and
+ -- is not inlined across modules. Rather ironic since this does not
+ -- happen without the INLINE pragma!
+ --
+ -- Solution: make meth_insts available, so that 'then' refers directly
+ -- to the local 'bind' rather than going via the dictionary.
+ --
+ -- BUT WATCH OUT! If the method type mentions the class variable, then
+ -- this optimisation is not right. Consider
+ -- class C a where
+ -- op :: Eq a => a
+ --
+ -- instance C Int where
+ -- op = op
+ -- The occurrence of 'op' on the rhs gives rise to a constraint
+ -- op at Int
+ -- The trouble is that the 'meth_inst' for op, which is 'available', also
+ -- looks like 'op at Int'. But they are not the same.
let
- maybe_tycon = case maybeAppDataTyCon inst_ty of
- Just (tc,_,_) -> Just tc
- Nothing -> Nothing
-
- maybe_unspec_inst = lookup_unspec_inst clas maybe_tycon inst_infos
- in
- -- Check that we have a local instance declaration to specialise
- checkMaybeTc maybe_unspec_inst
- (specInstUnspecInstNotFoundErr clas inst_ty src_loc) `thenTc_`
-
- -- Create tvs to substitute for tmpls while simplifying the context
- copyTyVars inst_tmpls `thenNF_Tc` \ (tv_e, inst_tvs, inst_tv_tys) ->
- let
- Just (InstInfo _ unspec_tyvars unspec_inst_ty unspec_theta
- _ _ binds _ uprag) = maybe_unspec_inst
-
- subst = case matchTy unspec_inst_ty inst_ty of
- Just subst -> subst
- Nothing -> panic "tcSpecInstSig:matchTy"
-
- subst_theta = instantiateThetaTy subst unspec_theta
- subst_tv_theta = instantiateThetaTy tv_e subst_theta
-
- mk_spec_origin clas ty
- = InstanceSpecOrigin inst_mapper clas ty src_loc
- -- I'm VERY SUSPICIOUS ABOUT THIS
- -- the inst-mapper is in a knot at this point so it's no good
- -- looking at it in tcSimplify...
+ prag_fn = mkPragFun uprags
+ all_insts = avail_insts ++ catMaybes meth_insts
+ tc_method_bind = tcMethodBind inst_tyvars' dfun_theta' all_insts prag_fn
+ meth_ids = [meth_id | (_,meth_id,_) <- meth_infos]
in
- tcSimplifyThetas mk_spec_origin subst_tv_theta
- `thenTc` \ simpl_tv_theta ->
- let
- simpl_theta = [ (clas, tv_to_tmpl tv) | (clas, tv) <- simpl_tv_theta ]
- tv_tmpl_map = zipEqual "tcSpecInstSig" inst_tv_tys inst_tmpl_tys
- tv_to_tmpl tv = assoc "tcSpecInstSig" tv_tmpl_map tv
- in
- mkInstanceRelatedIds
- clas inst_tmpls inst_ty simpl_theta uprag
- `thenNF_Tc` \ (dfun_id, dfun_theta, const_meth_ids) ->
-
- getSwitchCheckerTc `thenNF_Tc` \ sw_chkr ->
- (if sw_chkr SpecialiseTrace then
- pprTrace "Specialised Instance: "
- (vcat [hsep [if null simpl_theta then empty else ppr PprDebug simpl_theta,
- if null simpl_theta then empty else ptext SLIT("=>"),
- ppr PprDebug clas,
- pprParendGenType PprDebug inst_ty],
- hsep [ptext SLIT(" derived from:"),
- if null unspec_theta then empty else ppr PprDebug unspec_theta,
- if null unspec_theta then empty else ptext SLIT("=>"),
- ppr PprDebug clas,
- pprParendGenType PprDebug unspec_inst_ty]])
- else id) (
-
- returnTc (unitBag (InstInfo clas inst_tmpls inst_ty simpl_theta
- dfun_theta dfun_id
- binds src_loc uprag))
- )))
-
-
-lookup_unspec_inst clas maybe_tycon inst_infos
- = case filter (match_info match_inst_ty) (bagToList inst_infos) of
- [] -> Nothing
- (info:_) -> Just info
- where
- match_info match_ty (InstInfo inst_clas _ inst_ty _ _ _ _ _ from_here _ _ _)
- = from_here && clas == inst_clas &&
- match_ty inst_ty && is_plain_instance inst_ty
+ mapM tc_method_bind meth_infos `thenM` \ meth_binds_s ->
+
+ returnM (meth_ids, unionManyBags meth_binds_s)
- match_inst_ty = case maybe_tycon of
- Just tycon -> match_tycon tycon
- Nothing -> match_fun
- match_tycon tycon inst_ty = case (maybeAppDataTyCon inst_ty) of
- Just (inst_tc,_,_) -> tycon == inst_tc
- Nothing -> False
+-- Derived newtype instances
+tcMethods origin clas inst_tyvars' dfun_theta' inst_tys'
+ avail_insts op_items (NewTypeDerived rep_tys)
+ = getInstLoc origin `thenM` \ inst_loc ->
+ mapAndUnzip3M (do_one inst_loc) op_items `thenM` \ (meth_ids, meth_binds, rhs_insts) ->
+
+ tcSimplifyCheck
+ (ptext SLIT("newtype derived instance"))
+ inst_tyvars' avail_insts rhs_insts `thenM` \ lie_binds ->
- match_fun inst_ty = isFunType inst_ty
+ -- I don't think we have to do the checkSigTyVars thing
+ returnM (meth_ids, lie_binds `unionBags` listToBag meth_binds)
-is_plain_instance inst_ty
- = case (maybeAppDataTyCon inst_ty) of
- Just (_,tys,_) -> all isTyVarTemplateTy tys
- Nothing -> case maybeUnpackFunTy inst_ty of
- Just (arg, res) -> isTyVarTemplateTy arg && isTyVarTemplateTy res
- Nothing -> error "TcInstDecls:is_plain_instance"
--}
+ where
+ do_one inst_loc (sel_id, _)
+ = -- The binding is like "op @ NewTy = op @ RepTy"
+ -- Make the *binder*, like in mkMethodBind
+ tcInstClassOp inst_loc sel_id inst_tys' `thenM` \ meth_inst ->
+
+ -- Make the *occurrence on the rhs*
+ tcInstClassOp inst_loc sel_id rep_tys' `thenM` \ rhs_inst ->
+ let
+ meth_id = instToId meth_inst
+ in
+ return (meth_id, noLoc (VarBind meth_id (nlHsVar (instToId rhs_inst))), rhs_inst)
+
+ -- Instantiate rep_tys with the relevant type variables
+ -- This looks a bit odd, because inst_tyvars' are the skolemised version
+ -- of the type variables in the instance declaration; but rep_tys doesn't
+ -- have the skolemised version, so we substitute them in here
+ rep_tys' = substTys subst rep_tys
+ subst = zipOpenTvSubst inst_tyvars' (mkTyVarTys inst_tyvars')
\end{code}
-Checking for a decent instance type
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-@scrutiniseInstanceType@ checks the type {\em and} its syntactic constraints:
-it must normally look like: @instance Foo (Tycon a b c ...) ...@
-
-The exceptions to this syntactic checking: (1)~if the @GlasgowExts@
-flag is on, or (2)~the instance is imported (they must have been
-compiled elsewhere). In these cases, we let them go through anyway.
-
-We can also have instances for functions: @instance Foo (a -> b) ...@.
+ ------------------------------
+ [Inline dfuns] Inlining dfuns unconditionally
+ ------------------------------
+
+The code above unconditionally inlines dict funs. Here's why.
+Consider this program:
+
+ test :: Int -> Int -> Bool
+ test x y = (x,y) == (y,x) || test y x
+ -- Recursive to avoid making it inline.
+
+This needs the (Eq (Int,Int)) instance. If we inline that dfun
+the code we end up with is good:
+
+ Test.$wtest =
+ \r -> case ==# [ww ww1] of wild {
+ PrelBase.False -> Test.$wtest ww1 ww;
+ PrelBase.True ->
+ case ==# [ww1 ww] of wild1 {
+ PrelBase.False -> Test.$wtest ww1 ww;
+ PrelBase.True -> PrelBase.True [];
+ };
+ };
+ Test.test = \r [w w1]
+ case w of w2 {
+ PrelBase.I# ww ->
+ case w1 of w3 { PrelBase.I# ww1 -> Test.$wtest ww ww1; };
+ };
+
+If we don't inline the dfun, the code is not nearly as good:
+
+ (==) = case PrelTup.$fEq(,) PrelBase.$fEqInt PrelBase.$fEqInt of tpl {
+ PrelBase.:DEq tpl1 tpl2 -> tpl2;
+ };
+
+ Test.$wtest =
+ \r [ww ww1]
+ let { y = PrelBase.I#! [ww1]; } in
+ let { x = PrelBase.I#! [ww]; } in
+ let { sat_slx = PrelTup.(,)! [y x]; } in
+ let { sat_sly = PrelTup.(,)! [x y];
+ } in
+ case == sat_sly sat_slx of wild {
+ PrelBase.False -> Test.$wtest ww1 ww;
+ PrelBase.True -> PrelBase.True [];
+ };
+
+ Test.test =
+ \r [w w1]
+ case w of w2 {
+ PrelBase.I# ww ->
+ case w1 of w3 { PrelBase.I# ww1 -> Test.$wtest ww ww1; };
+ };
+
+Why doesn't GHC inline $fEq? Because it looks big:
+
+ PrelTup.zdfEqZ1T{-rcX-}
+ = \ @ a{-reT-} :: * @ b{-reS-} :: *
+ zddEq{-rf6-} _Ks :: {PrelBase.Eq{-23-} a{-reT-}}
+ zddEq1{-rf7-} _Ks :: {PrelBase.Eq{-23-} b{-reS-}} ->
+ let {
+ zeze{-rf0-} _Kl :: (b{-reS-} -> b{-reS-} -> PrelBase.Bool{-3c-})
+ zeze{-rf0-} = PrelBase.zeze{-01L-}@ b{-reS-} zddEq1{-rf7-} } in
+ let {
+ zeze1{-rf3-} _Kl :: (a{-reT-} -> a{-reT-} -> PrelBase.Bool{-3c-})
+ zeze1{-rf3-} = PrelBase.zeze{-01L-} @ a{-reT-} zddEq{-rf6-} } in
+ let {
+ zeze2{-reN-} :: ((a{-reT-}, b{-reS-}) -> (a{-reT-}, b{-reS-})-> PrelBase.Bool{-3c-})
+ zeze2{-reN-} = \ ds{-rf5-} _Ks :: (a{-reT-}, b{-reS-})
+ ds1{-rf4-} _Ks :: (a{-reT-}, b{-reS-}) ->
+ case ds{-rf5-}
+ of wild{-reW-} _Kd { (a1{-rf2-} _Ks, a2{-reZ-} _Ks) ->
+ case ds1{-rf4-}
+ of wild1{-reX-} _Kd { (b1{-rf1-} _Ks, b2{-reY-} _Ks) ->
+ PrelBase.zaza{-r4e-}
+ (zeze1{-rf3-} a1{-rf2-} b1{-rf1-})
+ (zeze{-rf0-} a2{-reZ-} b2{-reY-})
+ }
+ } } in
+ let {
+ a1{-reR-} :: ((a{-reT-}, b{-reS-})-> (a{-reT-}, b{-reS-})-> PrelBase.Bool{-3c-})
+ a1{-reR-} = \ a2{-reV-} _Ks :: (a{-reT-}, b{-reS-})
+ b1{-reU-} _Ks :: (a{-reT-}, b{-reS-}) ->
+ PrelBase.not{-r6I-} (zeze2{-reN-} a2{-reV-} b1{-reU-})
+ } in
+ PrelBase.zdwZCDEq{-r8J-} @ (a{-reT-}, b{-reS-}) a1{-reR-} zeze2{-reN-})
+
+and it's not as bad as it seems, because it's further dramatically
+simplified: only zeze2 is extracted and its body is simplified.
-\begin{code}
-scrutiniseInstanceType dfun_name clas inst_tau
- -- TYCON CHECK
- | not (maybeToBool inst_tycon_maybe) || isSynTyCon inst_tycon
- = failTc (instTypeErr inst_tau)
-
- -- IMPORTED INSTANCES ARE OK (but see tcInstDecl1)
- | not (isLocallyDefined dfun_name)
- = returnTc (inst_tycon,arg_tys)
-
- -- TYVARS CHECK
- | not (opt_GlasgowExts ||
- (all isTyVarTy arg_tys && null tyvar_dups)
- )
- = failTc (instTypeErr inst_tau)
-
- -- DERIVING CHECK
- -- It is obviously illegal to have an explicit instance
- -- for something that we are also planning to `derive'
- -- Though we can have an explicit instance which is more
- -- specific than the derived instance
- | clas `elem` (derivedClasses inst_tycon)
- && all isTyVarTy arg_tys
- = failTc (derivingWhenInstanceExistsErr clas inst_tycon)
-
- | -- CCALL CHECK
- -- A user declaration of a CCallable/CReturnable instance
- -- must be for a "boxed primitive" type.
- (uniqueOf clas == cCallableClassKey && not (ccallable_type inst_tau)) ||
- (uniqueOf clas == cReturnableClassKey && not (creturnable_type inst_tau))
- = failTc (nonBoxedPrimCCallErr clas inst_tau)
-
- | otherwise
- = returnTc (inst_tycon,arg_tys)
- where
- (possible_tycon, arg_tys) = splitAppTys inst_tau
- inst_tycon_maybe = getTyCon_maybe possible_tycon
- inst_tycon = expectJust "tcInstDecls1:inst_tycon" inst_tycon_maybe
- (_, tyvar_dups) = removeDups cmp (map (getTyVar "tcInstDecls1:getTyVarTy") arg_tys)
-
--- These conditions come directly from what the DsCCall is capable of.
--- Totally grotesque. Green card should solve this.
-
-ccallable_type ty = isPrimType ty || -- Allow CCallable Int# etc
- maybeToBool (maybeBoxedPrimType ty) || -- Ditto Int etc
- ty `eqTy` stringTy ||
- byte_arr_thing
- where
- byte_arr_thing = case maybeAppDataTyCon ty of
- Just (tycon, ty_args, [data_con]) | isDataTyCon tycon ->
- length data_con_arg_tys == 2 &&
- maybeToBool maybe_arg2_tycon &&
- (arg2_tycon == byteArrayPrimTyCon ||
- arg2_tycon == mutableByteArrayPrimTyCon)
- where
- data_con_arg_tys = dataConArgTys data_con ty_args
- (data_con_arg_ty1 : data_con_arg_ty2 : _) = data_con_arg_tys
- maybe_arg2_tycon = maybeAppTyCon data_con_arg_ty2
- Just (arg2_tycon,_) = maybe_arg2_tycon
-
- other -> False
-
-creturnable_type ty = maybeToBool (maybeBoxedPrimType ty) ||
- -- Or, a data type with a single nullary constructor
- case (maybeAppDataTyCon ty) of
- Just (tycon, tys_applied, [data_con])
- -> isNullaryDataCon data_con
- other -> False
-\end{code}
+%************************************************************************
+%* *
+\subsection{Error messages}
+%* *
+%************************************************************************
\begin{code}
-
-instTypeErr ty sty
- = case ty of
- SynTy tc _ _ -> hsep [ptext SLIT("The type synonym"), ppr sty tc, rest_of_msg]
- TyVarTy tv -> hsep [ptext SLIT("The type variable"), ppr sty tv, rest_of_msg]
- other -> sep [ptext SLIT("The type"), nest 4 (ppr sty ty), rest_of_msg]
+instDeclCtxt1 hs_inst_ty
+ = inst_decl_ctxt (case unLoc hs_inst_ty of
+ HsForAllTy _ _ _ (L _ (HsPredTy pred)) -> ppr pred
+ HsPredTy pred -> ppr pred
+ other -> ppr hs_inst_ty) -- Don't expect this
+instDeclCtxt2 dfun_ty
+ = inst_decl_ctxt (ppr (mkClassPred cls tys))
where
- rest_of_msg = ptext SLIT("cannot be used as an instance type")
-
-instBndrErr bndr clas sty
- = hsep [ptext SLIT("Class"), ppr sty clas, ptext SLIT("does not have a method"), ppr sty bndr]
-
-derivingWhenInstanceExistsErr clas tycon sty
- = hang (hsep [ptext SLIT("Deriving class"),
- ppr sty clas,
- ptext SLIT("type"), ppr sty tycon])
- 4 (ptext SLIT("when an explicit instance exists"))
-
-nonBoxedPrimCCallErr clas inst_ty sty
- = hang (ptext SLIT("Unacceptable instance type for ccall-ish class"))
- 4 (hsep [ ptext SLIT("class"), ppr sty clas, ptext SLIT("type"),
- ppr sty inst_ty])
-
-omittedMethodWarn sel_id clas sty
- = sep [ptext SLIT("Warning: no explicit method nor default method for") <+> ppr sty sel_id,
- ptext SLIT("in an instance declaration for") <+> ppr sty clas]
-
-instMethodNotInClassErr occ clas sty
- = hang (ptext SLIT("Instance mentions a method not in the class"))
- 4 (hsep [ptext SLIT("class"), ppr sty clas, ptext SLIT("method"),
- ppr sty occ])
-
-patMonoBindsCtxt pbind sty
- = hang (ptext SLIT("In a pattern binding:"))
- 4 (ppr sty pbind)
-
-methodSigCtxt name ty sty
- = hang (hsep [ptext SLIT("When matching the definition of class method"),
- ppr sty name, ptext SLIT("to its signature :") ])
- 4 (ppr sty ty)
+ (_,_,cls,tys) = tcSplitDFunTy dfun_ty
-bindSigCtxt sty
- = ptext SLIT("When checking methods of an instance declaration")
+inst_decl_ctxt doc = ptext SLIT("In the instance declaration for") <+> quotes doc
-superClassSigCtxt sty
- = ptext SLIT("When checking superclass constraints of an instance declaration")
+superClassCtxt = ptext SLIT("When checking the super-classes of an instance declaration")
\end{code}