Simon's big boxy-type commit
[ghc-hetmet.git] / ghc / compiler / typecheck / TcEnv.lhs
index 5b760ac..497ba23 100644 (file)
@@ -3,8 +3,8 @@ module TcEnv(
        TyThing(..), TcTyThing(..), TcId,
 
        -- Instance environment, and InstInfo type
-       InstInfo(..), pprInstInfo, pprInstInfoDetails,
-       simpleInstInfoTy, simpleInstInfoTyCon, 
+       InstInfo(..), iDFunId, pprInstInfo, pprInstInfoDetails,
+       simpleInstInfoClsTy, simpleInstInfoTy, simpleInstInfoTyCon, 
        InstBindings(..),
 
        -- Global environment
@@ -13,17 +13,17 @@ module TcEnv(
        tcLookupLocatedGlobal,  tcLookupGlobal, 
        tcLookupGlobalId, tcLookupTyCon, tcLookupClass, tcLookupDataCon,
        tcLookupLocatedGlobalId, tcLookupLocatedTyCon,
-       tcLookupLocatedClass, tcLookupLocatedDataCon,
+       tcLookupLocatedClass, 
        
-       getInGlobalScope,
-
        -- Local environment
-       tcExtendTyVarKindEnv,
-       tcExtendTyVarEnv,    tcExtendTyVarEnv2, 
-       tcExtendLocalValEnv, tcExtendLocalValEnv2, 
-       tcLookup, tcLookupLocated, tcLookupLocalIds,
-       tcLookupId, tcLookupTyVar,
+       tcExtendKindEnv, tcExtendKindEnvTvs,
+       tcExtendTyVarEnv, tcExtendTyVarEnv2, 
+       tcExtendIdEnv, tcExtendIdEnv1, tcExtendIdEnv2, 
+       tcLookup, tcLookupLocated, tcLookupLocalIds, tcLookupLocalId_maybe,
+       tcLookupId, tcLookupTyVar, getScopedTyVarBinds,
        lclEnvElts, getInLocalScope, findGlobals, 
+       wrongThingErr, pprBinders,
+       refineEnvironment,
 
        tcExtendRecEnv,         -- For knot-tying
 
@@ -37,44 +37,43 @@ module TcEnv(
        checkWellStaged, spliceOK, bracketOK, tcMetaTy, thLevel, 
        topIdLvl, 
 
-       -- Arrow stuff
-       checkProcLevel,
-
        -- New Ids
        newLocalName, newDFunName
   ) where
 
 #include "HsVersions.h"
 
-import HsSyn           ( LRuleDecl, , HsTyVarBndr(..), LHsTyVarBndr, LHsBinds,
-                         LSig )
+import HsSyn           ( LRuleDecl, LHsBinds, LSig, 
+                         LHsTyVarBndr, HsTyVarBndr(..), pprLHsBinds )
 import TcIface         ( tcImportDecl )
+import IfaceEnv                ( newGlobalBinder )
 import TcRnMonad
-import TcMType         ( zonkTcType, zonkTcTyVar, zonkTcTyVarsAndFV )
-import TcType          ( Type, TcTyVar, TcTyVarSet, 
-                         tyVarsOfType, tyVarsOfTypes, tcSplitDFunTy, mkGenTyConApp,
-                         getDFunTyKey, tcTyConAppTyCon, tyVarBindingInfo, 
-                         tidyOpenType, tidyOpenTyVar
+import TcMType         ( zonkTcType, zonkTcTyVarsAndFV )
+import TcType          ( Type, TcKind, TcTyVar, TcTyVarSet, TcType, TvSubst,
+                         substTy, substTyVar, tyVarsOfType, tcTyVarsOfTypes, mkTyConApp,
+                         getDFunTyKey, tcTyConAppTyCon, tcGetTyVar, mkTyVarTy,
+                         tidyOpenType, isRefineableTy
                        )
 import qualified Type  ( getTyVar_maybe )
-import Id              ( idName, isLocalId )
-import Var             ( TyVar, Id, mkTyVar, idType )
+import Id              ( idName, isLocalId, setIdType )
+import Var             ( TyVar, Id, idType, tyVarName )
 import VarSet
 import VarEnv
 import RdrName         ( extendLocalRdrEnv )
+import InstEnv         ( Instance, DFunId, instanceDFunId, instanceHead )
 import DataCon         ( DataCon )
 import TyCon           ( TyCon )
 import Class           ( Class )
-import Name            ( Name, NamedThing(..), getSrcLoc, mkInternalName, nameIsLocalOrFrom )
+import Name            ( Name, NamedThing(..), getSrcLoc, nameModule, isExternalName )
+import PrelNames       ( thFAKE )
 import NameEnv
 import OccName         ( mkDFunOcc, occNameString )
-import HscTypes                ( DFunId, extendTypeEnvList, lookupType,
-                         TyThing(..), tyThingId, tyThingTyCon, tyThingClass, tyThingDataCon,
+import HscTypes                ( extendTypeEnvList, lookupType,
+                         TyThing(..), tyThingId, tyThingDataCon,
                          ExternalPackageState(..) )
 
 import SrcLoc          ( SrcLoc, Located(..) )
 import Outputable
-import Maybe           ( isJust )
 \end{code}
 
 
@@ -95,26 +94,33 @@ tcLookupLocatedGlobal name
   = addLocM tcLookupGlobal name
 
 tcLookupGlobal :: Name -> TcM TyThing
+-- The Name is almost always an ExternalName, but not always
+-- In GHCi, we may make command-line bindings (ghci> let x = True)
+-- that bind a GlobalId, but with an InternalName
 tcLookupGlobal name
   = do { env <- getGblEnv
-       ; if nameIsLocalOrFrom (tcg_mod env) name
-
-         then  -- It's defined in this module
-             case lookupNameEnv (tcg_type_env env) name of
-               Just thing -> return thing
-               Nothing    -> notFound "tcLookupGlobal" name
+       
+               -- Try local envt
+       ; case lookupNameEnv (tcg_type_env env) name of {
+               Just thing -> return thing ;
+               Nothing    -> do 
         
-         else do               -- It's imported
-       { eps <- getEps
-       ; hpt <- getHpt
-       ; case lookupType hpt (eps_PTE eps) name of 
-           Just thing -> return thing 
-           Nothing    -> do { traceIf (text "tcLookupGlobal" <+> ppr name)
-                            ; initIfaceTcRn (tcImportDecl name) }
-    }}
-\end{code}
+               -- Try global envt
+       { (eps,hpt) <- getEpsAndHpt
+       ; case lookupType hpt (eps_PTE eps) name of  {
+           Just thing -> return thing ;
+           Nothing    -> do
+
+               -- Should it have been in the local envt?
+       { let mod = nameModule name
+       ; if mod == tcg_mod env || mod == thFAKE then
+               notFound name   -- It should be local, so panic
+                               -- The thFAKE possibility is because it
+                               -- might be in a declaration bracket
+         else
+               tcImportDecl name       -- Go find it in an interface
+       }}}}}
 
-\begin{code}
 tcLookupGlobalId :: Name -> TcM Id
 -- Never used for Haskell-source DataCons, hence no ADataCon case
 tcLookupGlobalId name
@@ -129,19 +135,20 @@ tcLookupDataCon con_name
 tcLookupClass :: Name -> TcM Class
 tcLookupClass name
   = tcLookupGlobal name                `thenM` \ thing ->
-    return (tyThingClass thing)
+    case thing of
+       AClass cls -> return cls
+       other      -> wrongThingErr "class" (AGlobal thing) name
        
 tcLookupTyCon :: Name -> TcM TyCon
 tcLookupTyCon name
   = tcLookupGlobal name                `thenM` \ thing ->
-    return (tyThingTyCon thing)
+    case thing of
+       ATyCon tc -> return tc
+       other     -> wrongThingErr "type constructor" (AGlobal thing) name
 
 tcLookupLocatedGlobalId :: Located Name -> TcM Id
 tcLookupLocatedGlobalId = addLocM tcLookupId
 
-tcLookupLocatedDataCon :: Located Name -> TcM DataCon
-tcLookupLocatedDataCon = addLocM tcLookupDataCon
-
 tcLookupLocatedClass :: Located Name -> TcM Class
 tcLookupLocatedClass = addLocM tcLookupClass
 
@@ -171,33 +178,14 @@ tcExtendGlobalValEnv ids thing_inside
   = tcExtendGlobalEnv [AnId id | id <- ids] thing_inside
 \end{code}
 
-A variety of global lookups, when we know what we are looking for.
-
 \begin{code}
-getInGlobalScope :: TcM (Name -> Bool)
--- Get all things in the global environment; used for deciding what 
--- rules to suck in.  Anything defined in this module (nameIsLocalOrFrom)
--- is certainly in the envt, so we don't bother to look.
-getInGlobalScope 
-  = do { mod <- getModule
-       ; eps <- getEps
-       ; hpt <- getHpt
-       ; return (\n -> nameIsLocalOrFrom mod n || 
-                      isJust (lookupType hpt (eps_PTE eps) n)) }
-\end{code}
-
-
-\begin{code}
-tcExtendRecEnv :: [(Name,TyThing)]     -- Global bindings
-              -> [(Name,TcTyThing)]    -- Local bindings
-              -> TcM r -> TcM r
--- Extend both local and global environments for the type/class knot tying game
-tcExtendRecEnv gbl_stuff lcl_stuff thing_inside
- = do { (gbl_env, lcl_env) <- getEnvs
-      ; let { ge' = extendNameEnvList (tcg_type_env gbl_env) gbl_stuff
-           ; le' = extendNameEnvList (tcl_env lcl_env)      lcl_stuff }
-      ; setEnvs (gbl_env {tcg_type_env = ge'}, lcl_env {tcl_env = le'}) 
-               thing_inside }
+tcExtendRecEnv :: [(Name,TyThing)] -> TcM r -> TcM r
+-- Extend the global environments for the type/class knot tying game
+tcExtendRecEnv gbl_stuff thing_inside
+ = updGblEnv upd thing_inside
+ where
+   upd env = env { tcg_type_env = extend (tcg_type_env env) }
+   extend env = extendNameEnvList env gbl_stuff
 \end{code}
 
 
@@ -219,12 +207,12 @@ tcLookup name
        Nothing    -> tcLookupGlobal name `thenM` \ thing ->
                      returnM (AGlobal thing)
 
-tcLookupTyVar :: Name -> TcM Id
+tcLookupTyVar :: Name -> TcM TcTyVar
 tcLookupTyVar name
   = tcLookup name      `thenM` \ thing -> 
     case thing of
-       ATyVar tv -> returnM tv
-       other     -> pprPanic "tcLookupTyVar" (ppr name)
+       ATyVar _ ty -> return (tcGetTyVar "tcLookupTyVar" ty)
+       other       -> pprPanic "tcLookupTyVar" (ppr name)
 
 tcLookupId :: Name -> TcM Id
 -- Used when we aren't interested in the binding level
@@ -236,6 +224,13 @@ tcLookupId name
        AGlobal (AnId id) -> returnM id
        other             -> pprPanic "tcLookupId" (ppr name)
 
+tcLookupLocalId_maybe :: Name -> TcM (Maybe Id)
+tcLookupLocalId_maybe name
+  = getLclEnv          `thenM` \ local_env ->
+    case lookupNameEnv (tcl_env local_env) name of
+       Just (ATcId tc_id _ _) -> return (Just tc_id)
+       other                  -> return Nothing
+
 tcLookupLocalIds :: [Name] -> TcM [TcId]
 -- We expect the variables to all be bound, and all at
 -- the same level as the lookup.  Only used in one place...
@@ -261,34 +256,34 @@ getInLocalScope = getLclEnv       `thenM` \ env ->
 \end{code}
 
 \begin{code}
-tcExtendTyVarKindEnv :: [LHsTyVarBndr Name] -> TcM r -> TcM r
--- The tyvars are all kinded
-tcExtendTyVarKindEnv tvs thing_inside
+tcExtendKindEnv :: [(Name, TcKind)] -> TcM r -> TcM r
+tcExtendKindEnv things thing_inside
   = updLclEnv upd thing_inside
   where
     upd lcl_env = lcl_env { tcl_env = extend (tcl_env lcl_env) }
-    extend env  = extendNameEnvList env [(n, ATyVar (mkTyVar n k)) 
-                                       | L _ (KindedTyVar n k) <- tvs]
-       -- No need to extend global tyvars for kind checking
+    extend env  = extendNameEnvList env [(n, AThing k) | (n,k) <- things]
+
+tcExtendKindEnvTvs :: [LHsTyVarBndr Name] -> TcM r -> TcM r
+tcExtendKindEnvTvs bndrs thing_inside
+  = updLclEnv upd thing_inside
+  where
+    upd lcl_env = lcl_env { tcl_env = extend (tcl_env lcl_env) }
+    extend env  = extendNameEnvList env pairs
+    pairs       = [(n, AThing k) | L _ (KindedTyVar n k) <- bndrs]
 
 tcExtendTyVarEnv :: [TyVar] -> TcM r -> TcM r
 tcExtendTyVarEnv tvs thing_inside
-  = tc_extend_tv_env [(getName tv, ATyVar tv) | tv <- tvs] tvs thing_inside
-
-tcExtendTyVarEnv2 :: [(TyVar,TcTyVar)] -> TcM r -> TcM r
-tcExtendTyVarEnv2 tv_pairs thing_inside
-  = tc_extend_tv_env [(getName tv1, ATyVar tv2) | (tv1,tv2) <- tv_pairs]
-                    [tv | (_,tv) <- tv_pairs]
-                    thing_inside
+  = tcExtendTyVarEnv2 [(tyVarName tv, mkTyVarTy tv) | tv <- tvs] thing_inside
 
-tc_extend_tv_env binds tyvars thing_inside
+tcExtendTyVarEnv2 :: [(Name,TcType)] -> TcM r -> TcM r
+tcExtendTyVarEnv2 binds thing_inside
   = getLclEnv     `thenM` \ env@(TcLclEnv {tcl_env = le, 
                                            tcl_tyvars = gtvs, 
                                            tcl_rdr = rdr_env}) ->
     let
-       le'        = extendNameEnvList le binds
        rdr_env'   = extendLocalRdrEnv rdr_env (map fst binds)
-       new_tv_set = mkVarSet tyvars
+       new_tv_set = tcTyVarsOfTypes (map snd binds)
+       le'        = extendNameEnvList le [(name, ATyVar name ty) | (name, ty) <- binds]
     in
        -- It's important to add the in-scope tyvars to the global tyvar set
        -- as well.  Consider
@@ -298,37 +293,44 @@ tc_extend_tv_env binds tyvars thing_inside
        -- when typechecking the methods.
     tc_extend_gtvs gtvs new_tv_set             `thenM` \ gtvs' ->
     setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs', tcl_rdr = rdr_env'}) thing_inside
+
+getScopedTyVarBinds :: TcM [(Name, TcType)]
+getScopedTyVarBinds
+  = do { lcl_env <- getLclEnv
+       ; return [(name, ty) | ATyVar name ty <- nameEnvElts (tcl_env lcl_env)] }
 \end{code}
 
 
 \begin{code}
-tcExtendLocalValEnv :: [TcId] -> TcM a -> TcM a
-tcExtendLocalValEnv ids thing_inside
-  = getLclEnv          `thenM` \ env ->
-    let
-       extra_global_tyvars = tyVarsOfTypes [idType id | id <- ids]
-       th_lvl              = thLevel (tcl_th_ctxt env)
-       proc_lvl            = proc_level (tcl_arrow_ctxt env)
-       extra_env           = [(idName id, ATcId id th_lvl proc_lvl) | id <- ids]
-       le'                 = extendNameEnvList (tcl_env env) extra_env
-       rdr_env'            = extendLocalRdrEnv (tcl_rdr env) (map idName ids)
-    in
-    tc_extend_gtvs (tcl_tyvars env) extra_global_tyvars        `thenM` \ gtvs' ->
-    setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs', tcl_rdr = rdr_env'}) thing_inside
-
-tcExtendLocalValEnv2 :: [(Name,TcId)] -> TcM a -> TcM a
-tcExtendLocalValEnv2 names_w_ids thing_inside
+tcExtendIdEnv :: [TcId] -> TcM a -> TcM a
+-- Invariant: the TcIds are fully zonked. Reasons:
+--     (a) The kinds of the forall'd type variables are defaulted
+--         (see Kind.defaultKind, done in zonkQuantifiedTyVar)
+--     (b) There are no via-Indirect occurrences of the bound variables
+--         in the types, because instantiation does not look through such things
+--     (c) The call to tyVarsOfTypes is ok without looking through refs
+tcExtendIdEnv ids thing_inside = tcExtendIdEnv2 [(idName id, id) | id <- ids] thing_inside
+
+tcExtendIdEnv1 :: Name -> TcId -> TcM a -> TcM a
+tcExtendIdEnv1 name id thing_inside = tcExtendIdEnv2 [(name,id)] thing_inside
+
+tcExtendIdEnv2 :: [(Name,TcId)] -> TcM a -> TcM a
+-- Invariant: the TcIds are fully zonked (see tcExtendIdEnv above)
+tcExtendIdEnv2 names_w_ids thing_inside
   = getLclEnv          `thenM` \ env ->
     let
-       extra_global_tyvars = tyVarsOfTypes [idType id | (name,id) <- names_w_ids]
-       th_lvl              = thLevel    (tcl_th_ctxt   env)
-       proc_lvl            = proc_level (tcl_arrow_ctxt env)
-       extra_env           = [(name, ATcId id th_lvl proc_lvl) | (name,id) <- names_w_ids]
+       extra_global_tyvars = tcTyVarsOfTypes [idType id | (_,id) <- names_w_ids]
+       th_lvl              = thLevel (tcl_th_ctxt   env)
+       extra_env           = [ (name, ATcId id th_lvl (isRefineableTy (idType id)))
+                             | (name,id) <- names_w_ids]
        le'                 = extendNameEnvList (tcl_env env) extra_env
-       rdr_env'            = extendLocalRdrEnv (tcl_rdr env) (map fst names_w_ids)
+       rdr_env'            = extendLocalRdrEnv (tcl_rdr env) [name | (name,_) <- names_w_ids]
     in
+    traceTc (text "env2") `thenM_`
+    traceTc (text "env3" <+> ppr extra_env) `thenM_`
     tc_extend_gtvs (tcl_tyvars env) extra_global_tyvars        `thenM` \ gtvs' ->
-    setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs', tcl_rdr = rdr_env'}) thing_inside
+    (traceTc (text "env4") `thenM_`
+    setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs', tcl_rdr = rdr_env'}) thing_inside)
 \end{code}
 
 
@@ -369,25 +371,36 @@ find_thing ignore_it tidy_env (ATcId id _ _)
     in
     returnM (tidy_env', Just msg)
 
-find_thing ignore_it tidy_env (ATyVar tv)
-  = zonkTcTyVar tv             `thenM` \ tv_ty ->
+find_thing ignore_it tidy_env (ATyVar tv ty)
+  = zonkTcType ty              `thenM` \ tv_ty ->
     if ignore_it tv_ty then
        returnM (tidy_env, Nothing)
     else let
-       (tidy_env1, tv1)     = tidyOpenTyVar tidy_env  tv
-       (tidy_env2, tidy_ty) = tidyOpenType  tidy_env1 tv_ty
-       msg = sep [ppr tv1 <+> eq_stuff, nest 2 bound_at]
+       -- The name tv is scoped, so we don't need to tidy it
+       (tidy_env1, tidy_ty) = tidyOpenType  tidy_env tv_ty
+       msg = sep [ptext SLIT("Scoped type variable") <+> quotes (ppr tv) <+> eq_stuff, nest 2 bound_at]
 
        eq_stuff | Just tv' <- Type.getTyVar_maybe tv_ty, 
-                  tv == tv' = empty
+                  getOccName tv == getOccName tv' = empty
                 | otherwise = equals <+> ppr tidy_ty
                -- It's ok to use Type.getTyVar_maybe because ty is zonked by now
-       
-       bound_at = tyVarBindingInfo tv
+       bound_at = parens $ ptext SLIT("bound at:") <+> ppr (getSrcLoc tv)
     in
-    returnM (tidy_env2, Just msg)
+    returnM (tidy_env1, Just msg)
 \end{code}
 
+\begin{code}
+refineEnvironment :: TvSubst -> TcM a -> TcM a
+refineEnvironment reft thing_inside
+  = do { env <- getLclEnv
+       ; let le' = mapNameEnv refine (tcl_env env)
+       ; gtvs' <- refineGlobalTyVars reft (tcl_tyvars env) 
+       ; setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs'}) thing_inside }
+  where
+    refine (ATcId id lvl True) = ATcId (setIdType id (substTy reft (idType id))) lvl True
+    refine (ATyVar tv ty)      = ATyVar tv (substTy reft ty)
+    refine elt                = elt
+\end{code}
 
 %************************************************************************
 %*                                                                     *
@@ -399,6 +412,11 @@ find_thing ignore_it tidy_env (ATyVar tv)
 tc_extend_gtvs gtvs extra_global_tvs
   = readMutVar gtvs            `thenM` \ global_tvs ->
     newMutVar (global_tvs `unionVarSet` extra_global_tvs)
+
+refineGlobalTyVars :: GadtRefinement -> TcRef TcTyVarSet -> TcM (TcRef TcTyVarSet)
+refineGlobalTyVars reft gtv_var
+  = readMutVar gtv_var                         `thenM` \ gbl_tvs ->
+    newMutVar (tcTyVarsOfTypes (map (substTyVar reft) (varSetElems gbl_tvs)))
 \end{code}
 
 @tcGetGlobalTyVars@ returns a fully-zonked set of tyvars free in the environment.
@@ -438,25 +456,6 @@ tcExtendRules lcl_rules thing_inside
 
 %************************************************************************
 %*                                                                     *
-               Arrow notation proc levels
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-checkProcLevel :: TcId -> ProcLevel -> TcM ()
-checkProcLevel id id_lvl
-  = do { banned <- getBannedProcLevels
-       ; checkTc (not (id_lvl `elem` banned))
-                 (procLevelErr id id_lvl) }
-
-procLevelErr id id_lvl
-  = hang (ptext SLIT("Command-bound variable") <+> quotes (ppr id) <+> ptext SLIT("is not in scope here"))
-        4 (ptext SLIT("Reason: it is used in the left argument of (-<)"))
-\end{code}
-               
-
-%************************************************************************
-%*                                                                     *
                Meta level
 %*                                                                     *
 %************************************************************************
@@ -499,7 +498,7 @@ checkWellStaged pp_thing bind_lvl use_stage
 topIdLvl :: Id -> ThLevel
 -- Globals may either be imported, or may be from an earlier "chunk" 
 -- (separated by declaration splices) of this module.  The former
--- *can* be used inside a top-level splice, but the latter cannot.
+--  *can* be used inside a top-level splice, but the latter cannot.
 -- Hence we give the former impLevel, but the latter topLevel
 -- E.g. this is bad:
 --     x = [| foo |]
@@ -512,7 +511,7 @@ topIdLvl id | isLocalId id = topLevel
 -- Indicates the legal transitions on bracket( [| |] ).
 bracketOK :: ThStage -> Maybe ThLevel
 bracketOK (Brack _ _ _) = Nothing      -- Bracket illegal inside a bracket
-bracketOK stage         = (Just (thLevel stage + 1))
+bracketOK stage         = Just (thLevel stage + 1)
 
 -- Indicates the legal transitions on splice($).
 spliceOK :: ThStage -> Maybe ThLevel
@@ -525,42 +524,7 @@ tcMetaTy :: Name -> TcM Type
 -- E.g. given the name "Expr" return the type "Expr"
 tcMetaTy tc_name
   = tcLookupTyCon tc_name      `thenM` \ t ->
-    returnM (mkGenTyConApp t [])
-       -- Use mkGenTyConApp because it might be a synonym
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-\subsection{Making new Ids}
-%*                                                                     *
-%************************************************************************
-
-Constructing new Ids
-
-\begin{code}
-newLocalName :: Name -> TcM Name
-newLocalName name      -- Make a clone
-  = newUnique          `thenM` \ uniq ->
-    returnM (mkInternalName uniq (getOccName name) (getSrcLoc name))
-\end{code}
-
-Make a name for the dict fun for an instance decl.  It's a *local*
-name for the moment.  The CoreTidy pass will externalise it.  Even in
---make and ghci stuff, we rebuild the instance environment each time,
-so the dfun id is internal to begin with, and external when compiling
-other modules
-
-\begin{code}
-newDFunName :: Class -> [Type] -> SrcLoc -> TcM Name
-newDFunName clas (ty:_) loc
-  = newUnique                  `thenM` \ uniq ->
-    returnM (mkInternalName uniq (mkDFunOcc dfun_string) loc)
-  where
-       -- Any string that is somewhat unique will do
-    dfun_string = occNameString (getOccName clas) ++ occNameString (getDFunTyKey ty)
-
-newDFunName clas [] loc = pprPanic "newDFunName" (ppr clas <+> ppr loc)
+    returnM (mkTyConApp t [])
 \end{code}
 
 
@@ -583,10 +547,13 @@ as well as explicit user written ones.
 \begin{code}
 data InstInfo
   = InstInfo {
-      iDFunId :: DFunId,               -- The dfun id
-      iBinds  :: InstBindings
+      iSpec  :: Instance,              -- Includes the dfun id.  Its forall'd type 
+      iBinds :: InstBindings           -- variables scope over the stuff in InstBindings!
     }
 
+iDFunId :: InstInfo -> DFunId
+iDFunId info = instanceDFunId (iSpec info)
+
 data InstBindings
   = VanillaInst                -- The normal case
        (LHsBinds Name)         -- Bindings
@@ -603,12 +570,15 @@ pprInstInfo info = vcat [ptext SLIT("InstInfo:") <+> ppr (idType (iDFunId info))
 
 pprInstInfoDetails info = pprInstInfo info $$ nest 2 (details (iBinds info))
   where
-    details (VanillaInst b _)  = ppr b
+    details (VanillaInst b _)  = pprLHsBinds b
     details (NewTypeDerived _) = text "Derived from the representation type"
 
+simpleInstInfoClsTy :: InstInfo -> (Class, Type)
+simpleInstInfoClsTy info = case instanceHead (iSpec info) of
+                         (_, _, cls, [ty]) -> (cls, ty)
+
 simpleInstInfoTy :: InstInfo -> Type
-simpleInstInfoTy info = case tcSplitDFunTy (idType (iDFunId info)) of
-                         (_, _, _, [ty]) -> ty
+simpleInstInfoTy info = snd (simpleInstInfoClsTy info)
 
 simpleInstInfoTyCon :: InstInfo -> TyCon
   -- Gets the type constructor for a simple instance declaration,
@@ -616,6 +586,24 @@ simpleInstInfoTyCon :: InstInfo -> TyCon
 simpleInstInfoTyCon inst = tcTyConAppTyCon (simpleInstInfoTy inst)
 \end{code}
 
+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 clas (ty:_) loc
+  = do { index   <- nextDFunIndex
+       ; is_boot <- tcIsHsBoot
+       ; mod     <- getModule
+       ; let info_string = occNameString (getOccName clas) ++ 
+                           occNameString (getDFunTyKey ty)
+             dfun_occ = mkDFunOcc info_string is_boot index
+
+       ; newGlobalBinder mod dfun_occ Nothing loc }
+
+newDFunName clas [] loc = pprPanic "newDFunName" (ppr clas <+> ppr loc)
+\end{code}
+
 
 %************************************************************************
 %*                                                                     *
@@ -624,6 +612,17 @@ simpleInstInfoTyCon inst = tcTyConAppTyCon (simpleInstInfoTy inst)
 %************************************************************************
 
 \begin{code}
-notFound wheRe name = failWithTc (text wheRe <> colon <+> quotes (ppr name) <+> 
-                                 ptext SLIT("is not in scope"))
+pprBinders :: [Name] -> SDoc
+-- Used in error messages
+-- Use quotes for a single one; they look a bit "busy" for several
+pprBinders [bndr] = quotes (ppr bndr)
+pprBinders bndrs  = pprWithCommas ppr bndrs
+
+notFound name 
+  = failWithTc (ptext SLIT("GHC internal error:") <+> quotes (ppr name) <+> 
+               ptext SLIT("is not in scope"))
+
+wrongThingErr expected thing name
+  = failWithTc (pprTcTyThingCategory thing <+> quotes (ppr name) <+> 
+               ptext SLIT("used as a") <+> text expected)
 \end{code}