[project @ 2000-11-24 09:51:38 by simonpj]
[ghc-hetmet.git] / ghc / compiler / rename / RnSource.lhs
index 65edce3..c60d850 100644 (file)
@@ -1,73 +1,69 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 \section[RnSource]{Main pass of renamer}
 
 \begin{code}
 %
 \section[RnSource]{Main pass of renamer}
 
 \begin{code}
-#include "HsVersions.h"
-
-module RnSource ( rnDecl, rnHsType ) where
+module RnSource ( rnDecl, rnTyClDecl, rnIfaceRuleDecl, rnInstDecl, rnSourceDecls, 
+                 rnHsType, rnHsSigType, rnHsTypeFVs, rnHsSigTypeFVs
+       ) where
 
 
-IMP_Ubiq()
-IMPORT_DELOOPER(RnLoop)                -- *check* the RnPass/RnExpr/RnBinds loop-breaking
+#include "HsVersions.h"
 
 
+import RnExpr
 import HsSyn
 import HsSyn
-import HsDecls         ( HsIdInfo(..) )
-import HsPragmas
-import HsTypes         ( getTyVarName )
-import RdrHsSyn
+import HscTypes                ( GlobalRdrEnv )
+import HsTypes         ( hsTyVarNames, pprHsContext )
+import RdrName         ( RdrName, isRdrDataCon, rdrNameOcc, mkRdrNameWkr, elemRdrEnv )
+import RdrHsSyn                ( RdrNameContext, RdrNameHsType, RdrNameConDecl, RdrNameTyClDecl,
+                         extractRuleBndrsTyVars, extractHsTyRdrTyVars,
+                         extractHsCtxtRdrTyVars, extractGenericPatTyVars
+                       )
 import RnHsSyn
 import HsCore
 import RnHsSyn
 import HsCore
-import CmdLineOpts     ( opt_IgnoreIfacePragmas )
 
 
-import RnBinds         ( rnTopBinds, rnMethodBinds )
-import RnEnv           ( bindTyVarsRn, lookupBndrRn, lookupOccRn, lookupImplicitOccRn, bindLocalsRn,
-                         lookupOptionalOccRn, newSysName, newDfunName,
-                         listType_RDR, tupleType_RDR )
+import RnBinds         ( rnTopBinds, rnMethodBinds, renameSigs, renameSigsFVs )
+import RnEnv           ( lookupTopBndrRn, lookupOccRn, newIPName, lookupIfaceName,
+                         lookupOrigNames, lookupSysBinder, newLocalsRn,
+                         bindLocalsFVRn, 
+                         bindTyVarsRn, bindTyVars2Rn,
+                         bindTyVarsFV2Rn, extendTyVarEnvFVRn,
+                         bindCoreLocalRn, bindCoreLocalsRn, bindLocalNames,
+                         checkDupOrQualNames, checkDupNames, mapFvRn
+                       )
 import RnMonad
 
 import RnMonad
 
-import Name            ( Name, isLocallyDefined, 
-                         OccName(..), occNameString, prefixOccName,
-                         ExportFlag(..),
-                         Provenance,
-                         SYN_IE(NameSet), unionNameSets, emptyNameSet, mkNameSet, unitNameSet,
-                         elemNameSet
+import Class           ( FunDep, DefMeth (..) )
+import Name            ( Name, OccName, nameOccName, NamedThing(..) )
+import NameSet
+import PrelInfo                ( derivableClassKeys, cCallishClassKeys )
+import PrelNames       ( deRefStablePtr_RDR, newStablePtr_RDR,
+                         bindIO_RDR, returnIO_RDR
                        )
                        )
-import ErrUtils                ( addErrLoc, addShortErrLocLine, addShortWarnLocLine )
-import FiniteMap       ( emptyFM, lookupFM, addListToFM_C )
-import Id              ( GenId{-instance NamedThing-} )
-import IdInfo          ( IdInfo, StrictnessInfo(..), FBTypeInfo, DemandInfo, ArgUsageInfo )
-import SpecEnv         ( SpecEnv )
-import Lex             ( isLexCon )
-import CoreUnfold      ( Unfolding(..), SimpleUnfolding )
-import MagicUFs                ( MagicUnfoldingFun )
-import PrelInfo                ( derivingOccurrences, evalClass_RDR, numClass_RDR )
-import ListSetOps      ( unionLists, minusList )
-import Maybes          ( maybeToBool, catMaybes )
-import Bag             ( emptyBag, unitBag, consBag, unionManyBags, unionBags, listToBag, bagToList )
-import Outputable      ( Outputable(..){-instances-} )
---import PprStyle      -- ToDo:rm 
-import Pretty
+import List            ( partition, nub )
+import Outputable
 import SrcLoc          ( SrcLoc )
 import SrcLoc          ( SrcLoc )
--- import TyCon                ( TyCon{-instance NamedThing-} )
-import Unique          ( Unique )
-import UniqSet         ( SYN_IE(UniqSet) )
-import UniqFM          ( UniqFM, lookupUFM )
-import Util            ( isIn, isn'tIn, thenCmp, removeDups, cmpPString,
-                         panic, assertPanic{- , pprTrace ToDo:rm-} )
+import CmdLineOpts     ( DynFlag(..) )
+                               -- Warn of unused for-all'd tyvars
+import Unique          ( Uniquable(..) )
+import ErrUtils                ( Message )
+import CStrings                ( isCLabelString )
+import ListSetOps      ( removeDupsEq )
 \end{code}
 
 \end{code}
 
-rnDecl `renames' declarations.
+@rnDecl@ `renames' declarations.
 It simultaneously performs dependency analysis and precedence parsing.
 It also does the following error checks:
 \begin{enumerate}
 \item
 Checks that tyvars are used properly. This includes checking
 for undefined tyvars, and tyvars in contexts that are ambiguous.
 It simultaneously performs dependency analysis and precedence parsing.
 It also does the following error checks:
 \begin{enumerate}
 \item
 Checks that tyvars are used properly. This includes checking
 for undefined tyvars, and tyvars in contexts that are ambiguous.
+(Some of this checking has now been moved to module @TcMonoType@,
+since we don't have functional dependency information at this point.)
 \item
 Checks that all variable occurences are defined.
 \item 
 \item
 Checks that all variable occurences are defined.
 \item 
-Checks the (..) etc constraints in the export list.
+Checks the @(..)@ etc constraints in the export list.
 \end{enumerate}
 
 
 \end{enumerate}
 
 
@@ -78,190 +74,355 @@ Checks the (..) etc constraints in the export list.
 %*********************************************************
 
 \begin{code}
 %*********************************************************
 
 \begin{code}
-rnDecl :: RdrNameHsDecl -> RnMS s RenamedHsDecl
-
-rnDecl (ValD binds) = rnTopBinds binds `thenRn` \ new_binds ->
-                     returnRn (ValD new_binds)
-
-
-rnDecl (SigD (IfaceSig name ty id_infos loc))
-  = pushSrcLocRn loc $
-    lookupBndrRn name          `thenRn` \ name' ->
-    rnHsType ty                        `thenRn` \ ty' ->
-
-       -- Get the pragma info, unless we should ignore it
-    (if opt_IgnoreIfacePragmas then
-       returnRn []
-     else
-       mapRn rnIdInfo id_infos
-    )                          `thenRn` \ id_infos' -> 
+rnSourceDecls :: GlobalRdrEnv -> LocalFixityEnv
+             -> [RdrNameHsDecl] 
+             -> RnMG ([RenamedHsDecl], FreeVars)
+       -- The decls get reversed, but that's ok
 
 
-    returnRn (SigD (IfaceSig name' ty' id_infos' loc))
+rnSourceDecls gbl_env local_fixity_env decls
+  = initRnMS gbl_env local_fixity_env SourceMode (go emptyFVs [] decls)
+  where
+       -- Fixity and deprecations have been dealt with already; ignore them
+    go fvs ds' []             = returnRn (ds', fvs)
+    go fvs ds' (FixD _:ds)    = go fvs ds' ds
+    go fvs ds' (DeprecD _:ds) = go fvs ds' ds
+    go fvs ds' (d:ds)         = rnDecl d       `thenRn` \(d', fvs') ->
+                               go (fvs `plusFV` fvs') (d':ds') ds
 \end{code}
 
 \end{code}
 
+
 %*********************************************************
 %*                                                     *
 %*********************************************************
 %*                                                     *
-\subsection{Type declarations}
+\subsection{Value declarations}
 %*                                                     *
 %*********************************************************
 
 %*                                                     *
 %*********************************************************
 
-@rnTyDecl@ uses the `global name function' to create a new type
-declaration in which local names have been replaced by their original
-names, reporting any unknown names.
-
-Renaming type variables is a pain. Because they now contain uniques,
-it is necessary to pass in an association list which maps a parsed
-tyvar to its Name representation. In some cases (type signatures of
-values), it is even necessary to go over the type first in order to
-get the set of tyvars used by it, make an assoc list, and then go over
-it again to rename the tyvars! However, we can also do some scoping
-checks at the same time.
-
 \begin{code}
 \begin{code}
-rnDecl (TyD (TyData context tycon tyvars condecls derivings pragmas src_loc))
-  = pushSrcLocRn src_loc $
-    lookupBndrRn tycon                         `thenRn` \ tycon' ->
-    bindTyVarsRn "data declaration" tyvars     $ \ tyvars' ->
-    rnContext context                          `thenRn` \ context' ->
-    mapRn rnConDecl condecls                   `thenRn` \ condecls' ->
-    rnDerivs derivings                         `thenRn` \ derivings' ->
-    ASSERT(isNoDataPragmas pragmas)
-    returnRn (TyD (TyData context' tycon' tyvars' condecls' derivings' noDataPragmas src_loc))
+-- rnDecl does all the work
+rnDecl :: RdrNameHsDecl -> RnMS (RenamedHsDecl, FreeVars)
+
+rnDecl (ValD binds) = rnTopBinds binds `thenRn` \ (new_binds, fvs) ->
+                     returnRn (ValD new_binds, fvs)
+
+rnDecl (TyClD tycl_decl)
+  = rnTyClDecl tycl_decl               `thenRn` \ new_decl ->
+    rnClassBinds tycl_decl new_decl    `thenRn` \ (new_decl', fvs) ->
+    returnRn (TyClD new_decl', fvs `plusFV` tyClDeclFVs new_decl')
+
+rnDecl (InstD inst)
+  = rnInstDecl inst            `thenRn` \ new_inst ->
+    rnInstBinds inst new_inst  `thenRn` \ (new_inst', fvs) ->
+    returnRn (InstD new_inst', fvs `plusFV` instDeclFVs new_inst')
+
+rnDecl (RuleD rule)
+  | isIfaceRuleDecl rule
+  = rnIfaceRuleDecl rule       `thenRn` \ new_rule ->
+    returnRn (RuleD new_rule, ruleDeclFVs new_rule)
+  | otherwise
+  = rnHsRuleDecl rule          `thenRn` \ (new_rule, fvs) ->
+    returnRn (RuleD new_rule, fvs)
 
 
-rnDecl (TyD (TyNew context tycon tyvars condecl derivings pragmas src_loc))
+rnDecl (DefD (DefaultDecl tys src_loc))
   = pushSrcLocRn src_loc $
   = pushSrcLocRn src_loc $
-    lookupBndrRn tycon                         `thenRn` \ tycon' ->
-    bindTyVarsRn "newtype declaration" tyvars  $ \ tyvars' ->
-    rnContext context                          `thenRn` \ context' ->
-    rnConDecl condecl                          `thenRn` \ condecl' ->
-    rnDerivs derivings                         `thenRn` \ derivings' ->
-    ASSERT(isNoDataPragmas pragmas)
-    returnRn (TyD (TyNew context' tycon' tyvars' condecl' derivings' noDataPragmas src_loc))
+    mapFvRn (rnHsTypeFVs doc_str) tys          `thenRn` \ (tys', fvs) ->
+    returnRn (DefD (DefaultDecl tys' src_loc), fvs)
+  where
+    doc_str = text "a `default' declaration"
 
 
-rnDecl (TyD (TySynonym name tyvars ty src_loc))
+rnDecl (ForD (ForeignDecl name imp_exp ty ext_nm cconv src_loc))
   = pushSrcLocRn src_loc $
   = pushSrcLocRn src_loc $
-    lookupBndrRn name                          `thenRn` \ name' ->
-    bindTyVarsRn "type declaration" tyvars     $ \ tyvars' ->
-    rnHsType ty                                        `thenRn` \ ty' ->
-    returnRn (TyD (TySynonym name' tyvars' ty' src_loc))
+    lookupOccRn name                   `thenRn` \ name' ->
+    let 
+       extra_fvs FoExport 
+         | isDyn = lookupOrigNames [newStablePtr_RDR, deRefStablePtr_RDR,
+                                    bindIO_RDR, returnIO_RDR]
+         | otherwise =
+               lookupOrigNames [bindIO_RDR, returnIO_RDR] `thenRn` \ fvs ->
+               returnRn (addOneFV fvs name')
+       extra_fvs other = returnRn emptyFVs
+    in
+    checkRn (ok_ext_nm ext_nm) (badExtName ext_nm)     `thenRn_`
+
+    extra_fvs imp_exp                                  `thenRn` \ fvs1 -> 
+
+    rnHsTypeFVs fo_decl_msg ty                 `thenRn` \ (ty', fvs2) ->
+    returnRn (ForD (ForeignDecl name' imp_exp ty' ext_nm cconv src_loc), 
+             fvs1 `plusFV` fvs2)
+ where
+  fo_decl_msg = ptext SLIT("The foreign declaration for") <+> ppr name
+  isDyn              = isDynamicExtName ext_nm
+
+  ok_ext_nm Dynamic               = True
+  ok_ext_nm (ExtName nm (Just mb)) = isCLabelString nm && isCLabelString mb
+  ok_ext_nm (ExtName nm Nothing)   = isCLabelString nm
 \end{code}
 
 \end{code}
 
+
 %*********************************************************
 %*                                                     *
 %*********************************************************
 %*                                                     *
-\subsection{Class declarations}
+\subsection{Instance declarations}
 %*                                                     *
 %*********************************************************
 
 %*                                                     *
 %*********************************************************
 
-@rnClassDecl@ uses the `global name function' to create a new
-class declaration in which local names have been replaced by their
-original names, reporting any unknown names.
-
 \begin{code}
 \begin{code}
-rnDecl (ClD (ClassDecl context cname tyvar sigs mbinds pragmas src_loc))
+rnInstDecl (InstDecl inst_ty mbinds uprags maybe_dfun_rdr_name src_loc)
   = pushSrcLocRn src_loc $
   = pushSrcLocRn src_loc $
-    bindTyVarsRn "class declaration" [tyvar]           $ \ [tyvar'] ->
-    rnContext context                                  `thenRn` \ context' ->
-    lookupBndrRn cname                                 `thenRn` \ cname' ->
-    mapRn (rn_op cname' (getTyVarName tyvar')) sigs    `thenRn` \ sigs' ->
-    rnMethodBinds mbinds                               `thenRn` \ mbinds' ->
-    ASSERT(isNoClassPragmas pragmas)
-    returnRn (ClD (ClassDecl context' cname' tyvar' sigs' mbinds' NoClassPragmas src_loc))
-  where
-    rn_op clas clas_tyvar sig@(ClassOpSig op _ ty locn)
-      = pushSrcLocRn locn $
-       let
-               dm_occ = prefixOccName SLIT("$m") (rdrNameOcc op)
-       in
-       lookupBndrRn op                         `thenRn` \ op_name ->
-       newSysName dm_occ Exported locn         `thenRn` \ dm_name ->
-        addOccurrenceName Optional dm_name     `thenRn_`
-               -- Call up interface info for default method, if such info exists
-       
-       rnHsType ty                     `thenRn` \ new_ty  ->
-       let
-           (ctxt, op_ty) = case new_ty of
-                               HsForAllTy tvs ctxt op_ty -> (ctxt, op_ty)
-                               other                     -> ([], new_ty)
-           ctxt_fvs  = extractCtxtTyNames ctxt
-           op_ty_fvs = extractHsTyNames op_ty          -- Includes tycons/classes but we
-                                                       -- don't care about that
-       in
-       -- check that class tyvar appears in op_ty
-        checkRn (clas_tyvar `elemNameSet` op_ty_fvs)
-               (classTyVarNotInOpTyErr clas_tyvar sig)
-                                                        `thenRn_`
-
-       -- check that class tyvar *doesn't* appear in the sig's context
-        checkRn (not (clas_tyvar `elemNameSet` ctxt_fvs))
-               (classTyVarInOpCtxtErr clas_tyvar sig)
-                                                        `thenRn_`
-
---     ASSERT(isNoClassOpPragmas pragmas)
-       returnRn (ClassOpSig op_name dm_name new_ty locn)
-\end{code}
+    rnHsSigType (text "an instance decl") inst_ty      `thenRn` \ inst_ty' ->
+
+    (case maybe_dfun_rdr_name of
+       Nothing            -> returnRn Nothing
+       Just dfun_rdr_name -> lookupIfaceName dfun_rdr_name     `thenRn` \ dfun_name ->
+                             returnRn (Just dfun_name)
+    )                                                  `thenRn` \ maybe_dfun_name ->
+
+    -- The typechecker checks that all the bindings are for the right class.
+    returnRn (InstDecl inst_ty' EmptyMonoBinds [] maybe_dfun_name src_loc)
+
+-- Compare rnClassBinds
+rnInstBinds (InstDecl _       mbinds uprags _                   _      )
+           (InstDecl inst_ty _      _      maybe_dfun_rdr_name src_loc)
+  = let
+       meth_doc    = text "the bindings in an instance declaration"
+       meth_names  = collectLocatedMonoBinders mbinds
+       inst_tyvars = case inst_ty of
+                       HsForAllTy (Just inst_tyvars) _ _ -> inst_tyvars
+                       other                             -> []
+       -- (Slightly strangely) the forall-d tyvars scope over
+       -- the method bindings too
+    in
 
 
+       -- Rename the bindings
+       -- NB meth_names can be qualified!
+    checkDupNames meth_doc meth_names          `thenRn_`
+    extendTyVarEnvFVRn (map hsTyVarName inst_tyvars) (         
+       rnMethodBinds [] mbinds
+    )                                          `thenRn` \ (mbinds', meth_fvs) ->
+    let 
+       binders    = collectMonoBinders mbinds'
+       binder_set = mkNameSet binders
+    in
+       -- Rename the prags and signatures.
+       -- Note that the type variables are not in scope here,
+       -- so that      instance Eq a => Eq (T a) where
+       --                      {-# SPECIALISE instance Eq a => Eq (T [a]) #-}
+       -- works OK. 
+       --
+       -- But the (unqualified) method names are in scope
+    bindLocalNames binders (
+       renameSigsFVs (okInstDclSig binder_set) uprags
+    )                                                  `thenRn` \ (uprags', prag_fvs) ->
+
+    returnRn (InstDecl inst_ty mbinds' uprags' maybe_dfun_rdr_name src_loc,
+             meth_fvs `plusFV` prag_fvs)
+\end{code}
 
 %*********************************************************
 %*                                                     *
 
 %*********************************************************
 %*                                                     *
-\subsection{Instance declarations}
+\subsection{Rules}
 %*                                                     *
 %*********************************************************
 
 \begin{code}
 %*                                                     *
 %*********************************************************
 
 \begin{code}
-rnDecl (InstD (InstDecl inst_ty mbinds uprags maybe_dfun src_loc))
-  = pushSrcLocRn src_loc $
-    rnHsType inst_ty                           `thenRn` \ inst_ty' ->
-    rnMethodBinds mbinds                       `thenRn` \ mbinds' ->
-    mapRn rn_uprag uprags                      `thenRn` \ new_uprags ->
-
-    newDfunName maybe_dfun src_loc             `thenRn` \ dfun_name ->
-    addOccurrenceName Compulsory dfun_name     `thenRn_`
-                       -- The dfun is not optional, because we use its version number
-                       -- to identify the version of the instance declaration
-
-    returnRn (InstD (InstDecl inst_ty' mbinds' new_uprags (Just dfun_name) src_loc))
+rnIfaceRuleDecl (IfaceRule rule_name vars fn args rhs src_loc)
+  = pushSrcLocRn src_loc       $
+    lookupOccRn fn             `thenRn` \ fn' ->
+    rnCoreBndrs vars           $ \ vars' ->
+    mapRn rnCoreExpr args      `thenRn` \ args' ->
+    rnCoreExpr rhs             `thenRn` \ rhs' ->
+    returnRn (IfaceRule rule_name vars' fn' args' rhs' src_loc)
+
+rnHsRuleDecl (HsRule rule_name tvs vars lhs rhs src_loc)
+  = ASSERT( null tvs )
+    pushSrcLocRn src_loc                       $
+
+    bindTyVarsFV2Rn doc (map UserTyVar sig_tvs)        $ \ sig_tvs' _ ->
+    bindLocalsFVRn doc (map get_var vars)      $ \ ids ->
+    mapFvRn rn_var (vars `zip` ids)            `thenRn` \ (vars', fv_vars) ->
+
+    rnExpr lhs                                 `thenRn` \ (lhs', fv_lhs) ->
+    rnExpr rhs                                 `thenRn` \ (rhs', fv_rhs) ->
+    checkRn (validRuleLhs ids lhs')
+           (badRuleLhsErr rule_name lhs')      `thenRn_`
+    let
+       bad_vars = [var | var <- ids, not (var `elemNameSet` fv_lhs)]
+    in
+    mapRn (addErrRn . badRuleVar rule_name) bad_vars   `thenRn_`
+    returnRn (HsRule rule_name sig_tvs' vars' lhs' rhs' src_loc,
+             fv_vars `plusFV` fv_lhs `plusFV` fv_rhs)
   where
   where
-    rn_uprag (SpecSig op ty using locn)
-      = pushSrcLocRn src_loc $
-       lookupBndrRn op                 `thenRn` \ op_name ->
-       rnHsType ty                     `thenRn` \ new_ty ->
-       rn_using using                  `thenRn` \ new_using ->
-       returnRn (SpecSig op_name new_ty new_using locn)
-
-    rn_uprag (InlineSig op locn)
-      = pushSrcLocRn locn $
-       lookupBndrRn op                 `thenRn` \ op_name ->
-       returnRn (InlineSig op_name locn)
-
-    rn_uprag (DeforestSig op locn)
-      = pushSrcLocRn locn $
-       lookupBndrRn op                 `thenRn` \ op_name ->
-       returnRn (DeforestSig op_name locn)
-
-    rn_uprag (MagicUnfoldingSig op str locn)
-      = pushSrcLocRn locn $
-       lookupBndrRn op                 `thenRn` \ op_name ->
-       returnRn (MagicUnfoldingSig op_name str locn)
-
-    rn_using Nothing  = returnRn Nothing
-    rn_using (Just v) = lookupOccRn v  `thenRn` \ new_v ->
-                       returnRn (Just new_v)
+    doc = text "the transformation rule" <+> ptext rule_name
+    sig_tvs = extractRuleBndrsTyVars vars
+  
+    get_var (RuleBndr v)      = v
+    get_var (RuleBndrSig v _) = v
+
+    rn_var (RuleBndr v, id)     = returnRn (RuleBndr id, emptyFVs)
+    rn_var (RuleBndrSig v t, id) = rnHsTypeFVs doc t   `thenRn` \ (t', fvs) ->
+                                  returnRn (RuleBndrSig id t', fvs)
 \end{code}
 
 \end{code}
 
+
 %*********************************************************
 %*                                                     *
 %*********************************************************
 %*                                                     *
-\subsection{Default declarations}
+\subsection{Type, class and iface sig declarations}
 %*                                                     *
 %*********************************************************
 
 %*                                                     *
 %*********************************************************
 
+@rnTyDecl@ uses the `global name function' to create a new type
+declaration in which local names have been replaced by their original
+names, reporting any unknown names.
+
+Renaming type variables is a pain. Because they now contain uniques,
+it is necessary to pass in an association list which maps a parsed
+tyvar to its @Name@ representation.
+In some cases (type signatures of values),
+it is even necessary to go over the type first
+in order to get the set of tyvars used by it, make an assoc list,
+and then go over it again to rename the tyvars!
+However, we can also do some scoping checks at the same time.
+
 \begin{code}
 \begin{code}
-rnDecl (DefD (DefaultDecl tys src_loc))
+rnTyClDecl (IfaceSig name ty id_infos loc)
+  = pushSrcLocRn loc $
+    lookupTopBndrRn name               `thenRn` \ name' ->
+    rnHsType doc_str ty                        `thenRn` \ ty' ->
+    mapRn rnIdInfo id_infos            `thenRn` \ id_infos' -> 
+    returnRn (IfaceSig name' ty' id_infos' loc)
+  where
+    doc_str = text "the interface signature for" <+> quotes (ppr name)
+
+rnTyClDecl (TyData new_or_data context tycon tyvars condecls nconstrs derivings src_loc gen_name1 gen_name2)
   = pushSrcLocRn src_loc $
   = pushSrcLocRn src_loc $
-    mapRn rnHsType tys                         `thenRn` \ tys' ->
-    lookupImplicitOccRn numClass_RDR   `thenRn_` 
-    returnRn (DefD (DefaultDecl tys' src_loc))
+    lookupTopBndrRn tycon                      `thenRn` \ tycon' ->
+    bindTyVarsRn data_doc tyvars               $ \ tyvars' ->
+    rnContext data_doc context                         `thenRn` \ context' ->
+    checkDupOrQualNames data_doc con_names     `thenRn_`
+    mapRn rnConDecl condecls                   `thenRn` \ condecls' ->
+    lookupSysBinder gen_name1                  `thenRn` \ name1' ->
+    lookupSysBinder gen_name2                  `thenRn` \ name2' ->
+    rnDerivs derivings                         `thenRn` \ derivings' ->
+    returnRn (TyData new_or_data context' tycon' tyvars' condecls' nconstrs
+                     derivings' src_loc name1' name2')
+  where
+    data_doc = text "the data type declaration for" <+> quotes (ppr tycon)
+    con_names = map conDeclName condecls
+
+rnTyClDecl (TySynonym name tyvars ty src_loc)
+  = pushSrcLocRn src_loc $
+    doptRn Opt_GlasgowExts                     `thenRn` \ glaExts ->
+    lookupTopBndrRn name                       `thenRn` \ name' ->
+    bindTyVarsRn syn_doc tyvars                $ \ tyvars' ->
+    rnHsType syn_doc (unquantify glaExts ty)   `thenRn` \ ty' ->
+    returnRn (TySynonym name' tyvars' ty' src_loc)
+  where
+    syn_doc = text "the declaration for type synonym" <+> quotes (ppr name)
+
+       -- For H98 we do *not* universally quantify on the RHS of a synonym
+       -- Silently discard context... but the tyvars in the rest won't be in scope
+    unquantify glaExts (HsForAllTy Nothing ctxt ty) | glaExts = ty
+    unquantify glaExys ty                                    = ty
+
+rnTyClDecl (ClassDecl context cname tyvars fds sigs mbinds names src_loc)
+  = pushSrcLocRn src_loc $
+
+    lookupTopBndrRn cname                      `thenRn` \ cname' ->
+
+       -- Deal with the implicit tycon and datacon name
+       -- They aren't in scope (because they aren't visible to the user)
+       -- and what we want to do is simply look them up in the cache;
+       -- we jolly well ought to get a 'hit' there!
+    mapRn lookupSysBinder names                        `thenRn` \ names' ->
+
+       -- Tyvars scope over bindings and context
+    bindTyVars2Rn cls_doc tyvars               $ \ clas_tyvar_names tyvars' ->
+
+       -- Check the superclasses
+    rnContext cls_doc context                  `thenRn` \ context' ->
+
+       -- Check the functional dependencies
+    rnFds cls_doc fds                          `thenRn` \ fds' ->
+
+       -- Check the signatures
+       -- First process the class op sigs (op_sigs), then the fixity sigs (non_op_sigs).
+    let
+       (op_sigs, non_op_sigs) = partition isClassOpSig sigs
+       sig_rdr_names_w_locs   = [(op,locn) | ClassOpSig op _ _ locn <- sigs]
+    in
+    checkDupOrQualNames sig_doc sig_rdr_names_w_locs           `thenRn_` 
+    mapRn (rnClassOp cname' clas_tyvar_names fds') op_sigs     `thenRn` \ sigs' ->
+    let
+       binders = mkNameSet [ nm | (ClassOpSig nm _ _ _) <- sigs' ]
+    in
+    renameSigs (okClsDclSig binders) non_op_sigs         `thenRn` \ non_ops' ->
+
+       -- Typechecker is responsible for checking that we only
+       -- give default-method bindings for things in this class.
+       -- The renamer *could* check this for class decls, but can't
+       -- for instance decls.
+
+    returnRn (ClassDecl context' cname' tyvars' fds' (non_ops' ++ sigs') EmptyMonoBinds names' src_loc)
+  where
+    cls_doc  = text "the declaration for class"        <+> ppr cname
+    sig_doc  = text "the signatures for class"         <+> ppr cname
+
+rnClassOp clas clas_tyvars clas_fds sig@(ClassOpSig op maybe_dm_stuff ty locn)
+  = pushSrcLocRn locn $
+    lookupTopBndrRn op                 `thenRn` \ op_name ->
+    
+       -- Check the signature
+    rnHsSigType (quotes (ppr op)) ty   `thenRn` \ new_ty ->
+    
+       -- Make the default-method name
+    (case maybe_dm_stuff of 
+        Nothing -> returnRn Nothing                    -- Source-file class decl
+    
+        Just (DefMeth dm_rdr_name)
+           ->  -- Imported class that has a default method decl
+               -- See comments with tname, snames, above
+               lookupSysBinder dm_rdr_name     `thenRn` \ dm_name ->
+               returnRn (Just (DefMeth dm_name))
+                       -- An imported class decl for a class decl that had an explicit default
+                       -- method, mentions, rather than defines,
+                       -- the default method, so we must arrange to pull it in
+
+        Just GenDefMeth        -> returnRn (Just GenDefMeth)
+        Just NoDefMeth         -> returnRn (Just NoDefMeth)
+    )                                          `thenRn` \ maybe_dm_stuff' ->
+    
+    returnRn (ClassOpSig op_name maybe_dm_stuff' new_ty locn)
+
+rnClassBinds :: RdrNameTyClDecl -> RenamedTyClDecl -> RnMS (RenamedTyClDecl, FreeVars)
+  -- Rename the mbinds only; the rest is done already
+rnClassBinds (ClassDecl _       _     _      _   _    mbinds _     _      )    -- Get mbinds from here
+            (ClassDecl context cname tyvars fds sigs _      names src_loc)     -- Everything else is here
+  =    -- The newLocals call is tiresome: given a generic class decl
+       --      class C a where
+       --        op :: a -> a
+       --        op {| x+y |} (Inl a) = ...
+       --        op {| x+y |} (Inr b) = ...
+       --        op {| a*b |} (a*b)   = ...
+       -- we want to name both "x" tyvars with the same unique, so that they are
+       -- easy to group together in the typechecker.  
+       -- Hence the 
+    extendTyVarEnvFVRn (map hsTyVarName tyvars)                $
+    getLocalNameEnv                                    `thenRn` \ name_env ->
+    let
+       meth_rdr_names_w_locs = collectLocatedMonoBinders mbinds
+       gen_rdr_tyvars_w_locs = [(tv,src_loc) | tv <- extractGenericPatTyVars mbinds,
+                                               not (tv `elemRdrEnv` name_env)]
+    in
+    checkDupOrQualNames meth_doc meth_rdr_names_w_locs `thenRn_`
+    newLocalsRn gen_rdr_tyvars_w_locs                  `thenRn` \ gen_tyvars ->
+    rnMethodBinds gen_tyvars mbinds                    `thenRn` \ (mbinds', meth_fvs) ->
+    returnRn (ClassDecl context cname tyvars fds sigs mbinds' names src_loc, meth_fvs)
+  where
+    meth_doc = text "the default-methods for class"    <+> ppr cname
+
+rnClassBinds _ tycl_decl = returnRn (tycl_decl, emptyFVs)
+       -- Not a class declaration
 \end{code}
 
 \end{code}
 
+
 %*********************************************************
 %*                                                     *
 \subsection{Support code for type/data declarations}
 %*********************************************************
 %*                                                     *
 \subsection{Support code for type/data declarations}
@@ -269,74 +430,74 @@ rnDecl (DefD (DefaultDecl tys src_loc))
 %*********************************************************
 
 \begin{code}
 %*********************************************************
 
 \begin{code}
-rnDerivs :: Maybe [RdrName] -> RnMS s (Maybe [Name])
+rnDerivs :: Maybe [RdrName] -> RnMS (Maybe [Name])
 
 rnDerivs Nothing -- derivs not specified
 
 rnDerivs Nothing -- derivs not specified
-  = lookupImplicitOccRn evalClass_RDR          `thenRn_`
-    returnRn Nothing
+  = returnRn Nothing
 
 
-rnDerivs (Just ds)
-  = lookupImplicitOccRn evalClass_RDR          `thenRn_`
-    mapRn rn_deriv ds `thenRn` \ derivs ->
-    returnRn (Just derivs)
+rnDerivs (Just clss)
+  = mapRn do_one clss  `thenRn` \ clss' ->
+    returnRn (Just clss')
   where
   where
-    rn_deriv clas
-      = lookupOccRn clas           `thenRn` \ clas_name ->
-
-               -- Now add extra "occurrences" for things that
-               -- the deriving mechanism will later need in order to
-               -- generate code for this class.
-       case lookupUFM derivingOccurrences clas_name of
-               Nothing -> addErrRn (derivingNonStdClassErr clas_name)  `thenRn_`
-                          returnRn clas_name
-
-               Just occs -> mapRn lookupImplicitOccRn occs     `thenRn_`
-                            returnRn clas_name
+    do_one cls = lookupOccRn cls       `thenRn` \ clas_name ->
+                checkRn (getUnique clas_name `elem` derivableClassKeys)
+                        (derivingNonStdClassErr clas_name)     `thenRn_`
+                returnRn clas_name
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-rnConDecl :: RdrNameConDecl -> RnMS s RenamedConDecl
+conDeclName :: RdrNameConDecl -> (RdrName, SrcLoc)
+conDeclName (ConDecl n _ _ _ _ l) = (n,l)
 
 
-rnConDecl (ConDecl name tys src_loc)
-  = pushSrcLocRn src_loc $
+rnConDecl :: RdrNameConDecl -> RnMS RenamedConDecl
+rnConDecl (ConDecl name wkr tvs cxt details locn)
+  = pushSrcLocRn locn $
     checkConName name          `thenRn_` 
     checkConName name          `thenRn_` 
-    lookupBndrRn name          `thenRn` \ new_name ->
-    mapRn rnBangTy tys         `thenRn` \ new_tys  ->
-    returnRn (ConDecl new_name new_tys src_loc)
+    lookupTopBndrRn name       `thenRn` \ new_name ->
 
 
-rnConDecl (ConOpDecl ty1 op ty2 src_loc)
-  = pushSrcLocRn src_loc $
-    lookupBndrRn op                    `thenRn` \ new_op  ->
-    rnBangTy ty1               `thenRn` \ new_ty1 ->
-    rnBangTy ty2               `thenRn` \ new_ty2 ->
-    returnRn (ConOpDecl new_ty1 new_op new_ty2 src_loc)
+    lookupSysBinder wkr                `thenRn` \ new_wkr ->
+       -- See comments with ClassDecl
 
 
-rnConDecl (NewConDecl name ty src_loc)
-  = pushSrcLocRn src_loc $
-    checkConName name          `thenRn_` 
-    lookupBndrRn name          `thenRn` \ new_name ->
-    rnHsType ty                        `thenRn` \ new_ty  ->
-    returnRn (NewConDecl new_name new_ty src_loc)
+    bindTyVarsRn doc tvs               $ \ new_tyvars ->
+    rnContext doc cxt                  `thenRn` \ new_context ->
+    rnConDetails doc locn details      `thenRn` \ new_details -> 
+    returnRn (ConDecl new_name new_wkr new_tyvars new_context new_details locn)
+  where
+    doc = text "the definition of data constructor" <+> quotes (ppr name)
 
 
-rnConDecl (RecConDecl name fields src_loc)
-  = pushSrcLocRn src_loc $
-    lookupBndrRn name          `thenRn` \ new_name ->
-    mapRn rnField fields       `thenRn` \ new_fields ->
-    returnRn (RecConDecl new_name new_fields src_loc)
+rnConDetails doc locn (VanillaCon tys)
+  = mapRn (rnBangTy doc) tys   `thenRn` \ new_tys  ->
+    returnRn (VanillaCon new_tys)
 
 
-rnField (names, ty)
-  = mapRn lookupBndrRn names   `thenRn` \ new_names ->
-    rnBangTy ty                        `thenRn` \ new_ty ->
+rnConDetails doc locn (InfixCon ty1 ty2)
+  = rnBangTy doc ty1           `thenRn` \ new_ty1 ->
+    rnBangTy doc ty2           `thenRn` \ new_ty2 ->
+    returnRn (InfixCon new_ty1 new_ty2)
+
+rnConDetails doc locn (RecCon fields)
+  = checkDupOrQualNames doc field_names        `thenRn_`
+    mapRn (rnField doc) fields         `thenRn` \ new_fields ->
+    returnRn (RecCon new_fields)
+  where
+    field_names = [(fld, locn) | (flds, _) <- fields, fld <- flds]
+
+rnField doc (names, ty)
+  = mapRn lookupTopBndrRn names        `thenRn` \ new_names ->
+    rnBangTy doc ty            `thenRn` \ new_ty ->
     returnRn (new_names, new_ty) 
 
     returnRn (new_names, new_ty) 
 
-rnBangTy (Banged ty)
-  = rnHsType ty `thenRn` \ new_ty ->
+rnBangTy doc (Banged ty)
+  = rnHsType doc ty            `thenRn` \ new_ty ->
     returnRn (Banged new_ty)
 
     returnRn (Banged new_ty)
 
-rnBangTy (Unbanged ty)
-  = rnHsType ty `thenRn` \ new_ty ->
+rnBangTy doc (Unbanged ty)
+  = rnHsType doc ty            `thenRn` \ new_ty ->
     returnRn (Unbanged new_ty)
 
     returnRn (Unbanged new_ty)
 
+rnBangTy doc (Unpacked ty)
+  = rnHsType doc ty            `thenRn` \ new_ty ->
+    returnRn (Unpacked new_ty)
+
 -- This data decl will parse OK
 --     data T = a Int
 -- treating "a" as the constructor.
 -- This data decl will parse OK
 --     data T = a Int
 -- treating "a" as the constructor.
@@ -348,7 +509,7 @@ rnBangTy (Unbanged ty)
 -- from interface files, which always print in prefix form
 
 checkConName name
 -- from interface files, which always print in prefix form
 
 checkConName name
-  = checkRn (isLexCon (occNameString (rdrNameOcc name)))
+  = checkRn (isRdrDataCon name)
            (badDataCon name)
 \end{code}
 
            (badDataCon name)
 \end{code}
 
@@ -360,152 +521,240 @@ checkConName name
 %*********************************************************
 
 \begin{code}
 %*********************************************************
 
 \begin{code}
-rnHsType :: RdrNameHsType -> RnMS s RenamedHsType
-
-rnHsType (HsForAllTy tvs ctxt ty)
-  = rn_poly_help tvs ctxt ty
-
-rnHsType full_ty@(HsPreForAllTy ctxt ty)
-  = getNameEnv         `thenRn` \ name_env ->
+rnHsTypeFVs :: SDoc -> RdrNameHsType -> RnMS (RenamedHsType, FreeVars)
+rnHsTypeFVs doc_str ty 
+  = rnHsType doc_str ty                `thenRn` \ ty' ->
+    returnRn (ty', extractHsTyNames ty')
+
+rnHsSigTypeFVs :: SDoc -> RdrNameHsType -> RnMS (RenamedHsType, FreeVars)
+rnHsSigTypeFVs doc_str ty
+  = rnHsSigType doc_str ty     `thenRn` \ ty' ->
+    returnRn (ty', extractHsTyNames ty')
+
+rnHsSigType :: SDoc -> RdrNameHsType -> RnMS RenamedHsType
+       -- rnHsSigType is used for source-language type signatures,
+       -- which use *implicit* universal quantification.
+rnHsSigType doc_str ty
+  = rnHsType (text "the type signature for" <+> doc_str) ty
+    
+---------------------------------------
+rnHsType :: SDoc -> RdrNameHsType -> RnMS RenamedHsType
+
+rnHsType doc (HsForAllTy Nothing ctxt ty)
+       -- Implicit quantifiction in source code (no kinds on tyvars)
+       -- Given the signature  C => T  we universally quantify 
+       -- over FV(T) \ {in-scope-tyvars} 
+  = getLocalNameEnv            `thenRn` \ name_env ->
     let
     let
-       mentioned_tyvars = extractHsTyVars full_ty
-       forall_tyvars    = filter not_in_scope mentioned_tyvars
-       not_in_scope tv  = case lookupFM name_env tv of
-                                   Nothing -> True
-                                   Just _  -> False
+       mentioned_in_tau  = extractHsTyRdrTyVars ty
+       mentioned_in_ctxt = extractHsCtxtRdrTyVars ctxt
+       mentioned         = nub (mentioned_in_tau ++ mentioned_in_ctxt)
+       forall_tyvars     = filter (not . (`elemRdrEnv` name_env)) mentioned
+    in
+    rnForAll doc (map UserTyVar forall_tyvars) ctxt ty
+
+rnHsType doc (HsForAllTy (Just forall_tyvars) ctxt tau)
+       -- Explicit quantification.
+       -- Check that the forall'd tyvars are actually 
+       -- mentioned in the type, and produce a warning if not
+  = let
+       mentioned_in_tau                = extractHsTyRdrTyVars tau
+       mentioned_in_ctxt               = extractHsCtxtRdrTyVars ctxt
+       mentioned                       = nub (mentioned_in_tau ++ mentioned_in_ctxt)
+       forall_tyvar_names              = hsTyVarNames forall_tyvars
+
+       -- Explicitly quantified but not mentioned in ctxt or tau
+       warn_guys                       = filter (`notElem` mentioned) forall_tyvar_names
     in
     in
-    rn_poly_help (map UserTyVar forall_tyvars) ctxt ty
+    mapRn_ (forAllWarn doc tau) warn_guys      `thenRn_`
+    rnForAll doc forall_tyvars ctxt tau
 
 
-rnHsType (MonoTyVar tyvar)
+rnHsType doc (HsTyVar tyvar)
   = lookupOccRn tyvar          `thenRn` \ tyvar' ->
   = lookupOccRn tyvar          `thenRn` \ tyvar' ->
-    returnRn (MonoTyVar tyvar')
-
-rnHsType (MonoFunTy ty1 ty2)
-  = andRn MonoFunTy (rnHsType ty1) (rnHsType ty2)
-
-rnHsType (MonoListTy _ ty)
-  = lookupImplicitOccRn listType_RDR           `thenRn` \ tycon_name ->
-    rnHsType ty                                        `thenRn` \ ty' ->
-    returnRn (MonoListTy tycon_name ty')
-
-rnHsType (MonoTupleTy _ tys)
-  = lookupImplicitOccRn (tupleType_RDR (length tys))   `thenRn` \ tycon_name ->
-    mapRn rnHsType tys                                 `thenRn` \ tys' ->
-    returnRn (MonoTupleTy tycon_name tys')
-
-rnHsType (MonoTyApp ty1 ty2)
-  = rnHsType ty1               `thenRn` \ ty1' ->
-    rnHsType ty2               `thenRn` \ ty2' ->
-    returnRn (MonoTyApp ty1' ty2')
-
-rnHsType (MonoDictTy clas ty)
-  = lookupOccRn clas           `thenRn` \ clas' ->
-    rnHsType ty                        `thenRn` \ ty' ->
-    returnRn (MonoDictTy clas' ty')
-
-
-rn_poly_help :: [HsTyVar RdrName]              -- Universally quantified tyvars
-            -> RdrNameContext
-            -> RdrNameHsType
-            -> RnMS s RenamedHsType
-
-rn_poly_help tyvars ctxt ty
-  = bindTyVarsRn "type signature" tyvars               $ \ new_tyvars ->
-    rnContext ctxt                                     `thenRn` \ new_ctxt ->
-    rnHsType ty                                                `thenRn` \ new_ty ->
-    returnRn (HsForAllTy new_tyvars new_ctxt new_ty)
+    returnRn (HsTyVar tyvar')
+
+rnHsType doc (HsOpTy ty1 opname ty2)
+  = lookupOccRn opname `thenRn` \ name' ->
+    rnHsType doc ty1   `thenRn` \ ty1' ->
+    rnHsType doc ty2   `thenRn` \ ty2' -> 
+    returnRn (HsOpTy ty1' name' ty2')
+
+rnHsType doc (HsNumTy i)
+  | i == 1    = returnRn (HsNumTy i)
+  | otherwise = failWithRn (HsNumTy i)
+                          (ptext SLIT("Only unit numeric type pattern is valid"))
+
+rnHsType doc (HsFunTy ty1 ty2)
+  = rnHsType doc ty1   `thenRn` \ ty1' ->
+       -- Might find a for-all as the arg of a function type
+    rnHsType doc ty2   `thenRn` \ ty2' ->
+       -- Or as the result.  This happens when reading Prelude.hi
+       -- when we find return :: forall m. Monad m -> forall a. a -> m a
+    returnRn (HsFunTy ty1' ty2')
+
+rnHsType doc (HsListTy ty)
+  = rnHsType doc ty                            `thenRn` \ ty' ->
+    returnRn (HsListTy ty')
+
+-- Unboxed tuples are allowed to have poly-typed arguments.  These
+-- sometimes crop up as a result of CPR worker-wrappering dictionaries.
+rnHsType doc (HsTupleTy (HsTupCon _ boxity) tys)
+       -- Don't do lookupOccRn, because this is built-in syntax
+       -- so it doesn't need to be in scope
+  = mapRn (rnHsType doc) tys           `thenRn` \ tys' ->
+    returnRn (HsTupleTy (HsTupCon n' boxity) tys')
+  where
+    n' = tupleTyCon_name boxity (length tys)
+  
+
+rnHsType doc (HsAppTy ty1 ty2)
+  = rnHsType doc ty1           `thenRn` \ ty1' ->
+    rnHsType doc ty2           `thenRn` \ ty2' ->
+    returnRn (HsAppTy ty1' ty2')
+
+rnHsType doc (HsPredTy pred)
+  = rnPred doc pred    `thenRn` \ pred' ->
+    returnRn (HsPredTy pred')
+
+rnHsTypes doc tys = mapRn (rnHsType doc) tys
 \end{code}
 
 \end{code}
 
+\begin{code}
+-- We use lookupOcc here because this is interface file only stuff
+-- and we need the workers...
+rnHsTupCon (HsTupCon n boxity)
+  = lookupOccRn n      `thenRn` \ n' ->
+    returnRn (HsTupCon n' boxity)
+
+rnHsTupConWkr (HsTupCon n boxity)
+       -- Tuple construtors are for the *worker* of the tuple
+       -- Going direct saves needless messing about 
+  = lookupOccRn (mkRdrNameWkr n)       `thenRn` \ n' ->
+    returnRn (HsTupCon n' boxity)
+\end{code}
 
 \begin{code}
 
 \begin{code}
-rnContext :: RdrNameContext -> RnMS s RenamedContext
+rnForAll doc forall_tyvars ctxt ty
+  = bindTyVarsRn doc forall_tyvars     $ \ new_tyvars ->
+    rnContext doc ctxt                 `thenRn` \ new_ctxt ->
+    rnHsType doc ty                    `thenRn` \ new_ty ->
+    returnRn (mkHsForAllTy (Just new_tyvars) new_ctxt new_ty)
+\end{code}
 
 
-rnContext  ctxt
-  = mapRn rn_ctxt ctxt `thenRn` \ result ->
+\begin{code}
+rnContext :: SDoc -> RdrNameContext -> RnMS RenamedContext
+rnContext doc ctxt
+  = mapRn rn_pred ctxt         `thenRn` \ theta ->
     let
     let
-       (_, dup_asserts) = removeDups cmp_assert result
+       (_, dups) = removeDupsEq theta
+               -- We only have equality, not ordering
     in
     in
-    -- If this isn't an error, then it ought to be:
-    mapRn (addWarnRn . dupClassAssertWarn result) dup_asserts `thenRn_`
-    returnRn result
+       -- Check for duplicate assertions
+       -- If this isn't an error, then it ought to be:
+    mapRn (addWarnRn . dupClassAssertWarn theta) dups          `thenRn_`
+    returnRn theta
   where
   where
-    rn_ctxt (clas, ty)
-      = lookupOccRn clas       `thenRn` \ clas_name ->
-       rnHsType ty             `thenRn` \ ty' ->
-       returnRn (clas_name, ty')
-
-    cmp_assert (c1,ty1) (c2,ty2)
-      = (c1 `cmp` c2) `thenCmp` (cmpHsType cmp ty1 ty2)
+       --Someone discovered that @CCallable@ and @CReturnable@
+       -- could be used in contexts such as:
+       --      foo :: CCallable a => a -> PrimIO Int
+       -- Doing this utterly wrecks the whole point of introducing these
+       -- classes so we specifically check that this isn't being done.
+    rn_pred pred = rnPred doc pred                             `thenRn` \ pred'->
+                  checkRn (not (bad_pred pred'))
+                          (naughtyCCallContextErr pred')       `thenRn_`
+                  returnRn pred'
+
+    bad_pred (HsPClass clas _) = getUnique clas `elem` cCallishClassKeys
+    bad_pred other            = False
+
+
+rnPred doc (HsPClass clas tys)
+  = lookupOccRn clas           `thenRn` \ clas_name ->
+    rnHsTypes doc tys          `thenRn` \ tys' ->
+    returnRn (HsPClass clas_name tys')
+
+rnPred doc (HsPIParam n ty)
+  = newIPName n                        `thenRn` \ name ->
+    rnHsType doc ty            `thenRn` \ ty' ->
+    returnRn (HsPIParam name ty')
 \end{code}
 
 \end{code}
 
+\begin{code}
+rnFds :: SDoc -> [FunDep RdrName] -> RnMS [FunDep Name]
+
+rnFds doc fds
+  = mapRn rn_fds fds
+  where
+    rn_fds (tys1, tys2)
+      =        rnHsTyVars doc tys1             `thenRn` \ tys1' ->
+       rnHsTyVars doc tys2             `thenRn` \ tys2' ->
+       returnRn (tys1', tys2')
+
+rnHsTyVars doc tvs  = mapRn (rnHsTyvar doc) tvs
+rnHsTyvar doc tyvar = lookupOccRn tyvar
+\end{code}
 
 %*********************************************************
 
 %*********************************************************
-%*                                                     *
+%*                                                      *
 \subsection{IdInfo}
 \subsection{IdInfo}
-%*                                                     *
+%*                                                      *
 %*********************************************************
 
 \begin{code}
 %*********************************************************
 
 \begin{code}
-rnIdInfo (HsStrictness strict)
-  = rnStrict strict    `thenRn` \ strict' ->
-    returnRn (HsStrictness strict')
+rnIdInfo (HsWorker worker)
+  = lookupOccRn worker                 `thenRn` \ worker' ->
+    returnRn (HsWorker worker')
 
 
-rnIdInfo (HsUnfold expr)       = rnCoreExpr expr       `thenRn` \ expr' ->
-                                 returnRn (HsUnfold expr')
+rnIdInfo (HsUnfold inline expr)        = rnCoreExpr expr `thenRn` \ expr' ->
+                                 returnRn (HsUnfold inline expr')
+rnIdInfo (HsStrictness str)     = returnRn (HsStrictness str)
 rnIdInfo (HsArity arity)       = returnRn (HsArity arity)
 rnIdInfo (HsArity arity)       = returnRn (HsArity arity)
-rnIdInfo (HsUpdate update)     = returnRn (HsUpdate update)
-rnIdInfo (HsFBType fb)         = returnRn (HsFBType fb)
-rnIdInfo (HsArgUsage au)       = returnRn (HsArgUsage au)
-rnIdInfo (HsDeforest df)       = returnRn (HsDeforest df)
-
-rnStrict (StrictnessInfo demands (Just worker))
-  = lookupOptionalOccRn worker         `thenRn` \ worker' ->
-    returnRn (StrictnessInfo demands (Just worker'))
-
--- Boring, but necessary for the type checker.
-rnStrict (StrictnessInfo demands Nothing) = returnRn (StrictnessInfo demands Nothing)
-rnStrict BottomGuaranteed                = returnRn BottomGuaranteed
-rnStrict NoStrictnessInfo                = returnRn NoStrictnessInfo
+rnIdInfo HsNoCafRefs           = returnRn HsNoCafRefs
+rnIdInfo HsCprInfo             = returnRn HsCprInfo
 \end{code}
 
 \end{code}
 
-UfCore expressions.
+@UfCore@ expressions.
 
 \begin{code}
 
 \begin{code}
+rnCoreExpr (UfType ty)
+  = rnHsType (text "unfolding type") ty        `thenRn` \ ty' ->
+    returnRn (UfType ty')
+
 rnCoreExpr (UfVar v)
 rnCoreExpr (UfVar v)
-  = lookupOptionalOccRn v      `thenRn` \ v' ->
+  = lookupOccRn v      `thenRn` \ v' ->
     returnRn (UfVar v')
 
     returnRn (UfVar v')
 
-rnCoreExpr (UfLit lit) = returnRn (UfLit lit)
+rnCoreExpr (UfLit l)
+  = returnRn (UfLit l)
+
+rnCoreExpr (UfLitLit l ty)
+  = rnHsType (text "litlit") ty        `thenRn` \ ty' ->
+    returnRn (UfLitLit l ty')
 
 
-rnCoreExpr (UfCon con args) 
-  = lookupOptionalOccRn con            `thenRn` \ con' ->
-    mapRn rnCoreArg args       `thenRn` \ args' ->
-    returnRn (UfCon con' args')
+rnCoreExpr (UfCCall cc ty)
+  = rnHsType (text "ccall") ty `thenRn` \ ty' ->
+    returnRn (UfCCall cc ty')
 
 
-rnCoreExpr (UfPrim prim args) 
-  = rnCorePrim prim            `thenRn` \ prim' ->
-    mapRn rnCoreArg args       `thenRn` \ args' ->
-    returnRn (UfPrim prim' args')
+rnCoreExpr (UfTuple con args) 
+  = rnHsTupConWkr con                  `thenRn` \ con' ->
+    mapRn rnCoreExpr args              `thenRn` \ args' ->
+    returnRn (UfTuple con' args')
 
 rnCoreExpr (UfApp fun arg)
   = rnCoreExpr fun             `thenRn` \ fun' ->
 
 rnCoreExpr (UfApp fun arg)
   = rnCoreExpr fun             `thenRn` \ fun' ->
-    rnCoreArg arg              `thenRn` \ arg' ->
+    rnCoreExpr arg             `thenRn` \ arg' ->
     returnRn (UfApp fun' arg')
 
     returnRn (UfApp fun' arg')
 
-rnCoreExpr (UfCase scrut alts) 
-  = rnCoreExpr scrut           `thenRn` \ scrut' ->
-    rnCoreAlts alts            `thenRn` \ alts' ->
-    returnRn (UfCase scrut' alts')
+rnCoreExpr (UfCase scrut bndr alts)
+  = rnCoreExpr scrut                   `thenRn` \ scrut' ->
+    bindCoreLocalRn bndr               $ \ bndr' ->
+    mapRn rnCoreAlt alts               `thenRn` \ alts' ->
+    returnRn (UfCase scrut' bndr' alts')
 
 
-rnCoreExpr (UfSCC cc expr) 
-  = rnCoreExpr expr            `thenRn` \ expr' ->
-    returnRn  (UfSCC cc expr') 
-
-rnCoreExpr(UfCoerce coercion ty body)
-  = rnCoercion coercion                `thenRn` \ coercion' ->
-    rnHsType ty                        `thenRn` \ ty' ->
-    rnCoreExpr body            `thenRn` \ body' ->
-    returnRn (UfCoerce coercion' ty' body')
+rnCoreExpr (UfNote note expr) 
+  = rnNote note                        `thenRn` \ note' ->
+    rnCoreExpr expr            `thenRn` \ expr' ->
+    returnRn  (UfNote note' expr')
 
 rnCoreExpr (UfLam bndr body)
   = rnCoreBndr bndr            $ \ bndr' ->
 
 rnCoreExpr (UfLam bndr body)
   = rnCoreBndr bndr            $ \ bndr' ->
@@ -529,149 +778,133 @@ rnCoreExpr (UfLet (UfRec pairs) body)
 
 \begin{code}
 rnCoreBndr (UfValBinder name ty) thing_inside
 
 \begin{code}
 rnCoreBndr (UfValBinder name ty) thing_inside
-  = rnHsType ty                        `thenRn` \ ty' ->
-    bindLocalsRn "unfolding value" [name] $ \ [name'] ->
+  = rnHsType doc ty            `thenRn` \ ty' ->
+    bindCoreLocalRn name       $ \ name' ->
     thing_inside (UfValBinder name' ty')
     thing_inside (UfValBinder name' ty')
+  where
+    doc = text "unfolding id"
     
 rnCoreBndr (UfTyBinder name kind) thing_inside
     
 rnCoreBndr (UfTyBinder name kind) thing_inside
-  = bindLocalsRn "unfolding tyvar" [name] $ \ [name'] ->
+  = bindCoreLocalRn name               $ \ name' ->
     thing_inside (UfTyBinder name' kind)
     
     thing_inside (UfTyBinder name' kind)
     
-rnCoreBndr (UfUsageBinder name) thing_inside
-  = bindLocalsRn "unfolding usage" [name] $ \ [name'] ->
-    thing_inside (UfUsageBinder name')
-
-rnCoreBndrs bndrs thing_inside         -- Expect them all to be ValBinders
-  = mapRn rnHsType tys                 `thenRn` \ tys' ->
-    bindLocalsRn "unfolding value" names $ \ names' ->
-    thing_inside (zipWith UfValBinder names' tys')
-  where
-    names = map (\ (UfValBinder name _) -> name) bndrs
-    tys   = map (\ (UfValBinder _   ty) -> ty)   bndrs
-
-rnCoreBndrNamess names thing_inside
-  = bindLocalsRn "unfolding value" names $ \ names' ->
-    thing_inside names'
+rnCoreBndrs []     thing_inside = thing_inside []
+rnCoreBndrs (b:bs) thing_inside = rnCoreBndr b         $ \ name' ->
+                                 rnCoreBndrs bs        $ \ names' ->
+                                 thing_inside (name':names')
 \end{code}    
 
 \begin{code}
 \end{code}    
 
 \begin{code}
-rnCoreArg (UfVarArg v)  = lookupOptionalOccRn v        `thenRn` \ v' -> returnRn (UfVarArg v')
-rnCoreArg (UfUsageArg u) = lookupOptionalOccRn u       `thenRn` \ u' -> returnRn (UfUsageArg u')
-rnCoreArg (UfTyArg ty)  = rnHsType ty                  `thenRn` \ ty' -> returnRn (UfTyArg ty')
-rnCoreArg (UfLitArg lit) = returnRn (UfLitArg lit)
-
-rnCoreAlts (UfAlgAlts alts deflt)
-  = mapRn rn_alt alts          `thenRn` \ alts' ->
-    rnCoreDefault deflt                `thenRn` \ deflt' ->
-    returnRn (UfAlgAlts alts' deflt')
-  where
-    rn_alt (con, bndrs, rhs) = lookupOptionalOccRn con                 `thenRn` \ con' ->
-                               bindLocalsRn "unfolding alt" bndrs      $ \ bndrs' ->
-                               rnCoreExpr rhs                          `thenRn` \ rhs' ->
-                               returnRn (con', bndrs', rhs')
-
-rnCoreAlts (UfPrimAlts alts deflt)
-  = mapRn rn_alt alts          `thenRn` \ alts' ->
-    rnCoreDefault deflt                `thenRn` \ deflt' ->
-    returnRn (UfPrimAlts alts' deflt')
-  where
-    rn_alt (lit, rhs) =        rnCoreExpr rhs          `thenRn` \ rhs' ->
-                       returnRn (lit, rhs')
+rnCoreAlt (con, bndrs, rhs)
+  = rnUfCon con bndrs                  `thenRn` \ con' ->
+    bindCoreLocalsRn bndrs             $ \ bndrs' ->
+    rnCoreExpr rhs                     `thenRn` \ rhs' ->
+    returnRn (con', bndrs', rhs')
 
 
-rnCoreDefault UfNoDefault = returnRn UfNoDefault
-rnCoreDefault (UfBindDefault bndr rhs) = bindLocalsRn "unfolding default" [bndr]       $ \ [bndr'] ->
-                                        rnCoreExpr rhs                                 `thenRn` \ rhs' ->
-                                        returnRn (UfBindDefault bndr' rhs')
+rnNote (UfCoerce ty)
+  = rnHsType (text "unfolding coerce") ty      `thenRn` \ ty' ->
+    returnRn (UfCoerce ty')
 
 
-rnCoercion (UfIn  n) = lookupOptionalOccRn n `thenRn` \ n' -> returnRn (UfIn  n')
-rnCoercion (UfOut n) = lookupOptionalOccRn n `thenRn` \ n' -> returnRn (UfOut n')
+rnNote (UfSCC cc)   = returnRn (UfSCC cc)
+rnNote UfInlineCall = returnRn UfInlineCall
+rnNote UfInlineMe   = returnRn UfInlineMe
 
 
-rnCorePrim (UfOtherOp op) 
-  = lookupOptionalOccRn op     `thenRn` \ op' ->
-    returnRn (UfOtherOp op')
 
 
-rnCorePrim (UfCCallOp str casm gc arg_tys res_ty)
-  = mapRn rnHsType arg_tys     `thenRn` \ arg_tys' ->
-    rnHsType res_ty            `thenRn` \ res_ty' ->
-    returnRn (UfCCallOp str casm gc arg_tys' res_ty')
-\end{code}
-
-%*********************************************************
-%*                                                     *
-\subsection{Errors}
-%*                                                     *
-%*********************************************************
-
-\begin{code}
-derivingNonStdClassErr clas sty
-  = ppCat [ppPStr SLIT("non-standard class in deriving:"), ppr sty clas]
-
-classTyVarNotInOpTyErr clas_tyvar sig sty
-  = ppHang (ppBesides [ppPStr SLIT("Class type variable `"), 
-                      ppr sty clas_tyvar, 
-                      ppPStr SLIT("' does not appear in method signature:")])
-        4 (ppr sty sig)
-
-classTyVarInOpCtxtErr clas_tyvar sig sty
-  = ppHang (ppBesides [ ppPStr SLIT("Class type variable `"), ppr sty clas_tyvar, 
-                       ppPStr SLIT("' present in method's local overloading context:")])
-        4 (ppr sty sig)
-
-dupClassAssertWarn ctxt dups sty
-  = ppHang (ppBesides [ppPStr SLIT("Duplicate class assertion `"), 
-                      ppr sty dups, 
-                      ppPStr SLIT("' in context:")])
-        4 (ppr sty ctxt)
-
-badDataCon name sty
-   = ppCat [ppPStr SLIT("Illegal data constructor name:"), ppr sty name]
-\end{code}
+rnUfCon UfDefault _
+  = returnRn UfDefault
 
 
+rnUfCon (UfTupleAlt tup_con) bndrs
+  = rnHsTupCon tup_con                 `thenRn` \ (HsTupCon con' _) -> 
+    returnRn (UfDataAlt con')
+       -- Makes the type checker a little easier
 
 
+rnUfCon (UfDataAlt con) _
+  = lookupOccRn con            `thenRn` \ con' ->
+    returnRn (UfDataAlt con')
 
 
+rnUfCon (UfLitAlt lit) _
+  = returnRn (UfLitAlt lit)
 
 
-
-===================    OLD STUFF    ======================
+rnUfCon (UfLitLitAlt lit ty) _
+  = rnHsType (text "litlit") ty                `thenRn` \ ty' ->
+    returnRn (UfLitLitAlt lit ty')
+\end{code}
 
 %*********************************************************
 %*                                                      *
 
 %*********************************************************
 %*                                                      *
-\subsection{SPECIALIZE data pragmas}
+\subsection{Rule shapes}
 %*                                                      *
 %*********************************************************
 
 %*                                                      *
 %*********************************************************
 
-\begin{pseudocode}
-rnSpecDataSig :: RdrNameSpecDataSig
-             -> RnMS s RenamedSpecDataSig
+Check the shape of a transformation rule LHS.  Currently
+we only allow LHSs of the form @(f e1 .. en)@, where @f@ is
+not one of the @forall@'d variables.
 
 
-rnSpecDataSig (SpecDataSig tycon ty src_loc)
-  = pushSrcLocRn src_loc $
-    let
-       tyvars = filter extractHsTyNames ty
-    in
-    mkTyVarNamesEnv src_loc tyvars             `thenRn` \ (tv_env,_) ->
-    lookupOccRn tycon                  `thenRn` \ tycon' ->
-    rnHsType tv_env ty         `thenRn` \ ty' ->
-    returnRn (SpecDataSig tycon' ty' src_loc)
+\begin{code}
+validRuleLhs foralls lhs
+  = check lhs
+  where
+    check (HsApp e1 e2)                  = check e1
+    check (HsVar v) | v `notElem` foralls = True
+    check other                                  = False
+\end{code}
 
 
-\end{pseudocode}
 
 %*********************************************************
 
 %*********************************************************
-%*                                                     *
-\subsection{@SPECIALIZE instance@ user-pragmas}
-%*                                                     *
+%*                                                      *
+\subsection{Errors}
+%*                                                      *
 %*********************************************************
 
 %*********************************************************
 
-\begin{pseudocode}
-rnSpecInstSig :: RdrNameSpecInstSig
-             -> RnMS s RenamedSpecInstSig
-
-rnSpecInstSig (SpecInstSig clas ty src_loc)
-  = pushSrcLocRn src_loc $
-    let
-       tyvars = extractHsTyNames is_tyvar_name ty
-    in
-    mkTyVarNamesEnv src_loc tyvars             `thenRn` \ (tv_env,_) ->
-    lookupOccRn clas                   `thenRn` \ new_clas ->
-    rnHsType tv_env ty         `thenRn` \ new_ty ->
-    returnRn (SpecInstSig new_clas new_ty src_loc)
-\end{pseudocode}
+\begin{code}
+derivingNonStdClassErr clas
+  = hsep [ptext SLIT("non-standard class"), ppr clas, ptext SLIT("in deriving clause")]
+
+badDataCon name
+   = hsep [ptext SLIT("Illegal data constructor name"), quotes (ppr name)]
+
+forAllWarn doc ty tyvar
+  = doptRn Opt_WarnUnusedMatches `thenRn` \ warn_unused -> case () of
+    () | not warn_unused -> returnRn ()
+       | otherwise
+       -> getModeRn            `thenRn` \ mode ->
+          case mode of {
+#ifndef DEBUG
+            InterfaceMode -> returnRn () ; -- Don't warn of unused tyvars in interface files
+                                           -- unless DEBUG is on, in which case it is slightly
+                                           -- informative.  They can arise from mkRhsTyLam,
+#endif                                     -- leading to (say)         f :: forall a b. [b] -> [b]
+            other ->
+               addWarnRn (
+                  sep [ptext SLIT("The universally quantified type variable") <+> quotes (ppr tyvar),
+                  nest 4 (ptext SLIT("does not appear in the type") <+> quotes (ppr ty))]
+                  $$
+                  (ptext SLIT("In") <+> doc)
+                )
+          }
+
+badRuleLhsErr name lhs
+  = sep [ptext SLIT("Rule") <+> ptext name <> colon,
+        nest 4 (ptext SLIT("Illegal left-hand side:") <+> ppr lhs)]
+    $$
+    ptext SLIT("LHS must be of form (f e1 .. en) where f is not forall'd")
+
+badRuleVar name var
+  = sep [ptext SLIT("Rule") <+> ptext name <> colon,
+        ptext SLIT("Forall'd variable") <+> quotes (ppr var) <+> 
+               ptext SLIT("does not appear on left hand side")]
+
+badExtName :: ExtName -> Message
+badExtName ext_nm
+  = sep [quotes (ppr ext_nm) <+> ptext SLIT("is not a valid C identifier")]
+
+dupClassAssertWarn ctxt (assertion : dups)
+  = sep [hsep [ptext SLIT("Duplicate class assertion"), 
+              quotes (ppr assertion),
+              ptext SLIT("in the context:")],
+        nest 4 (pprHsContext ctxt <+> ptext SLIT("..."))]
+
+naughtyCCallContextErr (HsPClass clas _)
+  = sep [ptext SLIT("Can't use class") <+> quotes (ppr clas), 
+        ptext SLIT("in a context")]
+\end{code}