[project @ 2000-02-25 14:55:31 by panne]
[ghc-hetmet.git] / ghc / compiler / rename / Rename.lhs
index 730f02d..a064dd6 100644 (file)
@@ -15,8 +15,7 @@ import RnHsSyn                ( RenamedHsModule, RenamedHsDecl,
                        )
 
 import CmdLineOpts     ( opt_HiMap, opt_D_dump_rn_trace,
-                         opt_D_dump_rn, opt_D_dump_rn_stats,
-                         opt_WarnUnusedBinds, opt_WarnUnusedImports
+                         opt_D_dump_rn, opt_D_dump_rn_stats, opt_WarnDeprecations
                        )
 import RnMonad
 import RnNames         ( getGlobalNames )
@@ -24,33 +23,29 @@ import RnSource             ( rnSourceDecls, rnDecl )
 import RnIfaces                ( getImportedInstDecls, importDecl, getImportVersions,
                          getImportedRules, loadHomeInterface, getSlurped, removeContext
                        )
-import RnEnv           ( availName, availNames, availsToNameSet, 
-                         warnUnusedTopNames, mapFvRn, lookupImplicitOccRn,
+import RnEnv           ( availName, availsToNameSet, 
+                         warnUnusedImports, warnUnusedLocalBinds, lookupImplicitOccRn,
                          FreeVars, plusFVs, plusFV, unitFV, emptyFVs, isEmptyFVs
                        )
-import Module           ( Module, ModuleName, pprModule, mkSearchPath, mkThisModule )
-import Name            ( Name, isLocallyDefined,
-                         NamedThing(..), ImportReason(..), Provenance(..),
-                         pprOccName, nameOccName,
-                         getNameProvenance, 
+import Module           ( Module, ModuleName, mkSearchPath, mkThisModule )
+import Name            ( Name, isLocallyDefined, NamedThing(..), getSrcLoc,
+                         nameOccName, nameUnique, isUserImportedExplicitlyName,
                          maybeWiredInTyConName, maybeWiredInIdName, isWiredInName
                        )
+import OccName         ( occNameFlavour )
 import Id              ( idType )
-import DataCon         ( dataConTyCon, dataConType )
-import TyCon           ( TyCon, tyConDataCons, isSynTyCon, getSynTyConDefn )
-import RdrName         ( RdrName )
+import TyCon           ( isSynTyCon, getSynTyConDefn )
 import NameSet
 import PrelMods                ( mAIN_Name, pREL_MAIN_Name )
 import TysWiredIn      ( unitTyCon, intTyCon, doubleTyCon, boolTyCon )
-import PrelInfo                ( ioTyCon_NAME, numClass_RDR, thinAirIdNames, derivingOccurrences )
+import PrelInfo                ( ioTyCon_NAME, thinAirIdNames, fractionalClassKeys, derivingOccurrences )
 import Type            ( namesOfType, funTyCon )
 import ErrUtils                ( printErrorsAndWarnings, dumpIfSet, ghcExit )
 import BasicTypes      ( NewOrData(..) )
 import Bag             ( isEmptyBag, bagToList )
-import FiniteMap       ( fmToList, delListFromFM, addToFM, sizeFM, eltsFM )
+import FiniteMap       ( eltsFM )
 import UniqSupply      ( UniqSupply )
 import UniqFM          ( lookupUFM )
-import Util            ( equivClasses )
 import Maybes          ( maybeToBool )
 import Outputable
 \end{code}
@@ -68,7 +63,7 @@ renameModule :: UniqSupply
                      , [ModuleName]      -- Imported modules; for profiling
                      ))
 
-renameModule us this_mod@(HsModule mod_name vers exports imports local_decls loc)
+renameModule us this_mod@(HsModule mod_name vers exports imports local_decls _ loc)
   =    -- Initialise the renamer monad
     initRn mod_name us (mkSearchPath opt_HiMap) loc
           (rename this_mod)                            >>=
@@ -89,7 +84,9 @@ renameModule us this_mod@(HsModule mod_name vers exports imports local_decls loc
 
 
 \begin{code}
-rename this_mod@(HsModule mod_name vers exports imports local_decls loc)
+rename :: RdrNameHsModule
+       -> RnMG (Maybe (Module, RenamedHsModule, InterfaceDetails, RnNameSupply, [ModuleName]), IO ())
+rename this_mod@(HsModule mod_name vers _ imports local_decls mod_deprec loc)
   =    -- FIND THE GLOBAL NAME ENVIRONMENT
     getGlobalNames this_mod                    `thenRn` \ maybe_stuff ->
 
@@ -118,7 +115,13 @@ rename this_mod@(HsModule mod_name vers exports imports local_decls loc)
     in
     slurpImpDecls real_source_fvs      `thenRn` \ rn_imp_decls ->
     let
-       rn_all_decls       = rn_imp_decls ++ rn_local_decls 
+       rn_all_decls       = rn_local_decls ++ rn_imp_decls
+
+       -- COLLECT ALL DEPRECATIONS
+       deprec_sigs = [ ds | ValD bnds <- rn_local_decls, ds <- collectDeprecs bnds ]
+       deprecs = case mod_deprec of
+          Nothing -> deprec_sigs
+          Just txt -> Deprecation (IEModuleContents undefined) txt : deprec_sigs
     in
 
        -- EXIT IF ERRORS FOUND
@@ -130,8 +133,8 @@ rename this_mod@(HsModule mod_name vers exports imports local_decls loc)
     else
 
        -- GENERATE THE VERSION/USAGE INFO
-    getImportVersions mod_name exports                 `thenRn` \ my_usages ->
-    getNameSupplyRn                                    `thenRn` \ name_supply ->
+    getImportVersions mod_name export_env      `thenRn` \ my_usages ->
+    getNameSupplyRn                            `thenRn` \ name_supply ->
 
        -- REPORT UNUSED NAMES
     reportUnusedNames gbl_env global_avail_env
@@ -145,17 +148,22 @@ rename this_mod@(HsModule mod_name vers exports imports local_decls loc)
        renamed_module = HsModule mod_name vers 
                                  trashed_exports trashed_imports
                                  rn_all_decls
+                                 mod_deprec
                                  loc
     in
     rnDump rn_imp_decls        rn_all_decls            `thenRn` \ dump_action ->
     returnRn (Just (mkThisModule mod_name,
                    renamed_module, 
-                   (has_orphans, my_usages, export_env),
+                   (InterfaceDetails has_orphans my_usages export_env deprecs),
                    name_supply,
                    direct_import_mods), dump_action)
   where
     trashed_exports  = {-trace "rnSource:trashed_exports"-} Nothing
     trashed_imports  = {-trace "rnSource:trashed_imports"-} []
+
+    collectDeprecs EmptyBinds = []
+    collectDeprecs (ThenBinds x y) = collectDeprecs x ++ collectDeprecs y
+    collectDeprecs (MonoBind _ sigs _) = [ d | DeprecSig d _ <- sigs ]
 \end{code}
 
 @implicitFVs@ forces the renamer to slurp in some things which aren't
@@ -164,21 +172,20 @@ mentioned explicitly, but which might be needed by the type checker.
 \begin{code}
 implicitFVs mod_name decls
   = mapRn lookupImplicitOccRn implicit_occs    `thenRn` \ implicit_names ->
-    returnRn (implicit_main            `plusFV` 
-             mkNameSet default_tys     `plusFV`
-             mkNameSet thinAirIdNames  `plusFV`
+    returnRn (implicit_main                            `plusFV` 
+             mkNameSet (map getName default_tycons)    `plusFV`
+             mkNameSet thinAirIdNames                  `plusFV`
              mkNameSet implicit_names)
-    
   where
-       -- Add occurrences for Int, Double, and (), because they
+       -- Add occurrences for Int, and (), because they
        -- are the types to which ambigious type variables may be defaulted by
        -- the type checker; so they won't always appear explicitly.
        -- [The () one is a GHC extension for defaulting CCall results.]
        -- ALSO: funTyCon, since it occurs implicitly everywhere!
        --       (we don't want to be bothered with making funTyCon a
        --        free var at every function application!)
-    default_tys = [getName intTyCon, getName doubleTyCon,
-                  getName unitTyCon, getName funTyCon, getName boolTyCon]
+       -- Double is dealt with separately in getGates
+    default_tycons = [unitTyCon, funTyCon, boolTyCon, intTyCon]
 
        -- Add occurrences for IO or PrimIO
     implicit_main |  mod_name == mAIN_Name
@@ -190,7 +197,6 @@ implicitFVs mod_name decls
        -- generate code
     implicit_occs = foldr ((++) . get) [] decls
 
-    get (DefD _) = [numClass_RDR]
     get (TyClD (TyData _ _ _ _ _ (Just deriv_classes) _ _))
        = concat (map get_deriv deriv_classes)
     get other = []
@@ -211,13 +217,35 @@ isOrphanDecl (InstD (InstDecl inst_ty _ _ _ _))
 isOrphanDecl (RuleD (RuleDecl _ _ _ lhs _ _))
   = check lhs
   where
-    check (HsVar v)   = not (isLocallyDefined v)
-    check (HsApp f a) = check f && check a
-    check other              = True
+       -- At the moment we just check for common LHS forms
+       -- Expand as necessary.  Getting it wrong just means
+       -- more orphans than necessary
+    check (HsVar v)      = not (isLocallyDefined v)
+    check (HsApp f a)    = check f && check a
+    check (HsLit _)      = False
+    check (OpApp l o _ r) = check l && check o && check r
+    check (NegApp e _)    = check e
+    check (HsPar e)      = check e
+    check (SectionL e o)  = check e && check o
+    check (SectionR o e)  = check e && check o
+
+    check other                  = True        -- Safe fall through
+
 isOrphanDecl other = False
 \end{code}
 
 
+\begin{code}
+dupDefaultDeclErrRn (DefaultDecl _ locn1 : dup_things)
+  = pushSrcLocRn locn1 $
+    addErrRn msg
+  where
+    msg = hang (ptext SLIT("Multiple default declarations"))
+              4  (vcat (map pp dup_things))
+    pp (DefaultDecl _ locn) = ptext SLIT("here was another default declaration") <+> ppr locn
+\end{code}
+
+
 %*********************************************************
 %*                                                      *
 \subsection{Slurping declarations}
@@ -274,7 +302,7 @@ slurpSourceRefs source_binders source_fvs
          rnInstDecls decls1 fvs1 gates1 inst_decls             `thenRn` \ (decls2, fvs2, gates2) ->
          go_outer decls2 fvs2 (all_gates `plusFV` gates2)
                               (nameSetToList (gates2 `minusNameSet` all_gates))
-               -- Knock out the all_gates because even ifwe don't slurp any new
+               -- Knock out the all_gates because even if we don't slurp any new
                -- decls we can get some apparently-new gates from wired-in names
 
     go_inner decls fvs gates []
@@ -397,14 +425,25 @@ getGates source_fvs (SigD (IfaceSig _ ty _ _))
   = extractHsTyNames ty
 
 getGates source_fvs (TyClD (ClassDecl ctxt cls tvs _ sigs _ _ _ _ _ _))
-  = delListFromNameSet (foldr (plusFV . get) (extractHsCtxtTyNames ctxt) sigs)
+  = (delListFromNameSet (foldr (plusFV . get) (extractHsCtxtTyNames ctxt) sigs)
                       (map getTyVarName tvs)
-    `addOneToNameSet` cls
+     `addOneToNameSet` cls)
+    `plusFV` maybe_double
   where
     get (ClassOpSig n _ _ ty _) 
        | n `elemNameSet` source_fvs = extractHsTyNames ty
        | otherwise                  = emptyFVs
 
+       -- If we load any numeric class that doesn't have
+       -- Int as an instance, add Double to the gates. 
+       -- This takes account of the fact that Double might be needed for
+       -- defaulting, but we don't want to load Double (and all its baggage)
+       -- if the more exotic classes aren't used at all.
+    maybe_double | nameUnique cls `elem` fractionalClassKeys 
+                = unitFV (getName doubleTyCon)
+                | otherwise
+                = emptyFVs
+
 getGates source_fvs (TyClD (TySynonym tycon tvs ty _))
   = delListFromNameSet (extractHsTyNames ty)
                       (map getTyVarName tvs)
@@ -479,7 +518,8 @@ getInstDeclGates other                                  = emptyFVs
 %*********************************************************
 
 \begin{code}
-reportUnusedNames gbl_env avail_env (ExportEnv export_avails _) mentioned_names
+reportUnusedNames :: GlobalRdrEnv -> NameEnv AvailInfo -> ExportEnv -> NameSet -> RnM d ()
+reportUnusedNames gbl_env avail_env (ExportEnv export_avails _ _) mentioned_names
   = let
        used_names = mentioned_names `unionNameSets` availsToNameSet export_avails
 
@@ -499,20 +539,27 @@ reportUnusedNames gbl_env avail_env (ExportEnv export_avails _) mentioned_names
           nameSetToList (defined_names `minusNameSet` really_used_names)
 
        -- Filter out the ones only defined implicitly
-       bad_guys = filter reportableUnusedName defined_but_not_used
-    in
-    warnUnusedTopNames bad_guys
+       bad_locals = [n | n <- defined_but_not_used, isLocallyDefined             n]
+       bad_imps   = [n | n <- defined_but_not_used, isUserImportedExplicitlyName n]
 
-reportableUnusedName :: Name -> Bool
-reportableUnusedName name
-  = explicitlyImported (getNameProvenance name)
-  where
-    explicitlyImported (LocalDef _ _)                       = True
-       -- Report unused defns of local vars
-    explicitlyImported (NonLocalDef (UserImport _ _ expl) _) = expl
-       -- Report unused explicit imports
-    explicitlyImported other                                = False
-       -- Don't report others
+       non_locally_used = [ n | n <- nameSetToList really_used_names, not (isLocallyDefined n) ]
+       deprec_used deprec_env = [ (n,txt) | n <- non_locally_used, Just txt <- [lookupNameEnv deprec_env n] ]
+    in
+    traceRn (text "really used and non-locally defined" <> colon <+>
+             nest 4 (fsep (punctuate comma [ text (occNameFlavour (nameOccName n)) <+> ppr n
+                                           | n <- non_locally_used]))) `thenRn_`
+    getIfacesRn                                                                `thenRn` \ ifaces ->
+    if opt_WarnDeprecations
+       then mapRn_ warnDeprec (deprec_used (iDeprecs ifaces))
+       else returnRn ()                                                `thenRn_`
+    warnUnusedLocalBinds bad_locals                                    `thenRn_`
+    warnUnusedImports bad_imps
+
+warnDeprec :: (Name, DeprecTxt) -> RnM d ()
+warnDeprec (name, txt)
+  = pushSrcLocRn (getSrcLoc name)      $
+    addWarnRn                          $
+    sep [ text "Using deprecated entity" <+> ppr name <> colon, nest 4 (ppr txt) ]
 
 rnDump  :: [RenamedHsDecl]     -- Renamed imported decls
        -> [RenamedHsDecl]      -- Renamed local decls