/ghc-7.0.4/compiler/main/HscTypes.lhs
Haskell | 1710 lines | 887 code | 261 blank | 562 comment | 20 complexity | 644346083585be87dd13674e40378241 MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
Large files files are truncated, but you can click here to view the full file
- %
- % (c) The University of Glasgow, 2006
- %
- \section[HscTypes]{Types for the per-module compiler}
- \begin{code}
- -- | Types for the per-module compiler
- module HscTypes (
- -- * 'Ghc' monad stuff
- Ghc(..), GhcT(..), liftGhcT,
- GhcMonad(..), WarnLogMonad(..),
- liftIO,
- ioMsgMaybe, ioMsg,
- logWarnings, clearWarnings, hasWarnings,
- SourceError, GhcApiError, mkSrcErr, srcErrorMessages, mkApiErr,
- throwOneError, handleSourceError,
- reflectGhc, reifyGhc,
- handleFlagWarnings,
- -- * Sessions and compilation state
- Session(..), withSession, modifySession, withTempSession,
- HscEnv(..), hscEPS,
- FinderCache, FindResult(..), ModLocationCache,
- Target(..), TargetId(..), pprTarget, pprTargetId,
- ModuleGraph, emptyMG,
- -- ** Callbacks
- GhcApiCallbacks(..), withLocalCallbacks,
- -- * Information about modules
- ModDetails(..), emptyModDetails,
- ModGuts(..), CoreModule(..), CgGuts(..), ForeignStubs(..),
- ImportedMods,
- ModSummary(..), ms_mod_name, showModMsg, isBootSummary,
- msHsFilePath, msHiFilePath, msObjFilePath,
- -- * Information about the module being compiled
- HscSource(..), isHsBoot, hscSourceString, -- Re-exported from DriverPhases
-
- -- * State relating to modules in this package
- HomePackageTable, HomeModInfo(..), emptyHomePackageTable,
- hptInstances, hptRules, hptVectInfo,
-
- -- * State relating to known packages
- ExternalPackageState(..), EpsStats(..), addEpsInStats,
- PackageTypeEnv, PackageIfaceTable, emptyPackageIfaceTable,
- lookupIfaceByModule, emptyModIface,
-
- PackageInstEnv, PackageRuleBase,
- -- * Annotations
- prepareAnnotations,
- -- * Interactive context
- InteractiveContext(..), emptyInteractiveContext,
- icPrintUnqual, extendInteractiveContext,
- substInteractiveContext,
- mkPrintUnqualified, pprModulePrefix,
- -- * Interfaces
- ModIface(..), mkIfaceWarnCache, mkIfaceHashCache, mkIfaceFixCache,
- emptyIfaceWarnCache,
- -- * Fixity
- FixityEnv, FixItem(..), lookupFixity, emptyFixityEnv,
- -- * TyThings and type environments
- TyThing(..),
- tyThingClass, tyThingTyCon, tyThingDataCon, tyThingId,
- implicitTyThings, isImplicitTyThing,
-
- TypeEnv, lookupType, lookupTypeHscEnv, mkTypeEnv, emptyTypeEnv,
- extendTypeEnv, extendTypeEnvList, extendTypeEnvWithIds, lookupTypeEnv,
- typeEnvElts, typeEnvClasses, typeEnvTyCons, typeEnvIds,
- typeEnvDataCons,
- -- * MonadThings
- MonadThings(..),
- -- * Information on imports and exports
- WhetherHasOrphans, IsBootInterface, Usage(..),
- Dependencies(..), noDependencies,
- NameCache(..), OrigNameCache, OrigIParamCache,
- Avails, availsToNameSet, availsToNameEnv, availName, availNames,
- GenAvailInfo(..), AvailInfo, RdrAvailInfo,
- IfaceExport,
- -- * Warnings
- Warnings(..), WarningTxt(..), plusWarns,
- -- * Linker stuff
- Linkable(..), isObjectLinkable,
- Unlinked(..), CompiledByteCode,
- isObject, nameOfObject, isInterpretable, byteCodeOfObject,
-
- -- * Program coverage
- HpcInfo(..), emptyHpcInfo, isHpcUsed, AnyHpcUsage,
- -- * Breakpoints
- ModBreaks (..), BreakIndex, emptyModBreaks,
- -- * Vectorisation information
- VectInfo(..), IfaceVectInfo(..), noVectInfo, plusVectInfo,
- noIfaceVectInfo
- ) where
- #include "HsVersions.h"
- #ifdef GHCI
- import ByteCodeAsm ( CompiledByteCode )
- import {-# SOURCE #-} InteractiveEval ( Resume )
- #endif
- import HsSyn
- import RdrName
- import Name
- import NameEnv
- import NameSet
- import Module
- import InstEnv ( InstEnv, Instance )
- import FamInstEnv ( FamInstEnv, FamInst )
- import Rules ( RuleBase )
- import CoreSyn ( CoreBind )
- import VarEnv
- import Var
- import Id
- import Type
- import Annotations
- import Class ( Class, classAllSelIds, classATs, classTyCon )
- import TyCon
- import DataCon ( DataCon, dataConImplicitIds, dataConWrapId )
- import PrelNames ( gHC_PRIM )
- import Packages hiding ( Version(..) )
- import DynFlags ( DynFlags(..), isOneShot, HscTarget (..), dopt,
- DynFlag(..) )
- import DriverPhases ( HscSource(..), isHsBoot, hscSourceString, Phase )
- import BasicTypes ( IPName, defaultFixity, WarningTxt(..) )
- import OptimizationFuel ( OptFuelState )
- import IfaceSyn
- import CoreSyn ( CoreRule )
- import Maybes ( orElse, expectJust, catMaybes )
- import Outputable
- import BreakArray
- import SrcLoc ( SrcSpan, Located(..) )
- import UniqFM ( lookupUFM, eltsUFM, emptyUFM )
- import UniqSupply ( UniqSupply )
- import FastString
- import StringBuffer ( StringBuffer )
- import Fingerprint
- import MonadUtils
- import Data.Dynamic ( Typeable )
- import qualified Data.Dynamic as Dyn
- import Bag
- import ErrUtils
- import System.FilePath
- import System.Time ( ClockTime )
- import Data.IORef
- import Data.Array ( Array, array )
- import Data.List
- import Data.Map (Map)
- import Control.Monad ( mplus, guard, liftM, when )
- import Exception
- \end{code}
- %************************************************************************
- %* *
- \subsection{Compilation environment}
- %* *
- %************************************************************************
- \begin{code}
- -- | The Session is a handle to the complete state of a compilation
- -- session. A compilation session consists of a set of modules
- -- constituting the current program or library, the context for
- -- interactive evaluation, and various caches.
- data Session = Session !(IORef HscEnv) !(IORef WarningMessages)
- mkSrcErr :: ErrorMessages -> SourceError
- srcErrorMessages :: SourceError -> ErrorMessages
- mkApiErr :: SDoc -> GhcApiError
- throwOneError :: MonadIO m => ErrMsg -> m ab
- throwOneError err = liftIO $ throwIO $ mkSrcErr $ unitBag err
- -- | A source error is an error that is caused by one or more errors in the
- -- source code. A 'SourceError' is thrown by many functions in the
- -- compilation pipeline. Inside GHC these errors are merely printed via
- -- 'log_action', but API clients may treat them differently, for example,
- -- insert them into a list box. If you want the default behaviour, use the
- -- idiom:
- --
- -- > handleSourceError printExceptionAndWarnings $ do
- -- > ... api calls that may fail ...
- --
- -- The 'SourceError's error messages can be accessed via 'srcErrorMessages'.
- -- This list may be empty if the compiler failed due to @-Werror@
- -- ('Opt_WarnIsError').
- --
- -- See 'printExceptionAndWarnings' for more information on what to take care
- -- of when writing a custom error handler.
- data SourceError = SourceError ErrorMessages
- instance Show SourceError where
- show (SourceError msgs) = unlines . map show . bagToList $ msgs
- -- ToDo: is there some nicer way to print this?
- sourceErrorTc :: Dyn.TyCon
- sourceErrorTc = Dyn.mkTyCon "SourceError"
- {-# NOINLINE sourceErrorTc #-}
- instance Typeable SourceError where
- typeOf _ = Dyn.mkTyConApp sourceErrorTc []
- instance Exception SourceError
- mkSrcErr = SourceError
- -- | Perform the given action and call the exception handler if the action
- -- throws a 'SourceError'. See 'SourceError' for more information.
- handleSourceError :: (ExceptionMonad m) =>
- (SourceError -> m a) -- ^ exception handler
- -> m a -- ^ action to perform
- -> m a
- handleSourceError handler act =
- gcatch act (\(e :: SourceError) -> handler e)
- srcErrorMessages (SourceError msgs) = msgs
- -- | XXX: what exactly is an API error?
- data GhcApiError = GhcApiError SDoc
- instance Show GhcApiError where
- show (GhcApiError msg) = showSDoc msg
- ghcApiErrorTc :: Dyn.TyCon
- ghcApiErrorTc = Dyn.mkTyCon "GhcApiError"
- {-# NOINLINE ghcApiErrorTc #-}
- instance Typeable GhcApiError where
- typeOf _ = Dyn.mkTyConApp ghcApiErrorTc []
- instance Exception GhcApiError
- mkApiErr = GhcApiError
- -- | A monad that allows logging of warnings.
- class Monad m => WarnLogMonad m where
- setWarnings :: WarningMessages -> m ()
- getWarnings :: m WarningMessages
- logWarnings :: WarnLogMonad m => WarningMessages -> m ()
- logWarnings warns = do
- warns0 <- getWarnings
- setWarnings (unionBags warns warns0)
- -- | Clear the log of 'Warnings'.
- clearWarnings :: WarnLogMonad m => m ()
- clearWarnings = setWarnings emptyBag
- -- | Returns true if there were any warnings.
- hasWarnings :: WarnLogMonad m => m Bool
- hasWarnings = getWarnings >>= return . not . isEmptyBag
- -- | A monad that has all the features needed by GHC API calls.
- --
- -- In short, a GHC monad
- --
- -- - allows embedding of IO actions,
- --
- -- - can log warnings,
- --
- -- - allows handling of (extensible) exceptions, and
- --
- -- - maintains a current session.
- --
- -- If you do not use 'Ghc' or 'GhcT', make sure to call 'GHC.initGhcMonad'
- -- before any call to the GHC API functions can occur.
- --
- class (Functor m, MonadIO m, WarnLogMonad m, ExceptionMonad m)
- => GhcMonad m where
- getSession :: m HscEnv
- setSession :: HscEnv -> m ()
- -- | Call the argument with the current session.
- withSession :: GhcMonad m => (HscEnv -> m a) -> m a
- withSession f = getSession >>= f
- -- | Set the current session to the result of applying the current session to
- -- the argument.
- modifySession :: GhcMonad m => (HscEnv -> HscEnv) -> m ()
- modifySession f = do h <- getSession
- setSession $! f h
- withSavedSession :: GhcMonad m => m a -> m a
- withSavedSession m = do
- saved_session <- getSession
- m `gfinally` setSession saved_session
- -- | Call an action with a temporarily modified Session.
- withTempSession :: GhcMonad m => (HscEnv -> HscEnv) -> m a -> m a
- withTempSession f m =
- withSavedSession $ modifySession f >> m
- -- | A minimal implementation of a 'GhcMonad'. If you need a custom monad,
- -- e.g., to maintain additional state consider wrapping this monad or using
- -- 'GhcT'.
- newtype Ghc a = Ghc { unGhc :: Session -> IO a }
- instance Functor Ghc where
- fmap f m = Ghc $ \s -> f `fmap` unGhc m s
- instance Monad Ghc where
- return a = Ghc $ \_ -> return a
- m >>= g = Ghc $ \s -> do a <- unGhc m s; unGhc (g a) s
- instance MonadIO Ghc where
- liftIO ioA = Ghc $ \_ -> ioA
- instance ExceptionMonad Ghc where
- gcatch act handle =
- Ghc $ \s -> unGhc act s `gcatch` \e -> unGhc (handle e) s
- gblock (Ghc m) = Ghc $ \s -> gblock (m s)
- gunblock (Ghc m) = Ghc $ \s -> gunblock (m s)
- gmask f =
- Ghc $ \s -> gmask $ \io_restore ->
- let
- g_restore (Ghc m) = Ghc $ \s -> io_restore (m s)
- in
- unGhc (f g_restore) s
- instance WarnLogMonad Ghc where
- setWarnings warns = Ghc $ \(Session _ wref) -> writeIORef wref warns
- -- | Return 'Warnings' accumulated so far.
- getWarnings = Ghc $ \(Session _ wref) -> readIORef wref
- instance GhcMonad Ghc where
- getSession = Ghc $ \(Session r _) -> readIORef r
- setSession s' = Ghc $ \(Session r _) -> writeIORef r s'
- -- | A monad transformer to add GHC specific features to another monad.
- --
- -- Note that the wrapped monad must support IO and handling of exceptions.
- newtype GhcT m a = GhcT { unGhcT :: Session -> m a }
- liftGhcT :: Monad m => m a -> GhcT m a
- liftGhcT m = GhcT $ \_ -> m
- instance Functor m => Functor (GhcT m) where
- fmap f m = GhcT $ \s -> f `fmap` unGhcT m s
- instance Monad m => Monad (GhcT m) where
- return x = GhcT $ \_ -> return x
- m >>= k = GhcT $ \s -> do a <- unGhcT m s; unGhcT (k a) s
- instance MonadIO m => MonadIO (GhcT m) where
- liftIO ioA = GhcT $ \_ -> liftIO ioA
- instance ExceptionMonad m => ExceptionMonad (GhcT m) where
- gcatch act handle =
- GhcT $ \s -> unGhcT act s `gcatch` \e -> unGhcT (handle e) s
- gblock (GhcT m) = GhcT $ \s -> gblock (m s)
- gunblock (GhcT m) = GhcT $ \s -> gunblock (m s)
- gmask f =
- GhcT $ \s -> gmask $ \io_restore ->
- let
- g_restore (GhcT m) = GhcT $ \s -> io_restore (m s)
- in
- unGhcT (f g_restore) s
- instance MonadIO m => WarnLogMonad (GhcT m) where
- setWarnings warns = GhcT $ \(Session _ wref) -> liftIO $ writeIORef wref warns
- -- | Return 'Warnings' accumulated so far.
- getWarnings = GhcT $ \(Session _ wref) -> liftIO $ readIORef wref
- instance (Functor m, ExceptionMonad m, MonadIO m) => GhcMonad (GhcT m) where
- getSession = GhcT $ \(Session r _) -> liftIO $ readIORef r
- setSession s' = GhcT $ \(Session r _) -> liftIO $ writeIORef r s'
- -- | Lift an IO action returning errors messages into a 'GhcMonad'.
- --
- -- In order to reduce dependencies to other parts of the compiler, functions
- -- outside the "main" parts of GHC return warnings and errors as a parameter
- -- and signal success via by wrapping the result in a 'Maybe' type. This
- -- function logs the returned warnings and propagates errors as exceptions
- -- (of type 'SourceError').
- --
- -- This function assumes the following invariants:
- --
- -- 1. If the second result indicates success (is of the form 'Just x'),
- -- there must be no error messages in the first result.
- --
- -- 2. If there are no error messages, but the second result indicates failure
- -- there should be warnings in the first result. That is, if the action
- -- failed, it must have been due to the warnings (i.e., @-Werror@).
- ioMsgMaybe :: GhcMonad m =>
- IO (Messages, Maybe a) -> m a
- ioMsgMaybe ioA = do
- ((warns,errs), mb_r) <- liftIO ioA
- logWarnings warns
- case mb_r of
- Nothing -> liftIO $ throwIO (mkSrcErr errs)
- Just r -> ASSERT( isEmptyBag errs ) return r
- -- | Lift a non-failing IO action into a 'GhcMonad'.
- --
- -- Like 'ioMsgMaybe', but assumes that the action will never return any error
- -- messages.
- ioMsg :: GhcMonad m => IO (Messages, a) -> m a
- ioMsg ioA = do
- ((warns,errs), r) <- liftIO ioA
- logWarnings warns
- ASSERT( isEmptyBag errs ) return r
- -- | Reflect a computation in the 'Ghc' monad into the 'IO' monad.
- --
- -- You can use this to call functions returning an action in the 'Ghc' monad
- -- inside an 'IO' action. This is needed for some (too restrictive) callback
- -- arguments of some library functions:
- --
- -- > libFunc :: String -> (Int -> IO a) -> IO a
- -- > ghcFunc :: Int -> Ghc a
- -- >
- -- > ghcFuncUsingLibFunc :: String -> Ghc a -> Ghc a
- -- > ghcFuncUsingLibFunc str =
- -- > reifyGhc $ \s ->
- -- > libFunc $ \i -> do
- -- > reflectGhc (ghcFunc i) s
- --
- reflectGhc :: Ghc a -> Session -> IO a
- reflectGhc m = unGhc m
- -- > Dual to 'reflectGhc'. See its documentation.
- reifyGhc :: (Session -> IO a) -> Ghc a
- reifyGhc act = Ghc $ act
- handleFlagWarnings :: GhcMonad m => DynFlags -> [Located String] -> m ()
- handleFlagWarnings dflags warns
- = when (dopt Opt_WarnDeprecatedFlags dflags)
- (handleFlagWarnings' dflags warns)
- handleFlagWarnings' :: GhcMonad m => DynFlags -> [Located String] -> m ()
- handleFlagWarnings' _ [] = return ()
- handleFlagWarnings' dflags warns
- = do -- It would be nicer if warns :: [Located Message], but that has circular
- -- import problems.
- logWarnings $ listToBag (map mkFlagWarning warns)
- when (dopt Opt_WarnIsError dflags) $
- liftIO $ throwIO $ mkSrcErr emptyBag
- mkFlagWarning :: Located String -> WarnMsg
- mkFlagWarning (L loc warn)
- = mkPlainWarnMsg loc (text warn)
- \end{code}
- \begin{code}
- -- | These functions are called in various places of the GHC API.
- --
- -- API clients can override any of these callbacks to change GHC's default
- -- behaviour.
- data GhcApiCallbacks
- = GhcApiCallbacks {
- -- | Called by 'load' after the compilating of each module.
- --
- -- The default implementation simply prints all warnings and errors to
- -- @stderr@. Don't forget to call 'clearWarnings' when implementing your
- -- own call.
- --
- -- The first argument is the module that was compiled.
- --
- -- The second argument is @Nothing@ if no errors occured, but there may
- -- have been warnings. If it is @Just err@ at least one error has
- -- occured. If 'srcErrorMessages' is empty, compilation failed due to
- -- @-Werror@.
- reportModuleCompilationResult :: GhcMonad m =>
- ModSummary -> Maybe SourceError
- -> m ()
- }
- -- | Temporarily modify the callbacks. After the action is executed all
- -- callbacks are reset (not, however, any other modifications to the session
- -- state.)
- withLocalCallbacks :: GhcMonad m =>
- (GhcApiCallbacks -> GhcApiCallbacks)
- -> m a -> m a
- withLocalCallbacks f m = do
- hsc_env <- getSession
- let cb0 = hsc_callbacks hsc_env
- let cb' = f cb0
- setSession (hsc_env { hsc_callbacks = cb' `seq` cb' })
- r <- m
- hsc_env' <- getSession
- setSession (hsc_env' { hsc_callbacks = cb0 })
- return r
- \end{code}
- \begin{code}
- -- | Hscenv is like 'Session', except that some of the fields are immutable.
- -- An HscEnv is used to compile a single module from plain Haskell source
- -- code (after preprocessing) to either C, assembly or C--. Things like
- -- the module graph don't change during a single compilation.
- --
- -- Historical note: \"hsc\" used to be the name of the compiler binary,
- -- when there was a separate driver and compiler. To compile a single
- -- module, the driver would invoke hsc on the source code... so nowadays
- -- we think of hsc as the layer of the compiler that deals with compiling
- -- a single module.
- data HscEnv
- = HscEnv {
- hsc_dflags :: DynFlags,
- -- ^ The dynamic flag settings
- hsc_callbacks :: GhcApiCallbacks,
- -- ^ Callbacks for the GHC API.
- hsc_targets :: [Target],
- -- ^ The targets (or roots) of the current session
- hsc_mod_graph :: ModuleGraph,
- -- ^ The module graph of the current session
- hsc_IC :: InteractiveContext,
- -- ^ The context for evaluating interactive statements
- hsc_HPT :: HomePackageTable,
- -- ^ The home package table describes already-compiled
- -- home-package modules, /excluding/ the module we
- -- are compiling right now.
- -- (In one-shot mode the current module is the only
- -- home-package module, so hsc_HPT is empty. All other
- -- modules count as \"external-package\" modules.
- -- However, even in GHCi mode, hi-boot interfaces are
- -- demand-loaded into the external-package table.)
- --
- -- 'hsc_HPT' is not mutable because we only demand-load
- -- external packages; the home package is eagerly
- -- loaded, module by module, by the compilation manager.
- --
- -- The HPT may contain modules compiled earlier by @--make@
- -- but not actually below the current module in the dependency
- -- graph.
- -- (This changes a previous invariant: changed Jan 05.)
-
- hsc_EPS :: {-# UNPACK #-} !(IORef ExternalPackageState),
- -- ^ Information about the currently loaded external packages.
- -- This is mutable because packages will be demand-loaded during
- -- a compilation run as required.
-
- hsc_NC :: {-# UNPACK #-} !(IORef NameCache),
- -- ^ As with 'hsc_EPS', this is side-effected by compiling to
- -- reflect sucking in interface files. They cache the state of
- -- external interface files, in effect.
- hsc_FC :: {-# UNPACK #-} !(IORef FinderCache),
- -- ^ The cached result of performing finding in the file system
- hsc_MLC :: {-# UNPACK #-} !(IORef ModLocationCache),
- -- ^ This caches the location of modules, so we don't have to
- -- search the filesystem multiple times. See also 'hsc_FC'.
- hsc_OptFuel :: OptFuelState,
- -- ^ Settings to control the use of \"optimization fuel\":
- -- by limiting the number of transformations,
- -- we can use binary search to help find compiler bugs.
- hsc_type_env_var :: Maybe (Module, IORef TypeEnv)
- -- ^ Used for one-shot compilation only, to initialise
- -- the 'IfGblEnv'. See 'TcRnTypes.tcg_type_env_var' for
- -- 'TcRunTypes.TcGblEnv'
- }
- hscEPS :: HscEnv -> IO ExternalPackageState
- hscEPS hsc_env = readIORef (hsc_EPS hsc_env)
- -- | A compilation target.
- --
- -- A target may be supplied with the actual text of the
- -- module. If so, use this instead of the file contents (this
- -- is for use in an IDE where the file hasn't been saved by
- -- the user yet).
- data Target = Target
- { targetId :: TargetId -- ^ module or filename
- , targetAllowObjCode :: Bool -- ^ object code allowed?
- , targetContents :: Maybe (StringBuffer,ClockTime)
- -- ^ in-memory text buffer?
- }
- data TargetId
- = TargetModule ModuleName
- -- ^ A module name: search for the file
- | TargetFile FilePath (Maybe Phase)
- -- ^ A filename: preprocess & parse it to find the module name.
- -- If specified, the Phase indicates how to compile this file
- -- (which phase to start from). Nothing indicates the starting phase
- -- should be determined from the suffix of the filename.
- deriving Eq
- pprTarget :: Target -> SDoc
- pprTarget (Target id obj _) =
- (if obj then char '*' else empty) <> pprTargetId id
- instance Outputable Target where
- ppr = pprTarget
- pprTargetId :: TargetId -> SDoc
- pprTargetId (TargetModule m) = ppr m
- pprTargetId (TargetFile f _) = text f
- instance Outputable TargetId where
- ppr = pprTargetId
- -- | Helps us find information about modules in the home package
- type HomePackageTable = ModuleNameEnv HomeModInfo
- -- Domain = modules in the home package that have been fully compiled
- -- "home" package name cached here for convenience
- -- | Helps us find information about modules in the imported packages
- type PackageIfaceTable = ModuleEnv ModIface
- -- Domain = modules in the imported packages
- emptyHomePackageTable :: HomePackageTable
- emptyHomePackageTable = emptyUFM
- emptyPackageIfaceTable :: PackageIfaceTable
- emptyPackageIfaceTable = emptyModuleEnv
- -- | Information about modules in the package being compiled
- data HomeModInfo
- = HomeModInfo {
- hm_iface :: !ModIface,
- -- ^ The basic loaded interface file: every loaded module has one of
- -- these, even if it is imported from another package
- hm_details :: !ModDetails,
- -- ^ Extra information that has been created from the 'ModIface' for
- -- the module, typically during typechecking
- hm_linkable :: !(Maybe Linkable)
- -- ^ The actual artifact we would like to link to access things in
- -- this module.
- --
- -- 'hm_linkable' might be Nothing:
- --
- -- 1. If this is an .hs-boot module
- --
- -- 2. Temporarily during compilation if we pruned away
- -- the old linkable because it was out of date.
- --
- -- After a complete compilation ('GHC.load'), all 'hm_linkable' fields
- -- in the 'HomePackageTable' will be @Just@.
- --
- -- When re-linking a module ('HscMain.HscNoRecomp'), we construct the
- -- 'HomeModInfo' by building a new 'ModDetails' from the old
- -- 'ModIface' (only).
- }
- -- | Find the 'ModIface' for a 'Module', searching in both the loaded home
- -- and external package module information
- lookupIfaceByModule
- :: DynFlags
- -> HomePackageTable
- -> PackageIfaceTable
- -> Module
- -> Maybe ModIface
- lookupIfaceByModule dflags hpt pit mod
- | modulePackageId mod == thisPackage dflags
- = -- The module comes from the home package, so look first
- -- in the HPT. If it's not from the home package it's wrong to look
- -- in the HPT, because the HPT is indexed by *ModuleName* not Module
- fmap hm_iface (lookupUFM hpt (moduleName mod))
- `mplus` lookupModuleEnv pit mod
- | otherwise = lookupModuleEnv pit mod -- Look in PIT only
- -- If the module does come from the home package, why do we look in the PIT as well?
- -- (a) In OneShot mode, even home-package modules accumulate in the PIT
- -- (b) Even in Batch (--make) mode, there is *one* case where a home-package
- -- module is in the PIT, namely GHC.Prim when compiling the base package.
- -- We could eliminate (b) if we wanted, by making GHC.Prim belong to a package
- -- of its own, but it doesn't seem worth the bother.
- \end{code}
- \begin{code}
- hptInstances :: HscEnv -> (ModuleName -> Bool) -> ([Instance], [FamInst])
- -- ^ Find all the instance declarations (of classes and families) that are in
- -- modules imported by this one, directly or indirectly, and are in the Home
- -- Package Table. This ensures that we don't see instances from modules @--make@
- -- compiled before this one, but which are not below this one.
- hptInstances hsc_env want_this_module
- = let (insts, famInsts) = unzip $ flip hptAllThings hsc_env $ \mod_info -> do
- guard (want_this_module (moduleName (mi_module (hm_iface mod_info))))
- let details = hm_details mod_info
- return (md_insts details, md_fam_insts details)
- in (concat insts, concat famInsts)
- hptVectInfo :: HscEnv -> VectInfo
- -- ^ Get the combined VectInfo of all modules in the home package table. In
- -- contrast to instances and rules, we don't care whether the modules are
- -- \"below\" us in the dependency sense. The VectInfo of those modules not \"below\"
- -- us does not affect the compilation of the current module.
- hptVectInfo = concatVectInfo . hptAllThings ((: []) . md_vect_info . hm_details)
- hptRules :: HscEnv -> [(ModuleName, IsBootInterface)] -> [CoreRule]
- -- ^ Get rules from modules \"below\" this one (in the dependency sense)
- hptRules = hptSomeThingsBelowUs (md_rules . hm_details) False
- hptAnns :: HscEnv -> Maybe [(ModuleName, IsBootInterface)] -> [Annotation]
- -- ^ Get annotations from modules \"below\" this one (in the dependency sense)
- hptAnns hsc_env (Just deps) = hptSomeThingsBelowUs (md_anns . hm_details) False hsc_env deps
- hptAnns hsc_env Nothing = hptAllThings (md_anns . hm_details) hsc_env
- hptAllThings :: (HomeModInfo -> [a]) -> HscEnv -> [a]
- hptAllThings extract hsc_env = concatMap extract (eltsUFM (hsc_HPT hsc_env))
- hptSomeThingsBelowUs :: (HomeModInfo -> [a]) -> Bool -> HscEnv -> [(ModuleName, IsBootInterface)] -> [a]
- -- Get things from modules \"below\" this one (in the dependency sense)
- -- C.f Inst.hptInstances
- hptSomeThingsBelowUs extract include_hi_boot hsc_env deps
- | isOneShot (ghcMode (hsc_dflags hsc_env)) = []
- | otherwise
- = let
- hpt = hsc_HPT hsc_env
- in
- [ thing
- | -- Find each non-hi-boot module below me
- (mod, is_boot_mod) <- deps
- , include_hi_boot || not is_boot_mod
- -- unsavoury: when compiling the base package with --make, we
- -- sometimes try to look up RULES etc for GHC.Prim. GHC.Prim won't
- -- be in the HPT, because we never compile it; it's in the EPT
- -- instead. ToDo: clean up, and remove this slightly bogus
- -- filter:
- , mod /= moduleName gHC_PRIM
- -- Look it up in the HPT
- , let things = case lookupUFM hpt mod of
- Just info -> extract info
- Nothing -> pprTrace "WARNING in hptSomeThingsBelowUs" msg []
- msg = vcat [ptext (sLit "missing module") <+> ppr mod,
- ptext (sLit "Probable cause: out-of-date interface files")]
- -- This really shouldn't happen, but see Trac #962
- -- And get its dfuns
- , thing <- things ]
- \end{code}
- %************************************************************************
- %* *
- \subsection{Dealing with Annotations}
- %* *
- %************************************************************************
- \begin{code}
- prepareAnnotations :: HscEnv -> Maybe ModGuts -> IO AnnEnv
- -- ^ Deal with gathering annotations in from all possible places
- -- and combining them into a single 'AnnEnv'
- prepareAnnotations hsc_env mb_guts
- = do { eps <- hscEPS hsc_env
- ; let -- Extract annotations from the module being compiled if supplied one
- mb_this_module_anns = fmap (mkAnnEnv . mg_anns) mb_guts
- -- Extract dependencies of the module if we are supplied one,
- -- otherwise load annotations from all home package table
- -- entries regardless of dependency ordering.
- home_pkg_anns = (mkAnnEnv . hptAnns hsc_env) $ fmap (dep_mods . mg_deps) mb_guts
- other_pkg_anns = eps_ann_env eps
- ann_env = foldl1' plusAnnEnv $ catMaybes [mb_this_module_anns,
- Just home_pkg_anns,
- Just other_pkg_anns]
- ; return ann_env }
- \end{code}
- %************************************************************************
- %* *
- \subsection{The Finder cache}
- %* *
- %************************************************************************
- \begin{code}
- -- | The 'FinderCache' maps home module names to the result of
- -- searching for that module. It records the results of searching for
- -- modules along the search path. On @:load@, we flush the entire
- -- contents of this cache.
- --
- -- Although the @FinderCache@ range is 'FindResult' for convenience ,
- -- in fact it will only ever contain 'Found' or 'NotFound' entries.
- --
- type FinderCache = ModuleNameEnv FindResult
- -- | The result of searching for an imported module.
- data FindResult
- = Found ModLocation Module
- -- ^ The module was found
- | NoPackage PackageId
- -- ^ The requested package was not found
- | FoundMultiple [PackageId]
- -- ^ _Error_: both in multiple packages
- | NotFound [FilePath] (Maybe PackageId) [PackageId] [PackageId]
- -- ^ The module was not found, including either
- -- * the specified places were searched
- -- * the package that this module should have been in
- -- * list of packages in which the module was hidden,
- -- * list of hidden packages containing this module
- | NotFoundInPackage PackageId
- -- ^ The module was not found in this package
- -- | Cache that remembers where we found a particular module. Contains both
- -- home modules and package modules. On @:load@, only home modules are
- -- purged from this cache.
- type ModLocationCache = ModuleEnv ModLocation
- \end{code}
- %************************************************************************
- %* *
- \subsection{Symbol tables and Module details}
- %* *
- %************************************************************************
- \begin{code}
- -- | A 'ModIface' plus a 'ModDetails' summarises everything we know
- -- about a compiled module. The 'ModIface' is the stuff *before* linking,
- -- and can be written out to an interface file. The 'ModDetails is after
- -- linking and can be completely recovered from just the 'ModIface'.
- --
- -- When we read an interface file, we also construct a 'ModIface' from it,
- -- except that we explicitly make the 'mi_decls' and a few other fields empty;
- -- as when reading we consolidate the declarations etc. into a number of indexed
- -- maps and environments in the 'ExternalPackageState'.
- data ModIface
- = ModIface {
- mi_module :: !Module, -- ^ Name of the module we are for
- mi_iface_hash :: !Fingerprint, -- ^ Hash of the whole interface
- mi_mod_hash :: !Fingerprint, -- ^ Hash of the ABI only
- mi_orphan :: !WhetherHasOrphans, -- ^ Whether this module has orphans
- mi_finsts :: !WhetherHasFamInst, -- ^ Whether this module has family instances
- mi_boot :: !IsBootInterface, -- ^ Read from an hi-boot file?
- mi_deps :: Dependencies,
- -- ^ The dependencies of the module. This is
- -- consulted for directly-imported modules, but not
- -- for anything else (hence lazy)
- mi_usages :: [Usage],
- -- ^ Usages; kept sorted so that it's easy to decide
- -- whether to write a new iface file (changing usages
- -- doesn't affect the hash of this module)
-
- -- NOT STRICT! we read this field lazily from the interface file
- -- It is *only* consulted by the recompilation checker
- -- Exports
- -- Kept sorted by (mod,occ), to make version comparisons easier
- mi_exports :: ![IfaceExport],
- -- ^ Records the modules that are the declaration points for things
- -- exported by this module, and the 'OccName's of those things
-
- mi_exp_hash :: !Fingerprint, -- ^ Hash of export list
- mi_fixities :: [(OccName,Fixity)],
- -- ^ Fixities
-
- -- NOT STRICT! we read this field lazily from the interface file
- mi_warns :: Warnings,
- -- ^ Warnings
-
- -- NOT STRICT! we read this field lazily from the interface file
- mi_anns :: [IfaceAnnotation],
- -- ^ Annotations
-
- -- NOT STRICT! we read this field lazily from the interface file
- -- Type, class and variable declarations
- -- The hash of an Id changes if its fixity or deprecations change
- -- (as well as its type of course)
- -- Ditto data constructors, class operations, except that
- -- the hash of the parent class/tycon changes
- mi_decls :: [(Fingerprint,IfaceDecl)], -- ^ Sorted type, variable, class etc. declarations
- mi_globals :: !(Maybe GlobalRdrEnv),
- -- ^ Binds all the things defined at the top level in
- -- the /original source/ code for this module. which
- -- is NOT the same as mi_exports, nor mi_decls (which
- -- may contains declarations for things not actually
- -- defined by the user). Used for GHCi and for inspecting
- -- the contents of modules via the GHC API only.
- --
- -- (We need the source file to figure out the
- -- top-level environment, if we didn't compile this module
- -- from source then this field contains @Nothing@).
- --
- -- Strictly speaking this field should live in the
- -- 'HomeModInfo', but that leads to more plumbing.
- -- Instance declarations and rules
- mi_insts :: [IfaceInst], -- ^ Sorted class instance
- mi_fam_insts :: [IfaceFamInst], -- ^ Sorted family instances
- mi_rules :: [IfaceRule], -- ^ Sorted rules
- mi_orphan_hash :: !Fingerprint, -- ^ Hash for orphan rules and
- -- class and family instances
- -- combined
- mi_vect_info :: !IfaceVectInfo, -- ^ Vectorisation information
- -- Cached environments for easy lookup
- -- These are computed (lazily) from other fields
- -- and are not put into the interface file
- mi_warn_fn :: Name -> Maybe WarningTxt, -- ^ Cached lookup for 'mi_warns'
- mi_fix_fn :: OccName -> Fixity, -- ^ Cached lookup for 'mi_fixities'
- mi_hash_fn :: OccName -> Maybe (OccName, Fingerprint),
- -- ^ Cached lookup for 'mi_decls'.
- -- The @Nothing@ in 'mi_hash_fn' means that the thing
- -- isn't in decls. It's useful to know that when
- -- seeing if we are up to date wrt. the old interface.
- -- The 'OccName' is the parent of the name, if it has one.
- mi_hpc :: !AnyHpcUsage
- -- ^ True if this program uses Hpc at any point in the program.
- }
- -- | The 'ModDetails' is essentially a cache for information in the 'ModIface'
- -- for home modules only. Information relating to packages will be loaded into
- -- global environments in 'ExternalPackageState'.
- data ModDetails
- = ModDetails {
- -- The next two fields are created by the typechecker
- md_exports :: [AvailInfo],
- md_types :: !TypeEnv, -- ^ Local type environment for this particular module
- md_insts :: ![Instance], -- ^ 'DFunId's for the instances in this module
- md_fam_insts :: ![FamInst],
- md_rules :: ![CoreRule], -- ^ Domain may include 'Id's from other modules
- md_anns :: ![Annotation], -- ^ Annotations present in this module: currently
- -- they only annotate things also declared in this module
- md_vect_info :: !VectInfo -- ^ Module vectorisation information
- }
- emptyModDetails :: ModDetails
- emptyModDetails = ModDetails { md_types = emptyTypeEnv,
- md_exports = [],
- md_insts = [],
- md_rules = [],
- md_fam_insts = [],
- md_anns = [],
- md_vect_info = noVectInfo
- }
- -- | Records the modules directly imported by a module for extracting e.g. usage information
- type ImportedMods = ModuleEnv [(ModuleName, Bool, SrcSpan)]
- -- TODO: we are not actually using the codomain of this type at all, so it can be
- -- replaced with ModuleEnv ()
- -- | A ModGuts is carried through the compiler, accumulating stuff as it goes
- -- There is only one ModGuts at any time, the one for the module
- -- being compiled right now. Once it is compiled, a 'ModIface' and
- -- 'ModDetails' are extracted and the ModGuts is dicarded.
- data ModGuts
- = ModGuts {
- mg_module :: !Module, -- ^ Module being compiled
- mg_boot :: IsBootInterface, -- ^ Whether it's an hs-boot module
- mg_exports :: ![AvailInfo], -- ^ What it exports
- mg_deps :: !Dependencies, -- ^ What it depends on, directly or
- -- otherwise
- mg_dir_imps :: !ImportedMods, -- ^ Directly-imported modules; used to
- -- generate initialisation code
- mg_used_names:: !NameSet, -- ^ What the module needed (used in 'MkIface.mkIface')
- mg_rdr_env :: !GlobalRdrEnv, -- ^ Top-level lexical environment
- -- These fields all describe the things **declared in this module**
- mg_fix_env :: !FixityEnv, -- ^ Fixities declared in this module
- -- TODO: I'm unconvinced this is actually used anywhere
- mg_types :: !TypeEnv, -- ^ Types declared in this module
- mg_insts :: ![Instance], -- ^ Class instances declared in this module
- mg_fam_insts :: ![FamInst], -- ^ Family instances declared in this module
- mg_rules :: ![CoreRule], -- ^ Before the core pipeline starts, contains
- -- See Note [Overall plumbing for rules] in Rules.lhs
- mg_binds :: ![CoreBind], -- ^ Bindings for this module
- mg_foreign :: !ForeignStubs, -- ^ Foreign exports declared in this module
- mg_warns :: !Warnings, -- ^ Warnings declared in the module
- mg_anns :: [Annotation], -- ^ Annotations declared in this module
- mg_hpc_info :: !HpcInfo, -- ^ Coverage tick boxes in the module
- mg_modBreaks :: !ModBreaks, -- ^ Breakpoints for the module
- mg_vect_info :: !VectInfo, -- ^ Pool of vectorised declarations in the module
- -- The next two fields are unusual, because they give instance
- -- environments for *all* modules in the home package, including
- -- this module, rather than for *just* this module.
- -- Reason: when looking up an instance we don't want to have to
- -- look at each module in the home package in turn
- mg_inst_env :: InstEnv,
- -- ^ Class instance environment from /home-package/ modules (including
- -- this one); c.f. 'tcg_inst_env'
- mg_fam_inst_env :: FamInstEnv
- -- ^ Type-family instance enviroment for /home-package/ modules
- -- (including this one); c.f. 'tcg_fam_inst_env'
- }
- -- The ModGuts takes on several slightly different forms:
- --
- -- After simplification, the following fields change slightly:
- -- mg_rules Orphan rules only (local ones now attached to binds)
- -- mg_binds With rules attached
- -- | A CoreModule consists of just the fields of a 'ModGuts' that are needed for
- -- the 'GHC.compileToCoreModule' interface.
- data CoreModule
- = CoreModule {
- -- | Module name
- cm_module :: !Module,
- -- | Type environment for types declared in this module
- cm_types :: !TypeEnv,
- -- | Declarations
- cm_binds :: [CoreBind],
- -- | Imports
- cm_imports :: ![Module]
- }
- instance Outputable CoreModule where
- ppr (CoreModule {cm_module = mn, cm_types = te, cm_binds = cb}) =
- text "%module" <+> ppr mn <+> ppr te $$ vcat (map ppr cb)
- -- The ModGuts takes on several slightly different forms:
- --
- -- After simplification, the following fields change slightly:
- -- mg_rules Orphan rules only (local ones now attached to binds)
- -- mg_binds With rules attached
- ---------------------------------------------------------
- -- The Tidy pass forks the information about this module:
- -- * one lot goes to interface file generation (ModIface)
- -- and later compilations (ModDetails)
- -- * the other lot goes to code generation (CgGuts)
- -- | A restricted form of 'ModGuts' for code generation purposes
- data CgGuts
- = CgGuts {
- cg_module :: !Module, -- ^ Module being compiled
- cg_tycons :: [TyCon],
- -- ^ Algebraic data types (including ones that started
- -- life as classes); generate constructors and info
- -- tables. Includes newtypes, just for the benefit of
- -- External Core
- cg_binds :: [CoreBind],
- -- ^ The tidied main bindings, including
- -- previously-implicit bindings for record and class
- -- selectors, and data construtor wrappers. But *not*
- -- data constructor workers; reason: we we regard them
- -- as part of the code-gen of tycons
- cg_dir_imps :: ![Module],
- -- ^ Directly-imported modules; used to generate
- -- initialisation code
- cg_foreign :: !ForeignStubs, -- ^ Foreign export stubs
- cg_dep_pkgs :: ![PackageId], -- ^ Dependent packages, used to
- -- generate #includes for C code gen
- cg_hpc_info :: !HpcInfo, -- ^ Program coverage tick box information
- cg_modBreaks :: !ModBreaks -- ^ Module breakpoints
- }
- -----------------------------------
- -- | Foreign export stubs
- data ForeignStubs = NoStubs -- ^ We don't have any stubs
- | ForeignStubs
- SDoc
- SDoc
- -- ^ There are some stubs. Parameters:
- --
- -- 1) Header file prototypes for
- -- "foreign exported" functions
- --
- -- 2) C stubs to use when calling
- -- "foreign exported" functions
- \end{code}
- \begin{code}
- emptyModIface :: Module -> ModIface
- emptyModIface mod
- = ModIface { mi_module = mod,
- mi_iface_hash = fingerprint0,
- mi_mod_hash = fingerprint0,
- mi_orphan = False,
- mi_finsts = False,
- mi_boot = False,
- mi_deps = noDependencies,
- mi_usages = [],
- mi_exports = [],
- mi_exp_hash = fingerprint0,
- mi_fixities = [],
- mi_warns = NoWarnings,
- mi_anns = [],
- mi_insts = [],
- mi_fam_insts = [],
- mi_rules = [],
- mi_decls = [],
- mi_globals = Nothing,
- mi_orphan_hash = fingerprint0,
- mi_vect_info = noIfaceVectInfo,
- mi_warn_fn = emptyIfaceWarnCache,
- mi_fix_fn = emptyIfaceFixCache,
- mi_hash_fn = emptyIfaceHashCache,
- mi_hpc = False
- }
- \end{code}
- %************************************************************************
- %* *
- \subsection{The interactive context}
- %* *
- %************************************************************************
- \begin{code}
- -- | Interactive context, recording information relevant to GHCi
- data InteractiveContext
- = InteractiveContext {
- ic_toplev_scope :: [Module] -- ^ The context includes the "top-level" scope of
- -- these modules
- , ic_exports :: [(Module, Maybe (ImportDecl RdrName))] -- ^ The context includes just the exported parts of these
- -- modules
- , ic_rn_gbl_env :: GlobalRdrEnv -- ^ The contexts' cached 'GlobalRdrEnv', built from
- -- 'ic_toplev_scope' and 'ic_exports'
- , ic_tmp_ids :: [Id] -- ^ Names bound during interaction with the user.
- -- Later Ids shadow earlier ones with the same OccName
- -- Expressions are typed with these Ids in the envt
- -- For runtime-debugging, these Ids may have free
- -- TcTyVars of RuntimUnkSkol flavour, but no free TyVars
- -- (because the typechecker doesn't expect that)
- #ifdef GHCI
- , ic_resume :: [Resume] -- ^ The stack of breakpoint contexts
- #endif
- , ic_cwd :: Maybe FilePath -- virtual CWD of the program
- }
- emptyInteractiveContext :: InteractiveContext
- emptyInteractiveContext
- = InteractiveContext { ic_toplev_scope = [],
- ic_exports = [],
- ic_rn_gbl_env = emptyGlobalRdrEnv,
- ic_tmp_ids = []
- #ifdef GHCI
- , ic_resume = []
- #endif
- , ic_cwd = Nothing
- }
- icPrintUnqual :: DynFlags -> InteractiveContext -> PrintUnqualified
- icPrintUnqual dflags ictxt = mkPrintUnqualified dflags (ic_rn_gbl_env ictxt)
- extendInteractiveContext
- :: InteractiveContext
- -> [Id]
- -> InteractiveContext
- extendInteractiveContext ictxt ids
- = ictxt { ic_tmp_ids = snub ((ic_tmp_ids ictxt \\ ids) ++ ids)
- -- NB. must be this way around, because we want
- -- new ids to shadow existing bindings.
- }
- where snub = map head . group . sort
- substInteractiveContext :: InteractiveContext -> TvSubst -> InteractiveContext
- substInteractiveContext ictxt subst | isEmptyTvSubst subst = ictxt
- substInteractiveContext ictxt@InteractiveContext{ic_tmp_ids=ids} subst
- = ictxt { ic_tmp_ids = map subst_ty ids }
- where
- subst_ty id = id `setIdType` substTy subst (idType id)
- \end{code}
- %************************************************************************
- %* *
- Building a PrintUnqualified
- %* *
- %************************************************************************
- Note [Printing original names]
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Deciding how to print names is pretty tricky. We are given a name
- P:M.T, where P is the package name, M is the defining module, and T is
- the occurrence name, and we have to decide in which form to display
- the name given a GlobalRdrEnv describing the current scope.
- Ideally we want to display the name in the form in which it is in
- scope. However, the name might not be in scope at all, and that's
- where it gets tricky. Here are the cases:
- 1. T uniquely maps to P:M.T ---> "T" NameUnqual
- 2. There is an X for which X.T
- uniquely maps to P:M.T ---> "X.T" NameQual X
- 3. There is no binding for "M.T" ---> "M.T" NameNotInScope1
- 4. Otherwise ---> "P:M.T" NameNotInScope2
- (3) and (4) apply when the entity P:M.T is not in the GlobalRdrEnv at
- all. In these cases we still want to refer to the name as "M.T", *but*
- "M.T" might mean something else in the current scope (e.g. if there's
- an "import X as M"), so to avoid confusion we avoid using "M.T" if
- there's already a binding for it. Instead we write P:M.T.
- There's one further subtlety: in case (3), what if there are two
- things around, P1:M.T and P2:M.T? Then we don't want to print both of
- them as M.T! However only one of the modules P1:M and P2:M can be
- exposed (say P2), so we use M.T for that, and P1:M.T for the other one.
- This is handled by the qual_mod component of PrintUnqualified, inside
- the (ppr mod) of case (3), in Name.pprModulePrefix
- \begin{code}
- -- | Creates some functions that work out the best ways to format
- -- names for the user according to a set of heuristics
- mkPrintUnqualified :: DynFlags -> GlobalRdrEnv -> PrintUnqualified
- mkPrintUnqualified dflags env = (qual_name, qual_mod)
- where
- qual_name mod occ -- The (mod,occ) pair is the original name of the thing
- | [gre] <- unqual_gres, right_name gre = NameUnqual
- -- If there's a unique entity that's in scope unqualified with 'occ'
- -- AND that entity is the right one, then we can use the unqualified name
- | [gre] <- qual_gres = NameQual (get_qual_mod (gre_prov gre))
- | null qual_gres =
- if null (lookupGRE_RdrName (mkRdrQual (moduleName mod) occ) env)
- then NameNotInScope1
- else NameNotInScope2
- | otherwise = panic "mkPrintUnqualified"
- where
- right_name gre = nameModule_maybe (gre_name gre) == Just mod
- unqual_gres = lookupGRE_RdrName (mkRdrUnqual occ) env
- qual_gres = filter right_name (lookupGlobalRdrEnv env occ)
- get_qual_mod LocalDef = moduleName mod
- get_qual_mod (Imported is) = ASSERT( not (null is) ) is_as (is_decl (head is))
- -- we can mention a module P:M without the P: qualifier iff
- -- "import M" would resolve unambiguously to P:M. (if P is the
- -- current package we can just assume it is unqualified).
- qual_mod mod
- | modulePackageId mod == thisPackage dflags = False
- | [pkgconfig] <- [pkg | (pkg,exposed_module) <- lookup,
- exposed pkg && exposed_module],
- packageConfigId pkgconfig == modulePackageId mod
- -- this says: we are given a module P:M, is there just one exposed package
- -- that exposes a module M, and is it package P?
- = False
- | otherwise = True
- where lookup = lookupModuleInAllPackages dflags (moduleName mod)
- \end{code}
- %************************************************************************
- %* *
- TyThing
- %* *
- %************************************************************************
- \begin{code}
- -- | Determine the 'TyThing's brought into scope by another 'TyThing'
- -- /other/ than itself. For example, Id's don't have any implicit TyThings
- -- as they just bring themselves into scope, but classes bring their
- -- dictionary datatype, type constructor and some selector functions into
- -- scope, just for a start!
- -- N.B. the set of TyThings returned here *must* match the set of
- -- names returned by LoadIface.ifaceDeclSubBndrs, in the sense that
- -- TyThing.getOccName should define a bijection between the two lists.
- -- This invariant is used in LoadIface.loadDecl (see note [Tricky iface loop])
- -- The order of the list does not matter.
- implicitTyThings :: TyThing -> [TyThing]
- -- For data and newtype declarations:
- implicitTyThings (ATyCon tc)
- = -- fields (names of selectors)
- -- (possibly) implicit coercion and family coercion
- -- depending on whether it's a newtype or a family instance or both
- implicitCoTyCon tc ++
- -- for each data constructor in order,
- -- the contructor, worker, and (possibly) wrapper
- concatMap (extras_plus . ADataCon) (tyConDataCons tc)
-
- implicitTyThings (AClass cl)
- = -- dictionary datatype:
- -- [extras_plus:]
- -- type constructor
- -- [recursive call:]
- -- (possibly) newtype coe…
Large files files are truncated, but you can click here to view the full file