[project @ 1999-04-27 17:33:49 by sof]
[ghc-hetmet.git] / ghc / compiler / rename / RnExpr.lhs
index 73b1c44..1c4914e 100644 (file)
@@ -1,48 +1,53 @@
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 \section[RnExpr]{Renaming of expressions}
 
 Basically dependency analysis.
 
-Handles @Match@, @GRHSsAndBinds@, @HsExpr@, and @Qualifier@ datatypes.  In
+Handles @Match@, @GRHSs@, @HsExpr@, and @Qualifier@ datatypes.  In
 general, all of these functions return a renamed thing, and a set of
 free variables.
 
 \begin{code}
-#include "HsVersions.h"
-
 module RnExpr (
-       rnMatch, rnGRHSsAndBinds, rnPat,
+       rnMatch, rnGRHSs, rnPat,
        checkPrecMatch
    ) where
 
-IMP_Ubiq()
-IMPORT_DELOOPER(RnLoop)                -- break the RnPass/RnExpr/RnBinds loops
+#include "HsVersions.h"
+
+import {-# SOURCE #-} RnBinds  ( rnBinds ) 
+import {-# SOURCE #-} RnSource ( rnHsSigType, rnHsType )
 
 import HsSyn
 import RdrHsSyn
 import RnHsSyn
 import RnMonad
 import RnEnv
-import PrelInfo                ( numClass_RDR, fractionalClass_RDR, eqClass_RDR, ccallableClass_RDR,
-                         creturnableClass_RDR, monadZeroClass_RDR, enumClass_RDR,
-                         negate_RDR
+import CmdLineOpts     ( opt_GlasgowExts, opt_IgnoreAsserts )
+import BasicTypes      ( Fixity(..), FixityDirection(..) )
+import PrelInfo                ( numClass_RDR, fractionalClass_RDR, eqClass_RDR, 
+                         ccallableClass_RDR, creturnableClass_RDR, 
+                         monadClass_RDR, enumClass_RDR, ordClass_RDR,
+                         ratioDataCon_RDR, negate_RDR, assertErr_RDR,
+                         ioDataCon_RDR
                        )
 import TysPrim         ( charPrimTyCon, addrPrimTyCon, intPrimTyCon, 
                          floatPrimTyCon, doublePrimTyCon
                        )
-import TyCon           ( TyCon )
-import ErrUtils                ( addErrLoc, addShortErrLocLine )
-import Name
-import Pretty
-import UniqFM          ( lookupUFM{-, ufmToList ToDo:rm-} )
-import UniqSet         ( emptyUniqSet, unitUniqSet,
-                         unionUniqSets, unionManyUniqSets,
-                         SYN_IE(UniqSet)
+import Name            ( nameUnique, isLocallyDefined, NamedThing(..)
+                        , mkSysLocalName, nameSrcLoc
                        )
-import PprStyle                ( PprStyle(..) )
-import Util            ( Ord3(..), removeDups, panic, pprPanic, assertPanic )
+import NameSet
+import UniqFM          ( isNullUFM )
+import FiniteMap       ( elemFM )
+import UniqSet         ( emptyUniqSet, UniqSet )
+import Unique          ( assertIdKey )
+import Util            ( removeDups )
+import ListSetOps      ( unionLists )
+import Maybes          ( maybeToBool )
+import Outputable
 \end{code}
 
 
@@ -53,39 +58,52 @@ import Util         ( Ord3(..), removeDups, panic, pprPanic, assertPanic )
 *********************************************************
 
 \begin{code}
-rnPat :: RdrNamePat -> RnMS s RenamedPat
+rnPat :: RdrNamePat -> RnMS s (RenamedPat, FreeVars)
 
-rnPat WildPatIn = returnRn WildPatIn
+rnPat WildPatIn = returnRn (WildPatIn, emptyFVs)
 
 rnPat (VarPatIn name)
-  = lookupRn name      `thenRn` \ vname ->
-    returnRn (VarPatIn vname)
-
+  = lookupBndrRn  name                 `thenRn` \ vname ->
+    returnRn (VarPatIn vname, emptyFVs)
+
+rnPat (SigPatIn pat ty)
+  | opt_GlasgowExts
+  = rnPat pat          `thenRn` \ (pat', fvs1) ->
+    rnHsType doc ty    `thenRn` \ (ty',  fvs2) ->
+    returnRn (SigPatIn pat' ty', fvs1 `plusFV` fvs2)
+
+  | otherwise
+  = addErrRn (patSigErr ty)    `thenRn_`
+    rnPat pat
+  where
+    doc = text "a pattern type-signature"
+    
 rnPat (LitPatIn lit) 
   = litOccurrence lit                  `thenRn_`
     lookupImplicitOccRn eqClass_RDR    `thenRn_`       -- Needed to find equality on pattern
-    returnRn (LitPatIn lit)
+    returnRn (LitPatIn lit, emptyFVs)
 
 rnPat (LazyPatIn pat)
-  = rnPat pat          `thenRn` \ pat' ->
-    returnRn (LazyPatIn pat')
+  = rnPat pat          `thenRn` \ (pat', fvs) ->
+    returnRn (LazyPatIn pat', fvs)
 
 rnPat (AsPatIn name pat)
-  = rnPat pat          `thenRn` \ pat' ->
-    lookupRn name      `thenRn` \ vname ->
-    returnRn (AsPatIn vname pat')
+  = rnPat pat          `thenRn` \ (pat', fvs) ->
+    lookupBndrRn name  `thenRn` \ vname ->
+    returnRn (AsPatIn vname pat', fvs)
 
 rnPat (ConPatIn con pats)
-  = lookupRn con       `thenRn` \ con' ->
-    mapRn rnPat pats   `thenRn` \ patslist ->
-    returnRn (ConPatIn con' patslist)
+  = lookupOccRn con            `thenRn` \ con' ->
+    mapAndUnzipRn rnPat pats   `thenRn` \ (patslist, fvs_s) ->
+    returnRn (ConPatIn con' patslist, plusFVs fvs_s `addOneFV` con')
 
 rnPat (ConOpPatIn pat1 con _ pat2)
-  = rnPat pat1         `thenRn` \ pat1' ->
-    lookupRn con       `thenRn` \ con' ->
-    lookupFixity con   `thenRn` \ fixity ->
-    rnPat pat2         `thenRn` \ pat2' ->
-    mkConOpPatRn pat1' con' fixity pat2'
+  = rnPat pat1         `thenRn` \ (pat1', fvs1) ->
+    lookupOccRn con    `thenRn` \ con' ->
+    lookupFixity con'  `thenRn` \ fixity ->
+    rnPat pat2         `thenRn` \ (pat2', fvs2) ->
+    mkConOpPatRn pat1' con' fixity pat2'       `thenRn` \ pat' ->
+    returnRn (pat', fvs1 `plusFV` fvs2 `addOneFV` con')
 
 -- Negated patters can only be literals, and they are dealt with
 -- by negating the literal at compile time, not by using the negation
@@ -94,31 +112,37 @@ rnPat (ConOpPatIn pat1 con _ pat2)
 rnPat neg@(NegPatIn pat)
   = checkRn (valid_neg_pat pat) (negPatErr neg)
                        `thenRn_`
-    rnPat pat          `thenRn` \ pat' ->
-    returnRn (NegPatIn pat')
+    rnPat pat          `thenRn` \ (pat', fvs) ->
+    returnRn (NegPatIn pat', fvs)
   where
     valid_neg_pat (LitPatIn (HsInt  _)) = True
     valid_neg_pat (LitPatIn (HsFrac _)) = True
     valid_neg_pat _                     = False
 
 rnPat (ParPatIn pat)
-  = rnPat pat          `thenRn` \ pat' ->
-    returnRn (ParPatIn pat')
+  = rnPat pat          `thenRn` \ (pat', fvs) ->
+    returnRn (ParPatIn pat', fvs)
+
+rnPat (NPlusKPatIn name lit)
+  = litOccurrence lit                  `thenRn_`
+    lookupImplicitOccRn ordClass_RDR   `thenRn_`
+    lookupBndrRn name                  `thenRn` \ name' ->
+    returnRn (NPlusKPatIn name' lit, emptyFVs)
 
 rnPat (ListPatIn pats)
-  = addImplicitOccRn listType_name     `thenRn_` 
-    mapRn rnPat pats                   `thenRn` \ patslist ->
-    returnRn (ListPatIn patslist)
+  = addImplicitOccRn listTyCon_name    `thenRn_` 
+    mapAndUnzipRn rnPat pats           `thenRn` \ (patslist, fvs_s) ->
+    returnRn (ListPatIn patslist, plusFVs fvs_s)
 
-rnPat (TuplePatIn pats)
-  = addImplicitOccRn (tupleType_name (length pats))    `thenRn_` 
-    mapRn rnPat pats                                   `thenRn` \ patslist ->
-    returnRn (TuplePatIn patslist)
+rnPat (TuplePatIn pats boxed)
+  = addImplicitOccRn (tupleTyCon_name boxed (length pats)) `thenRn_`
+    mapAndUnzipRn rnPat pats                           `thenRn` \ (patslist, fvs_s) ->
+    returnRn (TuplePatIn patslist boxed, plusFVs fvs_s)
 
 rnPat (RecPatIn con rpats)
-  = lookupRn con       `thenRn` \ con' ->
-    rnRpats rpats      `thenRn` \ rpats' ->
-    returnRn (RecPatIn con' rpats')
+  = lookupOccRn con    `thenRn` \ con' ->
+    rnRpats rpats      `thenRn` \ (rpats', fvs) ->
+    returnRn (RecPatIn con' rpats', fvs `addOneFV` con')
 \end{code}
 
 ************************************************************************
@@ -130,50 +154,81 @@ rnPat (RecPatIn con rpats)
 \begin{code}
 rnMatch :: RdrNameMatch -> RnMS s (RenamedMatch, FreeVars)
 
-rnMatch (PatMatch pat match)
-  = bindLocalsRn "pattern" binders     $ \ new_binders ->
-    rnPat pat                          `thenRn` \ pat' ->
-    rnMatch match                      `thenRn` \ (match', fvMatch) ->
-    returnRn (PatMatch pat' match', fvMatch `minusNameSet` mkNameSet new_binders)
- where
-    binders = collectPatBinders pat
+rnMatch match@(Match _ pats maybe_rhs_sig grhss)
+  = pushSrcLocRn (getMatchLoc match)   $
 
-rnMatch (GRHSMatch grhss_and_binds)
-  = rnGRHSsAndBinds grhss_and_binds `thenRn` \ (grhss_and_binds', fvs) ->
-    returnRn (GRHSMatch grhss_and_binds', fvs)
+       -- Find the universally quantified type variables
+       -- in the pattern type signatures
+    getLocalNameEnv                    `thenRn` \ name_env ->
+    let
+       tyvars_in_sigs = rhs_sig_tyvars `unionLists` tyvars_in_pats
+       rhs_sig_tyvars = case maybe_rhs_sig of
+                               Nothing -> []
+                               Just ty -> extractHsTyVars ty
+       tyvars_in_pats = extractPatsTyVars pats
+       forall_tyvars  = filter (not . (`elemFM` name_env)) tyvars_in_sigs
+       doc            = text "a pattern type-signature"
+    in
+    bindTyVarsFVRn doc (map UserTyVar forall_tyvars)   $ \ sig_tyvars ->
+
+       -- Note that we do a single bindLocalsRn for all the
+       -- matches together, so that we spot the repeated variable in
+       --      f x x = 1
+    bindLocalsFVRn "a pattern" (collectPatsBinders pats) $ \ new_binders ->
+
+    mapAndUnzipRn rnPat pats           `thenRn` \ (pats', pat_fvs_s) ->
+    rnGRHSs grhss                      `thenRn` \ (grhss', grhss_fvs) ->
+    (case maybe_rhs_sig of
+       Nothing -> returnRn (Nothing, emptyFVs)
+       Just ty | opt_GlasgowExts -> rnHsType doc ty    `thenRn` \ (ty', ty_fvs) ->
+                                    returnRn (Just ty', ty_fvs)
+               | otherwise       -> addErrRn (patSigErr ty)    `thenRn_`
+                                    returnRn (Nothing, emptyFVs)
+    )                                  `thenRn` \ (maybe_rhs_sig', ty_fvs) ->
+
+    let
+       binder_set     = mkNameSet new_binders
+       unused_binders = nameSetToList (binder_set `minusNameSet` grhss_fvs)
+       all_fvs        = grhss_fvs `plusFV` plusFVs pat_fvs_s `plusFV` ty_fvs
+    in
+    warnUnusedMatches unused_binders           `thenRn_`
+    
+    returnRn (Match sig_tyvars pats' maybe_rhs_sig' grhss', all_fvs)
+       -- The bindLocals and bindTyVars will remove the bound FVs
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\subsubsection{Guarded right-hand sides (GRHSsAndBinds)}
+\subsubsection{Guarded right-hand sides (GRHSs)}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
-rnGRHSsAndBinds :: RdrNameGRHSsAndBinds -> RnMS s (RenamedGRHSsAndBinds, FreeVars)
-
-rnGRHSsAndBinds (GRHSsAndBindsIn grhss binds)
-  = rnBinds binds              $ \ binds' ->
-    rnGRHSs grhss              `thenRn` \ (grhss', fvGRHS) ->
-    returnRn (GRHSsAndBindsIn grhss' binds', fvGRHS)
+rnGRHSs :: RdrNameGRHSs -> RnMS s (RenamedGRHSs, FreeVars)
+
+rnGRHSs (GRHSs grhss binds maybe_ty)
+  = ASSERT( not (maybeToBool maybe_ty) )
+    rnBinds binds              $ \ binds' ->
+    mapAndUnzipRn rnGRHS grhss `thenRn` \ (grhss', fvGRHSs) ->
+    returnRn (GRHSs grhss' binds' Nothing, plusFVs fvGRHSs)
+
+rnGRHS (GRHS guarded locn)
+  = pushSrcLocRn locn $                    
+    (if not (opt_GlasgowExts || is_standard_guard guarded) then
+               addWarnRn (nonStdGuardErr guarded)
+     else
+               returnRn ()
+    )          `thenRn_`
+
+    rnStmts rnExpr guarded     `thenRn` \ (guarded', fvs) ->
+    returnRn (GRHS guarded' locn, fvs)
   where
-    rnGRHSs [] = returnRn ([], emptyNameSet)
-
-    rnGRHSs (grhs:grhss)
-      = rnGRHS  grhs   `thenRn` \ (grhs',  fvs) ->
-       rnGRHSs grhss  `thenRn` \ (grhss', fvss) ->
-       returnRn (grhs' : grhss', fvs `unionNameSets` fvss)
-
-    rnGRHS (GRHS guard expr locn)
-      = pushSrcLocRn locn $                
-       rnExpr guard    `thenRn` \ (guard', fvsg) ->
-       rnExpr expr     `thenRn` \ (expr',  fvse) ->
-       returnRn (GRHS guard' expr' locn, fvsg `unionNameSets` fvse)
-
-    rnGRHS (OtherwiseGRHS expr locn)
-      = pushSrcLocRn locn $
-       rnExpr expr     `thenRn` \ (expr', fvs) ->
-       returnRn (OtherwiseGRHS expr' locn, fvs)
+       -- Standard Haskell 1.4 guards are just a single boolean
+       -- expression, rather than a list of qualifiers as in the
+       -- Glasgow extension
+    is_standard_guard [ExprStmt _ _]                = True
+    is_standard_guard [GuardStmt _ _, ExprStmt _ _] = True
+    is_standard_guard other                        = False
 \end{code}
 
 %************************************************************************
@@ -184,34 +239,43 @@ rnGRHSsAndBinds (GRHSsAndBindsIn grhss binds)
 
 \begin{code}
 rnExprs :: [RdrNameHsExpr] -> RnMS s ([RenamedHsExpr], FreeVars)
+rnExprs ls = rnExprs' ls emptyUniqSet
+ where
+  rnExprs' [] acc = returnRn ([], acc)
+  rnExprs' (expr:exprs) acc
+   = rnExpr expr               `thenRn` \ (expr', fvExpr) ->
 
-rnExprs [] = returnRn ([], emptyNameSet)
+       -- Now we do a "seq" on the free vars because typically it's small
+       -- or empty, especially in very long lists of constants
+    let
+       acc' = acc `plusFV` fvExpr
+    in
+    (grubby_seqNameSet acc' rnExprs') exprs acc'       `thenRn` \ (exprs', fvExprs) ->
+    returnRn (expr':exprs', fvExprs)
 
-rnExprs (expr:exprs)
-  = rnExpr expr        `thenRn` \ (expr', fvExpr) ->
-    rnExprs exprs      `thenRn` \ (exprs', fvExprs) ->
-    returnRn (expr':exprs', fvExpr `unionNameSets` fvExprs)
+-- Grubby little function to do "seq" on namesets; replace by proper seq when GHC can do seq
+grubby_seqNameSet ns result | isNullUFM ns = result
+                           | otherwise    = result
 \end{code}
 
-Variables. We look up the variable and return the resulting name.  The
-interesting question is what the free-variable set should be.  We
-don't want to return imported or prelude things as free vars.  So we
-look at the Name returned from the lookup, and make it part of the
-free-var set iff if it's a LocallyDefined Name.
-\end{itemize}
+Variables. We look up the variable and return the resulting name. 
 
 \begin{code}
 rnExpr :: RdrNameHsExpr -> RnMS s (RenamedHsExpr, FreeVars)
 
 rnExpr (HsVar v)
-  = lookupOccRn v      `thenRn` \ vname ->
-    returnRn (HsVar vname, if isLocallyDefined vname
-                          then unitNameSet vname
-                          else emptyUniqSet)
+  = lookupOccRn v      `thenRn` \ name ->
+    if nameUnique name == assertIdKey then
+       -- We expand it to (GHCerr.assert__ location)
+        mkAssertExpr  `thenRn` \ expr ->
+       returnRn (expr, emptyUniqSet)
+    else
+        -- The normal case
+       returnRn (HsVar name, unitFV name)
 
 rnExpr (HsLit lit) 
   = litOccurrence lit          `thenRn_`
-    returnRn (HsLit lit, emptyNameSet)
+    returnRn (HsLit lit, emptyFVs)
 
 rnExpr (HsLam match)
   = rnMatch match      `thenRn` \ (match', fvMatch) ->
@@ -220,29 +284,31 @@ rnExpr (HsLam match)
 rnExpr (HsApp fun arg)
   = rnExpr fun         `thenRn` \ (fun',fvFun) ->
     rnExpr arg         `thenRn` \ (arg',fvArg) ->
-    returnRn (HsApp fun' arg', fvFun `unionNameSets` fvArg)
+    returnRn (HsApp fun' arg', fvFun `plusFV` fvArg)
 
-rnExpr (OpApp e1 op@(HsVar op_name) _ e2) 
+rnExpr (OpApp e1 op _ e2) 
   = rnExpr e1                          `thenRn` \ (e1', fv_e1) ->
     rnExpr e2                          `thenRn` \ (e2', fv_e2) ->
-    rnExpr op                          `thenRn` \ (op', fv_op) ->
+    rnExpr op                          `thenRn` \ (op'@(HsVar op_name), fv_op) ->
 
-       -- Deal wth fixity
+       -- Deal with fixity
+       -- When renaming code synthesised from "deriving" declarations
+       -- we're in Interface mode, and we should ignore fixity; assume
+       -- that the deriving code generator got the association correct
     lookupFixity op_name               `thenRn` \ fixity ->
     getModeRn                          `thenRn` \ mode -> 
     (case mode of
-       SourceMode    -> mkOpAppRn e1' op' fixity e2'
-       InterfaceMode -> returnRn (OpApp e1' op' fixity e2')
+       SourceMode      -> mkOpAppRn e1' op' fixity e2'
+       InterfaceMode _ -> returnRn (OpApp e1' op' fixity e2')
     )                                  `thenRn` \ final_e -> 
 
     returnRn (final_e,
-             fv_e1 `unionNameSets` fv_op `unionNameSets` fv_e2)
+             fv_e1 `plusFV` fv_op `plusFV` fv_e2)
 
 rnExpr (NegApp e n)
   = rnExpr e                           `thenRn` \ (e', fv_e) ->
     lookupImplicitOccRn negate_RDR     `thenRn` \ neg ->
-    getModeRn                          `thenRn` \ mode -> 
-    mkNegAppRn mode e' (HsVar neg)     `thenRn` \ final_e ->
+    mkNegAppRn e' (HsVar neg)          `thenRn` \ final_e ->
     returnRn (final_e, fv_e)
 
 rnExpr (HsPar e)
@@ -252,16 +318,18 @@ rnExpr (HsPar e)
 rnExpr (SectionL expr op)
   = rnExpr expr                `thenRn` \ (expr', fvs_expr) ->
     rnExpr op          `thenRn` \ (op', fvs_op) ->
-    returnRn (SectionL expr' op', fvs_op `unionNameSets` fvs_expr)
+    returnRn (SectionL expr' op', fvs_op `plusFV` fvs_expr)
 
 rnExpr (SectionR op expr)
   = rnExpr op          `thenRn` \ (op',   fvs_op) ->
     rnExpr expr                `thenRn` \ (expr', fvs_expr) ->
-    returnRn (SectionR op' expr', fvs_op `unionNameSets` fvs_expr)
+    returnRn (SectionR op' expr', fvs_op `plusFV` fvs_expr)
 
 rnExpr (CCall fun args may_gc is_casm fake_result_ty)
+       -- Check out the comment on RnIfaces.getNonWiredDataDecl about ccalls
   = lookupImplicitOccRn ccallableClass_RDR     `thenRn_`
     lookupImplicitOccRn creturnableClass_RDR   `thenRn_`
+    lookupImplicitOccRn ioDataCon_RDR          `thenRn_`
     rnExprs args                               `thenRn` \ (args', fvs_args) ->
     returnRn (CCall fun args' may_gc is_casm fake_result_ty, fvs_args)
 
@@ -273,55 +341,50 @@ rnExpr (HsCase expr ms src_loc)
   = pushSrcLocRn src_loc $
     rnExpr expr                        `thenRn` \ (new_expr, e_fvs) ->
     mapAndUnzipRn rnMatch ms   `thenRn` \ (new_ms, ms_fvs) ->
-    returnRn (HsCase new_expr new_ms src_loc, unionManyNameSets (e_fvs : ms_fvs))
+    returnRn (HsCase new_expr new_ms src_loc, plusFVs (e_fvs : ms_fvs))
 
 rnExpr (HsLet binds expr)
   = rnBinds binds              $ \ binds' ->
     rnExpr expr                         `thenRn` \ (expr',fvExpr) ->
     returnRn (HsLet binds' expr', fvExpr)
 
-rnExpr (HsDo stmts src_loc)
+rnExpr (HsDo do_or_lc stmts src_loc)
   = pushSrcLocRn src_loc $
-    lookupImplicitOccRn monadZeroClass_RDR     `thenRn_`       -- Forces Monad to come too
-    rnStmts stmts                              `thenRn` \ (stmts', fvStmts) ->
-    returnRn (HsDo stmts' src_loc, fvStmts)
-
-rnExpr (ListComp expr quals)
-  = addImplicitOccRn listType_name     `thenRn_` 
-    rnQuals expr quals                         `thenRn` \ ((expr', quals'), fvs) ->
-    returnRn (ListComp expr' quals', fvs)
+    lookupImplicitOccRn monadClass_RDR         `thenRn_`
+    rnStmts rnExpr stmts                       `thenRn` \ (stmts', fvs) ->
+    returnRn (HsDo do_or_lc stmts' src_loc, fvs)
 
 rnExpr (ExplicitList exps)
-  = addImplicitOccRn listType_name     `thenRn_` 
+  = addImplicitOccRn listTyCon_name    `thenRn_` 
     rnExprs exps                       `thenRn` \ (exps', fvs) ->
     returnRn  (ExplicitList exps', fvs)
 
-rnExpr (ExplicitTuple exps)
-  = addImplicitOccRn (tupleType_name (length exps))    `thenRn_` 
-    rnExprs exps                                       `thenRn` \ (exps', fvExps) ->
-    returnRn (ExplicitTuple exps', fvExps)
+rnExpr (ExplicitTuple exps boxed)
+  = addImplicitOccRn (tupleTyCon_name boxed (length exps)) `thenRn_` 
+    rnExprs exps                               `thenRn` \ (exps', fvExps) ->
+    returnRn (ExplicitTuple exps' boxed, fvExps)
 
-rnExpr (RecordCon (HsVar con) rbinds)
-  = lookupOccRn con                    `thenRn` \ conname ->
+rnExpr (RecordCon con_id rbinds)
+  = lookupOccRn con_id                         `thenRn` \ conname ->
     rnRbinds "construction" rbinds     `thenRn` \ (rbinds', fvRbinds) ->
-    returnRn (RecordCon (HsVar conname) rbinds', fvRbinds)
+    returnRn (RecordCon conname rbinds', fvRbinds)
 
 rnExpr (RecordUpd expr rbinds)
   = rnExpr expr                        `thenRn` \ (expr', fvExpr) ->
     rnRbinds "update" rbinds   `thenRn` \ (rbinds', fvRbinds) ->
-    returnRn (RecordUpd expr' rbinds', fvExpr `unionNameSets` fvRbinds)
+    returnRn (RecordUpd expr' rbinds', fvExpr `plusFV` fvRbinds)
 
 rnExpr (ExprWithTySig expr pty)
-  = rnExpr expr                                `thenRn` \ (expr', fvExpr) ->
-    rnHsType pty                       `thenRn` \ pty' ->
-    returnRn (ExprWithTySig expr' pty', fvExpr)
+  = rnExpr expr                                        `thenRn` \ (expr', fvExpr) ->
+    rnHsSigType (text "an expression") pty     `thenRn` \ (pty', fvTy) ->
+    returnRn (ExprWithTySig expr' pty', fvExpr `plusFV` fvTy)
 
 rnExpr (HsIf p b1 b2 src_loc)
   = pushSrcLocRn src_loc $
     rnExpr p           `thenRn` \ (p', fvP) ->
     rnExpr b1          `thenRn` \ (b1', fvB1) ->
     rnExpr b2          `thenRn` \ (b2', fvB2) ->
-    returnRn (HsIf p' b1' b2' src_loc, unionManyNameSets [fvP, fvB1, fvB2])
+    returnRn (HsIf p' b1' b2' src_loc, plusFVs [fvP, fvB1, fvB2])
 
 rnExpr (ArithSeqIn seq)
   = lookupImplicitOccRn enumClass_RDR  `thenRn_`
@@ -335,19 +398,19 @@ rnExpr (ArithSeqIn seq)
     rn_seq (FromThen expr1 expr2)
      = rnExpr expr1    `thenRn` \ (expr1', fvExpr1) ->
        rnExpr expr2    `thenRn` \ (expr2', fvExpr2) ->
-       returnRn (FromThen expr1' expr2', fvExpr1 `unionNameSets` fvExpr2)
+       returnRn (FromThen expr1' expr2', fvExpr1 `plusFV` fvExpr2)
 
     rn_seq (FromTo expr1 expr2)
      = rnExpr expr1    `thenRn` \ (expr1', fvExpr1) ->
        rnExpr expr2    `thenRn` \ (expr2', fvExpr2) ->
-       returnRn (FromTo expr1' expr2', fvExpr1 `unionNameSets` fvExpr2)
+       returnRn (FromTo expr1' expr2', fvExpr1 `plusFV` fvExpr2)
 
     rn_seq (FromThenTo expr1 expr2 expr3)
      = rnExpr expr1    `thenRn` \ (expr1', fvExpr1) ->
        rnExpr expr2    `thenRn` \ (expr2', fvExpr2) ->
        rnExpr expr3    `thenRn` \ (expr3', fvExpr3) ->
        returnRn (FromThenTo expr1' expr2' expr3',
-                 unionManyNameSets [fvExpr1, fvExpr2, fvExpr3])
+                 plusFVs [fvExpr1, fvExpr2, fvExpr3])
 \end{code}
 
 %************************************************************************
@@ -358,36 +421,37 @@ rnExpr (ArithSeqIn seq)
 
 \begin{code}
 rnRbinds str rbinds 
-  = mapRn field_dup_err dup_fields     `thenRn_`
+  = mapRn_ field_dup_err dup_fields    `thenRn_`
     mapAndUnzipRn rn_rbind rbinds      `thenRn` \ (rbinds', fvRbind_s) ->
-    returnRn (rbinds', unionManyNameSets fvRbind_s)
+    returnRn (rbinds', plusFVs fvRbind_s)
   where
-    (_, dup_fields) = removeDups cmp [ f | (f,_,_) <- rbinds ]
+    (_, dup_fields) = removeDups compare [ f | (f,_,_) <- rbinds ]
 
     field_dup_err dups = addErrRn (dupFieldErr str dups)
 
     rn_rbind (field, expr, pun)
-      = lookupOccRn field      `thenRn` \ fieldname ->
+      = lookupGlobalOccRn field        `thenRn` \ fieldname ->
        rnExpr expr             `thenRn` \ (expr', fvExpr) ->
-       returnRn ((fieldname, expr', pun), fvExpr)
+       returnRn ((fieldname, expr', pun), fvExpr `addOneFV` fieldname)
 
 rnRpats rpats
-  = mapRn field_dup_err dup_fields     `thenRn_`
-    mapRn rn_rpat rpats
+  = mapRn_ field_dup_err dup_fields    `thenRn_`
+    mapAndUnzipRn rn_rpat rpats                `thenRn` \ (rpats', fvs_s) ->
+    returnRn (rpats', plusFVs fvs_s)
   where
-    (_, dup_fields) = removeDups cmp [ f | (f,_,_) <- rpats ]
+    (_, dup_fields) = removeDups compare [ f | (f,_,_) <- rpats ]
 
     field_dup_err dups = addErrRn (dupFieldErr "pattern" dups)
 
     rn_rpat (field, pat, pun)
-      = lookupOccRn field      `thenRn` \ fieldname ->
-       rnPat pat               `thenRn` \ pat' ->
-       returnRn (fieldname, pat', pun)
+      = lookupGlobalOccRn field        `thenRn` \ fieldname ->
+       rnPat pat               `thenRn` \ (pat', fvs) ->
+       returnRn ((fieldname, pat', pun), fvs `addOneFV` fieldname)
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\subsubsection{@Qualifier@s: in list comprehensions}
+\subsubsection{@Stmt@s: in @do@ expressions}
 %*                                                                     *
 %************************************************************************
 
@@ -400,87 +464,53 @@ be @{r}@, and the free var set for the entire Quals will be @{r}@. This
 Quals.
 
 \begin{code}
-rnQuals :: RdrNameHsExpr -> [RdrNameQual]
-        -> RnMS s ((RenamedHsExpr, [RenamedQual]), FreeVars)
-
-rnQuals expr [qual]                            -- must be at least one qual
-  = rnQual qual                        $ \ new_qual ->
-    rnExpr expr                                `thenRn` \ (expr', fvs) ->
-    returnRn ((expr', [new_qual]), fvs)
-
-rnQuals expr (qual: quals)
-  = rnQual qual                        $ \ qual' ->
-    rnQuals expr quals         `thenRn` \ ((expr', quals'), fv_quals) ->
-    returnRn ((expr', qual' : quals'), fv_quals)
-
-
--- rnQual :: RdrNameQual
---        -> (RenamedQual -> RnMS s (a,FreeVars))
---        -> RnMS s (a,FreeVars)
--- Because of mutual recursion the actual type is a bit less general than this [Haskell 1.2]
-
-rnQual (GeneratorQual pat expr) thing_inside
-  = rnExpr expr                                                        `thenRn` \ (expr', fv_expr) ->
-    bindLocalsRn "pattern in list comprehension" binders       $ \ new_binders ->
-    rnPat pat                                                  `thenRn` \ pat' ->
-
-    thing_inside (GeneratorQual pat' expr')            `thenRn` \ (result, fvs) ->     
-    returnRn (result, fv_expr `unionNameSets` (fvs `minusNameSet` mkNameSet new_binders))
-  where
-    binders = collectPatBinders pat
-
-rnQual (FilterQual expr) thing_inside
-  = rnExpr expr                                `thenRn` \ (expr', fv_expr) ->
-    thing_inside (FilterQual expr')    `thenRn` \ (result, fvs) ->
-    returnRn (result, fv_expr `unionNameSets` fvs)
-
-rnQual (LetQual binds) thing_inside
-  = rnBinds binds                      $ \ binds' ->
-    thing_inside (LetQual binds')
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-\subsubsection{@Stmt@s: in @do@ expressions}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-rnStmts :: [RdrNameStmt] -> RnMS s ([RenamedStmt], FreeVars)
+type RnExprTy s = RdrNameHsExpr -> RnMS s (RenamedHsExpr, FreeVars)
 
-rnStmts [stmt@(ExprStmt expr src_loc)]         -- last stmt must be ExprStmt
-  = pushSrcLocRn src_loc $
-    rnExpr expr                                `thenRn` \ (expr', fv_expr) ->
-    returnRn ([ExprStmt expr' src_loc], fv_expr)
+rnStmts :: RnExprTy s
+       -> [RdrNameStmt] 
+       -> RnMS s ([RenamedStmt], FreeVars)
 
-rnStmts (stmt:stmts)
-  = rnStmt stmt                                $ \ stmt' ->
-    rnStmts stmts                      `thenRn` \ (stmts', fv_stmts) ->
-    returnRn (stmt':stmts', fv_stmts)
+rnStmts rn_expr []
+  = returnRn ([], emptyFVs)
 
+rnStmts rn_expr (stmt:stmts)
+  = rnStmt rn_expr stmt                                $ \ stmt' ->
+    rnStmts rn_expr stmts                      `thenRn` \ (stmts', fvs) ->
+    returnRn (stmt' : stmts', fvs)
 
--- rnStmt :: RdrNameStmt -> (RenamedStmt -> RnMS s (a, FreeVars)) -> RnMS s (a, FreeVars)
--- Because of mutual recursion the actual type is a bit less general than this [Haskell 1.2]
+rnStmt :: RnExprTy s -> RdrNameStmt
+       -> (RenamedStmt -> RnMS s (a, FreeVars))
+       -> RnMS s (a, FreeVars)
+-- Because of mutual recursion we have to pass in rnExpr.
 
-rnStmt (BindStmt pat expr src_loc) thing_inside
+rnStmt rn_expr (BindStmt pat expr src_loc) thing_inside
   = pushSrcLocRn src_loc $
-    rnExpr expr                                                `thenRn` \ (expr', fv_expr) ->
-    bindLocalsRn "pattern in do binding" binders       $ \ new_binders ->
-    rnPat pat                                          `thenRn` \ pat' ->
-
+    rn_expr expr                                       `thenRn` \ (expr', fv_expr) ->
+    bindLocalsFVRn "a pattern in do binding" binders   $ \ new_binders ->
+    rnPat pat                                          `thenRn` \ (pat', fv_pat) ->
     thing_inside (BindStmt pat' expr' src_loc)         `thenRn` \ (result, fvs) -> 
-    returnRn (result, fv_expr `unionNameSets` (fvs `minusNameSet` mkNameSet new_binders))
+    returnRn (result, fv_expr `plusFV` fvs `plusFV` fv_pat)
   where
     binders = collectPatBinders pat
 
-rnStmt (ExprStmt expr src_loc) thing_inside
+rnStmt rn_expr (ExprStmt expr src_loc) thing_inside
   = pushSrcLocRn src_loc $
-    rnExpr expr                                        `thenRn` \ (expr', fv_expr) ->
+    rn_expr expr                               `thenRn` \ (expr', fv_expr) ->
     thing_inside (ExprStmt expr' src_loc)      `thenRn` \ (result, fvs) ->
-    returnRn (result, fv_expr `unionNameSets` fvs)
+    returnRn (result, fv_expr `plusFV` fvs)
 
-rnStmt (LetStmt binds) thing_inside
+rnStmt rn_expr (GuardStmt expr src_loc) thing_inside
+  = pushSrcLocRn src_loc $
+    rn_expr expr                               `thenRn` \ (expr', fv_expr) ->
+    thing_inside (GuardStmt expr' src_loc)     `thenRn` \ (result, fvs) ->
+    returnRn (result, fv_expr `plusFV` fvs)
+
+rnStmt rn_expr (ReturnStmt expr) thing_inside
+  = rn_expr expr                               `thenRn` \ (expr', fv_expr) ->
+    thing_inside (ReturnStmt expr')            `thenRn` \ (result, fvs) ->
+    returnRn (result, fv_expr `plusFV` fvs)
+
+rnStmt rn_expr (LetStmt binds) thing_inside
   = rnBinds binds              $ \ binds' ->
     thing_inside (LetStmt binds')
 \end{code}
@@ -515,20 +545,31 @@ mkOpAppRn e1@(OpApp e11 op1 fix1 e12)
     returnRn (OpApp e11 op1 fix1 new_e)
   where
     (nofix_error, rearrange_me) = compareFixity fix1 fix2
-    get (HsVar n) = n
 
-mkOpAppRn e1@(NegApp neg_arg neg_id) 
+mkOpAppRn e1@(NegApp neg_arg neg_op) 
          op2 
          fix2@(Fixity prec2 dir2)
          e2
-  | prec2 > 6  -- Precedence of unary - is wired in as 6!
+  | nofix_error
+  = addErrRn (precParseErr (get neg_op,fix_neg) (get op2,fix2))        `thenRn_`
+    returnRn (OpApp e1 op2 fix2 e2)
+
+  | rearrange_me
   = mkOpAppRn neg_arg op2 fix2 e2      `thenRn` \ new_e ->
-    returnRn (NegApp new_e neg_id)
+    returnRn (NegApp new_e neg_op)
+  where
+    fix_neg = Fixity 6 InfixL          -- Precedence of unary negate is wired in as infixl 6!
+    (nofix_error, rearrange_me) = compareFixity fix_neg fix2
 
 mkOpAppRn e1 op fix e2                         -- Default case, no rearrangment
-  = ASSERT( right_op_ok fix e2 )
+  = ASSERT( if right_op_ok fix e2 then True
+           else pprPanic "mkOpAppRn" (vcat [ppr e1, text "---", ppr op, 
+                                            text "---", ppr fix, text "---", ppr e2])
+    )
     returnRn (OpApp e1 op fix e2)
 
+get (HsVar n) = n
+
 -- Parser left-associates everything, but 
 -- derived instances may have correctly-associated things to
 -- in the right operarand.  So we just check that the right operand is OK
@@ -540,9 +581,13 @@ right_op_ok fix1 other
   = True
 
 -- Parser initially makes negation bind more tightly than any other operator
-mkNegAppRn mode neg_arg neg_id
-  = ASSERT( not_op_app mode neg_arg )
-    returnRn (NegApp neg_arg neg_id)
+mkNegAppRn neg_arg neg_op
+  = 
+#ifdef DEBUG
+    getModeRn                  `thenRn` \ mode ->
+    ASSERT( not_op_app mode neg_arg )
+#endif
+    returnRn (NegApp neg_arg neg_op)
 
 not_op_app SourceMode (OpApp _ _ _ _) = False
 not_op_app mode other                = True
@@ -582,15 +627,14 @@ not_op_pat other                  = True
 \end{code}
 
 \begin{code}
-checkPrecMatch :: Bool -> RdrName -> RdrNameMatch -> RnMS s ()
+checkPrecMatch :: Bool -> Name -> RenamedMatch -> RnMS s ()
 
 checkPrecMatch False fn match
   = returnRn ()
-checkPrecMatch True op (PatMatch p1 (PatMatch p2 (GRHSMatch _)))
+checkPrecMatch True op (Match _ [p1,p2] _ _)
   = checkPrec op p1 False      `thenRn_`
     checkPrec op p2 True
-checkPrecMatch True op _
-  = panic "checkPrecMatch"
+checkPrecMatch True op _ = panic "checkPrecMatch"
 
 checkPrec op (ConOpPatIn _ op1 _ _) right
   = lookupFixity op    `thenRn` \  op_fix@(Fixity op_prec  op_dir) ->
@@ -626,10 +670,10 @@ compareFixity :: Fixity -> Fixity
              -> (Bool,         -- Error please
                  Bool)         -- Associate to the right: a op1 (b op2 c)
 compareFixity (Fixity prec1 dir1) (Fixity prec2 dir2)
-  = case prec1 `cmp` prec2 of
-       GT_ -> left
-       LT_ -> right
-       EQ_ -> case (dir1, dir2) of
+  = case prec1 `compare` prec2 of
+       GT -> left
+       LT -> right
+       EQ -> case (dir1, dir2) of
                        (InfixR, InfixR) -> right
                        (InfixL, InfixL) -> left
                        _                -> error_please
@@ -650,26 +694,30 @@ are made available.
 
 \begin{code}
 litOccurrence (HsChar _)
-  = addImplicitOccRn charType_name
+  = addImplicitOccRn charTyCon_name
 
 litOccurrence (HsCharPrim _)
   = addImplicitOccRn (getName charPrimTyCon)
 
 litOccurrence (HsString _)
-  = addImplicitOccRn listType_name     `thenRn_`
-    addImplicitOccRn charType_name
+  = addImplicitOccRn listTyCon_name    `thenRn_`
+    addImplicitOccRn charTyCon_name
 
 litOccurrence (HsStringPrim _)
   = addImplicitOccRn (getName addrPrimTyCon)
 
 litOccurrence (HsInt _)
-  = lookupImplicitOccRn numClass_RDR   `thenRn_`       -- Int and Integer are forced in by Num
-    returnRn ()
+  = lookupImplicitOccRn numClass_RDR                   -- Int and Integer are forced in by Num
 
 litOccurrence (HsFrac _)
-  = lookupImplicitOccRn fractionalClass_RDR    `thenRn_`       -- ... similarly Rational
-    returnRn ()
-
+  = lookupImplicitOccRn fractionalClass_RDR    `thenRn_`
+    lookupImplicitOccRn ratioDataCon_RDR
+       -- We have to make sure that the Ratio type is imported with
+       -- its constructor, because literals of type Ratio t are
+       -- built with that constructor.
+       -- The Rational type is needed too, but that will come in
+       -- when fractionalClass does.
+    
 litOccurrence (HsIntPrim _)
   = addImplicitOccRn (getName intPrimTyCon)
 
@@ -680,32 +728,81 @@ litOccurrence (HsDoublePrim _)
   = addImplicitOccRn (getName doublePrimTyCon)
 
 litOccurrence (HsLitLit _)
-  = lookupImplicitOccRn ccallableClass_RDR     `thenRn_`
-    returnRn ()
+  = lookupImplicitOccRn ccallableClass_RDR
 \end{code}
 
-
 %************************************************************************
 %*                                                                     *
-\subsubsection{Errors}
+\subsubsection{Assertion utils}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
-dupFieldErr str (dup:rest) sty
-  = ppBesides [ppStr "duplicate field name `", ppr sty dup, ppStr "' in record ", ppStr str]
+mkAssertExpr :: RnMS s RenamedHsExpr
+mkAssertExpr =
+  newImportedGlobalFromRdrName assertErr_RDR   `thenRn` \ name ->
+  addOccurrenceName name                               `thenRn_`
+  getSrcLocRn                                          `thenRn` \ sloc ->
+
+    -- if we're ignoring asserts, return (\ _ e -> e)
+    -- if not, return (assertError "src-loc")
+
+  if opt_IgnoreAsserts then
+    getUniqRn                          `thenRn` \ uniq ->
+    let
+     vname = mkSysLocalName uniq SLIT("v")
+     expr  = HsLam ignorePredMatch
+     loc   = nameSrcLoc vname
+     ignorePredMatch = Match [] [WildPatIn, VarPatIn vname] Nothing 
+                             (GRHSs [GRHS [ExprStmt (HsVar vname) loc] loc]
+                                   EmptyBinds Nothing)
+    in
+    returnRn expr
+  else
+    let
+     expr = 
+          HsApp (HsVar name)
+               (HsLit (HsString (_PK_ (showSDoc (ppr sloc)))))
 
-negPatErr pat  sty
-  = ppSep [ppStr "prefix `-' not applied to literal in pattern", ppr sty pat]
+    in
+    returnRn expr
 
-precParseNegPatErr op sty 
-  = ppHang (ppStr "precedence parsing error")
-      4 (ppBesides [ppStr "prefix `-' has lower precedence than ", pp_op sty op, ppStr " in pattern"])
+\end{code}
 
-precParseErr op1 op2  sty
-  = ppHang (ppStr "precedence parsing error")
-      4 (ppBesides [ppStr "cannot mix ", pp_op sty op1, ppStr " and ", pp_op sty op2,
-                   ppStr " in the same infix expression"])
+%************************************************************************
+%*                                                                     *
+\subsubsection{Errors}
+%*                                                                     *
+%************************************************************************
 
-pp_op sty (op, fix) = ppBesides [pprSym sty op, ppLparen, ppr sty fix, ppRparen]
+\begin{code}
+dupFieldErr str (dup:rest)
+  = hsep [ptext SLIT("duplicate field name"), 
+          quotes (ppr dup),
+         ptext SLIT("in record"), text str]
+
+negPatErr pat 
+  = sep [ptext SLIT("prefix `-' not applied to literal in pattern"), quotes (ppr pat)]
+
+precParseNegPatErr op 
+  = hang (ptext SLIT("precedence parsing error"))
+      4 (hsep [ptext SLIT("prefix `-' has lower precedence than"), 
+              quotes (pp_op op), 
+              ptext SLIT("in pattern")])
+
+precParseErr op1 op2 
+  = hang (ptext SLIT("precedence parsing error"))
+      4 (hsep [ptext SLIT("cannot mix"), quotes (pp_op op1), ptext SLIT("and"), 
+              quotes (pp_op op2),
+              ptext SLIT("in the same infix expression")])
+
+nonStdGuardErr guard
+  = hang (ptext SLIT("accepting non-standard pattern guards (-fglasgow-exts to suppress this message)"))
+      4 (ppr guard)
+
+patSigErr ty
+  = hang (ptext SLIT("Illegal signature in pattern:") <+> ppr ty)
+        4 (ptext SLIT("Use -fglasgow-exts to permit it"))
+
+pp_op (op, fix) = hcat [ppr op, space, parens (ppr fix)]
 \end{code}