[project @ 2002-03-29 21:39:36 by sof]
[ghc-hetmet.git] / ghc / compiler / rename / RnIfaces.lhs
index 7cab59c..9a07a2f 100644 (file)
@@ -36,13 +36,13 @@ import RnEnv
 import RnMonad
 import Id              ( idType, idName, globalIdDetails )
 import IdInfo          ( GlobalIdDetails(..) )
-import Type            ( namesOfType )
+import TcType          ( namesOfType )
 import FieldLabel      ( fieldLabelTyCon )
 import DataCon         ( dataConTyCon )
-import TyCon           ( isSynTyCon, getSynTyConDefn, tyConClass_maybe, tyConName )
+import TyCon           ( visibleDataCons, isSynTyCon, getSynTyConDefn, tyConClass_maybe, tyConName )
 import Class           ( className )
 import Name            ( Name {-instance NamedThing-}, nameOccName,
-                         nameModule, isLocalName, NamedThing(..)
+                         nameModule, isInternalName, NamedThing(..)
                         )
 import NameEnv                 ( elemNameEnv, delFromNameEnv, lookupNameEnv )
 import NameSet
@@ -55,7 +55,7 @@ import Module         ( Module, ModuleEnv,
                        )
 import PrelInfo                ( wiredInThingEnv, hasKey, fractionalClassKey, numClassKey, 
                          integerTyConName, doubleTyConName )
-import Maybes          ( maybeToBool )
+import Maybe           ( isJust )
 import FiniteMap
 import Outputable
 import Bag
@@ -144,9 +144,9 @@ mkImportInfo this_mod imports
                -- (apart from hiding some, perhaps)
        import_all_mods = [ m | ImportDecl m _ _ _ imp_list _ <- imports,
                                import_all imp_list ]
-                       where
-                         import_all (Just (False, _)) = False  -- Imports are specified explicitly
-                         import_all other             = True   -- Everything is imported
+         where
+          import_all (Just (False, _)) = False -- Imports are spec'd explicitly
+          import_all other             = True  -- Everything is imported
 
        -- mv_map groups together all the things imported and used
        -- from a particular module in this package
@@ -159,33 +159,41 @@ mkImportInfo this_mod imports
                             add_item names _ = name:names
 
        -- In our usage list we record
-       --      a) Specifically: Detailed version info for imports from modules in this package
-       --                       Gotten from iVSlurp plus import_all_mods
        --
-       --      b) Everything:   Just the module version for imports from modules in other packages
-       --                       Gotten from iVSlurp plus import_all_mods
+       --      a) Specifically: Detailed version info for imports
+       --         from modules in this package Gotten from iVSlurp plus
+       --         import_all_mods
+       --
+       --      b) Everything: Just the module version for imports
+       --         from modules in other packages Gotten from iVSlurp plus
+       --         import_all_mods
        --
-       --      c) NothingAtAll: The name only of modules, Baz, in this package that are 'below' us, 
-       --                       but which we didn't need at all (this is needed only to decide whether
-       --                       to open Baz.hi or Baz.hi-boot higher up the tree).
-       --                       This happens when a module, Foo, that we explicitly imported has 
-       --                       'import Baz' in its interface file, recording that Baz is below
-       --                       Foo in the module dependency hierarchy.  We want to propagate this info.
-       --                       These modules are in a combination of HIT/PIT and iImpModInfo
+       --      c) NothingAtAll: The name only of modules, Baz, in
+       --         this package that are 'below' us, but which we didn't need
+       --         at all (this is needed only to decide whether to open Baz.hi
+       --         or Baz.hi-boot higher up the tree).  This happens when a
+       --         module, Foo, that we explicitly imported has 'import Baz' in
+       --         its interface file, recording that Baz is below Foo in the
+       --         module dependency hierarchy.  We want to propagate this
+       --         info.  These modules are in a combination of HIT/PIT and
+       --         iImpModInfo
        --
-       --      d) NothingAtAll: The name only of all orphan modules we know of (this is needed
-       --                       so that anyone who imports us can find the orphan modules)
-       --                       These modules are in a combination of HIT/PIT and iImpModInfo
+       --      d) NothingAtAll: The name only of all orphan modules
+       --         we know of (this is needed so that anyone who imports us can
+       --         find the orphan modules) These modules are in a combination
+       --         of HIT/PIT and iImpModInfo
 
        import_info0 = foldModuleEnv mk_imp_info  []           pit
        import_info1 = foldModuleEnv mk_imp_info  import_info0 hit
        import_info  = not_even_opened_imports ++ import_info1
 
-               -- Recall that iImpModInfo describes modules that have been mentioned
-               -- in the import lists of interfaces we have opened, but which we have
-               -- not even opened when compiling this module
-       not_even_opened_imports = [ (mod_name, orphans, is_boot, NothingAtAll) 
-                                 | (mod_name, (orphans, is_boot)) <- fmToList (iImpModInfo ifaces) ]
+               -- Recall that iImpModInfo describes modules that have
+               -- been mentioned in the import lists of interfaces we
+               -- have opened, but which we have not even opened when
+               -- compiling this module
+       not_even_opened_imports =
+         [ (mod_name, orphans, is_boot, NothingAtAll) 
+         | (mod_name, (orphans, is_boot)) <- fmToList (iImpModInfo ifaces) ]
 
        
        mk_imp_info :: ModIface -> [ImportVersion Name] -> [ImportVersion Name]
@@ -372,7 +380,7 @@ recordDeclSlurp ifaces@(Ifaces { iDecls  = (decls_map, n_slurped),
                                 iSlurp  = slurped_names, 
                                 iVSlurp = vslurp })
            avail
-  = ASSERT2( not (isLocalName (availName avail)), ppr avail )
+  = ASSERT2( not (isInternalName (availName avail)), ppr avail )
     ifaces { iDecls = (new_decls_map, n_slurped+1),
             iSlurp  = new_slurped_names, 
             iVSlurp = updateVSlurp vslurp (availName avail) }
@@ -448,7 +456,7 @@ that are mentioned in:
 We slurp in an instance decl from the gated instance pool iff
        
        all its gates are either in the gates of the module, 
-       or are a previously-loaded class.  
+       or are a previously-loaded tycon or class.  
 
 The latter constraint is because there might have been an instance
 decl slurped in during an earlier compilation, like this:
@@ -457,8 +465,19 @@ decl slurped in during an earlier compilation, like this:
 
 In the module being compiled we might need (Baz (Maybe T)), where T
 is defined in this module, and hence we need (Foo T).  So @Foo@ becomes
-a gate.  But there's no way to 'see' that, so we simply treat all 
-previously-loaded classes as gates.
+a gate.  But there's no way to 'see' that.  More generally, types
+might be involved as well:
+
+       instance Foo2 T a => Baz2 a where ...
+
+Now we must treat T as a gate too, as well as Foo.  So the solution
+we adopt is:
+
+       we simply treat all previously-loaded 
+       tycons and classes as gates.
+
+This gloss only affects ghc --make and ghc --interactive.
+
 
 Consructors and class operations
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -483,13 +502,17 @@ vars of the source program, and extracts from the decl the gate names.
 
 \begin{code}
 getGates :: FreeVars           -- Things mentioned in the source program
+                               -- Used for the cunning "constructors and 
+                               -- class ops" story described 10 lines above.
         -> RenamedTyClDecl
         -> FreeVars
 
 getGates source_fvs decl 
   = get_gates (\n -> n `elemNameSet` source_fvs) decl
 
-get_gates is_used (IfaceSig {tcdType = ty}) = extractHsTyNames ty
+get_gates is_used (ForeignType {tcdName = tycon}) = unitNameSet tycon
+get_gates is_used (IfaceSig    {tcdType = ty})    = extractHsTyNames ty
+get_gates is_used (CoreDecl    {tcdType = ty})    = extractHsTyNames ty
 
 get_gates is_used (ClassDecl { tcdCtxt = ctxt, tcdName = cls, tcdTyVars = tvs, tcdSigs = sigs})
   = (super_cls_and_sigs `addOneToNameSet` cls) `unionNameSets` 
@@ -506,7 +529,8 @@ get_gates is_used (TySynonym {tcdTyVars = tvs, tcdSynRhs = ty})
        -- A type synonym type constructor isn't a "gate" for instance decls
 
 get_gates is_used (TyData {tcdCtxt = ctxt, tcdName = tycon, tcdTyVars = tvs, tcdCons = cons})
-  = delListFromNameSet (foldr (plusFV . get) (extractHsCtxtTyNames ctxt) cons)
+  = delListFromNameSet (foldr (plusFV . get) (extractHsCtxtTyNames ctxt) 
+                                            (visibleDataCons cons))
                       (hsTyVarNames tvs)
     `addOneToNameSet` tycon
   where
@@ -598,10 +622,8 @@ getImportedInstDecls gates
     getIfacesRn                                        `thenRn` \ ifaces ->
     getTypeEnvRn                                       `thenRn` \ lookup ->
     let
-       available n
-         | n `elemNameSet` gates = True
-         | otherwise             = case lookup n of { Just (AClass c) -> True; other -> False }
-               -- See "The gating story" above for the AClass thing
+       available n = n `elemNameSet` gates || isJust (lookup n)
+               -- See "The gating story" above for the isJust thing
 
        (decls, new_insts) = selectGated available (iInsts ifaces)
     in
@@ -630,7 +652,7 @@ getImportedRules
                -- Slurp rules for anything that is slurped, 
                -- either now or previously
        gates              = iSlurp ifaces      
-       available n        = n `elemNameSet` gates || maybeToBool (lookup n)
+       available n        = n `elemNameSet` gates || isJust (lookup n)
        (decls, new_rules) = selectGated available (iRules ifaces)
     in
     if null decls then
@@ -657,9 +679,9 @@ selectGated available (decl_bag, n_slurped)
   = case foldrBag select ([], emptyBag) decl_bag of
        (decls, new_bag) -> (decls, (new_bag, n_slurped + length decls))
   where
-    select (reqd, decl) (yes, no)
-       | all available reqd = (decl:yes, no)
-       | otherwise          = (yes,      (reqd,decl) `consBag` no)
+    select (gate_fn, decl) (yes, no)
+       | gate_fn available  = (decl:yes, no)
+       | otherwise          = (yes,      (gate_fn,decl) `consBag` no)
 \end{code}
 
 
@@ -858,8 +880,10 @@ checkEntityUsage new_vers (name,old_vers)
                          out_of_date (sep [ptext SLIT("No longer exported:"), ppr name])
 
        Just new_vers   -- It's there, but is it up to date?
-         | new_vers == old_vers -> traceHiDiffsRn (text "Up to date" <+> ppr name <+> parens (ppr new_vers)) `thenRn_` returnRn upToDate
-         | otherwise            -> out_of_date (sep [ptext SLIT("Out of date:"), ppr name])
+         | new_vers == old_vers -> traceHiDiffsRn (text "Up to date" <+> ppr name <+> parens (ppr new_vers)) `thenRn_`
+                                   returnRn upToDate
+         | otherwise            -> out_of_date (sep [ptext SLIT("Out of date:"), ppr name, ppr 
+                                                     old_vers, ptext SLIT("->"), ppr new_vers])
 
 up_to_date  msg = traceHiDiffsRn msg `thenRn_` returnRn upToDate
 out_of_date msg = traceHiDiffsRn msg `thenRn_` returnRn outOfDate