[project @ 2005-06-15 12:03:19 by simonmar]
authorsimonmar <unknown>
Wed, 15 Jun 2005 12:03:46 +0000 (12:03 +0000)
committersimonmar <unknown>
Wed, 15 Jun 2005 12:03:46 +0000 (12:03 +0000)
Re-implement GHCi's :info and :browse commands in terms of TyThings
rather than IfaceSyn.

The GHC API now exposes its internal types for Haskell entities:
TyCons, Classes, DataCons, Ids and Instances (collectively known as
TyThings), so we can inspect these directly to pretty-print
information about an entity.  Previously the internal representations
were converted to IfaceSyn for passing to InteractiveUI, but we can
now remove that code.

Some of the new code comes via Visual Haskell, but I've changed it
around a lot to fix various dark corners and properly print things
like GADTs.

The pretty-printing interfaces for TyThings are exposed by a new
module PprTyThing, which is implemented purely in terms of the GHC API
(and is probably a good source of sample code).  Visual Haskell should
be able to use the functions exported by this module directly.

Lots of new goodies are exported by the GHC module, mainly for
inspecting TyThings.

ghc/compiler/basicTypes/Id.lhs
ghc/compiler/ghci/InteractiveUI.hs
ghc/compiler/main/GHC.hs
ghc/compiler/main/HscMain.lhs
ghc/compiler/main/PprTyThing.hs [new file with mode: 0644]
ghc/compiler/nativeGen/RegisterAlloc.hs
ghc/compiler/typecheck/TcRnDriver.lhs
ghc/compiler/typecheck/TcRnMonad.lhs
ghc/compiler/types/Class.lhs
ghc/compiler/types/InstEnv.lhs

index 4348e4a..62c722a 100644 (file)
@@ -27,6 +27,7 @@ module Id (
        isImplicitId, isDeadBinder,
        isSpecPragmaId, isExportedId, isLocalId, isGlobalId,
        isRecordSelector,
+       isClassOpId_maybe,
        isPrimOpId, isPrimOpId_maybe, 
        isFCallId, isFCallId_maybe,
        isDataConWorkId, isDataConWorkId_maybe, idDataCon,
@@ -249,6 +250,10 @@ isRecordSelector id = case globalIdDetails id of
                        RecordSelId _ _ -> True
                        other           -> False
 
+isClassOpId_maybe id = case globalIdDetails id of
+                       ClassOpId cls -> Just cls
+                       _other        -> Nothing
+
 isPrimOpId id = case globalIdDetails id of
                    PrimOpId op -> True
                    other       -> False
index 0b617dd..8ef6d69 100644 (file)
@@ -19,7 +19,8 @@ import GHC            ( Session, verbosity, dopt, DynFlag(..),
                          mkModule, pprModule, Type, Module, SuccessFlag(..),
                          TyThing(..), Name, LoadHowMuch(..), Phase,
                          GhcException(..), showGhcException,
-                         CheckedModule(..) )
+                         CheckedModule(..), SrcLoc )
+import PprTyThing
 import Outputable
 
 -- for createtags (should these come via GHC?)
@@ -28,17 +29,8 @@ import Name( nameSrcLoc, nameModule, nameOccName )
 import OccName( pprOccName )
 import SrcLoc( isGoodSrcLoc, srcLocFile, srcLocLine, srcLocCol )
 
--- following all needed for :info... ToDo: remove
-import IfaceSyn                ( IfaceDecl(..), IfaceClassOp(..), IfaceConDecls(..),
-                         IfaceConDecl(..), IfaceType,
-                         pprIfaceDeclHead, pprParendIfaceType,
-                         pprIfaceForAllPart, pprIfaceType )
-import FunDeps         ( pprFundeps )
-import SrcLoc          ( SrcLoc, pprDefnLoc )
-import OccName         ( OccName, parenSymOcc, occNameUserString )
-import BasicTypes      ( StrictnessMark(..), defaultFixity, failed, successIf )
-
 -- Other random utilities
+import BasicTypes      ( failed, successIf )
 import Panic           ( panic, installSignalHandlers )
 import Config
 import StaticFlags     ( opt_IgnoreDotGhci )
@@ -70,7 +62,7 @@ import Data.Dynamic
 import Numeric
 import Data.List
 import Data.Int                ( Int64 )
-import Data.Maybe      ( isJust )
+import Data.Maybe      ( isJust, fromMaybe, catMaybes )
 import System.Cmd
 import System.CPUTime
 import System.Environment
@@ -536,126 +528,32 @@ info s  = do { let names = words s
             ; let exts = dopt Opt_GlasgowExts dflags
             ; mapM_ (infoThing exts session) names }
   where
-    infoThing exts session name
-       = do { stuff <- io (GHC.getInfo session name)
-            ; unqual <- io (GHC.getPrintUnqual session)
-            ; io (putStrLn (showSDocForUser unqual $
-                  vcat (intersperse (text "") (map (showThing exts) stuff)))) }
-
-showThing :: Bool -> GHC.GetInfoResult -> SDoc
-showThing exts (wanted_str, thing, fixity, src_loc, insts) 
-    = vcat [ showWithLoc src_loc (showDecl exts want_name thing),
-            show_fixity fixity,
-            vcat (map show_inst insts)]
+    infoThing exts session str = io $ do
+       names <- GHC.parseName session str
+       let filtered = filterOutChildren names
+       mb_stuffs <- mapM (GHC.getInfo session) filtered
+       unqual <- GHC.getPrintUnqual session
+       putStrLn (showSDocForUser unqual $
+                  vcat (intersperse (text "") $
+                  [ pprInfo exts stuff | Just stuff <-  mb_stuffs ]))
+
+  -- Filter out names whose parent is also there Good
+  -- example is '[]', which is both a type and data
+  -- constructor in the same type
+filterOutChildren :: [Name] -> [Name]
+filterOutChildren names = filter (not . parent_is_there) names
+ where parent_is_there n 
+        | Just p <- GHC.nameParent_maybe n = p `elem` names
+        | otherwise                       = False
+
+pprInfo exts (thing, fixity, insts)
+  =  pprTyThingLoc exts thing 
+  $$ show_fixity fixity
+  $$ vcat (map GHC.pprInstance insts)
   where
-    want_name occ = wanted_str == occNameUserString occ
-
     show_fixity fix 
-       | fix == defaultFixity = empty
-       | otherwise            = ppr fix <+> text wanted_str
-
-    show_inst (inst_ty, loc)
-       = showWithLoc loc (ptext SLIT("instance") <+> ppr inst_ty)
-
-showWithLoc :: SrcLoc -> SDoc -> SDoc
-showWithLoc loc doc 
-    = hang doc 2 (char '\t' <> comment <+> pprDefnLoc loc)
-               -- The tab tries to make them line up a bit
-  where
-    comment = ptext SLIT("--")
-
-
--- Now there is rather a lot of goop just to print declarations in a
--- civilised way with "..." for the parts we are less interested in.
-
-showDecl :: Bool -> (OccName -> Bool) -> IfaceDecl -> SDoc
-showDecl exts want_name (IfaceForeign {ifName = tc})
-  = ppr tc <+> ptext SLIT("is a foreign type")
-
-showDecl exts want_name (IfaceId {ifName = var, ifType = ty})
-  = ppr var <+> dcolon <+> showIfaceType exts ty 
-
-showDecl exts want_name (IfaceSyn {ifName = tycon, ifTyVars = tyvars, ifSynRhs = mono_ty})
-  = hang (ptext SLIT("type") <+> pprIfaceDeclHead [] tycon tyvars)
-       2 (equals <+> ppr mono_ty)
-
-showDecl exts want_name (IfaceData {ifName = tycon, 
-                    ifTyVars = tyvars, ifCons = condecls, ifCtxt = context})
-  = hang (pp_nd <+> pprIfaceDeclHead context tycon tyvars)
-       2 (add_bars (ppr_trim show_con cs))
-  where
-    show_con (IfVanillaCon { ifConOcc = con_name, ifConInfix = is_infix, ifConArgTys = tys, 
-                            ifConStricts = strs, ifConFields = flds})
-       | want_name tycon || want_name con_name || any want_name flds
-       = Just (show_guts con_name is_infix tys_w_strs flds)
-       | otherwise = Nothing
-       where
-         tys_w_strs = tys `zip` (strs ++ repeat NotMarkedStrict)
-    show_con (IfGadtCon { ifConOcc = con_name, ifConTyVars = tvs, ifConCtxt = theta, 
-                         ifConArgTys = arg_tys, ifConResTys = res_tys, ifConStricts = strs })
-       | want_name tycon || want_name con_name
-       = Just (ppr_bndr con_name <+> colon <+> pprIfaceForAllPart tvs theta pp_tau)
-       | otherwise = Nothing
-       where
-         tys_w_strs = arg_tys `zip` (strs ++ repeat NotMarkedStrict)
-         pp_tau = foldr add pp_res_ty tys_w_strs
-         pp_res_ty = ppr_bndr tycon <+> hsep (map pprParendIfaceType res_tys)
-         add bty pp_ty = ppr_bangty bty <+> arrow <+> pp_ty
-
-    show_guts con True [ty1, ty2] flds = sep [ppr_bangty ty1, ppr con, ppr_bangty ty2]
-    show_guts con _ tys []   = ppr_bndr con <+> sep (map ppr_bangty tys)
-    show_guts con _ tys flds 
-       = ppr_bndr con <+> braces (sep (punctuate comma (ppr_trim show_fld (tys `zip` flds))))
-       where
-         show_fld (bty, fld) | want_name tycon || want_name con || want_name fld
-                             = Just (ppr_bndr fld <+> dcolon <+> ppr_bangty bty)
-                             | otherwise = Nothing
-
-    (pp_nd, cs) = case condecls of
-                   IfAbstractTyCon        -> (ptext SLIT("data"),   [])
-                   IfDataTyCon cs         -> (ptext SLIT("data"),   cs)
-                   IfNewTyCon c           -> (ptext SLIT("newtype"),[c])
-
-    add_bars []      = empty
-    add_bars [c]     = equals <+> c
-    add_bars (c:cs)  = equals <+> sep (c : map (char '|' <+>) cs)
-
-    ppr_bangty (ty, str) = ppr_str str <> pprParendIfaceType ty
-    ppr_str MarkedStrict    = char '!'
-    ppr_str MarkedUnboxed   = ptext SLIT("!!")
-    ppr_str NotMarkedStrict = empty
-
-showDecl exts want_name (IfaceClass {ifCtxt = context, ifName = clas, ifTyVars = tyvars, 
-                     ifFDs = fds, ifSigs = sigs})
-  = hang (ptext SLIT("class") <+> pprIfaceDeclHead context clas tyvars
-               <+> pprFundeps fds <+> opt_where)
-       2 (vcat (ppr_trim show_op sigs))
-  where
-    opt_where | null sigs = empty
-             | otherwise = ptext SLIT("where")
-    show_op (IfaceClassOp op dm ty) 
-       | want_name clas || want_name op 
-       = Just (ppr_bndr op <+> dcolon <+> showIfaceType exts ty)
-       | otherwise
-       = Nothing
-
-showIfaceType :: Bool -> IfaceType -> SDoc
-showIfaceType True  ty = pprIfaceType ty -- -fglasgow-exts: print with the foralls
-showIfaceType False ty = ppr ty            -- otherwise, print without the foralls
-
-ppr_trim :: (a -> Maybe SDoc) -> [a] -> [SDoc]
-ppr_trim show xs
-  = snd (foldr go (False, []) xs)
-  where
-    go x (eliding, so_far)
-       | Just doc <- show x = (False, doc : so_far)
-       | otherwise = if eliding then (True, so_far)
-                                else (True, ptext SLIT("...") : so_far)
-
-ppr_bndr :: OccName -> SDoc
--- Wrap operators in ()
-ppr_bndr occ = parenSymOcc occ (ppr occ)
-
+       | fix == GHC.defaultFixity = empty
+       | otherwise                = ppr fix <+> ppr (GHC.getName thing)
 
 -----------------------------------------------------------------------------
 -- Commands
@@ -974,16 +872,29 @@ browseModule m exports_only = do
   (as,bs) <- io (GHC.getContext s)
   io (if exports_only then GHC.setContext s [] [prelude_mod,modl]
                      else GHC.setContext s [modl] [])
+  unqual <- io (GHC.getPrintUnqual s)
   io (GHC.setContext s as bs)
 
-  things <- io (GHC.browseModule s modl exports_only)
-  unqual <- io (GHC.getPrintUnqual s)
+  mb_mod_info <- io $ GHC.getModuleInfo s modl
+  case mb_mod_info of
+    Nothing -> throwDyn (CmdLineError ("unknown module: " ++ m))
+    Just mod_info -> do
+        let names
+              | exports_only = GHC.modInfoExports mod_info
+              | otherwise    = fromMaybe [] (GHC.modInfoTopLevelScope mod_info)
 
-  dflags <- getDynFlags
-  let exts = dopt Opt_GlasgowExts dflags
-  io (putStrLn (showSDocForUser unqual (
-        vcat (map (showDecl exts (const True)) things)
-      )))
+           filtered = filterOutChildren names
+       
+        things <- io $ mapM (GHC.lookupName s) filtered
+
+        dflags <- getDynFlags
+       let exts = dopt Opt_GlasgowExts dflags
+       io (putStrLn (showSDocForUser unqual (
+               vcat (map (pprTyThing exts) (catMaybes things))
+          )))
+       -- ToDo: modInfoInstances currently throws an exception for
+       -- package modules.  When it works, we can do this:
+       --      $$ vcat (map GHC.pprInstance (GHC.modInfoInstances mod_info))
 
 -----------------------------------------------------------------------------
 -- Setting the module context
index 4be8e55..21b4fd9 100644 (file)
@@ -65,13 +65,12 @@ module GHC (
        setContext, getContext, 
        getNamesInScope,
        moduleIsInterpreted,
-       getInfo, GetInfoResult,
+       getInfo,
        exprType,
        typeKind,
        parseName,
        RunResult(..),
        runStmt,
-       browseModule,
        showModule,
        compileExpr, HValue,
        lookupName,
@@ -83,34 +82,47 @@ module GHC (
        Module, mkModule, pprModule,
 
        -- ** Names
-       Name, nameModule,
+       Name, 
+       nameModule, nameParent_maybe, pprParenSymName, nameSrcLoc,
+       NamedThing(..),
        
        -- ** Identifiers
        Id, idType,
        isImplicitId, isDeadBinder,
        isSpecPragmaId, isExportedId, isLocalId, isGlobalId,
        isRecordSelector,
-       isPrimOpId, isFCallId,
+       isPrimOpId, isFCallId, isClassOpId_maybe,
        isDataConWorkId, idDataCon,
        isBottomingId, isDictonaryId,
+       recordSelectorFieldLabel,
 
        -- ** Type constructors
        TyCon, 
+       tyConTyVars, tyConDataCons,
        isClassTyCon, isSynTyCon, isNewTyCon,
+       getSynTyConDefn,
 
        -- ** Data constructors
        DataCon,
+       dataConSig, dataConType, dataConTyCon, dataConFieldLabels,
+       dataConIsInfix, isVanillaDataCon,
+       dataConStrictMarks,  
+       StrictnessMark(..), isMarkedStrict,
 
        -- ** Classes
        Class, 
-       classSCTheta, classTvsFds,
+       classMethods, classSCTheta, classTvsFds,
+       pprFundeps,
 
        -- ** Instances
-       Instance,
+       Instance, 
+       instanceDFunId, pprInstance,
 
        -- ** Types and Kinds
-       Type, dropForAlls,
+       Type, dropForAlls, splitForAllTys, funResultTy, pprParendType,
        Kind,
+       PredType,
+       ThetaType, pprThetaArrow,
 
        -- ** Entities
        TyThing(..), 
@@ -118,6 +130,15 @@ module GHC (
        -- ** Syntax
        module HsSyn, -- ToDo: remove extraneous bits
 
+       -- ** Fixities
+       FixityDirection(..), 
+       defaultFixity, maxPrecedence, 
+       negateFixity,
+       compareFixity,
+
+       -- ** Source locations
+       SrcLoc, pprDefnLoc,
+
        -- * Exceptions
        GhcException(..), showGhcException,
 
@@ -129,8 +150,7 @@ module GHC (
 {-
  ToDo:
 
-  * inline bits of HscMain here to simplify layering: hscGetInfo,
-    hscTcExpr, hscStmt.
+  * inline bits of HscMain here to simplify layering: hscTcExpr, hscStmt.
   * we need to expose DynFlags, so should parseDynamicFlags really be
     part of this interface?
   * what StaticFlags should we expose, if any?
@@ -141,17 +161,15 @@ module GHC (
 #ifdef GHCI
 import qualified Linker
 import Linker          ( HValue, extendLinkEnv )
-import TcRnDriver      ( getModuleContents, tcRnLookupRdrName,
-                         getModuleExports )
+import TcRnDriver      ( tcRnLookupRdrName, tcRnGetInfo,
+                         tcRnLookupName, getModuleExports )
 import RdrName         ( plusGlobalRdrEnv, Provenance(..), 
                          ImportSpec(..), ImpDeclSpec(..), ImpItemSpec(..),
                          emptyGlobalRdrEnv, mkGlobalRdrEnv )
-import HscMain         ( hscGetInfo, GetInfoResult, hscParseIdentifier,
-                         hscStmt, hscTcExpr, hscKcType )
+import HscMain         ( hscParseIdentifier, hscStmt, hscTcExpr, hscKcType )
 import Type            ( tidyType )
 import VarEnv          ( emptyTidyEnv )
 import GHC.Exts                ( unsafeCoerce# )
-import IfaceSyn                ( IfaceDecl )
 #endif
 
 import Packages                ( initPackages, isHomeModule )
@@ -159,19 +177,27 @@ import NameSet            ( NameSet, nameSetToList, elemNameSet )
 import RdrName         ( GlobalRdrEnv, GlobalRdrElt(..), RdrName, 
                          globalRdrEnvElts )
 import HsSyn
-import Type            ( Kind, Type, dropForAlls )
+import Type            ( Kind, Type, dropForAlls, PredType, ThetaType,
+                         pprThetaArrow, pprParendType, splitForAllTys,
+                         funResultTy )
 import Id              ( Id, idType, isImplicitId, isDeadBinder,
                           isSpecPragmaId, isExportedId, isLocalId, isGlobalId,
-                          isRecordSelector,
-                          isPrimOpId, isFCallId,
+                          isRecordSelector, recordSelectorFieldLabel,
+                          isPrimOpId, isFCallId, isClassOpId_maybe,
                           isDataConWorkId, idDataCon,
                           isBottomingId )
-import TyCon           ( TyCon, isClassTyCon, isSynTyCon, isNewTyCon )
-import Class           ( Class, classSCTheta, classTvsFds )
-import DataCon         ( DataCon )
-import Name            ( Name, nameModule )
+import TyCon           ( TyCon, isClassTyCon, isSynTyCon, isNewTyCon,
+                         tyConTyVars, tyConDataCons, getSynTyConDefn )
+import Class           ( Class, classSCTheta, classTvsFds, classMethods )
+import FunDeps         ( pprFundeps )
+import DataCon         ( DataCon, dataConWrapId, dataConSig, dataConTyCon,
+                         dataConFieldLabels, dataConStrictMarks, 
+                         dataConIsInfix, isVanillaDataCon )
+import Name            ( Name, nameModule, NamedThing(..), nameParent_maybe,
+                         nameSrcLoc )
+import OccName         ( parenSymOcc )
 import NameEnv         ( nameEnvElts )
-import InstEnv         ( Instance )
+import InstEnv         ( Instance, instanceDFunId, pprInstance )
 import SrcLoc
 import DriverPipeline
 import DriverPhases    ( Phase(..), isHaskellSrcFilename, startPhase )
@@ -195,7 +221,7 @@ import Util
 import StringBuffer    ( StringBuffer, hGetStringBuffer )
 import Outputable
 import SysTools                ( cleanTempFilesExcept )
-import BasicTypes      ( SuccessFlag(..), succeeded, failed )
+import BasicTypes
 import TcType           ( tcSplitSigmaTy, isDictTy )
 import FastString      ( mkFastString )
 
@@ -1794,9 +1820,8 @@ moduleIsInterpreted s modl = withSession s $ \h ->
       _not_a_home_module -> return False
 
 -- | Looks up an identifier in the current interactive context (for :info)
-{-# DEPRECATED getInfo "we should be using parseName/lookupName instead" #-}
-getInfo :: Session -> String -> IO [GetInfoResult]
-getInfo s id = withSession s $ \hsc_env -> hscGetInfo hsc_env id
+getInfo :: Session -> Name -> IO (Maybe (TyThing,Fixity,[Instance]))
+getInfo s name = withSession s $ \hsc_env -> tcRnGetInfo hsc_env name
 
 -- | Returns all names in scope in the current interactive context
 getNamesInScope :: Session -> IO [Name]
@@ -1820,12 +1845,17 @@ parseName s str = withSession s $ \hsc_env -> do
 -- | Returns the 'TyThing' for a 'Name'.  The 'Name' may refer to any
 -- entity known to GHC, including 'Name's defined using 'runStmt'.
 lookupName :: Session -> Name -> IO (Maybe TyThing)
-lookupName s name = withSession s $ \hsc_env -> do
-  case lookupTypeEnv (ic_type_env (hsc_IC hsc_env)) name of
-       Just tt -> return (Just tt)
-       Nothing -> do
-           eps <- readIORef (hsc_EPS hsc_env)
-           return $! lookupType (hsc_HPT hsc_env) (eps_PTE eps) name
+lookupName s name = withSession s $ \hsc_env -> tcRnLookupName hsc_env name
+
+-- -----------------------------------------------------------------------------
+-- Misc exported utils
+
+dataConType :: DataCon -> Type
+dataConType dc = idType (dataConWrapId dc)
+
+-- | print a 'NamedThing', adding parentheses if the name is an operator.
+pprParenSymName :: NamedThing a => a -> SDoc
+pprParenSymName a = parenSymOcc (getOccName a) (ppr (getName a))
 
 -- -----------------------------------------------------------------------------
 -- Getting the type of an expression
@@ -1948,18 +1978,6 @@ foreign import "rts_evalStableIO"  {- safe -}
   -- more informative than the C type!
 -}
 
--- ---------------------------------------------------------------------------
--- cmBrowseModule: get all the TyThings defined in a module
-
-{-# DEPRECATED browseModule "we should be using getModuleInfo instead" #-}
-browseModule :: Session -> Module -> Bool -> IO [IfaceDecl]
-browseModule s modl exports_only = withSession s $ \hsc_env -> do
-  mb_decls <- getModuleContents hsc_env modl exports_only
-  case mb_decls of
-       Nothing -> return []            -- An error of some kind
-       Just ds -> return ds
-
-
 -----------------------------------------------------------------------------
 -- show a module and it's source/object filenames
 
index ab14e17..98c0085 100644 (file)
@@ -12,7 +12,6 @@ module HscMain (
        hscParseIdentifier,
 #ifdef GHCI
        hscStmt, hscTcExpr, hscKcType,
-       hscGetInfo, GetInfoResult,
        compileExpr,
 #endif
        ) where
@@ -28,7 +27,7 @@ import Linker         ( HValue, linkExpr )
 import CoreTidy                ( tidyExpr )
 import CorePrep                ( corePrepExpr )
 import Flattening      ( flattenExpr )
-import TcRnDriver      ( tcRnStmt, tcRnExpr, tcRnGetInfo, GetInfoResult, tcRnType ) 
+import TcRnDriver      ( tcRnStmt, tcRnExpr, tcRnType ) 
 import Type            ( Type )
 import PrelNames       ( iNTERACTIVE )
 import Kind            ( Kind )
@@ -715,34 +714,6 @@ hscParseThing parser dflags str
 
 %************************************************************************
 %*                                                                     *
-\subsection{Getting information about an identifer}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-#ifdef GHCI
-hscGetInfo -- like hscStmt, but deals with a single identifier
-  :: HscEnv
-  -> String                    -- The identifier
-  -> IO [GetInfoResult]
-
-hscGetInfo hsc_env str
-   = do maybe_rdr_name <- hscParseIdentifier (hsc_dflags hsc_env) str
-       case maybe_rdr_name of {
-         Nothing -> return [];
-         Just (L _ rdr_name) -> do
-
-       maybe_tc_result <- tcRnGetInfo hsc_env (hsc_IC hsc_env) rdr_name
-
-       case maybe_tc_result of
-            Nothing     -> return []
-            Just things -> return things
-       }
-#endif
-\end{code}
-
-%************************************************************************
-%*                                                                     *
        Desugar, simplify, convert to bytecode, and link an expression
 %*                                                                     *
 %************************************************************************
diff --git a/ghc/compiler/main/PprTyThing.hs b/ghc/compiler/main/PprTyThing.hs
new file mode 100644 (file)
index 0000000..fc53e72
--- /dev/null
@@ -0,0 +1,211 @@
+-----------------------------------------------------------------------------
+--
+-- Pretty-printing TyThings
+--
+-- (c) The GHC Team 2005
+--
+-----------------------------------------------------------------------------
+
+module PprTyThing (
+       pprTyThing,
+       pprTyThingInContext,
+       pprTyThingLoc,
+       pprTyThingInContextLoc,
+  ) where
+
+#include "HsVersions.h"
+
+import qualified GHC
+import GHC ( TyThing(..), SrcLoc )
+import Outputable
+
+-- -----------------------------------------------------------------------------
+-- Pretty-printing entities that we get from the GHC API
+
+-- This should be a good source of sample code for using the GHC API to
+-- inspect source code entities.
+
+-- | Pretty-prints a 'TyThing' with its defining location.
+pprTyThingLoc :: Bool -> TyThing -> SDoc
+pprTyThingLoc exts tyThing 
+  = showWithLoc loc (pprTyThing exts tyThing)
+  where loc = GHC.nameSrcLoc (GHC.getName tyThing)
+
+-- | Pretty-prints a 'TyThing'.
+pprTyThing :: Bool -> TyThing -> SDoc
+pprTyThing exts (AnId id)          = pprId         exts id
+pprTyThing exts (ADataCon dataCon) = pprDataConSig exts dataCon
+pprTyThing exts (ATyCon tyCon)     = pprTyCon      exts tyCon
+pprTyThing exts (AClass cls)       = pprClass      exts cls
+        
+-- | Like 'pprTyThingInContext', but adds the defining location.
+pprTyThingInContextLoc :: Bool -> TyThing -> SDoc
+pprTyThingInContextLoc exts tyThing 
+  = showWithLoc loc (pprTyThingInContext exts tyThing)
+  where loc = GHC.nameSrcLoc (GHC.getName tyThing)
+
+-- | Pretty-prints a 'TyThing' in context: that is, if the entity
+-- is a data constructor, record selector, or class method, then 
+-- the entity's parent declaration is pretty-printed with irrelevant
+-- parts omitted.
+pprTyThingInContext :: Bool -> TyThing -> SDoc
+pprTyThingInContext exts (AnId id)          = pprIdInContext exts id
+pprTyThingInContext exts (ADataCon dataCon) = pprDataCon exts dataCon
+pprTyThingInContext exts (ATyCon tyCon)     = pprTyCon   exts tyCon
+pprTyThingInContext exts (AClass cls)       = pprClass   exts cls
+        
+pprTyConHdr exts tyCon =
+  ptext keyword <+> ppr_bndr tyCon <+> hsep (map ppr vars)
+  where
+    vars = GHC.tyConTyVars tyCon
+    
+    keyword | GHC.isSynTyCon tyCon = SLIT("type")
+            | GHC.isNewTyCon tyCon = SLIT("newtype")
+            | otherwise            = SLIT("data")
+
+pprDataConSig exts dataCon =
+  ppr_bndr dataCon <+> dcolon <+> pprType exts (GHC.dataConType dataCon)
+
+pprClassHdr exts cls =
+  let (tyVars, funDeps) = GHC.classTvsFds cls
+  in ptext SLIT("class") <+> 
+     GHC.pprThetaArrow (GHC.classSCTheta cls) <+>
+     ppr_bndr cls <+>
+     hsep (map ppr tyVars) <+>
+     GHC.pprFundeps funDeps
+
+pprIdInContext exts id
+  | GHC.isRecordSelector id              = pprRecordSelector exts id
+  | Just cls <- GHC.isClassOpId_maybe id  = pprClassOneMethod exts cls id
+  | otherwise                            = pprId exts id
+
+pprRecordSelector exts id
+  = pprAlgTyCon exts tyCon show_con show_label
+  where
+       (tyCon,label) = GHC.recordSelectorFieldLabel id
+       show_con dataCon  = label `elem` GHC.dataConFieldLabels dataCon
+       show_label label' = label == label'
+
+pprId exts id
+  = hang (ppr_bndr id <+> dcolon) 2 
+       (pprType exts (GHC.idType id))
+
+pprType True  ty = ppr ty
+pprType False ty = ppr (GHC.dropForAlls ty)
+
+pprTyCon exts tyCon
+  | GHC.isSynTyCon tyCon
+  = let (_,rhs_type) = GHC.getSynTyConDefn tyCon
+    in hang (pprTyConHdr exts tyCon <+> equals) 2 (pprType exts rhs_type)
+  | otherwise
+  = pprAlgTyCon exts tyCon (const True) (const True)
+
+pprAlgTyCon exts tyCon ok_con ok_label
+  | gadt      = pprTyConHdr exts tyCon <+> ptext SLIT("where") $$ 
+                  nest 2 (vcat (ppr_trim show_con datacons))
+  | otherwise = hang (pprTyConHdr exts tyCon)
+                  2 (add_bars (ppr_trim show_con datacons))
+  where
+    datacons = GHC.tyConDataCons tyCon
+    gadt = any (not . GHC.isVanillaDataCon) datacons
+
+    show_con dataCon
+      | ok_con dataCon = Just (pprDataConDecl exts gadt ok_label dataCon)
+      | otherwise      = Nothing
+
+pprDataCon exts dataCon = pprAlgTyCon exts tyCon (== dataCon) (const True)
+  where tyCon = GHC.dataConTyCon dataCon
+
+pprDataConDecl exts gadt_style show_label dataCon
+  | not gadt_style = ppr_fields tys_w_strs
+  | otherwise      = ppr_bndr dataCon <+> dcolon <+> 
+                       sep [ ppr_tvs, GHC.pprThetaArrow theta, pp_tau ]
+  where
+    (tyvars, theta, argTypes, tyCon, res_tys) = GHC.dataConSig dataCon
+    labels = GHC.dataConFieldLabels dataCon
+    qualVars = filter (flip notElem (GHC.tyConTyVars tyCon)) tyvars
+    stricts = GHC.dataConStrictMarks dataCon
+    tys_w_strs = zip stricts argTypes
+
+    ppr_tvs 
+       | null qualVars = empty
+       | otherwise     = ptext SLIT("forall") <+> 
+                               hsep (map ppr qualVars) <> dot
+
+       -- printing out the dataCon as a type signature, in GADT style
+    pp_tau = foldr add pp_res_ty tys_w_strs
+    pp_res_ty = ppr_bndr tyCon <+> hsep (map GHC.pprParendType res_tys)
+    add (str,ty) pp_ty = pprBangTy str ty <+> arrow <+> pp_ty
+
+    pprParendBangTy (strict,ty)
+       | GHC.isMarkedStrict strict = char '!' <> GHC.pprParendType ty
+       | otherwise                 = GHC.pprParendType ty
+
+    pprBangTy strict ty
+       | GHC.isMarkedStrict strict = char '!' <> ppr ty
+       | otherwise                 = ppr ty
+
+    maybe_show_label (lbl,(strict,tp))
+       | show_label lbl = Just (ppr lbl <+> dcolon <+> pprBangTy strict tp)
+       | otherwise      = Nothing
+
+    ppr_fields [ty1, ty2]
+       | GHC.dataConIsInfix dataCon && null labels
+       = sep [pprParendBangTy ty1, ppr dataCon, pprParendBangTy ty2]
+    ppr_fields fields
+       | null labels
+       = ppr_bndr dataCon <+> sep (map pprParendBangTy fields)
+       | otherwise
+       = ppr_bndr dataCon <+> 
+               braces (sep (punctuate comma (ppr_trim maybe_show_label 
+                                       (zip labels fields))))
+
+pprClass exts cls
+  | null methods = 
+       pprClassHdr exts cls
+  | otherwise = 
+       hang (pprClassHdr exts cls <+> ptext SLIT("where"))
+           2 (vcat (map (pprClassMethod exts) methods))
+  where
+       methods = GHC.classMethods cls
+
+pprClassOneMethod exts cls this_one = 
+  hang (pprClassHdr exts cls <+> ptext SLIT("where"))
+       2 (vcat (ppr_trim show_meth methods))
+  where
+       methods = GHC.classMethods cls
+       show_meth id | id == this_one = Just (pprClassMethod exts id)
+                    | otherwise      = Nothing
+
+pprClassMethod exts id =
+  hang (ppr_bndr id <+> dcolon) 2 (pprType exts (classOpType id))
+  where
+  -- Here's the magic incantation to strip off the dictionary
+  -- from the class op type.  Stolen from IfaceSyn.tyThingToIfaceDecl.
+  classOpType id = GHC.funResultTy rho_ty
+     where (_sel_tyvars, rho_ty) = GHC.splitForAllTys (GHC.idType id)
+
+ppr_trim :: (a -> Maybe SDoc) -> [a] -> [SDoc]
+ppr_trim show xs
+  = snd (foldr go (False, []) xs)
+  where
+    go x (eliding, so_far)
+       | Just doc <- show x = (False, doc : so_far)
+       | otherwise = if eliding then (True, so_far)
+                                else (True, ptext SLIT("...") : so_far)
+
+add_bars []      = empty
+add_bars [c]     = equals <+> c
+add_bars (c:cs)  = sep ((equals <+> c) : map (char '|' <+>) cs)
+
+-- Wrap operators in ()
+ppr_bndr :: GHC.NamedThing a => a -> SDoc
+ppr_bndr a = GHC.pprParenSymName a
+
+showWithLoc :: SrcLoc -> SDoc -> SDoc
+showWithLoc loc doc 
+    = hang doc 2 (char '\t' <> comment <+> GHC.pprDefnLoc loc)
+               -- The tab tries to make them line up a bit
+  where
+    comment = ptext SLIT("--")
+
index 1295f9c..303d8a6 100644 (file)
@@ -80,6 +80,58 @@ The algorithm is roughly:
 
 -}
 
+{-
+Possible plan for x86 floating pt register alloc:
+
+  - The standard reg alloc procedure allocates pretend floating point
+    registers to the GXXX instructions.  We need to convert these GXXX
+    instructions to proper x86 FXXX instructions, using the FP stack for
+    registers.
+
+    We could do this in a separate pass, but it helps to have the
+    information about which real registers are live after the
+    instruction, so we do it at reg alloc time where that information
+    is already available.
+
+  - keep a mapping from %fakeN to FP stack slot in the monad.
+
+  - after assigning registers to the GXXX instruction, convert the
+    instruction to an FXXX instruction.  eg. 
+       - for GMOV just update the mapping, and ffree any dead regs.
+       - GLD:  just fld and update mapping
+         GLDZ: just fldz and update mapping
+         GLD1: just fld1 and update mapping
+       - GST: just fst and update mapping, ffree dead regs.
+          - special case for GST reg, where reg is st(0), we can fstp.
+       - for GADD fp1, fp2, fp3:
+         - easy way: fld fp2
+                     fld fp1
+                     faddp
+                     -- record that fp3 is now in %st(0), and all other
+                     -- slots are pushed down one.
+                     ffree fp1 -- if fp1 is dead now
+                     ffree fp2 -- if fp2 is dead now
+         - optimisation #1
+           - if fp1 is in %st(0) and is dead afterward
+               fadd %st(0), fp2
+               -- record fp3 is in %st(0)
+               ffree fp2 -- if fp2 is dead now
+           - if fp2 is in %st(0) and is dead afterward
+               fadd %st(0), fp1
+               -- record fp3 is in %st(0)
+           - if fp1 is in %st(0), fp2 is dead afterward
+               fadd fp2, %st(0)
+               -- record fp3 is in fp2's locn
+           - if fp2 is in %st(0), fp1 is dead afterward
+               fadd fp1, %st(0)
+               -- record fp3 is in fp1's locn
+
+  - we should be able to avoid the nasty ffree problems of the current
+    scheme.  The stack should be empty before doing a non-local
+    jump/call - we can assert that this is the case.
+-}
+
+
 module RegisterAlloc (
        regAlloc
   ) where
index 52f3c1b..8e91367 100644 (file)
@@ -6,10 +6,10 @@
 \begin{code}
 module TcRnDriver (
 #ifdef GHCI
-       getModuleContents, tcRnStmt, 
-       tcRnGetInfo, GetInfoResult,
-       tcRnExpr, tcRnType,
+       tcRnStmt, tcRnExpr, tcRnType,
        tcRnLookupRdrName,
+       tcRnLookupName,
+       tcRnGetInfo,
        getModuleExports, 
 #endif
        tcRnModule, 
@@ -102,33 +102,26 @@ import Inst               ( tcGetInstEnvs )
 import InstEnv         ( classInstances, instEnvElts )
 import RnExpr          ( rnStmts, rnLExpr )
 import LoadIface       ( loadSrcInterface, loadSysInterface )
-import IfaceSyn                ( IfaceDecl(..), IfaceClassOp(..), IfaceConDecl(..), 
-                         IfaceExtName(..), IfaceConDecls(..), 
-                         tyThingToIfaceDecl )
-import IfaceType       ( IfaceType, toIfaceType, 
-                         interactiveExtNameFun )
-import IfaceEnv                ( lookupOrig, ifaceExportNames )
-import Module          ( lookupModuleEnv, moduleSetElts, mkModuleSet )
+import IfaceEnv                ( ifaceExportNames )
+import Module          ( moduleSetElts, mkModuleSet )
 import RnEnv           ( lookupOccRn, dataTcOccs, lookupFixityRn )
-import Id              ( isImplicitId, setIdType, globalIdDetails )
+import Id              ( setIdType )
 import MkId            ( unsafeCoerceId )
-import DataCon         ( dataConTyCon )
 import TyCon           ( tyConName )
 import TysWiredIn      ( mkListTy, unitTy )
 import IdInfo          ( GlobalIdDetails(..) )
 import Kind            ( Kind )
 import Var             ( globaliseId )
-import Name            ( nameOccName, nameModule, isBuiltInSyntax, nameParent_maybe )
-import OccName         ( occNameUserString, isTcOcc )
+import Name            ( nameOccName, nameModule, isBuiltInSyntax )
+import OccName         ( isTcOcc )
 import NameEnv         ( delListFromNameEnv )
 import PrelNames       ( iNTERACTIVE, ioTyConName, printName, itName, 
                          bindIOName, thenIOName, returnIOName )
-import HscTypes                ( InteractiveContext(..), HomeModInfo(..), 
-                         availNames, availName, ModIface(..), icPrintUnqual,
+import HscTypes                ( InteractiveContext(..),
+                         ModIface(..), icPrintUnqual,
                          Dependencies(..) )
 import BasicTypes      ( RecFlag(..), Fixity )
-import Panic           ( ghcError, GhcException(..) )
-import SrcLoc          ( SrcLoc, unLoc, noSrcSpan )
+import SrcLoc          ( unLoc, noSrcSpan )
 #endif
 
 import FastString      ( mkFastString )
@@ -1110,85 +1103,18 @@ tcGetModuleExports mod = do
                -- Load any orphan-module interfaces,
                -- so their instances are visible
   ifaceExportNames (mi_exports iface)
-\end{code}
 
-\begin{code}
-getModuleContents
-  :: HscEnv
-  -> Module                    -- Module to inspect
-  -> Bool                      -- Grab just the exports, or the whole toplev
-  -> IO (Maybe [IfaceDecl])
-
-getModuleContents hsc_env mod exports_only
- = initTcPrintErrors hsc_env iNTERACTIVE (get_mod_contents exports_only)
- where
-   get_mod_contents exports_only
-      | not exports_only  -- We want the whole top-level type env
-                         -- so it had better be a home module
-      = do { hpt <- getHpt
-          ; case lookupModuleEnv hpt mod of
-              Just mod_info -> return (map (toIfaceDecl ext_nm) $
-                                       filter wantToSee $
-                                       typeEnvElts $
-                                       md_types (hm_details mod_info))
-              Nothing -> ghcError (ProgramError (showSDoc (noRdrEnvErr mod)))
-                         -- This is a system error; the module should be in the HPT
-          }
-  
-      | otherwise              -- Want the exports only
-      = do { iface <- load_iface mod
-          ; mappM get_decl [ (mod,avail) | (mod, avails) <- mi_exports iface
-                                         , avail <- avails ]
-       }
-
-   get_decl (mod, avail)
-       = do { main_name <- lookupOrig mod (availName avail) 
-            ; thing     <- tcLookupGlobal main_name
-            ; return (filter_decl (availNames avail) (toIfaceDecl ext_nm thing)) }
-
-   ext_nm = interactiveExtNameFun (icPrintUnqual (hsc_IC hsc_env))
-
----------------------
-filter_decl occs decl@(IfaceClass {ifSigs = sigs})
-  = decl { ifSigs = filter (keep_sig occs) sigs }
-filter_decl occs decl@(IfaceData {ifCons = IfDataTyCon cons})
-  = decl { ifCons = IfDataTyCon (filter (keep_con occs) cons) }
-filter_decl occs decl@(IfaceData {ifCons = IfNewTyCon con})
-  | keep_con occs con = decl
-  | otherwise        = decl {ifCons = IfAbstractTyCon} -- Hmm?
-filter_decl occs decl
-  = decl
-
-keep_sig occs (IfaceClassOp occ _ _) = occ `elem` occs
-keep_con occs con                   = ifConOcc con `elem` occs
-
-wantToSee (AnId id)    = not (isImplicitId id)
-wantToSee (ADataCon _) = False -- They'll come via their TyCon
-wantToSee _           = True
-
----------------------
 load_iface mod = loadSrcInterface doc mod False {- Not boot iface -}
               where
                 doc = ptext SLIT("context for compiling statements")
 
----------------------
-noRdrEnvErr mod = ptext SLIT("No top-level environment available for module") 
-                 <+> quotes (ppr mod)
-\end{code}
-
-\begin{code}
-type GetInfoResult = (String, IfaceDecl, Fixity, SrcLoc, 
-                             [(IfaceType,SrcLoc)]      -- Instances
-                    )
 
 tcRnLookupRdrName :: HscEnv -> RdrName -> IO (Maybe [Name])
-
 tcRnLookupRdrName hsc_env rdr_name 
   = initTcPrintErrors hsc_env iNTERACTIVE $ 
     setInteractiveContext hsc_env (hsc_IC hsc_env) $ 
     lookup_rdr_name rdr_name
 
-
 lookup_rdr_name rdr_name = do {
        -- If the identifier is a constructor (begins with an
        -- upper-case letter), then we need to consider both
@@ -1219,10 +1145,16 @@ lookup_rdr_name rdr_name = do {
  }
 
 
+tcRnLookupName :: HscEnv -> Name -> IO (Maybe TyThing)
+tcRnLookupName hsc_env name
+  = initTcPrintErrors hsc_env iNTERACTIVE $ 
+    setInteractiveContext hsc_env (hsc_IC hsc_env) $
+    tcLookupGlobal name
+
+
 tcRnGetInfo :: HscEnv
-           -> InteractiveContext
-           -> RdrName
-           -> IO (Maybe [GetInfoResult])
+           -> Name
+           -> IO (Maybe (TyThing, Fixity, [Instance]))
 
 -- Used to implemnent :info in GHCi
 --
@@ -1231,51 +1163,22 @@ tcRnGetInfo :: HscEnv
 -- but we want to treat it as *both* a data constructor 
 --  *and* as a type or class constructor; 
 -- hence the call to dataTcOccs, and we return up to two results
-tcRnGetInfo hsc_env ictxt rdr_name
+tcRnGetInfo hsc_env name
   = initTcPrintErrors hsc_env iNTERACTIVE $ 
-    setInteractiveContext hsc_env ictxt $ do {
+    let ictxt = hsc_IC hsc_env in
+    setInteractiveContext hsc_env ictxt $ do
 
        -- Load the interface for all unqualified types and classes
        -- That way we will find all the instance declarations
        -- (Packages have not orphan modules, and we assume that
        --  in the home package all relevant modules are loaded.)
-    loadUnqualIfaces ictxt ;
-
-    good_names <- lookup_rdr_name rdr_name ;
-
-       -- And lookup up the entities, avoiding duplicates, which arise
-       -- because constructors and record selectors are represented by
-       -- their parent declaration
-    let { do_one name = do { thing  <- tcLookupGlobal name
-                          ; fixity <- lookupFixityRn name
-                          ; ispecs <- lookupInsts print_unqual thing
-                          ; return (str, toIfaceDecl ext_nm thing, fixity, 
-                                    getSrcLoc thing, 
-                                    [(toIfaceType ext_nm (idType dfun), getSrcLoc dfun) 
-                                    | dfun <- map instanceDFunId ispecs ]
-                            ) } 
-               where
-                       -- str is the the naked occurrence name
-                       -- after stripping off qualification and parens (+)
-                 str = occNameUserString (nameOccName name)
-
-       ; parent_is_there n 
-               | Just p <- nameParent_maybe n = p `elem` good_names
-               | otherwise                    = False
-       } ;
-
-       -- For the SrcLoc, the 'thing' has better info than
-       -- the 'name' because getting the former forced the
-       -- declaration to be loaded into the cache
-
-    mapM do_one (filter (not . parent_is_there) good_names)
-       -- Filter out names whose parent is also there
-       -- Good example is '[]', which is both a type and data constructor
-       -- in the same type
-    }
-  where
-    ext_nm = interactiveExtNameFun print_unqual
-    print_unqual = icPrintUnqual ictxt
+    loadUnqualIfaces ictxt
+
+    thing  <- tcLookupGlobal name
+    fixity <- lookupFixityRn name
+    ispecs <- lookupInsts (icPrintUnqual ictxt) thing
+    return (thing, fixity, ispecs)
+
 
 lookupInsts :: PrintUnqualified -> TyThing -> TcM [Instance]
 -- Filter the instances by the ones whose tycons (or clases resp) 
@@ -1309,18 +1212,6 @@ plausibleDFun print_unqual dfun  -- Dfun involving only names that print unqualif
            | isExternalName name  = print_unqual (nameModule name) (nameOccName name)
            | otherwise            = True
 
-toIfaceDecl :: (Name -> IfaceExtName) -> TyThing -> IfaceDecl
-toIfaceDecl ext_nm thing
-  = tyThingToIfaceDecl ext_nm (munge thing)
-  where
-       -- munge transforms a thing to its "parent" thing
-    munge (ADataCon dc) = ATyCon (dataConTyCon dc)
-    munge (AnId id) = case globalIdDetails id of
-                       RecordSelId tc lbl -> ATyCon tc
-                       ClassOpId cls      -> AClass cls
-                       other              -> AnId id
-    munge other_thing = other_thing
-
 loadUnqualIfaces :: InteractiveContext -> TcM ()
 -- Load the home module for everything that is in scope unqualified
 -- This is so that we can accurately report the instances for 
index ea8b69d..5fc329f 100644 (file)
@@ -314,22 +314,22 @@ newUniqueSupply
 
 \begin{code}
 traceTc, traceRn :: SDoc -> TcRn ()
-traceRn      = dumpOptTcRn Opt_D_dump_rn_trace
-traceTc      = dumpOptTcRn Opt_D_dump_tc_trace
-traceSplice  = dumpOptTcRn Opt_D_dump_splices
+traceRn      = traceOptTcRn Opt_D_dump_rn_trace
+traceTc      = traceOptTcRn Opt_D_dump_tc_trace
+traceSplice  = traceOptTcRn Opt_D_dump_splices
 
 
 traceIf :: SDoc -> TcRnIf m n ()       
-traceIf      = dumpOptIf Opt_D_dump_if_trace
-traceHiDiffs = dumpOptIf Opt_D_dump_hi_diffs
+traceIf      = traceOptIf Opt_D_dump_if_trace
+traceHiDiffs = traceOptIf Opt_D_dump_hi_diffs
 
 
-dumpOptIf :: DynFlag -> SDoc -> TcRnIf m n ()  -- No RdrEnv available, so qualify everything
-dumpOptIf flag doc = ifOptM flag $
+traceOptIf :: DynFlag -> SDoc -> TcRnIf m n ()  -- No RdrEnv available, so qualify everything
+traceOptIf flag doc = ifOptM flag $
                     ioToIOEnv (printForUser stderr alwaysQualify doc)
 
-dumpOptTcRn :: DynFlag -> SDoc -> TcRn ()
-dumpOptTcRn flag doc = ifOptM flag $ do
+traceOptTcRn :: DynFlag -> SDoc -> TcRn ()
+traceOptTcRn flag doc = ifOptM flag $ do
                        { ctxt <- getErrCtxt
                        ; loc  <- getSrcSpanM
                        ; ctxt_msgs <- do_ctxt emptyTidyEnv ctxt 
@@ -339,6 +339,9 @@ dumpOptTcRn flag doc = ifOptM flag $ do
 dumpTcRn :: SDoc -> TcRn ()
 dumpTcRn doc = do { rdr_env <- getGlobalRdrEnv ;
                    ioToTcRn (printForUser stderr (unQualInScope rdr_env) doc) }
+
+dumpOptTcRn :: DynFlag -> SDoc -> TcRn ()
+dumpOptTcRn flag doc = ifOptM flag (dumpTcRn doc)
 \end{code}
 
 
index 3385adc..016ce1b 100644 (file)
@@ -9,7 +9,7 @@ module Class (
        DefMeth (..),
 
        mkClass, classTyVars, classArity,
-       classKey, className, classSelIds, classTyCon,
+       classKey, className, classSelIds, classTyCon, classMethods,
        classBigSig, classExtraBigSig, classTvsFds, classSCTheta
     ) where
 
@@ -100,8 +100,13 @@ classArity :: Class -> Arity
 classArity clas = length (classTyVars clas)
        -- Could memoise this
 
-classSelIds (Class {classSCSels = sc_sels, classOpStuff = op_stuff})
-  = sc_sels ++ [op_sel | (op_sel, _) <- op_stuff]
+classSelIds :: Class -> [Id]
+classSelIds c@(Class {classSCSels = sc_sels})
+  = sc_sels ++ classMethods c
+
+classMethods :: Class -> [Id]
+classMethods (Class {classOpStuff = op_stuff})
+  = [op_sel | (op_sel, _) <- op_stuff]
 
 classTvsFds c
   = (classTyVars c, classFunDeps c)
index 2ed8309..03d65a0 100644 (file)
@@ -155,7 +155,7 @@ pprInstance :: Instance -> SDoc
 pprInstance ispec@(Instance { is_flag = flag })
   = hang (ptext SLIT("instance") <+> ppr flag
          <+> sep [pprThetaArrow theta, pprClassPred clas tys])
-       2 (parens (pprDefnLoc (getSrcLoc ispec)))
+       2 (ptext SLIT("--") <+> (pprDefnLoc (getSrcLoc ispec)))
   where
     (_, theta, clas, tys) = instanceHead ispec
        -- Print without the for-all, which the programmer doesn't write