Big tidy-up of deriving code
[ghc-hetmet.git] / compiler / typecheck / TcInstDcls.lhs
index 2d59676..fe7b1d8 100644 (file)
@@ -1,7 +1,9 @@
 %
+% (c) The University of Glasgow 2006
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-\section[TcInstDecls]{Typechecking instance declarations}
+
+TcInstDecls: Typechecking instance declarations
 
 \begin{code}
 module TcInstDcls ( tcInstDecls1, tcInstDecls2 ) where
@@ -9,56 +11,43 @@ module TcInstDcls ( tcInstDecls1, tcInstDecls2 ) where
 #include "HsVersions.h"
 
 import HsSyn
-import TcBinds         ( mkPragFun, tcPrags, badBootDeclErr )
-import TcTyClsDecls     ( tcIdxTyInstDecl )
-import TcClassDcl      ( tcMethodBind, mkMethodBind, badMethodErr, badATErr,
-                         omittedATWarn, tcClassDecl2, getGenericInstances )
+import TcBinds
+import TcTyClsDecls
+import TcClassDcl
 import TcRnMonad       
-import TcMType         ( tcSkolSigType, checkValidInstance,
-                         checkValidInstHead )
-import TcType          ( TcType, mkClassPred, tcSplitSigmaTy,
-                         tcSplitDFunHead,  SkolemInfo(InstSkol),
-                         tcSplitTyConApp, 
-                         tcSplitDFunTy, mkFunTy ) 
-import Inst            ( newDictBndr, newDictBndrs, instToId, showLIE, 
-                         getOverlapFlag, tcExtendLocalInstEnv )
-import InstEnv         ( mkLocalInstance, instanceDFunId )
-import FamInst         ( tcExtendLocalFamInstEnv )
-import FamInstEnv      ( extractFamInsts )
-import TcDeriv         ( tcDeriving )
-import TcEnv           ( InstInfo(..), InstBindings(..), 
-                         newDFunName, tcExtendIdEnv, tcExtendGlobalEnv
-                       )
-import TcHsType                ( kcHsSigType, tcHsKindedType )
-import TcUnify         ( checkSigTyVars )
-import TcSimplify      ( tcSimplifySuperClasses )
-import Type            ( zipOpenTvSubst, substTheta, mkTyConApp, mkTyVarTy,
-                          TyThing(ATyCon), isTyVarTy, tcEqType,
-                          substTys, emptyTvSubst, extendTvSubst )
-import Coercion         ( mkSymCoercion )
-import TyCon            ( TyCon, tyConName, newTyConCo_maybe, tyConTyVars,
-                         isTyConAssoc, tyConFamInst_maybe, tyConDataCons,
-                         assocTyConArgPoss_maybe )
-import DataCon         ( classDataCon, dataConInstArgTys )
-import Class           ( Class, classTyCon, classBigSig, classATs )
-import Var             ( TyVar, Id, idName, idType, tyVarName )
-import MkId            ( mkDictFunId )
-import Name            ( Name, getSrcLoc, nameOccName )
-import NameSet         ( addListToNameSet, emptyNameSet, minusNameSet,
-                         nameSetToList ) 
-import Maybe           ( fromJust, catMaybes )
-import Monad           ( when )
-import List            ( find )
-import DynFlags                ( DynFlag(Opt_WarnMissingMethods) )
-import SrcLoc          ( srcLocSpan, unLoc, noLoc, Located(..), srcSpanStart,
-                         getLoc)
-import ListSetOps      ( minusList )
-import Util            ( snocView, dropList )
+import TcMType
+import TcType
+import Inst
+import InstEnv
+import FamInst
+import FamInstEnv
+import TcDeriv
+import TcEnv
+import TcHsType
+import TcUnify
+import TcSimplify
+import Type
+import Coercion
+import TyCon
+import DataCon
+import Class
+import Var
+import MkId
+import Name
+import NameSet
+import DynFlags
+import SrcLoc
+import ListSetOps
+import Util
 import Outputable
 import Bag
-import BasicTypes      ( Activation( AlwaysActive ), InlineSpec(..) )
-import HscTypes                ( implicitTyThings )
+import BasicTypes
+import HscTypes
 import FastString
+
+import Data.Maybe
+import Control.Monad hiding (zipWithM_, mapAndUnzipM)
+import Data.List
 \end{code}
 
 Typechecking instance declarations is done in two passes. The first
@@ -146,12 +135,13 @@ Gather up the instance declarations from their various sources
 tcInstDecls1   -- Deal with both source-code and imported instance decls
    :: [LTyClDecl Name]         -- For deriving stuff
    -> [LInstDecl Name]         -- Source code instance decls
+   -> [LDerivDecl Name]                -- Source code stand-alone deriving 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
+tcInstDecls1 tycl_decls inst_decls deriv_decls
   = checkNoErrs $
     do {        -- Stop if addInstInfos etc discovers any errors
                -- (they recover, so that we get more than one error each
@@ -190,7 +180,7 @@ tcInstDecls1 tycl_decls inst_decls
                -- (4) 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
-       ; (deriv_inst_info, deriv_binds) <- tcDeriving tycl_decls
+       ; (deriv_inst_info, deriv_binds) <- tcDeriving tycl_decls deriv_decls
        ; addInsts deriv_inst_info   $ do {
 
        ; gbl_env <- getGblEnv
@@ -226,8 +216,12 @@ addInsts infos thing_inside
 
 addFamInsts :: [TyThing] -> TcM a -> TcM a
 addFamInsts tycons thing_inside
-  = tcExtendLocalFamInstEnv (extractFamInsts tycons) thing_inside
-\end{code} 
+  = tcExtendLocalFamInstEnv (map mkLocalFamInstTyThing tycons) thing_inside
+  where
+    mkLocalFamInstTyThing (ATyCon tycon) = mkLocalFamInst tycon
+    mkLocalFamInstTyThing tything       = pprPanic "TcInstDcls.addFamInsts"
+                                                   (ppr tything)
+\end{code}
 
 \begin{code}
 tcLocalInstDecl1 :: LInstDecl Name 
@@ -246,11 +240,7 @@ tcLocalInstDecl1 decl@(L loc (InstDecl poly_ty binds uprags ats))
        ; checkTc (not is_boot || (isEmptyLHsBinds binds && null uprags))
                  badBootDeclErr
 
-       -- Typecheck the instance type itself.  We can't use 
-       -- tcHsSigType, because it's not a valid user type.
-       ; kinded_ty <- kcHsSigType poly_ty
-       ; poly_ty'  <- tcHsKindedType kinded_ty
-       ; let (tyvars, theta, tau) = tcSplitSigmaTy poly_ty'
+       ; (tyvars, theta, tau) <- tcHsInstHead poly_ty
        
        -- Next, process any associated types.
        ; idx_tycons <- mappM tcIdxTyInstDecl ats
@@ -489,7 +479,7 @@ tcInstDecl2 :: InstInfo -> TcM (LHsBinds Id)
 
 tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = NewTypeDerived mb_preds })
   = do { let dfun_id      = instanceDFunId ispec 
-             rigid_info   = InstSkol dfun_id
+             rigid_info   = InstSkol
              origin       = SigOrigin rigid_info
              inst_ty      = idType dfun_id
        ; (tvs, theta, inst_head_ty) <- tcSkolSigType rigid_info inst_ty
@@ -505,11 +495,11 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = NewTypeDerived mb_preds })
         ; let (cls, cls_inst_tys) = tcSplitDFunHead inst_head_ty
              cls_tycon           = classTyCon cls
              the_coercion        = make_coercion cls_tycon cls_inst_tys
-              coerced_rep_dict           = mkHsCoerce the_coercion (HsVar rep_dict_id)
+              coerced_rep_dict           = mkHsWrap the_coercion (HsVar rep_dict_id)
 
        ; body <- make_body cls_tycon cls_inst_tys sc_dict_ids coerced_rep_dict
               
-        ; return (sc_binds `snocBag` (noLoc $ VarBind dfun_id $ noLoc $ mkHsCoerce wrap_fn body)) }
+        ; return (sc_binds `snocBag` (noLoc $ VarBind dfun_id $ noLoc $ mkHsWrap wrap_fn body)) }
   where
 
       -----------------------
@@ -524,15 +514,16 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = NewTypeDerived mb_preds })
     make_wrapper inst_loc tvs theta (Just preds)       -- Case (a)
       = ASSERT( null tvs && null theta )
        do { dicts <- newDictBndrs inst_loc preds
-          ; sc_binds <- addErrCtxt superClassCtxt (tcSimplifySuperClasses [] [] dicts)
+          ; sc_binds <- addErrCtxt superClassCtxt $
+                        tcSimplifySuperClasses inst_loc [] dicts
                -- Use tcSimplifySuperClasses to avoid creating loops, for the
                -- same reason as Note [SUPERCLASS-LOOP 1] in TcSimplify
-          ; return (map instToId dicts, idCoercion, sc_binds) }
+          ; return (map instToId dicts, idHsWrapper, sc_binds) }
 
     make_wrapper inst_loc tvs theta Nothing    -- Case (b)
       = do { dicts <- newDictBndrs inst_loc theta
           ; let dict_ids = map instToId dicts
-          ; return (dict_ids, mkCoTyLams tvs <.> mkCoLams dict_ids, emptyBag) }
+          ; return (dict_ids, mkWpTyLams tvs <.> mkWpLams dict_ids, emptyBag) }
 
       -----------------------
       --       make_coercion
@@ -548,9 +539,9 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = NewTypeDerived mb_preds })
        , (tycon, tc_args) <- tcSplitTyConApp last_ty   -- Should not fail
        , Just co_con <- newTyConCo_maybe tycon
        , let co = mkSymCoercion (mkTyConApp co_con tc_args)
-        = ExprCoFn (mkTyConApp cls_tycon (all_tys_but_last ++ [co]))
+        = WpCo (mkTyConApp cls_tycon (all_tys_but_last ++ [co]))
         | otherwise    -- The newtype is transparent; no need for a cast
-        = idCoercion
+        = idHsWrapper
 
       -----------------------
       --       make_body
@@ -590,7 +581,7 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = NewTypeDerived mb_preds })
 tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = VanillaInst monobinds uprags })
   = let 
        dfun_id    = instanceDFunId ispec
-       rigid_info = InstSkol dfun_id
+       rigid_info = InstSkol
        inst_ty    = idType dfun_id
     in
         -- Prime error recovery
@@ -616,7 +607,7 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = VanillaInst monobinds uprags })
     newDictBndrs sc_loc sc_theta'                      `thenM` \ sc_dicts ->
     getInstLoc origin                                  `thenM` \ inst_loc -> 
     newDictBndrs inst_loc dfun_theta'                  `thenM` \ dfun_arg_dicts ->
-    newDictBndr inst_loc (mkClassPred clas inst_tys')  `thenM` \ this_dict ->
+    newDictBndr inst_loc (mkClassPred clas inst_tys')   `thenM` \ this_dict ->
                -- Default-method Ids may be mentioned in synthesised RHSs,
                -- but they'll already be in the environment.
 
@@ -632,9 +623,8 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = VanillaInst monobinds uprags })
        -- 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 ->
+       (tcSimplifySuperClasses inst_loc
+                        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