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
)
import PrelInfo ( wiredInThingEnv, hasKey, fractionalClassKey, numClassKey,
integerTyConName, doubleTyConName )
-import Maybes ( maybeToBool )
+import Maybe ( isJust )
import FiniteMap
import Outputable
import Bag
-- (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
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]
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) }
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:
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\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`
-- 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
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
-- 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
= 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}
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