[project @ 2000-05-09 13:15:37 by simonpj]
[ghc-hetmet.git] / ghc / compiler / rename / RnEnv.lhs
index a4fad13..118267f 100644 (file)
@@ -21,7 +21,8 @@ import HsTypes                ( getTyVarName, replaceTyVarName )
 import RnMonad
 import Name            ( Name, Provenance(..), ExportFlag(..), NamedThing(..),
                          ImportReason(..), getSrcLoc, 
-                         mkLocalName, mkImportedLocalName, mkGlobalName, isSystemName,
+                         mkLocalName, mkImportedLocalName, mkGlobalName, mkUnboundName,
+                         mkIPName, isSystemName, isWiredInName,
                          nameOccName, setNameModule, nameModule,
                          pprOccName, isLocallyDefined, nameUnique, nameOccName,
                           occNameUserString,
@@ -34,7 +35,7 @@ import OccName                ( OccName,
                        )
 import TysWiredIn      ( tupleTyCon, unboxedTupleTyCon, listTyCon )
 import Type            ( funTyCon )
-import Module          ( ModuleName, mkThisModule, mkVanillaModule, moduleName )
+import Module          ( ModuleName, mkThisModule, moduleName, mkVanillaModule )
 import TyCon           ( TyCon )
 import FiniteMap
 import Unique          ( Unique, Uniquable(..) )
@@ -56,43 +57,128 @@ import Maybes              ( mapMaybe )
 %*********************************************************
 
 \begin{code}
-newImportedGlobalName mod_name occ mod
-  = getNameSupplyRn            `thenRn` \ (us, inst_ns, cache) ->
+newLocalTopBinder :: Module -> OccName 
+              -> (Name -> ExportFlag) -> SrcLoc
+              -> RnM d Name
+newLocalTopBinder mod occ rec_exp_fn loc
+  = newTopBinder mod occ (\name -> setNameProvenance name (LocalDef loc (rec_exp_fn name)))
+       -- We must set the provenance of the thing in the cache
+       -- correctly, particularly whether or not it is locally defined.
+       --
+       -- Since newLocalTopBinder is used only
+       -- at binding occurrences, we may as well get the provenance
+       -- dead right first time; hence the rec_exp_fn passed in
+
+newImportedBinder :: Module -> RdrName -> RnM d Name
+newImportedBinder mod rdr_name
+  = ASSERT2( isUnqual rdr_name, ppr rdr_name )
+    newTopBinder mod (rdrNameOcc rdr_name) (\name -> name)
+       -- Provenance is already implicitImportProvenance
+
+implicitImportProvenance = NonLocalDef ImplicitImport False
+
+newTopBinder :: Module -> OccName -> (Name -> Name) -> RnM d Name
+newTopBinder mod occ set_prov
+  =    -- First check the cache
+    getNameSupplyRn            `thenRn` \ (us, inst_ns, cache, ipcache) ->
+    let 
+       key          = (moduleName mod, occ)
+    in
+    case lookupFM cache key of
+
+       -- A hit in the cache! 
+       -- Set the Module of the thing, and set its provenance (hack pending 
+       --      spj update)
+       --
+       -- It also means that if there are two defns for the same thing
+       -- in a module, then each gets a separate SrcLoc
+       --
+       -- There's a complication for wired-in names.  We don't want to
+       -- forget that they are wired in even when compiling that module
+       -- (else we spit out redundant defns into the interface file)
+       -- So for them we just set the provenance
+
+       Just name -> let 
+                       new_name  = set_prov (setNameModule name mod)
+                       new_cache = addToFM cache key new_name
+                    in
+                    setNameSupplyRn (us, inst_ns, new_cache, ipcache)  `thenRn_`
+                    returnRn new_name
+                    
+       -- Miss in the cache!
+       -- Build a completely new Name, and put it in the cache
+       Nothing -> let
+                       (us', us1) = splitUniqSupply us
+                       uniq       = uniqFromSupply us1
+                       new_name   = set_prov (mkGlobalName uniq mod occ implicitImportProvenance)
+                       new_cache  = addToFM cache key new_name
+                  in
+                  setNameSupplyRn (us', inst_ns, new_cache, ipcache)   `thenRn_`
+                  returnRn new_name
+
+
+mkImportedGlobalName :: ModuleName -> OccName -> RnM d Name
+  -- Used for *occurrences*.  We make a place-holder Name, really just
+  -- to agree on its unique, which gets overwritten when we read in
+  -- the binding occurence later (newImportedBinder)
+  -- The place-holder Name doesn't have the right Provenance, and its
+  -- Module won't have the right Package either
+  --
+  -- This means that a renamed program may have incorrect info
+  -- on implicitly-imported occurrences, but the correct info on the 
+  -- *binding* declaration. It's the type checker that propagates the 
+  -- correct information to all the occurrences.
+  -- Since implicitly-imported names never occur in error messages,
+  -- it doesn't matter that we get the correct info in place till later,
+  -- (but since it affects DLL-ery it does matter that we get it right
+  --  in the end).
+mkImportedGlobalName mod_name occ
+  = getNameSupplyRn            `thenRn` \ (us, inst_ns, cache, ipcache) ->
     let
        key = (mod_name, occ)
     in
     case lookupFM cache key of
        Just name -> returnRn name
-       Nothing   -> setNameSupplyRn (us', inst_ns, new_cache)  `thenRn_`
+       Nothing   -> setNameSupplyRn (us', inst_ns, new_cache, ipcache) `thenRn_`
                     returnRn name
                  where
                     (us', us1) = splitUniqSupply us
                     uniq       = uniqFromSupply us1
-                    name       = mkGlobalName uniq mod occ (NonLocalDef ImplicitImport False)
+                    mod        = mkVanillaModule mod_name
+                    name       = mkGlobalName uniq mod occ implicitImportProvenance
                     new_cache  = addToFM cache key name
 
 updateProvenances :: [Name] -> RnM d ()
+-- Update the provenances of everything that is in scope.
+-- We must be careful not to disturb the Module package info
+-- already in the cache.  Why not?  Consider
+--   module A          module M( f )
+--     import M( f )     import N( f)
+--     import N
+-- So f is defined in N, and M re-exports it.
+-- When processing module A:
+--     1. We read M.hi first, and make a vanilla name N.f 
+--        (without reading N.hi). The package info says <THIS> 
+--        for lack of anything better.  
+--     2. Now we read N, which update the cache to record 
+--        the correct package for N.f.
+--     3. Finally we update provenances (once we've read all imports).
+-- Step 3 must not destroy package info recorded in Step 2.
+
 updateProvenances names
-  = getNameSupplyRn            `thenRn` \ (us, inst_ns, cache) ->
-    setNameSupplyRn (us, inst_ns, update cache names)
+  = getNameSupplyRn            `thenRn` \ (us, inst_ns, cache, ipcache) ->
+    setNameSupplyRn (us, inst_ns, foldr update cache names, ipcache)
   where
-    update cache []          = cache
-    update cache (name:names) = WARN( not (key `elemFM` cache), ppr name )
-                               update (addToFM cache key name) names
-                             where
-                               key = (moduleName (nameModule name), nameOccName name)
+    update name cache = addToFM_C update_prov cache key name
+                     where
+                       key = (moduleName (nameModule name), nameOccName name)
 
-newImportedBinder :: Module -> RdrName -> RnM d Name
-newImportedBinder mod rdr_name
-  = ASSERT2( isUnqual rdr_name, ppr rdr_name )
-    newImportedGlobalName (moduleName mod) (rdrNameOcc rdr_name) mod
+    update_prov name_in_cache name_with_prov
+       = setNameProvenance name_in_cache (getNameProvenance name_with_prov)
+                       
 
--- Make an imported global name, checking first to see if it's in the cache
-mkImportedGlobalName :: ModuleName -> OccName -> RnM d Name
-mkImportedGlobalName mod_name occ
-  = lookupModuleRn mod_name `thenRn` \ mod ->
-    newImportedGlobalName mod_name occ mod --(mkVanillaModule mod_name)
-       
+
+mkImportedGlobalFromRdrName :: RdrName -> RnM d Name 
 mkImportedGlobalFromRdrName rdr_name
   | isQual rdr_name
   = mkImportedGlobalName (rdrNameModule rdr_name) (rdrNameOcc rdr_name)
@@ -105,48 +191,18 @@ mkImportedGlobalFromRdrName rdr_name
     mkImportedGlobalName mod_name (rdrNameOcc rdr_name)
 
 
-newLocalTopBinder :: Module -> OccName 
-              -> (Name -> ExportFlag) -> SrcLoc
-              -> RnM d Name
-newLocalTopBinder mod occ rec_exp_fn loc
-  =    -- First check the cache
-    getNameSupplyRn            `thenRn` \ (us, inst_ns, cache) ->
-    let 
-       key          = (moduleName mod,occ)
-       mk_prov name = LocalDef loc (rec_exp_fn name)
-       -- We must set the provenance of the thing in the cache
-       -- correctly, particularly whether or not it is locally defined.
-       --
-       -- Since newLocallyDefinedGlobalName is used only
-       -- at binding occurrences, we may as well get the provenance
-       -- dead right first time; hence the rec_exp_fn passed in
-    in
-    case lookupFM cache key of
-
-       -- A hit in the cache!
-       -- Overwrite whatever provenance is in the cache already; 
-       -- this updates WiredIn things and known-key things, 
-       -- which are there from the start, to LocalDef.
-       --
-       -- It also means that if there are two defns for the same thing
-       -- in a module, then each gets a separate SrcLoc
-       Just name -> let 
-                       new_name = setNameProvenance name (mk_prov new_name)
-                       new_cache = addToFM cache key new_name
-                    in
-                    setNameSupplyRn (us, inst_ns, new_cache)           `thenRn_`
-                    returnRn new_name
-                    
-       -- Miss in the cache!
-       -- Build a new original name, and put it in the cache
-       Nothing -> let
-                       (us', us1) = splitUniqSupply us
-                       uniq       = uniqFromSupply us1
-                       new_name   = mkGlobalName uniq mod occ (mk_prov new_name)
-                       new_cache  = addToFM cache key new_name
-                  in
-                  setNameSupplyRn (us', inst_ns, new_cache)            `thenRn_`
-                  returnRn new_name
+getIPName rdr_name
+  = getNameSupplyRn            `thenRn` \ (us, inst_ns, cache, ipcache) ->
+    case lookupFM ipcache key of
+       Just name -> returnRn name
+       Nothing   -> setNameSupplyRn (us', inst_ns, cache, new_ipcache) `thenRn_`
+                    returnRn name
+                 where
+                    (us', us1)  = splitUniqSupply us
+                    uniq        = uniqFromSupply us1
+                    name        = mkIPName uniq key
+                    new_ipcache = addToFM ipcache key name
+    where key = (rdrNameOcc rdr_name)
 \end{code}
 
 %*********************************************************
@@ -214,7 +270,7 @@ bindLocatedLocalsRn doc_str rdr_names_w_loc enclosed_scope
        returnRn ()
     )                                  `thenRn_`
        
-    getNameSupplyRn            `thenRn` \ (us, inst_ns, cache) ->
+    getNameSupplyRn            `thenRn` \ (us, inst_ns, cache, ipcache) ->
     getModeRn                  `thenRn` \ mode ->
     let
        n          = length rdr_names_w_loc
@@ -229,7 +285,7 @@ bindLocatedLocalsRn doc_str rdr_names_w_loc enclosed_scope
                     -- Keep track of whether the name originally came from 
                     -- an interface file.
     in
-    setNameSupplyRn (us', inst_ns, cache)      `thenRn_`
+    setNameSupplyRn (us', inst_ns, cache, ipcache)     `thenRn_`
 
     let
        new_name_env = addListToRdrEnv name_env (map fst rdr_names_w_loc `zip` names)
@@ -254,13 +310,13 @@ bindCoreLocalFVRn :: RdrName -> (Name -> RnMS (a, FreeVars))
 bindCoreLocalFVRn rdr_name enclosed_scope
   = getSrcLocRn                `thenRn` \ loc ->
     getLocalNameEnv            `thenRn` \ name_env ->
-    getNameSupplyRn            `thenRn` \ (us, inst_ns, cache) ->
+    getNameSupplyRn            `thenRn` \ (us, inst_ns, cache, ipcache) ->
     let
        (us', us1) = splitUniqSupply us
        uniq       = uniqFromSupply us1
        name       = mkImportedLocalName uniq (rdrNameOcc rdr_name) loc
     in
-    setNameSupplyRn (us', inst_ns, cache)      `thenRn_`
+    setNameSupplyRn (us', inst_ns, cache, ipcache)     `thenRn_`
     let
        new_name_env = extendRdrEnv name_env rdr_name name
     in
@@ -574,7 +630,7 @@ mkExportAvails mod_name unqual_imp name_env avails
 
 plusExportAvails ::  ExportAvails ->  ExportAvails ->  ExportAvails
 plusExportAvails (m1, e1) (m2, e2)
-  = (plusFM_C (++) m1 m2, plusUFM_C plusAvail e1 e2)
+  = (plusFM_C (++) m1 m2, plusAvailEnv e1 e2)
        -- ToDo: wasteful: we do this once for each constructor!
 \end{code}
 
@@ -583,12 +639,24 @@ plusExportAvails (m1, e1) (m2, e2)
 
 \begin{code}
 plusAvail (Avail n1)      (Avail n2)       = Avail n1
-plusAvail (AvailTC n1 ns1) (AvailTC n2 ns2) = AvailTC n1 (nub (ns1 ++ ns2))
+plusAvail (AvailTC n1 ns1) (AvailTC n2 ns2) = AvailTC n2 (nub (ns1 ++ ns2))
 -- Added SOF 4/97
 #ifdef DEBUG
 plusAvail a1 a2 = pprPanic "RnEnv.plusAvail" (hsep [pprAvail a1,pprAvail a2])
 #endif
 
+addAvail :: AvailEnv -> AvailInfo -> AvailEnv
+addAvail avails avail = addToNameEnv_C plusAvail avails (availName avail) avail
+
+emptyAvailEnv = emptyNameEnv
+unitAvailEnv :: AvailInfo -> AvailEnv
+unitAvailEnv a = unitNameEnv (availName a) a
+
+plusAvailEnv :: AvailEnv -> AvailEnv -> AvailEnv
+plusAvailEnv = plusNameEnv_C plusAvail
+
+availEnvElts = nameEnvElts
+
 addAvailToNameSet :: NameSet -> AvailInfo -> NameSet
 addAvailToNameSet names avail = addListToNameSet names (availNames avail)
 
@@ -603,6 +671,10 @@ availNames :: AvailInfo -> [Name]
 availNames (Avail n)      = [n]
 availNames (AvailTC n ns) = ns
 
+addSysAvails :: AvailInfo -> [Name] -> AvailInfo
+addSysAvails avail          []  = avail
+addSysAvails (AvailTC n ns) sys = AvailTC n (sys ++ ns)
+
 filterAvail :: RdrNameIE       -- Wanted
            -> AvailInfo        -- Available
            -> Maybe AvailInfo  -- Resulting available; 
@@ -631,24 +703,19 @@ filterAvail (IEVar v)      avail@(AvailTC n ns) = Just (AvailTC n (filter wanted
        --      import A( op ) 
        -- where op is a class operation
 
-filterAvail (IEThingAll _) avail@(AvailTC _ _)  = Just avail
+filterAvail (IEThingAll _) avail@(AvailTC _ _)   = Just avail
+       -- We don't complain even if the IE says T(..), but
+       -- no constrs/class ops of T are available
+       -- Instead that's caught with a warning by the caller
 
 filterAvail ie avail = Nothing
 
+pprAvail :: AvailInfo -> SDoc
+pprAvail (AvailTC n ns) = ppr n <> case filter (/= n) ns of
+                                       []  -> empty
+                                       ns' -> parens (hsep (punctuate comma (map ppr ns')))
 
--- In interfaces, pprAvail gets given the OccName of the "host" thing
-pprAvail avail = getPprStyle $ \ sty ->
-                if ifaceStyle sty then
-                   ppr_avail (pprOccName . nameOccName) avail
-                else
-                   ppr_avail ppr avail
-
-ppr_avail pp_name (AvailTC n ns) = hsep [
-                                    pp_name n,
-                                    parens  $ hsep $ punctuate comma $
-                                    map pp_name ns
-                                  ]
-ppr_avail pp_name (Avail n) = pp_name n
+pprAvail (Avail n) = ppr n
 \end{code}
 
 
@@ -694,18 +761,19 @@ mapFvRn f xs = mapRn f xs `thenRn` \ stuff ->
 %************************************************************************
 
 
+
 \begin{code}
-warnUnusedLocalBinds, warnUnusedTopNames, warnUnusedMatches :: [Name] -> RnM d ()
+warnUnusedLocalBinds, warnUnusedImports, warnUnusedMatches :: [Name] -> RnM d ()
 
-warnUnusedTopNames names
-  | not opt_WarnUnusedBinds && not opt_WarnUnusedImports
-  = returnRn ()        -- Don't force ns unless necessary
+warnUnusedImports names
+  | not opt_WarnUnusedImports
+  = returnRn ()        -- Don't force names unless necessary
   | otherwise
-  = warnUnusedBinds (\ is_local -> not is_local) names
+  = warnUnusedBinds (const True) names
 
 warnUnusedLocalBinds ns
   | not opt_WarnUnusedBinds = returnRn ()
-  | otherwise              = warnUnusedBinds (\ is_local -> is_local) ns
+  | otherwise              = warnUnusedBinds (const True) ns
 
 warnUnusedMatches names
   | opt_WarnUnusedMatches = warnUnusedGroup (const True) names
@@ -731,6 +799,12 @@ warnUnusedBinds warn_when_local names
 
 -------------------------
 
+--     NOTE: the function passed to warnUnusedGroup is
+--     now always (const True) so we should be able to
+--     simplify the code slightly.  I'm leaving it there
+--     for now just in case I havn't realised why it was there.
+--     Looks highly bogus to me.  SLPJ Dec 99
+
 warnUnusedGroup :: (Bool -> Bool) -> [Name] -> RnM d ()
 warnUnusedGroup emit_warning names
   | null filtered_names         = returnRn ()