Store a SrcSpan instead of a SrcLoc inside a Name
[ghc-hetmet.git] / compiler / typecheck / TcClassDcl.lhs
index 31e3d5a..f4c7058 100644 (file)
@@ -1,72 +1,61 @@
 %
+% (c) The University of Glasgow 2006
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-\section[TcClassDcl]{Typechecking class declarations}
+
+Typechecking class declarations
 
 \begin{code}
 module TcClassDcl ( tcClassSigs, tcClassDecl2, 
                    getGenericInstances, 
                    MethodSpec, tcMethodBind, mkMethodBind, 
-                   tcAddDeclCtxt, badMethodErr
+                   tcAddDeclCtxt, badMethodErr, badATErr, omittedATWarn
                  ) where
 
 #include "HsVersions.h"
 
 import HsSyn
-import RnHsSyn         ( maybeGenericMatch, extractHsTyVars )
-import RnExpr          ( rnLExpr )
-import RnEnv           ( lookupTopBndrRn, lookupImportedName )
-import Inst            ( instToId, newDicts, newDictsAtLoc, newMethod, getOverlapFlag )
-import InstEnv         ( mkLocalInstance )
-import TcEnv           ( tcLookupLocatedClass, 
-                         tcExtendTyVarEnv, tcExtendIdEnv,
-                         InstInfo(..), pprInstInfoDetails,
-                         simpleInstInfoTyCon, simpleInstInfoTy,
-                         InstBindings(..), newDFunName
-                       )
-import TcBinds         ( TcPragFun, tcMonoBinds, tcPrags, mkPragFun, TcSigInfo(..), 
-                         TcSigFun, mkTcSigFun )
-import TcHsType                ( tcHsKindedType, tcHsSigType )
-import TcSimplify      ( tcSimplifyCheck )
-import TcUnify         ( checkSigTyVars, sigCtxt )
-import TcMType         ( tcSkolSigTyVars )
-import TcType          ( Type, SkolemInfo(ClsSkol, InstSkol), UserTypeCtxt( GenPatCtxt ),
-                         TcType, TcThetaType, TcTyVar, mkTyVarTys,
-                         mkClassPred, tcSplitSigmaTy, tcSplitFunTys,
-                         tcIsTyVarTy, tcSplitTyConApp_maybe, tcSplitForAllTys, tcSplitPhiTy,
-                         getClassPredTys_maybe, mkPhiTy, mkTyVarTy
-                       )
+import RnHsSyn
+import RnExpr
+import RnEnv
+import Inst
+import InstEnv
+import TcEnv
+import TcBinds
+import TcHsType
+import TcSimplify
+import TcUnify
+import TcMType
+import TcType
 import TcRnMonad
-import Generics                ( mkGenericRhs, validGenericInstanceType )
-import PrelInfo                ( nO_METHOD_BINDING_ERROR_ID )
-import Class           ( classTyVars, classBigSig, 
-                         Class, ClassOpItem, DefMeth (..) )
-import TyCon           ( TyCon, tyConName, tyConHasGenerics )
-import Type            ( substTyWith )
-import MkId            ( mkDefaultMethodId, mkDictFunId )
-import Id              ( Id, idType, idName, mkUserLocal )
-import Name            ( Name, NamedThing(..) )
-import NameEnv         ( NameEnv, lookupNameEnv, mkNameEnv )
-import NameSet         ( nameSetToList )
-import OccName         ( reportIfUnused, mkDefaultMethodOcc )
-import RdrName         ( RdrName, mkDerivedRdrName )
+import Generics
+import PrelInfo
+import Class
+import TyCon
+import Type
+import MkId
+import Id
+import Name
+import NameEnv
+import NameSet
+import OccName
+import RdrName
 import Outputable
-import PrelNames       ( genericTyConNames )
+import PrelNames
 import DynFlags
-import ErrUtils                ( dumpIfSet_dyn )
-import Util            ( count, lengthIs, isSingleton, lengthExceeds )
-import Unique          ( Uniquable(..) )
-import ListSetOps      ( equivClassesByUniq, minusList )
-import SrcLoc          ( Located(..), srcSpanStart, unLoc, noLoc )
-import Maybes          ( seqMaybe, isJust, mapCatMaybes )
-import List            ( partition )
-import BasicTypes      ( RecFlag(..), Boxity(..) )
+import ErrUtils
+import Util
+import Unique
+import ListSetOps
+import SrcLoc
+import Maybes
+import List
+import BasicTypes
 import Bag
 import FastString
 \end{code}
 
 
-
 Dictionary handling
 ~~~~~~~~~~~~~~~~~~~
 Every class implicitly declares a new data type, corresponding to dictionaries
@@ -246,9 +235,13 @@ tcClassDecl2 (L loc (ClassDecl {tcdLName = class_name, tcdSigs = sigs,
        -- default methods.  Better to make separate AbsBinds for each
     let
        (tyvars, _, _, op_items) = classBigSig clas
+       rigid_info               = ClsSkol clas
+       origin                   = SigOrigin rigid_info
        prag_fn                  = mkPragFun sigs
        sig_fn                   = mkTcSigFun sigs
-       tc_dm                    = tcDefMeth clas tyvars default_binds sig_fn prag_fn
+       clas_tyvars              = tcSkolSigTyVars rigid_info tyvars
+       tc_dm                    = tcDefMeth origin clas clas_tyvars
+                                            default_binds sig_fn prag_fn
 
        dm_sel_ids               = [sel_id | (sel_id, DefMeth) <- op_items]
        -- Generate code for polymorphic default methods only
@@ -261,32 +254,30 @@ tcClassDecl2 (L loc (ClassDecl {tcdLName = class_name, tcdSigs = sigs,
     mapAndUnzipM tc_dm dm_sel_ids      `thenM` \ (defm_binds, dm_ids_s) ->
     returnM (listToBag defm_binds, concat dm_ids_s)
     
-tcDefMeth clas tyvars binds_in sig_fn prag_fn sel_id
+tcDefMeth origin clas tyvars binds_in sig_fn prag_fn sel_id
   = do { dm_name <- lookupTopBndrRn (mkDefMethRdrName sel_id)
-       ; let   rigid_info  = ClsSkol clas
-               clas_tyvars = tcSkolSigTyVars rigid_info tyvars
-               inst_tys    = mkTyVarTys clas_tyvars
+       ; let   inst_tys    = mkTyVarTys tyvars
                dm_ty       = idType sel_id     -- Same as dict selector!
-               theta       = [mkClassPred clas inst_tys]
+               cls_pred    = mkClassPred clas inst_tys
                local_dm_id = mkDefaultMethodId dm_name dm_ty
-               origin      = SigOrigin rigid_info
 
        ; (_, meth_info) <- mkMethodBind origin clas inst_tys binds_in (sel_id, DefMeth)
-       ; [this_dict] <- newDicts origin theta
-       ; (defm_bind, insts_needed) <- getLIE (tcMethodBind clas_tyvars theta [this_dict]
+       ; loc <- getInstLoc origin
+       ; this_dict <- newDictBndr loc cls_pred
+       ; (defm_bind, insts_needed) <- getLIE (tcMethodBind tyvars [cls_pred] [this_dict]
                                                            sig_fn prag_fn meth_info)
     
        ; addErrCtxt (defltMethCtxt clas) $ do
     
         -- Check the context
        { dict_binds <- tcSimplifyCheck
-                               (ptext SLIT("class") <+> ppr clas)
-                               clas_tyvars
+                               loc
+                               tyvars
                                [this_dict]
                                insts_needed
 
        -- Simplification can do unification
-       ; checkSigTyVars clas_tyvars
+       ; checkSigTyVars tyvars
     
        -- Inline pragmas 
        -- We'll have an inline pragma on the local binding, made by tcMethodBind
@@ -297,9 +288,9 @@ tcDefMeth clas tyvars binds_in sig_fn prag_fn sel_id
              inline_prags     = filter isInlineLSig (prag_fn sel_name)
        ; prags <- tcPrags dm_inst_id inline_prags
 
-       ; let full_bind = AbsBinds  clas_tyvars
+       ; let full_bind = AbsBinds  tyvars
                                    [instToId this_dict]
-                                   [(clas_tyvars, local_dm_id, dm_inst_id, prags)]
+                                   [(tyvars, local_dm_id, dm_inst_id, prags)]
                                    (dict_binds `unionBags` defm_bind)
        ; returnM (noLoc full_bind, [local_dm_id]) }}
 
@@ -371,18 +362,18 @@ tcMethodBind inst_tyvars inst_theta avail_insts sig_fn prag_fn
 
     let
        [(_, Just sig, local_meth_id)] = mono_bind_infos
+       loc = sig_loc sig
     in
 
     addErrCtxtM (sigCtxt sel_id inst_tyvars inst_theta (idType meth_id))       $
-    newDictsAtLoc (sig_loc sig) (sig_theta sig)                `thenM` \ meth_dicts ->
+    newDictBndrs loc (sig_theta sig)           `thenM` \ meth_dicts ->
     let
        meth_tvs   = sig_tvs sig
        all_tyvars = meth_tvs ++ inst_tyvars
        all_insts  = avail_insts ++ meth_dicts
     in
     tcSimplifyCheck
-        (ptext SLIT("class or instance method") <+> quotes (ppr sel_id))
-        all_tyvars all_insts meth_lie          `thenM` \ lie_binds ->
+        loc all_tyvars all_insts meth_lie      `thenM` \ lie_binds ->
 
     checkSigTyVars all_tyvars                  `thenM_`
 
@@ -461,8 +452,7 @@ mkMethId origin clas sel_id inst_tys
        getSrcSpanM                     `thenM` \ loc ->
        let 
            real_tau = mkPhiTy (tail preds) tau
-           meth_id  = mkUserLocal (getOccName sel_id) uniq real_tau 
-                       (srcSpanStart loc) --TODO
+           meth_id  = mkUserLocal (getOccName sel_id) uniq real_tau loc
        in
        returnM (Nothing, meth_id)
 
@@ -546,8 +536,8 @@ mkDefMethRhs origin clas inst_tys sel_id loc GenDefMeth
                                  other                                           -> Nothing
                        other -> Nothing
 
-isInstDecl (SigOrigin (InstSkol _)) = True
-isInstDecl (SigOrigin (ClsSkol _))  = False
+isInstDecl (SigOrigin InstSkol)    = True
+isInstDecl (SigOrigin (ClsSkol _)) = False
 \end{code}
 
 
@@ -630,6 +620,8 @@ get_generics decl@(ClassDecl {tcdLName = class_name, tcdMeths = def_methods})
        --      f {| a+b |} ... = ...
        --      f {| x+y |} ... = ...
        -- Then at this point we'll have an InstInfo for each
+       --
+       -- The class should be unary, which is why simpleInstInfoTyCon should be ok
     let
        tc_inst_infos :: [(TyCon, InstInfo)]
        tc_inst_infos = [(simpleInstInfoTyCon i, i) | i <- inst_infos]
@@ -714,7 +706,7 @@ mkGenericInstance clas (hs_ty, binds)
        -- Make the dictionary function.
     getSrcSpanM                                                `thenM` \ span -> 
     getOverlapFlag                                     `thenM` \ overlap_flag -> 
-    newDFunName clas [inst_ty] (srcSpanStart span)     `thenM` \ dfun_name ->
+    newDFunName clas [inst_ty] span                    `thenM` \ dfun_name ->
     let
        inst_theta = [mkClassPred clas [mkTyVarTy tv] | tv <- tyvars]
        dfun_id    = mkDictFunId dfun_name tyvars inst_theta clas [inst_ty]
@@ -734,11 +726,15 @@ mkGenericInstance clas (hs_ty, binds)
 tcAddDeclCtxt decl thing_inside
   = addErrCtxt ctxt thing_inside
   where
-     thing = case decl of
-               ClassDecl {}              -> "class"
-               TySynonym {}              -> "type synonym"
-               TyData {tcdND = NewType}  -> "newtype"
-               TyData {tcdND = DataType} -> "data type"
+     thing | isClassDecl decl  = "class"
+          | isTypeDecl decl   = "type synonym" ++ maybeInst
+          | isDataDecl decl   = if tcdND decl == NewType 
+                                then "newtype" ++ maybeInst
+                                else "data type" ++ maybeInst
+          | isFamilyDecl decl = "family"
+
+     maybeInst | isFamInstDecl decl = " family"
+              | otherwise          = ""
 
      ctxt = hsep [ptext SLIT("In the"), text thing, 
                  ptext SLIT("declaration for"), quotes (ppr (tcdName decl))]
@@ -753,9 +749,16 @@ badMethodErr clas op
   = hsep [ptext SLIT("Class"), quotes (ppr clas), 
          ptext SLIT("does not have a method"), quotes (ppr op)]
 
+badATErr clas at
+  = hsep [ptext SLIT("Class"), quotes (ppr clas), 
+         ptext SLIT("does not have an associated type"), quotes (ppr at)]
+
 omittedMethodWarn sel_id
   = ptext SLIT("No explicit method nor default method for") <+> quotes (ppr sel_id)
 
+omittedATWarn at
+  = ptext SLIT("No explicit AT declaration for") <+> quotes (ppr at)
+
 badGenericInstance sel_id because
   = sep [ptext SLIT("Can't derive generic code for") <+> quotes (ppr sel_id),
         because]
@@ -763,7 +766,7 @@ badGenericInstance sel_id because
 notSimple inst_tys
   = vcat [ptext SLIT("because the instance type(s)"), 
          nest 2 (ppr inst_tys),
-         ptext SLIT("is not a simple type of form (T a b c)")]
+         ptext SLIT("is not a simple type of form (T a1 ... an)")]
 
 notGeneric tycon
   = vcat [ptext SLIT("because the instance type constructor") <+> quotes (ppr tycon) <+>