topIdLvl,
-- New Ids
- newLocalName, newDFunName, newFamInstTyConName
+ newLocalName, newDFunName, newFamInstTyConName,
+
+ -- Errors
+ famInstNotFound
) where
#include "HsVersions.h"
import TcType
import TcGadt
import qualified Type
-import Id
import Var
import VarSet
import VarEnv
-- Look up the representation tycon of a family instance.
--
-tcLookupFamInst :: TyCon -> [Type] -> TcM TyCon
+-- The match must be unique - ie, match exactly one instance - but the
+-- type arguments used for matching may be more specific than those of
+-- the family instance declaration.
+--
+-- Return the instance tycon and its type instance. For example, if we have
+--
+-- tcLookupFamInst 'T' '[Int]' yields (':R42T', 'Int')
+--
+-- then we have a coercion (ie, type instance of family instance coercion)
+--
+-- :Co:R42T Int :: T [Int] ~ :R42T Int
+--
+-- which implies that :R42T was declared as 'data instance T [a]'.
+--
+tcLookupFamInst :: TyCon -> [Type] -> TcM (TyCon, [Type])
tcLookupFamInst tycon tys
+ | not (isOpenTyCon tycon)
+ = return (tycon, tys)
+ | otherwise
= do { env <- getGblEnv
; eps <- getEps
; let instEnv = (eps_fam_inst_env eps, tcg_fam_inst_env env)
- ; case lookupFamInstEnvExact instEnv tycon tys of
- Nothing -> famInstNotFound tycon tys
- Just famInst -> return $ famInstTyCon famInst
+ ; case lookupFamInstEnv instEnv tycon tys of
+ [(fam_inst, rep_tys)] -> return (famInstTyCon fam_inst, rep_tys)
+ other -> famInstNotFound tycon tys other
}
\end{code}
name, like otber top-level names, and hence must be made with newGlobalBinder.
\begin{code}
-newDFunName :: Class -> [Type] -> SrcLoc -> TcM Name
+newDFunName :: Class -> [Type] -> SrcSpan -> TcM Name
newDFunName clas (ty:_) loc
= do { index <- nextDFunIndex
; is_boot <- tcIsHsBoot
newDFunName clas [] loc = pprPanic "newDFunName" (ppr clas <+> ppr loc)
\end{code}
-Make a name for the representation tycon of a data/newtype instance. It's an
+Make a name for the representation tycon of a family instance. It's an
*external* name, like otber top-level names, and hence must be made with
newGlobalBinder.
\begin{code}
-newFamInstTyConName :: Name -> SrcLoc -> TcM Name
+newFamInstTyConName :: Name -> SrcSpan -> TcM Name
newFamInstTyConName tc_name loc
= do { index <- nextDFunIndex
; mod <- getModule
= failWithTc (pprTcTyThingCategory thing <+> quotes (ppr name) <+>
ptext SLIT("used as a") <+> text expected)
-famInstNotFound tycon tys
- = failWithTc (quotes famInst <+> ptext SLIT("is not in scope"))
+famInstNotFound tycon tys what
+ = failWithTc (msg <+> quotes (pprTypeApp (ppr tycon) tys))
where
- famInst = ppr tycon <+> hsep (map pprParendType tys)
+ msg = ptext $ if length what > 1
+ then SLIT("More than one family instance for")
+ else SLIT("No family instance exactly matching")
\end{code}