[project @ 1999-03-02 14:22:43 by sof]
[ghc-hetmet.git] / ghc / compiler / basicTypes / Name.lhs
index 7304c35..c895f18 100644 (file)
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 \section[Name]{@Name@: to transmit name info from renamer to typechecker}
 
 \begin{code}
-#include "HsVersions.h"
-
 module Name (
-       -- The Module type
-       SYN_IE(Module),
-       pprModule, moduleString,
-
-       -- The OccName type
-       OccName(..),
-       pprOccName, occNameString, occNameFlavour, 
-       isTvOcc, isTCOcc, isVarOcc, prefixOccName,
-       quoteInText, parenInCode,
+       -- Re-export the OccName stuff
+       module OccName,
 
        -- The Name type
        Name,                                   -- Abstract
-       mkLocalName, mkSysLocalName, 
-
-       mkCompoundName, mkGlobalName, mkInstDeclName,
-
+       mkLocalName, mkSysLocalName, mkTopName,
+       mkDerivedName, mkGlobalName,
        mkWiredInIdName,   mkWiredInTyConName,
        maybeWiredInIdName, maybeWiredInTyConName,
        isWiredInName,
 
-       nameUnique, changeUnique, setNameProvenance, getNameProvenance,
-       setNameVisibility,
-       nameOccName, nameString, nameModule,
+       nameUnique, setNameUnique, setNameProvenance, getNameProvenance, setNameImportReason,
+       tidyTopName, 
+       nameOccName, nameModule, setNameOcc, nameRdrName, setNameModule,
 
        isExportedName, nameSrcLoc,
        isLocallyDefinedName,
 
-       isLocalName, 
-
-        pprNameProvenance,
+       isSystemName, isLocalName, isGlobalName, isExternallyVisibleName,
 
-       -- Sets of Names
-       SYN_IE(NameSet),
-       emptyNameSet, unitNameSet, mkNameSet, unionNameSets, unionManyNameSets,
-       minusNameSet, elemNameSet, nameSetToList, addListToNameSet, isEmptyNameSet,
 
-       -- Misc
-       DefnInfo(..),
-       Provenance(..), pprProvenance,
-       ExportFlag(..),
+       -- Provenance
+       Provenance(..), ImportReason(..), pprProvenance,
+       ExportFlag(..), PrintUnqualified,
+        pprNameProvenance, systemProvenance,
 
        -- Class NamedThing and overloaded friends
        NamedThing(..),
-       modAndOcc, isExported, 
+       isExported, 
        getSrcLoc, isLocallyDefined, getOccString
     ) where
 
-IMP_Ubiq()
-import TyLoop          --( GenId, Id(..), TyCon )                      -- Used inside Names
-import CStrings                ( identToC, modnameToC, cSEP )
-import CmdLineOpts     ( opt_OmitInterfacePragmas, opt_EnsureSplittableC )
-
-import Outputable      ( Outputable(..) )
-import PprStyle                ( PprStyle(..), codeStyle, ifaceStyle )
-import PrelMods                ( gHC__ )
-import Pretty
-import Lex             ( isLexSym, isLexConId )
-import SrcLoc          ( noSrcLoc, SrcLoc )
-import Usage            ( SYN_IE(UVar), SYN_IE(Usage) )
-import Unique          ( pprUnique, showUnique, Unique )
-import UniqSet         ( UniqSet(..), emptyUniqSet, unitUniqSet, unionUniqSets, uniqSetToList, isEmptyUniqSet,
-                         unionManyUniqSets, minusUniqSet, mkUniqSet, elementOfUniqSet, addListToUniqSet )
-import UniqFM          ( UniqFM, SYN_IE(Uniquable) )
-import Util            --( cmpPString, panic, assertPanic {-, pprTrace ToDo:rm-} )
+#include "HsVersions.h"
+
+import {-# SOURCE #-} Var   ( Id, setIdName )
+import {-# SOURCE #-} TyCon ( TyCon, setTyConName )
+
+import OccName         -- All of it
+import Module
+import RdrName         ( RdrName, mkRdrQual, mkRdrUnqual )
+import CmdLineOpts     ( opt_PprStyle_NoPrags, opt_OmitInterfacePragmas, opt_EnsureSplittableC )
 
+import SrcLoc          ( noSrcLoc, mkBuiltinSrcLoc, SrcLoc )
+import Unique          ( pprUnique, Unique, Uniquable(..) )
+import Outputable
+import GlaExts
 \end{code}
 
 
 %************************************************************************
 %*                                                                     *
-\subsection[Name-pieces-datatypes]{The @Module@, @OccName@ datatypes}
+\subsection[Name-datatype]{The @Name@ datatype, and name construction}
 %*                                                                     *
 %************************************************************************
-
 \begin{code}
-type Module   = FAST_STRING
+data Name = Name {
+               n_sort :: NameSort,     -- What sort of name it is
+               n_uniq :: Unique,
+               n_occ  :: OccName,      -- Its occurrence name
+               n_prov :: Provenance    -- How it was made
+           }
+
+data NameSort
+  = Local
+  | Global Module
+  | WiredInId Module Id
+  | WiredInTyCon Module TyCon
+\end{code}
 
-data OccName  = VarOcc  FAST_STRING    -- Variables and data constructors
-             | TvOcc   FAST_STRING     -- Type variables
-             | TCOcc   FAST_STRING     -- Type constructors and classes
+Things with a @Global@ name are given C static labels, so they finally
+appear in the .o file's symbol table.  They appear in the symbol table
+in the form M.n.  If originally-local things have this property they
+must be made @Global@ first.
 
-moduleString :: Module -> String
-moduleString mod = _UNPK_ mod
+\begin{code}
+mkLocalName :: Unique -> OccName -> SrcLoc -> Name
+mkLocalName uniq occ loc = Name { n_uniq = uniq, n_sort = Local, n_occ = occ, 
+                                 n_prov = LocalDef loc NotExported }
+       -- NB: You might worry that after lots of huffing and
+       -- puffing we might end up with two local names with distinct
+       -- uniques, but the same OccName.  Indeed we can, but that's ok
+       --      * the insides of the compiler don't care: they use the Unique
+       --      * when printing for -ddump-xxx you can switch on -dppr-debug to get the
+       --        uniques if you get confused
+       --      * for interface files we tidyCore first, which puts the uniques
+       --        into the print name (see setNameVisibility below)
+
+mkGlobalName :: Unique -> Module -> OccName -> Provenance -> Name
+mkGlobalName uniq mod occ prov = Name { n_uniq = uniq, n_sort = Global mod,
+                                       n_occ = occ, n_prov = prov }
+                               
+
+mkSysLocalName :: Unique -> FAST_STRING -> Name
+mkSysLocalName uniq fs = Name { n_uniq = uniq, n_sort = Local, 
+                               n_occ = mkSrcVarOcc fs, n_prov = SystemProv }
+
+mkTopName :: Unique -> Module -> FAST_STRING -> Name
+       -- Make a top-level name; make it Global if top-level
+       -- things should be externally visible; Local otherwise
+       -- This chap is only used *after* the tidyCore phase
+       -- Notably, it is used during STG lambda lifting
+       --
+       -- We have to make sure that the name is globally unique
+       -- and we don't have tidyCore to help us. So we append
+       -- the unique.  Hack!  Hack!
+mkTopName uniq mod fs
+  = Name { n_uniq = uniq, 
+          n_sort = mk_top_sort mod,
+          n_occ  = mkSrcVarOcc (_PK_ ((_UNPK_ fs) ++ show uniq)),
+          n_prov = LocalDef noSrcLoc NotExported }
+
+------------------------- Wired in names -------------------------
+
+mkWiredInIdName :: Unique -> Module -> OccName -> Id -> Name
+mkWiredInIdName uniq mod occ id = Name { n_uniq = uniq, n_sort = WiredInId mod id,
+                                        n_occ = occ, n_prov = SystemProv }
+
+-- mkWiredInTyConName takes a FAST_STRING instead of
+-- an OccName, which is a bit yukky but that's what the 
+-- clients find easiest.
+mkWiredInTyConName :: Unique -> Module -> FAST_STRING -> TyCon -> Name
+mkWiredInTyConName uniq mod fs tycon
+  = Name { n_uniq = uniq, n_sort = WiredInTyCon mod tycon,
+          n_occ = mkSrcOccFS tcName fs, n_prov = SystemProv }
 
-pprModule :: PprStyle -> Module -> Doc
-pprModule sty m = ptext m
 
-pprOccName :: PprStyle -> OccName -> Doc
-pprOccName sty      n = if codeStyle sty 
-                       then identToC (occNameString n)
-                       else ptext (occNameString n)
+---------------------------------------------------------------------
+mkDerivedName :: (OccName -> OccName)
+             -> Name           -- Base name
+             -> Unique         -- New unique
+             -> Name           -- Result is always a value name
 
-occNameString :: OccName -> FAST_STRING
-occNameString (VarOcc s)  = s
-occNameString (TvOcc s)   = s
-occNameString (TCOcc s)   = s
+mkDerivedName f name uniq = name {n_uniq = uniq, n_occ = f (n_occ name)}
 
-prefixOccName :: FAST_STRING -> OccName -> OccName
-prefixOccName prefix (VarOcc s) = VarOcc (prefix _APPEND_ s)
-prefixOccName prefix (TvOcc s)  = TvOcc (prefix _APPEND_ s)
-prefixOccName prefix (TCOcc s) = TCOcc (prefix _APPEND_ s)
+-- When we renumber/rename things, we need to be
+-- able to change a Name's Unique to match the cached
+-- one in the thing it's the name of.  If you know what I mean.
+setNameUnique name uniq = name {n_uniq = uniq}
+
+setNameOcc :: Name -> OccName -> Name
+       -- Give the thing a new OccName, *and*
+       -- record that it's no longer a sys-local
+       -- This is used by the tidy-up pass
+setNameOcc name occ = name {n_occ = occ}
+
+setNameModule :: Name -> Module -> Name
+setNameModule name mod = name {n_sort = set (n_sort name)}
+                      where
+                        set (Global _)             = Global mod
+                        set (WiredInId _ id)       = WiredInId mod id
+                        set (WiredInTyCon _ tycon) = WiredInTyCon mod tycon
+\end{code}
 
--- occNameFlavour is used only to generate good error messages, so it doesn't matter
--- that the VarOcc case isn't mega-efficient.  We could have different Occ constructors for
--- data constructors and values, but that makes everything else a bit more complicated.
-occNameFlavour :: OccName -> String
-occNameFlavour (VarOcc s) | isLexConId s = "data constructor"
-                         | otherwise    = "value"
-occNameFlavour (TvOcc s)  = "type variable"
-occNameFlavour (TCOcc s)  = "type constructor or class"
 
-isVarOcc, isTCOcc, isTvOcc :: OccName -> Bool
-isVarOcc (VarOcc s) = True
-isVarOcc other     = False
+%************************************************************************
+%*                                                                     *
+\subsection{Setting provenance and visibility
+%*                                                                     *
+%************************************************************************
 
-isTvOcc (TvOcc s) = True
-isTvOcc other     = False
+tidyTopName is applied to top-level names in the final program
 
-isTCOcc (TCOcc s) = True
-isTCOcc other     = False
+For top-level things, it globalises Local names 
+                               (if all top-level things should be visible)
+                        and localises non-exported Global names
+                                (if only exported things should be visible)
 
+In all cases except an exported global, it gives it a new occurrence name.
 
-instance Eq OccName where
-    a == b = case (a `cmp` b) of { EQ_ -> True;  _ -> False }
-    a /= b = case (a `cmp` b) of { EQ_ -> False; _ -> True }
+The "visibility" here concerns whether the .o file's symbol table
+mentions the thing; if so, it needs a module name in its symbol.
+The Global things are "visible" and the Local ones are not
 
-instance Ord OccName where
-    a <= b = case (a `cmp` b) of { LT_ -> True;         EQ_ -> True;  GT__ -> False }
-    a <         b = case (a `cmp` b) of { LT_ -> True;  EQ_ -> False; GT__ -> False }
-    a >= b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True;  GT__ -> True  }
-    a >         b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True  }
+Why should things be "visible"?  Certainly they must be if they
+are exported.  But also:
 
-instance Ord3 OccName where
-    cmp = cmpOcc
+(a) In certain (prelude only) modules we split up the .hc file into
+    lots of separate little files, which are separately compiled by the C
+    compiler.  That gives lots of little .o files.  The idea is that if
+    you happen to mention one of them you don't necessarily pull them all
+    in.  (Pulling in a piece you don't need can be v bad, because it may
+    mention other pieces you don't need either, and so on.)
+    
+    Sadly, splitting up .hc files means that local names (like s234) are
+    now globally visible, which can lead to clashes between two .hc
+    files. So unlocaliseWhatnot goes through making all the local things
+    into global things, essentially by giving them full names so when they
+    are printed they'll have their module name too.  Pretty revolting
+    really.
 
-(VarOcc s1) `cmpOcc` (VarOcc s2) = s1 `_CMP_STRING_` s2
-(VarOcc s1) `cmpOcc` other2      = LT_
+(b) When optimisation is on we want to make all the internal
+    top-level defns externally visible
 
-(TvOcc s1)  `cmpOcc` (VarOcc s2) = GT_
-(TvOcc s1)  `cmpOcc` (TvOcc s2)  = s1 `_CMP_STRING_` s2
-(TvOcc s1)  `cmpOcc` other      = LT_
+\begin{code}
+tidyTopName :: Module -> TidyOccEnv -> Name -> (TidyOccEnv, Name)
+tidyTopName mod env name
+  | isExported name = (env, name)      -- Don't fiddle with an exported name
+                                       -- It should be in the TidyOccEnv already
+  | otherwise       = (env', name')
+  where
+    (env', occ') = tidyOccName env (n_occ name)
 
-(TCOcc s1) `cmpOcc` (TCOcc s2) = s1 `_CMP_STRING_` s2
-(TCOcc s1) `cmpOcc` other      = GT_
+    name'        = Name { n_uniq = n_uniq name, n_sort = mk_top_sort mod,
+                         n_occ = occ', n_prov = LocalDef noSrcLoc NotExported }
 
-instance Outputable OccName where
-  ppr = pprOccName
-\end{code}
+mk_top_sort mod | all_toplev_ids_visible = Global mod
+               | otherwise              = Local
 
+all_toplev_ids_visible = 
+       not opt_OmitInterfacePragmas ||  -- Pragmas can make them visible
+       opt_EnsureSplittableC            -- Splitting requires visiblilty
+\end{code}
 
 \begin{code}
-parenInCode, quoteInText :: OccName -> Bool
-parenInCode occ = isLexSym (occNameString occ)
+setNameProvenance :: Name -> Provenance -> Name        
+       -- setNameProvenance used to only change the provenance of 
+       -- Implicit-provenance things, but that gives bad error messages 
+       -- for names defined twice in the same module, so I changed it to 
+       -- set the provenance of *any* global (SLPJ Jun 97)
+setNameProvenance name prov = name {n_prov = prov}
 
-quoteInText occ = not (isLexSym (occNameString occ))
+getNameProvenance :: Name -> Provenance
+getNameProvenance name = n_prov name
+
+setNameImportReason :: Name -> ImportReason -> Name
+setNameImportReason name reason
+  = name { n_prov = new_prov }
+  where
+       -- It's important that we don't do the pattern matching
+       -- in the top-level clause, else we get a black hole in 
+       -- the renamer.  Rather a yukky constraint.  There's only
+       -- one call, in RnNames
+    old_prov = n_prov name
+    new_prov = case old_prov of
+                 NonLocalDef _ omit -> NonLocalDef reason omit
+                 other              -> old_prov
 \end{code}
 
+
 %************************************************************************
 %*                                                                     *
-\subsection[Name-datatype]{The @Name@ datatype, and name construction}
+\subsection{Provenance and export info}
 %*                                                                     *
 %************************************************************************
+
 \begin{code}
-data Name
-  = Local    Unique
-             OccName
-             SrcLoc
-
-  | Global   Unique
-            Module             -- The defining module
-            OccName            -- Its name in that module
-            DefnInfo           -- How it is defined
-             Provenance                -- How it was brought into scope
+data Provenance
+  = LocalDef                   -- Defined locally
+       SrcLoc                  -- Defn site
+       ExportFlag              -- Whether it's exported
+
+  | NonLocalDef                -- Defined non-locally
+       ImportReason
+       PrintUnqualified
+
+  | SystemProv                 -- Either (a) a system-generated local with 
+                               --            a v short name OccName
+                               -- or     (b) a known-key global which should have a proper
+                               --            provenance attached by the renamer
 \end{code}
 
-Things with a @Global@ name are given C static labels, so they finally
-appear in the .o file's symbol table.  They appear in the symbol table
-in the form M.n.  If originally-local things have this property they
-must be made @Global@ first.
+Sys-provs are only used internally.  When the compiler generates (say)
+a fresh desguar variable it always calls it "ds", and of course it gets
+a fresh unique.  But when printing -ddump-xx dumps, we must print it with
+its unique, because there'll be a lot of "ds" variables.
+
+Names with SystemProv differ in the following ways:
+       a) locals have unique attached when printing dumps
+       b) unifier eliminates sys tyvars in favour of user provs where possible
+       c) renamer replaces SystemProv with a better one
+
+Before anything gets printed in interface files or output code, it's
+fed through a 'tidy' processor, which zaps the OccNames to have
+unique names; and converts all sys-locals to user locals
+If any desugarer sys-locals have survived that far, they get changed to
+"ds1", "ds2", etc.
 
 \begin{code}
-data DefnInfo =        VanillaDefn     
-             | WiredInTyCon TyCon      -- There's a wired-in version
-             | WiredInId    Id         -- ...ditto...
+data ImportReason
+  = UserImport Module SrcLoc Bool      -- Imported from module M on line L
+                                       -- Note the M may well not be the defining module
+                                       -- for this thing!
+       -- The Bool is true iff the thing was named *explicitly* in the import spec,
+       -- rather than being imported as part of a group; e.g.
+       --      import B
+       --      import C( T(..) )
+       -- Here, everything imported by B, and the constructors of T
+       -- are not named explicitly; only T is named explicitly.
+       -- This info is used when warning of unused names.
+
+  | ImplicitImport                     -- Imported implicitly for some other reason
+                       
+
+type PrintUnqualified = Bool   -- True <=> the unqualified name of this thing is
+                               -- in scope in this module, so print it 
+                               -- unqualified in error messages
 
-data Provenance
-  = LocalDef ExportFlag SrcLoc -- Locally defined
-  | Imported Module SrcLoc     -- Directly imported from M; gives locn of import statement
-  | Implicit                   -- Implicitly imported
+data ExportFlag = Exported  | NotExported
 \end{code}
 
 Something is "Exported" if it may be mentioned by another module without
@@ -205,7 +312,10 @@ never be dropped as dead code, even if they aren't used in this module.
 Furthermore, being Exported means that we can't see all call sites of the thing.
 
 Exported things include:
-       - explicitly exported Ids, including data constructors, class method selectors
+
+       - explicitly exported Ids, including data constructors, 
+         class method selectors
+
        - dfuns from instance decls
 
 Being Exported is *not* the same as finally appearing in the .o file's 
@@ -213,89 +323,25 @@ symbol table.  For example, a local Id may be mentioned in an Exported
 Id's unfolding in the interface file, in which case the local Id goes
 out too.
 
-\begin{code}
-data ExportFlag = Exported  | NotExported
-\end{code}
 
 \begin{code}
-mkLocalName    :: Unique -> OccName -> SrcLoc -> Name
-mkLocalName = Local
-
-mkGlobalName :: Unique -> Module -> OccName -> DefnInfo -> Provenance -> Name
-mkGlobalName = Global
-
-mkSysLocalName :: Unique -> FAST_STRING -> SrcLoc -> Name
-mkSysLocalName uniq str loc = Local uniq (VarOcc str) loc
-
-mkWiredInIdName :: Unique -> Module -> FAST_STRING -> Id -> Name
-mkWiredInIdName uniq mod occ id 
-  = Global uniq mod (VarOcc occ) (WiredInId id) Implicit
-
-mkWiredInTyConName :: Unique -> Module -> FAST_STRING -> TyCon -> Name
-mkWiredInTyConName uniq mod occ tycon
-  = Global uniq mod (TCOcc occ) (WiredInTyCon tycon) Implicit
-
-
-mkCompoundName :: (FAST_STRING -> FAST_STRING) -- Occurrence-name modifier
-              -> Unique                        -- New unique
-              -> Name                          -- Base name (must be a Global)
-              -> Name          -- Result is always a value name
-
-mkCompoundName str_fn uniq (Global _ mod occ defn prov)
-  = Global uniq mod new_occ defn prov
-  where    
-    new_occ = VarOcc (str_fn (occNameString occ))              -- Always a VarOcc
-
-mkCompoundName str_fn uniq (Local _ occ loc)
-  = Local uniq (VarOcc (str_fn (occNameString occ))) loc
-
-       -- Rather a wierd one that's used for names generated for instance decls
-mkInstDeclName :: Unique -> Module -> OccName -> SrcLoc -> Bool -> Name
-mkInstDeclName uniq mod occ loc from_here
-  = Global uniq mod occ VanillaDefn prov
-  where
-    prov | from_here = LocalDef Exported loc
-         | otherwise = Implicit
-
-
-setNameProvenance :: Name -> Provenance -> Name                -- Implicit Globals only
-setNameProvenance (Global uniq mod occ def Implicit) prov = Global uniq mod occ def prov
-setNameProvenance other_name                        prov = other_name
-
-getNameProvenance :: Name -> Provenance
-getNameProvenance (Global uniq mod occ def prov) = prov
-getNameProvenance (Local uniq occ locn)         = LocalDef NotExported locn
-
--- When we renumber/rename things, we need to be
--- able to change a Name's Unique to match the cached
--- one in the thing it's the name of.  If you know what I mean.
-changeUnique (Local      _ n l)  u = Local u n l
-changeUnique (Global   _ mod occ def prov) u = Global u mod occ def prov
-
-setNameVisibility :: Module -> Name -> Name
--- setNameVisibility is applied to top-level names in the final program
--- The "visibility" here concerns whether the .o file's symbol table
--- mentions the thing; if so, it needs a module name in its symbol,
--- otherwise we just use its unique.  The Global things are "visible"
--- and the local ones are not
-
-setNameVisibility _ (Global uniq mod occ def (LocalDef NotExported loc))
-  | not all_toplev_ids_visible
-  = Local uniq occ loc
-
-setNameVisibility mod (Local uniq occ loc)
-  | all_toplev_ids_visible
-  = Global uniq mod 
-          (VarOcc (showUnique uniq))   -- It's local name must be unique!
-          VanillaDefn (LocalDef NotExported loc)
-
-setNameVisibility mod name = name
-
-all_toplev_ids_visible = not opt_OmitInterfacePragmas ||  -- Pragmas can make them visible
-                        opt_EnsureSplittableC            -- Splitting requires visiblilty
+systemProvenance :: Provenance
+systemProvenance = SystemProv
 
+-- pprNameProvenance is used in error messages to say where a name came from
+pprNameProvenance :: Name -> SDoc
+pprNameProvenance name = pprProvenance (getNameProvenance name)
+
+pprProvenance :: Provenance -> SDoc
+pprProvenance SystemProv            = ptext SLIT("System")
+pprProvenance (LocalDef loc _)       = ptext SLIT("defined at")    <+> ppr loc
+pprProvenance (NonLocalDef ImplicitImport _)
+  = ptext SLIT("implicitly imported")
+pprProvenance (NonLocalDef (UserImport mod loc _) _) 
+  =  ptext SLIT("imported from") <+> ppr mod <+> ptext SLIT("at") <+> ppr loc
 \end{code}
 
+
 %************************************************************************
 %*                                                                     *
 \subsection{Predicates and selectors}
@@ -304,62 +350,77 @@ all_toplev_ids_visible = not opt_OmitInterfacePragmas ||  -- Pragmas can make th
 
 \begin{code}
 nameUnique             :: Name -> Unique
-nameModAndOcc          :: Name -> (Module, OccName)    -- Globals only
 nameOccName            :: Name -> OccName 
 nameModule             :: Name -> Module
-nameString             :: Name -> FAST_STRING          -- A.b form
 nameSrcLoc             :: Name -> SrcLoc
 isLocallyDefinedName   :: Name -> Bool
 isExportedName         :: Name -> Bool
 isWiredInName          :: Name -> Bool
 isLocalName            :: Name -> Bool
+isGlobalName           :: Name -> Bool
+isExternallyVisibleName :: Name -> Bool
 
 
 
-nameUnique (Local  u _ _)   = u
-nameUnique (Global u _ _ _ _) = u
+nameUnique name = n_uniq name
+nameOccName name = n_occ name
 
-nameOccName (Local _ occ _)      = occ
-nameOccName (Global _ _ occ _ _) = occ
+nameModule name =
+  case n_sort name of
+    Local -> pprPanic "nameModule" (ppr name)
+    x     -> nameSortModule x
 
-nameModule (Global _ mod occ _ _) = mod
+nameSortModule (Global       mod)   = mod
+nameSortModule (WiredInId    mod _) = mod
+nameSortModule (WiredInTyCon mod _) = mod
 
-nameModAndOcc (Global _ mod occ _ _) = (mod,occ)
+nameRdrName :: Name -> RdrName
+nameRdrName (Name { n_sort = Local, n_occ = occ }) = mkRdrUnqual occ
+nameRdrName (Name { n_sort = sort,  n_occ = occ }) = mkRdrQual (nameSortModule sort) occ
 
-nameString (Local _ occ _)        = occNameString occ
-nameString (Global _ mod occ _ _) = mod _APPEND_ SLIT(".") _APPEND_ occNameString occ
+isExportedName (Name { n_prov = LocalDef _ Exported }) = True
+isExportedName other                                  = False
 
-isExportedName (Global _ _ _ _ (LocalDef Exported _)) = True
-isExportedName other                                 = False
+nameSrcLoc name = provSrcLoc (n_prov name)
 
-nameSrcLoc (Local _ _ loc)     = loc
-nameSrcLoc (Global _ _ _ _ (LocalDef _ loc)) = loc
-nameSrcLoc (Global _ _ _ _ (Imported _ loc)) = loc
-nameSrcLoc other                            = noSrcLoc
+provSrcLoc (LocalDef loc _)                    = loc        
+provSrcLoc (NonLocalDef (UserImport _ loc _) _) = loc
+provSrcLoc SystemProv                          = noSrcLoc   
   
-isLocallyDefinedName (Local  _ _ _)                 = True
-isLocallyDefinedName (Global _ _ _ _ (LocalDef _ _)) = True
-isLocallyDefinedName other                          = False
+isLocallyDefinedName (Name {n_sort = Local})        = True     -- Local (might have SystemProv)
+isLocallyDefinedName (Name {n_prov = LocalDef _ _}) = True     -- Global, but defined here
+isLocallyDefinedName other                         = False     -- Other
 
 -- Things the compiler "knows about" are in some sense
 -- "imported".  When we are compiling the module where
 -- the entities are defined, we need to be able to pick
 -- them out, often in combination with isLocallyDefined.
-isWiredInName (Global _ _ _ (WiredInTyCon _) _) = True
-isWiredInName (Global _ _ _ (WiredInId    _) _) = True
-isWiredInName _                                          = False
+isWiredInName (Name {n_sort = WiredInTyCon _ _}) = True
+isWiredInName (Name {n_sort = WiredInId    _ _}) = True
+isWiredInName _                                         = False
 
 maybeWiredInIdName :: Name -> Maybe Id
-maybeWiredInIdName (Global _ _ _ (WiredInId id) _) = Just id
-maybeWiredInIdName other                          = Nothing
+maybeWiredInIdName (Name {n_sort = WiredInId _ id}) = Just id
+maybeWiredInIdName other                           = Nothing
 
 maybeWiredInTyConName :: Name -> Maybe TyCon
-maybeWiredInTyConName (Global _ _ _ (WiredInTyCon tc) _) = Just tc
-maybeWiredInTyConName other                             = Nothing
+maybeWiredInTyConName (Name {n_sort = WiredInTyCon _ tc}) = Just tc
+maybeWiredInTyConName other                              = Nothing
+
 
+isLocalName (Name {n_sort = Local}) = True
+isLocalName _                      = False
 
-isLocalName (Local _ _ _) = True
-isLocalName _            = False
+isGlobalName (Name {n_sort = Local}) = False
+isGlobalName other                  = True
+
+-- Global names are by definition those that are visible
+-- outside the module, *as seen by the linker*.  Externally visible
+-- does not mean visible at the source level (that's isExported).
+isExternallyVisibleName name = isGlobalName name
+
+isSystemName (Name {n_prov = SystemProv}) = True
+isSystemName other                       = False
 \end{code}
 
 
@@ -370,37 +431,29 @@ isLocalName _               = False
 %************************************************************************
 
 \begin{code}
-cmpName n1 n2 = c n1 n2
-  where
-    c (Local  u1 _ _)   (Local  u2 _ _)       = cmp u1 u2
-    c (Local   _ _ _)    _                   = LT_
-    c (Global u1 _ _ _ _) (Global u2 _ _ _ _) = cmp u1 u2
-    c (Global  _ _ _ _ _)   _                = GT_
+cmpName n1 n2 = n_uniq n1 `compare` n_uniq n2
 \end{code}
 
 \begin{code}
 instance Eq Name where
-    a == b = case (a `cmp` b) of { EQ_ -> True;  _ -> False }
-    a /= b = case (a `cmp` b) of { EQ_ -> False; _ -> True }
+    a == b = case (a `compare` b) of { EQ -> True;  _ -> False }
+    a /= b = case (a `compare` b) of { EQ -> False; _ -> True }
 
 instance Ord Name where
-    a <= b = case (a `cmp` b) of { LT_ -> True;         EQ_ -> True;  GT__ -> False }
-    a <         b = case (a `cmp` b) of { LT_ -> True;  EQ_ -> False; GT__ -> False }
-    a >= b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True;  GT__ -> True  }
-    a >         b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True  }
-
-instance Ord3 Name where
-    cmp = cmpName
+    a <= b = case (a `compare` b) of { LT -> True;     EQ -> True;  GT -> False }
+    a <         b = case (a `compare` b) of { LT -> True;      EQ -> False; GT -> False }
+    a >= b = case (a `compare` b) of { LT -> False; EQ -> True;  GT -> True  }
+    a >         b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True  }
+    compare a b = cmpName a b
 
 instance Uniquable Name where
-    uniqueOf = nameUnique
+    getUnique = nameUnique
 
 instance NamedThing Name where
     getName n = n
 \end{code}
 
 
-
 %************************************************************************
 %*                                                                     *
 \subsection{Pretty printing}
@@ -409,85 +462,83 @@ instance NamedThing Name where
 
 \begin{code}
 instance Outputable Name where
-    ppr PprQuote name@(Local _ _ _) = quotes (ppr PprForUser name)
-    ppr PprForUser (Local _ n _)    = ptext (occNameString n)
-
-    ppr sty (Local u n _) | codeStyle sty ||
-                           ifaceStyle sty = pprUnique u
-
-    ppr sty  (Local u n _) = hcat [ptext (occNameString n), ptext SLIT("_"), pprUnique u]
-
-    ppr PprQuote name@(Global _ _ _ _ _) = quotes (ppr PprForUser name)
-
-    ppr sty name@(Global u m n _ _)
-       | codeStyle sty
-       = identToC (m _APPEND_ SLIT(".") _APPEND_ occNameString n)
-
-    ppr sty name@(Global u m n _ prov)
-       = hcat [pp_mod, ptext (occNameString n), pp_debug sty name]
-       where
-         pp_mod = case prov of                         --- Omit home module qualifier
-                       LocalDef _ _ -> empty
-                       other        -> pprModule PprForUser m <> char '.'
-
-
-pp_debug PprDebug (Global uniq m n _ prov) = hcat [text "{-", pprUnique uniq, char ',', 
-                                                       pp_prov prov, text "-}"]
-                                       where
-                                               pp_prov (LocalDef Exported _)    = char 'x'
-                                               pp_prov (LocalDef NotExported _) = char 'l'
-                                               pp_prov (Imported _ _) = char 'i'
-                                               pp_prov Implicit       = char 'p'
-pp_debug other    name                         = empty
-
--- pprNameProvenance is used in error messages to say where a name came from
-pprNameProvenance :: PprStyle -> Name -> Doc
-pprNameProvenance sty (Local _ _ loc)       = pprProvenance sty (LocalDef NotExported loc)
-pprNameProvenance sty (Global _ _ _ _ prov) = pprProvenance sty prov
-
-pprProvenance :: PprStyle -> Provenance -> Doc
-pprProvenance sty (Imported mod loc)
-  = sep [ptext SLIT("Imported from"), pprModule sty mod, ptext SLIT("at"), ppr sty loc]
-pprProvenance sty (LocalDef _ loc) 
-  = sep [ptext SLIT("Defined at"), ppr sty loc]
-pprProvenance sty Implicit
-  = panic "pprNameProvenance: Implicit"
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-\subsection[Sets of names}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-type NameSet = UniqSet Name
-emptyNameSet     :: NameSet
-unitNameSet      :: Name -> NameSet
-addListToNameSet  :: NameSet -> [Name] -> NameSet
-mkNameSet         :: [Name] -> NameSet
-unionNameSets    :: NameSet -> NameSet -> NameSet
-unionManyNameSets :: [NameSet] -> NameSet
-minusNameSet     :: NameSet -> NameSet -> NameSet
-elemNameSet      :: Name -> NameSet -> Bool
-nameSetToList    :: NameSet -> [Name]
-isEmptyNameSet   :: NameSet -> Bool
-
-isEmptyNameSet    = isEmptyUniqSet
-emptyNameSet     = emptyUniqSet
-unitNameSet      = unitUniqSet
-mkNameSet         = mkUniqSet
-addListToNameSet  = addListToUniqSet
-unionNameSets     = unionUniqSets
-unionManyNameSets = unionManyUniqSets
-minusNameSet     = minusUniqSet
-elemNameSet       = elementOfUniqSet
-nameSetToList     = uniqSetToList
+       -- When printing interfaces, all Locals have been given nice print-names
+    ppr name = pprName name
+
+pprName (Name {n_sort = Local, n_uniq = uniq, n_occ = occ, n_prov = prov})
+       -- Locals
+  = getPprStyle $ \ sty ->
+    if codeStyle sty then
+       pprUnique uniq          -- When printing in code we required all names to 
+                               -- be globally unique; for example, we use this identifier
+                               -- for the closure name.  So we just print the unique alone.
+    else
+       pprOccName occ <> pp_local_extra sty uniq
+  where
+    sys_local = case prov of
+                 SystemProv -> True
+                 other      -> False
+
+    pp_local_extra sty uniq
+       | sys_local      = underscore <> pprUnique uniq         -- Must print uniques for sys_locals
+       | debugStyle sty = text "{-" <> pprUnique uniq <> text "-}"
+       | otherwise      = empty
+
+
+pprName (Name {n_sort = sort, n_uniq = uniq, n_occ = occ, n_prov = prov})
+       -- Globals, and wired in things
+  = getPprStyle $ \ sty ->
+    if codeStyle sty then
+       ppr mod <> underscore <> ppr occ
+    else
+       pp_mod_dot sty <> ppr occ <> pp_global_debug sty uniq prov
+  where
+    mod = nameSortModule sort
+
+    pp_mod_dot sty
+      = case prov of
+          SystemProv                                -> pp_qual mod  pp_sep    user_sty
+               -- Hack alert!  Omit the qualifier on SystemProv things in user style
+                -- I claim such SystemProv things will also be WiredIn things.
+               -- We can't get the omit flag right
+               -- on wired in tycons etc (sigh) so we just leave it out in user style, 
+               -- and hope that leaving it out isn't too consfusing.
+               -- (e.g. if the programmer hides Bool and  redefines it.  If so, use -dppr-debug.)
+
+          LocalDef _ _                              -> pp_qual mod  dot    (user_sty || iface_sty)
+
+          NonLocalDef (UserImport imp_mod _ _) omit 
+               | user_sty                           -> pp_qual imp_mod pp_sep omit
+               | otherwise                          -> pp_qual mod     pp_sep False
+          NonLocalDef ImplicitImport           omit -> pp_qual mod     pp_sep (user_sty && omit)
+      where
+        user_sty  = userStyle sty
+        iface_sty = ifaceStyle sty
+    
+    pp_qual mod sep omit_qual
+        | omit_qual  = empty
+        | otherwise  = pprModule mod <> sep
+    
+    pp_sep | bootFlavour (moduleIfaceFlavour mod) = text "!"   -- M!t indicates a name imported 
+                                                               -- from a .hi-boot interface
+          | otherwise                            = dot         -- Vanilla case
+   
+    pp_global_debug sty uniq prov
+      | debugStyle sty = hcat [text "{-", pprUnique uniq, prov_p prov, text "-}"]
+      | otherwise      = empty
+
+    prov_p prov | opt_PprStyle_NoPrags = empty
+               | otherwise            = comma <> pp_prov prov
+
+pp_prov (LocalDef _ Exported)          = char 'x'
+pp_prov (LocalDef _ NotExported)       = char 'l'
+pp_prov (NonLocalDef ImplicitImport _) = char 'j'
+pp_prov (NonLocalDef (UserImport _ _ True ) _) = char 'I'      -- Imported by name
+pp_prov (NonLocalDef (UserImport _ _ False) _) = char 'i'      -- Imported by ..
+pp_prov SystemProv                    = char 's'
 \end{code}
 
 
-
 %************************************************************************
 %*                                                                     *
 \subsection{Overloaded functions related to Names}
@@ -496,30 +547,24 @@ nameSetToList     = uniqSetToList
 
 \begin{code}
 class NamedThing a where
-    getOccName :: a -> OccName         -- Even RdrNames can do this!
+    getOccName :: a -> OccName
     getName    :: a -> Name
 
     getOccName n = nameOccName (getName n)     -- Default method
 \end{code}
 
 \begin{code}
-modAndOcc          :: NamedThing a => a -> (Module, OccName)
-getModule          :: NamedThing a => a -> Module
 getSrcLoc          :: NamedThing a => a -> SrcLoc
 isLocallyDefined    :: NamedThing a => a -> Bool
 isExported         :: NamedThing a => a -> Bool
 getOccString       :: NamedThing a => a -> String
 
-modAndOcc          = nameModAndOcc        . getName
-getModule          = nameModule           . getName
 isExported         = isExportedName       . getName
 getSrcLoc          = nameSrcLoc           . getName
 isLocallyDefined    = isLocallyDefinedName . getName
-getOccString x     = _UNPK_ (occNameString (getOccName x))
+getOccString x     = occNameString (getOccName x)
 \end{code}
 
 \begin{code}
-{-# SPECIALIZE isLocallyDefined
-       :: Name     -> Bool
-  #-}
+{-# SPECIALIZE isLocallyDefined :: Name -> Bool #-}
 \end{code}