Improve error message when 'main' is not defined
[ghc-hetmet.git] / compiler / typecheck / TcEnv.lhs
index d59278a..0f9bf23 100644 (file)
@@ -42,7 +42,10 @@ module TcEnv(
        topIdLvl, 
 
        -- New Ids
-       newLocalName, newDFunName, newFamInstTyConName
+       newLocalName, newDFunName, newFamInstTyConName,
+
+        -- Errors
+        famInstNotFound
   ) where
 
 #include "HsVersions.h"
@@ -55,7 +58,6 @@ import TcMType
 import TcType
 import TcGadt
 import qualified Type
-import Id
 import Var
 import VarSet
 import VarEnv
@@ -161,14 +163,31 @@ tcLookupLocatedTyCon = addLocM tcLookupTyCon
 
 -- 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}
 
@@ -621,7 +640,7 @@ Make a name for the dict fun for an instance decl.  It's an *external*
 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
@@ -635,12 +654,12 @@ newDFunName clas (ty:_) loc
 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
@@ -670,8 +689,10 @@ wrongThingErr expected thing name
   = 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}