2 % (c) The University of Glasgow, 2000
4 \section[HscTypes]{Types for the per-module compiler}
8 ModDetails(..), GlobalSymbolTable,
10 TyThing(..), lookupTypeEnv,
12 WhetherHasOrphans, ImportVersion, ExportItem,
13 PersistentRenamerState(..), IsBootInterface, Avails, DeclsMap,
14 IfaceInsts, IfaceRules, DeprecationEnv, OrigNameEnv, AvailEnv,
19 Provenance(..), ImportReason(..), PrintUnqualified,
20 pprProvenance, hasBetterProv
24 #include "HsVersions.h"
26 import Name ( Name, NameEnv, NamedThing,
27 unitNameEnv, extendNameEnv, plusNameEnv,
28 lookupNameEnv, emptyNameEnv, getName, nameModule )
29 import Module ( Module, ModuleName,
30 extendModuleEnv, lookupModuleEnv )
31 import Class ( Class )
32 import OccName ( OccName )
33 import RdrName ( RdrNameEnv, emptyRdrEnv )
34 import Outputable ( SDoc )
35 import UniqFM ( UniqFM )
36 import FiniteMap ( FiniteMap, emptyFM, addToFM, lookupFM, foldFM )
39 import VarEnv ( IdEnv )
40 import BasicTypes ( Version, Fixity, defaultFixity )
41 import TyCon ( TyCon )
42 import ErrUtils ( ErrMsg, WarnMsg )
43 import CmLink ( Linkable )
44 import RdrHsSyn ( RdrNameInstDecl, RdrNameRuleDecl, RdrNameHsDecl,
45 RdrNameDeprecation, RdrNameFixitySig )
46 import UniqSupply ( UniqSupply )
47 import HsDecls ( DeprecTxt )
48 import CoreSyn ( CoreRule )
49 import NameSet ( NameSet )
51 import VarSet ( TyVarSet )
53 TcInstUtil ( emptyInstEnv )
54 import Panic ( panic )
57 %************************************************************************
59 \subsection{Symbol tables and Module details}
61 %************************************************************************
63 A @ModDetails@ summarises everything we know about a compiled module.
69 moduleExports :: Avails, -- What it exports
70 mdVersion :: VersionInfo,
71 moduleEnv :: GlobalRdrEnv, -- Its top level environment
73 fixityEnv :: NameEnv Fixity,
74 deprecEnv :: NameEnv DeprecTxt,
77 mdInsts :: [DFunId], -- Dfun-ids for the instances in this module
78 mdRules :: RuleEnv -- Domain may include Id from other modules
81 emptyModDetails :: Module -> ModDetails
83 = ModDetails { moduleId = mod,
85 moduleEnv = emptyRdrEnv,
86 fixityEnv = emptyNameEnv,
87 deprecEnv = emptyNameEnv,
88 typeEnv = emptyNameEnv,
90 mdRules = emptyRuleEnv
94 Symbol tables map modules to ModDetails:
97 type SymbolTable = ModuleEnv ModDetails
98 type HomeSymbolTable = SymbolTable -- Domain = modules in the home package
99 type PackageSymbolTable = SymbolTable -- Domain = modules in the some other package
100 type GlobalSymbolTable = SymbolTable -- Domain = all modules
103 Simple lookups in the symbol table.
106 lookupFixityEnv :: SymbolTable -> Name -> Maybe Fixity
107 -- Returns defaultFixity if there isn't an explicit fixity
108 lookupFixityEnv tbl name
109 = case lookupModuleEnv tbl (nameModule name) of
111 Just details -> lookupNameEnv (fixityEnv details) name
115 %************************************************************************
117 \subsection{Type environment stuff}
119 %************************************************************************
122 type TypeEnv = NameEnv TyThing
124 data TyThing = AnId Id
128 instance NamedThing TyThing where
129 getName (AnId id) = getName id
130 getName (ATyCon tc) = getName tc
131 getName (AClass cl) = getName cl
136 lookupTypeEnv :: SymbolTable -> Name -> Maybe TyThing
137 lookupTypeEnv tbl name
138 = case lookupModuleEnv tbl (nameModule name) of
139 Just details -> lookupNameEnv (typeEnv details) name
143 groupTyThings :: [TyThing] -> FiniteMap Module TypeEnv
144 -- Finite map because we want the range too
146 = foldl add emptyFM things
148 add :: FiniteMap Module TypeEnv -> TyThing -> FiniteMap Module TypeEnv
149 add tbl thing = addToFM tbl mod new_env
152 mod = nameModule name
153 new_env = case lookupFM tbl mod of
154 Nothing -> unitNameEnv name thing
155 Just env -> extendNameEnv env name thing
157 extendTypeEnv :: SymbolTable -> FiniteMap Module TypeEnv -> SymbolTable
158 extendTypeEnv tbl things
159 = foldFM add tbl things
162 = panic "extendTypeEnv" --extendModuleEnv mod new_details
165 = case lookupModuleEnv tbl mod of
166 Nothing -> (emptyModDetails mod) {typeEnv = type_env}
167 Just details -> details {typeEnv = typeEnv details
168 `plusNameEnv` type_env}
172 %************************************************************************
174 \subsection{Auxiliary types}
176 %************************************************************************
178 These types are defined here because they are mentioned in ModDetails,
179 but they are mostly elaborated elsewhere
187 declVers :: NameEnv Version
190 type DeprecationEnv = NameEnv DeprecTxt -- Give reason for deprecation
192 type InstEnv = UniqFM ClsInstEnv -- Maps Class to instances for that class
193 type ClsInstEnv = [(TyVarSet, [Type], DFunId)] -- The instances for a particular class
196 type RuleEnv = IdEnv [CoreRule]
198 emptyRuleEnv = emptyVarEnv
203 type Avails = [AvailInfo]
204 type AvailInfo = GenAvailInfo Name
205 type RdrAvailInfo = GenAvailInfo OccName
207 data GenAvailInfo name = Avail name -- An ordinary identifier
208 | AvailTC name -- The name of the type or class
209 [name] -- The available pieces of type/class.
210 -- NB: If the type or class is itself
211 -- to be in scope, it must be in this list.
212 -- Thus, typically: AvailTC Eq [Eq, ==, /=]
214 -- Equality used when deciding if the interface has changed
216 type AvailEnv = NameEnv AvailInfo -- Maps a Name to the AvailInfo that contains it
220 %************************************************************************
222 \subsection{ModIface}
224 %************************************************************************
227 -- ModIFace is nearly the same as RnMonad.ParsedIface.
228 -- Right now it's identical :)
231 mi_mod :: Module, -- Complete with package info
232 mi_vers :: Version, -- Module version number
233 mi_orphan :: WhetherHasOrphans, -- Whether this module has orphans
234 mi_usages :: [ImportVersion OccName], -- Usages
235 mi_exports :: [ExportItem], -- Exports
236 mi_insts :: [RdrNameInstDecl], -- Local instance declarations
237 mi_decls :: [(Version, RdrNameHsDecl)], -- Local definitions
238 mi_fixity :: (Version, [RdrNameFixitySig]), -- Local fixity declarations,
239 -- with their version
240 mi_rules :: (Version, [RdrNameRuleDecl]), -- Rules, with their version
241 mi_deprecs :: [RdrNameDeprecation] -- Deprecations
244 type ExportItem = (ModuleName, [RdrAvailInfo])
246 type ImportVersion name = (ModuleName, WhetherHasOrphans, IsBootInterface, WhatsImported name)
248 type ModVersionInfo = (Version, -- Version of the whole module
249 Version, -- Version number for all fixity decls together
250 Version) -- ...ditto all rules together
252 type WhetherHasOrphans = Bool
254 -- * an instance decl in a module other than the defn module for
255 -- one of the tycons or classes in the instance head
256 -- * a transformation rule in a module other than the one defining
257 -- the function in the head of the rule.
259 type IsBootInterface = Bool
261 data WhatsImported name = NothingAtAll -- The module is below us in the
262 -- hierarchy, but we import nothing
264 | Everything Version -- The module version
266 | Specifically Version -- Module version
267 Version -- Fixity version
268 Version -- Rules version
269 [(name,Version)] -- List guaranteed non-empty
271 -- 'Specifically' doesn't let you say "I imported f but none of the fixities in
272 -- the module". If you use anything in the module you get its fixity and rule version
273 -- So if the fixities or rules change, you'll recompile, even if you don't use either.
274 -- This is easy to implement, and it's safer: you might not have used the rules last
275 -- time round, but if someone has added a new rule you might need it this time
277 -- 'Everything' means there was a "module M" in
278 -- this module's export list, so we just have to go by M's version,
279 -- not the list of (name,version) pairs
283 %************************************************************************
285 \subsection{The persistent compiler state}
287 %************************************************************************
290 data PersistentCompilerState
292 pcsPST :: PackageSymbolTable, -- Domain = non-home-package modules
293 -- except that the InstEnv components is empty
294 pcsInsts :: InstEnv, -- The total InstEnv accumulated from all
295 -- the non-home-package modules
296 pcsRules :: RuleEnv, -- Ditto RuleEnv
298 pcsPRS :: PersistentRenamerState
302 The @PersistentRenamerState@ persists across successive calls to the
306 * A name supply, which deals with allocating unique names to
307 (Module,OccName) original names,
309 * An accumulated InstEnv from all the modules in pcsPST
310 The point is that we don't want to keep recreating it whenever
311 we compile a new module. The InstEnv component of pcPST is empty.
312 (This means we might "see" instances that we shouldn't "really" see;
313 but the Haskell Report is vague on what is meant to be visible,
314 so we just take the easy road here.)
318 * A "holding pen" for declarations that have been read out of
319 interface files but not yet sucked in, renamed, and typechecked
322 data PersistentRenamerState
323 = PRS { prsOrig :: OrigNameEnv,
324 prsDecls :: DeclsMap,
325 prsInsts :: IfaceInsts,
326 prsRules :: IfaceRules
330 The OrigNameEnv makes sure that there is just one Unique assigned for
331 each original name; i.e. (module-name, occ-name) pair. The Name is
332 always stored as a Global, and has the SrcLoc of its binding location.
333 Actually that's not quite right. When we first encounter the original
334 name, we might not be at its binding site (e.g. we are reading an
335 interface file); so we give it 'noSrcLoc' then. Later, when we find
336 its binding site, we fix it up.
338 Exactly the same is true of the Module stored in the Name. When we first
339 encounter the occurrence, we may not know the details of the module, so
340 we just store junk. Then when we find the binding site, we fix it up.
344 = Orig { origNames :: FiniteMap (ModuleName,OccName) Name, -- Ensures that one original name gets one unique
345 origIParam :: FiniteMap OccName Name -- Ensures that one implicit parameter name gets one unique
350 A DeclsMap contains a binding for each Name in the declaration
351 including the constructors of a type decl etc. The Bool is True just
355 type DeclsMap = NameEnv (AvailInfo, Bool, (Module, RdrNameHsDecl))
357 type IfaceInsts = Bag GatedDecl
358 type IfaceRules = Bag GatedDecl
360 type GatedDecl = (NameSet, (Module, RdrNameHsDecl))
364 %************************************************************************
366 \subsection{The result of compiling one module}
368 %************************************************************************
372 = CompOK ModDetails -- new details (HST additions)
373 (Maybe (ModIFace, Linkable))
374 -- summary and code; Nothing => compilation not reqd
375 -- (old summary and code are still valid)
376 PersistentCompilerState -- updated PCS
377 (Bag WarnMsg) -- warnings
379 | CompErrs PersistentCompilerState -- updated PCS
380 (Bag ErrMsg) -- errors
381 (Bag WarnMsg) -- warnings
384 -- The driver sits between 'compile' and 'hscMain', translating calls
385 -- to the former into calls to the latter, and results from the latter
386 -- into results from the former. It does things like preprocessing
387 -- the .hs file if necessary, and compiling up the .stub_c files to
388 -- generate Linkables.
391 = HscOK ModDetails -- new details (HomeSymbolTable additions)
392 (Maybe ModIFace) -- new iface (if any compilation was done)
393 (Maybe String) -- generated stub_h
394 (Maybe String) -- generated stub_c
395 PersistentCompilerState -- updated PCS
398 | HscErrs PersistentCompilerState -- updated PCS
403 -- These two are only here to avoid recursion between CmCompile and
404 -- CompManager. They really ought to be in the latter.
405 type ModuleEnv a = UniqFM a -- Domain is Module
407 type HomeModMap = FiniteMap ModuleName Module -- domain: home mods only
408 type HomeInterfaceTable = ModuleEnv ModIFace
412 %************************************************************************
414 \subsection{Provenance and export info}
416 %************************************************************************
418 The GlobalRdrEnv gives maps RdrNames to Names. There is a separate
419 one for each module, corresponding to that module's top-level scope.
422 type GlobalRdrEnv = RdrNameEnv [(Name,Provenance)] -- The list is because there may be name clashes
423 -- These only get reported on lookup,
424 -- not on construction
427 The "provenance" of something says how it came to be in scope.
431 = LocalDef -- Defined locally
433 | NonLocalDef -- Defined non-locally
438 = UserImport Module SrcLoc Bool -- Imported from module M on line L
439 -- Note the M may well not be the defining module
441 -- The Bool is true iff the thing was named *explicitly* in the import spec,
442 -- rather than being imported as part of a group; e.g.
445 -- Here, everything imported by B, and the constructors of T
446 -- are not named explicitly; only T is named explicitly.
447 -- This info is used when warning of unused names.
449 | ImplicitImport -- Imported implicitly for some other reason
452 type PrintUnqualified = Bool -- True <=> the unqualified name of this thing is
453 -- in scope in this module, so print it
454 -- unqualified in error messages
458 hasBetterProv :: Provenance -> Provenance -> Bool
460 -- a local thing over an imported thing
461 -- a user-imported thing over a non-user-imported thing
462 -- an explicitly-imported thing over an implicitly imported thing
463 hasBetterProv LocalDef _ = True
464 hasBetterProv (NonLocalDef (UserImport _ _ True) _) _ = True
465 hasBetterProv (NonLocalDef (UserImport _ _ _ ) _) (NonLocalDef ImplicitImport _) = True
466 hasBetterProv _ _ = False
468 pprNameProvenance :: Name -> Provenance -> SDoc
469 pprProvenance name LocalDef = ptext SLIT("defined at") <+> ppr (nameSrcLoc name)
470 pprProvenance name (NonLocalDef why _) = sep [ppr_reason why,
471 nest 2 (parens (ppr_defn (nameSrcLoc name)))]
473 ppr_reason ImplicitImport = ptext SLIT("implicitly imported")
474 ppr_reason (UserImport mod loc _) = ptext SLIT("imported from") <+> ppr mod <+> ptext SLIT("at") <+> ppr loc
476 ppr_defn loc | isGoodSrcLoc loc = ptext SLIT("at") <+> ppr loc