Simon's big boxy-type commit
[ghc-hetmet.git] / ghc / compiler / typecheck / TcGenDeriv.lhs
index 5c66111..40e091d 100644 (file)
@@ -28,48 +28,38 @@ module TcGenDeriv (
 
 #include "HsVersions.h"
 
-import HsSyn           ( Pat(..), HsConDetails(..), HsExpr(..), MonoBinds(..),
-                         Match(..), GRHSs(..), Stmt(..), HsLit(..),
-                         HsBinds(..), HsType(..), HsStmtContext(..),
-                         unguardedRHS, mkSimpleMatch, mkMonoBind, andMonoBindList, placeHolderType
-                       )
-import RdrName         ( RdrName, mkUnqual, nameRdrName, getRdrName )
-import RdrHsSyn                ( mkHsOpApp, RdrNameMonoBinds, RdrNameHsExpr, RdrNamePat, mkHsDo )
-import BasicTypes      ( RecFlag(..), Fixity(..), FixityDirection(..)
-                       , maxPrecedence
-                       , Boxity(..)
-                       )
-import FieldLabel       ( fieldLabelName )
-import DataCon         ( isNullaryDataCon, dataConTag,
+import HsSyn
+import RdrName         ( RdrName, mkVarUnqual, getRdrName, mkRdrUnqual,
+                          mkDerivedRdrName )
+import BasicTypes      ( Fixity(..), maxPrecedence, Boxity(..) )
+import DataCon         ( isNullarySrcDataCon, dataConTag,
                          dataConOrigArgTys, dataConSourceArity, fIRST_TAG,
-                         DataCon, 
+                         DataCon, dataConName, dataConIsInfix,
                          dataConFieldLabels )
-import Name            ( getOccString, getOccName, getSrcLoc, occNameString, 
-                         occNameUserString, varName,
-                         Name, NamedThing(..), 
-                         isDataSymOcc, isSymOcc
-                       )
+import Name            ( getOccString, getSrcLoc, Name, NamedThing(..) )
 
 import HscTypes                ( FixityEnv, lookupFixity )
-import PrelNames       -- Lots of Names
-import PrimOp          -- Lots of Names
-import SrcLoc          ( generatedSrcLoc, SrcLoc )
-import TyCon           ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon,
-                         maybeTyConSingleCon, tyConFamilySize, tyConTyVars
+import PrelInfo
+import PrelNames
+import MkId            ( eRROR_ID )
+import PrimOp          ( PrimOp(..) )
+import SrcLoc          ( Located(..), noLoc, srcLocSpan )
+import TyCon           ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon, tyConArity,
+                         maybeTyConSingleCon, tyConFamilySize, tyConTyVars, tyConName
                        )
 import TcType          ( isUnLiftedType, tcEqType, Type )
-import TysPrim         ( charPrimTy, intPrimTy, wordPrimTy, addrPrimTy,
-                         floatPrimTy, doublePrimTy
-                       )
+import TysPrim         ( charPrimTy, intPrimTy, wordPrimTy, addrPrimTy, floatPrimTy, doublePrimTy,
+                         intPrimTyCon )
+import TysWiredIn      ( charDataCon, intDataCon, floatDataCon, doubleDataCon,
+                         intDataCon_RDR, true_RDR, false_RDR )
 import Util            ( zipWithEqual, isSingleton,
                          zipWith3Equal, nOfThem, zipEqual )
-import Panic           ( panic, assertPanic )
-import Char            ( ord, isAlpha )
 import Constants
 import List            ( partition, intersperse )
 import Outputable
 import FastString
 import OccName
+import Bag
 \end{code}
 
 %************************************************************************
@@ -152,53 +142,39 @@ instance ... Eq (Foo ...) where
 \end{itemize}
 
 
-deriveEq :: RdrName                            -- Class
-        -> RdrName                             -- Type constructor
-        -> [ (RdrName, [RdrType]) ]    -- Constructors
-        -> (RdrContext,                -- Context for the inst decl
-            [RdrBind],                 -- Binds in the inst decl
-            [RdrBind])                 -- Extra value bindings outside
-
-deriveEq clas tycon constrs 
-  = (context, [eq_bind, ne_bind], [])
-  where
-    context = [(clas, [ty]) | (_, tys) <- constrs, ty <- tys]
-
-    ne_bind = mkBind 
-    (nullary_cons, non_nullary_cons) = partition is_nullary constrs
-    is_nullary (_, args) = null args
-
 \begin{code}
-gen_Eq_binds :: TyCon -> RdrNameMonoBinds
+gen_Eq_binds :: TyCon -> LHsBinds RdrName
 
 gen_Eq_binds tycon
   = let
-       tycon_loc = getSrcLoc tycon
+       tycon_loc = getSrcSpan tycon
+
         (nullary_cons, nonnullary_cons)
            | isNewTyCon tycon = ([], tyConDataCons tycon)
-           | otherwise       = partition isNullaryDataCon (tyConDataCons tycon)
+           | otherwise       = partition isNullarySrcDataCon (tyConDataCons tycon)
 
        rest
          = if (null nullary_cons) then
                case maybeTyConSingleCon tycon of
                  Just _ -> []
                  Nothing -> -- if cons don't match, then False
-                    [([wildPat, wildPat], false_Expr)]
+                    [([nlWildPat, nlWildPat], false_Expr)]
            else -- calc. and compare the tags
                 [([a_Pat, b_Pat],
                    untag_Expr tycon [(a_RDR,ah_RDR), (b_RDR,bh_RDR)]
-                              (genOpApp (HsVar ah_RDR) eqInt_RDR (HsVar bh_RDR)))]
+                              (genOpApp (nlHsVar ah_RDR) eqInt_RDR (nlHsVar bh_RDR)))]
     in
-    mk_FunMonoBind tycon_loc eq_RDR ((map pats_etc nonnullary_cons) ++ rest)
-           `AndMonoBinds`
-    mk_easy_FunMonoBind tycon_loc ne_RDR [a_Pat, b_Pat] [] (
-       HsApp (HsVar not_RDR) (HsPar (mkHsVarApps eq_RDR [a_RDR, b_RDR])))
+    listToBag [
+      mk_FunBind tycon_loc eq_RDR ((map pats_etc nonnullary_cons) ++ rest),
+      mk_easy_FunBind tycon_loc ne_RDR [a_Pat, b_Pat] (
+       nlHsApp (nlHsVar not_RDR) (nlHsPar (nlHsVarApps eq_RDR [a_RDR, b_RDR])))
+    ]
   where
     ------------------------------------------------------------------
     pats_etc data_con
       = let
-           con1_pat = mkConPat data_con_RDR as_needed
-           con2_pat = mkConPat data_con_RDR bs_needed
+           con1_pat = nlConVarPat data_con_RDR as_needed
+           con2_pat = nlConVarPat data_con_RDR bs_needed
 
            data_con_RDR = getRdrName data_con
            con_arity   = length tys_needed
@@ -212,7 +188,7 @@ gen_Eq_binds tycon
        nested_eq_expr tys as bs
          = foldl1 and_Expr (zipWith3Equal "nested_eq" nested_eq tys as bs)
          where
-           nested_eq ty a b = HsPar (eq_Expr ty (HsVar a) (HsVar b))
+           nested_eq ty a b = nlHsPar (eq_Expr tycon ty (nlHsVar a) (nlHsVar b))
 \end{code}
 
 %************************************************************************
@@ -312,16 +288,19 @@ If there is only one constructor in the Data Type we don't need the WildCard Pat
 JJQC-30-Nov-1997
 
 \begin{code}
-gen_Ord_binds :: TyCon -> RdrNameMonoBinds
+gen_Ord_binds :: TyCon -> LHsBinds RdrName
 
 gen_Ord_binds tycon
-  = compare    -- `AndMonoBinds` compare       
+  = unitBag compare    -- `AndMonoBinds` compare       
                -- The default declaration in PrelBase handles this
   where
-    tycon_loc = getSrcLoc tycon
+    tycon_loc = getSrcSpan tycon
     --------------------------------------------------------------------
-    compare = mk_easy_FunMonoBind tycon_loc compare_RDR
-                                 [a_Pat, b_Pat] [cmp_eq] compare_rhs
+
+    compare = L tycon_loc (mkFunBind (L tycon_loc compare_RDR) compare_matches)
+    compare_matches = [mkMatch [a_Pat, b_Pat] compare_rhs cmp_eq_binds]
+    cmp_eq_binds    = HsValBinds (ValBindsIn (unitBag cmp_eq) [])
+
     compare_rhs
        | single_con_type = cmp_eq_Expr a_Expr b_Expr
        | otherwise
@@ -336,9 +315,9 @@ gen_Ord_binds tycon
     single_con_type = isSingleton tycon_data_cons
     (nullary_cons, nonnullary_cons)
        | isNewTyCon tycon = ([], tyConDataCons tycon)
-       | otherwise       = partition isNullaryDataCon tycon_data_cons
+       | otherwise       = partition isNullarySrcDataCon tycon_data_cons
 
-    cmp_eq = mk_FunMonoBind tycon_loc cmp_eq_RDR cmp_eq_match
+    cmp_eq = mk_FunBind tycon_loc cmp_eq_RDR cmp_eq_match
     cmp_eq_match
       | isEnumerationTyCon tycon
                           -- We know the tags are equal, so if it's an enumeration TyCon,
@@ -346,21 +325,21 @@ gen_Ord_binds tycon
                           -- Catch this specially to avoid warnings
                           -- about overlapping patterns from the desugarer,
                           -- and to avoid unnecessary pattern-matching
-      = [([wildPat,wildPat], eqTag_Expr)]
+      = [([nlWildPat,nlWildPat], eqTag_Expr)]
       | otherwise
       = map pats_etc nonnullary_cons ++
        (if single_con_type then        -- Omit wildcards when there's just one 
              []                        -- constructor, to silence desugarer
        else
-              [([wildPat, wildPat], default_rhs)])
+              [([nlWildPat, nlWildPat], default_rhs)])
 
       where
        pats_etc data_con
          = ([con1_pat, con2_pat],
             nested_compare_expr tys_needed as_needed bs_needed)
          where
-           con1_pat = mkConPat data_con_RDR as_needed
-           con2_pat = mkConPat data_con_RDR bs_needed
+           con1_pat = nlConVarPat data_con_RDR as_needed
+           con2_pat = nlConVarPat data_con_RDR bs_needed
 
            data_con_RDR = getRdrName data_con
            con_arity   = length tys_needed
@@ -369,11 +348,11 @@ gen_Ord_binds tycon
            tys_needed  = dataConOrigArgTys data_con
 
            nested_compare_expr [ty] [a] [b]
-             = careful_compare_Case ty eqTag_Expr (HsVar a) (HsVar b)
+             = careful_compare_Case tycon ty eqTag_Expr (nlHsVar a) (nlHsVar b)
 
            nested_compare_expr (ty:tys) (a:as) (b:bs)
              = let eq_expr = nested_compare_expr tys as bs
-               in  careful_compare_Case ty eq_expr (HsVar a) (HsVar b)
+               in  careful_compare_Case tycon ty eq_expr (nlHsVar a) (nlHsVar b)
 
        default_rhs | null nullary_cons = impossible_Expr       -- Keep desugarer from complaining about
                                                                -- inexhaustive patterns
@@ -423,76 +402,75 @@ instance ... Enum (Foo ...) where
 For @enumFromTo@ and @enumFromThenTo@, we use the default methods.
 
 \begin{code}
-gen_Enum_binds :: TyCon -> RdrNameMonoBinds
+gen_Enum_binds :: TyCon -> LHsBinds RdrName
 
 gen_Enum_binds tycon
-  = succ_enum          `AndMonoBinds`
-    pred_enum          `AndMonoBinds`
-    to_enum             `AndMonoBinds`
-    enum_from          `AndMonoBinds`
-    enum_from_then     `AndMonoBinds`
-    from_enum
+  = listToBag [
+       succ_enum,
+       pred_enum,
+       to_enum,
+       enum_from,
+       enum_from_then,
+       from_enum
+    ]
   where
-    tycon_loc = getSrcLoc tycon
+    tycon_loc = getSrcSpan tycon
     occ_nm    = getOccString tycon
 
     succ_enum
-      = mk_easy_FunMonoBind tycon_loc succ_RDR [a_Pat] [] $
+      = mk_easy_FunBind tycon_loc succ_RDR [a_Pat] $
        untag_Expr tycon [(a_RDR, ah_RDR)] $
-       HsIf (mkHsApps eq_RDR [HsVar (maxtag_RDR tycon),
-                              mkHsVarApps mkInt_RDR [ah_RDR]])
+       nlHsIf (nlHsApps eq_RDR [nlHsVar (maxtag_RDR tycon),
+                              nlHsVarApps intDataCon_RDR [ah_RDR]])
             (illegal_Expr "succ" occ_nm "tried to take `succ' of last tag in enumeration")
-            (HsApp (HsVar (tag2con_RDR tycon))
-                   (mkHsApps plus_RDR [mkHsVarApps mkInt_RDR [ah_RDR],
-                                       mkHsIntLit 1]))
-            tycon_loc
+            (nlHsApp (nlHsVar (tag2con_RDR tycon))
+                   (nlHsApps plus_RDR [nlHsVarApps intDataCon_RDR [ah_RDR],
+                                       nlHsIntLit 1]))
                    
     pred_enum
-      = mk_easy_FunMonoBind tycon_loc pred_RDR [a_Pat] [] $
+      = mk_easy_FunBind tycon_loc pred_RDR [a_Pat] $
        untag_Expr tycon [(a_RDR, ah_RDR)] $
-       HsIf (mkHsApps eq_RDR [mkHsIntLit 0,
-                              mkHsVarApps mkInt_RDR [ah_RDR]])
+       nlHsIf (nlHsApps eq_RDR [nlHsIntLit 0,
+                              nlHsVarApps intDataCon_RDR [ah_RDR]])
             (illegal_Expr "pred" occ_nm "tried to take `pred' of first tag in enumeration")
-            (HsApp (HsVar (tag2con_RDR tycon))
-                          (mkHsApps plus_RDR [mkHsVarApps mkInt_RDR [ah_RDR],
-                                              HsLit (HsInt (-1))]))
-            tycon_loc
+            (nlHsApp (nlHsVar (tag2con_RDR tycon))
+                          (nlHsApps plus_RDR [nlHsVarApps intDataCon_RDR [ah_RDR],
+                                              nlHsLit (HsInt (-1))]))
 
     to_enum
-      = mk_easy_FunMonoBind tycon_loc toEnum_RDR [a_Pat] [] $
-       HsIf (mkHsApps and_RDR
-               [mkHsApps ge_RDR [HsVar a_RDR, mkHsIntLit 0],
-                 mkHsApps le_RDR [HsVar a_RDR, HsVar (maxtag_RDR tycon)]])
-             (mkHsVarApps (tag2con_RDR tycon) [a_RDR])
+      = mk_easy_FunBind tycon_loc toEnum_RDR [a_Pat] $
+       nlHsIf (nlHsApps and_RDR
+               [nlHsApps ge_RDR [nlHsVar a_RDR, nlHsIntLit 0],
+                 nlHsApps le_RDR [nlHsVar a_RDR, nlHsVar (maxtag_RDR tycon)]])
+             (nlHsVarApps (tag2con_RDR tycon) [a_RDR])
             (illegal_toEnum_tag occ_nm (maxtag_RDR tycon))
-            tycon_loc
 
     enum_from
-      = mk_easy_FunMonoBind tycon_loc enumFrom_RDR [a_Pat] [] $
+      = mk_easy_FunBind tycon_loc enumFrom_RDR [a_Pat] $
          untag_Expr tycon [(a_RDR, ah_RDR)] $
-         mkHsApps map_RDR 
-               [HsVar (tag2con_RDR tycon),
-                HsPar (enum_from_to_Expr
-                           (mkHsVarApps mkInt_RDR [ah_RDR])
-                           (HsVar (maxtag_RDR tycon)))]
+         nlHsApps map_RDR 
+               [nlHsVar (tag2con_RDR tycon),
+                nlHsPar (enum_from_to_Expr
+                           (nlHsVarApps intDataCon_RDR [ah_RDR])
+                           (nlHsVar (maxtag_RDR tycon)))]
 
     enum_from_then
-      = mk_easy_FunMonoBind tycon_loc enumFromThen_RDR [a_Pat, b_Pat] [] $
+      = mk_easy_FunBind tycon_loc enumFromThen_RDR [a_Pat, b_Pat] $
          untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)] $
-         HsApp (mkHsVarApps map_RDR [tag2con_RDR tycon]) $
-           HsPar (enum_from_then_to_Expr
-                   (mkHsVarApps mkInt_RDR [ah_RDR])
-                   (mkHsVarApps mkInt_RDR [bh_RDR])
-                   (HsIf  (mkHsApps gt_RDR [mkHsVarApps mkInt_RDR [ah_RDR],
-                                            mkHsVarApps mkInt_RDR [bh_RDR]])
-                          (mkHsIntLit 0)
-                          (HsVar (maxtag_RDR tycon))
-                          tycon_loc))
+         nlHsApp (nlHsVarApps map_RDR [tag2con_RDR tycon]) $
+           nlHsPar (enum_from_then_to_Expr
+                   (nlHsVarApps intDataCon_RDR [ah_RDR])
+                   (nlHsVarApps intDataCon_RDR [bh_RDR])
+                   (nlHsIf  (nlHsApps gt_RDR [nlHsVarApps intDataCon_RDR [ah_RDR],
+                                            nlHsVarApps intDataCon_RDR [bh_RDR]])
+                          (nlHsIntLit 0)
+                          (nlHsVar (maxtag_RDR tycon))
+                          ))
 
     from_enum
-      = mk_easy_FunMonoBind tycon_loc fromEnum_RDR [a_Pat] [] $
+      = mk_easy_FunBind tycon_loc fromEnum_RDR [a_Pat] $
          untag_Expr tycon [(a_RDR, ah_RDR)] $
-         (mkHsVarApps mkInt_RDR [ah_RDR])
+         (nlHsVarApps intDataCon_RDR [ah_RDR])
 \end{code}
 
 %************************************************************************
@@ -504,17 +482,17 @@ gen_Enum_binds tycon
 \begin{code}
 gen_Bounded_binds tycon
   = if isEnumerationTyCon tycon then
-       min_bound_enum `AndMonoBinds` max_bound_enum
+       listToBag [ min_bound_enum, max_bound_enum ]
     else
        ASSERT(isSingleton data_cons)
-       min_bound_1con `AndMonoBinds` max_bound_1con
+       listToBag [ min_bound_1con, max_bound_1con ]
   where
     data_cons = tyConDataCons tycon
-    tycon_loc = getSrcLoc tycon
+    tycon_loc = getSrcSpan tycon
 
     ----- enum-flavored: ---------------------------
-    min_bound_enum = mkVarMonoBind tycon_loc minBound_RDR (HsVar data_con_1_RDR)
-    max_bound_enum = mkVarMonoBind tycon_loc maxBound_RDR (HsVar data_con_N_RDR)
+    min_bound_enum = mkVarBind tycon_loc minBound_RDR (nlHsVar data_con_1_RDR)
+    max_bound_enum = mkVarBind tycon_loc maxBound_RDR (nlHsVar data_con_N_RDR)
 
     data_con_1   = head data_cons
     data_con_N   = last data_cons
@@ -524,10 +502,10 @@ gen_Bounded_binds tycon
     ----- single-constructor-flavored: -------------
     arity         = dataConSourceArity data_con_1
 
-    min_bound_1con = mkVarMonoBind tycon_loc minBound_RDR $
-                    mkHsVarApps data_con_1_RDR (nOfThem arity minBound_RDR)
-    max_bound_1con = mkVarMonoBind tycon_loc maxBound_RDR $
-                    mkHsVarApps data_con_1_RDR (nOfThem arity maxBound_RDR)
+    min_bound_1con = mkVarBind tycon_loc minBound_RDR $
+                    nlHsVarApps data_con_1_RDR (nOfThem arity minBound_RDR)
+    max_bound_1con = mkVarBind tycon_loc maxBound_RDR $
+                    nlHsVarApps data_con_1_RDR (nOfThem arity maxBound_RDR)
 \end{code}
 
 %************************************************************************
@@ -556,11 +534,11 @@ instance ... Ix (Foo ...) where
        map tag2con_Foo (enumFromTo (I# a#) (I# b#))
        }}
 
-    index c@(a, b) d
-      = if inRange c d
-       then case (con2tag_Foo d -# con2tag_Foo a) of
+    -- Generate code for unsafeIndex, becuase using index leads
+    -- to lots of redundant range tests
+    unsafeIndex c@(a, b) d
+      = case (con2tag_Foo d -# con2tag_Foo a) of
               r# -> I# r#
-       else error "Ix.Foo.index: out of range"
 
     inRange (a, b) c
       = let
@@ -589,75 +567,64 @@ we follow the scheme given in Figure~19 of the Haskell~1.2 report
 (p.~147).
 
 \begin{code}
-gen_Ix_binds :: TyCon -> RdrNameMonoBinds
+gen_Ix_binds :: TyCon -> LHsBinds RdrName
 
 gen_Ix_binds tycon
   = if isEnumerationTyCon tycon
     then enum_ixes
     else single_con_ixes
   where
-    tycon_str = getOccString tycon
-    tycon_loc = getSrcLoc tycon
+    tycon_loc = getSrcSpan tycon
 
     --------------------------------------------------------------
-    enum_ixes = enum_range `AndMonoBinds`
-               enum_index `AndMonoBinds` enum_inRange
+    enum_ixes = listToBag [ enum_range, enum_index, enum_inRange ]
 
     enum_range
-      = mk_easy_FunMonoBind tycon_loc range_RDR 
-               [TuplePat [a_Pat, b_Pat] Boxed] [] $
+      = mk_easy_FunBind tycon_loc range_RDR [nlTuplePat [a_Pat, b_Pat] Boxed] $
          untag_Expr tycon [(a_RDR, ah_RDR)] $
          untag_Expr tycon [(b_RDR, bh_RDR)] $
-         HsApp (mkHsVarApps map_RDR [tag2con_RDR tycon]) $
-             HsPar (enum_from_to_Expr
-                       (mkHsVarApps mkInt_RDR [ah_RDR])
-                       (mkHsVarApps mkInt_RDR [bh_RDR]))
+         nlHsApp (nlHsVarApps map_RDR [tag2con_RDR tycon]) $
+             nlHsPar (enum_from_to_Expr
+                       (nlHsVarApps intDataCon_RDR [ah_RDR])
+                       (nlHsVarApps intDataCon_RDR [bh_RDR]))
 
     enum_index
-      = mk_easy_FunMonoBind tycon_loc index_RDR 
-               [AsPat c_RDR (TuplePat [a_Pat, wildPat] Boxed), 
-                               d_Pat] [] (
-       HsIf (HsPar (mkHsVarApps inRange_RDR [c_RDR, d_RDR])) (
+      = mk_easy_FunBind tycon_loc unsafeIndex_RDR 
+               [noLoc (AsPat (noLoc c_RDR) 
+                          (nlTuplePat [a_Pat, nlWildPat] Boxed)), 
+                               d_Pat] (
           untag_Expr tycon [(a_RDR, ah_RDR)] (
           untag_Expr tycon [(d_RDR, dh_RDR)] (
           let
-               rhs = mkHsVarApps mkInt_RDR [c_RDR]
+               rhs = nlHsVarApps intDataCon_RDR [c_RDR]
           in
-          HsCase
-            (genOpApp (HsVar dh_RDR) minusInt_RDR (HsVar ah_RDR))
-            [mkSimpleMatch [VarPat c_RDR] rhs placeHolderType tycon_loc]
-            tycon_loc
+          nlHsCase
+            (genOpApp (nlHsVar dh_RDR) minusInt_RDR (nlHsVar ah_RDR))
+            [mkSimpleHsAlt (nlVarPat c_RDR) rhs]
           ))
-       ) {-else-} (
-          HsApp (HsVar error_RDR) (HsLit (HsString (mkFastString ("Ix."++tycon_str++".index: out of range\n"))))
        )
-       tycon_loc)
 
     enum_inRange
-      = mk_easy_FunMonoBind tycon_loc inRange_RDR 
-         [TuplePat [a_Pat, b_Pat] Boxed, c_Pat] [] (
+      = mk_easy_FunBind tycon_loc inRange_RDR [nlTuplePat [a_Pat, b_Pat] Boxed, c_Pat] $
          untag_Expr tycon [(a_RDR, ah_RDR)] (
          untag_Expr tycon [(b_RDR, bh_RDR)] (
          untag_Expr tycon [(c_RDR, ch_RDR)] (
-         HsIf (genOpApp (HsVar ch_RDR) geInt_RDR (HsVar ah_RDR)) (
-            (genOpApp (HsVar ch_RDR) leInt_RDR (HsVar bh_RDR))
+         nlHsIf (genOpApp (nlHsVar ch_RDR) geInt_RDR (nlHsVar ah_RDR)) (
+            (genOpApp (nlHsVar ch_RDR) leInt_RDR (nlHsVar bh_RDR))
          ) {-else-} (
             false_Expr
-         ) tycon_loc))))
+         ))))
 
     --------------------------------------------------------------
     single_con_ixes 
-      = single_con_range `AndMonoBinds`
-       single_con_index `AndMonoBinds`
-       single_con_inRange
+      = listToBag [single_con_range, single_con_index, single_con_inRange]
 
     data_con
       =        case maybeTyConSingleCon tycon of -- just checking...
          Nothing -> panic "get_Ix_binds"
-         Just dc -> if (any isUnLiftedType (dataConOrigArgTys dc)) then
-                        error ("ERROR: Can't derive Ix for a single-constructor type with primitive argument types: "++tycon_str)
-                    else
-                        dc
+         Just dc | any isUnLiftedType (dataConOrigArgTys dc)
+                 -> pprPanic "Can't derive Ix for a single-constructor type with primitive argument types:" (ppr tycon)
+                 | otherwise -> dc
 
     con_arity    = dataConSourceArity data_con
     data_con_RDR = getRdrName data_con
@@ -666,60 +633,52 @@ gen_Ix_binds tycon
     bs_needed = take con_arity bs_RDRs
     cs_needed = take con_arity cs_RDRs
 
-    con_pat  xs  = mkConPat data_con_RDR xs
-    con_expr     = mkHsVarApps data_con_RDR cs_needed
+    con_pat  xs  = nlConVarPat data_con_RDR xs
+    con_expr     = nlHsVarApps data_con_RDR cs_needed
 
     --------------------------------------------------------------
     single_con_range
-      = mk_easy_FunMonoBind tycon_loc range_RDR 
-         [TuplePat [con_pat as_needed, con_pat bs_needed] Boxed] [] $
-       mkHsDo ListComp stmts tycon_loc
+      = mk_easy_FunBind tycon_loc range_RDR 
+         [nlTuplePat [con_pat as_needed, con_pat bs_needed] Boxed] $
+       nlHsDo ListComp stmts con_expr
       where
        stmts = zipWith3Equal "single_con_range" mk_qual as_needed bs_needed cs_needed
-               ++
-               [ResultStmt con_expr tycon_loc]
 
-       mk_qual a b c = BindStmt (VarPat c)
-                                (HsApp (HsVar range_RDR) 
-                                       (ExplicitTuple [HsVar a, HsVar b] Boxed))
-                                tycon_loc
+       mk_qual a b c = noLoc $ mkBindStmt (nlVarPat c)
+                                (nlHsApp (nlHsVar range_RDR) 
+                                       (nlTuple [nlHsVar a, nlHsVar b] Boxed))
 
     ----------------
     single_con_index
-      = mk_easy_FunMonoBind tycon_loc index_RDR 
-               [TuplePat [con_pat as_needed, con_pat bs_needed] Boxed, 
-                con_pat cs_needed] [range_size] (
-       foldl mk_index (mkHsIntLit 0) (zip3 as_needed bs_needed cs_needed))
+      = mk_easy_FunBind tycon_loc unsafeIndex_RDR 
+               [nlTuplePat [con_pat as_needed, con_pat bs_needed] Boxed, 
+                con_pat cs_needed] 
+               (mk_index (zip3 as_needed bs_needed cs_needed))
       where
-       mk_index multiply_by (l, u, i)
+       -- index (l1,u1) i1 + rangeSize (l1,u1) * (index (l2,u2) i2 + ...)
+       mk_index []        = nlHsIntLit 0
+       mk_index [(l,u,i)] = mk_one l u i
+       mk_index ((l,u,i) : rest)
          = genOpApp (
-              (mkHsApps index_RDR [ExplicitTuple [HsVar l, HsVar u] Boxed,  
-                                   HsVar i])
-          ) plus_RDR (
+               mk_one l u i
+           ) plus_RDR (
                genOpApp (
-                   (HsApp (HsVar rangeSize_RDR) 
-                          (ExplicitTuple [HsVar l, HsVar u] Boxed))
-               ) times_RDR multiply_by
+                   (nlHsApp (nlHsVar unsafeRangeSize_RDR) 
+                          (nlTuple [nlHsVar l, nlHsVar u] Boxed))
+               ) times_RDR (mk_index rest)
           )
-
-       range_size
-         = mk_easy_FunMonoBind tycon_loc rangeSize_RDR 
-                       [TuplePat [a_Pat, b_Pat] Boxed] [] (
-               genOpApp (
-                   (mkHsApps index_RDR [ExplicitTuple [a_Expr, b_Expr] Boxed,
-                                        b_Expr])
-               ) plus_RDR (mkHsIntLit 1))
+       mk_one l u i
+         = nlHsApps unsafeIndex_RDR [nlTuple [nlHsVar l, nlHsVar u] Boxed, nlHsVar i]
 
     ------------------
     single_con_inRange
-      = mk_easy_FunMonoBind tycon_loc inRange_RDR 
-               [TuplePat [con_pat as_needed, con_pat bs_needed] Boxed, 
-                con_pat cs_needed]
-                          [] (
-         foldl1 and_Expr (zipWith3Equal "single_con_inRange" in_range as_needed bs_needed cs_needed))
+      = mk_easy_FunBind tycon_loc inRange_RDR 
+               [nlTuplePat [con_pat as_needed, con_pat bs_needed] Boxed, 
+                con_pat cs_needed] $
+         foldl1 and_Expr (zipWith3Equal "single_con_inRange" in_range as_needed bs_needed cs_needed)
       where
-       in_range a b c = mkHsApps inRange_RDR [ExplicitTuple [HsVar a, HsVar b] Boxed,
-                                              HsVar c]
+       in_range a b c = nlHsApps inRange_RDR [nlTuple [nlHsVar a, nlHsVar b] Boxed,
+                                              nlHsVar c]
 \end{code}
 
 %************************************************************************
@@ -765,24 +724,25 @@ instance Read T where
 
 
 \begin{code}
-gen_Read_binds :: FixityEnv -> TyCon -> RdrNameMonoBinds
+gen_Read_binds :: FixityEnv -> TyCon -> LHsBinds RdrName
 
 gen_Read_binds get_fixity tycon
-  = read_prec `AndMonoBinds` default_binds
+  = listToBag [read_prec, default_readlist, default_readlistprec]
   where
     -----------------------------------------------------------------------
-    default_binds 
-       = mkVarMonoBind loc readList_RDR     (HsVar readListDefault_RDR)
-               `AndMonoBinds`
-         mkVarMonoBind loc readListPrec_RDR (HsVar readListPrecDefault_RDR)
+    default_readlist 
+       = mkVarBind loc readList_RDR     (nlHsVar readListDefault_RDR)
+
+    default_readlistprec
+       = mkVarBind loc readListPrec_RDR (nlHsVar readListPrecDefault_RDR)
     -----------------------------------------------------------------------
 
-    loc       = getSrcLoc tycon
+    loc       = getSrcSpan tycon
     data_cons = tyConDataCons tycon
-    (nullary_cons, non_nullary_cons) = partition isNullaryDataCon data_cons
+    (nullary_cons, non_nullary_cons) = partition isNullarySrcDataCon data_cons
     
-    read_prec = mkVarMonoBind loc readPrec_RDR
-                             (HsApp (HsVar parens_RDR) read_cons)
+    read_prec = mkVarBind loc readPrec_RDR
+                             (nlHsApp (nlHsVar parens_RDR) read_cons)
 
     read_cons            = foldr1 mk_alt (read_nullary_cons ++ read_non_nullary_cons)
     read_non_nullary_cons = map read_non_nullary_con non_nullary_cons
@@ -790,87 +750,89 @@ gen_Read_binds get_fixity tycon
     read_nullary_cons 
       = case nullary_cons of
            []    -> []
-           [con] -> [mkHsDo DoExpr [bindLex (ident_pat (data_con_str con)),
-                                    result_stmt con []] loc]
-            _     -> [HsApp (HsVar choose_RDR) 
-                           (ExplicitList placeHolderType (map mk_pair nullary_cons))]
+           [con] -> [nlHsDo DoExpr [bindLex (ident_pat (data_con_str con))]
+                                   (result_expr con [])]
+            _     -> [nlHsApp (nlHsVar choose_RDR) 
+                           (nlList (map mk_pair nullary_cons))]
     
-    mk_pair con = ExplicitTuple [HsLit (data_con_str con),
-                                HsApp (HsVar returnM_RDR) (HsVar (getRdrName con))]
-                               Boxed
+    mk_pair con = nlTuple [nlHsLit (mkHsString (data_con_str con)),
+                                  nlHsApp (nlHsVar returnM_RDR) (nlHsVar (getRdrName con))]
+                                  Boxed
     
     read_non_nullary_con data_con
-      = mkHsApps prec_RDR [mkHsIntLit prec, mkHsDo DoExpr stmts loc]
+      = nlHsApps prec_RDR [nlHsIntLit prec, nlHsDo DoExpr stmts body]
       where
                stmts | is_infix          = infix_stmts
              | length labels > 0 = lbl_stmts
              | otherwise         = prefix_stmts
      
+       body = result_expr data_con as_needed
+       con_str = data_con_str data_con
+       
                prefix_stmts            -- T a b c
-                 = [bindLex (ident_pat (data_con_str data_con))]
-                   ++ map read_arg as_needed
-                   ++ [result_stmt data_con as_needed]
+                 = [bindLex (ident_pat (wrapOpParens con_str))]
+                   ++ read_args
         
-               infix_stmts             -- a %% b
-                 = [read_arg a1, 
-            bindLex (symbol_pat (data_con_str data_con)),
-            read_arg a2,
-            result_stmt data_con [a1,a2]]
+               infix_stmts             -- a %% b, or  a `T` b 
+                 = [read_a1]
+           ++  (if isSym con_str
+                then [bindLex (symbol_pat con_str)]
+                else [read_punc "`", bindLex (ident_pat con_str), read_punc "`"])
+           ++ [read_a2]
      
                lbl_stmts               -- T { f1 = a, f2 = b }
-                 = [bindLex (ident_pat (data_con_str data_con)),
+                 = [bindLex (ident_pat (wrapOpParens con_str)),
                     read_punc "{"]
                    ++ concat (intersperse [read_punc ","] field_stmts)
-                   ++ [read_punc "}", result_stmt data_con as_needed]
+                   ++ [read_punc "}"]
      
                field_stmts  = zipWithEqual "lbl_stmts" read_field labels as_needed
      
                con_arity    = dataConSourceArity data_con
-               nullary_con  = con_arity == 0
                labels       = dataConFieldLabels data_con
-               lab_fields   = length labels
                dc_nm        = getName data_con
-               is_infix     = isDataSymOcc (getOccName dc_nm)
+               is_infix     = dataConIsInfix data_con
                as_needed    = take con_arity as_RDRs
-               (a1:a2:_)    = as_needed
+       read_args    = zipWithEqual "gen_Read_binds" read_arg as_needed (dataConOrigArgTys data_con)
+               (read_a1:read_a2:_) = read_args
                prec         = getPrec is_infix get_fixity dc_nm
 
     ------------------------------------------------------------------------
     --         Helpers
     ------------------------------------------------------------------------
     mk_alt e1 e2     = genOpApp e1 alt_RDR e2
-    bindLex pat             = BindStmt pat (HsVar lexP_RDR) loc
-    result_stmt c as = ResultStmt (HsApp (HsVar returnM_RDR) (con_app c as)) loc
-    con_app c as     = mkHsVarApps (getRdrName c) as
+    bindLex pat             = noLoc (mkBindStmt pat (nlHsVar lexP_RDR))
+    con_app c as     = nlHsVarApps (getRdrName c) as
+    result_expr c as = nlHsApp (nlHsVar returnM_RDR) (con_app c as)
     
-    punc_pat s   = ConPatIn punc_RDR  (PrefixCon [LitPat (mkHsString s)])        -- Punc 'c'
-    ident_pat s  = ConPatIn ident_RDR (PrefixCon [LitPat s])                     -- Ident "foo"
-    symbol_pat s = ConPatIn symbol_RDR (PrefixCon [LitPat s])                    -- Symbol ">>"
+    punc_pat s   = nlConPat punc_RDR   [nlLitPat (mkHsString s)]  -- Punc 'c'
+    ident_pat s  = nlConPat ident_RDR  [nlLitPat (mkHsString s)]  -- Ident "foo"
+    symbol_pat s = nlConPat symbol_RDR [nlLitPat (mkHsString s)]  -- Symbol ">>"
     
-    data_con_str con = mkHsString (occNameUserString (getOccName con))
+    data_con_str con = occNameString (getOccName con)
     
     read_punc c = bindLex (punc_pat c)
-    read_arg a  = BindStmt (VarPat a) (mkHsVarApps step_RDR [readPrec_RDR]) loc
+    read_arg a ty 
+       | isUnLiftedType ty = pprPanic "Error in deriving:" (text "Can't read unlifted types yet:" <+> ppr ty)
+       | otherwise = noLoc (mkBindStmt (nlVarPat a) (nlHsVarApps step_RDR [readPrec_RDR]))
     
     read_field lbl a = read_lbl lbl ++
                       [read_punc "=",
-                       BindStmt (VarPat a) (mkHsVarApps reset_RDR [readPrec_RDR]) loc]
+                       noLoc (mkBindStmt (nlVarPat a) (nlHsVarApps reset_RDR [readPrec_RDR]))]
 
        -- When reading field labels we might encounter
        --      a  = 3
        --      _a = 3
        -- or   (#) = 4
        -- Note the parens!
-    read_lbl lbl | is_id_start (head lbl_str) 
-                = [bindLex (ident_pat lbl_lit)]
-                | otherwise
+    read_lbl lbl | isSym lbl_str 
                 = [read_punc "(", 
-                   bindLex (symbol_pat lbl_lit),
+                   bindLex (symbol_pat lbl_str),
                    read_punc ")"]
+                | otherwise
+                = [bindLex (ident_pat lbl_str)]
                 where  
-                  lbl_str = occNameUserString (getOccName (fieldLabelName lbl)) 
-                  lbl_lit = mkHsString lbl_str
-                  is_id_start c = isAlpha c || c == '_'
+                  lbl_str = occNameString (getOccName lbl) 
 \end{code}
 
 
@@ -904,31 +866,32 @@ Example
                    -- the most tightly-binding operator
 
 \begin{code}
-gen_Show_binds :: FixityEnv -> TyCon -> RdrNameMonoBinds
+gen_Show_binds :: FixityEnv -> TyCon -> LHsBinds RdrName
 
 gen_Show_binds get_fixity tycon
-  = shows_prec `AndMonoBinds` show_list
+  = listToBag [shows_prec, show_list]
   where
-    tycon_loc = getSrcLoc tycon
+    tycon_loc = getSrcSpan tycon
     -----------------------------------------------------------------------
-    show_list = mkVarMonoBind tycon_loc showList_RDR
-                 (HsApp (HsVar showList___RDR) (HsPar (HsApp (HsVar showsPrec_RDR) (mkHsIntLit 0))))
+    show_list = mkVarBind tycon_loc showList_RDR
+                 (nlHsApp (nlHsVar showList___RDR) (nlHsPar (nlHsApp (nlHsVar showsPrec_RDR) (nlHsIntLit 0))))
     -----------------------------------------------------------------------
-    shows_prec = mk_FunMonoBind tycon_loc showsPrec_RDR (map pats_etc (tyConDataCons tycon))
+    shows_prec = mk_FunBind tycon_loc showsPrec_RDR (map pats_etc (tyConDataCons tycon))
       where
        pats_etc data_con
          | nullary_con =  -- skip the showParen junk...
             ASSERT(null bs_needed)
-            ([wildPat, con_pat], mk_showString_app con_str)
+            ([nlWildPat, con_pat], mk_showString_app con_str)
          | otherwise   =
             ([a_Pat, con_pat],
-                 showParen_Expr (HsPar (genOpApp a_Expr ge_RDR (HsLit (HsInt con_prec_plus_one))))
-                                (HsPar (nested_compose_Expr show_thingies)))
+                 showParen_Expr (nlHsPar (genOpApp a_Expr ge_RDR (nlHsLit (HsInt con_prec_plus_one))))
+                                (nlHsPar (nested_compose_Expr show_thingies)))
            where
             data_con_RDR  = getRdrName data_con
             con_arity     = dataConSourceArity data_con
             bs_needed     = take con_arity bs_RDRs
-            con_pat       = mkConPat data_con_RDR bs_needed
+            arg_tys       = dataConOrigArgTys data_con         -- Correspond 1-1 with bs_needed
+            con_pat       = nlConVarPat data_con_RDR bs_needed
             nullary_con   = con_arity == 0
              labels        = dataConFieldLabels data_con
             lab_fields    = length labels
@@ -936,32 +899,28 @@ gen_Show_binds get_fixity tycon
 
             dc_nm          = getName data_con
             dc_occ_nm      = getOccName data_con
-             con_str        = occNameUserString dc_occ_nm
+             con_str        = occNameString dc_occ_nm
+            op_con_str     = wrapOpParens con_str
+            backquote_str  = wrapOpBackquotes con_str
 
             show_thingies 
-               | is_infix      = [show_arg1, mk_showString_app (" " ++ con_str ++ " "), show_arg2]
-               | record_syntax = mk_showString_app (con_str ++ " {") : 
+               | is_infix      = [show_arg1, mk_showString_app (" " ++ backquote_str ++ " "), show_arg2]
+               | record_syntax = mk_showString_app (op_con_str ++ " {") : 
                                  show_record_args ++ [mk_showString_app "}"]
-               | otherwise     = mk_showString_app (con_str ++ " ") : show_prefix_args
+               | otherwise     = mk_showString_app (op_con_str ++ " ") : show_prefix_args
                 
-            show_label l = mk_showString_app (the_name ++ " = ")
+            show_label l = mk_showString_app (nm ++ " = ")
                        -- Note the spaces around the "=" sign.  If we don't have them
                        -- then we get Foo { x=-1 } and the "=-" parses as a single
                        -- lexeme.  Only the space after the '=' is necessary, but
                        -- it seems tidier to have them both sides.
                 where
-                  occ_nm   = getOccName (fieldLabelName l)
-                  nm       = occNameUserString occ_nm
+                  occ_nm   = getOccName l
+                  nm       = wrapOpParens (occNameString occ_nm)
 
-                  is_op    = isSymOcc occ_nm       -- Legal, but rare.
-                  the_name 
-                    | is_op     = '(':nm ++ ")"
-                    | otherwise = nm
-
-             show_args = [ mkHsApps showsPrec_RDR [HsLit (HsInt arg_prec), HsVar b]
-                        | b <- bs_needed ]
+             show_args                      = zipWith show_arg bs_needed arg_tys
             (show_arg1:show_arg2:_) = show_args
-            show_prefix_args = intersperse (HsVar showSpace_RDR) show_args
+            show_prefix_args        = intersperse (nlHsVar showSpace_RDR) show_args
 
                --  Assumption for record syntax: no of fields == no of labelled fields 
                --            (and in same order)
@@ -971,13 +930,31 @@ gen_Show_binds get_fixity tycon
                                | (lbl,arg) <- zipEqual "gen_Show_binds" 
                                                        labels show_args ]
                               
+               -- Generates (showsPrec p x) for argument x, but it also boxes
+               -- the argument first if necessary.  Note that this prints unboxed
+               -- things without any '#' decorations; could change that if need be
+            show_arg b arg_ty = nlHsApps showsPrec_RDR [nlHsLit (HsInt arg_prec), 
+                                                        box_if_necy "Show" tycon (nlHsVar b) arg_ty]
+
                -- Fixity stuff
-            is_infix = isDataSymOcc dc_occ_nm
+            is_infix = dataConIsInfix data_con
              con_prec_plus_one = 1 + getPrec is_infix get_fixity dc_nm
             arg_prec | record_syntax = 0       -- Record fields don't need parens
                      | otherwise     = con_prec_plus_one
 
-mk_showString_app str = HsApp (HsVar showString_RDR) (HsLit (mkHsString str))
+wrapOpParens :: String -> String
+wrapOpParens s | isSym s   = '(' : s ++ ")"
+              | otherwise = s
+
+wrapOpBackquotes :: String -> String
+wrapOpBackquotes s | isSym s   = s
+                  | otherwise = '`' : s ++ "`"
+
+isSym :: String -> Bool
+isSym ""     = False
+isSym (c:cs) = startsVarSym c || startsConSym c
+
+mk_showString_app str = nlHsApp (nlHsVar showString_RDR) (nlHsLit (mkHsString str))
 \end{code}
 
 \begin{code}
@@ -995,13 +972,6 @@ getPrecedence :: FixityEnv -> Name -> Integer
 getPrecedence get_fixity nm 
    = case lookupFixity get_fixity nm of
         Fixity x _ -> fromIntegral x
-
-isLRAssoc :: FixityEnv -> Name -> (Bool, Bool)
-isLRAssoc get_fixity nm =
-     case lookupFixity get_fixity nm of
-       Fixity _ InfixN -> (False, False)
-       Fixity _ InfixR -> (False, True)
-       Fixity _ InfixL -> (True,  False)
 \end{code}
 
 
@@ -1017,26 +987,30 @@ From the data type
 
 we generate
 
-       instance (Typeable a, Typeable b) => Typeable (T a b) where
-               typeOf _ = mkTypeRep (mkTyConRep "T")
-                                    [typeOf (undefined::a),
-                                     typeOf (undefined::b)]
+       instance Typeable2 T where
+               typeOf2 _ = mkTyConApp (mkTyConRep "T") []
 
-Notice the use of lexically scoped type variables.
+We are passed the Typeable2 class as well as T
 
 \begin{code}
-gen_Typeable_binds :: TyCon -> RdrNameMonoBinds
+gen_Typeable_binds :: TyCon -> LHsBinds RdrName
 gen_Typeable_binds tycon
-  = mk_easy_FunMonoBind tycon_loc typeOf_RDR [wildPat] []
-       (mkHsApps mkTypeRep_RDR [tycon_rep, arg_reps])
+  = unitBag $
+       mk_easy_FunBind tycon_loc 
+               (mk_typeOf_RDR tycon)   -- Name of appropriate type0f function
+               [nlWildPat] 
+               (nlHsApps mkTypeRep_RDR [tycon_rep, nlList []])
   where
-    tycon_loc = getSrcLoc tycon
-    tyvars    = tyConTyVars tycon
-    tycon_rep = HsVar mkTyConRep_RDR `HsApp` HsLit (mkHsString (showSDoc (ppr tycon)))
-    arg_reps  = ExplicitList placeHolderType (map mk tyvars)
-    mk tyvar  = HsApp (HsVar typeOf_RDR) 
-                     (ExprWithTySig (HsVar undefined_RDR)
-                                    (HsTyVar (getRdrName tyvar)))
+    tycon_loc = getSrcSpan tycon
+    tycon_rep = nlHsVar mkTyConRep_RDR `nlHsApp` nlHsLit (mkHsString (showSDoc (ppr tycon)))
+
+mk_typeOf_RDR :: TyCon -> RdrName
+-- Use the arity of the TyCon to make the right typeOfn function
+mk_typeOf_RDR tycon = varQual_RDR tYPEABLE (mkFastString ("typeOf" ++ suffix))
+               where
+                 arity = tyConArity tycon
+                 suffix | arity == 0 = ""
+                        | otherwise  = show arity
 \end{code}
 
 
@@ -1053,63 +1027,127 @@ From the data type
 
 we generate
 
-  instance (Data a, Data b) => Data (T a b) where
-       gfoldl k z (T1 a b) = z T `k` a `k` b
-       gfoldl k z T2       = z T2
-       -- ToDo: add gmapT,Q,M, gfoldr
-
-       gunfold k z _ (Constr "T1") = k (k (z T1))
-       gunfold k z _ (Constr "T2") = z T2
-       gunfold _ _ e _             = e
+  $cT1 = mkDataCon $dT "T1" Prefix
+  $cT2 = mkDataCon $dT "T2" Prefix
+  $dT  = mkDataType "Module.T" [] [$con_T1, $con_T2]
+  -- the [] is for field labels.
 
-       conOf (T1 _ _) = Constr "T1"
-       conOf T2       = Constr "T2"
-       
-       consOf _ = [Constr "T1", Constr "T2"]
-
-ToDo: generate auxiliary bindings for the Constrs?
+  instance (Data a, Data b) => Data (T a b) where
+    gfoldl k z (T1 a b) = z T `k` a `k` b
+    gfoldl k z T2          = z T2
+    -- ToDo: add gmapT,Q,M, gfoldr
+    gunfold k z c = case conIndex c of
+                       I# 1# -> k (k (z T1))
+                       I# 2# -> z T2
+
+    toConstr (T1 _ _) = $cT1
+    toConstr T2              = $cT2
+    
+    dataTypeOf _ = $dT
 
 \begin{code}
-gen_Data_binds :: TyCon -> RdrNameMonoBinds
-gen_Data_binds tycon
-  = andMonoBindList [gfoldl_bind, gunfold_bind, conOf_bind, consOf_bind]
+gen_Data_binds :: FixityEnv
+              -> TyCon 
+              -> (LHsBinds RdrName,    -- The method bindings
+                  LHsBinds RdrName)    -- Auxiliary bindings
+gen_Data_binds fix_env tycon
+  = (listToBag [gfoldl_bind, gunfold_bind, toCon_bind, dataTypeOf_bind],
+               -- Auxiliary definitions: the data type and constructors
+     datatype_bind `consBag` listToBag (map mk_con_bind data_cons))
   where
-    tycon_loc = getSrcLoc tycon
-    data_cons = tyConDataCons tycon
+    tycon_loc  = getSrcSpan tycon
+    tycon_name = tyConName tycon
+    data_cons  = tyConDataCons tycon
+    n_cons     = length data_cons
+    one_constr = n_cons == 1
 
        ------------ gfoldl
-    gfoldl_bind = mk_FunMonoBind tycon_loc gfoldl_RDR (map gfoldl_eqn data_cons)
-    gfoldl_eqn con = ([VarPat k_RDR, VarPat z_RDR, mkConPat con_name as_needed], 
-                      foldl mk_k_app (HsVar z_RDR `HsApp` HsVar con_name) as_needed)
+    gfoldl_bind = mk_FunBind tycon_loc gfoldl_RDR (map gfoldl_eqn data_cons)
+    gfoldl_eqn con = ([nlVarPat k_RDR, nlVarPat z_RDR, nlConVarPat con_name as_needed], 
+                      foldl mk_k_app (nlHsVar z_RDR `nlHsApp` nlHsVar con_name) as_needed)
                   where
-                    con_name :: RdrName
+                    con_name ::  RdrName
                     con_name = getRdrName con
                     as_needed = take (dataConSourceArity con) as_RDRs
-                    mk_k_app e v = HsPar (mkHsOpApp e k_RDR (HsVar v))
+                    mk_k_app e v = nlHsPar (nlHsOpApp e k_RDR (nlHsVar v))
 
        ------------ gunfold
-    gunfold_bind = mk_FunMonoBind tycon_loc gunfold_RDR (map gunfold_eqn data_cons ++ [catch_all])
-    gunfold_eqn con = ([VarPat k_RDR, VarPat z_RDR, wildPat, 
-                       ConPatIn constr_RDR (PrefixCon [LitPat (mk_constr_string con)])],
-                      apN (dataConSourceArity con)
-                          (\e -> HsVar k_RDR `HsApp` e) 
-                          (z_Expr `HsApp` HsVar (getRdrName con)))
-    catch_all = ([wildPat, wildPat, VarPat e_RDR, wildPat], HsVar e_RDR)
-    mk_constr_string con = mkHsString (occNameUserString (getOccName con))
-
-       ------------ conOf
-    conOf_bind = mk_FunMonoBind tycon_loc conOf_RDR (map conOf_eqn data_cons)
-    conOf_eqn con = ([mkWildConPat con], mk_constr con)
-
-       ------------ consOf
-    consOf_bind = mk_easy_FunMonoBind tycon_loc consOf_RDR [wildPat] []
-                               (ExplicitList placeHolderType (map mk_constr data_cons))
-    mk_constr con = HsVar constr_RDR `HsApp` (HsLit (mk_constr_string con))
-
-
-apN :: Int -> (a -> a) -> a -> a
-apN 0 k z = z
-apN n k z = apN (n-1) k (k z)
+    gunfold_bind = mk_FunBind tycon_loc
+                              gunfold_RDR
+                              [([k_Pat, z_Pat, if one_constr then nlWildPat else c_Pat], 
+                               gunfold_rhs)]
+
+    gunfold_rhs 
+       | one_constr = mk_unfold_rhs (head data_cons)   -- No need for case
+       | otherwise  = nlHsCase (nlHsVar conIndex_RDR `nlHsApp` c_Expr) 
+                               (map gunfold_alt data_cons)
+
+    gunfold_alt dc = mkSimpleHsAlt (mk_unfold_pat dc) (mk_unfold_rhs dc)
+    mk_unfold_rhs dc = foldr nlHsApp
+                           (nlHsVar z_RDR `nlHsApp` nlHsVar (getRdrName dc))
+                           (replicate (dataConSourceArity dc) (nlHsVar k_RDR))
+
+    mk_unfold_pat dc   -- Last one is a wild-pat, to avoid 
+                       -- redundant test, and annoying warning
+      | tag-fIRST_TAG == n_cons-1 = nlWildPat  -- Last constructor
+      | otherwise = nlConPat intDataCon_RDR [nlLitPat (HsIntPrim (toInteger tag))]
+      where 
+       tag = dataConTag dc
+                         
+       ------------ toConstr
+    toCon_bind = mk_FunBind tycon_loc toConstr_RDR (map to_con_eqn data_cons)
+    to_con_eqn dc = ([nlWildConPat dc], nlHsVar (mk_constr_name dc))
+    
+       ------------ dataTypeOf
+    dataTypeOf_bind = mk_easy_FunBind
+                        tycon_loc
+                        dataTypeOf_RDR
+                       [nlWildPat]
+                        (nlHsVar data_type_name)
+
+       ------------  $dT
+
+    data_type_name = mkDerivedRdrName tycon_name mkDataTOcc
+    datatype_bind  = mkVarBind
+                       tycon_loc
+                       data_type_name
+                      (           nlHsVar mkDataType_RDR 
+                         `nlHsApp` nlHsLit (mkHsString (showSDoc (ppr tycon)))
+                         `nlHsApp` nlList constrs
+                       )
+    constrs = [nlHsVar (mk_constr_name con) | con <- data_cons]
+
+
+       ------------  $cT1 etc
+    mk_constr_name con = mkDerivedRdrName (dataConName con) mkDataCOcc
+    mk_con_bind dc = mkVarBind
+                       tycon_loc
+                       (mk_constr_name dc) 
+                      (nlHsApps mkConstr_RDR (constr_args dc))
+    constr_args dc =
+        [ -- nlHsIntLit (toInteger (dataConTag dc)),           -- Tag
+          nlHsVar data_type_name,                              -- DataType
+          nlHsLit (mkHsString (occNameString dc_occ)), -- String name
+           nlList  labels,                                     -- Field labels
+          nlHsVar fixity]                                      -- Fixity
+       where
+          labels   = map (nlHsLit . mkHsString . getOccString)
+                         (dataConFieldLabels dc)
+         dc_occ   = getOccName dc
+         is_infix = isDataSymOcc dc_occ
+         fixity | is_infix  = infix_RDR
+                | otherwise = prefix_RDR
+
+gfoldl_RDR     = varQual_RDR gENERICS FSLIT("gfoldl")
+gunfold_RDR    = varQual_RDR gENERICS FSLIT("gunfold")
+toConstr_RDR   = varQual_RDR gENERICS FSLIT("toConstr")
+dataTypeOf_RDR = varQual_RDR gENERICS FSLIT("dataTypeOf")
+mkConstr_RDR   = varQual_RDR gENERICS FSLIT("mkConstr")
+mkDataType_RDR = varQual_RDR gENERICS FSLIT("mkDataType")
+conIndex_RDR   = varQual_RDR gENERICS FSLIT("constrIndex")
+prefix_RDR     = dataQual_RDR gENERICS FSLIT("Prefix")
+infix_RDR      = dataQual_RDR gENERICS FSLIT("Infix")
 \end{code}
 
 %************************************************************************
@@ -1134,51 +1172,53 @@ data TagThingWanted
   = GenCon2Tag | GenTag2Con | GenMaxTag
 
 gen_tag_n_con_monobind
-    :: (RdrName,           -- (proto)Name for the thing in question
+    :: ( RdrName,          -- (proto)Name for the thing in question
        TyCon,              -- tycon in question
        TagThingWanted)
-    -> RdrNameMonoBinds
+    -> LHsBind RdrName
 
 gen_tag_n_con_monobind (rdr_name, tycon, GenCon2Tag)
   | lots_of_constructors
-  = mk_FunMonoBind loc rdr_name [([], get_tag_rhs)]
+  = mk_FunBind tycon_loc rdr_name [([], get_tag_rhs)]
 
   | otherwise
-  = mk_FunMonoBind loc rdr_name (map mk_stuff (tyConDataCons tycon))
+  = mk_FunBind tycon_loc rdr_name (map mk_stuff (tyConDataCons tycon))
 
   where
-    loc = getSrcLoc tycon
+    tycon_loc = getSrcSpan tycon
+
+    tvs = map (mkRdrUnqual . getOccName) (tyConTyVars tycon)
+       -- We can't use gerRdrName because that makes an Exact  RdrName
+       -- and we can't put them in the LocalRdrEnv
 
        -- Give a signature to the bound variable, so 
        -- that the case expression generated by getTag is
        -- monomorphic.  In the push-enter model we get better code.
-    get_tag_rhs = ExprWithTySig 
-                       (HsLam (mk_match loc [VarPat a_RDR] 
-                                            (HsApp getTag_Expr a_Expr) 
-                                            EmptyBinds))
-                       (HsForAllTy Nothing [] con2tag_ty)
-                               -- Nothing => implicit quantification
-
-    con2tag_ty = foldl HsAppTy (HsTyVar (getRdrName tycon)) 
-                    [HsTyVar (getRdrName tv) | tv <- tyConTyVars tycon]
-               `HsFunTy` 
-               HsTyVar (getRdrName intPrimTyConName)
+    get_tag_rhs = noLoc $ ExprWithTySig 
+                       (nlHsLam (mkSimpleHsAlt (nlVarPat a_RDR) 
+                                             (nlHsApp (nlHsVar getTag_RDR) a_Expr)))
+                       (noLoc (mkExplicitHsForAllTy (map (noLoc.UserTyVar) tvs) (noLoc []) con2tag_ty))
+
+    con2tag_ty = foldl nlHsAppTy (nlHsTyVar (getRdrName tycon)) 
+                      (map nlHsTyVar tvs)
+               `nlHsFunTy` 
+               nlHsTyVar (getRdrName intPrimTyCon)
 
     lots_of_constructors = tyConFamilySize tycon > mAX_FAMILY_SIZE_FOR_VEC_RETURNS
 
-    mk_stuff :: DataCon -> ([RdrNamePat], RdrNameHsExpr)
-    mk_stuff con = ([mkWildConPat con], 
-                   HsLit (HsIntPrim (toInteger ((dataConTag con) - fIRST_TAG))))
+    mk_stuff :: DataCon -> ([LPat RdrName], LHsExpr RdrName)
+    mk_stuff con = ([nlWildConPat con], 
+                   nlHsLit (HsIntPrim (toInteger ((dataConTag con) - fIRST_TAG))))
 
 gen_tag_n_con_monobind (rdr_name, tycon, GenTag2Con)
-  = mk_FunMonoBind (getSrcLoc tycon) rdr_name 
-       [([mkConPat mkInt_RDR [a_RDR]], 
-          ExprWithTySig (HsApp tagToEnum_Expr a_Expr) 
-                        (HsTyVar (getRdrName tycon)))]
+  = mk_FunBind (getSrcSpan tycon) rdr_name 
+       [([nlConVarPat intDataCon_RDR [a_RDR]], 
+          noLoc (ExprWithTySig (nlHsApp (nlHsVar tagToEnum_RDR) a_Expr) 
+                        (nlHsTyVar (getRdrName tycon))))]
 
 gen_tag_n_con_monobind (rdr_name, tycon, GenMaxTag)
-  = mkVarMonoBind (getSrcLoc tycon) rdr_name 
-                 (HsApp (HsVar mkInt_RDR) (HsLit (HsIntPrim max_tag)))
+  = mkVarBind (getSrcSpan tycon) rdr_name 
+                 (nlHsApp (nlHsVar intDataCon_RDR) (nlHsLit (HsIntPrim max_tag)))
   where
     max_tag =  case (tyConDataCons tycon) of
                 data_cons -> toInteger ((length data_cons) - fIRST_TAG)
@@ -1191,298 +1231,250 @@ gen_tag_n_con_monobind (rdr_name, tycon, GenMaxTag)
 %*                                                                     *
 %************************************************************************
 
-@mk_easy_FunMonoBind fun pats binds expr@ generates:
-\begin{verbatim}
-    fun pat1 pat2 ... patN = expr where binds
-\end{verbatim}
-
-@mk_FunMonoBind fun [([p1a, p1b, ...], e1), ...]@ is for
-multi-clause definitions; it generates:
-\begin{verbatim}
-    fun p1a p1b ... p1N = e1
-    fun p2a p2b ... p2N = e2
-    ...
-    fun pMa pMb ... pMN = eM
-\end{verbatim}
-
-\begin{code}
-mkVarMonoBind :: SrcLoc -> RdrName -> RdrNameHsExpr -> RdrNameMonoBinds
-mkVarMonoBind loc var rhs = mk_easy_FunMonoBind loc var [] [] rhs
-
-mk_easy_FunMonoBind :: SrcLoc -> RdrName -> [RdrNamePat]
-                   -> [RdrNameMonoBinds] -> RdrNameHsExpr
-                   -> RdrNameMonoBinds
-
-mk_easy_FunMonoBind loc fun pats binds expr
-  = FunMonoBind fun False{-not infix-} [mk_easy_Match loc pats binds expr] loc
-
-mk_easy_Match loc pats binds expr
-  = mk_match loc pats expr (mkMonoBind Recursive (andMonoBindList binds))
-       -- The renamer expects everything in its input to be a
-       -- "recursive" MonoBinds, and it is its job to sort things out
-       -- from there.
-
-mk_FunMonoBind :: SrcLoc -> RdrName
-               -> [([RdrNamePat], RdrNameHsExpr)]
-               -> RdrNameMonoBinds
-
-mk_FunMonoBind loc fun [] = panic "TcGenDeriv:mk_FunMonoBind"
-mk_FunMonoBind loc fun pats_and_exprs
-  = FunMonoBind fun False{-not infix-}
-               [ mk_match loc p e EmptyBinds | (p,e) <-pats_and_exprs ]
-               loc
-
-mk_match loc pats expr binds
-  = Match (map paren pats) Nothing 
-         (GRHSs (unguardedRHS expr loc) binds placeHolderType)
-  where
-    paren p@(VarPat _) = p
-    paren other_p      = ParPat other_p
-\end{code}
-
-\begin{code}
-mkHsApps    f xs = foldl HsApp (HsVar f) xs
-mkHsVarApps f xs = foldl HsApp (HsVar f) (map HsVar xs)
-
-mkHsIntLit n = HsLit (HsInt n)
-mkHsString s = HsString (mkFastString s)
-mkHsChar c   = HsChar   (ord c)
-
-mkConPat con vars   = ConPatIn con (PrefixCon (map VarPat vars))
-mkNullaryConPat con = ConPatIn con (PrefixCon [])
-mkWildConPat con    = ConPatIn (getRdrName con) (PrefixCon (nOfThem (dataConSourceArity con) wildPat))
-\end{code}
 
 ToDo: Better SrcLocs.
 
 \begin{code}
 compare_gen_Case ::
-         RdrNameHsExpr -- What to do for equality
-         -> RdrNameHsExpr -> RdrNameHsExpr
-         -> RdrNameHsExpr
+         LHsExpr RdrName       -- What to do for equality
+         -> LHsExpr RdrName -> LHsExpr RdrName
+         -> LHsExpr RdrName
 careful_compare_Case :: -- checks for primitive types...
-         Type
-         -> RdrNameHsExpr      -- What to do for equality
-         -> RdrNameHsExpr -> RdrNameHsExpr
-         -> RdrNameHsExpr
+         TyCon                 -- The tycon we are deriving for
+         -> Type
+         -> LHsExpr RdrName    -- What to do for equality
+         -> LHsExpr RdrName -> LHsExpr RdrName
+         -> LHsExpr RdrName
 
-cmp_eq_Expr a b = HsApp (HsApp (HsVar cmp_eq_RDR) a) b
+cmp_eq_Expr a b = nlHsApp (nlHsApp (nlHsVar cmp_eq_RDR) a) b
        -- Was: compare_gen_Case cmp_eq_RDR
 
-compare_gen_Case (HsVar eq_tag) a b | eq_tag == eqTag_RDR
-  = HsApp (HsApp (HsVar compare_RDR) a) b      -- Simple case 
+compare_gen_Case (L _ (HsVar eq_tag)) a b | eq_tag == eqTag_RDR
+  = nlHsApp (nlHsApp (nlHsVar compare_RDR) a) b        -- Simple case 
 compare_gen_Case eq a b                                -- General case
-  = HsCase (HsPar (HsApp (HsApp (HsVar compare_RDR) a) b)) {-of-}
-      [mkSimpleMatch [mkNullaryConPat ltTag_RDR] ltTag_Expr placeHolderType generatedSrcLoc,
-       mkSimpleMatch [mkNullaryConPat eqTag_RDR] eq placeHolderType generatedSrcLoc,
-       mkSimpleMatch [mkNullaryConPat gtTag_RDR] gtTag_Expr placeHolderType generatedSrcLoc]
-      generatedSrcLoc
-
-careful_compare_Case ty eq a b
-  | not (isUnLiftedType ty) =
-       compare_gen_Case eq a b
-  | otherwise               =
-         -- we have to do something special for primitive things...
-       HsIf (genOpApp a relevant_eq_op b)
-           eq
-           (HsIf (genOpApp a relevant_lt_op b) ltTag_Expr gtTag_Expr generatedSrcLoc)
-           generatedSrcLoc
+  = nlHsCase (nlHsPar (nlHsApp (nlHsApp (nlHsVar compare_RDR) a) b)) {-of-}
+      [mkSimpleHsAlt (nlNullaryConPat ltTag_RDR) ltTag_Expr,
+       mkSimpleHsAlt (nlNullaryConPat eqTag_RDR) eq,
+       mkSimpleHsAlt (nlNullaryConPat gtTag_RDR) gtTag_Expr]
+
+careful_compare_Case tycon ty eq a b
+  | not (isUnLiftedType ty)
+  = compare_gen_Case eq a b
+  | otherwise      -- We have to do something special for primitive things...
+  = nlHsIf (genOpApp a relevant_eq_op b)
+        eq
+        (nlHsIf (genOpApp a relevant_lt_op b) ltTag_Expr gtTag_Expr)
   where
-    relevant_eq_op = assoc_ty_id eq_op_tbl ty
-    relevant_lt_op = assoc_ty_id lt_op_tbl ty
-
-assoc_ty_id tyids ty 
-  = if null res then panic "assoc_ty"
-    else head res
+    relevant_eq_op = primOpRdrName (assoc_ty_id "Ord" tycon eq_op_tbl ty)
+    relevant_lt_op = primOpRdrName (assoc_ty_id "Ord" tycon lt_op_tbl ty)
+
+
+box_if_necy :: String          -- The class involved
+           -> TyCon            -- The tycon involved
+           -> LHsExpr RdrName  -- The argument
+           -> Type             -- The argument type
+           -> LHsExpr RdrName  -- Boxed version of the arg
+box_if_necy cls_str tycon arg arg_ty
+  | isUnLiftedType arg_ty = nlHsApp (nlHsVar box_con) arg
+  | otherwise            = arg
+  where
+    box_con = assoc_ty_id cls_str tycon box_con_tbl arg_ty
+
+assoc_ty_id :: String          -- The class involved
+           -> TyCon            -- The tycon involved
+           -> [(Type,a)]       -- The table
+           -> Type             -- The type
+           -> a                -- The result of the lookup
+assoc_ty_id cls_str tycon tbl ty 
+  | null res = pprPanic "Error in deriving:" (text "Can't derive" <+> text cls_str <+> 
+                                             text "for primitive type" <+> ppr ty)
+  | otherwise = head res
   where
-    res = [id | (ty',id) <- tyids, ty `tcEqType` ty']
+    res = [id | (ty',id) <- tbl, ty `tcEqType` ty']
 
+eq_op_tbl :: [(Type, PrimOp)]
 eq_op_tbl =
-    [(charPrimTy,      eqChar_RDR)
-    ,(intPrimTy,       eqInt_RDR)
-    ,(wordPrimTy,      eqWord_RDR)
-    ,(addrPrimTy,      eqAddr_RDR)
-    ,(floatPrimTy,     eqFloat_RDR)
-    ,(doublePrimTy,    eqDouble_RDR)
+    [(charPrimTy,      CharEqOp)
+    ,(intPrimTy,       IntEqOp)
+    ,(wordPrimTy,      WordEqOp)
+    ,(addrPrimTy,      AddrEqOp)
+    ,(floatPrimTy,     FloatEqOp)
+    ,(doublePrimTy,    DoubleEqOp)
     ]
 
+lt_op_tbl :: [(Type, PrimOp)]
 lt_op_tbl =
-    [(charPrimTy,      ltChar_RDR)
-    ,(intPrimTy,       ltInt_RDR)
-    ,(wordPrimTy,      ltWord_RDR)
-    ,(addrPrimTy,      ltAddr_RDR)
-    ,(floatPrimTy,     ltFloat_RDR)
-    ,(doublePrimTy,    ltDouble_RDR)
+    [(charPrimTy,      CharLtOp)
+    ,(intPrimTy,       IntLtOp)
+    ,(wordPrimTy,      WordLtOp)
+    ,(addrPrimTy,      AddrLtOp)
+    ,(floatPrimTy,     FloatLtOp)
+    ,(doublePrimTy,    DoubleLtOp)
     ]
 
------------------------------------------------------------------------
+box_con_tbl =
+    [(charPrimTy,      getRdrName charDataCon)
+    ,(intPrimTy,       getRdrName intDataCon)
+    ,(wordPrimTy,      wordDataCon_RDR)
+    ,(addrPrimTy,      addrDataCon_RDR)
+    ,(floatPrimTy,     getRdrName floatDataCon)
+    ,(doublePrimTy,    getRdrName doubleDataCon)
+    ]
 
-and_Expr, append_Expr :: RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
+-----------------------------------------------------------------------
 
-and_Expr    a b = genOpApp a and_RDR    b
-append_Expr a b = genOpApp a append_RDR b
+and_Expr :: LHsExpr RdrName -> LHsExpr RdrName -> LHsExpr RdrName
+and_Expr a b = genOpApp a and_RDR    b
 
 -----------------------------------------------------------------------
 
-eq_Expr :: Type -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
-eq_Expr ty a b = genOpApp a eq_op b
+eq_Expr :: TyCon -> Type -> LHsExpr RdrName -> LHsExpr RdrName -> LHsExpr RdrName
+eq_Expr tycon ty a b = genOpApp a eq_op b
  where
    eq_op
     | not (isUnLiftedType ty) = eq_RDR
-    | otherwise               =
+    | otherwise               = primOpRdrName (assoc_ty_id "Eq" tycon eq_op_tbl ty)
          -- we have to do something special for primitive things...
-       assoc_ty_id eq_op_tbl ty
-
 \end{code}
 
 \begin{code}
-untag_Expr :: TyCon -> [(RdrName, RdrName)] -> RdrNameHsExpr -> RdrNameHsExpr
+untag_Expr :: TyCon -> [( RdrName,  RdrName)] -> LHsExpr RdrName -> LHsExpr RdrName
 untag_Expr tycon [] expr = expr
 untag_Expr tycon ((untag_this, put_tag_here) : more) expr
-  = HsCase (HsPar (HsApp (con2tag_Expr tycon) (HsVar untag_this))) {-of-}
-      [mkSimpleMatch [VarPat put_tag_here] (untag_Expr tycon more expr) placeHolderType generatedSrcLoc]
-      generatedSrcLoc
+  = nlHsCase (nlHsPar (nlHsVarApps (con2tag_RDR tycon) [untag_this])) {-of-}
+      [mkSimpleHsAlt (nlVarPat put_tag_here) (untag_Expr tycon more expr)]
 
-cmp_tags_Expr :: RdrName               -- Comparison op
-            -> RdrName -> RdrName      -- Things to compare
-            -> RdrNameHsExpr           -- What to return if true
-            -> RdrNameHsExpr           -- What to return if false
-            -> RdrNameHsExpr
+cmp_tags_Expr ::  RdrName              -- Comparison op
+            ->  RdrName ->  RdrName    -- Things to compare
+            -> LHsExpr RdrName                 -- What to return if true
+            -> LHsExpr RdrName         -- What to return if false
+            -> LHsExpr RdrName
 
 cmp_tags_Expr op a b true_case false_case
-  = HsIf (genOpApp (HsVar a) op (HsVar b)) true_case false_case generatedSrcLoc
+  = nlHsIf (genOpApp (nlHsVar a) op (nlHsVar b)) true_case false_case
 
 enum_from_to_Expr
-       :: RdrNameHsExpr -> RdrNameHsExpr
-       -> RdrNameHsExpr
+       :: LHsExpr RdrName -> LHsExpr RdrName
+       -> LHsExpr RdrName
 enum_from_then_to_Expr
-       :: RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
-       -> RdrNameHsExpr
+       :: LHsExpr RdrName -> LHsExpr RdrName -> LHsExpr RdrName
+       -> LHsExpr RdrName
 
-enum_from_to_Expr      f   t2 = HsApp (HsApp (HsVar enumFromTo_RDR) f) t2
-enum_from_then_to_Expr f t t2 = HsApp (HsApp (HsApp (HsVar enumFromThenTo_RDR) f) t) t2
+enum_from_to_Expr      f   t2 = nlHsApp (nlHsApp (nlHsVar enumFromTo_RDR) f) t2
+enum_from_then_to_Expr f t t2 = nlHsApp (nlHsApp (nlHsApp (nlHsVar enumFromThenTo_RDR) f) t) t2
 
 showParen_Expr
-       :: RdrNameHsExpr -> RdrNameHsExpr
-       -> RdrNameHsExpr
+       :: LHsExpr RdrName -> LHsExpr RdrName
+       -> LHsExpr RdrName
 
-showParen_Expr e1 e2 = HsApp (HsApp (HsVar showParen_RDR) e1) e2
+showParen_Expr e1 e2 = nlHsApp (nlHsApp (nlHsVar showParen_RDR) e1) e2
 
-nested_compose_Expr :: [RdrNameHsExpr] -> RdrNameHsExpr
+nested_compose_Expr :: [LHsExpr RdrName] -> LHsExpr RdrName
 
 nested_compose_Expr [e] = parenify e
 nested_compose_Expr (e:es)
-  = HsApp (HsApp (HsVar compose_RDR) (parenify e)) (nested_compose_Expr es)
+  = nlHsApp (nlHsApp (nlHsVar compose_RDR) (parenify e)) (nested_compose_Expr es)
 
 -- impossible_Expr is used in case RHSs that should never happen.
 -- We generate these to keep the desugarer from complaining that they *might* happen!
-impossible_Expr = HsApp (HsVar error_RDR) (HsLit (HsString (mkFastString "Urk! in TcGenDeriv")))
+impossible_Expr = nlHsApp (nlHsVar error_RDR) (nlHsLit (mkHsString "Urk! in TcGenDeriv"))
 
 -- illegal_Expr is used when signalling error conditions in the RHS of a derived
 -- method. It is currently only used by Enum.{succ,pred}
 illegal_Expr meth tp msg = 
-   HsApp (HsVar error_RDR) (HsLit (HsString (mkFastString (meth ++ '{':tp ++ "}: " ++ msg))))
+   nlHsApp (nlHsVar error_RDR) (nlHsLit (mkHsString (meth ++ '{':tp ++ "}: " ++ msg)))
 
 -- illegal_toEnum_tag is an extended version of illegal_Expr, which also allows you
 -- to include the value of a_RDR in the error string.
 illegal_toEnum_tag tp maxtag =
-   HsApp (HsVar error_RDR) 
-         (HsApp (HsApp (HsVar append_RDR)
-                      (HsLit (HsString (mkFastString ("toEnum{" ++ tp ++ "}: tag (")))))
-                      (HsApp (HsApp (HsApp 
-                          (HsVar showsPrec_RDR)
-                          (mkHsIntLit 0))
-                          (HsVar a_RDR))
-                          (HsApp (HsApp 
-                              (HsVar append_RDR)
-                              (HsLit (HsString (mkFastString ") is outside of enumeration's range (0,"))))
-                              (HsApp (HsApp (HsApp 
-                                       (HsVar showsPrec_RDR)
-                                       (mkHsIntLit 0))
-                                       (HsVar maxtag))
-                                       (HsLit (HsString (mkFastString ")")))))))
-
-parenify e@(HsVar _) = e
-parenify e          = HsPar e
+   nlHsApp (nlHsVar error_RDR) 
+           (nlHsApp (nlHsApp (nlHsVar append_RDR)
+                      (nlHsLit (mkHsString ("toEnum{" ++ tp ++ "}: tag ("))))
+                   (nlHsApp (nlHsApp (nlHsApp 
+                          (nlHsVar showsPrec_RDR)
+                          (nlHsIntLit 0))
+                          (nlHsVar a_RDR))
+                          (nlHsApp (nlHsApp 
+                              (nlHsVar append_RDR)
+                              (nlHsLit (mkHsString ") is outside of enumeration's range (0,")))
+                              (nlHsApp (nlHsApp (nlHsApp 
+                                       (nlHsVar showsPrec_RDR)
+                                       (nlHsIntLit 0))
+                                       (nlHsVar maxtag))
+                                       (nlHsLit (mkHsString ")"))))))
+
+parenify e@(L _ (HsVar _)) = e
+parenify e                = mkHsPar e
 
 -- genOpApp wraps brackets round the operator application, so that the
 -- renamer won't subsequently try to re-associate it. 
--- For some reason the renamer doesn't reassociate it right, and I can't
--- be bothered to find out why just now.
+genOpApp e1 op e2 = nlHsPar (nlHsOpApp e1 op e2)
+\end{code}
 
-genOpApp e1 op e2 = mkHsOpApp e1 op e2
+\begin{code}
+getSrcSpan = srcLocSpan . getSrcLoc
 \end{code}
 
 \begin{code}
-varUnqual n     = mkUnqual OccName.varName n
-
-zz_a_RDR       = varUnqual FSLIT("_a")
-a_RDR          = varUnqual FSLIT("a")
-b_RDR          = varUnqual FSLIT("b")
-c_RDR          = varUnqual FSLIT("c")
-d_RDR          = varUnqual FSLIT("d")
-e_RDR          = varUnqual FSLIT("e")
-k_RDR          = varUnqual FSLIT("k")
-z_RDR          = varUnqual FSLIT("z") :: RdrName
-ah_RDR         = varUnqual FSLIT("a#")
-bh_RDR         = varUnqual FSLIT("b#")
-ch_RDR         = varUnqual FSLIT("c#")
-dh_RDR         = varUnqual FSLIT("d#")
-cmp_eq_RDR     = varUnqual FSLIT("cmp_eq")
-rangeSize_RDR  = varUnqual FSLIT("rangeSize")
-
-as_RDRs                = [ varUnqual (mkFastString ("a"++show i)) | i <- [(1::Int) .. ] ]
-bs_RDRs                = [ varUnqual (mkFastString ("b"++show i)) | i <- [(1::Int) .. ] ]
-cs_RDRs                = [ varUnqual (mkFastString ("c"++show i)) | i <- [(1::Int) .. ] ]
-
-zz_a_Expr      = HsVar zz_a_RDR
-a_Expr         = HsVar a_RDR
-b_Expr         = HsVar b_RDR
-c_Expr         = HsVar c_RDR
-d_Expr         = HsVar d_RDR
-z_Expr         = HsVar z_RDR
-ltTag_Expr     = HsVar ltTag_RDR
-eqTag_Expr     = HsVar eqTag_RDR
-gtTag_Expr     = HsVar gtTag_RDR
-false_Expr     = HsVar false_RDR
-true_Expr      = HsVar true_RDR
-
-getTag_Expr    = HsVar getTag_RDR
-tagToEnum_Expr         = HsVar tagToEnum_RDR
-con2tag_Expr tycon = HsVar (con2tag_RDR tycon)
-
-wildPat                = WildPat placeHolderType
-zz_a_Pat       = VarPat zz_a_RDR
-a_Pat          = VarPat a_RDR
-b_Pat          = VarPat b_RDR
-c_Pat          = VarPat c_RDR
-d_Pat          = VarPat d_RDR
-
-con2tag_RDR, tag2con_RDR, maxtag_RDR :: TyCon -> RdrName
-
-con2tag_RDR tycon = varUnqual (mkFastString ("con2tag_" ++ occNameString (getOccName tycon) ++ "#"))
-tag2con_RDR tycon = varUnqual (mkFastString ("tag2con_" ++ occNameString (getOccName tycon) ++ "#"))
-maxtag_RDR tycon  = varUnqual (mkFastString ("maxtag_"  ++ occNameString (getOccName tycon) ++ "#"))
+a_RDR          = mkVarUnqual FSLIT("a")
+b_RDR          = mkVarUnqual FSLIT("b")
+c_RDR          = mkVarUnqual FSLIT("c")
+d_RDR          = mkVarUnqual FSLIT("d")
+k_RDR          = mkVarUnqual FSLIT("k")
+z_RDR          = mkVarUnqual FSLIT("z")
+ah_RDR         = mkVarUnqual FSLIT("a#")
+bh_RDR         = mkVarUnqual FSLIT("b#")
+ch_RDR         = mkVarUnqual FSLIT("c#")
+dh_RDR         = mkVarUnqual FSLIT("d#")
+cmp_eq_RDR     = mkVarUnqual FSLIT("cmp_eq")
+
+as_RDRs                = [ mkVarUnqual (mkFastString ("a"++show i)) | i <- [(1::Int) .. ] ]
+bs_RDRs                = [ mkVarUnqual (mkFastString ("b"++show i)) | i <- [(1::Int) .. ] ]
+cs_RDRs                = [ mkVarUnqual (mkFastString ("c"++show i)) | i <- [(1::Int) .. ] ]
+
+a_Expr         = nlHsVar a_RDR
+b_Expr         = nlHsVar b_RDR
+c_Expr         = nlHsVar c_RDR
+ltTag_Expr     = nlHsVar ltTag_RDR
+eqTag_Expr     = nlHsVar eqTag_RDR
+gtTag_Expr     = nlHsVar gtTag_RDR
+false_Expr     = nlHsVar false_RDR
+true_Expr      = nlHsVar true_RDR
+
+a_Pat          = nlVarPat a_RDR
+b_Pat          = nlVarPat b_RDR
+c_Pat          = nlVarPat c_RDR
+d_Pat          = nlVarPat d_RDR
+k_Pat          = nlVarPat k_RDR
+z_Pat          = nlVarPat z_RDR
+
+con2tag_RDR, tag2con_RDR, maxtag_RDR :: TyCon ->  RdrName
+-- Generates Orig s RdrName, for the binding positions
+con2tag_RDR tycon = mk_tc_deriv_name tycon "con2tag_"
+tag2con_RDR tycon = mk_tc_deriv_name tycon "tag2con_"
+maxtag_RDR  tycon = mk_tc_deriv_name tycon "maxtag_"
+
+mk_tc_deriv_name tycon str 
+  = mkDerivedRdrName tc_name mk_occ
+  where
+    tc_name = tyConName tycon
+    mk_occ tc_occ = mkVarOccFS (mkFastString new_str)
+                 where
+                   new_str = str ++ occNameString tc_occ ++ "#"
 \end{code}
 
-RdrNames for PrimOps.  Can't be done in PrelNames, because PrimOp imports
+s RdrName for PrimOps.  Can't be done in PrelNames, because PrimOp imports
 PrelNames, so PrelNames can't import PrimOp.
 
 \begin{code}
-minusInt_RDR  = nameRdrName minusIntName
-eqInt_RDR     = nameRdrName eqIntName
-ltInt_RDR     = nameRdrName ltIntName
-geInt_RDR     = nameRdrName geIntName
-leInt_RDR     = nameRdrName leIntName
-eqChar_RDR    = nameRdrName eqCharName
-eqWord_RDR    = nameRdrName eqWordName
-eqAddr_RDR    = nameRdrName eqAddrName
-eqFloat_RDR   = nameRdrName eqFloatName
-eqDouble_RDR  = nameRdrName eqDoubleName
-ltChar_RDR    = nameRdrName ltCharName
-ltWord_RDR    = nameRdrName ltWordName
-ltAddr_RDR    = nameRdrName ltAddrName
-ltFloat_RDR   = nameRdrName ltFloatName
-ltDouble_RDR  = nameRdrName ltDoubleName
-tagToEnum_RDR = nameRdrName tagToEnumName                   
+primOpRdrName op = getRdrName (primOpId op)
+
+minusInt_RDR  = primOpRdrName IntSubOp
+eqInt_RDR     = primOpRdrName IntEqOp
+ltInt_RDR     = primOpRdrName IntLtOp
+geInt_RDR     = primOpRdrName IntGeOp
+leInt_RDR     = primOpRdrName IntLeOp
+tagToEnum_RDR = primOpRdrName TagToEnumOp
+
+error_RDR = getRdrName eRROR_ID
 \end{code}