Remove unused lookupDeprec function
[ghc-hetmet.git] / compiler / rename / RnNames.lhs
index 4ee759a..06cddd2 100644 (file)
@@ -30,34 +30,19 @@ import Module
 import Name
 import NameEnv
 import NameSet
-import OccName         ( srcDataName, pprNonVarNameSpace,
-                         occNameSpace,
-                         OccEnv, mkOccEnv, mkOccEnv_C, lookupOccEnv,
-                         emptyOccEnv, extendOccEnv )
-import HscTypes                ( GenAvailInfo(..), AvailInfo, availNames, availName,
-                         HomePackageTable, PackageIfaceTable, 
-                         mkPrintUnqualified, availsToNameSet,
-                         Deprecs(..), ModIface(..), Dependencies(..), 
-                         lookupIfaceByModule, ExternalPackageState(..)
-                       )
-import RdrName         ( RdrName, rdrNameOcc, setRdrNameSpace, Parent(..),
-                         GlobalRdrEnv, mkGlobalRdrEnv, GlobalRdrElt(..), 
-                         emptyGlobalRdrEnv, plusGlobalRdrEnv, globalRdrEnvElts,
-                         extendGlobalRdrEnv, lookupGlobalRdrEnv, lookupGRE_Name,
-                         Provenance(..), ImportSpec(..), ImpDeclSpec(..), ImpItemSpec(..), 
-                         importSpecLoc, importSpecModule, isLocalGRE, pprNameProvenance,
-                         unQualSpecOK, qualSpecOK )
+import OccName
+import HscTypes
+import RdrName
 import Outputable
 import Maybes
-import SrcLoc          ( Located(..), mkGeneralSrcSpan, getLoc,
-                         unLoc, noLoc, srcLocSpan, SrcSpan )
+import SrcLoc
 import FiniteMap
 import ErrUtils
 import BasicTypes      ( DeprecTxt )
 import DriverPhases    ( isHsBoot )
 import Util
 import ListSetOps
-import Data.List        ( partition, concatMap, (\\) )
+import Data.List        ( partition, concatMap, (\\), delete )
 import IO              ( openFile, IOMode(..) )
 import Monad           ( when )
 \end{code}
@@ -80,29 +65,16 @@ rnImports imports
          -- warning for {- SOURCE -} ones that are unnecessary
     = do this_mod <- getModule
          implicit_prelude <- doptM Opt_ImplicitPrelude
-         let all_imports              = mk_prel_imports this_mod implicit_prelude ++ imports
-             (source, ordinary) = partition is_source_import all_imports
+         let prel_imports      = mkPrelImports this_mod implicit_prelude imports
+             (source, ordinary) = partition is_source_import imports
              is_source_import (L _ (ImportDecl _ is_boot _ _ _)) = is_boot
 
-         stuff1 <- mapM (rnImportDecl this_mod) ordinary
+         stuff1 <- mapM (rnImportDecl this_mod) (prel_imports ++ ordinary)
          stuff2 <- mapM (rnImportDecl this_mod) source
          let (decls, rdr_env, imp_avails) = combine (stuff1 ++ stuff2)
          return (decls, rdr_env, imp_avails) 
 
     where
--- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
--- because the former doesn't even look at Prelude.hi for instance 
--- declarations, whereas the latter does.
-   mk_prel_imports this_mod implicit_prelude
-       |  this_mod == pRELUDE
-          || explicit_prelude_import
-          || not implicit_prelude
-           = []
-       | otherwise = [preludeImportDecl]
-   explicit_prelude_import
-       = notNull [ () | L _ (ImportDecl mod _ _ _ _) <- imports, 
-                  unLoc mod == pRELUDE_NAME ]
-
    combine :: [(LImportDecl Name,  GlobalRdrEnv, ImportAvails)]
            -> ([LImportDecl Name], GlobalRdrEnv, ImportAvails)
    combine = foldr plus ([], emptyGlobalRdrEnv, emptyImportAvails)
@@ -112,18 +84,34 @@ rnImports imports
                    gbl_env1 `plusGlobalRdrEnv` gbl_env2,
                    imp_avails1 `plusImportAvails` imp_avails2)
 
-preludeImportDecl :: LImportDecl RdrName
-preludeImportDecl
-  = L loc $
-       ImportDecl (L loc pRELUDE_NAME)
+mkPrelImports :: Module -> Bool -> [LImportDecl RdrName] -> [LImportDecl RdrName]
+-- Consruct the implicit declaration "import Prelude" (or not)
+--
+-- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
+-- because the former doesn't even look at Prelude.hi for instance 
+-- declarations, whereas the latter does.
+mkPrelImports this_mod implicit_prelude import_decls
+  | this_mod == pRELUDE
+   || explicit_prelude_import
+   || not implicit_prelude
+  = []
+  | otherwise = [preludeImportDecl]
+  where
+      explicit_prelude_import
+       = notNull [ () | L _ (ImportDecl mod _ _ _ _) <- import_decls, 
+                  unLoc mod == pRELUDE_NAME ]
+
+      preludeImportDecl :: LImportDecl RdrName
+      preludeImportDecl
+        = L loc $
+         ImportDecl (L loc pRELUDE_NAME)
               False {- Not a boot interface -}
               False    {- Not qualified -}
               Nothing  {- No "as" -}
               Nothing  {- No import list -}
-  where
-    loc = mkGeneralSrcSpan FSLIT("Implicit import declaration")         
 
-       
+      loc = mkGeneralSrcSpan FSLIT("Implicit import declaration")         
+
 
 rnImportDecl  :: Module
              -> LImportDecl RdrName
@@ -191,7 +179,7 @@ rnImportDecl this_mod (L loc (ImportDecl loc_imp_mod_name want_boot
 
         -- filter the imports according to the import declaration
     (new_imp_details, gbl_env) <- 
-        filterImports2 iface imp_spec imp_details total_avails
+        filterImports iface imp_spec imp_details total_avails
 
     dflags <- getDOpts
 
@@ -408,11 +396,6 @@ filterImports iface decl_spec (Just (want_hiding, import_items)) all_avails
            gres | want_hiding = gresFromAvails hiding_prov pruned_avails
                 | otherwise   = concatMap (gresFromIE decl_spec) items2
 
-        traceRn (ppr $ all_avails)
-        traceRn (ppr $ occ_env)
-        traceRn (ppr $ items2)
-        traceRn (ppr $ mkGlobalRdrEnv gres)
-
         return (Just (want_hiding, map fst items2), mkGlobalRdrEnv gres)
   where
        -- This environment is how we map names mentioned in the import
@@ -545,134 +528,6 @@ catMaybeErr :: [MaybeErr err a] -> [a]
 catMaybeErr ms =  [ a | Succeeded a <- ms ]
 \end{code}
 
-\begin{code}
-filterImports2 :: ModIface
-             -> ImpDeclSpec                    -- The span for the entire import decl
-             -> Maybe (Bool, [LIE RdrName])    -- Import spec; True => hiding
-             -> [AvailInfo]                    -- What's available
-             -> RnM (Maybe (Bool, [LIE Name]), -- Import spec w/ Names
-                     GlobalRdrEnv)             -- Same again, but in GRE form
-                       
-filterImports2 iface decl_spec Nothing all_avails
-  = return (Nothing, mkGlobalRdrEnv (gresFromAvails prov all_avails))
-  where
-    prov = Imported [ImpSpec { is_decl = decl_spec, is_item = ImpAll }]
-
-
-filterImports2 iface decl_spec (Just (want_hiding, import_items)) all_avails
-  = do   -- check for errors, convert RdrNames to Names
-        opt_indexedtypes <- doptM Opt_IndexedTypes
-        items1 <- mapM (lookup_lie opt_indexedtypes) import_items
-
-        let items2 :: [(LIE Name, AvailInfo)]
-            items2 = concat items1
-               -- NB the AvailInfo may have duplicates, and several items
-               --    for the same parent; e.g N(x) and N(y)
-
-            names  = availsToNameSet (map snd items2)
-           keep n = not (n `elemNameSet` names)
-           pruned_avails = filterAvails keep all_avails
-           hiding_prov = Imported [ImpSpec { is_decl = decl_spec, is_item = ImpAll }]
-
-           gres | want_hiding = gresFromAvails hiding_prov pruned_avails
-                | otherwise   = concatMap (gresFromIE decl_spec) items2
-
-        return (Just (want_hiding, map fst items2), mkGlobalRdrEnv gres)
-  where
-       -- This environment is how we map names mentioned in the import
-        -- list to the actual Name they correspond to, and the family
-        -- that the Name belongs to (an AvailInfo).
-        --
-       -- This env will have entries for data constructors too,
-       -- they won't make any difference because naked entities like T
-       -- in an import list map to TcOccs, not VarOccs.
-    occ_env :: OccEnv (Name,AvailInfo)
-    occ_env = mkOccEnv [ (nameOccName n, (n,a)) 
-                       | a <- all_avails, n <- availNames a ]
-
-    lookup_lie :: Bool -> LIE RdrName -> TcRn [(LIE Name, AvailInfo)]
-    lookup_lie opt_indexedtypes (L loc ieRdr)
-        = do 
-             stuff <- setSrcSpan loc $ 
-                      case lookup_ie opt_indexedtypes ieRdr of
-                            Failed err  -> addErr err >> return []
-                            Succeeded a -> return a
-             checkDodgyImport stuff
-             return [ (L loc ie, avail) | (ie,avail) <- stuff ]
-        where
-                -- Warn when importing T(..) if T was exported abstractly
-            checkDodgyImport stuff
-                | IEThingAll n <- ieRdr, (_, AvailTC _ [one]):_ <- stuff
-                = ifOptM Opt_WarnDodgyImports (addWarn (dodgyImportWarn n))
-                -- NB. use the RdrName for reporting the warning
-            checkDodgyImport _
-                = return ()
-
-        -- For each import item, we convert its RdrNames to Names,
-        -- and at the same time construct an AvailInfo corresponding
-        -- to what is actually imported by this item.
-        -- Returns Nothing on error.
-        -- We return a list here, because in the case of an import
-        -- item like C, if we are hiding, then C refers to *both* a
-        -- type/class and a data constructor.
-    lookup_ie :: Bool -> IE RdrName -> MaybeErr Message [(IE Name,AvailInfo)]
-    lookup_ie opt_indexedtypes ie 
-      = let bad_ie = Failed (badImportItemErr iface decl_spec ie)
-
-            lookup_name rdrName = 
-                case lookupOccEnv occ_env (rdrNameOcc rdrName) of
-                   Nothing -> bad_ie
-                   Just n  -> return n
-        in
-        case ie of
-         IEVar n -> do
-             (name,avail) <- lookup_name n
-             return [(IEVar name, trimAvail avail name)]
-
-         IEThingAll tc -> do
-             (name,avail) <- lookup_name tc
-             return [(IEThingAll name, avail)]
-
-         IEThingAbs tc
-             | want_hiding   -- hiding ( C )
-                        -- Here the 'C' can be a data constructor 
-                        --  *or* a type/class, or even both
-             -> let tc_name = lookup_name tc
-                    dc_name = lookup_name (setRdrNameSpace tc srcDataName)
-                in
-                case catMaybeErr [ tc_name, dc_name ] of
-                  []    -> bad_ie
-                  names -> return [ (IEThingAbs n, trimAvail av n) 
-                                 | (n,av) <- names ]
-             | otherwise
-             -> do (name,avail) <- lookup_name tc
-                   return [(IEThingAbs name, AvailTC name [name])]
-
-         IEThingWith n ns -> do
-            (name,avail) <- lookup_name n
-            case avail of
-                AvailTC nm subnames | nm == name -> do
-                     let env = mkOccEnv [ (nameOccName s, s) 
-                                        | s <- subnames ]
-                     let mb_children = map (lookupOccEnv env . rdrNameOcc) ns
-                     children <- 
-                        if any isNothing mb_children
-                          then bad_ie
-                          else return (catMaybes mb_children)
-                        -- check for proper import of indexed types
-                     when (not opt_indexedtypes && any isTyConName children) $
-                        Failed (typeItemErr (head . filter isTyConName 
-                                                $ children )
-                                    (text "in import list"))
-                     return [(IEThingWith name children, AvailTC name (name:children))]
-
-                _otherwise -> bad_ie
-
-         _other -> Failed illegalImportItemErr
-         -- could be IEModuleContents, IEGroup, IEDoc, IEDocNamed
-         -- all errors.
-\end{code}
-
 %************************************************************************
 %*                                                                     *
         Import/Export Utils
@@ -784,9 +639,18 @@ mkAvailEnv :: [AvailInfo] -> AvailEnv
        -- We want to combine these; addAvail does that
 mkAvailEnv avails = foldl addAvail emptyAvailEnv avails
 
+-- After combining the avails, we need to ensure that the parent name is the
+-- first entry in the list of subnames, if it is included at all.  (Subsequent
+-- functions rely on that.)
+normaliseAvail :: AvailInfo -> AvailInfo
+normaliseAvail avail@(Avail _)     = avail
+normaliseAvail (AvailTC name subs) = AvailTC name subs'
+  where
+    subs' = if name `elem` subs then name : (delete name subs) else subs
+
 -- | combines 'AvailInfo's from the same family
 nubAvails :: [AvailInfo] -> [AvailInfo]
-nubAvails avails = nameEnvElts (mkAvailEnv avails)
+nubAvails avails = map normaliseAvail . nameEnvElts . mkAvailEnv $ avails
 \end{code}
 
 
@@ -878,6 +742,7 @@ exports_from_avail Nothing rdr_env imports this_mod
 
 exports_from_avail (Just rdr_items) rdr_env imports this_mod
   = do (ie_names, _, exports) <- foldlM do_litem emptyExportAccum rdr_items
+
        return (Just ie_names, exports)
   where
     do_litem :: ExportAccum -> LIE RdrName -> RnM ExportAccum
@@ -934,8 +799,13 @@ exports_from_avail (Just rdr_items) rdr_env imports this_mod
              return (IEVar (gre_name gre), greAvail gre)
 
     lookup_ie (IEThingAbs rdr) 
-        = do name <- lookupGlobalOccRn rdr
-             return (IEThingAbs name, AvailTC name [name])
+        = do gre <- lookupGreRn rdr
+            let name = gre_name gre
+            case gre_par gre of
+               NoParent   -> return (IEThingAbs name, 
+                                     AvailTC name [name])
+               ParentIs p -> return (IEThingAbs name, 
+                                     AvailTC p [name])
 
     lookup_ie ie@(IEThingAll rdr) 
         = do name <- lookupGlobalOccRn rdr
@@ -1048,7 +918,7 @@ reportDeprecations dflags tcg_env
 
     check hpt pit gre@(GRE {gre_name = name, gre_prov = Imported (imp_spec:_)})
       | name `elemNameSet` used_names
-      ,        Just deprec_txt <- lookupDeprec dflags hpt pit gre
+      ,        Just deprec_txt <- lookupImpDeprec dflags hpt pit gre
       = addWarnAt (importSpecLoc imp_spec)
                  (sep [ptext SLIT("Deprecated use of") <+> 
                        pprNonVarNameSpace (occNameSpace (nameOccName name)) <+> 
@@ -1070,9 +940,10 @@ reportDeprecations dflags tcg_env
            -- the defn of a non-deprecated thing, when changing a module's 
            -- interface
 
-lookupDeprec :: DynFlags -> HomePackageTable -> PackageIfaceTable 
-            -> GlobalRdrElt -> Maybe DeprecTxt
-lookupDeprec dflags hpt pit gre
+lookupImpDeprec :: DynFlags -> HomePackageTable -> PackageIfaceTable 
+               -> GlobalRdrElt -> Maybe DeprecTxt
+-- The name is definitely imported, so look in HPT, PIT
+lookupImpDeprec dflags hpt pit gre
   = case lookupIfaceByModule dflags hpt pit (nameModule name) of
        Just iface -> mi_dep_fn iface name `seqMaybe`   -- Bleat if the thing, *or
                      case gre_par gre of