[project @ 1999-07-27 07:31:16 by simonpj]
[ghc-hetmet.git] / ghc / compiler / rename / RnExpr.lhs
index 1c4914e..ad4a408 100644 (file)
@@ -11,22 +11,23 @@ free variables.
 
 \begin{code}
 module RnExpr (
-       rnMatch, rnGRHSs, rnPat,
+       rnMatch, rnGRHSs, rnPat, rnExpr, rnExprs,
        checkPrecMatch
    ) where
 
 #include "HsVersions.h"
 
 import {-# SOURCE #-} RnBinds  ( rnBinds ) 
-import {-# SOURCE #-} RnSource ( rnHsSigType, rnHsType )
+import {-# SOURCE #-} RnSource ( rnHsSigType, rnHsPolyType, rnHsType )
 
 import HsSyn
 import RdrHsSyn
 import RnHsSyn
 import RnMonad
 import RnEnv
+import RnIfaces                ( lookupFixity )
 import CmdLineOpts     ( opt_GlasgowExts, opt_IgnoreAsserts )
-import BasicTypes      ( Fixity(..), FixityDirection(..) )
+import BasicTypes      ( Fixity(..), FixityDirection(..), defaultFixity, negateFixity, negatePrecedence )
 import PrelInfo                ( numClass_RDR, fractionalClass_RDR, eqClass_RDR, 
                          ccallableClass_RDR, creturnableClass_RDR, 
                          monadClass_RDR, enumClass_RDR, ordClass_RDR,
@@ -58,7 +59,7 @@ import Outputable
 *********************************************************
 
 \begin{code}
-rnPat :: RdrNamePat -> RnMS s (RenamedPat, FreeVars)
+rnPat :: RdrNamePat -> RnMS (RenamedPat, FreeVars)
 
 rnPat WildPatIn = returnRn (WildPatIn, emptyFVs)
 
@@ -69,7 +70,7 @@ rnPat (VarPatIn name)
 rnPat (SigPatIn pat ty)
   | opt_GlasgowExts
   = rnPat pat          `thenRn` \ (pat', fvs1) ->
-    rnHsType doc ty    `thenRn` \ (ty',  fvs2) ->
+    rnHsPolyType doc ty        `thenRn` \ (ty',  fvs2) ->
     returnRn (SigPatIn pat' ty', fvs1 `plusFV` fvs2)
 
   | otherwise
@@ -79,9 +80,9 @@ rnPat (SigPatIn pat ty)
     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, emptyFVs)
+  = litOccurrence lit                  `thenRn` \ fvs1 ->
+    lookupImplicitOccRn eqClass_RDR    `thenRn` \ eq   ->      -- Needed to find equality on pattern
+    returnRn (LitPatIn lit, fvs1 `addOneFV` eq)
 
 rnPat (LazyPatIn pat)
   = rnPat pat          `thenRn` \ (pat', fvs) ->
@@ -94,15 +95,21 @@ rnPat (AsPatIn name pat)
 
 rnPat (ConPatIn con pats)
   = lookupOccRn con            `thenRn` \ con' ->
-    mapAndUnzipRn rnPat pats   `thenRn` \ (patslist, fvs_s) ->
-    returnRn (ConPatIn con' patslist, plusFVs fvs_s `addOneFV` con')
+    mapFvRn rnPat pats         `thenRn` \ (patslist, fvs) ->
+    returnRn (ConPatIn con' patslist, fvs `addOneFV` con')
 
 rnPat (ConOpPatIn pat1 con _ 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' ->
+
+    getModeRn          `thenRn` \ mode ->
+       -- See comments with rnExpr (OpApp ...)
+    (case mode of
+       InterfaceMode -> returnRn (ConOpPatIn pat1' con' defaultFixity pat2')
+       SourceMode    -> lookupFixity con'      `thenRn` \ fixity ->
+                        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
@@ -115,29 +122,32 @@ rnPat neg@(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
+    valid_neg_pat (LitPatIn (HsInt        _)) = True
+    valid_neg_pat (LitPatIn (HsIntPrim    _)) = True
+    valid_neg_pat (LitPatIn (HsFrac       _)) = True
+    valid_neg_pat (LitPatIn (HsFloatPrim  _)) = True
+    valid_neg_pat (LitPatIn (HsDoublePrim _)) = True
+    valid_neg_pat _                           = False
 
 rnPat (ParPatIn pat)
   = rnPat pat          `thenRn` \ (pat', fvs) ->
     returnRn (ParPatIn pat', fvs)
 
 rnPat (NPlusKPatIn name lit)
-  = litOccurrence lit                  `thenRn_`
-    lookupImplicitOccRn ordClass_RDR   `thenRn_`
+  = litOccurrence lit                  `thenRn` \ fvs ->
+    lookupImplicitOccRn ordClass_RDR   `thenRn` \ ord ->
     lookupBndrRn name                  `thenRn` \ name' ->
-    returnRn (NPlusKPatIn name' lit, emptyFVs)
+    returnRn (NPlusKPatIn name' lit, fvs `addOneFV` ord)
 
 rnPat (ListPatIn pats)
-  = addImplicitOccRn listTyCon_name    `thenRn_` 
-    mapAndUnzipRn rnPat pats           `thenRn` \ (patslist, fvs_s) ->
-    returnRn (ListPatIn patslist, plusFVs fvs_s)
+  = mapFvRn rnPat pats                 `thenRn` \ (patslist, fvs) ->
+    returnRn (ListPatIn patslist, fvs `addOneFV` listTyCon_name)
 
 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)
+  = mapFvRn rnPat pats                                    `thenRn` \ (patslist, fvs) ->
+    returnRn (TuplePatIn patslist boxed, fvs `addOneFV` tycon_name)
+  where
+    tycon_name = tupleTyCon_name boxed (length pats)
 
 rnPat (RecPatIn con rpats)
   = lookupOccRn con    `thenRn` \ con' ->
@@ -152,7 +162,7 @@ rnPat (RecPatIn con rpats)
 ************************************************************************
 
 \begin{code}
-rnMatch :: RdrNameMatch -> RnMS s (RenamedMatch, FreeVars)
+rnMatch :: RdrNameMatch -> RnMS (RenamedMatch, FreeVars)
 
 rnMatch match@(Match _ pats maybe_rhs_sig grhss)
   = pushSrcLocRn (getMatchLoc match)   $
@@ -164,7 +174,7 @@ rnMatch match@(Match _ pats maybe_rhs_sig grhss)
        tyvars_in_sigs = rhs_sig_tyvars `unionLists` tyvars_in_pats
        rhs_sig_tyvars = case maybe_rhs_sig of
                                Nothing -> []
-                               Just ty -> extractHsTyVars ty
+                               Just ty -> extractHsTyRdrNames ty
        tyvars_in_pats = extractPatsTyVars pats
        forall_tyvars  = filter (not . (`elemFM` name_env)) tyvars_in_sigs
        doc            = text "a pattern type-signature"
@@ -174,9 +184,9 @@ rnMatch match@(Match _ pats maybe_rhs_sig grhss)
        -- 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 ->
+    bindLocalsFVRn doc (collectPatsBinders pats) $ \ new_binders ->
 
-    mapAndUnzipRn rnPat pats           `thenRn` \ (pats', pat_fvs_s) ->
+    mapFvRn rnPat pats                 `thenRn` \ (pats', pat_fvs) ->
     rnGRHSs grhss                      `thenRn` \ (grhss', grhss_fvs) ->
     (case maybe_rhs_sig of
        Nothing -> returnRn (Nothing, emptyFVs)
@@ -189,7 +199,7 @@ rnMatch match@(Match _ pats maybe_rhs_sig grhss)
     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
+       all_fvs        = grhss_fvs `plusFV` pat_fvs `plusFV` ty_fvs
     in
     warnUnusedMatches unused_binders           `thenRn_`
     
@@ -204,13 +214,13 @@ rnMatch match@(Match _ pats maybe_rhs_sig grhss)
 %************************************************************************
 
 \begin{code}
-rnGRHSs :: RdrNameGRHSs -> RnMS s (RenamedGRHSs, FreeVars)
+rnGRHSs :: RdrNameGRHSs -> RnMS (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)
+    mapFvRn rnGRHS grhss       `thenRn` \ (grhss', fvGRHSs) ->
+    returnRn (GRHSs grhss' binds' Nothing, fvGRHSs)
 
 rnGRHS (GRHS guarded locn)
   = pushSrcLocRn locn $                    
@@ -238,7 +248,7 @@ rnGRHS (GRHS guarded locn)
 %************************************************************************
 
 \begin{code}
-rnExprs :: [RdrNameHsExpr] -> RnMS s ([RenamedHsExpr], FreeVars)
+rnExprs :: [RdrNameHsExpr] -> RnMS ([RenamedHsExpr], FreeVars)
 rnExprs ls = rnExprs' ls emptyUniqSet
  where
   rnExprs' [] acc = returnRn ([], acc)
@@ -261,21 +271,20 @@ grubby_seqNameSet ns result | isNullUFM ns = result
 Variables. We look up the variable and return the resulting name. 
 
 \begin{code}
-rnExpr :: RdrNameHsExpr -> RnMS s (RenamedHsExpr, FreeVars)
+rnExpr :: RdrNameHsExpr -> RnMS (RenamedHsExpr, FreeVars)
 
 rnExpr (HsVar v)
   = lookupOccRn v      `thenRn` \ name ->
     if nameUnique name == assertIdKey then
        -- We expand it to (GHCerr.assert__ location)
-        mkAssertExpr  `thenRn` \ expr ->
-       returnRn (expr, emptyUniqSet)
+        mkAssertExpr
     else
         -- The normal case
        returnRn (HsVar name, unitFV name)
 
 rnExpr (HsLit lit) 
-  = litOccurrence lit          `thenRn_`
-    returnRn (HsLit lit, emptyFVs)
+  = litOccurrence lit          `thenRn` \ fvs ->
+    returnRn (HsLit lit, fvs)
 
 rnExpr (HsLam match)
   = rnMatch match      `thenRn` \ (match', fvMatch) ->
@@ -295,21 +304,28 @@ rnExpr (OpApp e1 op _ e2)
        -- 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 ->
+       -- Don't even look up the fixity when in interface mode
     getModeRn                          `thenRn` \ mode -> 
     (case mode of
-       SourceMode      -> mkOpAppRn e1' op' fixity e2'
-       InterfaceMode _ -> returnRn (OpApp e1' op' fixity e2')
+       SourceMode    -> lookupFixity op_name           `thenRn` \ fixity ->
+                        mkOpAppRn e1' op' fixity e2'
+       InterfaceMode -> returnRn (OpApp e1' op' defaultFixity e2')
     )                                  `thenRn` \ final_e -> 
 
     returnRn (final_e,
              fv_e1 `plusFV` fv_op `plusFV` fv_e2)
 
+-- constant-fold some negate applications on unboxed literals.  Since
+-- negate is a polymorphic function, we have to do these here.
+rnExpr (NegApp (HsLit (HsIntPrim i))    _) = rnExpr (HsLit (HsIntPrim (-i)))
+rnExpr (NegApp (HsLit (HsFloatPrim i))  _) = rnExpr (HsLit (HsFloatPrim (-i)))
+rnExpr (NegApp (HsLit (HsDoublePrim i)) _) = rnExpr (HsLit (HsDoublePrim (-i)))
+
 rnExpr (NegApp e n)
   = rnExpr e                           `thenRn` \ (e', fv_e) ->
     lookupImplicitOccRn negate_RDR     `thenRn` \ neg ->
     mkNegAppRn e' (HsVar neg)          `thenRn` \ final_e ->
-    returnRn (final_e, fv_e)
+    returnRn (final_e, fv_e `addOneFV` neg)
 
 rnExpr (HsPar e)
   = rnExpr e           `thenRn` \ (e', fvs_e) ->
@@ -327,21 +343,22 @@ rnExpr (SectionR op 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_`
+  = lookupImplicitOccRn ccallableClass_RDR     `thenRn` \ cc ->
+    lookupImplicitOccRn creturnableClass_RDR   `thenRn` \ cr ->
+    lookupImplicitOccRn ioDataCon_RDR          `thenRn` \ io ->
     rnExprs args                               `thenRn` \ (args', fvs_args) ->
-    returnRn (CCall fun args' may_gc is_casm fake_result_ty, fvs_args)
+    returnRn (CCall fun args' may_gc is_casm fake_result_ty, 
+             fvs_args `addOneFV` cc `addOneFV` cr `addOneFV` io)
 
-rnExpr (HsSCC label expr)
+rnExpr (HsSCC lbl expr)
   = rnExpr expr                `thenRn` \ (expr', fvs_expr) ->
-    returnRn (HsSCC label expr', fvs_expr)
+    returnRn (HsSCC lbl expr', fvs_expr)
 
 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, plusFVs (e_fvs : ms_fvs))
+    mapFvRn rnMatch ms         `thenRn` \ (new_ms, ms_fvs) ->
+    returnRn (HsCase new_expr new_ms src_loc, e_fvs `plusFV` ms_fvs)
 
 rnExpr (HsLet binds expr)
   = rnBinds binds              $ \ binds' ->
@@ -350,24 +367,24 @@ rnExpr (HsLet binds expr)
 
 rnExpr (HsDo do_or_lc stmts src_loc)
   = pushSrcLocRn src_loc $
-    lookupImplicitOccRn monadClass_RDR         `thenRn_`
+    lookupImplicitOccRn monadClass_RDR         `thenRn` \ monad ->
     rnStmts rnExpr stmts                       `thenRn` \ (stmts', fvs) ->
-    returnRn (HsDo do_or_lc stmts' src_loc, fvs)
+    returnRn (HsDo do_or_lc stmts' src_loc, fvs `addOneFV` monad)
 
 rnExpr (ExplicitList exps)
-  = addImplicitOccRn listTyCon_name    `thenRn_` 
-    rnExprs exps                       `thenRn` \ (exps', fvs) ->
-    returnRn  (ExplicitList exps', fvs)
+  = rnExprs exps                       `thenRn` \ (exps', fvs) ->
+    returnRn  (ExplicitList exps', fvs `addOneFV` listTyCon_name)
 
 rnExpr (ExplicitTuple exps boxed)
-  = addImplicitOccRn (tupleTyCon_name boxed (length exps)) `thenRn_` 
-    rnExprs exps                               `thenRn` \ (exps', fvExps) ->
-    returnRn (ExplicitTuple exps' boxed, fvExps)
+  = rnExprs exps                               `thenRn` \ (exps', fvs) ->
+    returnRn (ExplicitTuple exps' boxed, fvs `addOneFV` tycon_name)
+  where
+    tycon_name = tupleTyCon_name boxed (length exps)
 
 rnExpr (RecordCon con_id rbinds)
   = lookupOccRn con_id                         `thenRn` \ conname ->
     rnRbinds "construction" rbinds     `thenRn` \ (rbinds', fvRbinds) ->
-    returnRn (RecordCon conname rbinds', fvRbinds)
+    returnRn (RecordCon conname rbinds', fvRbinds `addOneFV` conname)
 
 rnExpr (RecordUpd expr rbinds)
   = rnExpr expr                        `thenRn` \ (expr', fvExpr) ->
@@ -387,9 +404,9 @@ rnExpr (HsIf p b1 b2 src_loc)
     returnRn (HsIf p' b1' b2' src_loc, plusFVs [fvP, fvB1, fvB2])
 
 rnExpr (ArithSeqIn seq)
-  = lookupImplicitOccRn enumClass_RDR  `thenRn_`
+  = lookupImplicitOccRn enumClass_RDR  `thenRn` \ enum ->
     rn_seq seq                         `thenRn` \ (new_seq, fvs) ->
-    returnRn (ArithSeqIn new_seq, fvs)
+    returnRn (ArithSeqIn new_seq, fvs `addOneFV` enum)
   where
     rn_seq (From expr)
      = rnExpr expr     `thenRn` \ (expr', fvExpr) ->
@@ -413,6 +430,21 @@ rnExpr (ArithSeqIn seq)
                  plusFVs [fvExpr1, fvExpr2, fvExpr3])
 \end{code}
 
+These three are pattern syntax appearing in expressions.
+Since all the symbols are reservedops we can simply reject them.
+We return a (bogus) EWildPat in each case.
+
+\begin{code}
+rnExpr e@EWildPat = addErrRn (patSynErr e)     `thenRn_`
+                   returnRn (EWildPat, emptyFVs)
+
+rnExpr e@(EAsPat _ _) = addErrRn (patSynErr e) `thenRn_`
+                       returnRn (EWildPat, emptyFVs)
+
+rnExpr e@(ELazyPat _) = addErrRn (patSynErr e) `thenRn_`
+                       returnRn (EWildPat, emptyFVs)
+\end{code}
+
 %************************************************************************
 %*                                                                     *
 \subsubsection{@Rbinds@s and @Rpats@s: in record expressions}
@@ -422,8 +454,8 @@ rnExpr (ArithSeqIn seq)
 \begin{code}
 rnRbinds str rbinds 
   = mapRn_ field_dup_err dup_fields    `thenRn_`
-    mapAndUnzipRn rn_rbind rbinds      `thenRn` \ (rbinds', fvRbind_s) ->
-    returnRn (rbinds', plusFVs fvRbind_s)
+    mapFvRn rn_rbind rbinds            `thenRn` \ (rbinds', fvRbind) ->
+    returnRn (rbinds', fvRbind)
   where
     (_, dup_fields) = removeDups compare [ f | (f,_,_) <- rbinds ]
 
@@ -436,8 +468,8 @@ rnRbinds str rbinds
 
 rnRpats rpats
   = mapRn_ field_dup_err dup_fields    `thenRn_`
-    mapAndUnzipRn rn_rpat rpats                `thenRn` \ (rpats', fvs_s) ->
-    returnRn (rpats', plusFVs fvs_s)
+    mapFvRn rn_rpat rpats              `thenRn` \ (rpats', fvs) ->
+    returnRn (rpats', fvs)
   where
     (_, dup_fields) = removeDups compare [ f | (f,_,_) <- rpats ]
 
@@ -464,11 +496,11 @@ be @{r}@, and the free var set for the entire Quals will be @{r}@. This
 Quals.
 
 \begin{code}
-type RnExprTy s = RdrNameHsExpr -> RnMS s (RenamedHsExpr, FreeVars)
+type RnExprTy = RdrNameHsExpr -> RnMS (RenamedHsExpr, FreeVars)
 
-rnStmts :: RnExprTy s
+rnStmts :: RnExprTy
        -> [RdrNameStmt] 
-       -> RnMS s ([RenamedStmt], FreeVars)
+       -> RnMS ([RenamedStmt], FreeVars)
 
 rnStmts rn_expr []
   = returnRn ([], emptyFVs)
@@ -478,20 +510,21 @@ rnStmts rn_expr (stmt:stmts)
     rnStmts rn_expr stmts                      `thenRn` \ (stmts', fvs) ->
     returnRn (stmt' : stmts', fvs)
 
-rnStmt :: RnExprTy s -> RdrNameStmt
-       -> (RenamedStmt -> RnMS s (a, FreeVars))
-       -> RnMS s (a, FreeVars)
+rnStmt :: RnExprTy -> RdrNameStmt
+       -> (RenamedStmt -> RnMS (a, FreeVars))
+       -> RnMS (a, FreeVars)
 -- Because of mutual recursion we have to pass in rnExpr.
 
 rnStmt rn_expr (BindStmt pat expr src_loc) thing_inside
   = pushSrcLocRn src_loc $
     rn_expr expr                                       `thenRn` \ (expr', fv_expr) ->
-    bindLocalsFVRn "a pattern in do binding" binders   $ \ new_binders ->
+    bindLocalsFVRn doc binders                         $ \ new_binders ->
     rnPat pat                                          `thenRn` \ (pat', fv_pat) ->
     thing_inside (BindStmt pat' expr' src_loc)         `thenRn` \ (result, fvs) -> 
     returnRn (result, fv_expr `plusFV` fvs `plusFV` fv_pat)
   where
     binders = collectPatBinders pat
+    doc = text "a pattern in do binding" 
 
 rnStmt rn_expr (ExprStmt expr src_loc) thing_inside
   = pushSrcLocRn src_loc $
@@ -528,43 +561,56 @@ the programmer actually wrote, so you can't find it out from the Name.
 
 Furthermore, the second argument is guaranteed not to be another
 operator application.  Why? Because the parser parses all
-operator appications left-associatively.
+operator appications left-associatively, EXCEPT negation, which
+we need to handle specially.
 
 \begin{code}
-mkOpAppRn :: RenamedHsExpr -> RenamedHsExpr -> Fixity -> RenamedHsExpr
-         -> RnMS s RenamedHsExpr
-
-mkOpAppRn e1@(OpApp e11 op1 fix1 e12) 
-         op2 fix2 e2
+mkOpAppRn :: RenamedHsExpr                     -- Left operand; already rearranged
+         -> RenamedHsExpr -> Fixity            -- Operator and fixity
+         -> RenamedHsExpr                      -- Right operand (not an OpApp, but might
+                                               -- be a NegApp)
+         -> RnMS RenamedHsExpr
+
+---------------------------
+-- (e11 `op1` e12) `op2` e2
+mkOpAppRn e1@(OpApp e11 op1 fix1 e12) op2 fix2 e2
   | nofix_error
   = addErrRn (precParseErr (get op1,fix1) (get op2,fix2))      `thenRn_`
     returnRn (OpApp e1 op2 fix2 e2)
 
-  | rearrange_me
+  | associate_right
   = mkOpAppRn e12 op2 fix2 e2          `thenRn` \ new_e ->
     returnRn (OpApp e11 op1 fix1 new_e)
   where
-    (nofix_error, rearrange_me) = compareFixity fix1 fix2
+    (nofix_error, associate_right) = compareFixity fix1 fix2
 
-mkOpAppRn e1@(NegApp neg_arg neg_op) 
-         op2 
-         fix2@(Fixity prec2 dir2)
-         e2
+---------------------------
+--     (- neg_arg) `op` e2
+mkOpAppRn e1@(NegApp neg_arg neg_op) op2 fix2 e2
   | nofix_error
-  = addErrRn (precParseErr (get neg_op,fix_neg) (get op2,fix2))        `thenRn_`
+  = addErrRn (precParseErr (get neg_op,negateFixity) (get op2,fix2))   `thenRn_`
     returnRn (OpApp e1 op2 fix2 e2)
 
-  | rearrange_me
+  | associate_right
   = mkOpAppRn neg_arg op2 fix2 e2      `thenRn` \ new_e ->
     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
+    (nofix_error, associate_right) = compareFixity negateFixity fix2
+
+---------------------------
+--     e1 `op` - neg_arg
+mkOpAppRn e1 op1 fix1 e2@(NegApp neg_arg neg_op)       -- NegApp can occur on the right
+  | not associate_right                                        -- We *want* right association
+  = addErrRn (precParseErr (get op1, fix1) (get neg_op, negateFixity)) `thenRn_`
+    returnRn (OpApp e1 op1 fix1 e2)
+  where
+    (nofix_err, associate_right) = compareFixity fix1 negateFixity
 
+---------------------------
+--     Default case
 mkOpAppRn e1 op fix e2                         -- Default case, no rearrangment
-  = ASSERT( if right_op_ok fix e2 then True
-           else pprPanic "mkOpAppRn" (vcat [ppr e1, text "---", ppr op, 
-                                            text "---", ppr fix, text "---", ppr e2])
+  = ASSERT2( right_op_ok fix e2,
+            ppr e1 $$ text "---" $$ ppr op $$ text "---" $$ ppr fix $$ text "---" $$ ppr e2
     )
     returnRn (OpApp e1 op fix e2)
 
@@ -595,7 +641,7 @@ not_op_app mode other                     = True
 
 \begin{code}
 mkConOpPatRn :: RenamedPat -> Name -> Fixity -> RenamedPat
-            -> RnMS s RenamedPat
+            -> RnMS RenamedPat
 
 mkConOpPatRn p1@(ConOpPatIn p11 op1 fix1 p12) 
             op2 fix2 p2
@@ -603,18 +649,18 @@ mkConOpPatRn p1@(ConOpPatIn p11 op1 fix1 p12)
   = addErrRn (precParseErr (op1,fix1) (op2,fix2))      `thenRn_`
     returnRn (ConOpPatIn p1 op2 fix2 p2)
 
-  | rearrange_me
+  | associate_right
   = mkConOpPatRn p12 op2 fix2 p2               `thenRn` \ new_p ->
     returnRn (ConOpPatIn p11 op1 fix1 new_p)
 
   where
-    (nofix_error, rearrange_me) = compareFixity fix1 fix2
+    (nofix_error, associate_right) = compareFixity fix1 fix2
 
 mkConOpPatRn p1@(NegPatIn neg_arg) 
          op2 
          fix2@(Fixity prec2 dir2)
          p2
-  | prec2 > 6  -- Precedence of unary - is wired in as 6!
+  | prec2 > negatePrecedence   -- Precedence of unary - is wired in
   = addErrRn (precParseNegPatErr (op2,fix2))   `thenRn_`
     returnRn (ConOpPatIn p1 op2 fix2 p2)
 
@@ -627,13 +673,19 @@ not_op_pat other                  = True
 \end{code}
 
 \begin{code}
-checkPrecMatch :: Bool -> Name -> RenamedMatch -> RnMS s ()
+checkPrecMatch :: Bool -> Name -> RenamedMatch -> RnMS ()
 
 checkPrecMatch False fn match
   = returnRn ()
+
 checkPrecMatch True op (Match _ [p1,p2] _ _)
-  = checkPrec op p1 False      `thenRn_`
-    checkPrec op p2 True
+  = getModeRn          `thenRn` \ mode ->
+       -- See comments with rnExpr (OpApp ...)
+    case mode of
+       InterfaceMode -> returnRn ()
+       SourceMode    -> checkPrec op p1 False  `thenRn_`
+                        checkPrec op p2 True
+
 checkPrecMatch True op _ = panic "checkPrecMatch"
 
 checkPrec op (ConOpPatIn _ op1 _ _) right
@@ -653,16 +705,17 @@ checkPrec op (ConOpPatIn _ op1 _ _) right
 
 checkPrec op (NegPatIn _) right
   = lookupFixity op    `thenRn` \ op_fix@(Fixity op_prec op_dir) ->
-    checkRn (op_prec <= 6) (precParseNegPatErr (op,op_fix))
+    checkRn (op_prec <= negatePrecedence) (precParseNegPatErr (op,op_fix))
 
 checkPrec op pat right
   = returnRn ()
 \end{code}
 
 Consider
+\begin{verbatim}
        a `op1` b `op2` c
-
-(compareFixity op1 op2) tells which way to arrange appication, or
+\end{verbatim}
+@(compareFixity op1 op2)@ tells which way to arrange appication, or
 whether there's an error.
 
 \begin{code}
@@ -689,29 +742,31 @@ compareFixity (Fixity prec1 dir1) (Fixity prec2 dir2)
 %*                                                                     *
 %************************************************************************
 
-When literals occur we have to make sure that the types and classes they involve
+When literals occur we have to make sure
+that the types and classes they involve
 are made available.
 
 \begin{code}
 litOccurrence (HsChar _)
-  = addImplicitOccRn charTyCon_name
+  = returnRn (unitFV charTyCon_name)
 
 litOccurrence (HsCharPrim _)
-  = addImplicitOccRn (getName charPrimTyCon)
+  = returnRn (unitFV (getName charPrimTyCon))
 
 litOccurrence (HsString _)
-  = addImplicitOccRn listTyCon_name    `thenRn_`
-    addImplicitOccRn charTyCon_name
+  = returnRn (unitFV listTyCon_name `plusFV` unitFV charTyCon_name)
 
 litOccurrence (HsStringPrim _)
-  = addImplicitOccRn (getName addrPrimTyCon)
+  = returnRn (unitFV (getName addrPrimTyCon))
 
 litOccurrence (HsInt _)
-  = lookupImplicitOccRn numClass_RDR                   -- Int and Integer are forced in by Num
+  = lookupImplicitOccRn numClass_RDR `thenRn` \ num ->
+    returnRn (unitFV num)                      -- Int and Integer are forced in by Num
 
 litOccurrence (HsFrac _)
-  = lookupImplicitOccRn fractionalClass_RDR    `thenRn_`
-    lookupImplicitOccRn ratioDataCon_RDR
+  = lookupImplicitOccRn fractionalClass_RDR    `thenRn` \ frac ->
+    lookupImplicitOccRn ratioDataCon_RDR       `thenRn` \ ratio ->
+    returnRn (unitFV frac `plusFV` unitFV ratio)
        -- 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.
@@ -719,16 +774,17 @@ litOccurrence (HsFrac _)
        -- when fractionalClass does.
     
 litOccurrence (HsIntPrim _)
-  = addImplicitOccRn (getName intPrimTyCon)
+  = returnRn (unitFV (getName intPrimTyCon))
 
 litOccurrence (HsFloatPrim _)
-  = addImplicitOccRn (getName floatPrimTyCon)
+  = returnRn (unitFV (getName floatPrimTyCon))
 
 litOccurrence (HsDoublePrim _)
-  = addImplicitOccRn (getName doublePrimTyCon)
+  = returnRn (unitFV (getName doublePrimTyCon))
 
 litOccurrence (HsLitLit _)
-  = lookupImplicitOccRn ccallableClass_RDR
+  = lookupImplicitOccRn ccallableClass_RDR     `thenRn` \ cc ->
+    returnRn (unitFV cc)
 \end{code}
 
 %************************************************************************
@@ -738,10 +794,9 @@ litOccurrence (HsLitLit _)
 %************************************************************************
 
 \begin{code}
-mkAssertExpr :: RnMS s RenamedHsExpr
+mkAssertExpr :: RnMS (RenamedHsExpr, FreeVars)
 mkAssertExpr =
-  newImportedGlobalFromRdrName assertErr_RDR   `thenRn` \ name ->
-  addOccurrenceName name                               `thenRn_`
+  mkImportedGlobalFromRdrName assertErr_RDR            `thenRn` \ name ->
   getSrcLocRn                                          `thenRn` \ sloc ->
 
     -- if we're ignoring asserts, return (\ _ e -> e)
@@ -757,7 +812,7 @@ mkAssertExpr =
                              (GRHSs [GRHS [ExprStmt (HsVar vname) loc] loc]
                                    EmptyBinds Nothing)
     in
-    returnRn expr
+    returnRn (expr, unitFV name)
   else
     let
      expr = 
@@ -765,7 +820,7 @@ mkAssertExpr =
                (HsLit (HsString (_PK_ (showSDoc (ppr sloc)))))
 
     in
-    returnRn expr
+    returnRn (expr, unitFV name)
 
 \end{code}
 
@@ -787,22 +842,27 @@ negPatErr pat
 precParseNegPatErr op 
   = hang (ptext SLIT("precedence parsing error"))
       4 (hsep [ptext SLIT("prefix `-' has lower precedence than"), 
-              quotes (pp_op op), 
+              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),
+      4 (hsep [ptext SLIT("cannot mix"), pp_op op1, ptext SLIT("and"), 
+              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)
+  = 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"))
+  =  (ptext SLIT("Illegal signature in pattern:") <+> ppr ty)
+       $$ nest 4 (ptext SLIT("Use -fglasgow-exts to permit it"))
+
+pp_op (op, fix) = hcat [quotes (ppr op), space, parens (ppr fix)]
 
-pp_op (op, fix) = hcat [ppr op, space, parens (ppr fix)]
+patSynErr e 
+  = sep [ptext SLIT("Pattern syntax in expression context:"),
+        nest 4 (ppr e)]
 \end{code}