[project @ 2002-10-23 02:36:37 by chak]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcGenDeriv.lhs
index 0f74003..a4b286f 100644 (file)
@@ -26,30 +26,32 @@ module TcGenDeriv (
 
 #include "HsVersions.h"
 
-import HsSyn           ( InPat(..), HsExpr(..), MonoBinds(..),
+import HsSyn           ( Pat(..), HsConDetails(..), HsExpr(..), MonoBinds(..),
                          Match(..), GRHSs(..), Stmt(..), HsLit(..),
-                         HsBinds(..), HsType(..), HsDoContext(..),
+                         HsBinds(..), HsType(..), HsStmtContext(..),
                          unguardedRHS, mkSimpleMatch, mkMonoBind, andMonoBindList, placeHolderType
                        )
-import RdrHsSyn                ( mkHsOpApp, RdrNameMonoBinds, RdrNameHsExpr, RdrNamePat )
-import RdrName         ( RdrName, mkUnqual )
+import PrelNames       ( )
+import RdrName         ( RdrName, mkUnqual, nameRdrName, getRdrName )
+import RdrHsSyn                ( mkHsOpApp, RdrNameMonoBinds, RdrNameHsExpr, RdrNamePat, mkHsDo )
 import BasicTypes      ( RecFlag(..), Fixity(..), FixityDirection(..)
                        , maxPrecedence
                        , Boxity(..)
                        )
-import FieldLabel       ( FieldLabel, fieldLabelName )
+import FieldLabel       ( fieldLabelName )
 import DataCon         ( isNullaryDataCon, dataConTag,
                          dataConOrigArgTys, dataConSourceArity, fIRST_TAG,
                          DataCon, 
                          dataConFieldLabels )
 import Name            ( getOccString, getOccName, getSrcLoc, occNameString, 
-                         occNameUserString, nameRdrName, varName,
+                         occNameUserString, varName,
                          Name, NamedThing(..), 
                          isDataSymOcc, isSymOcc
                        )
 
 import HscTypes                ( FixityEnv, lookupFixity )
-import PrelInfo                -- Lots of RdrNames
+import PrelNames       -- Lots of Names
+import PrimOp          -- Lots of Names
 import SrcLoc          ( generatedSrcLoc, SrcLoc )
 import TyCon           ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon,
                          maybeTyConSingleCon, tyConFamilySize
@@ -58,14 +60,14 @@ import TcType               ( isUnLiftedType, tcEqType, Type )
 import TysPrim         ( charPrimTy, intPrimTy, wordPrimTy, addrPrimTy,
                          floatPrimTy, doublePrimTy
                        )
-import Util            ( mapAccumL, zipEqual, zipWithEqual, isSingleton,
-                         zipWith3Equal, nOfThem )
+import Util            ( zipWithEqual, isSingleton,
+                         zipWith3Equal, nOfThem, zipEqual )
 import Panic           ( panic, assertPanic )
-import Maybes          ( maybeToBool )
-import Char            ( ord )
+import Char            ( ord, isAlpha )
 import Constants
 import List            ( partition, intersperse )
 import FastString
+import OccName
 \end{code}
 
 %************************************************************************
@@ -183,7 +185,7 @@ gen_Eq_binds tycon
            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) eqH_Int_RDR (HsVar bh_RDR)))]
+                              (genOpApp (HsVar ah_RDR) eqInt_RDR (HsVar bh_RDR)))]
     in
     mk_FunMonoBind tycon_loc eq_RDR ((map pats_etc nonnullary_cons) ++ rest)
            `AndMonoBinds`
@@ -193,10 +195,10 @@ gen_Eq_binds tycon
     ------------------------------------------------------------------
     pats_etc data_con
       = let
-           con1_pat = ConPatIn data_con_RDR (map VarPatIn as_needed)
-           con2_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
+           con1_pat = mkConPat data_con_RDR as_needed
+           con2_pat = mkConPat data_con_RDR bs_needed
 
-           data_con_RDR = qual_orig_name data_con
+           data_con_RDR = getRdrName data_con
            con_arity   = length tys_needed
            as_needed   = take con_arity as_RDRs
            bs_needed   = take con_arity bs_RDRs
@@ -317,75 +319,59 @@ gen_Ord_binds tycon
     tycon_loc = getSrcLoc tycon
     --------------------------------------------------------------------
     compare = mk_easy_FunMonoBind tycon_loc compare_RDR
-               [a_Pat, b_Pat]
-               [cmp_eq]
-           (if maybeToBool (maybeTyConSingleCon tycon) then
-
---             cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
--- Weird.  Was: case (cmp a b) of { LT -> LT; EQ -> EQ; GT -> GT }
-
-               cmp_eq_Expr a_Expr b_Expr
-            else
-               untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)]
-                 (cmp_tags_Expr eqH_Int_RDR ah_RDR bh_RDR
-                       -- True case; they are equal
-                       -- If an enumeration type we are done; else
-                       -- recursively compare their components
-                   (if isEnumerationTyCon tycon then
-                       eqTag_Expr
-                    else
---                     cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
--- Ditto
-                       cmp_eq_Expr a_Expr b_Expr
-                   )
+                                 [a_Pat, b_Pat] [cmp_eq] compare_rhs
+    compare_rhs
+       | single_con_type = cmp_eq_Expr a_Expr b_Expr
+       | otherwise
+       = untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)]
+                 (cmp_tags_Expr eqInt_RDR ah_RDR bh_RDR
+                       (cmp_eq_Expr a_Expr b_Expr)     -- True case
                        -- False case; they aren't equal
                        -- So we need to do a less-than comparison on the tags
-                   (cmp_tags_Expr ltH_Int_RDR ah_RDR bh_RDR ltTag_Expr gtTag_Expr)))
+                       (cmp_tags_Expr ltInt_RDR ah_RDR bh_RDR ltTag_Expr gtTag_Expr))
 
     tycon_data_cons = tyConDataCons tycon
+    single_con_type = isSingleton tycon_data_cons
     (nullary_cons, nonnullary_cons)
        | isNewTyCon tycon = ([], tyConDataCons tycon)
        | otherwise       = partition isNullaryDataCon tycon_data_cons
 
-    cmp_eq =
-       mk_FunMonoBind tycon_loc 
-                      cmp_eq_RDR 
-                      (if null nonnullary_cons && isSingleton nullary_cons then
-                          -- catch this specially to avoid warnings
-                          -- about overlapping patterns from the desugarer.
-                         let 
-                          data_con     = head nullary_cons
-                          data_con_RDR = qual_orig_name data_con
-                           pat          = ConPatIn data_con_RDR []
-                          in
-                         [([pat,pat], eqTag_Expr)]
-                      else
-                         map pats_etc nonnullary_cons ++
-                         -- leave out wildcards to silence desugarer.
-                         (if isSingleton tycon_data_cons then
-                             []
-                          else
-                              [([WildPatIn, WildPatIn], default_rhs)]))
+    cmp_eq = mk_FunMonoBind 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,
+                          -- then there is nothing left to do
+                          -- Catch this specially to avoid warnings
+                          -- about overlapping patterns from the desugarer,
+                          -- and to avoid unnecessary pattern-matching
+      = [([wildPat,wildPat], 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)])
+
       where
        pats_etc data_con
          = ([con1_pat, con2_pat],
             nested_compare_expr tys_needed as_needed bs_needed)
          where
-           con1_pat = ConPatIn data_con_RDR (map VarPatIn as_needed)
-           con2_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
+           con1_pat = mkConPat data_con_RDR as_needed
+           con2_pat = mkConPat data_con_RDR bs_needed
 
-           data_con_RDR = qual_orig_name data_con
+           data_con_RDR = getRdrName data_con
            con_arity   = length tys_needed
            as_needed   = take con_arity as_RDRs
            bs_needed   = take con_arity bs_RDRs
            tys_needed  = dataConOrigArgTys data_con
 
            nested_compare_expr [ty] [a] [b]
-             = careful_compare_Case ty ltTag_Expr eqTag_Expr gtTag_Expr (HsVar a) (HsVar b)
+             = careful_compare_Case ty eqTag_Expr (HsVar a) (HsVar b)
 
            nested_compare_expr (ty:tys) (a:as) (b:bs)
              = let eq_expr = nested_compare_expr tys as bs
-               in  careful_compare_Case ty ltTag_Expr eq_expr gtTag_Expr (HsVar a) (HsVar b)
+               in  careful_compare_Case ty eq_expr (HsVar a) (HsVar b)
 
        default_rhs | null nullary_cons = impossible_Expr       -- Keep desugarer from complaining about
                                                                -- inexhaustive patterns
@@ -530,8 +516,8 @@ gen_Bounded_binds tycon
 
     data_con_1   = head data_cons
     data_con_N   = last data_cons
-    data_con_1_RDR = qual_orig_name data_con_1
-    data_con_N_RDR = qual_orig_name data_con_N
+    data_con_1_RDR = getRdrName data_con_1
+    data_con_N_RDR = getRdrName data_con_N
 
     ----- single-constructor-flavored: -------------
     arity         = dataConSourceArity data_con_1
@@ -617,7 +603,7 @@ gen_Ix_binds tycon
 
     enum_range
       = mk_easy_FunMonoBind tycon_loc range_RDR 
-               [TuplePatIn [a_Pat, b_Pat] Boxed] [] $
+               [TuplePat [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]) $
@@ -627,7 +613,7 @@ gen_Ix_binds tycon
 
     enum_index
       = mk_easy_FunMonoBind tycon_loc index_RDR 
-               [AsPatIn c_RDR (TuplePatIn [a_Pat, wildPat] Boxed), 
+               [AsPat c_RDR (TuplePat [a_Pat, wildPat] Boxed), 
                                d_Pat] [] (
        HsIf (HsPar (mkHsVarApps inRange_RDR [c_RDR, d_RDR])) (
           untag_Expr tycon [(a_RDR, ah_RDR)] (
@@ -636,8 +622,8 @@ gen_Ix_binds tycon
                rhs = mkHsVarApps mkInt_RDR [c_RDR]
           in
           HsCase
-            (genOpApp (HsVar dh_RDR) minusH_RDR (HsVar ah_RDR))
-            [mkSimpleMatch [VarPatIn c_RDR] rhs placeHolderType tycon_loc]
+            (genOpApp (HsVar dh_RDR) minusInt_RDR (HsVar ah_RDR))
+            [mkSimpleMatch [VarPat c_RDR] rhs placeHolderType tycon_loc]
             tycon_loc
           ))
        ) {-else-} (
@@ -647,12 +633,12 @@ gen_Ix_binds tycon
 
     enum_inRange
       = mk_easy_FunMonoBind tycon_loc inRange_RDR 
-         [TuplePatIn [a_Pat, b_Pat] Boxed, c_Pat] [] (
+         [TuplePat [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) geH_RDR (HsVar ah_RDR)) (
-            (genOpApp (HsVar ch_RDR) leH_RDR (HsVar bh_RDR))
+         HsIf (genOpApp (HsVar ch_RDR) geInt_RDR (HsVar ah_RDR)) (
+            (genOpApp (HsVar ch_RDR) leInt_RDR (HsVar bh_RDR))
          ) {-else-} (
             false_Expr
          ) tycon_loc))))
@@ -672,26 +658,26 @@ gen_Ix_binds tycon
                         dc
 
     con_arity    = dataConSourceArity data_con
-    data_con_RDR = qual_orig_name data_con
+    data_con_RDR = getRdrName data_con
 
     as_needed = take con_arity as_RDRs
     bs_needed = take con_arity bs_RDRs
     cs_needed = take con_arity cs_RDRs
 
-    con_pat  xs  = ConPatIn data_con_RDR (map VarPatIn xs)
+    con_pat  xs  = mkConPat data_con_RDR xs
     con_expr     = mkHsVarApps data_con_RDR cs_needed
 
     --------------------------------------------------------------
     single_con_range
       = mk_easy_FunMonoBind tycon_loc range_RDR 
-         [TuplePatIn [con_pat as_needed, con_pat bs_needed] Boxed] [] $
-       HsDo ListComp stmts tycon_loc
+         [TuplePat [con_pat as_needed, con_pat bs_needed] Boxed] [] $
+       mkHsDo ListComp stmts tycon_loc
       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 (VarPatIn c)
+       mk_qual a b c = BindStmt (VarPat c)
                                 (HsApp (HsVar range_RDR) 
                                        (ExplicitTuple [HsVar a, HsVar b] Boxed))
                                 tycon_loc
@@ -699,7 +685,7 @@ gen_Ix_binds tycon
     ----------------
     single_con_index
       = mk_easy_FunMonoBind tycon_loc index_RDR 
-               [TuplePatIn [con_pat as_needed, con_pat bs_needed] Boxed, 
+               [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))
       where
@@ -716,7 +702,7 @@ gen_Ix_binds tycon
 
        range_size
          = mk_easy_FunMonoBind tycon_loc rangeSize_RDR 
-                       [TuplePatIn [a_Pat, b_Pat] Boxed] [] (
+                       [TuplePat [a_Pat, b_Pat] Boxed] [] (
                genOpApp (
                    (mkHsApps index_RDR [ExplicitTuple [a_Expr, b_Expr] Boxed,
                                         b_Expr])
@@ -725,7 +711,7 @@ gen_Ix_binds tycon
     ------------------
     single_con_inRange
       = mk_easy_FunMonoBind tycon_loc inRange_RDR 
-               [TuplePatIn [con_pat as_needed, con_pat bs_needed] Boxed, 
+               [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))
@@ -750,7 +736,7 @@ Example
 
 instance Read T where
   readPrec =
-    block
+    parens
     ( prec 4 (
         do x           <- ReadP.step Read.readPrec
            Symbol "%%" <- Lex.lex
@@ -759,11 +745,11 @@ instance Read T where
       +++
       prec appPrec (
        do Ident "T1" <- Lex.lex
-          Single '{' <- Lex.lex
+          Punc '{' <- Lex.lex
           Ident "f1" <- Lex.lex
-          Single '=' <- Lex.lex
+          Punc '=' <- Lex.lex
           x          <- ReadP.reset Read.readPrec
-          Single '}' <- Lex.lex
+          Punc '}' <- Lex.lex
           return (T1 { f1 = x }))
       +++
       prec appPrec (
@@ -802,38 +788,38 @@ gen_Read_binds get_fixity tycon
     read_nullary_cons 
       = case nullary_cons of
            []    -> []
-           [con] -> [HsDo DoExpr [BindStmt (ident_pat (data_con_str con)) lex loc,
-                     result_stmt con []] loc]
+           [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))]
     
     mk_pair con = ExplicitTuple [HsLit (data_con_str con),
-                                HsApp (HsVar returnM_RDR) (HsVar (qual_orig_name con))]
+                                HsApp (HsVar returnM_RDR) (HsVar (getRdrName con))]
                                Boxed
     
     read_non_nullary_con data_con
-      = mkHsApps prec_RDR [mkHsIntLit prec, HsDo DoExpr stmts loc]
+      = mkHsApps prec_RDR [mkHsIntLit prec, mkHsDo DoExpr stmts loc]
       where
                stmts | is_infix          = infix_stmts
              | length labels > 0 = lbl_stmts
              | otherwise         = prefix_stmts
      
                prefix_stmts            -- T a b c
-                 = [BindStmt (ident_pat (data_con_str data_con)) lex loc]
+                 = [bindLex (ident_pat (data_con_str data_con))]
                    ++ map read_arg as_needed
                    ++ [result_stmt data_con as_needed]
         
                infix_stmts             -- a %% b
                  = [read_arg a1, 
-            BindStmt (symbol_pat (data_con_str data_con)) lex loc,
+            bindLex (symbol_pat (data_con_str data_con)),
             read_arg a2,
             result_stmt data_con [a1,a2]]
      
                lbl_stmts               -- T { f1 = a, f2 = b }
-                 = [BindStmt (ident_pat (data_con_str data_con)) lex loc,
-                    read_punc '{']
-                   ++ concat (intersperse [read_punc ','] field_stmts)
-                   ++ [read_punc '}', result_stmt data_con as_needed]
+                 = [bindLex (ident_pat (data_con_str data_con)),
+                    read_punc "{"]
+                   ++ concat (intersperse [read_punc ","] field_stmts)
+                   ++ [read_punc "}", result_stmt data_con as_needed]
      
                field_stmts  = zipWithEqual "lbl_stmts" read_field labels as_needed
      
@@ -841,36 +827,46 @@ gen_Read_binds get_fixity tycon
                nullary_con  = con_arity == 0
                labels       = dataConFieldLabels data_con
                lab_fields   = length labels
-               dc_nm   = getName data_con
+               dc_nm        = getName data_con
                is_infix     = isDataSymOcc (getOccName dc_nm)
                as_needed    = take con_arity as_RDRs
                (a1:a2:_)    = as_needed
-     
-               prec | not is_infix  = appPrecedence
-             | otherwise     = getPrecedence get_fixity dc_nm
+               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 (qual_orig_name c) as
+    con_app c as     = mkHsVarApps (getRdrName c) as
     
-    lex          = HsVar lexP_RDR
-    single_pat c = ConPatIn single_RDR [LitPatIn (mkHsChar c)]   -- Single 'x'
-    ident_pat s  = ConPatIn ident_RDR [LitPatIn s]               -- Ident "foo"
-    symbol_pat s = ConPatIn symbol_RDR [LitPatIn s]              -- Symbol ">>"
+    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 ">>"
     
-    lbl_str :: FieldLabel -> HsLit
-    lbl_str      lbl = mkHsString (occNameUserString (getOccName (fieldLabelName lbl)))
     data_con_str con = mkHsString (occNameUserString (getOccName con))
     
-    read_punc c = BindStmt (single_pat c) lex loc
-    read_arg a  = BindStmt (VarPatIn a) (mkHsVarApps step_RDR [readPrec_RDR]) loc
+    read_punc c = bindLex (punc_pat c)
+    read_arg a  = BindStmt (VarPat a) (mkHsVarApps step_RDR [readPrec_RDR]) loc
     
-    read_field lbl a = [BindStmt (ident_pat (lbl_str lbl)) lex loc,
-                       read_punc '=',
-                       BindStmt (VarPatIn a) (mkHsVarApps reset_RDR [readPrec_RDR]) loc]
+    read_field lbl a = read_lbl lbl ++
+                      [read_punc "=",
+                       BindStmt (VarPat a) (mkHsVarApps reset_RDR [readPrec_RDR]) loc]
+
+       -- When reading field labels we might encounter
+       --      a = 3
+       -- or   (#) = 4
+       -- Note the parens!
+    read_lbl lbl | isAlpha (head lbl_str) 
+                = [bindLex (ident_pat lbl_lit)]
+                | otherwise
+                = [read_punc "(", 
+                   bindLex (symbol_pat lbl_lit),
+                   read_punc ")"]
+                where  
+                  lbl_str = occNameUserString (getOccName (fieldLabelName lbl)) 
+                  lbl_lit = mkHsString lbl_str
 \end{code}
 
 
@@ -880,6 +876,29 @@ gen_Read_binds get_fixity tycon
 %*                                                                     *
 %************************************************************************
 
+Example
+
+    infixr 5 :^:
+
+    data Tree a =  Leaf a  |  Tree a :^: Tree a
+
+    instance (Show a) => Show (Tree a) where
+
+        showsPrec d (Leaf m) = showParen (d > app_prec) showStr
+          where
+             showStr = showString "Leaf " . showsPrec (app_prec+1) m
+
+        showsPrec d (u :^: v) = showParen (d > up_prec) showStr
+          where
+             showStr = showsPrec (up_prec+1) u . 
+                       showString " :^: "      .
+                       showsPrec (up_prec+1) v
+                -- Note: right-associativity of :^: ignored
+
+    up_prec  = 5    -- Precedence of :^:
+    app_prec = 10   -- Application has precedence one more than
+                   -- the most tightly-binding operator
+
 \begin{code}
 gen_Show_binds :: FixityEnv -> TyCon -> RdrNameMonoBinds
 
@@ -896,117 +915,77 @@ gen_Show_binds get_fixity tycon
        pats_etc data_con
          | nullary_con =  -- skip the showParen junk...
             ASSERT(null bs_needed)
-            ([wildPat, con_pat], show_con)
+            ([wildPat, con_pat], mk_showString_app con_str)
          | otherwise   =
             ([a_Pat, con_pat],
-                 showParen_Expr (HsPar (genOpApp a_Expr ge_RDR (HsLit (HsInt paren_prec_limit))))
+                 showParen_Expr (HsPar (genOpApp a_Expr ge_RDR (HsLit (HsInt con_prec_plus_one))))
                                 (HsPar (nested_compose_Expr show_thingies)))
            where
-            data_con_RDR = qual_orig_name data_con
-            con_arity    = dataConSourceArity data_con
-            bs_needed    = take con_arity bs_RDRs
-            con_pat      = ConPatIn data_con_RDR (map VarPatIn bs_needed)
-            nullary_con  = con_arity == 0
-             labels       = dataConFieldLabels data_con
-            lab_fields   = length labels
+            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
+            nullary_con   = con_arity == 0
+             labels        = dataConFieldLabels data_con
+            lab_fields    = length labels
+            record_syntax = lab_fields > 0
 
             dc_nm          = getName data_con
             dc_occ_nm      = getOccName data_con
-             dc_occ_nm_str  = occNameUserString dc_occ_nm
+             con_str        = occNameUserString dc_occ_nm
 
-            is_infix     = isDataSymOcc dc_occ_nm
-
-
-            show_con
-              | is_infix  = mk_showString_app (' ':dc_occ_nm_str)
-              | otherwise = mk_showString_app (dc_occ_nm_str ++ space_ocurly_maybe)
-                where
-                 space_ocurly_maybe
-                    | nullary_con     = ""
-                   | lab_fields == 0 = " "
-                   | otherwise       = "{"
-                
-
-            show_all con fs@(x:xs)
-               | is_infix  = x:con:xs
-               | otherwise = 
-                 let
-                    ccurly_maybe 
-                      | lab_fields > 0  = [mk_showString_app "}"]
-                      | otherwise       = []
-                 in
-                 con:fs ++ ccurly_maybe
-
-            show_thingies = show_all show_con real_show_thingies_with_labs
+            show_thingies 
+               | is_infix      = [show_arg1, mk_showString_app (" " ++ con_str ++ " "), show_arg2]
+               | record_syntax = mk_showString_app (con_str ++ " {") : 
+                                 show_record_args ++ [mk_showString_app "}"]
+               | otherwise     = mk_showString_app (con_str ++ " ") : show_prefix_args
                 
-            show_label l = mk_showString_app (the_name ++ "=")
+            show_label l = mk_showString_app (the_name ++ " = ")
+                       -- 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)
-                   -- legal, but rare.
-                  is_op    = isSymOcc occ_nm
+                  nm       = occNameUserString occ_nm
+
+                  is_op    = isSymOcc occ_nm       -- Legal, but rare.
                   the_name 
                     | is_op     = '(':nm ++ ")"
                     | otherwise = nm
 
-                  nm       = occNameUserString occ_nm
-               
-
-             mk_showString_app str = HsApp (HsVar showString_RDR)
-                                          (HsLit (mkHsString str))
-
-             prec_cons = getLRPrecs is_infix get_fixity dc_nm
-
-             real_show_thingies
-               | is_infix  = 
-                    [ mkHsApps showsPrec_RDR [HsLit (HsInt p), HsVar b]
-                    | (p,b) <- zip prec_cons bs_needed ]
-               | otherwise =
-                    [ mkHsApps showsPrec_RDR [mkHsIntLit 10, HsVar b]
-                    | b <- bs_needed ]
-
-             real_show_thingies_with_labs
-               | lab_fields == 0 = intersperse (HsVar showSpace_RDR) real_show_thingies
-               | otherwise       = --Assumption: no of fields == no of labelled fields 
-                                    --            (and in same order)
-                   concat $
-                   intersperse ([mk_showString_app ","]) $ -- Using SLIT()s containing ,s spells trouble.
-                   zipWithEqual "gen_Show_binds"
-                                (\ a b -> [a,b])
-                                (map show_label labels) 
-                                real_show_thingies
+             show_args = [ mkHsApps showsPrec_RDR [HsLit (HsInt arg_prec), HsVar b]
+                        | b <- bs_needed ]
+            (show_arg1:show_arg2:_) = show_args
+            show_prefix_args = intersperse (HsVar showSpace_RDR) show_args
+
+               --  Assumption for record syntax: no of fields == no of labelled fields 
+               --            (and in same order)
+            show_record_args = concat $
+                               intersperse [mk_showString_app ", "] $
+                               [ [show_label lbl, arg] 
+                               | (lbl,arg) <- zipEqual "gen_Show_binds" 
+                                                       labels show_args ]
                               
-             {-
-               c.f. Figure 16 and 17 in Haskell 1.1 report
-             -}  
-            paren_prec_limit
-               | not is_infix = appPrecedence + 1
-               | otherwise    = getPrecedence get_fixity dc_nm + 1
+               -- Fixity stuff
+            is_infix = isDataSymOcc dc_occ_nm
+             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))
 \end{code}
 
 \begin{code}
-getLRPrecs :: Bool -> FixityEnv -> Name -> [Integer]
-getLRPrecs is_infix get_fixity nm = [lp, rp]
-    where
-     {-
-       Figuring out the fixities of the arguments to a constructor,
-       cf. Figures 16-18 in Haskell 1.1 report.
-     -}
-     (con_left_assoc, con_right_assoc) = isLRAssoc get_fixity nm
-     paren_con_prec = getPrecedence get_fixity nm
-
-     lp
-      | not is_infix   = appPrecedence + 1
-      | con_left_assoc = paren_con_prec
-      | otherwise      = paren_con_prec + 1
-                 
-     rp
-      | not is_infix    = appPrecedence + 1
-      | con_right_assoc = paren_con_prec
-      | otherwise       = paren_con_prec + 1
+getPrec :: Bool -> FixityEnv -> Name -> Integer
+getPrec is_infix get_fixity nm 
+  | not is_infix   = appPrecedence
+  | otherwise      = getPrecedence get_fixity nm
                  
 appPrecedence :: Integer
-appPrecedence = fromIntegral maxPrecedence
+appPrecedence = fromIntegral maxPrecedence + 1
+  -- One more than the precedence of the most 
+  -- tightly-binding operator
 
 getPrecedence :: FixityEnv -> Name -> Integer
 getPrecedence get_fixity nm 
@@ -1052,7 +1031,7 @@ gen_tag_n_con_monobind
 gen_tag_n_con_monobind (rdr_name, tycon, GenCon2Tag)
   | lots_of_constructors
   = mk_FunMonoBind (getSrcLoc tycon) rdr_name 
-       [([VarPatIn a_RDR], HsApp getTag_Expr a_Expr)]
+       [([VarPat a_RDR], HsApp getTag_Expr a_Expr)]
 
   | otherwise
   = mk_FunMonoBind (getSrcLoc tycon) rdr_name (map mk_stuff (tyConDataCons tycon))
@@ -1064,14 +1043,14 @@ gen_tag_n_con_monobind (rdr_name, tycon, GenCon2Tag)
     mk_stuff var
       = ([pat], HsLit (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG))))
       where
-       pat    = ConPatIn var_RDR (nOfThem (dataConSourceArity var) WildPatIn)
-       var_RDR = qual_orig_name var
+       pat    = ConPatIn var_RDR (PrefixCon (nOfThem (dataConSourceArity var) wildPat))
+       var_RDR = getRdrName var
 
 gen_tag_n_con_monobind (rdr_name, tycon, GenTag2Con)
   = mk_FunMonoBind (getSrcLoc tycon) rdr_name 
-       [([ConPatIn mkInt_RDR [VarPatIn a_RDR]], 
+       [([mkConPat mkInt_RDR [a_RDR]], 
           ExprWithTySig (HsApp tagToEnum_Expr a_Expr) 
-                        (HsTyVar (qual_orig_name tycon)))]
+                        (HsTyVar (getRdrName tycon)))]
 
 gen_tag_n_con_monobind (rdr_name, tycon, GenMaxTag)
   = mk_easy_FunMonoBind (getSrcLoc tycon) 
@@ -1130,8 +1109,8 @@ mk_match loc pats expr binds
   = Match (map paren pats) Nothing 
          (GRHSs (unguardedRHS expr loc) binds placeHolderType)
   where
-    paren p@(VarPatIn _) = p
-    paren other_p       = ParPatIn other_p
+    paren p@(VarPat _) = p
+    paren other_p      = ParPat other_p
 \end{code}
 
 \begin{code}
@@ -1141,40 +1120,44 @@ 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 [])
 \end{code}
 
 ToDo: Better SrcLocs.
 
 \begin{code}
 compare_gen_Case ::
-         RdrName
-         -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
+         RdrNameHsExpr -- What to do for equality
          -> RdrNameHsExpr -> RdrNameHsExpr
          -> RdrNameHsExpr
 careful_compare_Case :: -- checks for primitive types...
          Type
-         -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
+         -> RdrNameHsExpr      -- What to do for equality
          -> RdrNameHsExpr -> RdrNameHsExpr
          -> RdrNameHsExpr
 
 cmp_eq_Expr a b = HsApp (HsApp (HsVar cmp_eq_RDR) a) b
        -- Was: compare_gen_Case cmp_eq_RDR
 
-compare_gen_Case fun lt eq gt a b
-  = HsCase (HsPar (HsApp (HsApp (HsVar fun) a) b)) {-of-}
-      [mkSimpleMatch [ConPatIn ltTag_RDR []] lt placeHolderType generatedSrcLoc,
-       mkSimpleMatch [ConPatIn eqTag_RDR []] eq placeHolderType generatedSrcLoc,
-       mkSimpleMatch [ConPatIn gtTag_RDR []] gt placeHolderType generatedSrcLoc]
+compare_gen_Case (HsVar eq_tag) a b | eq_tag == eqTag_RDR
+  = HsApp (HsApp (HsVar 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 lt eq gt a b
+careful_compare_Case ty eq a b
   | not (isUnLiftedType ty) =
-       compare_gen_Case compare_RDR lt eq gt a b
+       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) lt gt generatedSrcLoc)
+           (HsIf (genOpApp a relevant_lt_op b) ltTag_Expr gtTag_Expr generatedSrcLoc)
            generatedSrcLoc
   where
     relevant_eq_op = assoc_ty_id eq_op_tbl ty
@@ -1187,21 +1170,21 @@ assoc_ty_id tyids ty
     res = [id | (ty',id) <- tyids, ty `tcEqType` ty']
 
 eq_op_tbl =
-    [(charPrimTy,      eqH_Char_RDR)
-    ,(intPrimTy,       eqH_Int_RDR)
-    ,(wordPrimTy,      eqH_Word_RDR)
-    ,(addrPrimTy,      eqH_Addr_RDR)
-    ,(floatPrimTy,     eqH_Float_RDR)
-    ,(doublePrimTy,    eqH_Double_RDR)
+    [(charPrimTy,      eqChar_RDR)
+    ,(intPrimTy,       eqInt_RDR)
+    ,(wordPrimTy,      eqWord_RDR)
+    ,(addrPrimTy,      eqAddr_RDR)
+    ,(floatPrimTy,     eqFloat_RDR)
+    ,(doublePrimTy,    eqDouble_RDR)
     ]
 
 lt_op_tbl =
-    [(charPrimTy,      ltH_Char_RDR)
-    ,(intPrimTy,       ltH_Int_RDR)
-    ,(wordPrimTy,      ltH_Word_RDR)
-    ,(addrPrimTy,      ltH_Addr_RDR)
-    ,(floatPrimTy,     ltH_Float_RDR)
-    ,(doublePrimTy,    ltH_Double_RDR)
+    [(charPrimTy,      ltChar_RDR)
+    ,(intPrimTy,       ltInt_RDR)
+    ,(wordPrimTy,      ltWord_RDR)
+    ,(addrPrimTy,      ltAddr_RDR)
+    ,(floatPrimTy,     ltFloat_RDR)
+    ,(doublePrimTy,    ltDouble_RDR)
     ]
 
 -----------------------------------------------------------------------
@@ -1229,7 +1212,7 @@ untag_Expr :: TyCon -> [(RdrName, RdrName)] -> RdrNameHsExpr -> RdrNameHsExpr
 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 [VarPatIn put_tag_here] (untag_Expr tycon more expr) placeHolderType generatedSrcLoc]
+      [mkSimpleMatch [VarPat put_tag_here] (untag_Expr tycon more expr) placeHolderType generatedSrcLoc]
       generatedSrcLoc
 
 cmp_tags_Expr :: RdrName               -- Comparison op
@@ -1303,8 +1286,7 @@ genOpApp e1 op e2 = mkHsOpApp e1 op e2
 \end{code}
 
 \begin{code}
-qual_orig_name n = nameRdrName (getName n)
-varUnqual n      = mkUnqual varName n
+varUnqual n     = mkUnqual OccName.varName n
 
 zz_a_RDR       = varUnqual FSLIT("_a")
 a_RDR          = varUnqual FSLIT("a")
@@ -1334,15 +1316,15 @@ false_Expr      = HsVar false_RDR
 true_Expr      = HsVar true_RDR
 
 getTag_Expr    = HsVar getTag_RDR
-tagToEnum_Expr         = HsVar tagToEnumH_RDR
+tagToEnum_Expr         = HsVar tagToEnum_RDR
 con2tag_Expr tycon = HsVar (con2tag_RDR tycon)
 
-wildPat                = WildPatIn
-zz_a_Pat       = VarPatIn zz_a_RDR
-a_Pat          = VarPatIn a_RDR
-b_Pat          = VarPatIn b_RDR
-c_Pat          = VarPatIn c_RDR
-d_Pat          = VarPatIn d_RDR
+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
 
@@ -1350,3 +1332,25 @@ con2tag_RDR tycon = varUnqual (mkFastString ("con2tag_" ++ occNameString (getOcc
 tag2con_RDR tycon = varUnqual (mkFastString ("tag2con_" ++ occNameString (getOccName tycon) ++ "#"))
 maxtag_RDR tycon  = varUnqual (mkFastString ("maxtag_"  ++ occNameString (getOccName tycon) ++ "#"))
 \end{code}
+
+RdrNames 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                   
+\end{code}