diff --git a/ghc/compiler/typecheck/TcEnv.lhs b/ghc/compiler/typecheck/TcEnv.lhs
index 4b45f0a538406d0562b34cdbc5e390894882fa83..946eb8b8fb7542eb4a6ff3b0b3010851300aceed 100644
--- a/ghc/compiler/typecheck/TcEnv.lhs
+++ b/ghc/compiler/typecheck/TcEnv.lhs
@@ -15,7 +15,7 @@ module TcEnv(
 	tcExtendGlobalValEnv, tcExtendLocalValEnv,
 	tcLookupLocalValue, tcLookupLocalValueOK, tcLookupLocalValueByKey, 
 	tcLookupGlobalValue, tcLookupGlobalValueByKey, tcLookupGlobalValueMaybe,
-	tcAddImportedIdInfo,
+	tcAddImportedIdInfo, tcExplicitLookupGlobal,
 	tcLookupGlobalValueByKeyMaybe, 
 
 	newMonoIds, newLocalIds, newLocalId,
@@ -26,8 +26,6 @@ module TcEnv(
 IMP_Ubiq()
 #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ <= 201
 IMPORT_DELOOPER(TcMLoop)  -- for paranoia checking
-#else
-import {-# SOURCE #-} TcType
 #endif
 
 import HsTypes	( HsTyVar(..) )
@@ -42,13 +40,13 @@ import TyVar	( unionTyVarSets, emptyTyVarSet, tyVarSetToList, SYN_IE(TyVar) )
 import PprType	( GenTyVar )
 import Type	( tyVarsOfTypes, splitForAllTy )
 import TyCon	( TyCon, tyConKind, synTyConArity, SYN_IE(Arity) )
-import Class	( SYN_IE(Class), GenClass, classSig )
+import Class	( SYN_IE(Class), GenClass )
 
 import TcMonad
 
 import IdInfo		( noIdInfo )
 import Name		( Name, OccName(..), getSrcLoc, occNameString,
-			  maybeWiredInTyConName, maybeWiredInIdName,
+			  maybeWiredInTyConName, maybeWiredInIdName, isLocallyDefined,
 			  NamedThing(..)
 			)
 import Pretty
@@ -255,7 +253,6 @@ tcLookupLocalValueOK err name
 
 
 tcLookupGlobalValue :: Name -> NF_TcM s Id
-
 tcLookupGlobalValue name
   = case maybeWiredInIdName name of
 	Just id -> returnNF_Tc id
@@ -265,7 +262,6 @@ tcLookupGlobalValue name
     def = pprPanic "tcLookupGlobalValue:" (ppr PprDebug name)
 
 tcLookupGlobalValueMaybe :: Name -> NF_TcM s (Maybe Id)
-
 tcLookupGlobalValueMaybe name
   = case maybeWiredInIdName name of
 	Just id -> returnNF_Tc (Just id)
@@ -289,18 +285,29 @@ tcLookupGlobalValueByKeyMaybe uniq
   = tcGetEnv 		`thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
     returnNF_Tc (lookupUFM_Directly gve uniq)
 
+
+-- Non-monadic version, environment given explicitly
+tcExplicitLookupGlobal :: TcEnv s -> Name -> Maybe Id
+tcExplicitLookupGlobal (TcEnv tve tce ce gve lve gtvs) name
+  = case maybeWiredInIdName name of
+	Just id -> Just id
+	Nothing -> lookupUFM gve name
+
 	-- Extract the IdInfo from an IfaceSig imported from an interface file
-tcAddImportedIdInfo :: Id -> NF_TcM s Id
-tcAddImportedIdInfo id
-  = tcLookupGlobalValueMaybe (getName id)	`thenNF_Tc` \ maybe_id ->
-    let 
-	new_info = case maybe_id of
+tcAddImportedIdInfo :: TcEnv s -> Id -> Id
+tcAddImportedIdInfo unf_env id
+  | isLocallyDefined id		-- Don't look up locally defined Ids, because they
+				-- have explicit local definitions, so we get a black hole!
+  = id
+  | otherwise
+  = id `replaceIdInfo` new_info
+	-- The Id must be returned without a data dependency on maybe_id
+  where
+    new_info = -- pprTrace "tcAdd" (ppr PprDebug id) $
+	       case tcExplicitLookupGlobal unf_env (getName id) of
 		     Nothing	      -> noIdInfo
 		     Just imported_id -> getIdInfo imported_id
 		-- ToDo: could check that types are the same
-    in
-    returnNF_Tc (id `replaceIdInfo` new_info)
-	-- The Id must be returned without a data dependency on maybe_id
 \end{code}
 
 
diff --git a/ghc/compiler/typecheck/TcExpr.lhs b/ghc/compiler/typecheck/TcExpr.lhs
index ad0fe5533dce7afeee186d3a07f8ac4dd80069dc..48c62a049c35e66433cf52999a33a416c32c69e3 100644
--- a/ghc/compiler/typecheck/TcExpr.lhs
+++ b/ghc/compiler/typecheck/TcExpr.lhs
@@ -44,7 +44,7 @@ import TcType		( SYN_IE(TcType), TcMaybe(..),
 			  newTyVarTy, newTyVarTys, zonkTcTyVars, zonkTcType )
 import TcKind		( TcKind )
 
-import Class		( SYN_IE(Class), classSig )
+import Class		( SYN_IE(Class) )
 import FieldLabel	( FieldLabel, fieldLabelName, fieldLabelType )
 import Id		( idType, dataConFieldLabels, dataConSig, recordSelectorFieldLabel,
 			  isRecordSelector,
@@ -295,7 +295,7 @@ tcExpr (HsLet binds expr)
   where
     tc_expr expr = tcExpr expr `thenTc` \ (expr', lie, ty) ->
 	   	   returnTc ((expr',ty), lie)
-    combiner bind (expr, ty) = (HsLet bind expr, ty)
+    combiner is_rec bind (expr, ty) = (HsLet (MonoBind bind [] is_rec) expr, ty)
 
 tcExpr in_expr@(HsCase expr matches src_loc)
   = tcAddSrcLoc src_loc	$
@@ -885,7 +885,7 @@ tcStmt tc_expr do_or_lc m combine (LetStmt binds) do_next
   	binds
   	do_next
      where
-      	combine' binds' thing' = combine (LetStmt binds') Nothing thing'
+      	combine' is_rec binds' thing' = combine (LetStmt (MonoBind binds' [] is_rec)) Nothing thing'
 \end{code}
 
 %************************************************************************
diff --git a/ghc/compiler/typecheck/TcGRHSs.lhs b/ghc/compiler/typecheck/TcGRHSs.lhs
index e2ea7ebdfcafd07a3b7c143adf86014c5bd57690..ef582eafcee88400bbb38460413d942f0034d98f 100644
--- a/ghc/compiler/typecheck/TcGRHSs.lhs
+++ b/ghc/compiler/typecheck/TcGRHSs.lhs
@@ -76,6 +76,6 @@ tcGRHSsAndBinds (GRHSsAndBindsIn grhss binds)
 	 )			`thenTc` \ (grhss_and_binds'@(GRHSsAndBindsOut _ _ result_ty), lie) ->
     returnTc (grhss_and_binds', lie, result_ty)
   where
-    combiner binds1 (GRHSsAndBindsOut grhss binds2 ty) 
- 	= GRHSsAndBindsOut grhss (binds1 `ThenBinds` binds2) ty
+    combiner is_rec binds1 (GRHSsAndBindsOut grhss binds2 ty) 
+ 	= GRHSsAndBindsOut grhss ((MonoBind binds1 [] is_rec) `ThenBinds` binds2) ty
 \end{code}
diff --git a/ghc/compiler/typecheck/TcGenDeriv.lhs b/ghc/compiler/typecheck/TcGenDeriv.lhs
index 47e540f7ed57a6337b9da5b776e4c3e36eb5b98c..d317f105fd6f10d0ddc081f471539e64eeb7a66e 100644
--- a/ghc/compiler/typecheck/TcGenDeriv.lhs
+++ b/ghc/compiler/typecheck/TcGenDeriv.lhs
@@ -37,6 +37,7 @@ import HsSyn		( HsBinds(..), MonoBinds(..), Match(..), GRHSsAndBinds(..),
 import RdrHsSyn		( RdrName(..), varQual, varUnqual, mkOpApp,
 			  SYN_IE(RdrNameMonoBinds), SYN_IE(RdrNameHsExpr), SYN_IE(RdrNamePat)
 			)
+import BasicTypes	( IfaceFlavour(..) )
 import Id		( GenId, isNullaryDataCon, dataConTag,
 			  dataConRawArgTys, fIRST_TAG,
 			  isDataCon, SYN_IE(DataCon), SYN_IE(ConTag),
@@ -1051,7 +1052,7 @@ genOpApp e1 op e2 = mkOpApp e1 op e2
 \end{code}
 
 \begin{code}
-qual_orig_name n = case modAndOcc n of { (m,n) -> Qual m n }
+qual_orig_name n = case modAndOcc n of { (m,n) -> Qual m n HiFile }
 
 a_RDR		= varUnqual SLIT("a")
 b_RDR		= varUnqual SLIT("b")
diff --git a/ghc/compiler/typecheck/TcHsSyn.lhs b/ghc/compiler/typecheck/TcHsSyn.lhs
index 880dc7aef094557ca0dd9ba11c7429cb739d01f9..4b9fc3ce39c1ce0d2dcac2a7ec1f679f52bf94b8 100644
--- a/ghc/compiler/typecheck/TcHsSyn.lhs
+++ b/ghc/compiler/typecheck/TcHsSyn.lhs
@@ -29,7 +29,7 @@ module TcHsSyn (
 	mkHsTyLam, mkHsDictLam,
 	tcIdType, tcIdTyVars,
 
-	zonkBinds, zonkMonoBinds
+	zonkTopBinds, zonkBinds, zonkMonoBinds
   ) where
 
 IMP_Ubiq(){-uitous-}
@@ -38,12 +38,13 @@ IMP_Ubiq(){-uitous-}
 import HsSyn	-- oodles of it
 import Id	( GenId(..), IdDetails,	-- Can meddle modestly with Ids
 		  SYN_IE(DictVar), idType,
-		  SYN_IE(IdEnv), growIdEnvList, lookupIdEnv,
 		  SYN_IE(Id)
 		)
 
 -- others:
 import Name	( Name{--O only-}, NamedThing(..) )
+import BasicTypes ( IfaceFlavour )
+import TcEnv	( tcLookupGlobalValueMaybe, tcExtendGlobalValEnv )
 import TcMonad
 import TcType	( SYN_IE(TcType), TcMaybe, SYN_IE(TcTyVar),
 		  zonkTcTypeToType, zonkTcTyVarToTyVar
@@ -59,10 +60,11 @@ import Util	( zipEqual, panic,
 import PprType  ( GenType, GenTyVar ) 	-- instances
 import Type	( mkTyVarTy, tyVarsOfType, SYN_IE(Type) )
 import TyVar	( GenTyVar {- instances -}, SYN_IE(TyVar),
-		  SYN_IE(TyVarEnv), growTyVarEnvList, emptyTyVarSet )
+		  SYN_IE(TyVarEnv), nullTyVarEnv, growTyVarEnvList, emptyTyVarSet )
 import TysPrim	( voidTy )
 import CoreSyn  ( GenCoreExpr )
 import Unique	( Unique )		-- instances
+import Bag
 import UniqFM
 import Outputable
 import Pretty
@@ -160,17 +162,25 @@ This zonking pass runs over the bindings
 
  a) to convert TcTyVars to TyVars etc, dereferencing any bindings etc
  b) convert unbound TcTyVar to Void
+ c) convert each TcIdBndr to an Id by zonking its type
 
 We pass an environment around so that
+
  a) we know which TyVars are unbound
  b) we maintain sharing; eg an Id is zonked at its binding site and they
     all occurrences of that Id point to the common zonked copy
 
+Actually, since this is all in the Tc monad, it's convenient to keep the
+mapping from TcIds to Ids in the GVE of the Tc monad.   (Those TcIds
+were previously in the LVE of the Tc monad.)
+
 It's all pretty boring stuff, because HsSyn is such a large type, and 
 the environment manipulation is tiresome.
 
 
 \begin{code}
+extend_te te tyvars = growTyVarEnvList te [(tyvar, mkTyVarTy tyvar) | tyvar <- tyvars]
+
 zonkIdBndr :: TyVarEnv Type -> TcIdOcc s -> NF_TcM s Id
 zonkIdBndr te (TcId (Id u n ty details prags info))
   = zonkTcTypeToType te ty	`thenNF_Tc` \ ty' ->
@@ -178,98 +188,118 @@ zonkIdBndr te (TcId (Id u n ty details prags info))
 
 zonkIdBndr te (RealId id) = returnNF_Tc id
 
-zonkIdOcc :: IdEnv Id -> TcIdOcc s -> Id
-zonkIdOcc ve (RealId id) = id
-zonkIdOcc ve (TcId id)   = case (lookupIdEnv ve id) of
-				Just id' -> id'
-				Nothing  -> pprTrace "zonkIdOcc: " (ppr PprDebug id) $
-					    Id u n voidTy details prags info
-				         where
-					    Id u n _ details prags info = id
-
-extend_ve ve ids    = growIdEnvList ve [(id,id) | id <- ids]
-extend_te te tyvars = growTyVarEnvList te [(tyvar, mkTyVarTy tyvar) | tyvar <- tyvars]
+zonkIdOcc :: TcIdOcc s -> NF_TcM s Id
+zonkIdOcc (RealId id) = returnNF_Tc id
+zonkIdOcc (TcId id)   
+  = tcLookupGlobalValueMaybe (getName id)	`thenNF_Tc` \ maybe_id' ->
+    let
+	new_id = case maybe_id' of
+		    Just id' -> id'
+		    Nothing  -> pprTrace "zonkIdOcc: " (ppr PprDebug id) $
+				    Id u n voidTy details prags info
+			        where
+				    Id u n _ details prags info = id
+    in
+    returnNF_Tc new_id
 \end{code}
 
 
 \begin{code}
-zonkBinds :: TyVarEnv Type -> IdEnv Id 
-	  -> TcHsBinds s -> NF_TcM s (TypecheckedHsBinds, IdEnv Id)
-
-zonkBinds te ve EmptyBinds = returnNF_Tc (EmptyBinds, ve)
-
-zonkBinds te ve (ThenBinds binds1 binds2)
-  = zonkBinds te ve binds1   `thenNF_Tc` \ (new_binds1, ve1) ->
-    zonkBinds te ve1 binds2  `thenNF_Tc` \ (new_binds2, ve2) ->
-    returnNF_Tc (ThenBinds new_binds1 new_binds2, ve2)
-
-zonkBinds te ve (MonoBind bind sigs is_rec)
-  = ASSERT( null sigs )
-    fixNF_Tc (\ ~(_,new_ve) ->
-	zonkMonoBinds te new_ve bind  `thenNF_Tc` \ (new_bind, new_ids) ->
-	returnNF_Tc (MonoBind new_bind [] is_rec, extend_ve ve new_ids)
-    )
+zonkTopBinds :: TcMonoBinds s -> NF_TcM s (TypecheckedMonoBinds, TcEnv s)
+zonkTopBinds binds	-- Top level is implicitly recursive
+  = fixNF_Tc (\ ~(_, new_ids) ->
+	tcExtendGlobalValEnv (bagToList new_ids)	$
+	zonkMonoBinds nullTyVarEnv binds		`thenNF_Tc` \ (binds', new_ids) ->
+	tcGetEnv					`thenNF_Tc` \ env ->
+	returnNF_Tc ((binds', env), new_ids)
+    )					`thenNF_Tc` \ (stuff, _) ->
+    returnNF_Tc stuff
+
+
+zonkBinds :: TyVarEnv Type
+	  -> TcHsBinds s 
+	  -> NF_TcM s (TypecheckedHsBinds, TcEnv s)
+
+zonkBinds te binds 
+  = go binds (\ binds' -> tcGetEnv `thenNF_Tc` \ env -> returnNF_Tc (binds', env))
+  where
+    -- go :: TcHsBinds s -> (TypecheckedHsBinds -> NF_TcM s (TypecheckedHsBinds, TcEnv s)) 
+    --		         -> NF_TcM s (TypecheckedHsBinds, TcEnv s)
+    go (ThenBinds b1 b2) thing_inside = go b1 	$ \ b1' -> 
+					go b2	$ \ b2' ->
+					thing_inside (b1' `ThenBinds` b2')
+
+    go EmptyBinds thing_inside = thing_inside EmptyBinds
+
+    go (MonoBind bind sigs is_rec) thing_inside
+	  = ASSERT( null sigs )
+	    fixNF_Tc (\ ~(_, new_ids) ->
+		tcExtendGlobalValEnv (bagToList new_ids)	$
+		zonkMonoBinds te bind				`thenNF_Tc` \ (new_bind, new_ids) ->
+		thing_inside (MonoBind new_bind [] is_rec)	`thenNF_Tc` \ stuff ->
+		returnNF_Tc (stuff, new_ids)
+	    )						`thenNF_Tc` \ (stuff, _) ->
+	   returnNF_Tc stuff
 \end{code}
 
 \begin{code}
 -------------------------------------------------------------------------
-zonkMonoBinds :: TyVarEnv Type -> IdEnv Id 
-	      -> TcMonoBinds s -> NF_TcM s (TypecheckedMonoBinds, [Id])
+zonkMonoBinds :: TyVarEnv Type
+	      -> TcMonoBinds s 
+	      -> NF_TcM s (TypecheckedMonoBinds, Bag Id)
 
-zonkMonoBinds te ve EmptyMonoBinds = returnNF_Tc (EmptyMonoBinds, [])
+zonkMonoBinds te EmptyMonoBinds = returnNF_Tc (EmptyMonoBinds, emptyBag)
 
-zonkMonoBinds te ve (AndMonoBinds mbinds1 mbinds2)
-  = zonkMonoBinds te ve mbinds1  `thenNF_Tc` \ (new_mbinds1, ids1) ->
-    zonkMonoBinds te ve mbinds2  `thenNF_Tc` \ (new_mbinds2, ids2) ->
-    returnNF_Tc (AndMonoBinds new_mbinds1 new_mbinds2, ids1 ++ ids2)
+zonkMonoBinds te (AndMonoBinds mbinds1 mbinds2)
+  = zonkMonoBinds te mbinds1		`thenNF_Tc` \ (b1', ids1) ->
+    zonkMonoBinds te mbinds2		`thenNF_Tc` \ (b2', ids2) ->
+    returnNF_Tc (b1' `AndMonoBinds` b2', ids1 `unionBags` ids2)
 
-zonkMonoBinds te ve (PatMonoBind pat grhss_w_binds locn)
-  = zonkPat te ve pat	   			`thenNF_Tc` \ (new_pat, ids) ->
-    zonkGRHSsAndBinds te ve grhss_w_binds	`thenNF_Tc` \ new_grhss_w_binds ->
+zonkMonoBinds te (PatMonoBind pat grhss_w_binds locn)
+  = zonkPat te pat	   			`thenNF_Tc` \ (new_pat, ids) ->
+    zonkGRHSsAndBinds te grhss_w_binds		`thenNF_Tc` \ new_grhss_w_binds ->
     returnNF_Tc (PatMonoBind new_pat new_grhss_w_binds locn, ids)
 
-zonkMonoBinds te ve (VarMonoBind var expr)
+zonkMonoBinds te (VarMonoBind var expr)
   = zonkIdBndr te var    	`thenNF_Tc` \ new_var ->
-    zonkExpr te ve expr		`thenNF_Tc` \ new_expr ->
-    returnNF_Tc (VarMonoBind new_var new_expr, [new_var])
+    zonkExpr te expr		`thenNF_Tc` \ new_expr ->
+    returnNF_Tc (VarMonoBind new_var new_expr, unitBag new_var)
 
-zonkMonoBinds te ve (CoreMonoBind var core_expr)
+zonkMonoBinds te (CoreMonoBind var core_expr)
   = zonkIdBndr te var    	`thenNF_Tc` \ new_var ->
-    returnNF_Tc (CoreMonoBind new_var core_expr, [new_var])
+    returnNF_Tc (CoreMonoBind new_var core_expr, unitBag new_var)
 
-zonkMonoBinds te ve (FunMonoBind var inf ms locn)
+zonkMonoBinds te (FunMonoBind var inf ms locn)
   = zonkIdBndr te var			`thenNF_Tc` \ new_var ->
-    mapNF_Tc (zonkMatch te ve) ms	`thenNF_Tc` \ new_ms ->
-    returnNF_Tc (FunMonoBind new_var inf new_ms locn, [new_var])
+    mapNF_Tc (zonkMatch te) ms		`thenNF_Tc` \ new_ms ->
+    returnNF_Tc (FunMonoBind new_var inf new_ms locn, unitBag new_var)
 
 
-zonkMonoBinds te ve (AbsBinds tyvars dicts exports val_bind)
+zonkMonoBinds te (AbsBinds tyvars dicts exports val_bind)
   = mapNF_Tc zonkTcTyVarToTyVar tyvars	`thenNF_Tc` \ new_tyvars ->
     let
 	new_te = extend_te te new_tyvars
     in
     mapNF_Tc (zonkIdBndr new_te) dicts		`thenNF_Tc` \ new_dicts ->
 
-    let
-	ve1 = extend_ve ve new_dicts
-    in
-    fixNF_Tc (\ ~(_, _, ve2) ->
-	zonkMonoBinds new_te ve2 val_bind 		`thenNF_Tc` \ (new_val_bind, new_ids) ->
-        mapNF_Tc (zonkExport new_te ve2) exports	`thenNF_Tc` \ new_exports ->
-	returnNF_Tc (new_val_bind, new_exports, extend_ve ve1 new_ids)
+    tcExtendGlobalValEnv new_dicts			$
+    fixNF_Tc (\ ~(_, _, val_bind_ids) ->
+	tcExtendGlobalValEnv (bagToList val_bind_ids)		$
+	zonkMonoBinds new_te val_bind 		`thenNF_Tc` \ (new_val_bind, val_bind_ids) ->
+        mapNF_Tc (zonkExport new_te) exports	`thenNF_Tc` \ new_exports ->
+	returnNF_Tc (new_val_bind, new_exports, val_bind_ids)
     )						`thenNF_Tc ` \ (new_val_bind, new_exports, _) ->
-
     let
-	    new_globals = [global | (_, global, local) <- new_exports]
+	    new_globals = listToBag [global | (_, global, local) <- new_exports]
     in
     returnNF_Tc (AbsBinds new_tyvars new_dicts new_exports new_val_bind,
 		 new_globals)
-
   where
-    zonkExport te ve (tyvars, global, local)
+    zonkExport te (tyvars, global, local)
 	= mapNF_Tc zonkTcTyVarToTyVar tyvars	`thenNF_Tc` \ new_tyvars ->
 	  zonkIdBndr te global			`thenNF_Tc` \ new_global ->
-	  returnNF_Tc (new_tyvars, new_global, zonkIdOcc ve local)
+	  zonkIdOcc local			`thenNF_Tc` \ new_local -> 
+	  returnNF_Tc (new_tyvars, new_global, new_local)
 \end{code}
 
 %************************************************************************
@@ -279,40 +309,40 @@ zonkMonoBinds te ve (AbsBinds tyvars dicts exports val_bind)
 %************************************************************************
 
 \begin{code}
-zonkMatch :: TyVarEnv Type -> IdEnv Id 
+zonkMatch :: TyVarEnv Type
 	  -> TcMatch s -> NF_TcM s TypecheckedMatch
 
-zonkMatch te ve (PatMatch pat match)
-  = zonkPat te ve pat	    	`thenNF_Tc` \ (new_pat, ids) ->
-    let
-	new_ve = extend_ve ve ids
-    in
-    zonkMatch te new_ve match  	`thenNF_Tc` \ new_match ->
+zonkMatch te (PatMatch pat match)
+  = zonkPat te pat	    	`thenNF_Tc` \ (new_pat, ids) ->
+    tcExtendGlobalValEnv (bagToList ids)	$
+    zonkMatch te match  	`thenNF_Tc` \ new_match ->
     returnNF_Tc (PatMatch new_pat new_match)
 
-zonkMatch te ve (GRHSMatch grhss_w_binds)
-  = zonkGRHSsAndBinds te ve grhss_w_binds `thenNF_Tc` \ new_grhss_w_binds ->
+zonkMatch te (GRHSMatch grhss_w_binds)
+  = zonkGRHSsAndBinds te grhss_w_binds `thenNF_Tc` \ new_grhss_w_binds ->
     returnNF_Tc (GRHSMatch new_grhss_w_binds)
 
-zonkMatch te ve (SimpleMatch expr)
-  = zonkExpr te ve expr   `thenNF_Tc` \ new_expr ->
+zonkMatch te (SimpleMatch expr)
+  = zonkExpr te expr   `thenNF_Tc` \ new_expr ->
     returnNF_Tc (SimpleMatch new_expr)
 
 -------------------------------------------------------------------------
-zonkGRHSsAndBinds :: TyVarEnv Type -> IdEnv Id 
+zonkGRHSsAndBinds :: TyVarEnv Type
 	          -> TcGRHSsAndBinds s
 		  -> NF_TcM s TypecheckedGRHSsAndBinds
 
-zonkGRHSsAndBinds te ve (GRHSsAndBindsOut grhss binds ty)
-  = zonkBinds te ve binds   		`thenNF_Tc` \ (new_binds, new_ve) ->
+zonkGRHSsAndBinds te (GRHSsAndBindsOut grhss binds ty)
+  = zonkBinds te binds   		`thenNF_Tc` \ (new_binds, new_env) ->
+    tcSetEnv new_env $
     let
 	zonk_grhs (GRHS guard expr locn)
-	  = zonkStmts te new_ve guard  `thenNF_Tc` \ (new_guard, new_ve2) ->
-	    zonkExpr te new_ve2 expr   `thenNF_Tc` \ new_expr  ->
+	  = zonkStmts te guard  `thenNF_Tc` \ (new_guard, new_env) ->
+	    tcSetEnv new_env $
+	    zonkExpr te expr	`thenNF_Tc` \ new_expr  ->
 	    returnNF_Tc (GRHS new_guard new_expr locn)
 
         zonk_grhs (OtherwiseGRHS expr locn)
-          = zonkExpr te new_ve expr   `thenNF_Tc` \ new_expr  ->
+          = zonkExpr te expr	`thenNF_Tc` \ new_expr  ->
 	    returnNF_Tc (OtherwiseGRHS new_expr locn)
     in
     mapNF_Tc zonk_grhs grhss 	`thenNF_Tc` \ new_grhss ->
@@ -327,232 +357,229 @@ zonkGRHSsAndBinds te ve (GRHSsAndBindsOut grhss binds ty)
 %************************************************************************
 
 \begin{code}
-{-
-zonkExpr :: TyVarEnv Type -> IdEnv Id 
+zonkExpr :: TyVarEnv Type
 	 -> TcExpr s -> NF_TcM s TypecheckedHsExpr
--}
-zonkExpr te ve (HsVar name)
-  = returnNF_Tc (HsVar (zonkIdOcc ve name))
 
-zonkExpr te ve (HsLit _) = panic "zonkExpr te ve:HsLit"
+zonkExpr te (HsVar id)
+  = zonkIdOcc id	`thenNF_Tc` \ id' ->
+    returnNF_Tc (HsVar id')
 
-zonkExpr te ve (HsLitOut lit ty)
+zonkExpr te (HsLit _) = panic "zonkExpr te:HsLit"
+
+zonkExpr te (HsLitOut lit ty)
   = zonkTcTypeToType te ty	    `thenNF_Tc` \ new_ty  ->
     returnNF_Tc (HsLitOut lit new_ty)
 
-zonkExpr te ve (HsLam match)
-  = zonkMatch te ve match	`thenNF_Tc` \ new_match ->
+zonkExpr te (HsLam match)
+  = zonkMatch te match	`thenNF_Tc` \ new_match ->
     returnNF_Tc (HsLam new_match)
 
-zonkExpr te ve (HsApp e1 e2)
-  = zonkExpr te ve e1	`thenNF_Tc` \ new_e1 ->
-    zonkExpr te ve e2	`thenNF_Tc` \ new_e2 ->
+zonkExpr te (HsApp e1 e2)
+  = zonkExpr te e1	`thenNF_Tc` \ new_e1 ->
+    zonkExpr te e2	`thenNF_Tc` \ new_e2 ->
     returnNF_Tc (HsApp new_e1 new_e2)
 
-zonkExpr te ve (OpApp e1 op fixity e2)
-  = zonkExpr te ve e1	`thenNF_Tc` \ new_e1 ->
-    zonkExpr te ve op	`thenNF_Tc` \ new_op ->
-    zonkExpr te ve e2	`thenNF_Tc` \ new_e2 ->
+zonkExpr te (OpApp e1 op fixity e2)
+  = zonkExpr te e1	`thenNF_Tc` \ new_e1 ->
+    zonkExpr te op	`thenNF_Tc` \ new_op ->
+    zonkExpr te e2	`thenNF_Tc` \ new_e2 ->
     returnNF_Tc (OpApp new_e1 new_op fixity new_e2)
 
-zonkExpr te ve (NegApp _ _) = panic "zonkExpr te ve:NegApp"
-zonkExpr te ve (HsPar _)    = panic "zonkExpr te ve:HsPar"
+zonkExpr te (NegApp _ _) = panic "zonkExpr te:NegApp"
+zonkExpr te (HsPar _)    = panic "zonkExpr te:HsPar"
 
-zonkExpr te ve (SectionL expr op)
-  = zonkExpr te ve expr	`thenNF_Tc` \ new_expr ->
-    zonkExpr te ve op		`thenNF_Tc` \ new_op ->
+zonkExpr te (SectionL expr op)
+  = zonkExpr te expr	`thenNF_Tc` \ new_expr ->
+    zonkExpr te op		`thenNF_Tc` \ new_op ->
     returnNF_Tc (SectionL new_expr new_op)
 
-zonkExpr te ve (SectionR op expr)
-  = zonkExpr te ve op		`thenNF_Tc` \ new_op ->
-    zonkExpr te ve expr		`thenNF_Tc` \ new_expr ->
+zonkExpr te (SectionR op expr)
+  = zonkExpr te op		`thenNF_Tc` \ new_op ->
+    zonkExpr te expr		`thenNF_Tc` \ new_expr ->
     returnNF_Tc (SectionR new_op new_expr)
 
-zonkExpr te ve (HsCase expr ms src_loc)
-  = zonkExpr te ve expr    	    `thenNF_Tc` \ new_expr ->
-    mapNF_Tc (zonkMatch te ve) ms   `thenNF_Tc` \ new_ms ->
+zonkExpr te (HsCase expr ms src_loc)
+  = zonkExpr te expr    	    `thenNF_Tc` \ new_expr ->
+    mapNF_Tc (zonkMatch te) ms   `thenNF_Tc` \ new_ms ->
     returnNF_Tc (HsCase new_expr new_ms src_loc)
 
-zonkExpr te ve (HsIf e1 e2 e3 src_loc)
-  = zonkExpr te ve e1	`thenNF_Tc` \ new_e1 ->
-    zonkExpr te ve e2	`thenNF_Tc` \ new_e2 ->
-    zonkExpr te ve e3	`thenNF_Tc` \ new_e3 ->
+zonkExpr te (HsIf e1 e2 e3 src_loc)
+  = zonkExpr te e1	`thenNF_Tc` \ new_e1 ->
+    zonkExpr te e2	`thenNF_Tc` \ new_e2 ->
+    zonkExpr te e3	`thenNF_Tc` \ new_e3 ->
     returnNF_Tc (HsIf new_e1 new_e2 new_e3 src_loc)
 
-zonkExpr te ve (HsLet binds expr)
-  = zonkBinds te ve binds	`thenNF_Tc` \ (new_binds, new_ve) ->
-    zonkExpr  te new_ve expr	`thenNF_Tc` \ new_expr ->
+zonkExpr te (HsLet binds expr)
+  = zonkBinds te binds		`thenNF_Tc` \ (new_binds, new_env) ->
+    tcSetEnv new_env		$
+    zonkExpr te expr		`thenNF_Tc` \ new_expr ->
     returnNF_Tc (HsLet new_binds new_expr)
 
-zonkExpr te ve (HsDo _ _ _) = panic "zonkExpr te ve:HsDo"
+zonkExpr te (HsDo _ _ _) = panic "zonkExpr te:HsDo"
 
-zonkExpr te ve (HsDoOut do_or_lc stmts return_id then_id zero_id ty src_loc)
-  = zonkStmts te ve stmts 	`thenNF_Tc` \ (new_stmts, _) ->
+zonkExpr te (HsDoOut do_or_lc stmts return_id then_id zero_id ty src_loc)
+  = zonkStmts te stmts 		`thenNF_Tc` \ (new_stmts, _) ->
     zonkTcTypeToType te ty	`thenNF_Tc` \ new_ty   ->
-    returnNF_Tc (HsDoOut do_or_lc new_stmts 
-			 (zonkIdOcc ve return_id)
-			 (zonkIdOcc ve then_id)
-			 (zonkIdOcc ve zero_id)
+    zonkIdOcc return_id		`thenNF_Tc` \ new_return_id ->
+    zonkIdOcc then_id		`thenNF_Tc` \ new_then_id ->
+    zonkIdOcc zero_id		`thenNF_Tc` \ new_zero_id ->
+    returnNF_Tc (HsDoOut do_or_lc new_stmts new_return_id new_then_id new_zero_id
 			 new_ty src_loc)
 
-zonkExpr te ve (ExplicitList _) = panic "zonkExpr te ve:ExplicitList"
+zonkExpr te (ExplicitList _) = panic "zonkExpr te:ExplicitList"
 
-zonkExpr te ve (ExplicitListOut ty exprs)
+zonkExpr te (ExplicitListOut ty exprs)
   = zonkTcTypeToType te ty		`thenNF_Tc` \ new_ty ->
-    mapNF_Tc (zonkExpr te ve) exprs	`thenNF_Tc` \ new_exprs ->
+    mapNF_Tc (zonkExpr te) exprs	`thenNF_Tc` \ new_exprs ->
     returnNF_Tc (ExplicitListOut new_ty new_exprs)
 
-zonkExpr te ve (ExplicitTuple exprs)
-  = mapNF_Tc (zonkExpr te ve) exprs  `thenNF_Tc` \ new_exprs ->
+zonkExpr te (ExplicitTuple exprs)
+  = mapNF_Tc (zonkExpr te) exprs  `thenNF_Tc` \ new_exprs ->
     returnNF_Tc (ExplicitTuple new_exprs)
 
-zonkExpr te ve (RecordCon con rbinds)
-  = zonkExpr te ve con		`thenNF_Tc` \ new_con ->
-    zonkRbinds te ve rbinds	`thenNF_Tc` \ new_rbinds ->
+zonkExpr te (RecordCon con rbinds)
+  = zonkExpr te con		`thenNF_Tc` \ new_con ->
+    zonkRbinds te rbinds	`thenNF_Tc` \ new_rbinds ->
     returnNF_Tc (RecordCon new_con new_rbinds)
 
-zonkExpr te ve (RecordUpd _ _) = panic "zonkExpr te ve:RecordUpd"
+zonkExpr te (RecordUpd _ _) = panic "zonkExpr te:RecordUpd"
 
-zonkExpr te ve (RecordUpdOut expr ty dicts rbinds)
-  = zonkExpr te ve expr		`thenNF_Tc` \ new_expr ->
+zonkExpr te (RecordUpdOut expr ty dicts rbinds)
+  = zonkExpr te expr		`thenNF_Tc` \ new_expr ->
     zonkTcTypeToType te ty	`thenNF_Tc` \ new_ty ->
-    zonkRbinds te ve rbinds	`thenNF_Tc` \ new_rbinds ->
+    mapNF_Tc zonkIdOcc dicts	`thenNF_Tc` \ new_dicts ->
+    zonkRbinds te rbinds	`thenNF_Tc` \ new_rbinds ->
     returnNF_Tc (RecordUpdOut new_expr new_ty new_dicts new_rbinds)
-  where
-    new_dicts = map (zonkIdOcc ve) dicts
 
-zonkExpr te ve (ExprWithTySig _ _) = panic "zonkExpr te ve:ExprWithTySig"
-zonkExpr te ve (ArithSeqIn _) = panic "zonkExpr te ve:ArithSeqIn"
+zonkExpr te (ExprWithTySig _ _) = panic "zonkExpr te:ExprWithTySig"
+zonkExpr te (ArithSeqIn _) = panic "zonkExpr te:ArithSeqIn"
 
-zonkExpr te ve (ArithSeqOut expr info)
-  = zonkExpr te ve expr	`thenNF_Tc` \ new_expr ->
-    zonkArithSeq te ve info	`thenNF_Tc` \ new_info ->
+zonkExpr te (ArithSeqOut expr info)
+  = zonkExpr te expr	`thenNF_Tc` \ new_expr ->
+    zonkArithSeq te info	`thenNF_Tc` \ new_info ->
     returnNF_Tc (ArithSeqOut new_expr new_info)
 
-zonkExpr te ve (CCall fun args may_gc is_casm result_ty)
-  = mapNF_Tc (zonkExpr te ve) args 	`thenNF_Tc` \ new_args ->
+zonkExpr te (CCall fun args may_gc is_casm result_ty)
+  = mapNF_Tc (zonkExpr te) args 	`thenNF_Tc` \ new_args ->
     zonkTcTypeToType te result_ty	`thenNF_Tc` \ new_result_ty ->
     returnNF_Tc (CCall fun new_args may_gc is_casm new_result_ty)
 
-zonkExpr te ve (HsSCC label expr)
-  = zonkExpr te ve expr	`thenNF_Tc` \ new_expr ->
+zonkExpr te (HsSCC label expr)
+  = zonkExpr te expr	`thenNF_Tc` \ new_expr ->
     returnNF_Tc (HsSCC label new_expr)
 
-zonkExpr te ve (TyLam tyvars expr)
+zonkExpr te (TyLam tyvars expr)
   = mapNF_Tc zonkTcTyVarToTyVar tyvars	`thenNF_Tc` \ new_tyvars ->
     let
 	new_te = extend_te te new_tyvars
     in
-    zonkExpr new_te ve expr		`thenNF_Tc` \ new_expr ->
+    zonkExpr new_te expr		`thenNF_Tc` \ new_expr ->
     returnNF_Tc (TyLam new_tyvars new_expr)
 
-zonkExpr te ve (TyApp expr tys)
-  = zonkExpr te ve expr    	    	`thenNF_Tc` \ new_expr ->
+zonkExpr te (TyApp expr tys)
+  = zonkExpr te expr    	    	`thenNF_Tc` \ new_expr ->
     mapNF_Tc (zonkTcTypeToType te) tys	`thenNF_Tc` \ new_tys ->
     returnNF_Tc (TyApp new_expr new_tys)
 
-zonkExpr te ve (DictLam dicts expr)
+zonkExpr te (DictLam dicts expr)
   = mapNF_Tc (zonkIdBndr te) dicts	`thenNF_Tc` \ new_dicts ->
-    let
-	new_ve = extend_ve ve new_dicts
-    in
-    zonkExpr te new_ve expr    	    	`thenNF_Tc` \ new_expr ->
+    tcExtendGlobalValEnv new_dicts	$
+    zonkExpr te expr    	    	`thenNF_Tc` \ new_expr ->
     returnNF_Tc (DictLam new_dicts new_expr)
 
-zonkExpr te ve (DictApp expr dicts)
-  = zonkExpr te ve expr    	    	`thenNF_Tc` \ new_expr ->
+zonkExpr te (DictApp expr dicts)
+  = zonkExpr te expr    	    	`thenNF_Tc` \ new_expr ->
+    mapNF_Tc zonkIdOcc dicts	`thenNF_Tc` \ new_dicts ->
     returnNF_Tc (DictApp new_expr new_dicts)
-  where
-    new_dicts = map (zonkIdOcc ve) dicts
 
-zonkExpr te ve (ClassDictLam dicts methods expr)
-  = zonkExpr te ve expr    	    `thenNF_Tc` \ new_expr ->
+zonkExpr te (ClassDictLam dicts methods expr)
+  = zonkExpr te expr    	    `thenNF_Tc` \ new_expr ->
+    mapNF_Tc zonkIdOcc dicts	`thenNF_Tc` \ new_dicts ->
+    mapNF_Tc zonkIdOcc methods	`thenNF_Tc` \ new_methods ->
     returnNF_Tc (ClassDictLam new_dicts new_methods new_expr)
-  where
-    new_dicts   = map (zonkIdOcc ve) dicts
-    new_methods = map (zonkIdOcc ve) methods
-    
 
-zonkExpr te ve (Dictionary dicts methods)
-  = returnNF_Tc (Dictionary new_dicts new_methods)
-  where
-    new_dicts   = map (zonkIdOcc ve) dicts
-    new_methods = map (zonkIdOcc ve) methods
+zonkExpr te (Dictionary dicts methods)
+  = mapNF_Tc zonkIdOcc dicts	`thenNF_Tc` \ new_dicts ->
+    mapNF_Tc zonkIdOcc methods	`thenNF_Tc` \ new_methods ->
+    returnNF_Tc (Dictionary new_dicts new_methods)
 
-zonkExpr te ve (SingleDict name)
-  = returnNF_Tc (SingleDict (zonkIdOcc ve name))
+zonkExpr te (SingleDict name)
+  = zonkIdOcc name	`thenNF_Tc` \ name' ->
+    returnNF_Tc (SingleDict name')
 
 
 -------------------------------------------------------------------------
-zonkArithSeq :: TyVarEnv Type -> IdEnv Id 
+zonkArithSeq :: TyVarEnv Type
 	     -> TcArithSeqInfo s -> NF_TcM s TypecheckedArithSeqInfo
 
-zonkArithSeq te ve (From e)
-  = zonkExpr te ve e		`thenNF_Tc` \ new_e ->
+zonkArithSeq te (From e)
+  = zonkExpr te e		`thenNF_Tc` \ new_e ->
     returnNF_Tc (From new_e)
 
-zonkArithSeq te ve (FromThen e1 e2)
-  = zonkExpr te ve e1	`thenNF_Tc` \ new_e1 ->
-    zonkExpr te ve e2	`thenNF_Tc` \ new_e2 ->
+zonkArithSeq te (FromThen e1 e2)
+  = zonkExpr te e1	`thenNF_Tc` \ new_e1 ->
+    zonkExpr te e2	`thenNF_Tc` \ new_e2 ->
     returnNF_Tc (FromThen new_e1 new_e2)
 
-zonkArithSeq te ve (FromTo e1 e2)
-  = zonkExpr te ve e1	`thenNF_Tc` \ new_e1 ->
-    zonkExpr te ve e2	`thenNF_Tc` \ new_e2 ->
+zonkArithSeq te (FromTo e1 e2)
+  = zonkExpr te e1	`thenNF_Tc` \ new_e1 ->
+    zonkExpr te e2	`thenNF_Tc` \ new_e2 ->
     returnNF_Tc (FromTo new_e1 new_e2)
 
-zonkArithSeq te ve (FromThenTo e1 e2 e3)
-  = zonkExpr te ve e1	`thenNF_Tc` \ new_e1 ->
-    zonkExpr te ve e2	`thenNF_Tc` \ new_e2 ->
-    zonkExpr te ve e3	`thenNF_Tc` \ new_e3 ->
+zonkArithSeq te (FromThenTo e1 e2 e3)
+  = zonkExpr te e1	`thenNF_Tc` \ new_e1 ->
+    zonkExpr te e2	`thenNF_Tc` \ new_e2 ->
+    zonkExpr te e3	`thenNF_Tc` \ new_e3 ->
     returnNF_Tc (FromThenTo new_e1 new_e2 new_e3)
 
 -------------------------------------------------------------------------
-zonkStmts :: TyVarEnv Type -> IdEnv Id 
-	  -> [TcStmt s] -> NF_TcM s ([TypecheckedStmt], IdEnv Id)
+zonkStmts :: TyVarEnv Type
+	  -> [TcStmt s] -> NF_TcM s ([TypecheckedStmt], TcEnv s)
 
-zonkStmts te ve [] = returnNF_Tc ([], ve)
+zonkStmts te [] = tcGetEnv	`thenNF_Tc` \ env ->
+		  returnNF_Tc ([], env)
 
-zonkStmts te ve [ReturnStmt expr]
-  = zonkExpr te ve expr		`thenNF_Tc` \ new_expr ->
-    returnNF_Tc ([ReturnStmt new_expr], ve)
+zonkStmts te [ReturnStmt expr]
+  = zonkExpr te expr		`thenNF_Tc` \ new_expr ->
+    tcGetEnv			`thenNF_Tc` \ env ->
+    returnNF_Tc ([ReturnStmt new_expr], env)
 
-zonkStmts te ve (ExprStmt expr locn : stmts)
-  = zonkExpr te ve expr		`thenNF_Tc` \ new_expr ->
-    zonkStmts te ve	stmts	`thenNF_Tc` \ (new_stmts, new_ve) ->
-    returnNF_Tc (ExprStmt new_expr locn : new_stmts, new_ve)
+zonkStmts te (ExprStmt expr locn : stmts)
+  = zonkExpr te expr		`thenNF_Tc` \ new_expr ->
+    zonkStmts te	stmts	`thenNF_Tc` \ (new_stmts, new_env) ->
+    returnNF_Tc (ExprStmt new_expr locn : new_stmts, new_env)
 
-zonkStmts te ve (GuardStmt expr locn : stmts)
-  = zonkExpr te ve expr		`thenNF_Tc` \ new_expr ->
-    zonkStmts te ve	stmts	`thenNF_Tc` \ (new_stmts, new_ve) ->
-    returnNF_Tc (GuardStmt new_expr locn : new_stmts, new_ve)
+zonkStmts te (GuardStmt expr locn : stmts)
+  = zonkExpr te expr		`thenNF_Tc` \ new_expr ->
+    zonkStmts te	stmts	`thenNF_Tc` \ (new_stmts, new_env) ->
+    returnNF_Tc (GuardStmt new_expr locn : new_stmts, new_env)
 
-zonkStmts te ve (LetStmt binds : stmts)
-  = zonkBinds te ve     binds	`thenNF_Tc` \ (new_binds, new_ve) ->
-    zonkStmts te new_ve stmts	`thenNF_Tc` \ (new_stmts, new_ve2) ->
-    returnNF_Tc (LetStmt new_binds : new_stmts, new_ve2)
+zonkStmts te (LetStmt binds : stmts)
+  = zonkBinds te     binds	`thenNF_Tc` \ (new_binds, new_env) ->
+    tcSetEnv new_env		$
+    zonkStmts te stmts		`thenNF_Tc` \ (new_stmts, new_env2) ->
+    returnNF_Tc (LetStmt new_binds : new_stmts, new_env2)
 
-zonkStmts te ve (BindStmt pat expr locn : stmts)
-  = zonkPat te ve pat		`thenNF_Tc` \ (new_pat, ids) ->
-    zonkExpr te ve expr		`thenNF_Tc` \ new_expr ->
-    let
-	new_ve = extend_ve ve ids
-    in
-    zonkStmts te new_ve stmts	`thenNF_Tc` \ (new_stmts, new_ve2) ->
-    returnNF_Tc (BindStmt new_pat new_expr locn : new_stmts, new_ve2)
+zonkStmts te (BindStmt pat expr locn : stmts)
+  = zonkPat te pat		`thenNF_Tc` \ (new_pat, ids) ->
+    zonkExpr te expr		`thenNF_Tc` \ new_expr ->
+    tcExtendGlobalValEnv (bagToList ids)	$ 
+    zonkStmts te stmts		`thenNF_Tc` \ (new_stmts, new_env) ->
+    returnNF_Tc (BindStmt new_pat new_expr locn : new_stmts, new_env)
 
 
 
 -------------------------------------------------------------------------
-zonkRbinds :: TyVarEnv Type -> IdEnv Id 
+zonkRbinds :: TyVarEnv Type
 	   -> TcRecordBinds s -> NF_TcM s TypecheckedRecordBinds
 
-zonkRbinds te ve rbinds
+zonkRbinds te rbinds
   = mapNF_Tc zonk_rbind rbinds
   where
     zonk_rbind (field, expr, pun)
-      = zonkExpr te ve expr	`thenNF_Tc` \ new_expr ->
-	returnNF_Tc (zonkIdOcc ve field, new_expr, pun)
+      = zonkExpr te expr	`thenNF_Tc` \ new_expr ->
+	zonkIdOcc field		`thenNF_Tc` \ new_field ->
+	returnNF_Tc (new_field, new_expr, pun)
 \end{code}
 
 %************************************************************************
@@ -562,85 +589,84 @@ zonkRbinds te ve rbinds
 %************************************************************************
 
 \begin{code}
-{-
-zonkPat :: TyVarEnv Type -> IdEnv Id 
-	-> TcPat s -> NF_TcM s (TypecheckedPat, [Id])
--}
-zonkPat te ve (WildPat ty)
+zonkPat :: TyVarEnv Type
+	-> TcPat s -> NF_TcM s (TypecheckedPat, Bag Id)
+
+zonkPat te (WildPat ty)
   = zonkTcTypeToType te ty	    `thenNF_Tc` \ new_ty ->
-    returnNF_Tc (WildPat new_ty, [])
+    returnNF_Tc (WildPat new_ty, emptyBag)
 
-zonkPat te ve (VarPat v)
+zonkPat te (VarPat v)
   = zonkIdBndr te v	    `thenNF_Tc` \ new_v ->
-    returnNF_Tc (VarPat new_v, [new_v])
+    returnNF_Tc (VarPat new_v, unitBag new_v)
 
-zonkPat te ve (LazyPat pat)
-  = zonkPat te ve pat	    `thenNF_Tc` \ (new_pat, ids) ->
+zonkPat te (LazyPat pat)
+  = zonkPat te pat	    `thenNF_Tc` \ (new_pat, ids) ->
     returnNF_Tc (LazyPat new_pat, ids)
 
-zonkPat te ve (AsPat n pat)
+zonkPat te (AsPat n pat)
   = zonkIdBndr te n	    `thenNF_Tc` \ new_n ->
-    zonkPat te ve pat	    `thenNF_Tc` \ (new_pat, ids) ->
-    returnNF_Tc (AsPat new_n new_pat, new_n:ids)
+    zonkPat te pat	    `thenNF_Tc` \ (new_pat, ids) ->
+    returnNF_Tc (AsPat new_n new_pat, new_n `consBag` ids)
 
-zonkPat te ve (ConPat n ty pats)
+zonkPat te (ConPat n ty pats)
   = zonkTcTypeToType te ty	`thenNF_Tc` \ new_ty ->
-    zonkPats te ve pats		`thenNF_Tc` \ (new_pats, ids) ->
+    zonkPats te pats		`thenNF_Tc` \ (new_pats, ids) ->
     returnNF_Tc (ConPat n new_ty new_pats, ids)
 
-zonkPat te ve (ConOpPat pat1 op pat2 ty)
-  = zonkPat te ve pat1	    `thenNF_Tc` \ (new_pat1, ids1) ->
-    zonkPat te ve pat2	    `thenNF_Tc` \ (new_pat2, ids2) ->
+zonkPat te (ConOpPat pat1 op pat2 ty)
+  = zonkPat te pat1	    `thenNF_Tc` \ (new_pat1, ids1) ->
+    zonkPat te pat2	    `thenNF_Tc` \ (new_pat2, ids2) ->
     zonkTcTypeToType te ty  `thenNF_Tc` \ new_ty ->
-    returnNF_Tc (ConOpPat new_pat1 op new_pat2 new_ty, ids1 ++ ids2)
+    returnNF_Tc (ConOpPat new_pat1 op new_pat2 new_ty, ids1 `unionBags` ids2)
 
-zonkPat te ve (ListPat ty pats)
+zonkPat te (ListPat ty pats)
   = zonkTcTypeToType te ty	`thenNF_Tc` \ new_ty ->
-    zonkPats te ve pats		`thenNF_Tc` \ (new_pats, ids) ->
+    zonkPats te pats		`thenNF_Tc` \ (new_pats, ids) ->
     returnNF_Tc (ListPat new_ty new_pats, ids)
 
-zonkPat te ve (TuplePat pats)
-  = zonkPats te ve pats   		`thenNF_Tc` \ (new_pats, ids) ->
+zonkPat te (TuplePat pats)
+  = zonkPats te pats   		`thenNF_Tc` \ (new_pats, ids) ->
     returnNF_Tc (TuplePat new_pats, ids)
 
-zonkPat te ve (RecPat n ty rpats)
+zonkPat te (RecPat n ty rpats)
   = zonkTcTypeToType te ty		`thenNF_Tc` \ new_ty ->
     mapAndUnzipNF_Tc zonk_rpat rpats	`thenNF_Tc` \ (new_rpats, ids_s) ->
-    returnNF_Tc (RecPat n new_ty new_rpats, concat ids_s)
+    returnNF_Tc (RecPat n new_ty new_rpats, unionManyBags ids_s)
   where
     zonk_rpat (f, pat, pun)
-      = zonkPat te ve pat	     `thenNF_Tc` \ (new_pat, ids) ->
+      = zonkPat te pat	     `thenNF_Tc` \ (new_pat, ids) ->
 	returnNF_Tc ((f, new_pat, pun), ids)
 
-zonkPat te ve (LitPat lit ty)
+zonkPat te (LitPat lit ty)
   = zonkTcTypeToType te ty	    `thenNF_Tc` \ new_ty  ->
-    returnNF_Tc (LitPat lit new_ty, [])
+    returnNF_Tc (LitPat lit new_ty, emptyBag)
 
-zonkPat te ve (NPat lit ty expr)
+zonkPat te (NPat lit ty expr)
   = zonkTcTypeToType te ty	`thenNF_Tc` \ new_ty   ->
-    zonkExpr te ve expr		`thenNF_Tc` \ new_expr ->
-    returnNF_Tc (NPat lit new_ty new_expr, [])
+    zonkExpr te expr		`thenNF_Tc` \ new_expr ->
+    returnNF_Tc (NPat lit new_ty new_expr, emptyBag)
 
-zonkPat te ve (NPlusKPat n k ty e1 e2)
+zonkPat te (NPlusKPat n k ty e1 e2)
   = zonkIdBndr te n		`thenNF_Tc` \ new_n ->
     zonkTcTypeToType te ty	`thenNF_Tc` \ new_ty ->
-    zonkExpr te ve e1		`thenNF_Tc` \ new_e1 ->
-    zonkExpr te ve e2		`thenNF_Tc` \ new_e2 ->
-    returnNF_Tc (NPlusKPat new_n k new_ty new_e1 new_e2, [new_n])
+    zonkExpr te e1		`thenNF_Tc` \ new_e1 ->
+    zonkExpr te e2		`thenNF_Tc` \ new_e2 ->
+    returnNF_Tc (NPlusKPat new_n k new_ty new_e1 new_e2, unitBag new_n)
 
-zonkPat te ve (DictPat ds ms)
+zonkPat te (DictPat ds ms)
   = mapNF_Tc (zonkIdBndr te) ds    `thenNF_Tc` \ new_ds ->
     mapNF_Tc (zonkIdBndr te) ms    `thenNF_Tc` \ new_ms ->
-    returnNF_Tc (DictPat new_ds new_ms, new_ds ++ new_ms)
-
+    returnNF_Tc (DictPat new_ds new_ms, 
+		 listToBag new_ds `unionBags` listToBag new_ms)
 
-zonkPats te ve [] 
-  = returnNF_Tc ([], [])
-zonkPats te ve (pat:pats) 
-  = zonkPat te ve pat	`thenNF_Tc` \ (pat', ids1) ->
-    zonkPats te ve pats	`thenNF_Tc` \ (pats', ids2) ->
-    returnNF_Tc (pat':pats', ids1 ++ ids2)
 
+zonkPats te [] 
+  = returnNF_Tc ([], emptyBag)
+zonkPats te (pat:pats) 
+  = zonkPat te pat	`thenNF_Tc` \ (pat', ids1) ->
+    zonkPats te pats	`thenNF_Tc` \ (pats', ids2) ->
+    returnNF_Tc (pat':pats', ids1 `unionBags` ids2)
 \end{code}
 
 
diff --git a/ghc/compiler/typecheck/TcIfaceSig.lhs b/ghc/compiler/typecheck/TcIfaceSig.lhs
index a34a061fc7d7f481c5dec49838f5c581e2c457d6..3cdf85157fc49b189e2f818c3b80b7c2463c347d 100644
--- a/ghc/compiler/typecheck/TcIfaceSig.lhs
+++ b/ghc/compiler/typecheck/TcIfaceSig.lhs
@@ -13,7 +13,8 @@ IMP_Ubiq()
 import TcMonad
 import TcMonoType	( tcHsType, tcHsTypeKind )
 import TcEnv		( tcLookupGlobalValue, tcExtendTyVarEnv, tcExtendGlobalValEnv,
-			  tcLookupTyConByKey, tcLookupGlobalValueMaybe, tcLookupLocalValue
+			  tcLookupTyConByKey, tcLookupGlobalValueMaybe, tcLookupLocalValue,
+			  tcExplicitLookupGlobal
 			)
 import TcKind		( TcKind, kindToTcKind )
 
@@ -21,7 +22,7 @@ import HsSyn		( IfaceSig(..), HsDecl(..), TyDecl, ClassDecl, InstDecl, DefaultDe
 			  Fake, InPat, HsType )
 import RnHsSyn		( RenamedHsDecl(..) )
 import HsCore
-import HsDecls		( HsIdInfo(..) )
+import HsDecls		( HsIdInfo(..), HsStrictnessInfo(..) )
 import Literal		( Literal(..) )
 import CoreSyn
 import CoreUtils	( coreExprType )
@@ -34,9 +35,9 @@ import PrimOp		( PrimOp(..) )
 import Id		( GenId, mkImported, mkUserId, addInlinePragma,
 			  isPrimitiveId_maybe, dataConArgTys, SYN_IE(Id) )
 import Type		( mkSynTy, getAppDataTyConExpandingDicts )
-import TyVar		( mkTyVar )
+import TyVar		( mkSysTyVar )
 import Name		( Name )
-import Unique		( rationalTyConKey )
+import Unique		( rationalTyConKey, uniqueOf )
 import TysWiredIn	( integerTy )
 import PragmaInfo	( PragmaInfo(..) )
 import ErrUtils		( pprBagOfErrors )
@@ -56,95 +57,91 @@ As always, we do not have to worry about user-pragmas in interface
 signatures.
 
 \begin{code}
-tcInterfaceSigs :: [RenamedHsDecl] -> TcM s [Id]
-		   -- Ignore non-sig-decls in these decls
-
-tcInterfaceSigs (SigD (IfaceSig name ty id_infos src_loc) : rest)
-  = tcAddSrcLoc src_loc $
-    tcAddErrCtxt (ifaceSigCtxt name) $
-    tcHsType ty					`thenTc` \ sigma_ty ->
-    tcIdInfo name sigma_ty noIdInfo id_infos	`thenTc` \ id_info' ->
-    let
-	imp_id = mkImported name sigma_ty id_info'
-	sig_id | any inline_please id_infos = addInlinePragma imp_id
-	       | otherwise	 	    = imp_id
+tcInterfaceSigs :: TcEnv s		-- Envt to use when checking unfoldings
+		-> [RenamedHsDecl]	-- Ignore non-sig-decls in these decls
+		-> TcM s [Id]
+		
+
+tcInterfaceSigs unf_env (SigD (IfaceSig name ty id_infos src_loc) : rest)
+  = tcAddSrcLoc src_loc (
+    tcAddErrCtxt (ifaceSigCtxt name) (
+	tcHsType ty						`thenTc` \ sigma_ty ->
+	tcIdInfo unf_env name sigma_ty noIdInfo id_infos	`thenTc` \ id_info' ->
+	let
+	    imp_id = mkImported name sigma_ty id_info'
+	    sig_id | any inline_please id_infos = addInlinePragma imp_id
+	           | otherwise	 	        = imp_id
 
-	inline_please (HsUnfold inline _) = inline
-	inline_please other		  = False
-    in
-    tcInterfaceSigs rest		`thenTc` \ sig_ids ->
+	    inline_please (HsUnfold inline _) = inline
+	    inline_please other		  = False
+	in
+	returnTc sig_id
+    ))						`thenTc` \ sig_id ->
+    tcInterfaceSigs unf_env rest		`thenTc` \ sig_ids ->
     returnTc (sig_id : sig_ids)
 
-tcInterfaceSigs (other_decl : rest) = tcInterfaceSigs rest
+tcInterfaceSigs unf_env (other_decl : rest) = tcInterfaceSigs unf_env rest
 
-tcInterfaceSigs [] = returnTc []
+tcInterfaceSigs unf_env [] = returnTc []
 \end{code}
 
 \begin{code}
-tcIdInfo name ty info [] = returnTc info
-
-tcIdInfo name ty info (HsArity arity : rest)
-  = tcIdInfo name ty (info `addArityInfo` arity) rest
-
-tcIdInfo name ty info (HsUpdate upd : rest)
-  = tcIdInfo name ty (info `addUpdateInfo` upd) rest
-
-tcIdInfo name ty info (HsFBType fb : rest)
-  = tcIdInfo name ty (info `addFBTypeInfo` fb) rest
-
-tcIdInfo name ty info (HsArgUsage au : rest)
-  = tcIdInfo name ty (info `addArgUsageInfo` au) rest
-
-tcIdInfo name ty info (HsDeforest df : rest)
-  = tcIdInfo name ty (info `addDeforestInfo` df) rest
-
-tcIdInfo name ty info (HsUnfold inline expr : rest)
-  = tcUnfolding name expr 	`thenNF_Tc` \ unfold_info ->
-    tcIdInfo name ty (info `addUnfoldInfo` unfold_info) rest
-
-tcIdInfo name ty info (HsStrictness strict : rest)
-  = tcStrictness ty info strict 	`thenTc` \ info' ->
-    tcIdInfo name ty info' rest
+tcIdInfo unf_env name ty info info_ins
+  = go noIdInfo info_ins
+  where
+    go info_so_far []		   = returnTc info_so_far
+    go info (HsArity arity : rest) = go (info `addArityInfo` arity) rest
+    go info (HsUpdate upd : rest)  = go (info `addUpdateInfo` upd)  rest
+    go info (HsFBType fb : rest)   = go (info `addFBTypeInfo` fb)   rest
+    go info (HsArgUsage au : rest) = go (info `addArgUsageInfo` au) rest
+    go info (HsDeforest df : rest) = go (info `addDeforestInfo` df) rest
+
+    go info (HsUnfold inline expr : rest) = tcUnfolding unf_env name expr 	`thenNF_Tc` \ unfold_info ->
+					    go (info `addUnfoldInfo` unfold_info) rest
+
+    go info (HsStrictness strict : rest)  = tcStrictness unf_env ty info strict	`thenTc` \ info' ->
+					    go info' rest
 \end{code}
 
 \begin{code}
-tcStrictness ty info (StrictnessInfo demands maybe_worker)
-  = tcWorker maybe_worker			`thenNF_Tc` \ maybe_worker_id ->
+tcStrictness unf_env ty info (HsStrictnessInfo demands maybe_worker)
+  = tcWorker unf_env maybe_worker		`thenNF_Tc` \ maybe_worker_id ->
     uniqSMToTcM (mkWrapper ty demands)		`thenNF_Tc` \ wrap_fn ->
     let
 	-- Watch out! We can't pull on maybe_worker_id too eagerly!
 	info' = case maybe_worker_id of
-			Just (worker_id,_) -> info `addUnfoldInfo` mkUnfolding NoPragmaInfo (wrap_fn worker_id)
-			Nothing            -> info
+			Just worker_id -> info `addUnfoldInfo` mkUnfolding NoPragmaInfo (wrap_fn worker_id)
+			Nothing        -> info
+	has_worker = maybeToBool maybe_worker_id
     in
-    returnTc (info' `addStrictnessInfo` StrictnessInfo demands maybe_worker_id)
+    returnTc (info' `addStrictnessInfo` StrictnessInfo demands has_worker)
 
 -- Boring to write these out, but the result type differs from the arg type...
-tcStrictness ty info BottomGuaranteed
+tcStrictness unf_env ty info HsBottom
   = returnTc (info `addStrictnessInfo` BottomGuaranteed)
-tcStrictness ty info NoStrictnessInfo
-  = returnTc info
 \end{code}
 
 \begin{code}
-tcWorker Nothing = returnNF_Tc Nothing
+tcWorker unf_env Nothing = returnNF_Tc Nothing
 
-tcWorker (Just (worker_name,_))
-  = tcLookupGlobalValueMaybe worker_name	`thenNF_Tc` \ maybe_worker_id ->
-    returnNF_Tc (trace_maybe maybe_worker_id)
+tcWorker unf_env (Just (worker_name,_))
+  = returnNF_Tc (trace_maybe maybe_worker_id)
   where
+    maybe_worker_id = tcExplicitLookupGlobal unf_env worker_name
+
 	-- The trace is so we can see what's getting dropped
     trace_maybe Nothing  = pprTrace "tcWorker failed:" (ppr PprDebug worker_name) Nothing
-    trace_maybe (Just x) = Just (x, [])
+    trace_maybe (Just x) = Just x
 \end{code}
 
 For unfoldings we try to do the job lazily, so that we never type check
 an unfolding that isn't going to be looked at.
 
 \begin{code}
-tcUnfolding name core_expr
+tcUnfolding unf_env name core_expr
   = forkNF_Tc (
 	recoverNF_Tc no_unfolding (
+		tcSetEnv unf_env $
 		tcCoreExpr core_expr	`thenTc` \ core_expr' ->
 		returnTc (mkUnfolding NoPragmaInfo core_expr')
     ))			
@@ -261,7 +258,7 @@ tcCoreLamBndr (UfValBinder name ty) thing_inside
     
 tcCoreLamBndr (UfTyBinder name kind) thing_inside
   = let
-	tyvar = mkTyVar name kind
+	tyvar = mkSysTyVar (uniqueOf name) kind
     in
     tcExtendTyVarEnv [name] [(kindToTcKind kind, tyvar)] $
     thing_inside (TyBinder tyvar)
diff --git a/ghc/compiler/typecheck/TcInstDcls.lhs b/ghc/compiler/typecheck/TcInstDcls.lhs
index 45ed9134bf65a624680a8b9dfff5540ff783bb73..59d628416bb8832e2413184fb77a90ee09fffe10 100644
--- a/ghc/compiler/typecheck/TcInstDcls.lhs
+++ b/ghc/compiler/typecheck/TcInstDcls.lhs
@@ -34,15 +34,16 @@ import TcHsSyn		( TcIdOcc(..), SYN_IE(TcIdBndr), SYN_IE(TcHsBinds),
 			  mkHsTyLam, mkHsTyApp,
 			  mkHsDictLam, mkHsDictApp )
 
-import TcBinds		( tcBindWithSigs, tcPragmaSigs, TcSigInfo(..) )
+import TcBinds		( tcBindWithSigs, tcPragmaSigs, TcSigInfo(..), checkSigTyVars )
 import TcMonad
 import RnMonad		( SYN_IE(RnNameSupply) )
 import Inst		( Inst, InstOrigin(..), SYN_IE(InstanceMapper),
 			  instToId, newDicts, newMethod, SYN_IE(LIE), emptyLIE, plusLIE )
-import TcBinds		( tcPragmaSigs, checkSigTyVars )
 import PragmaInfo	( PragmaInfo(..) )
 import TcDeriv		( tcDeriving )
-import TcEnv		( tcLookupClass, newLocalId, tcExtendGlobalTyVars, tcGetGlobalTyVars )
+import TcEnv		( tcLookupClass, newLocalId, tcExtendGlobalTyVars, tcGetGlobalTyVars,
+			  tcExtendGlobalValEnv, tcAddImportedIdInfo
+			)
 import SpecEnv		( SpecEnv )
 import TcGRHSs		( tcGRHSsAndBinds )
 import TcInstUtil	( InstInfo(..), mkInstanceRelatedIds, buildInstanceEnvs )
@@ -61,23 +62,23 @@ import Bag		( emptyBag, unitBag, unionBags, unionManyBags,
 			  concatBag, foldBag, bagToList, listToBag,
 			  Bag )
 import CmdLineOpts	( opt_GlasgowExts, opt_CompilingGhcInternals,
-			  opt_OmitDefaultInstanceMethods,
+			  opt_OmitDefaultInstanceMethods, opt_PprUserLength,
 			  opt_SpecialiseOverloaded
 			)
-import Class		( GenClass, GenClassOp, 
-			  classBigSig, classOps, classOpLocalType,
+import Class		( GenClass,
+			  classBigSig,
 			  classDefaultMethodId, SYN_IE(Class)
 			  )
-import Id		( GenId, idType, isDefaultMethodId_maybe, replacePragmaInfo,
+import Id		( GenId, idType, replacePragmaInfo,
 			  isNullaryDataCon, dataConArgTys, SYN_IE(Id) )
 import ListSetOps	( minusList )
-import Maybes 		( maybeToBool, expectJust, seqMaybe )
-import Name		( nameOccName, getOccString, occNameString, moduleString,
+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 )
-import PprType		( GenType, GenTyVar, GenClass, GenClassOp, TyCon,
+import PrelVals		( nO_EXPLICIT_METHOD_ERROR_ID, nO_DEFAULT_METHOD_ERROR_ID )
+import PprType		( GenType, GenTyVar, GenClass, TyCon,
 			  pprParendGenType
 			)
 import Outputable
@@ -94,7 +95,7 @@ import TyVar		( GenTyVar, SYN_IE(GenTyVarSet), tyVarSetToList,
 import TysPrim		( byteArrayPrimTyCon, mutableByteArrayPrimTyCon )
 import TysWiredIn	( stringTy )
 import Unique		( Unique, cCallableClassKey, cReturnableClassKey, Uniquable(..) )
-import Util		( zipEqual, panic, pprPanic, pprTrace, removeDups, Ord3(..),
+import Util		( zipEqual, panic, pprPanic, pprTrace, removeDups, Ord3(..)
 #if __GLASGOW_HASKELL__ < 202
 		          , trace 
 #endif
@@ -175,16 +176,17 @@ and $dbinds_super$ bind the superclass dictionaries sd1 \ldots sdm.
 \end{enumerate}
 
 \begin{code}
-tcInstDecls1 :: [RenamedHsDecl]
+tcInstDecls1 :: TcEnv s			-- Contains IdInfo for dfun ids
+	     -> [RenamedHsDecl]
 	     -> Module			-- module name for deriving
 	     -> RnNameSupply			-- for renaming derivings
 	     -> TcM s (Bag InstInfo,
 		       RenamedHsBinds,
 		       PprStyle -> Doc)
 
-tcInstDecls1 decls mod_name rn_name_supply
+tcInstDecls1 unf_env decls mod_name rn_name_supply
   = 	-- Do the ordinary instance declarations
-    mapNF_Tc (tcInstDecl1 mod_name) 
+    mapNF_Tc (tcInstDecl1 unf_env mod_name) 
 	     [inst_decl | InstD inst_decl <- decls]	`thenNF_Tc` \ inst_info_bags ->
     let
 	decl_inst_info = unionManyBags inst_info_bags
@@ -202,9 +204,9 @@ tcInstDecls1 decls mod_name rn_name_supply
     returnTc (full_inst_info, deriv_binds, ddump_deriv)
 
 
-tcInstDecl1 :: Module -> RenamedInstDecl -> NF_TcM s (Bag InstInfo)
+tcInstDecl1 :: TcEnv s -> Module -> RenamedInstDecl -> NF_TcM s (Bag InstInfo)
 
-tcInstDecl1 mod_name (InstDecl poly_ty binds uprags (Just dfun_name) 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			$
@@ -225,12 +227,14 @@ tcInstDecl1 mod_name (InstDecl poly_ty binds uprags (Just dfun_name) src_loc)
 					`thenTc` \ (inst_tycon,arg_tys) ->
 
 	-- Make the dfun id and constant-method ids
-    mkInstanceRelatedIds dfun_name
-		         clas inst_tyvars inst_tau inst_theta
-					`thenNF_Tc` \ (dfun_id, dfun_theta) ->
-
+    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
+			dfun_theta final_dfun_id
 			     	binds src_loc uprags))
   where
     (tyvar_names, context, dict_ty) = case poly_ty of
@@ -250,15 +254,15 @@ tcInstDecl1 mod_name (InstDecl poly_ty binds uprags (Just dfun_name) src_loc)
 
 \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}
 
 
@@ -329,14 +333,14 @@ 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 -> NF_TcM s (LIE s, TcMonoBinds s)
 
 tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
 		      inst_decl_theta dfun_theta
 		      dfun_id monobinds
 		      locn uprags)
   | not (isLocallyDefined dfun_id)
-  = returnNF_Tc (emptyLIE, EmptyBinds)
+  = returnNF_Tc (emptyLIE, EmptyMonoBinds)
 
 {-
   -- I deleted this "optimisation" because when importing these
@@ -351,8 +355,8 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
 
   | 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) ->
@@ -360,7 +364,7 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
 	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' ->
@@ -390,8 +394,10 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
     in
     mapTc check_from_this_class (bagToList (collectMonoBinders monobinds))	`thenTc_`
     tcExtendGlobalTyVars inst_tyvars_set' (
-	mapAndUnzip3Tc (tcMethodBind (getDefmRhs clas) inst_ty' prag_fn monobinds) 
-		       (op_sel_ids `zip` [0..])
+        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) ->
 
 	-- Check the overloading constraints of the methods and superclasses
@@ -427,28 +433,16 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
 	method_binds = andMonoBinds method_binds_s
 
 	main_bind
-	  = MonoBind (
-		AbsBinds
+	  = AbsBinds
 		 inst_tyvars'
 		 dfun_arg_dicts_ids
 		 [(inst_tyvars', RealId dfun_id, this_dict_id)] 
 		 (super_binds	`AndMonoBinds` 
 		  method_binds	`AndMonoBinds`
-		  dict_bind))
-		[] recursive		-- Recursive to play safe
+		  dict_bind)
     in
     returnTc (const_lie `plusLIE` spec_lie,
-	      main_bind `ThenBinds` spec_binds)
-\end{code}
-
-The next function looks for a method binding; if there isn't one it
-manufactures one that just calls the global default method.
-
-See the notes under default decls in TcClassDcl.lhs.
-
-\begin{code}
-getDefmRhs :: Class -> Int -> RenamedHsExpr
-getDefmRhs clas idx = HsVar (getName (classDefaultMethodId clas idx))
+	      main_bind `AndMonoBinds` spec_binds)
 \end{code}
 
 
@@ -460,32 +454,32 @@ getDefmRhs clas idx = HsVar (getName (classDefaultMethodId clas idx))
 
 \begin{code}
 tcMethodBind 
-	:: (Int -> RenamedHsExpr)			-- Function mapping a tag to default RHS
+	:: Class
 	-> TcType s					-- Instance type
-	-> (Name -> PragmaInfo)
 	-> RenamedMonoBinds				-- Method binding
-	-> (Id, Int)					-- Selector ID (and its 0-indexed tag)
-							--  for which binding is wanted
+	-> (Id, Maybe Id)				-- Selector id and default-method id
 	-> TcM s (TcMonoBinds s, LIE s, (LIE s, TcIdOcc s))
 
-tcMethodBind deflt_fn inst_ty prag_fn meth_binds (sel_id, idx)
-  = newMethod origin (RealId sel_id) [inst_ty]	`thenNF_Tc` \ meth@(_, TcId meth_id) ->
-    tcInstSigTcType (idType meth_id)		`thenNF_Tc` \ (tyvars', rho_ty') ->
+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
-	meth_name    = getName meth_id
-	default_bind = PatMonoBind (VarPatIn meth_name)
-				   (GRHSsAndBindsIn [OtherwiseGRHS (deflt_fn idx) noSrcLoc] EmptyBinds)
-				   noSrcLoc
+	meth_name    = getName local_meth_id
 
-        (op_name, op_bind) = case go (getOccName sel_id) meth_binds of
-				Just stuff -> stuff
-				Nothing    -> (meth_name, default_bind)
+	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'
-	meth_id_w_prags = replacePragmaInfo meth_id (prag_fn meth_name)
-	sig_info        = TySigInfo op_name meth_id_w_prags tyvars' theta' tau' noSrcLoc
+	sig_info        = TySigInfo bndr_name local_meth_id tyvars' theta' tau' noSrcLoc
     in
-    tcBindWithSigs [op_name] op_bind [sig_info]
+
+	-- 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)
@@ -500,6 +494,23 @@ tcMethodBind deflt_fn inst_ty prag_fn meth_binds (sel_id, idx)
     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"
+
+
+    mk_default_bind local_meth_name
+      = PatMonoBind (VarPatIn local_meth_name)
+		    (GRHSsAndBindsIn [OtherwiseGRHS default_expr noSrcLoc] EmptyBinds)
+		    noSrcLoc
+
+    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
+
+    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}
 
 
@@ -730,7 +741,7 @@ instTypeErr ty sty
   = case ty of
       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	   -> hsep [ptext SLIT("The type"), ppr sty ty, rest_of_msg]
+      other	   -> sep [ptext SLIT("The type"), nest 4 (ppr sty ty), rest_of_msg]
   where
     rest_of_msg = ptext SLIT("cannot be used as an instance type")
 
@@ -743,24 +754,14 @@ derivingWhenInstanceExistsErr clas tycon sty
 		       ptext SLIT("type"), ppr sty tycon])
          4 (ptext SLIT("when an explicit instance exists"))
 
-derivingWhenInstanceImportedErr inst_mod clas tycon sty
-  = hang (hsep [ptext SLIT("Deriving class"), 
-		       ppr sty clas, 
-		       ptext SLIT("type"), ppr sty tycon])
-         4 (hsep [ptext SLIT("when an instance declared in module"), 
-		       pp_mod, ptext SLIT("has been imported")])
-  where
-    pp_mod = hsep [ptext SLIT("module"), ptext inst_mod]
-
 nonBoxedPrimCCallErr clas inst_ty sty
   = 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
-  = hsep [ptext SLIT("Warning: Omitted default method for"),
-	   ppr sty clas_op, ptext SLIT("in instance"),
-	   text 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"))
@@ -781,5 +782,4 @@ bindSigCtxt sty
 
 superClassSigCtxt sty
   = ptext SLIT("When checking superclass constraints of an instance declaration")
-
 \end{code}
diff --git a/ghc/compiler/typecheck/TcInstUtil.lhs b/ghc/compiler/typecheck/TcInstUtil.lhs
index 991eb6a325487381720b7a9941f7b37a6a193e74..0bebb37ab91473e33098a18233902bc0352ff65b 100644
--- a/ghc/compiler/typecheck/TcInstUtil.lhs
+++ b/ghc/compiler/typecheck/TcInstUtil.lhs
@@ -20,17 +20,15 @@ import HsSyn		( MonoBinds, Fake, InPat, Sig )
 import RnHsSyn		( SYN_IE(RenamedMonoBinds), RenamedSig(..), 
 			  RenamedInstancePragmas(..) )
 
-import TcEnv		( tcAddImportedIdInfo )
 import TcMonad
 import Inst		( SYN_IE(InstanceMapper) )
 
 import Bag		( bagToList, Bag )
-import Class		( GenClass, GenClassOp, SYN_IE(ClassInstEnv),
-			  classBigSig, classOps, classOpLocalType,
-			  SYN_IE(ClassOp), SYN_IE(Class)
+import Class		( GenClass, SYN_IE(ClassInstEnv),
+			  classBigSig, SYN_IE(Class)
 			)
 import CoreSyn		( GenCoreExpr(..), mkValLam, mkTyApp )
-import Id		( GenId, mkDictFunId, mkConstMethodId, mkSysLocal, SYN_IE(Id) )
+import Id		( GenId, mkDictFunId, mkSysLocal, SYN_IE(Id) )
 import MatchEnv		( nullMEnv, insertMEnv )
 import Maybes		( MaybeErr(..), mkLookupFunDef )
 import Name		( getSrcLoc, Name{--O only-} )
@@ -45,9 +43,7 @@ import TyVar		( GenTyVar, SYN_IE(TyVar) )
 import Unique		( Unique )
 import Util		( equivClasses, zipWithEqual, panic{-, pprTrace-}, Ord3(..) )
 
-#if __GLASGOW_HASKELL__ >= 202
 import Outputable
-#endif
 \end{code}
 
     instance c => k (t tvs) where b
@@ -82,13 +78,12 @@ mkInstanceRelatedIds :: Name		-- Name to use for the dict fun;
 		     -> [TyVar]
 		     -> Type
 		     -> ThetaType
-		     -> NF_TcM s (Id, ThetaType)
+		     -> (Id, ThetaType)
 
 mkInstanceRelatedIds dfun_name clas inst_tyvars inst_ty inst_decl_theta
-  = tcAddImportedIdInfo dfun_id			`thenNF_Tc` \ new_dfun_id ->
-    returnNF_Tc (new_dfun_id, dfun_theta)
+  = (dfun_id, dfun_theta)
   where
-    (_, super_classes, _, _, _, _) = classBigSig clas
+    (_, super_classes, _, _, _) = classBigSig clas
     super_class_theta = super_classes `zip` repeat inst_ty
 
     dfun_theta = case inst_decl_theta of
@@ -126,24 +121,20 @@ buildInstanceEnvs info
     in
     mapTc buildInstanceEnv info_by_class    `thenTc` \ inst_env_entries ->
     let
-	class_lookup_fn = mkLookupFunDef (==) inst_env_entries 
-					 (nullMEnv, \ o -> nullSpecEnv)
+	class_lookup_fn = mkLookupFunDef (==) inst_env_entries nullMEnv
     in
     returnTc class_lookup_fn
 \end{code}
 
 \begin{code}
 buildInstanceEnv :: [InstInfo]		-- Non-empty, and all for same class
-		 -> TcM s (Class, (ClassInstEnv, (ClassOp -> SpecEnv)))
+		 -> TcM s (Class, ClassInstEnv)
 
 buildInstanceEnv inst_infos@((InstInfo clas _ _ _ _ _ _ _ _) : _)
   = foldlTc addClassInstance
-	    (nullMEnv, [(op, nullSpecEnv) | op <- classOps clas])
-	    inst_infos
-					`thenTc` \ (class_inst_env, op_inst_envs) ->
-    returnTc (clas, (class_inst_env,
-		     mkLookupFunDef (==) op_inst_envs
-				    (panic "buildInstanceEnv")))
+	    nullMEnv
+	    inst_infos				`thenTc` \ class_inst_env ->
+    returnTc (clas, class_inst_env)
 \end{code}
 
 @addClassInstance@ adds the appropriate stuff to the @ClassInstEnv@
@@ -152,34 +143,19 @@ about any overlap with an existing instance.
 
 \begin{code}
 addClassInstance
-    :: (ClassInstEnv, [(ClassOp,SpecEnv)])
+    :: ClassInstEnv
     -> InstInfo
-    -> TcM s (ClassInstEnv, [(ClassOp,SpecEnv)])
+    -> TcM s ClassInstEnv
 
-addClassInstance
-    input_stuff@(class_inst_env, op_spec_envs)
+addClassInstance class_inst_env
     (InstInfo clas inst_tyvars inst_ty _ _ 
 	      dfun_id _ src_loc _)
-  = 
-
--- We only add specialised/overlapped instances
--- if we are specialising the overloading
--- ToDo ... This causes getConstMethodId errors!
---
---    if not (is_plain_instance inst_ty) && not opt_SpecialiseOverloaded
---    then
---	-- Drop this specialised/overlapped instance
---	returnTc (class_inst_env, op_spec_envs)
---    else	
-
-	-- Add the instance to the class's instance environment
-    case insertMEnv matchTy class_inst_env inst_ty dfun_id of {
-	Failed (ty', dfun_id')    -> recoverTc (returnTc input_stuff) $
+  = 	-- Add the instance to the class's instance environment
+    case insertMEnv matchTy class_inst_env inst_ty dfun_id of
+	Failed (ty', dfun_id')    -> recoverTc (returnTc class_inst_env) $
 				     dupInstFailure clas (inst_ty, src_loc) 
 							 (ty', getSrcLoc dfun_id');
-	Succeeded class_inst_env' -> 
-
-	    returnTc (class_inst_env', op_spec_envs)
+	Succeeded class_inst_env' -> returnTc class_inst_env'
 
 {- 		OLD STUFF FOR CONSTANT METHODS 
 
@@ -224,7 +200,6 @@ addClassInstance
     returnTc (class_inst_env', op_spec_envs')
 		END OF OLD STUFF -}
 
-    }
 \end{code}
 
 \begin{code}
@@ -233,8 +208,8 @@ dupInstFailure clas info1@(ty1, locn1) info2@(ty2, locn2)
   = tcAddErrCtxt ctxt $
     failTc (\sty -> ptext SLIT("Duplicate or overlapping instance declarations"))
   where
-    ctxt sty = hang (sep [ptext SLIT("Class"), ppr sty clas,
-			  ptext SLIT("type"),  ppr sty ty1])
-		    4 (sep [hcat [ptext SLIT("at "), ppr sty locn1],
-		    	      hcat [ptext SLIT("and "), ppr sty locn2]])
+    ctxt sty = sep [hsep [ptext SLIT("for"), 
+			  pprQuote sty $ \ sty -> ppr sty clas <+> ppr sty ty1],
+		    nest 4 (sep [ptext SLIT("at")  <+> ppr sty locn1,
+		    	         ptext SLIT("and") <+> ppr sty locn2])]
 \end{code}
diff --git a/ghc/compiler/typecheck/TcKind.lhs b/ghc/compiler/typecheck/TcKind.lhs
index 20b0ff1c7a2c4b49f5127d6bc28f9a158ba49353..bafa1fb62321028c2dd6571c1971be774caed952 100644
--- a/ghc/compiler/typecheck/TcKind.lhs
+++ b/ghc/compiler/typecheck/TcKind.lhs
@@ -24,9 +24,7 @@ import TcMonad
 import Unique	( Unique, pprUnique10 )
 import Pretty
 import Util	( nOfThem )
-#if __GLASGOW_HASKELL__ >= 202
 import Outputable
-#endif
 \end{code}
 
 
@@ -179,7 +177,7 @@ zonkTcKind kind@(TcVarKind uniq box)
 
 \begin{code}
 instance Outputable (TcKind s) where
-  ppr sty kind = ppr_kind sty kind
+  ppr sty kind = pprQuote sty $ \ sty -> ppr_kind sty kind
 
 ppr_kind sty TcTypeKind 
   = char '*'
diff --git a/ghc/compiler/typecheck/TcModule.lhs b/ghc/compiler/typecheck/TcModule.lhs
index c1681411e9f7035b8e982e130e6383f497bda343..ee23bb1aab9bc38acadd784e2a12daf0be082bd1 100644
--- a/ghc/compiler/typecheck/TcModule.lhs
+++ b/ghc/compiler/typecheck/TcModule.lhs
@@ -9,26 +9,26 @@
 module TcModule (
 	typecheckModule,
 	SYN_IE(TcResults),
-	SYN_IE(TcResultBinds),
 	SYN_IE(TcSpecialiseRequests),
 	SYN_IE(TcDDumpDeriv)
     ) where
 
 IMP_Ubiq(){-uitous-}
 
-import HsSyn		( HsDecl(..), HsModule(..), HsBinds(..), HsExpr, MonoBinds,
+import HsSyn		( HsDecl(..), HsModule(..), HsBinds(..), HsExpr, MonoBinds(..),
 			  TyDecl, SpecDataSig, ClassDecl, InstDecl, IfaceSig,
 			  SpecInstSig, DefaultDecl, Sig, Fake, InPat,
-			  SYN_IE(RecFlag), nonRecursive,
+			  SYN_IE(RecFlag), nonRecursive,  GRHSsAndBinds, Match,
  			  FixityDecl, IE, ImportDecl
 			)
 import RnHsSyn		( SYN_IE(RenamedHsModule), RenamedFixityDecl(..) )
 import TcHsSyn		( SYN_IE(TypecheckedHsBinds), SYN_IE(TypecheckedHsExpr),
-			  SYN_IE(TypecheckedDictBinds),
-			  TcIdOcc(..), zonkBinds )
+			  SYN_IE(TypecheckedDictBinds), SYN_IE(TcMonoBinds),
+			  SYN_IE(TypecheckedMonoBinds),
+			  TcIdOcc(..), zonkTopBinds )
 
 import TcMonad
-import Inst		( Inst, plusLIE )
+import Inst		( Inst, emptyLIE, plusLIE )
 import TcBinds		( tcBindsAndThen )
 import TcClassDcl	( tcClassDecls2 )
 import TcDefaults	( tcDefaults )
@@ -55,7 +55,7 @@ import Maybes		( catMaybes, MaybeErr )
 import Name		( Name, isLocallyDefined, pprModule )
 import Pretty
 import TyCon		( TyCon, isSynTyCon )
-import Class		( GenClass, SYN_IE(Class), classGlobalIds )
+import Class		( GenClass, SYN_IE(Class), classSelIds )
 import Type		( applyTyCon, mkSynTy, SYN_IE(Type) )
 import PprType		( GenType, GenTyVar )
 import TysWiredIn	( unitTy )
@@ -79,24 +79,22 @@ tycon_specs = emptyFM
 
 Outside-world interface:
 \begin{code}
+--ToDo: put this in HsVersions
+#if __GLASGOW_HASKELL__ >= 200
+# define REAL_WORLD RealWorld
+#else
+# define REAL_WORLD _RealWorld
+#endif
+
+
 -- Convenient type synonyms first:
 type TcResults
-  = (TcResultBinds,
+  = (TypecheckedMonoBinds,
      [TyCon], [Class],
      Bag InstInfo,		-- Instance declaration information
      TcSpecialiseRequests,
      TcDDumpDeriv)
 
-type TcResultBinds
-  = (TypecheckedHsBinds,	-- record selector binds
-     TypecheckedHsBinds,	-- binds from class decls; does NOT
-				-- include default-methods bindings
-     TypecheckedHsBinds,	-- binds from instance decls; INCLUDES
-				-- class default-methods binds
-     TypecheckedHsBinds,	-- binds from value decls
-
-     TypecheckedHsBinds)	-- constant instance binds
-
 type TcSpecialiseRequests
   = FiniteMap TyCon [(Bool, [Maybe Type])]
     -- source tycon specialisation requests
@@ -110,9 +108,9 @@ typecheckModule
 	-> RnNameSupply
 	-> RenamedHsModule
 	-> MaybeErr
-	    (TcResults,		-- if all goes well...
-	     Bag Warning)	-- (we can still get warnings)
-	    (Bag Error,		-- if we had errors...
+	    (TcResults, 		-- if all goes well...
+	     Bag Warning)	      	-- (we can still get warnings)
+	    (Bag Error,		      	-- if we had errors...
 	     Bag Warning)
 
 typecheckModule us rn_name_supply mod
@@ -129,133 +127,124 @@ tcModule rn_name_supply
 	(HsModule mod_name verion exports imports fixities decls src_loc)
   = tcAddSrcLoc src_loc $	-- record where we're starting
 
-	-- Tie the knot for inteface-file value declaration signatures
-	-- This info is only used inside the knot for type-checking the
-	-- pragmas, which is done lazily [ie failure just drops the pragma
+    fixTc (\ ~(unf_env ,_) ->
+	-- unf_env is used for type-checking interface pragmas
+	-- which is done lazily [ie failure just drops the pragma
 	-- without having any global-failure effect].
+	-- 
+	-- unf_env is also used to get the pragam info for dfuns.
+
+    	    -- The knot for instance information.  This isn't used at all
+	    -- till we type-check value declarations
+    	fixTc ( \ ~(rec_inst_mapper, _, _, _, _) ->
+    
+		 -- Type-check the type and class decls
+		-- trace "tcTyAndClassDecls:"	$
+		tcTyAndClassDecls1 unf_env rec_inst_mapper decls	`thenTc` \ env ->
+    
+		-- trace "tc3" $
+		    -- Typecheck the instance decls, includes deriving
+		tcSetEnv env (
+		-- trace "tcInstDecls:"	$
+		tcInstDecls1 unf_env decls mod_name rn_name_supply
+		)					`thenTc` \ (inst_info, deriv_binds, ddump_deriv) ->
+    
+		-- trace "tc4" $
+		buildInstanceEnvs inst_info	`thenTc` \ inst_mapper ->
+    
+		returnTc (inst_mapper, env, inst_info, deriv_binds, ddump_deriv)
+    
+    	-- End of inner fix loop
+    	) `thenTc` \ (_, env, inst_info, deriv_binds, ddump_deriv) ->
+    
+    	-- trace "tc5" $
+    	tcSetEnv env $
+    	
+    	    -- Default declarations
+    	tcDefaults decls		`thenTc` \ defaulting_tys ->
+    	tcSetDefaultTys defaulting_tys 	$
+    	
+    	-- Create any necessary record selector Ids and their bindings
+    	-- "Necessary" includes data and newtype declarations
+    	let
+    	    tycons   = getEnv_TyCons env
+    	    classes  = getEnv_Classes env
+    	in
+    	mkDataBinds tycons		`thenTc` \ (data_ids, data_binds) ->
+    	
+    	-- Extend the global value environment with 
+    	--	(a) constructors
+    	--	(b) record selectors
+    	--	(c) class op selectors
+    	-- 	(d) default-method ids
+    	tcExtendGlobalValEnv data_ids				$
+    	tcExtendGlobalValEnv (concat (map classSelIds classes))	$
 
-    -- trace "tc1" $
-
-    fixTc (\ ~(_, _, _, _, _, _, sig_ids) ->
-
-	-- trace "tc2" $
-	tcExtendGlobalValEnv sig_ids (
 
-	-- The knot for instance information.  This isn't used at all
-	-- till we type-check value declarations
-	fixTc ( \ ~(rec_inst_mapper, _, _, _, _) ->
+	    -- Interface type signatures
+	    -- We tie a knot so that the Ids read out of interfaces are in scope
+	    --   when we read their pragmas.
+	    -- What we rely on is that pragmas are typechecked lazily; if
+	    --   any type errors are found (ie there's an inconsistency)
+	    --   we silently discard the pragma
+	tcInterfaceSigs unf_env decls		`thenTc` \ sig_ids ->
+	tcExtendGlobalValEnv sig_ids		$
 
-	     -- Type-check the type and class decls
-	    -- trace "tcTyAndClassDecls:"	$
-	    tcTyAndClassDecls1 rec_inst_mapper decls	`thenTc` \ env ->
 
-	    -- trace "tc3" $
-		-- Typecheck the instance decls, includes deriving
-	    tcSetEnv env (
-	    -- trace "tcInstDecls:"	$
-	    tcInstDecls1 decls mod_name rn_name_supply
-	    )					`thenTc` \ (inst_info, deriv_binds, ddump_deriv) ->
+	-- Value declarations next.
+	-- We also typecheck any extra binds that came out of the "deriving" process
+        -- trace "tcBinds:"			$
+    	tcBindsAndThen
+	    (\ is_rec binds1 (binds2, thing) -> (binds1 `AndMonoBinds` binds2, thing))
+	    (get_val_decls decls `ThenBinds` deriv_binds)
+	    (	tcGetEnv		`thenNF_Tc` \ env ->
+		returnTc ((EmptyMonoBinds, env), emptyLIE)
+	    )				`thenTc` \ ((val_binds, final_env), lie_valdecls) ->
+	tcSetEnv final_env $
 
-	    -- trace "tc4" $
-	    buildInstanceEnvs inst_info	`thenTc` \ inst_mapper ->
 
-	    returnTc (inst_mapper, env, inst_info, deriv_binds, ddump_deriv)
+		-- Second pass over class and instance declarations,
+		-- to compile the bindings themselves.
+	-- trace "tc8" $
+	tcInstDecls2  inst_info		`thenNF_Tc` \ (lie_instdecls, inst_binds) ->
+	tcClassDecls2 decls		`thenNF_Tc` \ (lie_clasdecls, cls_binds) ->
 
-	) `thenTc` \ (_, env, inst_info, deriv_binds, ddump_deriv) ->
 
-	-- trace "tc5" $
-	tcSetEnv env (
 
-	    -- Default declarations
-	tcDefaults decls		`thenTc` \ defaulting_tys ->
-	tcSetDefaultTys defaulting_tys 	( -- for the iface sigs...
+	-- Check that "main" has the right signature
+	tcCheckMainSig mod_name		`thenTc_` 
 
-	-- Create any necessary record selector Ids and their bindings
-	-- "Necessary" includes data and newtype declarations
+	     -- Deal with constant or ambiguous InstIds.  How could
+	     -- there be ambiguous ones?  They can only arise if a
+	     -- top-level decl falls under the monomorphism
+	     -- restriction, and no subsequent decl instantiates its
+	     -- type.  (Usually, ambiguous type variables are resolved
+	     -- during the generalisation step.)
+	-- trace "tc9" $
 	let
-		tycons   = getEnv_TyCons env
-		classes  = getEnv_Classes env
+	    lie_alldecls = lie_valdecls `plusLIE` lie_instdecls `plusLIE` lie_clasdecls
 	in
-	mkDataBinds tycons		`thenTc` \ (data_ids, data_binds) ->
+	tcSimplifyTop lie_alldecls			`thenTc` \ const_inst_binds ->
 
-	-- Extend the global value environment with 
-	--	a) constructors
-	--	b) record selectors
-	--	c) class op selectors
-	-- 	d) default-method ids
-	tcExtendGlobalValEnv data_ids				$
-	tcExtendGlobalValEnv (concat (map classGlobalIds classes))	$
 
-	    -- Interface type signatures
-	    -- We tie a knot so that the Ids read out of interfaces are in scope
-	    --   when we read their pragmas.
-	    -- What we rely on is that pragmas are typechecked lazily; if
-	    --   any type errors are found (ie there's an inconsistency)
-	    --   we silently discard the pragma
-	tcInterfaceSigs decls		`thenTc` \ sig_ids ->
-	tcGetEnv			`thenNF_Tc` \ env ->
-	-- trace "tc6" $
-
-	returnTc (env, inst_info, data_binds, deriv_binds, ddump_deriv, defaulting_tys, sig_ids)
-
-    )))) `thenTc` \ (env, inst_info, data_binds, deriv_binds, ddump_deriv, defaulting_tys, _) ->
+	    -- Backsubstitution.    This must be done last.
+	    -- Even tcCheckMainSig and tcSimplifyTop may do some unification.
+	let
+	    all_binds = data_binds 		`AndMonoBinds` 
+			val_binds		`AndMonoBinds`
+		        inst_binds		`AndMonoBinds`
+		        cls_binds		`AndMonoBinds`
+		        const_inst_binds
+	in
+	zonkTopBinds all_binds	`thenNF_Tc` \ (all_binds', really_final_env)  ->
 
-    -- trace "tc7" $
-    tcSetEnv env (				-- to the end...
-    tcSetDefaultTys defaulting_tys (		-- ditto
+	returnTc (really_final_env, (all_binds', inst_info, ddump_deriv))
 
-	-- Value declarations next.
-	-- We also typecheck any extra binds that came out of the "deriving" process
-    -- trace "tcBinds:"			$
-    tcBindsAndThen
-	(\ binds1 (binds2, thing) -> (binds1 `ThenBinds` binds2, thing))
-	(get_val_decls decls `ThenBinds` deriv_binds)
-	(	-- Second pass over instance declarations,
-		-- to compile the bindings themselves.
-	    -- trace "tc8" $
-	    tcInstDecls2  inst_info	`thenNF_Tc` \ (lie_instdecls, inst_binds) ->
-	    tcClassDecls2 decls		`thenNF_Tc` \ (lie_clasdecls, cls_binds) ->
-	    tcCheckMainSig mod_name	`thenTc_` 
-	    tcGetEnv			`thenNF_Tc` \ env ->
-	    returnTc ( (EmptyBinds, (inst_binds, cls_binds, env)),
-		       lie_instdecls `plusLIE` lie_clasdecls
-		     )
-	)
-
-	`thenTc` \ ((val_binds, (inst_binds, cls_binds, final_env)), lie_alldecls) ->
-
-	-- Deal with constant or ambiguous InstIds.  How could
-	-- there be ambiguous ones?  They can only arise if a
-	-- top-level decl falls under the monomorphism
-	-- restriction, and no subsequent decl instantiates its
-	-- type.  (Usually, ambiguous type variables are resolved
-	-- during the generalisation step.)
-    -- trace "tc9" $
-    tcSimplifyTop lie_alldecls			`thenTc` \ const_insts ->
-
-
-	-- Backsubstitution.  Monomorphic top-level decls may have
-	-- been instantiated by subsequent decls, and the final
-	-- simplification step may have instantiated some
-	-- ambiguous types.  So, sadly, we need to back-substitute
-	-- over the whole bunch of bindings.
-	-- 
-	-- More horrible still, we have to do it in a careful order, so that
-	-- all the TcIds are in scope when we come across them.
-	-- 
-	-- These bindings ought really to be bundled together in a huge
-	-- recursive group, but HsSyn doesn't have recursion among Binds, only
-	-- among MonoBinds.  Sigh again.
-    zonkBinds nullTyVarEnv nullIdEnv (MonoBind const_insts [] nonRecursive)
-						 	`thenNF_Tc` \ (const_insts', ve1) ->
-    zonkBinds nullTyVarEnv ve1 val_binds 		`thenNF_Tc` \ (val_binds', ve2) ->
+    -- End of outer fix loop
+    ) `thenTc` \ (final_env, (all_binds', inst_info, ddump_deriv)) ->
 
-    zonkBinds nullTyVarEnv ve2 data_binds 	`thenNF_Tc` \ (data_binds', _) ->
-    zonkBinds nullTyVarEnv ve2 inst_binds	`thenNF_Tc` \ (inst_binds', _) ->
-    zonkBinds nullTyVarEnv ve2 cls_binds	`thenNF_Tc` \ (cls_binds', _) ->
 
     let
-        localids = getEnv_LocalIds final_env
 	tycons   = getEnv_TyCons   final_env
 	classes  = getEnv_Classes  final_env
 
@@ -264,12 +253,12 @@ tcModule rn_name_supply
     in
 	-- FINISHED AT LAST
     returnTc (
-	(data_binds', cls_binds', inst_binds', val_binds', const_insts'),
+	all_binds',
 
 	local_tycons, local_classes, inst_info, tycon_specs,
 
 	ddump_deriv
-    )))
+    )
 
 get_val_decls decls = foldr ThenBinds EmptyBinds [binds | ValD binds <- decls]
 \end{code}