Make access to NameCache atomic. Sometimes needs a lock.
[ghc-hetmet.git] / compiler / main / HscTypes.lhs
index c1e6f34..962c7a3 100644 (file)
@@ -54,8 +54,9 @@ module HscTypes (
 
         -- * Interactive context
        InteractiveContext(..), emptyInteractiveContext, 
-       icPrintUnqual, mkPrintUnqualified, extendInteractiveContext,
+       icPrintUnqual, extendInteractiveContext,
         substInteractiveContext,
+        mkPrintUnqualified, pprModulePrefix,
 
        -- * Interfaces
        ModIface(..), mkIfaceWarnCache, mkIfaceHashCache, mkIfaceFixCache,
@@ -116,8 +117,6 @@ import RdrName
 import Name
 import NameEnv
 import NameSet 
-import OccName         ( OccName, OccEnv, lookupOccEnv, mkOccEnv, emptyOccEnv, 
-                         extendOccEnv )
 import Module
 import InstEnv         ( InstEnv, Instance )
 import FamInstEnv      ( FamInstEnv, FamInst )
@@ -138,7 +137,7 @@ import Packages hiding ( Version(..) )
 import DynFlags                ( DynFlags(..), isOneShot, HscTarget (..), dopt,
                           DynFlag(..) )
 import DriverPhases    ( HscSource(..), isHsBoot, hscSourceString, Phase )
-import BasicTypes      ( IPName, Fixity, defaultFixity, WarningTxt(..) )
+import BasicTypes      ( IPName, defaultFixity, WarningTxt(..) )
 import OptimizationFuel        ( OptFuelState )
 import IfaceSyn
 import FiniteMap       ( FiniteMap )
@@ -165,6 +164,7 @@ import Data.Array       ( Array, array )
 import Data.List
 import Control.Monad    ( mplus, guard, liftM, when )
 import Exception
+import Control.Concurrent.MVar ( MVar )
 \end{code}
 
 
@@ -545,6 +545,9 @@ data HscEnv
                -- reflect sucking in interface files.  They cache the state of
                -- external interface files, in effect.
 
+        hsc_NC_lock :: !(MVar ()),
+                -- ^ A lock used for updating the name cache.
+
        hsc_FC   :: {-# UNPACK #-} !(IORef FinderCache),
                -- ^ The cached result of performing finding in the file system
        hsc_MLC  :: {-# UNPACK #-} !(IORef ModLocationCache),
@@ -1202,6 +1205,8 @@ substInteractiveContext ictxt@InteractiveContext{ic_tmp_ids=ids} subst =
 %*                                                                     *
 %************************************************************************
 
+Note [Printing original names]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Deciding how to print names is pretty tricky.  We are given a name
 P:M.T, where P is the package name, M is the defining module, and T is
 the occurrence name, and we have to decide in which form to display
@@ -1211,19 +1216,24 @@ Ideally we want to display the name in the form in which it is in
 scope.  However, the name might not be in scope at all, and that's
 where it gets tricky.  Here are the cases:
 
- 1. T   uniquely maps to  P:M.T                         --->  "T"
- 2. there is an X for which X.T uniquely maps to  P:M.T --->  "X.T"
- 3. there is no binding for "M.T"                       --->  "M.T"
- 4. otherwise                                           --->  "P:M.T"
-
-3 and 4 apply when P:M.T is not in scope.  In these cases we want to
-refer to the name as "M.T", but "M.T" might mean something else in the
-current scope (e.g. if there's an "import X as M"), so to avoid
-confusion we avoid using "M.T" if there's already a binding for it.
-
-There's one further subtlety: if the module M cannot be imported
-because it is not exposed by any package, then we must refer to it as
-"P:M".  This is handled by the qual_mod component of PrintUnqualified.
+ 1. T uniquely maps to  P:M.T      --->  "T"      NameUnqual
+ 2. There is an X for which X.T 
+       uniquely maps to  P:M.T     --->  "X.T"    NameQual X
+ 3. There is no binding for "M.T"  --->  "M.T"    NameNotInScope1
+ 4. Otherwise                      --->  "P:M.T"  NameNotInScope2
+
+(3) and (4) apply when the entity P:M.T is not in the GlobalRdrEnv at
+all. In these cases we still want to refer to the name as "M.T", *but*
+"M.T" might mean something else in the current scope (e.g. if there's
+an "import X as M"), so to avoid confusion we avoid using "M.T" if
+there's already a binding for it.  Instead we write P:M.T.
+
+There's one further subtlety: in case (3), what if there are two
+things around, P1:M.T and P2:M.T?  Then we don't want to print both of
+them as M.T!  However only one of the modules P1:M and P2:M can be
+exposed (say P2), so we use M.T for that, and P1:M.T for the other one.
+This is handled by the qual_mod component of PrintUnqualified, inside
+the (ppr mod) of case (3), in Name.pprModulePrefix
 
 \begin{code}
 -- | Creates some functions that work out the best ways to format