[project @ 2000-10-24 09:44:18 by simonpj]
[ghc-hetmet.git] / ghc / compiler / rename / RnEnv.lhs
index 6d212cc..adcdb82 100644 (file)
@@ -8,38 +8,38 @@ module RnEnv where            -- Export everything
 
 #include "HsVersions.h"
 
-import CmdLineOpts     ( opt_WarnNameShadowing, opt_WarnUnusedMatches,
-                         opt_WarnUnusedBinds, opt_WarnUnusedImports )
 import HsSyn
 import RdrHsSyn                ( RdrNameIE )
 import RdrName         ( RdrName, rdrNameModule, rdrNameOcc, isQual, isUnqual,
-                         mkRdrUnqual, qualifyRdrName
+                         mkRdrUnqual, qualifyRdrName, lookupRdrEnv
                        )
-import HsTypes         ( hsTyVarName, hsTyVarNames, replaceTyVarName )
-import HscTypes                ( pprNameProvenance )
+import HsTypes         ( hsTyVarName, replaceTyVarName )
+import HscTypes                ( Provenance(..), pprNameProvenance, hasBetterProv,
+                         ImportReason(..), GlobalRdrEnv, AvailEnv,
+                         AvailInfo, Avails, GenAvailInfo(..), RdrAvailInfo )
 import RnMonad
-import Name            ( Name, Provenance(..), ExportFlag(..), NamedThing(..),
-                         ImportReason(..), getSrcLoc, 
-                         mkLocalName, mkImportedLocalName, mkGlobalName, mkUnboundName,
-                         mkIPName, hasBetterProv, isLocallyDefined, 
-                         nameOccName, setNameModule, nameModule,
-                         extendNameEnv_C, plusNameEnv_C, nameEnvElts
+import Name            ( Name, NamedThing(..),
+                         getSrcLoc, 
+                         mkLocalName, mkImportedLocalName, mkGlobalName,
+                         mkIPName, nameOccName, nameModule,
+                         extendNameEnv_C, plusNameEnv_C, nameEnvElts,
+                         setNameModuleAndLoc
                        )
 import NameSet
 import OccName         ( OccName, occNameUserString, occNameFlavour )
-import Module          ( ModuleName, moduleName, mkVanillaModule, pprModuleName )
+import Module          ( ModuleName, moduleName, mkVanillaModule )
 import FiniteMap
 import Unique          ( Unique )
 import UniqSupply
-import SrcLoc          ( SrcLoc )
+import SrcLoc          ( SrcLoc, noSrcLoc )
 import Outputable
 import ListSetOps      ( removeDups, equivClasses )
-import Util            ( thenCmp, sortLt )
+import Util            ( sortLt )
 import List            ( nub )
+import PrelNames       ( mkUnboundName )
+import CmdLineOpts
 \end{code}
 
-
-
 %*********************************************************
 %*                                                     *
 \subsection{Making new names}
@@ -47,12 +47,10 @@ import List         ( nub )
 %*********************************************************
 
 \begin{code}
-implicitImportProvenance = NonLocalDef ImplicitImport False
-
 newTopBinder :: Module -> RdrName -> SrcLoc -> RnM d Name
 newTopBinder mod rdr_name loc
   =    -- First check the cache
-    traceRn (text "newTopBinder" <+> ppr mod <+> ppr occ) `thenRn_`
+    traceRn (text "newTopBinder" <+> ppr mod <+> ppr loc) `thenRn_`
 
     getNameSupplyRn            `thenRn` \ (us, cache, ipcache) ->
     let 
@@ -170,8 +168,8 @@ lookupTopBndrRn rdr_name
                getModuleRn             `thenRn` \ mod ->
                getGlobalNameEnv        `thenRn` \ global_env ->
                case lookupRdrEnv global_env (qualifyRdrName (moduleName mod) rdr_name) of
-                 Just (name:rest) -> ASSERT( null rest )
-                                     returnRn name 
+                 Just ((name,_):rest) -> ASSERT( null rest )
+                                         returnRn name 
                  Nothing          ->   -- Almost always this case is a compiler bug.
                                        -- But consider a type signature that doesn't have 
                                        -- a corresponding binder: 
@@ -218,12 +216,22 @@ lookupGlobalOccRn rdr_name
     getGlobalNameEnv   `thenRn` \ global_env ->
     case lookupRdrEnv global_env rdr_name of
        Just [(name,_)]  -> returnRn name
-       Just stuff@(_:_) -> addNameClashErrRn rdr_name stuff    `thenRn_`
-                           returnRn name
+       Just stuff@((name,_):_) 
+               -> addNameClashErrRn rdr_name stuff     `thenRn_`
+                          returnRn name
        Nothing ->      -- Not found when processing source code; so fail
                        failWithRn (mkUnboundName rdr_name)
                                   (unknownNameErr rdr_name)
     }
+
+lookupGlobalRn :: GlobalRdrEnv -> RdrName -> RnM d (Maybe Name)
+  -- Checks that there is exactly one
+lookupGlobalRn global_env rdr_name
+  = case lookupRdrEnv global_env rdr_name of
+       Just [(name,_)]         -> returnRn (Just name)
+       Just stuff@((name,_):_) -> addNameClashErrRn rdr_name stuff     `thenRn_`
+                                  returnRn (Just name)
+       Nothing                 -> returnRn Nothing
 \end{code}
 %
 
@@ -315,9 +323,11 @@ bindLocatedLocalsRn doc_str rdr_names_w_loc enclosed_scope
        -- Check for duplicate names
     checkDupOrQualNames doc_str rdr_names_w_loc        `thenRn_`
 
+    doptRn Opt_WarnNameShadowing `thenRn` \ warn_shadow ->
+
        -- Warn about shadowing, but only in source modules
     (case mode of
-       SourceMode | opt_WarnNameShadowing -> mapRn_ (check_shadow name_env) rdr_names_w_loc
+       SourceMode | warn_shadow -> mapRn_ (check_shadow name_env) rdr_names_w_loc
        other                              -> returnRn ()
     )                                  `thenRn_`
        
@@ -507,9 +517,9 @@ combine_globals ns_old ns_new       -- ns_new is often short
 
     (n,pn) `beats` (m,pm) = n==m && pn `hasBetterProv` pm
 
-    is_duplicate :: Provenance -> (Name,Provenance) -> Bool
-    is_duplicate (n1,LocalDef _) (n2,LocalDef _) = False
-    is_duplicate _              _               = n1 == n2
+    is_duplicate :: (Name,Provenance) -> (Name,Provenance) -> Bool
+    is_duplicate (n1,LocalDef) (n2,LocalDef) = False
+    is_duplicate (n1,_)        (n2,_)       = n1 == n2
 \end{code}
 
 We treat two bindings of a locally-defined name as a duplicate,
@@ -581,16 +591,19 @@ availNames :: GenAvailInfo name -> [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)
 
+-------------------------------------
 rdrAvailInfo :: AvailInfo -> RdrAvailInfo
 -- Used when building the avails we are going to put in an interface file
 -- We sort the components to reduce needless wobbling of interfaces
 rdrAvailInfo (Avail n)     = Avail   (nameOccName n)
 rdrAvailInfo (AvailTC n ns) = AvailTC (nameOccName n) (sortLt (<) (map nameOccName ns))
 
+-------------------------------------
 filterAvail :: RdrNameIE       -- Wanted
            -> AvailInfo        -- Available
            -> Maybe AvailInfo  -- Resulting available; 
@@ -626,6 +639,21 @@ filterAvail (IEThingAll _) avail@(AvailTC _ _)   = Just avail
 
 filterAvail ie avail = Nothing
 
+-------------------------------------
+sortAvails :: Avails -> Avails
+sortAvails avails = sortLt lt avails
+  where
+    a1 `lt` a2 = mod1 < mod2 ||
+                (mod1 == mod2 && occ1 < occ2)
+              where
+                name1 = availName a1
+                name2 = availName a2
+                mod1  = nameModule name1
+                mod2  = nameModule name2
+                occ1  = nameOccName name1
+                occ2  = nameOccName name2
+                               
+-------------------------------------
 pprAvail :: AvailInfo -> SDoc
 pprAvail (AvailTC n ns) = ppr n <> case filter (/= n) ns of
                                        []  -> empty
@@ -677,31 +705,32 @@ mapFvRn f xs = mapRn f xs `thenRn` \ stuff ->
 %************************************************************************
 
 \begin{code}
-warnUnusedModules :: [Module] -> RnM d ()
+warnUnusedModules :: [ModuleName] -> RnM d ()
 warnUnusedModules mods
-  | not opt_WarnUnusedImports = returnRn ()
-  | otherwise                = mapRn_ (addWarnRn . unused_mod . moduleName) mods
+  = doptRn Opt_WarnUnusedImports `thenRn` \ warn ->
+    if warn then mapRn_ (addWarnRn . unused_mod) mods
+           else returnRn ()
   where
-    unused_mod m = vcat [ptext SLIT("Module") <+> quotes (pprModuleName m) <+> 
+    unused_mod m = vcat [ptext SLIT("Module") <+> quotes (ppr m) <+> 
                           text "is imported, but nothing from it is used",
                         parens (ptext SLIT("except perhaps to re-export instances visible in") <+>
-                                  quotes (pprModuleName m))]
+                                  quotes (ppr m))]
 
 warnUnusedImports :: [(Name,Provenance)] -> RnM d ()
 warnUnusedImports names
-  | not opt_WarnUnusedImports
-  = returnRn ()        -- Don't force names unless necessary
-  | otherwise
-  = warnUnusedBinds names
+  = doptRn Opt_WarnUnusedImports `thenRn` \ warn ->
+    if warn then warnUnusedBinds names else returnRn ()
 
 warnUnusedLocalBinds, warnUnusedMatches :: [Name] -> RnM d ()
-warnUnusedLocalBinds ns
-  | not opt_WarnUnusedBinds = returnRn ()
-  | otherwise              = warnUnusedBinds [(n,LocalDef) | n<-ns]
+warnUnusedLocalBinds names
+  = doptRn Opt_WarnUnusedBinds `thenRn` \ warn ->
+    if warn then warnUnusedBinds [(n,LocalDef) | n<-names]
+           else returnRn ()
 
 warnUnusedMatches names
-  | opt_WarnUnusedMatches = warnUnusedGroup [(n,LocalDef) | n<-ns]
-  | otherwise            = returnRn ()
+  = doptRn Opt_WarnUnusedMatches `thenRn` \ warn ->
+    if warn then warnUnusedGroup [(n,LocalDef) | n<-names]
+           else returnRn ()
 
 -------------------------
 
@@ -711,15 +740,8 @@ warnUnusedBinds names
   where
        -- Group by provenance
    groups = equivClasses cmp names
-   (_,prov1) `cmp` (_,prov2) = prov1 `cmp_prov` prov2
+   (_,prov1) `cmp` (_,prov2) = prov1 `compare` prov2
  
-   cmp_prov (LocalDef _ _) (NonLocalDef _ _)       = LT
-   cmp_prov (LocalDef loc1 _) (LocalDef loc2 _)    = loc1 `compare` loc2
-   cmp_prov (NonLocalDef (UserImport m1 loc1 _) _)
-            (NonLocalDef (UserImport m2 loc2 _) _) =
-        (m1 `compare` m2) `thenCmp` (loc1 `compare` loc2)
-   cmp_prov (NonLocalDef _ _) (LocalDef _ _)       = GT
-                       -- In-scope NonLocalDefs must have UserImport info on them
 
 -------------------------
 
@@ -730,13 +752,13 @@ warnUnusedGroup names
   | otherwise
   = pushSrcLocRn def_loc       $
     addWarnRn                  $
-    sep [msg <> colon, nest 4 (fsep (punctuate comma (map ppr filtered_names)))]
+    sep [msg <> colon, nest 4 (fsep (punctuate comma (map (ppr.fst) filtered_names)))]
   where
     filtered_names = filter reportable names
     (name1, prov1) = head filtered_names
     (is_local, def_loc, msg)
        = case prov1 of
-               LocalDef loc _  -> (True, loc, text "Defined but not used")
+               LocalDef -> (True, getSrcLoc name1, text "Defined but not used")
 
                NonLocalDef (UserImport mod loc _) _ 
                        -> (True, loc, text "Imported from" <+> quotes (ppr mod) <+> text "but not used")