Super-monster patch implementing the new typechecker -- at last
[ghc-hetmet.git] / compiler / main / HscTypes.lhs
index 94d0f9e..5c41f68 100644 (file)
@@ -13,15 +13,18 @@ module HscTypes (
         ioMsgMaybe, ioMsg,
         logWarnings, clearWarnings, hasWarnings,
         SourceError, GhcApiError, mkSrcErr, srcErrorMessages, mkApiErr,
-        handleSourceError,
+        throwOneError, handleSourceError,
         reflectGhc, reifyGhc,
+        handleFlagWarnings,
 
        -- * Sessions and compilation state
-       Session(..), withSession, modifySession,
+       Session(..), withSession, modifySession, withTempSession,
         HscEnv(..), hscEPS,
        FinderCache, FindResult(..), ModLocationCache,
        Target(..), TargetId(..), pprTarget, pprTargetId,
        ModuleGraph, emptyMG,
+        -- ** Callbacks
+        GhcApiCallbacks(..), withLocalCallbacks,
 
         -- * Information about modules
        ModDetails(..), emptyModDetails,
@@ -45,10 +48,15 @@ module HscTypes (
        
        PackageInstEnv, PackageRuleBase,
 
+
+        -- * Annotations
+        prepareAnnotations,
+
         -- * Interactive context
        InteractiveContext(..), emptyInteractiveContext, 
-       icPrintUnqual, mkPrintUnqualified, extendInteractiveContext,
+       icPrintUnqual, extendInteractiveContext,
         substInteractiveContext,
+        mkPrintUnqualified, pprModulePrefix,
 
        -- * Interfaces
        ModIface(..), mkIfaceWarnCache, mkIfaceHashCache, mkIfaceFixCache,
@@ -104,12 +112,11 @@ import ByteCodeAsm        ( CompiledByteCode )
 import {-# SOURCE #-}  InteractiveEval ( Resume )
 #endif
 
+import HsSyn
 import RdrName
 import Name
 import NameEnv
 import NameSet 
-import OccName         ( OccName, OccEnv, lookupOccEnv, mkOccEnv, emptyOccEnv, 
-                         extendOccEnv )
 import Module
 import InstEnv         ( InstEnv, Instance )
 import FamInstEnv      ( FamInstEnv, FamInst )
@@ -121,14 +128,16 @@ import Var
 import Id
 import Type            
 
-import Class           ( Class, classSelIds, classATs, classTyCon )
+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 (..) )
+import DynFlags                ( DynFlags(..), isOneShot, HscTarget (..), dopt,
+                          DynFlag(..) )
 import DriverPhases    ( HscSource(..), isHsBoot, hscSourceString, Phase )
-import BasicTypes      ( IPName, Fixity, defaultFixity, WarningTxt(..) )
+import BasicTypes      ( IPName, defaultFixity, WarningTxt(..) )
 import OptimizationFuel        ( OptFuelState )
 import IfaceSyn
 import FiniteMap       ( FiniteMap )
@@ -136,25 +145,24 @@ import CoreSyn            ( CoreRule )
 import Maybes          ( orElse, expectJust, catMaybes )
 import Outputable
 import BreakArray
-import SrcLoc          ( SrcSpan, Located )
-import LazyUniqFM              ( lookupUFM, eltsUFM, emptyUFM )
+import SrcLoc          ( SrcSpan, Located(..) )
+import UniqFM          ( lookupUFM, eltsUFM, emptyUFM )
 import UniqSupply      ( UniqSupply )
 import FastString
 import StringBuffer    ( StringBuffer )
 import Fingerprint
 import MonadUtils
-import Bag              ( emptyBag, unionBags, isEmptyBag )
 import Data.Dynamic     ( Typeable )
 import qualified Data.Dynamic as Dyn
-import Bag              ( bagToList )
-import ErrUtils         ( ErrorMessages, WarningMessages, Messages )
+import Bag
+import ErrUtils
 
 import System.FilePath
 import System.Time     ( ClockTime )
 import Data.IORef
 import Data.Array       ( Array, array )
 import Data.List
-import Control.Monad    ( mplus, guard, liftM )
+import Control.Monad    ( mplus, guard, liftM, when )
 import Exception
 \end{code}
 
@@ -177,6 +185,9 @@ 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
@@ -284,6 +295,16 @@ 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'.
@@ -304,6 +325,12 @@ instance ExceptionMonad Ghc where
       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
@@ -336,6 +363,12 @@ instance ExceptionMonad m => ExceptionMonad (GhcT m) where
       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
@@ -368,7 +401,7 @@ ioMsgMaybe ioA = do
   ((warns,errs), mb_r) <- liftIO ioA
   logWarnings warns
   case mb_r of
-    Nothing -> throw (mkSrcErr errs)
+    Nothing -> liftIO $ throwIO (mkSrcErr errs)
     Just r  -> ASSERT( isEmptyBag errs ) return r
 
 -- | Lift a non-failing IO action into a 'GhcMonad'.
@@ -402,10 +435,71 @@ 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}
--- | HscEnv is like 'Session', except that some of the fields are immutable.
+-- | 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.
@@ -420,6 +514,9 @@ data 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
 
@@ -544,30 +641,31 @@ 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).
-        }
+  = 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
@@ -620,6 +718,12 @@ 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))
 
@@ -654,7 +758,32 @@ hptSomeThingsBelowUs extract include_hi_boot hsc_env deps
 
        -- 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}
 
 %************************************************************************
@@ -682,14 +811,12 @@ data FindResult
        -- ^ The requested package was not found
   | FoundMultiple [PackageId]
        -- ^ _Error_: both in multiple packages
-  | PackageHidden PackageId
-       -- ^ For an explicit source import, the package containing the module is
-       -- not exposed.
-  | ModuleHidden  PackageId
-       -- ^ For an explicit source import, the package containing the module is
-       -- exposed, but the module itself is hidden.
-  | NotFound [FilePath] (Maybe PackageId)
-       -- ^ The module was not found, the specified places were searched
+  | 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
 
@@ -726,11 +853,10 @@ data ModIface
        mi_boot     :: !IsBootInterface,    -- ^ Read from an hi-boot file?
 
        mi_deps     :: Dependencies,
-               -- ^ The dependencies of the module, consulted for directly
-               -- imported modules only
-       
-               -- This is consulted for directly-imported modules,
-               -- but not for anything else (hence lazy)
+               -- ^ 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
@@ -757,6 +883,11 @@ data ModIface
                
                -- 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)
@@ -815,6 +946,8 @@ data ModDetails
         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
      }
 
@@ -824,6 +957,7 @@ emptyModDetails = ModDetails { md_types = emptyTypeEnv,
                               md_insts     = [],
                               md_rules     = [],
                               md_fam_insts = [],
+                               md_anns      = [],
                                md_vect_info = noVectInfo
                              } 
 
@@ -856,12 +990,11 @@ data ModGuts
        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 
-                                         -- rules declared in this module. After the core
-                                         -- pipeline starts, it is changed to contain all
-                                         -- known rules for those things imported
+                                        -- 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
@@ -975,6 +1108,7 @@ emptyModIface mod
               mi_exp_hash = fingerprint0,
               mi_fixities = [],
               mi_warns    = NoWarnings,
+              mi_anns     = [],
               mi_insts     = [],
               mi_fam_insts = [],
               mi_rules     = [],
@@ -1003,7 +1137,7 @@ data InteractiveContext
        ic_toplev_scope :: [Module],    -- ^ The context includes the "top-level" scope of
                                        -- these modules
 
-       ic_exports :: [Module],         -- ^ The context includes just the exports of these
+       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
@@ -1021,6 +1155,8 @@ data InteractiveContext
 #ifdef GHCI
         , ic_resume :: [Resume]         -- ^ The stack of breakpoint contexts
 #endif
+
+        , ic_cwd :: Maybe FilePath      -- virtual CWD of the program
     }
 
 
@@ -1034,6 +1170,7 @@ emptyInteractiveContext
 #ifdef GHCI
                          , ic_resume = []
 #endif
+                         , ic_cwd = Nothing
                        }
 
 icPrintUnqual :: DynFlags -> InteractiveContext -> PrintUnqualified
@@ -1074,6 +1211,8 @@ substInteractiveContext ictxt@InteractiveContext{ic_tmp_ids=ids} subst =
 %*                                                                     *
 %************************************************************************
 
+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
@@ -1083,19 +1222,24 @@ 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"
- 2. there is an X for which X.T uniquely maps to  P:M.T --->  "X.T"
- 3. there is no binding for "M.T"                       --->  "M.T"
- 4. otherwise                                           --->  "P:M.T"
-
-3 and 4 apply when P:M.T is not in scope.  In these cases we 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.
-
-There's one further subtlety: if the module M cannot be imported
-because it is not exposed by any package, then we must refer to it as
-"P:M".  This is handled by the qual_mod component of PrintUnqualified.
+ 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
@@ -1165,14 +1309,13 @@ mkPrintUnqualified dflags env = (qual_name, qual_mod)
 implicitTyThings :: TyThing -> [TyThing]
 
 -- For data and newtype declarations:
-implicitTyThings (ATyCon tc) = 
-    -- fields (names of selectors)
-    map AnId (tyConSelIds tc) ++ 
-    -- (possibly) implicit coercion and family coercion
-    --   depending on whether it's a newtype or a family instance or both
+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
+      -- for each data constructor in order,
+      --   the contructor, worker, and (possibly) wrapper
     concatMap (extras_plus . ADataCon) (tyConDataCons tc)
                     
 implicitTyThings (AClass cl) 
@@ -1190,7 +1333,7 @@ implicitTyThings (AClass cl)
     --    are only the family decls; they have no implicit things
     map ATyCon (classATs cl) ++
     -- superclass and operation selectors
-    map AnId (classSelIds cl)
+    map AnId (classAllSelIds cl)
 
 implicitTyThings (ADataCon dc) = 
     -- For data cons add the worker and (possibly) wrapper
@@ -1295,7 +1438,7 @@ lookupType dflags hpt pte name
 lookupTypeHscEnv :: HscEnv -> Name -> IO (Maybe TyThing)
 lookupTypeHscEnv hsc_env name = do
     eps <- readIORef (hsc_EPS hsc_env)
-    return $ lookupType dflags hpt (eps_PTE eps) name
+    return $! lookupType dflags hpt (eps_PTE eps) name
   where 
     dflags = hsc_dflags hsc_env
     hpt = hsc_HPT hsc_env
@@ -1605,6 +1748,7 @@ type PackageRuleBase   = RuleBase
 type PackageInstEnv    = InstEnv
 type PackageFamInstEnv = FamInstEnv
 type PackageVectInfo   = VectInfo
+type PackageAnnEnv     = AnnEnv
 
 -- | Information about other packages that we have slurped in by reading
 -- their interface files
@@ -1656,6 +1800,8 @@ data ExternalPackageState
                                               -- from all the external-package modules
        eps_vect_info    :: !PackageVectInfo,  -- ^ The total 'VectInfo' accumulated
                                               -- from all the external-package modules
+        eps_ann_env      :: !PackageAnnEnv,    -- ^ The total 'AnnEnv' accumulated
+                                              -- from all the external-package modules
 
         eps_mod_fam_inst_env :: !(ModuleEnv FamInstEnv), -- ^ The family instances accumulated from external
                                                          -- packages, keyed off the module that declared them
@@ -1723,7 +1869,8 @@ type OrigIParamCache = FiniteMap (IPName OccName) (IPName Name)
 -- There will be a node for each source module, plus a node for each hi-boot
 -- module.
 --
--- The graph is not necessarily stored in topologically-sorted order.
+-- The graph is not necessarily stored in topologically-sorted order.  Use
+-- 'GHC.topSortModuleGraph' and 'Digraph.flattenSCC' to achieve this.
 type ModuleGraph = [ModSummary]
 
 emptyMG :: ModuleGraph
@@ -1743,8 +1890,8 @@ data ModSummary
         ms_location  :: ModLocation,           -- ^ Location of the various files belonging to the module
         ms_hs_date   :: ClockTime,             -- ^ Timestamp of source file
        ms_obj_date  :: Maybe ClockTime,        -- ^ Timestamp of object, if we have one
-        ms_srcimps   :: [Located ModuleName],  -- ^ Source imports of the module
-        ms_imps      :: [Located ModuleName],  -- ^ Non-source imports of the module
+        ms_srcimps   :: [Located (ImportDecl RdrName)],        -- ^ Source imports of the module
+        ms_imps      :: [Located (ImportDecl RdrName)],        -- ^ Non-source imports of the module
         ms_hspp_file :: FilePath,              -- ^ Filename of preprocessed source file
         ms_hspp_opts :: DynFlags,               -- ^ Cached flags from @OPTIONS@, @INCLUDE@
                                                 -- and @LANGUAGE@ pragmas in the modules source code
@@ -1849,7 +1996,6 @@ on just the OccName easily in a Core pass.
 
 \begin{code}
 -- | Vectorisation information for 'ModGuts', 'ModDetails' and 'ExternalPackageState'.
--- All of this information is always tidy, even in ModGuts.
 data VectInfo      
   = VectInfo {
       vectInfoVar     :: VarEnv  (Var    , Var  ),   -- ^ @(f, f_v)@ keyed on @f@
@@ -1910,8 +2056,14 @@ data Linkable = LM {
                                        -- (i.e. when the bytecodes were produced,
                                        --       or the mod date on the files)
   linkableModule   :: Module,           -- ^ The linkable module itself
-  linkableUnlinked :: [Unlinked]        -- ^ Those files and chunks of code we have
-                                        -- yet to link
+  linkableUnlinked :: [Unlinked]
+    -- ^ Those files and chunks of code we have yet to link.
+    --
+    -- INVARIANT: A valid linkable always has at least one 'Unlinked' item.
+    -- If this list is empty, the Linkable represents a fake linkable, which
+    -- is generated in HscNothing mode to avoid recompiling modules.
+    --
+    -- XXX: Do items get removed from this list when they get linked?
  }
 
 isObjectLinkable :: Linkable -> Bool