[project @ 1997-07-26 09:49:29 by sof]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcInstDcls.lhs
index 6f7e3a3..1dd90a3 100644 (file)
@@ -9,80 +9,97 @@
 module TcInstDcls (
        tcInstDecls1,
        tcInstDecls2,
-       processInstBinds
+       tcMethodBind
     ) where
 
 
 IMP_Ubiq()
 
-import HsSyn           ( InstDecl(..), FixityDecl, Sig(..),
-                         SpecInstSig(..), HsBinds(..), Bind(..),
-                         MonoBinds(..), GRHSsAndBinds, Match, 
+import HsSyn           ( HsDecl(..), InstDecl(..), TyDecl, ClassDecl, DefaultDecl,
+                         FixityDecl, IfaceSig, Sig(..),
+                         SpecInstSig(..), HsBinds(..),
+                         MonoBinds(..), GRHSsAndBinds(..), GRHS(..), Match, 
                          InPat(..), OutPat(..), HsExpr(..), HsLit(..),
-                         Stmt, Qualifier, ArithSeqInfo, Fake,
-                         PolyType(..), MonoType )
+                         Stmt, DoOrListComp, ArithSeqInfo, Fake, Fixity,
+                         HsType(..), HsTyVar,
+                         SYN_IE(RecFlag), recursive, nonRecursive, collectMonoBinders,
+                         andMonoBinds
+                       )
 import RnHsSyn         ( SYN_IE(RenamedHsBinds), SYN_IE(RenamedMonoBinds),
-                         RenamedInstDecl(..), RenamedFixityDecl(..),
-                         RenamedSig(..), RenamedSpecInstSig(..),
-                         RnName(..){-incl instance Outputable-}
+                         SYN_IE(RenamedInstDecl), SYN_IE(RenamedFixityDecl), SYN_IE(RenamedHsExpr),
+                         SYN_IE(RenamedSig), SYN_IE(RenamedSpecInstSig), SYN_IE(RenamedHsDecl)
                        )
-import TcHsSyn         ( TcIdOcc(..), SYN_IE(TcHsBinds),
+import TcHsSyn         ( SYN_IE(TcHsBinds),
                          SYN_IE(TcMonoBinds), SYN_IE(TcExpr), tcIdType,
                          mkHsTyLam, mkHsTyApp,
                          mkHsDictLam, mkHsDictApp )
 
-
-import TcMonad         hiding ( rnMtoTcM )
-import GenSpecEtc      ( checkSigTyVars )
+import TcBinds         ( tcBindWithSigs, tcPragmaSigs, TcSigInfo(..), checkSigTyVars )
+import TcMonad
+import RnMonad         ( SYN_IE(RnNameSupply) )
 import Inst            ( Inst, InstOrigin(..), SYN_IE(InstanceMapper),
-                         newDicts, newMethod, SYN_IE(LIE), emptyLIE, plusLIE )
-import TcBinds         ( tcPragmaSigs )
+                         instToId, newDicts, newMethod, SYN_IE(LIE), emptyLIE, plusLIE )
+import PragmaInfo      ( PragmaInfo(..) )
 import TcDeriv         ( tcDeriving )
-import TcEnv           ( tcLookupClass, tcTyVarScope, newLocalId, tcExtendGlobalTyVars )
+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      ( tcContext, tcMonoTypeKind )
+import TcMonoType      ( tcTyVarScope, tcContext, tcHsTypeKind )
 import TcSimplify      ( tcSimplifyAndCheck )
-import TcType          ( SYN_IE(TcType), SYN_IE(TcTyVar), SYN_IE(TcTyVarSet), 
-                         tcInstSigTyVars, tcInstType, tcInstTheta, tcInstTcType
+import TcType          ( TcIdOcc(..), SYN_IE(TcIdBndr), SYN_IE(TcType), SYN_IE(TcTyVar), SYN_IE(TcTyVarSet), 
+                         tcInstSigTyVars, tcInstType, tcInstSigTcType, 
+                         tcInstTheta, tcInstTcType, tcInstSigType
                        )
 import Unify           ( unifyTauTy, unifyTauTyLists )
 
 
 import Bag             ( emptyBag, unitBag, unionBags, unionManyBags,
-                         concatBag, foldBag, bagToList )
+                         concatBag, foldBag, bagToList, listToBag,
+                         Bag )
 import CmdLineOpts     ( opt_GlasgowExts, opt_CompilingGhcInternals,
-                         opt_OmitDefaultInstanceMethods,
+                         opt_OmitDefaultInstanceMethods, opt_PprUserLength,
                          opt_SpecialiseOverloaded
                        )
-import Class           ( GenClass, GenClassOp, 
-                         isCcallishClass, classBigSig,
-                         classOps, classOpLocalType,
-                         classOpTagByString
+import Class           ( GenClass,
+                         classBigSig,
+                         classDefaultMethodId, SYN_IE(Class)
                          )
-import Id              ( GenId, idType, isDefaultMethodId_maybe )
+import Id              ( GenId, idType, replacePragmaInfo,
+                         isNullaryDataCon, dataConArgTys, SYN_IE(Id) )
 import ListSetOps      ( minusList )
-import Maybes          ( maybeToBool, expectJust )
-import Name            ( getLocalName, origName, nameOf, Name{--O only-} )
-import PrelVals                ( nO_EXPLICIT_METHOD_ERROR_ID )
-import PrelMods                ( pRELUDE )
-import PprType         ( GenType, GenTyVar, GenClass, GenClassOp, TyCon,
+import Maybes          ( maybeToBool, expectJust, seqMaybe, catMaybes )
+import Name            ( nameOccName, getOccString, occNameString, moduleString, getSrcLoc,
+                         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 PprStyle
+import Outputable
+import SrcLoc          ( SrcLoc, noSrcLoc )
 import Pretty
-import RnUtils         ( SYN_IE(RnEnv) )
-import TyCon           ( isSynTyCon, derivedFor )
-import Type            ( GenType(..), SYN_IE(ThetaType), mkTyVarTys,
-                         splitSigmaTy, splitAppTy, isTyVarTy, matchTy, mkSigmaTy,
-                         getTyCon_maybe, maybeBoxedPrimType, splitRhoTy, eqTy
+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, GenTyVarSet(..), mkTyVarSet, unionTyVarSets )
+import TyVar           ( GenTyVar, SYN_IE(GenTyVarSet), tyVarSetToList, 
+                         mkTyVarSet, unionTyVarSets, SYN_IE(TyVar) )
+import TysPrim         ( byteArrayPrimTyCon, mutableByteArrayPrimTyCon )
 import TysWiredIn      ( stringTy )
-import Unique          ( Unique )
-import Util            ( zipEqual, panic )
+import Unique          ( Unique, cCallableClassKey, cReturnableClassKey, Uniquable(..) )
+import Util            ( zipEqual, panic, pprPanic, pprTrace, removeDups, Ord3(..)
+#if __GLASGOW_HASKELL__ < 202
+                         , trace 
+#endif
+                       )
 \end{code}
 
 Typechecking instance declarations is done in two passes. The first
@@ -159,98 +176,73 @@ and $dbinds_super$ bind the superclass dictionaries sd1 \ldots sdm.
 \end{enumerate}
 
 \begin{code}
-tcInstDecls1 :: Bag RenamedInstDecl
-            -> [RenamedSpecInstSig]
+tcInstDecls1 :: TcEnv s                        -- Contains IdInfo for dfun ids
+            -> [RenamedHsDecl]
             -> Module                  -- module name for deriving
-            -> RnEnv                   -- for renaming derivings
-            -> [RenamedFixityDecl]     -- fixities for deriving
+            -> RnNameSupply                    -- for renaming derivings
             -> TcM s (Bag InstInfo,
                       RenamedHsBinds,
-                      PprStyle -> Pretty)
+                      PprStyle -> Doc)
 
-tcInstDecls1 inst_decls specinst_sigs mod_name rn_env fixities
+tcInstDecls1 unf_env decls mod_name rn_name_supply
   =    -- Do the ordinary instance declarations
-    mapBagNF_Tc (tcInstDecl1 mod_name) inst_decls
-                       `thenNF_Tc` \ inst_info_bags ->
+    mapNF_Tc (tcInstDecl1 unf_env mod_name) 
+            [inst_decl | InstD inst_decl <- decls]     `thenNF_Tc` \ inst_info_bags ->
     let
-       decl_inst_info = concatBag inst_info_bags
+       decl_inst_info = unionManyBags inst_info_bags
     in
        -- Handle "derived" instances; note that we only do derivings
        -- for things in this module; we ignore deriving decls from
        -- interfaces! We pass fixities, because they may be used
        -- in deriving Read and Show.
-    tcDeriving mod_name rn_env decl_inst_info fixities
+    tcDeriving mod_name rn_name_supply decl_inst_info
                        `thenTc` \ (deriv_inst_info, deriv_binds, ddump_deriv) ->
 
     let
-       inst_info = deriv_inst_info `unionBags` decl_inst_info
-    in
-{- LATER
-       -- Handle specialise instance pragmas
-    tcSpecInstSigs inst_info specinst_sigs
-                       `thenTc` \ spec_inst_info ->
--}
-    let
-       spec_inst_info = emptyBag       -- For now
-
-       full_inst_info = inst_info `unionBags` spec_inst_info
+       full_inst_info = deriv_inst_info `unionBags` decl_inst_info
     in
     returnTc (full_inst_info, deriv_binds, ddump_deriv)
 
 
-tcInstDecl1 :: FAST_STRING -> RenamedInstDecl -> NF_TcM s (Bag InstInfo)
+tcInstDecl1 :: TcEnv s -> Module -> RenamedInstDecl -> NF_TcM s (Bag InstInfo)
 
-tcInstDecl1 mod_name
-           (InstDecl class_name
-                     poly_ty@(HsForAllTy tyvar_names context inst_ty)
-                     binds
-                     from_here inst_mod uprags pragmas src_loc)
+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           `thenNF_Tc` \ (clas_kind, clas) ->
+    tcLookupClass class_name           `thenTc` \ (clas_kind, clas) ->
 
-    let
-       de_rn (RnName n) = n
-    in
        -- Typecheck the context and instance type
-    tcTyVarScope (map de_rn tyvar_names) (\ tyvars ->
+    tcTyVarScope tyvar_names (\ tyvars ->
        tcContext context               `thenTc` \ theta ->
-       tcMonoTypeKind inst_ty          `thenTc` \ (tau_kind, tau) ->
+       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 from_here clas inst_tau
+    scrutiniseInstanceType dfun_name clas inst_tau
                                        `thenTc` \ (inst_tycon,arg_tys) ->
 
-       -- Deal with the case where we are deriving
-       -- and importing the same instance
-    if (not from_here && (clas `derivedFor` inst_tycon)
-                     && all isTyVarTy arg_tys)
-    then
-       if mod_name == inst_mod
-       then
-               -- Imported instance came from this module;
-               -- discard and derive fresh instance
-           returnTc emptyBag           
-       else
-               -- Imported instance declared in another module;
-               -- report duplicate instance error
-           failTc (derivingWhenInstanceImportedErr inst_mod clas inst_tycon)
-    else
-
        -- Make the dfun id and constant-method ids
-    mkInstanceRelatedIds from_here src_loc inst_mod pragmas
-                        clas inst_tyvars inst_tau inst_theta uprags
-                                       `thenTc` \ (dfun_id, dfun_theta, const_meth_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 dfun_id const_meth_ids
-                               binds from_here inst_mod src_loc uprags))
+                       dfun_theta final_dfun_id
+                               binds src_loc 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)
 \end{code}
 
 
@@ -262,15 +254,15 @@ tcInstDecl1 mod_name
 
 \begin{code}
 tcInstDecls2 :: Bag InstInfo
-            -> NF_TcM s (LIE s, TcHsBinds s)
+            -> NF_TcM s (LIE s, TcMonoBinds s)
 
 tcInstDecls2 inst_decls
-  = foldBag combine tcInstDecl2 (returnNF_Tc (emptyLIE, EmptyBinds)) 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 `ThenBinds` binds2)
+                                  binds1 `AndMonoBinds` binds2)
 \end{code}
 
 
@@ -341,34 +333,44 @@ is the @dfun_theta@ below.
 First comes the easy case of a non-local instance decl.
 
 \begin{code}
-tcInstDecl2 :: InstInfo
-           -> NF_TcM s (LIE s, TcHsBinds s)
-
-tcInstDecl2 (InstInfo _ _ _ _ _ _ _ _ False{-import-} _ _ _)
-  = returnNF_Tc (emptyLIE, EmptyBinds)
+tcInstDecl2 :: InstInfo -> NF_TcM s (LIE s, TcMonoBinds s)
 
 tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
                      inst_decl_theta dfun_theta
-                     dfun_id const_meth_ids monobinds
-                     True{-here-} inst_mod locn uprags)
+                     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, EmptyBinds))  $
-    tcAddSrcLoc locn                                   $
+    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,
-        class_ops, op_sel_ids, defm_ids) = classBigSig clas
+        op_sel_ids, defm_ids) = classBigSig clas
     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' ->
     let
        sc_theta'        = super_classes `zip` repeat inst_ty'
-       origin           = InstanceDeclOrigin
-       mk_method sel_id = newMethod origin (RealId sel_id) [inst_ty']
     in
         -- Create dictionary Ids from the specified instance contexts.
     newDicts origin sc_theta'          `thenNF_Tc` \ (sc_dicts,        sc_dict_ids) ->
@@ -376,40 +378,40 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
     newDicts origin inst_decl_theta'   `thenNF_Tc` \ (inst_decl_dicts, _) ->
     newDicts origin [(clas,inst_ty')]  `thenNF_Tc` \ (this_dict,       [this_dict_id]) ->
 
-        -- Create method variables
-    mapAndUnzipNF_Tc mk_method op_sel_ids      `thenNF_Tc` \ (meth_insts_s, meth_ids) ->
+       -- 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) ->
 
-        -- Collect available Insts
+        -- Check the method bindings
     let
        inst_tyvars_set' = mkTyVarSet inst_tyvars'
-
-       avail_insts      -- These insts are in scope; quite a few, eh?
-         = unionManyBags (this_dict : dfun_arg_dicts : meth_insts_s) 
-
-       mk_method_expr
-         = if opt_OmitDefaultInstanceMethods then
-               makeInstanceDeclNoDefaultExpr     origin meth_ids defm_ids inst_ty' clas inst_mod
-           else
-               makeInstanceDeclDefaultMethodExpr origin meth_ids defm_ids inst_ty' this_dict_id 
+       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
     in
+    mapTc check_from_this_class (bagToList (collectMonoBinders monobinds))     `thenTc_`
     tcExtendGlobalTyVars inst_tyvars_set' (
-       processInstBinds clas mk_method_expr avail_insts meth_ids monobinds
-    )                                  `thenTc` \ (insts_needed, method_mbinds) ->
-    let
-       -- Create the dict and method binds
-       dict_bind
-           = VarMonoBind this_dict_id (Dictionary sc_dict_ids meth_ids)
-
-       dict_and_method_binds
-           = dict_bind `AndMonoBinds` method_mbinds
+        tcExtendGlobalValEnv (catMaybes defm_ids) $
+               -- Default-method Ids may be mentioned in synthesised RHSs 
+       mapAndUnzip3Tc (tcMethodBind clas inst_ty' monobinds) 
+                      (op_sel_ids `zip` defm_ids)
+    )                                  `thenTc` \ (method_binds_s, insts_needed_s, meth_lies_w_ids) ->
 
-    in
        -- Check the overloading constraints of the methods and superclasses
-    tcAddErrCtxt (bindSigCtxt meth_ids) (
-       tcSimplifyAndCheck
+    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
+    in
+    tcAddErrCtxt bindSigCtxt (
+        tcSimplifyAndCheck
                 inst_tyvars_set'                       -- Local tyvars
                 avail_insts
-                (sc_dicts `unionBags` insts_needed)    -- Need to get defns for all these
+                (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,
@@ -417,7 +419,7 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
        -- the check ensures that the caller will never have a problem building
        -- them.
     tcAddErrCtxt superClassSigCtxt (
-    tcSimplifyAndCheck
+        tcSimplifyAndCheck
                 inst_tyvars_set'               -- Local tyvars
                 inst_decl_dicts                -- The instance dictionaries available
                 sc_dicts                       -- The superclass dicationaries reqd
@@ -425,86 +427,22 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
                                                -- Ignore the result; we're only doing
                                                -- this to make sure it can be done.
 
-       -- Now process any SPECIALIZE pragmas for the methods
+       -- Create the result bindings
     let
-       spec_sigs = [ s | s@(SpecSig _ _ _ _) <- uprags ]
-    in
-    tcPragmaSigs spec_sigs             `thenTc` \ (_, spec_binds, spec_lie) ->
-    let
-       -- Complete the binding group, adding any spec_binds
-       inst_binds
+       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
-                ((this_dict_id, RealId dfun_id) 
-                 : (meth_ids `zip` map RealId const_meth_ids))
-                       -- NB: const_meth_ids will often be empty
-                super_binds
-                (RecBind dict_and_method_binds)
-
-           `ThenBinds`
-           spec_binds
+                [(inst_tyvars', RealId dfun_id, this_dict_id)] 
+                (super_binds   `AndMonoBinds` 
+                 method_binds  `AndMonoBinds`
+                 dict_bind)
     in
-
-    returnTc (const_lie `plusLIE` spec_lie, inst_binds)
-\end{code}
-
-The next function makes a default method which calls the global default method, at
-the appropriate instance type.
-
-See the notes under default decls in TcClassDcl.lhs.
-
-\begin{code}
-makeInstanceDeclDefaultMethodExpr
-       :: InstOrigin s
-       -> [TcIdOcc s]
-       -> [Id]
-       -> TcType s
-       -> TcIdOcc s
-       -> Int
-       -> NF_TcM s (TcExpr s)
-
-makeInstanceDeclDefaultMethodExpr origin meth_ids defm_ids inst_ty this_dict tag
-  =
-       -- def_op_id = defm_id inst_ty this_dict
-    returnNF_Tc (mkHsDictApp (mkHsTyApp (HsVar (RealId defm_id)) [inst_ty]) [this_dict])
- where
-    idx            = tag - 1
-    meth_id = meth_ids !! idx
-    defm_id = defm_ids  !! idx
-
-makeInstanceDeclNoDefaultExpr
-       :: InstOrigin s
-       -> [TcIdOcc s]
-       -> [Id]
-       -> TcType s
-       -> Class
-       -> Module
-       -> Int
-       -> NF_TcM s (TcExpr s)
-
-makeInstanceDeclNoDefaultExpr origin meth_ids defm_ids inst_ty clas inst_mod tag
-  = 
-       -- Produce a warning if the default instance method
-       -- has been omitted when one exists in the class
-    warnTc (not err_defm_ok)
-          (omitDefaultMethodWarn clas_op clas_name inst_ty)
-                                       `thenNF_Tc_`
-    returnNF_Tc (HsApp (mkHsTyApp (HsVar (RealId nO_EXPLICIT_METHOD_ERROR_ID)) [tcIdType meth_id])
-                      (HsLitOut (HsString (_PK_ error_msg)) stringTy))
-  where
-    idx            = tag - 1
-    meth_id = meth_ids  !! idx
-    clas_op = (classOps clas) !! idx
-    defm_id = defm_ids  !! idx
-
-    Just (_, _, err_defm_ok) = isDefaultMethodId_maybe defm_id
-
-    error_msg = _UNPK_ inst_mod ++ "." ++ _UNPK_ clas_name ++ "."
-               ++ (ppShow 80 (ppr PprForUser inst_ty)) ++ "."
-               ++ (ppShow 80 (ppr PprForUser clas_op)) ++ "\""
-
-    clas_name = nameOf (origName "makeInstanceDeclNoDefaultExpr" clas)
+    returnTc (const_lie `plusLIE` spec_lie,
+             main_bind `AndMonoBinds` spec_binds)
 \end{code}
 
 
@@ -514,191 +452,69 @@ makeInstanceDeclNoDefaultExpr origin meth_ids defm_ids inst_ty clas inst_mod tag
 %*                                                                     *
 %************************************************************************
 
-@processInstBinds@ returns a @MonoBinds@ which binds
-all the method ids (which are passed in).  It is used
-       - both for instance decls,
-       - and to compile the default-method declarations in a class decl.
-
-Any method ids which don't have a binding have a suitable default
-binding created for them. The actual right-hand side used is
-created using a function which is passed in, because the right thing to
-do differs between instance and class decls.
-
 \begin{code}
-processInstBinds
+tcMethodBind 
        :: Class
-       -> (Int -> NF_TcM s (TcExpr s))    -- Function to make default method
-       -> LIE s                           -- available Insts
-       -> [TcIdOcc s]                     -- Local method ids in tag order
-                                          --   (instance tyvars are free in their types)
-       -> RenamedMonoBinds
-       -> TcM s (LIE s,                   -- These are required
-                 TcMonoBinds s)
-
-processInstBinds clas mk_default_method_rhs avail_insts method_ids monobinds
-  =
-        -- Process the explicitly-given method bindings
-    processInstBinds1 clas avail_insts method_ids monobinds
-                       `thenTc` \ (tags, insts_needed_in_methods, method_binds) ->
-
-        -- Find the methods not handled, and make default method bindings for them.
+       -> 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))
+
+tcMethodBind clas inst_ty meth_binds (sel_id, maybe_dm_id)
+  = newMethod origin (RealId sel_id) [inst_ty] `thenNF_Tc` \ meth@(_, TcId local_meth_id) ->
+    tcInstSigTcType (idType local_meth_id)     `thenNF_Tc` \ (tyvars', rho_ty') ->
     let
-       unmentioned_tags = [1.. length method_ids] `minusList` tags
+       meth_name    = getName local_meth_id
+
+       maybe_meth_bind      = go (getOccName sel_id) meth_binds 
+        (bndr_name, op_bind) = case maybe_meth_bind of
+                                 Just stuff -> stuff
+                                 Nothing    -> (meth_name, mk_default_bind meth_name)
+
+       (theta', tau')  = splitRhoTy rho_ty'
+       sig_info        = TySigInfo bndr_name local_meth_id tyvars' theta' tau' noSrcLoc
     in
-    mapNF_Tc mk_default_method unmentioned_tags
-                       `thenNF_Tc` \ default_bind_list ->
 
-    returnTc (insts_needed_in_methods,
-             foldr AndMonoBinds method_binds default_bind_list)
+       -- Warn if no method binding
+    warnTc (not (maybeToBool maybe_meth_bind) && not (maybeToBool maybe_dm_id))        
+          (omittedMethodWarn sel_id clas)              `thenNF_Tc_`
+
+    tcBindWithSigs [bndr_name] op_bind [sig_info]
+                  nonRecursive (\_ -> NoPragmaInfo)    `thenTc` \ (binds, insts, _) ->
+
+    returnTc (binds, insts, meth)
   where
-       -- From a tag construct us the passed-in function to construct
-       -- the binding for the default method
-    mk_default_method tag = mk_default_method_rhs tag  `thenNF_Tc` \ rhs ->
-                           returnNF_Tc (VarMonoBind (method_ids !! (tag-1)) rhs)
-\end{code}
+    origin = InstanceDeclOrigin        -- Poor
 
-\begin{code}
-processInstBinds1
-       :: Class
-       -> LIE s                -- available Insts
-       -> [TcIdOcc s]          -- Local method ids in tag order (instance tyvars are free),
-       -> RenamedMonoBinds
-       -> TcM s ([Int],        -- Class-op tags accounted for
-                 LIE s,        -- These are required
-                 TcMonoBinds s)
-
-processInstBinds1 clas avail_insts method_ids EmptyMonoBinds
-  = returnTc ([], emptyLIE, EmptyMonoBinds)
-
-processInstBinds1 clas avail_insts method_ids (AndMonoBinds mb1 mb2)
-  = processInstBinds1 clas avail_insts method_ids mb1
-                                `thenTc`       \ (op_tags1,dicts1,method_binds1) ->
-    processInstBinds1 clas avail_insts method_ids mb2
-                                `thenTc`       \ (op_tags2,dicts2,method_binds2) ->
-    returnTc (op_tags1 ++ op_tags2,
-             dicts1 `unionBags` dicts2,
-             AndMonoBinds method_binds1 method_binds2)
-\end{code}
+    go occ EmptyMonoBinds      = Nothing
+    go occ (AndMonoBinds b1 b2) = go occ b1 `seqMaybe` go occ b2
 
-\begin{code}
-processInstBinds1 clas avail_insts method_ids mbind
-  =
-    -- Find what class op is being defined here.  The complication is
-    -- that we could have a PatMonoBind or a FunMonoBind.  If the
-    -- former, it should only bind a single variable, or else we're in
-    -- trouble (I'm not sure what the static semantics of methods
-    -- defined in a pattern binding with multiple patterns is!)
-    -- Renamer has reduced us to these two cases.
-    let
-       (op,locn) = case mbind of
-                     FunMonoBind op _ _ locn          -> (op, locn)
-                     PatMonoBind (VarPatIn op) _ locn -> (op, locn)
+    go occ b@(FunMonoBind op_name _ _ locn)          | nameOccName op_name == occ = Just (op_name, b)
+                                                    | otherwise                  = Nothing
+    go occ b@(PatMonoBind (VarPatIn op_name) _ locn) | nameOccName op_name == occ = Just (op_name, b)
+                                                    | otherwise                  = Nothing
+    go occ other = panic "Urk! Bad instance method binding"
 
-        occ    = getLocalName op
-       origin = InstanceDeclOrigin
-    in
-    tcAddSrcLoc locn                    $
 
-    -- Make a method id for the method
-    let
-       tag       = classOpTagByString clas occ
-       method_id = method_ids !! (tag-1)
-       method_ty = tcIdType method_id
-    in
+    mk_default_bind local_meth_name
+      = PatMonoBind (VarPatIn local_meth_name)
+                   (GRHSsAndBindsIn [OtherwiseGRHS default_expr noSrcLoc] EmptyBinds)
+                   noSrcLoc
 
-    tcInstTcType method_ty             `thenNF_Tc` \ (method_tyvars, method_rho) ->
-    let
-       (method_theta, method_tau) = splitRhoTy method_rho
-    in
-    newDicts origin method_theta       `thenNF_Tc` \ (method_dicts,method_dict_ids) ->
-
-    case (method_tyvars, method_dict_ids) of
-
-      ([],[]) -> -- The simple case; no local polymorphism or overloading in the method
-
-               -- Type check the method itself
-       tcMethodBind method_id method_tau mbind `thenTc` \ (mbind', lieIop) ->
-       returnTc ([tag], lieIop, mbind')
-
-      other -> -- It's a locally-polymorphic and/or overloaded method; UGH!
-
-               -- Make a new id for (a) the local, non-overloaded method
-               -- and               (b) the locally-overloaded method
-               -- The latter is needed just so we can return an AbsBinds wrapped
-               -- up inside a MonoBinds.
-
-
-               -- Make the method_tyvars into signature tyvars so they
-               -- won't get unified with anything.
-       tcInstSigTyVars method_tyvars           `thenNF_Tc` \ (sig_tyvars, sig_tyvar_tys, _) ->
-       unifyTauTyLists (mkTyVarTys method_tyvars) sig_tyvar_tys        `thenTc_`
-
-       newLocalId occ method_tau               `thenNF_Tc` \ local_id ->
-       newLocalId occ method_ty                `thenNF_Tc` \ copy_id ->
-       let
-           sig_tyvar_set = mkTyVarSet sig_tyvars
-       in
-               -- Typecheck the method
-       tcMethodBind local_id method_tau mbind `thenTc` \ (mbind', lieIop) ->
-
-               -- Check the overloading part of the signature.
-
-       -- =========== POSSIBLE BUT NOT DONE =================
-               -- Simplify everything fully, even though some
-               -- constraints could "really" be left to the next
-               -- level out. The case which forces this is
-               --
-               --      class Foo a where { op :: Bar a => a -> a }
-               --
-               -- Here we must simplify constraints on "a" to catch all
-               -- the Bar-ish things.
-
-               -- We don't do this because it's currently illegal Haskell (not sure why),
-               -- and because the local type of the method would have a context at
-               -- the front with no for-all, which confuses the hell out of everything!
-       -- ====================================================
-
-       tcAddErrCtxt (methodSigCtxt op method_ty) (
-           checkSigTyVars
-               sig_tyvars method_tau                           `thenTc_`
-
-         tcSimplifyAndCheck
-               sig_tyvar_set
-               (method_dicts `plusLIE` avail_insts)
-               lieIop
-       )                                        `thenTc` \ (f_dicts, dict_binds) ->
-
-
-       returnTc ([tag],
-                 f_dicts,
-                 VarMonoBind method_id
-                        (HsLet
-                            (AbsBinds
-                               method_tyvars
-                               method_dict_ids
-                               [(local_id, copy_id)]
-                               dict_binds
-                               (NonRecBind mbind'))
-                            (HsVar copy_id)))
-\end{code}
+    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
 
-\begin{code}
-tcMethodBind :: TcIdOcc s -> TcType s -> RenamedMonoBinds
-            -> TcM s (TcMonoBinds s, LIE s)
-
-tcMethodBind meth_id meth_ty (FunMonoBind name inf matches locn)
-  = tcMatchesFun name meth_ty matches `thenTc` \ (rhs', lie) ->
-    returnTc (FunMonoBind meth_id inf rhs' locn, lie)
-
-tcMethodBind meth_id meth_ty pbind@(PatMonoBind pat grhss_and_binds locn)
-  -- pat is sure to be a (VarPatIn op)
-  = tcAddErrCtxt (patMonoBindsCtxt pbind) $
-    tcGRHSsAndBinds grhss_and_binds    `thenTc` \ (grhss_and_binds', lie, rhs_ty) ->
-    unifyTauTy meth_ty rhs_ty          `thenTc_`
-    returnTc (PatMonoBind (VarPat meth_id) grhss_and_binds' locn, lie)
+    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}
@@ -740,7 +556,7 @@ tcSpecInstSig e ce tce inst_infos inst_mapper (SpecInstSig class_name ty src_loc
        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                          = extractMonoTyNames ???is_tyvarish_name??? ty
+       ty_names                          = extractHsTyNames ???is_tyvarish_name??? ty
        (tmpl_e,inst_tmpls,inst_tmpl_tys) = mkTVE ty_names
     in
     babyTcMtoTcM (tcInstanceType ce tce tmpl_e True src_loc ty)
@@ -760,7 +576,7 @@ tcSpecInstSig e ce tce inst_infos inst_mapper (SpecInstSig class_name ty src_loc
     copyTyVars inst_tmpls      `thenNF_Tc` \ (tv_e, inst_tvs, inst_tv_tys) ->
     let
        Just (InstInfo _ unspec_tyvars unspec_inst_ty unspec_theta
-                      _ _ _ binds True{-from here-} mod _ uprag) = maybe_unspec_inst
+                      _ _ binds _ uprag) = maybe_unspec_inst
 
        subst = case matchTy unspec_inst_ty inst_ty of
                     Just subst -> subst
@@ -783,27 +599,27 @@ tcSpecInstSig e ce tce inst_infos inst_mapper (SpecInstSig class_name ty src_loc
        tv_tmpl_map   = zipEqual "tcSpecInstSig" inst_tv_tys inst_tmpl_tys
        tv_to_tmpl tv = assoc "tcSpecInstSig" tv_tmpl_map tv
     in
-    mkInstanceRelatedIds e True{-from here-} src_loc mod NoInstancePragmas 
+    mkInstanceRelatedIds 
                         clas inst_tmpls inst_ty simpl_theta uprag
-                               `thenTc` \ (dfun_id, dfun_theta, const_meth_ids) ->
+                               `thenNF_Tc` \ (dfun_id, dfun_theta, const_meth_ids) ->
 
     getSwitchCheckerTc         `thenNF_Tc` \ sw_chkr ->
     (if sw_chkr SpecialiseTrace then
        pprTrace "Specialised Instance: "
-       (ppAboves [ppCat [if null simpl_theta then ppNil else ppr PprDebug simpl_theta,
-                         if null simpl_theta then ppNil else ppStr "=>",
+       (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],
-                  ppCat [ppStr "        derived from:",
-                         if null unspec_theta then ppNil else ppr PprDebug unspec_theta,
-                         if null unspec_theta then ppNil else ppStr "=>",
+                  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 const_meth_ids
-                               binds True{-from here-} mod src_loc uprag))
+                               dfun_theta dfun_id
+                               binds src_loc uprag))
     )))
 
 
@@ -849,18 +665,19 @@ compiled elsewhere). In these cases, we let them go through anyway.
 We can also have instances for functions: @instance Foo (a -> b) ...@.
 
 \begin{code}
-scrutiniseInstanceType from_here clas inst_tau
+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 from_here
+  | not (isLocallyDefined dfun_name)
   = returnTc (inst_tycon,arg_tys)
 
        -- TYVARS CHECK
-  | not (all isTyVarTy arg_tys ||
-        opt_GlasgowExts)
+  | not (opt_GlasgowExts ||
+        (all isTyVarTy arg_tys && null tyvar_dups)
+    )
   = failTc (instTypeErr inst_tau)
 
        -- DERIVING CHECK
@@ -868,73 +685,101 @@ scrutiniseInstanceType from_here clas inst_tau
        -- 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 `derivedFor` inst_tycon
+  | 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.
-    isCcallishClass clas
-    && not (maybeToBool (maybeBoxedPrimType inst_tau)
-           || opt_CompilingGhcInternals) -- this lets us get up to mischief;
-                                    -- e.g., instance CCallable ()
+    (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) = splitAppTy inst_tau
+    (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}
 
 \begin{code}
 
 instTypeErr ty sty
   = case ty of
-      SynTy tc _ _ -> ppBesides [ppStr "The type synonym `", ppr sty tc, rest_of_msg]
-      TyVarTy tv   -> ppBesides [ppStr "The type variable `", ppr sty tv, rest_of_msg]
-      other       -> ppBesides [ppStr "The type `", ppr sty ty, rest_of_msg]
+      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]
   where
-    rest_of_msg = ppStr "' cannot be used as an instance type."
+    rest_of_msg = ptext SLIT("cannot be used as an instance type")
 
-derivingWhenInstanceExistsErr clas tycon sty
-  = ppHang (ppBesides [ppStr "Deriving class `", ppr sty clas, ppStr "' type `", ppr sty tycon, ppStr "'"])
-         4 (ppStr "when an explicit instance exists")
+instBndrErr bndr clas sty
+  = hsep [ptext SLIT("Class"), ppr sty clas, ptext SLIT("does not have a method"), ppr sty bndr]
 
-derivingWhenInstanceImportedErr inst_mod clas tycon sty
-  = ppHang (ppBesides [ppStr "Deriving class `", ppr sty clas, ppStr "' type `", ppr sty tycon, ppStr "'"])
-         4 (ppBesides [ppStr "when an instance declared in module `", pp_mod, ppStr "' has been imported"])
-  where
-    pp_mod = ppBesides [ppStr "module `", ppPStr inst_mod, ppStr "'"]
+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
-  = ppHang (ppStr "Instance isn't for a `boxed-primitive' type")
-        4 (ppBesides [ ppStr "class `", ppr sty clas, ppStr "' type `",
-                       ppr sty inst_ty, ppStr "'"])
+  = 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])
 
-omitDefaultMethodWarn clas_op clas_name inst_ty sty
-  = ppCat [ppStr "Warning: Omitted default method for",
-          ppr sty clas_op, ppStr "in instance",
-          ppPStr clas_name, pprParendGenType sty inst_ty]
+omittedMethodWarn sel_id clas sty
+  = sep [ptext SLIT("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
-  = ppHang (ppStr "In a pattern binding:")
+  = hang (ptext SLIT("In a pattern binding:"))
         4 (ppr sty pbind)
 
 methodSigCtxt name ty sty
-  = ppHang (ppBesides [ppStr "When matching the definition of class method `",
-                      ppr sty name, ppStr "' to its signature :" ])
+  = hang (hsep [ptext SLIT("When matching the definition of class method"),
+                      ppr sty name, ptext SLIT("to its signature :") ])
         4 (ppr sty ty)
 
-bindSigCtxt method_ids sty
-  = ppHang (ppStr "When checking type signatures for: ")
-        4 (ppInterleave (ppStr ", ") (map (ppr sty) method_ids))
+bindSigCtxt sty
+  = ptext SLIT("When checking methods of an instance declaration")
 
 superClassSigCtxt sty
-  = ppStr "When checking superclass constraints on instance declaration"
-
+  = ptext SLIT("When checking superclass constraints of an instance declaration")
 \end{code}