    {-
    (c) The University of Glasgow 2006
    (c) The GRASP/AQUA Project, Glasgow University, 1992-1998

    -}

    {-# LANGUAGE CPP, BangPatterns, RecordWildCards, NondecreasingIndentation #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE FlexibleContexts #-}

    {-# OPTIONS_GHC -fno-warn-orphans #-}

    -- | Loading interface files
    module GHC.Iface.Load (
            -- Importing one thing
            tcLookupImported_maybe, importDecl,
            checkWiredInTyCon, ifCheckWiredInThing,

            -- RnM/TcM functions
            loadModuleInterface, loadModuleInterfaces,
            loadSrcInterface, loadSrcInterface_maybe,
            loadInterfaceForName, loadInterfaceForNameMaybe, loadInterfaceForModule,

            -- IfM functions
            loadInterface,
            loadSysInterface, loadUserInterface, loadPluginInterface,
            findAndReadIface, readIface, writeIface,
            initExternalPackageState,
            moduleFreeHolesPrecise,
            needWiredInHomeIface, loadWiredInHomeIface,

            pprModIfaceSimple,
            ifaceStats, pprModIface, showIface,

            cannotFindModule
       ) where

    #include "HsVersions.h"

    import GHC.Prelude
    import GHC.Platform.Ways
    import GHC.Platform.Profile

    import {-# SOURCE #-} GHC.IfaceToCore
       ( tcIfaceDecls, tcIfaceRules, tcIfaceInst, tcIfaceFamInst
       , tcIfaceAnnotations, tcIfaceCompleteMatches )

    import GHC.Driver.Env
    import GHC.Driver.Session
    import GHC.Driver.Backend
    import GHC.Driver.Ppr
    import GHC.Driver.Hooks
    import GHC.Driver.Plugins

    import GHC.Iface.Syntax
    import GHC.Iface.Ext.Fields
    import GHC.Iface.Binary
    import GHC.Iface.Rename

    import GHC.Tc.Utils.Monad

    import GHC.Utils.Binary   ( BinData(..) )
    import GHC.Utils.Error
    import GHC.Utils.Outputable as Outputable
    import GHC.Utils.Panic
    import GHC.Utils.Misc
    import GHC.Utils.Logger

    import GHC.Settings.Constants

    import GHC.Builtin.Names
    import GHC.Builtin.Utils
    import GHC.Builtin.PrimOps    ( allThePrimOps, primOpFixity, primOpOcc )

    import GHC.Core.Rules
    import GHC.Core.TyCon
    import GHC.Core.InstEnv
    import GHC.Core.FamInstEnv

    import GHC.Types.Id.Make      ( seqId )
    import GHC.Types.Annotations
    import GHC.Types.Name
    import GHC.Types.Name.Env
    import GHC.Types.Avail
    import GHC.Types.Fixity
    import GHC.Types.Fixity.Env
    import GHC.Types.SourceError
    import GHC.Types.SourceText
    import GHC.Types.SourceFile
    import GHC.Types.SafeHaskell
    import GHC.Types.TypeEnv
    import GHC.Types.Unique.FM
    import GHC.Types.Unique.DSet
    import GHC.Types.SrcLoc
    import GHC.Types.TyThing

    import GHC.Unit.External
    import GHC.Unit.Module
    import GHC.Unit.Module.Warnings
    import GHC.Unit.Module.ModIface
    import GHC.Unit.Module.Deps
    import GHC.Unit.State
    import GHC.Unit.Home
    import GHC.Unit.Home.ModInfo
    import GHC.Unit.Finder
    import GHC.Unit.Env

    import GHC.Data.Maybe
    import GHC.Data.FastString

    import Control.Monad
    import Control.Exception
    import Data.Map ( toList )
    import System.FilePath
    import System.Directory

    {-
    ************************************************************************
    *                                                                      *
    *      tcImportDecl is the key function for "faulting in"              *
    *      imported things
    *                                                                      *
    ************************************************************************

    The main idea is this.  We are chugging along type-checking source code, and
    find a reference to GHC.Base.map.  We call tcLookupGlobal, which doesn't find
    it in the EPS type envt.  So it
            1 loads GHC.Base.hi
            2 gets the decl for GHC.Base.map
            3 typechecks it via tcIfaceDecl
            4 and adds it to the type env in the EPS

    Note that DURING STEP 4, we may find that map's type mentions a type
    constructor that also

    Notice that for imported things we read the current version from the EPS
    mutable variable.  This is important in situations like
            ...$(e1)...$(e2)...
    where the code that e1 expands to might import some defns that
    also turn out to be needed by the code that e2 expands to.
    -}

    tcLookupImported_maybe :: Name -> TcM (MaybeErr SDoc TyThing)
    -- Returns (Failed err) if we can't find the interface file for the thing
    tcLookupImported_maybe :: Name -> TcM (MaybeErr SDoc TyThing)
    tcLookupImported_maybe Name
    name
      = do  { HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
            ; Maybe TyThing
    mb_thing <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (HscEnv -> Name -> IO (Maybe TyThing)
    lookupType HscEnv
    hsc_env Name
    name)
            ; case Maybe TyThing
    mb_thing of
                Just TyThing
    thing -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded TyThing
    thing)
                Maybe TyThing
    Nothing    -> Name -> TcM (MaybeErr SDoc TyThing)
    tcImportDecl_maybe Name
    name }

    tcImportDecl_maybe :: Name -> TcM (MaybeErr SDoc TyThing)
    -- Entry point for *source-code* uses of importDecl
    tcImportDecl_maybe :: Name -> TcM (MaybeErr SDoc TyThing)
    tcImportDecl_maybe Name
    name
      | Just TyThing
    thing <- Name -> Maybe TyThing
    wiredInNameTyThing_maybe Name
    name
      = do  { forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (TyThing -> Bool
    needWiredInHomeIface TyThing
    thing)
                   (forall a. IfG a -> TcRn a
    initIfaceTcRn (forall lcl. Name -> IfM lcl ()
    loadWiredInHomeIface Name
    name))
                    -- See Note [Loading instances for wired-in things]
            ; forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded TyThing
    thing) }
      | Bool
    otherwise
      = forall a. IfG a -> TcRn a
    initIfaceTcRn (forall lcl. Name -> IfM lcl (MaybeErr SDoc TyThing)
    importDecl Name
    name)

    importDecl :: Name -> IfM lcl (MaybeErr SDoc TyThing)
    -- Get the TyThing for this Name from an interface file
    -- It's not a wired-in thing -- the caller caught that
    importDecl :: forall lcl. Name -> IfM lcl (MaybeErr SDoc TyThing)
    importDecl Name
    name
      = ASSERT( not (isWiredInName name) )
        do  { forall m n. SDoc -> TcRnIf m n ()
    traceIf SDoc
    nd_doc

            -- Load the interface, which should populate the PTE
            ; MaybeErr SDoc ModIface
    mb_iface <- ASSERT2( isExternalName name, ppr name )
                          forall lcl.
    SDoc
    -> GenModule Unit -> WhereFrom -> IfM lcl (MaybeErr SDoc ModIface)
    loadInterface SDoc
    nd_doc (HasDebugCallStack => Name -> GenModule Unit
    nameModule Name
    name) WhereFrom
    ImportBySystem
            ; case MaybeErr SDoc ModIface
    mb_iface of {
                    Failed SDoc
    err_msg  -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. err -> MaybeErr err val
    Failed SDoc
    err_msg) ;
                    Succeeded ModIface
    _ -> do

            -- Now look it up again; this time we should find it
            { ExternalPackageState
    eps <- forall gbl lcl. TcRnIf gbl lcl ExternalPackageState
    getEps
            ; case TypeEnv -> Name -> Maybe TyThing
    lookupTypeEnv (ExternalPackageState -> TypeEnv
    eps_PTE ExternalPackageState
    eps) Name
    name of
                Just TyThing
    thing -> forall (m :: * -> *) a. Monad m => a -> m a
    return forall a b. (a -> b) -> a -> b
    $ forall err val. val -> MaybeErr err val
    Succeeded TyThing
    thing
                Maybe TyThing
    Nothing    -> let doc :: SDoc
    doc = SDoc -> SDoc
    whenPprDebug (ExternalPackageState -> SDoc
    found_things_msg ExternalPackageState
    eps SDoc -> SDoc -> SDoc
    $$ SDoc
    empty)
                                        SDoc -> SDoc -> SDoc
    $$ SDoc
    not_found_msg
                              in forall (m :: * -> *) a. Monad m => a -> m a
    return forall a b. (a -> b) -> a -> b
    $ forall err val. err -> MaybeErr err val
    Failed SDoc
    doc
        }}}
      where
        nd_doc :: SDoc
    nd_doc = String -> SDoc
    text String
    "Need decl for" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr Name
    name
        not_found_msg :: SDoc
    not_found_msg = SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    text String
    "Can't find interface-file declaration for" SDoc -> SDoc -> SDoc
    <+>
                                    NameSpace -> SDoc
    pprNameSpace (Name -> NameSpace
    nameNameSpace Name
    name) SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr Name
    name)
                           Int
    2 ([SDoc] -> SDoc
    vcat [String -> SDoc
    text String
    "Probable cause: bug in .hi-boot file, or inconsistent .hi file",
                                    String -> SDoc
    text String
    "Use -ddump-if-trace to get an idea of which file caused the error"])
        found_things_msg :: ExternalPackageState -> SDoc
    found_things_msg ExternalPackageState
    eps =
            SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    text String
    "Found the following declarations in" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (HasDebugCallStack => Name -> GenModule Unit
    nameModule Name
    name) SDoc -> SDoc -> SDoc
    <> SDoc
    colon)
               Int
    2 ([SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    ppr forall a b. (a -> b) -> a -> b
    $ forall a. (a -> Bool) -> [a] -> [a]
    filter TyThing -> Bool
    is_interesting forall a b. (a -> b) -> a -> b
    $ forall a. NameEnv a -> [a]
    nameEnvElts forall a b. (a -> b) -> a -> b
    $ ExternalPackageState -> TypeEnv
    eps_PTE ExternalPackageState
    eps))
          where
            is_interesting :: TyThing -> Bool
    is_interesting TyThing
    thing = HasDebugCallStack => Name -> GenModule Unit
    nameModule Name
    name forall a. Eq a => a -> a -> Bool
    == HasDebugCallStack => Name -> GenModule Unit
    nameModule (forall a. NamedThing a => a -> Name
    getName TyThing
    thing)

    {-
    ************************************************************************
    *                                                                      *
               Checks for wired-in things
    *                                                                      *
    ************************************************************************

    Note [Loading instances for wired-in things]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    We need to make sure that we have at least *read* the interface files
    for any module with an instance decl or RULE that we might want.

    * If the instance decl is an orphan, we have a whole separate mechanism
      (loadOrphanModules)

    * If the instance decl is not an orphan, then the act of looking at the
      TyCon or Class will force in the defining module for the
      TyCon/Class, and hence the instance decl

    * BUT, if the TyCon is a wired-in TyCon, we don't really need its interface;
      but we must make sure we read its interface in case it has instances or
      rules.  That is what GHC.Iface.Load.loadWiredInHomeIface does.  It's called
      from GHC.IfaceToCore.{tcImportDecl, checkWiredInTyCon, ifCheckWiredInThing}

    * HOWEVER, only do this for TyCons.  There are no wired-in Classes.  There
      are some wired-in Ids, but we don't want to load their interfaces. For
      example, Control.Exception.Base.recSelError is wired in, but that module
      is compiled late in the base library, and we don't want to force it to
      load before it's been compiled!

    All of this is done by the type checker. The renamer plays no role.
    (It used to, but no longer.)
    -}

    checkWiredInTyCon :: TyCon -> TcM ()
    -- Ensure that the home module of the TyCon (and hence its instances)
    -- are loaded. See Note [Loading instances for wired-in things]
    -- It might not be a wired-in tycon (see the calls in GHC.Tc.Utils.Unify),
    -- in which case this is a no-op.
    checkWiredInTyCon :: TyCon -> TcM ()
    checkWiredInTyCon TyCon
    tc
      | Bool -> Bool
    not (Name -> Bool
    isWiredInName Name
    tc_name)
      = forall (m :: * -> *) a. Monad m => a -> m a
    return ()
      | Bool
    otherwise
      = do  { GenModule Unit
    mod <- forall (m :: * -> *). HasModule m => m (GenModule Unit)
    getModule
            ; forall m n. SDoc -> TcRnIf m n ()
    traceIf (String -> SDoc
    text String
    "checkWiredInTyCon" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr Name
    tc_name SDoc -> SDoc -> SDoc
    $$ forall a. Outputable a => a -> SDoc
    ppr GenModule Unit
    mod)
            ; ASSERT( isExternalName tc_name )
              forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (GenModule Unit
    mod forall a. Eq a => a -> a -> Bool
    /= HasDebugCallStack => Name -> GenModule Unit
    nameModule Name
    tc_name)
                   (forall a. IfG a -> TcRn a
    initIfaceTcRn (forall lcl. Name -> IfM lcl ()
    loadWiredInHomeIface Name
    tc_name))
                    -- Don't look for (non-existent) Float.hi when
                    -- compiling Float.hs, which mentions Float of course
                    -- A bit yukky to call initIfaceTcRn here
            }
      where
        tc_name :: Name
    tc_name = TyCon -> Name
    tyConName TyCon
    tc

    ifCheckWiredInThing :: TyThing -> IfL ()
    -- Even though we are in an interface file, we want to make
    -- sure the instances of a wired-in thing are loaded (imagine f :: Double -> Double)
    -- Ditto want to ensure that RULES are loaded too
    -- See Note [Loading instances for wired-in things]
    ifCheckWiredInThing :: TyThing -> IfL ()
    ifCheckWiredInThing TyThing
    thing
      = do  { GenModule Unit
    mod <- IfL (GenModule Unit)
    getIfModule
                    -- Check whether we are typechecking the interface for this
                    -- very module.  E.g when compiling the base library in --make mode
                    -- we may typecheck GHC.Base.hi. At that point, GHC.Base is not in
                    -- the HPT, so without the test we'll demand-load it into the PIT!
                    -- C.f. the same test in checkWiredInTyCon above
            ; let name :: Name
    name = forall a. NamedThing a => a -> Name
    getName TyThing
    thing
            ; ASSERT2( isExternalName name, ppr name )
              forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (TyThing -> Bool
    needWiredInHomeIface TyThing
    thing Bool -> Bool -> Bool
    && GenModule Unit
    mod forall a. Eq a => a -> a -> Bool
    /= HasDebugCallStack => Name -> GenModule Unit
    nameModule Name
    name)
                   (forall lcl. Name -> IfM lcl ()
    loadWiredInHomeIface Name
    name) }

    needWiredInHomeIface :: TyThing -> Bool
    -- Only for TyCons; see Note [Loading instances for wired-in things]
    needWiredInHomeIface :: TyThing -> Bool
    needWiredInHomeIface (ATyCon {}) = Bool
    True
    needWiredInHomeIface TyThing
    _           = Bool
    False

    {-
    ************************************************************************
    *                                                                      *
            loadSrcInterface, loadOrphanModules, loadInterfaceForName

                    These three are called from TcM-land
    *                                                                      *
    ************************************************************************
    -}

    -- | Load the interface corresponding to an @import@ directive in
    -- source code.  On a failure, fail in the monad with an error message.
    loadSrcInterface :: SDoc
                     -> ModuleName
                     -> IsBootInterface     -- {-# SOURCE #-} ?
                     -> Maybe FastString    -- "package", if any
                     -> RnM ModIface

    loadSrcInterface :: SDoc
    -> ModuleName
    -> IsBootInterface
    -> Maybe FastString
    -> RnM ModIface
    loadSrcInterface SDoc
    doc ModuleName
    mod IsBootInterface
    want_boot Maybe FastString
    maybe_pkg
      = do { MaybeErr SDoc ModIface
    res <- SDoc
    -> ModuleName
    -> IsBootInterface
    -> Maybe FastString
    -> RnM (MaybeErr SDoc ModIface)
    loadSrcInterface_maybe SDoc
    doc ModuleName
    mod IsBootInterface
    want_boot Maybe FastString
    maybe_pkg
           ; case MaybeErr SDoc ModIface
    res of
               Failed SDoc
    err      -> forall a. SDoc -> TcM a
    failWithTc SDoc
    err
               Succeeded ModIface
    iface -> forall (m :: * -> *) a. Monad m => a -> m a
    return ModIface
    iface }

    -- | Like 'loadSrcInterface', but returns a 'MaybeErr'.
    loadSrcInterface_maybe :: SDoc
                           -> ModuleName
                           -> IsBootInterface     -- {-# SOURCE #-} ?
                           -> Maybe FastString    -- "package", if any
                           -> RnM (MaybeErr SDoc ModIface)

    loadSrcInterface_maybe :: SDoc
    -> ModuleName
    -> IsBootInterface
    -> Maybe FastString
    -> RnM (MaybeErr SDoc ModIface)
    loadSrcInterface_maybe SDoc
    doc ModuleName
    mod IsBootInterface
    want_boot Maybe FastString
    maybe_pkg
      -- We must first find which Module this import refers to.  This involves
      -- calling the Finder, which as a side effect will search the filesystem
      -- and create a ModLocation.  If successful, loadIface will read the
      -- interface; it will call the Finder again, but the ModLocation will be
      -- cached from the first search.
      = do { HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
           ; FindResult
    res <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall a b. (a -> b) -> a -> b
    $ HscEnv -> ModuleName -> Maybe FastString -> IO FindResult
    findImportedModule HscEnv
    hsc_env ModuleName
    mod Maybe FastString
    maybe_pkg
           ; case FindResult
    res of
               Found ModLocation
    _ GenModule Unit
    mod -> forall a. IfG a -> TcRn a
    initIfaceTcRn forall a b. (a -> b) -> a -> b
    $ forall lcl.
    SDoc
    -> GenModule Unit -> WhereFrom -> IfM lcl (MaybeErr SDoc ModIface)
    loadInterface SDoc
    doc GenModule Unit
    mod (IsBootInterface -> WhereFrom
    ImportByUser IsBootInterface
    want_boot)
               -- TODO: Make sure this error message is good
               FindResult
    err         -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. err -> MaybeErr err val
    Failed (HscEnv -> ModuleName -> FindResult -> SDoc
    cannotFindModule HscEnv
    hsc_env ModuleName
    mod FindResult
    err)) }

    -- | Load interface directly for a fully qualified 'Module'.  (This is a fairly
    -- rare operation, but in particular it is used to load orphan modules
    -- in order to pull their instances into the global package table and to
    -- handle some operations in GHCi).
    loadModuleInterface :: SDoc -> Module -> TcM ModIface
    loadModuleInterface :: SDoc -> GenModule Unit -> RnM ModIface
    loadModuleInterface SDoc
    doc GenModule Unit
    mod = forall a. IfG a -> TcRn a
    initIfaceTcRn (forall lcl. SDoc -> GenModule Unit -> IfM lcl ModIface
    loadSysInterface SDoc
    doc GenModule Unit
    mod)

    -- | Load interfaces for a collection of modules.
    loadModuleInterfaces :: SDoc -> [Module] -> TcM ()
    loadModuleInterfaces :: SDoc -> [GenModule Unit] -> TcM ()
    loadModuleInterfaces SDoc
    doc [GenModule Unit]
    mods
      | forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [GenModule Unit]
    mods = forall (m :: * -> *) a. Monad m => a -> m a
    return ()
      | Bool
    otherwise = forall a. IfG a -> TcRn a
    initIfaceTcRn (forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ GenModule Unit -> IfM () ModIface
    load [GenModule Unit]
    mods)
      where
        load :: GenModule Unit -> IfM () ModIface
    load GenModule Unit
    mod = forall lcl. SDoc -> GenModule Unit -> IfM lcl ModIface
    loadSysInterface (SDoc
    doc SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    parens (forall a. Outputable a => a -> SDoc
    ppr GenModule Unit
    mod)) GenModule Unit
    mod

    -- | Loads the interface for a given Name.
    -- Should only be called for an imported name;
    -- otherwise loadSysInterface may not find the interface
    loadInterfaceForName :: SDoc -> Name -> TcRn ModIface
    loadInterfaceForName :: SDoc -> Name -> RnM ModIface
    loadInterfaceForName SDoc
    doc Name
    name
      = do { forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    debugIsOn forall a b. (a -> b) -> a -> b
    $  -- Check pre-condition
             do { GenModule Unit
    this_mod <- forall (m :: * -> *). HasModule m => m (GenModule Unit)
    getModule
                ; MASSERT2( not (nameIsLocalOrFrom this_mod name), ppr name <+> parens doc ) }
          ; ASSERT2( isExternalName name, ppr name )
            forall a. IfG a -> TcRn a
    initIfaceTcRn forall a b. (a -> b) -> a -> b
    $ forall lcl. SDoc -> GenModule Unit -> IfM lcl ModIface
    loadSysInterface SDoc
    doc (HasDebugCallStack => Name -> GenModule Unit
    nameModule Name
    name) }

    -- | Only loads the interface for external non-local names.
    loadInterfaceForNameMaybe :: SDoc -> Name -> TcRn (Maybe ModIface)
    loadInterfaceForNameMaybe :: SDoc -> Name -> TcRn (Maybe ModIface)
    loadInterfaceForNameMaybe SDoc
    doc Name
    name
      = do { GenModule Unit
    this_mod <- forall (m :: * -> *). HasModule m => m (GenModule Unit)
    getModule
           ; if GenModule Unit -> Name -> Bool
    nameIsLocalOrFrom GenModule Unit
    this_mod Name
    name Bool -> Bool -> Bool
    || Bool -> Bool
    not (Name -> Bool
    isExternalName Name
    name)
             then forall (m :: * -> *) a. Monad m => a -> m a
    return forall a. Maybe a
    Nothing
             else forall a. a -> Maybe a
    Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (forall a. IfG a -> TcRn a
    initIfaceTcRn forall a b. (a -> b) -> a -> b
    $ forall lcl. SDoc -> GenModule Unit -> IfM lcl ModIface
    loadSysInterface SDoc
    doc (HasDebugCallStack => Name -> GenModule Unit
    nameModule Name
    name))
           }

    -- | Loads the interface for a given Module.
    loadInterfaceForModule :: SDoc -> Module -> TcRn ModIface
    loadInterfaceForModule :: SDoc -> GenModule Unit -> RnM ModIface
    loadInterfaceForModule SDoc
    doc GenModule Unit
    m
      = do
        -- Should not be called with this module
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    debugIsOn forall a b. (a -> b) -> a -> b
    $ do
          GenModule Unit
    this_mod <- forall (m :: * -> *). HasModule m => m (GenModule Unit)
    getModule
          MASSERT2( this_mod /= m, ppr m <+> parens doc )
        forall a. IfG a -> TcRn a
    initIfaceTcRn forall a b. (a -> b) -> a -> b
    $ forall lcl. SDoc -> GenModule Unit -> IfM lcl ModIface
    loadSysInterface SDoc
    doc GenModule Unit
    m

    {-
    *********************************************************
    *                                                      *
                    loadInterface

            The main function to load an interface
            for an imported module, and put it in
            the External Package State
    *                                                      *
    *********************************************************
    -}

    -- | An 'IfM' function to load the home interface for a wired-in thing,
    -- so that we're sure that we see its instance declarations and rules
    -- See Note [Loading instances for wired-in things]
    loadWiredInHomeIface :: Name -> IfM lcl ()
    loadWiredInHomeIface :: forall lcl. Name -> IfM lcl ()
    loadWiredInHomeIface Name
    name
      = ASSERT( isWiredInName name )
        do ModIface
    _ <- forall lcl. SDoc -> GenModule Unit -> IfM lcl ModIface
    loadSysInterface SDoc
    doc (HasDebugCallStack => Name -> GenModule Unit
    nameModule Name
    name); forall (m :: * -> *) a. Monad m => a -> m a
    return ()
      where
        doc :: SDoc
    doc = String -> SDoc
    text String
    "Need home interface for wired-in thing" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr Name
    name

    ------------------
    -- | Loads a system interface and throws an exception if it fails
    loadSysInterface :: SDoc -> Module -> IfM lcl ModIface
    loadSysInterface :: forall lcl. SDoc -> GenModule Unit -> IfM lcl ModIface
    loadSysInterface SDoc
    doc GenModule Unit
    mod_name = forall lcl. SDoc -> GenModule Unit -> WhereFrom -> IfM lcl ModIface
    loadInterfaceWithException SDoc
    doc GenModule Unit
    mod_name WhereFrom
    ImportBySystem

    ------------------
    -- | Loads a user interface and throws an exception if it fails. The first parameter indicates
    -- whether we should import the boot variant of the module
    loadUserInterface :: IsBootInterface -> SDoc -> Module -> IfM lcl ModIface
    loadUserInterface :: forall lcl.
    IsBootInterface -> SDoc -> GenModule Unit -> IfM lcl ModIface
    loadUserInterface IsBootInterface
    is_boot SDoc
    doc GenModule Unit
    mod_name
      = forall lcl. SDoc -> GenModule Unit -> WhereFrom -> IfM lcl ModIface
    loadInterfaceWithException SDoc
    doc GenModule Unit
    mod_name (IsBootInterface -> WhereFrom
    ImportByUser IsBootInterface
    is_boot)

    loadPluginInterface :: SDoc -> Module -> IfM lcl ModIface
    loadPluginInterface :: forall lcl. SDoc -> GenModule Unit -> IfM lcl ModIface
    loadPluginInterface SDoc
    doc GenModule Unit
    mod_name
      = forall lcl. SDoc -> GenModule Unit -> WhereFrom -> IfM lcl ModIface
    loadInterfaceWithException SDoc
    doc GenModule Unit
    mod_name WhereFrom
    ImportByPlugin

    ------------------
    -- | A wrapper for 'loadInterface' that throws an exception if it fails
    loadInterfaceWithException :: SDoc -> Module -> WhereFrom -> IfM lcl ModIface
    loadInterfaceWithException :: forall lcl. SDoc -> GenModule Unit -> WhereFrom -> IfM lcl ModIface
    loadInterfaceWithException SDoc
    doc GenModule Unit
    mod_name WhereFrom
    where_from
      = forall gbl lcl a.
    TcRnIf gbl lcl (MaybeErr SDoc a) -> TcRnIf gbl lcl a
    withException (forall lcl.
    SDoc
    -> GenModule Unit -> WhereFrom -> IfM lcl (MaybeErr SDoc ModIface)
    loadInterface SDoc
    doc GenModule Unit
    mod_name WhereFrom
    where_from)

    ------------------
    loadInterface :: SDoc -> Module -> WhereFrom
                  -> IfM lcl (MaybeErr SDoc ModIface)

    -- loadInterface looks in both the HPT and PIT for the required interface
    -- If not found, it loads it, and puts it in the PIT (always).

    -- If it can't find a suitable interface file, we
    --      a) modify the PackageIfaceTable to have an empty entry
    --              (to avoid repeated complaints)
    --      b) return (Left message)
    --
    -- It's not necessarily an error for there not to be an interface
    -- file -- perhaps the module has changed, and that interface
    -- is no longer used

    loadInterface :: forall lcl.
    SDoc
    -> GenModule Unit -> WhereFrom -> IfM lcl (MaybeErr SDoc ModIface)
    loadInterface SDoc
    doc_str GenModule Unit
    mod WhereFrom
    from
      | forall u. GenModule (GenUnit u) -> Bool
    isHoleModule GenModule Unit
    mod
      -- Hole modules get special treatment
      = do HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
           let home_unit :: HomeUnit
    home_unit = HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env
           -- Redo search for our local hole module
           forall lcl.
    SDoc
    -> GenModule Unit -> WhereFrom -> IfM lcl (MaybeErr SDoc ModIface)
    loadInterface SDoc
    doc_str (HomeUnit -> ModuleName -> GenModule Unit
    mkHomeModule HomeUnit
    home_unit (forall unit. GenModule unit -> ModuleName
    moduleName GenModule Unit
    mod)) WhereFrom
    from
      | Bool
    otherwise
      = do
        Logger
    logger <- forall (m :: * -> *). HasLogger m => m Logger
    getLogger
        DynFlags
    dflags <- forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
        forall (m :: * -> *) a.
    MonadIO m =>
    Logger -> DynFlags -> SDoc -> (a -> ()) -> m a -> m a
    withTimingSilent Logger
    logger DynFlags
    dflags (String -> SDoc
    text String
    "loading interface") (forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()) forall a b. (a -> b) -> a -> b
    $ do
            {       -- Read the state
              (ExternalPackageState
    eps,HomePackageTable
    hpt) <- forall gbl lcl.
    TcRnIf gbl lcl (ExternalPackageState, HomePackageTable)
    getEpsAndHpt
            ; IfGblEnv
    gbl_env <- forall gbl lcl. TcRnIf gbl lcl gbl
    getGblEnv

            ; forall m n. SDoc -> TcRnIf m n ()
    traceIf (String -> SDoc
    text String
    "Considering whether to load" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr GenModule Unit
    mod SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr WhereFrom
    from)

                    -- Check whether we have the interface already
            ; HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
            ; let home_unit :: HomeUnit
    home_unit = HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env
            ; case HomePackageTable
    -> PackageIfaceTable -> GenModule Unit -> Maybe ModIface
    lookupIfaceByModule HomePackageTable
    hpt (ExternalPackageState -> PackageIfaceTable
    eps_PIT ExternalPackageState
    eps) GenModule Unit
    mod of {
                Just ModIface
    iface
                    -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded ModIface
    iface) ;   -- Already loaded
                            -- The (src_imp == mi_boot iface) test checks that the already-loaded
                            -- interface isn't a boot iface.  This can conceivably happen,
                            -- if an earlier import had a before we got to real imports.   I think.
                Maybe ModIface
    _ -> do {

            -- READ THE MODULE IN
            ; MaybeErr SDoc (ModIface, String)
    read_result <- case (HomeUnit
    -> ExternalPackageState
    -> GenModule Unit
    -> WhereFrom
    -> MaybeErr SDoc IsBootInterface
    wantHiBootFile HomeUnit
    home_unit ExternalPackageState
    eps GenModule Unit
    mod WhereFrom
    from) of
                               Failed SDoc
    err             -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. err -> MaybeErr err val
    Failed SDoc
    err)
                               Succeeded IsBootInterface
    hi_boot_file -> forall gbl lcl.
    SDoc
    -> IsBootInterface
    -> GenModule Unit
    -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, String))
    computeInterface SDoc
    doc_str IsBootInterface
    hi_boot_file GenModule Unit
    mod
            ; case MaybeErr SDoc (ModIface, String)
    read_result of {
                Failed SDoc
    err -> do
                    { let fake_iface :: ModIface
    fake_iface = GenModule Unit -> ModIface
    emptyFullModIface GenModule Unit
    mod

                    ; forall gbl lcl.
    (ExternalPackageState -> ExternalPackageState) -> TcRnIf gbl lcl ()
    updateEps_ forall a b. (a -> b) -> a -> b
    $ \ExternalPackageState
    eps ->
                            ExternalPackageState
    eps { eps_PIT :: PackageIfaceTable
    eps_PIT = forall a. ModuleEnv a -> GenModule Unit -> a -> ModuleEnv a
    extendModuleEnv (ExternalPackageState -> PackageIfaceTable
    eps_PIT ExternalPackageState
    eps) (forall (phase :: ModIfacePhase). ModIface_ phase -> GenModule Unit
    mi_module ModIface
    fake_iface) ModIface
    fake_iface }
                            -- Not found, so add an empty iface to
                            -- the EPS map so that we don't look again

                    ; forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. err -> MaybeErr err val
    Failed SDoc
    err) } ;

            -- Found and parsed!
            -- We used to have a sanity check here that looked for:
            --  * System importing ..
            --  * a home package module ..
            --  * that we know nothing about (mb_dep == Nothing)!
            --
            -- But this is no longer valid because thNameToGhcName allows users to
            -- cause the system to load arbitrary interfaces (by supplying an appropriate
            -- Template Haskell original-name).
                Succeeded (ModIface
    iface, String
    loc) ->
            let
                loc_doc :: SDoc
    loc_doc = String -> SDoc
    text String
    loc
            in
            forall a lcl.
    GenModule Unit -> SDoc -> IsBootInterface -> IfL a -> IfM lcl a
    initIfaceLcl (forall (phase :: ModIfacePhase). ModIface_ phase -> GenModule Unit
    mi_semantic_module ModIface
    iface) SDoc
    loc_doc (ModIface -> IsBootInterface
    mi_boot ModIface
    iface) forall a b. (a -> b) -> a -> b
    $

            forall a. IfL a -> IfL a
    dontLeakTheHPT forall a b. (a -> b) -> a -> b
    $ do

            --      Load the new ModIface into the External Package State
            -- Even home-package interfaces loaded by loadInterface
            --      (which only happens in OneShot mode; in Batch/Interactive
            --      mode, home-package modules are loaded one by one into the HPT)
            -- are put in the EPS.
            --
            -- The main thing is to add the ModIface to the PIT, but
            -- we also take the
            --      IfaceDecls, IfaceClsInst, IfaceFamInst, IfaceRules,
            -- out of the ModIface and put them into the big EPS pools

            -- NB: *first* we do tcIfaceDecls, so that the provenance of all the locally-defined
            ---    names is done correctly (notably, whether this is an .hi file or .hi-boot file).
            --     If we do loadExport first the wrong info gets into the cache (unless we
            --      explicitly tag each export which seems a bit of a bore)

            ; Bool
    ignore_prags      <- forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
    goptM GeneralFlag
    Opt_IgnoreInterfacePragmas
            ; [(Name, TyThing)]
    new_eps_decls     <- Bool -> [(Fingerprint, IfaceDecl)] -> IfL [(Name, TyThing)]
    tcIfaceDecls Bool
    ignore_prags (forall (phase :: ModIfacePhase).
    ModIface_ phase -> [IfaceDeclExts phase]
    mi_decls ModIface
    iface)
            ; [ClsInst]
    new_eps_insts     <- forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM IfaceClsInst -> IfL ClsInst
    tcIfaceInst (forall (phase :: ModIfacePhase). ModIface_ phase -> [IfaceClsInst]
    mi_insts ModIface
    iface)
            ; [FamInst]
    new_eps_fam_insts <- forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM IfaceFamInst -> IfL FamInst
    tcIfaceFamInst (forall (phase :: ModIfacePhase). ModIface_ phase -> [IfaceFamInst]
    mi_fam_insts ModIface
    iface)
            ; [CoreRule]
    new_eps_rules     <- Bool -> [IfaceRule] -> IfL [CoreRule]
    tcIfaceRules Bool
    ignore_prags (forall (phase :: ModIfacePhase). ModIface_ phase -> [IfaceRule]
    mi_rules ModIface
    iface)
            ; [Annotation]
    new_eps_anns      <- [IfaceAnnotation] -> IfL [Annotation]
    tcIfaceAnnotations (forall (phase :: ModIfacePhase).
    ModIface_ phase -> [IfaceAnnotation]
    mi_anns ModIface
    iface)
            ; [CompleteMatch]
    new_eps_complete_matches <- [IfaceCompleteMatch] -> IfL [CompleteMatch]
    tcIfaceCompleteMatches (forall (phase :: ModIfacePhase).
    ModIface_ phase -> [IfaceCompleteMatch]
    mi_complete_matches ModIface
    iface)

            ; let { final_iface :: ModIface
    final_iface = ModIface
    iface {
                                    mi_decls :: [IfaceDeclExts 'ModIfaceFinal]
    mi_decls     = forall a. String -> a
    panic String
    "No mi_decls in PIT",
                                    mi_insts :: [IfaceClsInst]
    mi_insts     = forall a. String -> a
    panic String
    "No mi_insts in PIT",
                                    mi_fam_insts :: [IfaceFamInst]
    mi_fam_insts = forall a. String -> a
    panic String
    "No mi_fam_insts in PIT",
                                    mi_rules :: [IfaceRule]
    mi_rules     = forall a. String -> a
    panic String
    "No mi_rules in PIT",
                                    mi_anns :: [IfaceAnnotation]
    mi_anns      = forall a. String -> a
    panic String
    "No mi_anns in PIT"
                                  }
                   }

            ; let bad_boot :: Bool
    bad_boot = ModIface -> IsBootInterface
    mi_boot ModIface
    iface forall a. Eq a => a -> a -> Bool
    == IsBootInterface
    IsBoot Bool -> Bool -> Bool
    && forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap forall a b. (a, b) -> a
    fst (IfGblEnv -> Maybe (GenModule Unit, IfG TypeEnv)
    if_rec_types IfGblEnv
    gbl_env) forall a. Eq a => a -> a -> Bool
    == forall a. a -> Maybe a
    Just GenModule Unit
    mod
                                -- Warn against an EPS-updating import
                                -- of one's own boot file! (one-shot only)
                                -- See Note [Loading your own hi-boot file]

            ; WARN( bad_boot, ppr mod )
              forall gbl lcl.
    (ExternalPackageState -> ExternalPackageState) -> TcRnIf gbl lcl ()
    updateEps_  forall a b. (a -> b) -> a -> b
    $ \ ExternalPackageState
    eps ->
               if forall a. GenModule Unit -> ModuleEnv a -> Bool
    elemModuleEnv GenModule Unit
    mod (ExternalPackageState -> PackageIfaceTable
    eps_PIT ExternalPackageState
    eps) Bool -> Bool -> Bool
    || HomeUnit -> ModIface -> Bool
    is_external_sig HomeUnit
    home_unit ModIface
    iface
                    then ExternalPackageState
    eps
               else if Bool
    bad_boot
                    -- See Note [Loading your own hi-boot file]
                    then ExternalPackageState
    eps { eps_PTE :: TypeEnv
    eps_PTE = TypeEnv -> [(Name, TyThing)] -> TypeEnv
    addDeclsToPTE (ExternalPackageState -> TypeEnv
    eps_PTE ExternalPackageState
    eps) [(Name, TyThing)]
    new_eps_decls }
               else
                    ExternalPackageState
    eps {
                      eps_PIT :: PackageIfaceTable
    eps_PIT          = forall a. ModuleEnv a -> GenModule Unit -> a -> ModuleEnv a
    extendModuleEnv (ExternalPackageState -> PackageIfaceTable
    eps_PIT ExternalPackageState
    eps) GenModule Unit
    mod ModIface
    final_iface,
                      eps_PTE :: TypeEnv
    eps_PTE          = TypeEnv -> [(Name, TyThing)] -> TypeEnv
    addDeclsToPTE   (ExternalPackageState -> TypeEnv
    eps_PTE ExternalPackageState
    eps) [(Name, TyThing)]
    new_eps_decls,
                      eps_rule_base :: PackageRuleBase
    eps_rule_base    = PackageRuleBase -> [CoreRule] -> PackageRuleBase
    extendRuleBaseList (ExternalPackageState -> PackageRuleBase
    eps_rule_base ExternalPackageState
    eps)
                                                            [CoreRule]
    new_eps_rules,
                      eps_complete_matches :: [CompleteMatch]
    eps_complete_matches
                                       = ExternalPackageState -> [CompleteMatch]
    eps_complete_matches ExternalPackageState
    eps forall a. [a] -> [a] -> [a]
    ++ [CompleteMatch]
    new_eps_complete_matches,
                      eps_inst_env :: PackageInstEnv
    eps_inst_env     = PackageInstEnv -> [ClsInst] -> PackageInstEnv
    extendInstEnvList (ExternalPackageState -> PackageInstEnv
    eps_inst_env ExternalPackageState
    eps)
                                                           [ClsInst]
    new_eps_insts,
                      eps_fam_inst_env :: PackageFamInstEnv
    eps_fam_inst_env = PackageFamInstEnv -> [FamInst] -> PackageFamInstEnv
    extendFamInstEnvList (ExternalPackageState -> PackageFamInstEnv
    eps_fam_inst_env ExternalPackageState
    eps)
                                                              [FamInst]
    new_eps_fam_insts,
                      eps_ann_env :: PackageAnnEnv
    eps_ann_env      = PackageAnnEnv -> [Annotation] -> PackageAnnEnv
    extendAnnEnvList (ExternalPackageState -> PackageAnnEnv
    eps_ann_env ExternalPackageState
    eps)
                                                          [Annotation]
    new_eps_anns,
                      eps_mod_fam_inst_env :: ModuleEnv PackageFamInstEnv
    eps_mod_fam_inst_env
                                       = let
                                           fam_inst_env :: PackageFamInstEnv
    fam_inst_env =
                                             PackageFamInstEnv -> [FamInst] -> PackageFamInstEnv
    extendFamInstEnvList PackageFamInstEnv
    emptyFamInstEnv
                                                                  [FamInst]
    new_eps_fam_insts
                                         in
                                         forall a. ModuleEnv a -> GenModule Unit -> a -> ModuleEnv a
    extendModuleEnv (ExternalPackageState -> ModuleEnv PackageFamInstEnv
    eps_mod_fam_inst_env ExternalPackageState
    eps)
                                                         GenModule Unit
    mod
                                                         PackageFamInstEnv
    fam_inst_env,
                      eps_stats :: EpsStats
    eps_stats        = EpsStats -> Int -> Int -> Int -> EpsStats
    addEpsInStats (ExternalPackageState -> EpsStats
    eps_stats ExternalPackageState
    eps)
                                                       (forall (t :: * -> *) a. Foldable t => t a -> Int
    length [(Name, TyThing)]
    new_eps_decls)
                                                       (forall (t :: * -> *) a. Foldable t => t a -> Int
    length [ClsInst]
    new_eps_insts)
                                                       (forall (t :: * -> *) a. Foldable t => t a -> Int
    length [CoreRule]
    new_eps_rules) }

            ; -- invoke plugins with *full* interface, not final_iface, to ensure
              -- that plugins have access to declarations, etc.
              ModIface
    res <- forall (m :: * -> *) a.
    Monad m =>
    HscEnv -> PluginOperation m a -> a -> m a
    withPlugins HscEnv
    hsc_env (\Plugin
    p -> Plugin -> forall lcl. [String] -> ModIface -> IfM lcl ModIface
    interfaceLoadAction Plugin
    p) ModIface
    iface
            ; forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded ModIface
    res)
        }}}}

    {- Note [Loading your own hi-boot file]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Generally speaking, when compiling module M, we should not
    load M.hi boot into the EPS.  After all, we are very shortly
    going to have full information about M.  Moreover, see
    Note [Do not update EPS with your own hi-boot] in GHC.Iface.Recomp.

    But there is a HORRIBLE HACK here.

    * At the end of tcRnImports, we call checkFamInstConsistency to
      check consistency of imported type-family instances
      See Note [The type family instance consistency story] in GHC.Tc.Instance.Family

    * Alas, those instances may refer to data types defined in M,
      if there is a M.hs-boot.

    * And that means we end up loading M.hi-boot, because those
      data types are not yet in the type environment.

    But in this weird case, /all/ we need is the types. We don't need
    instances, rules etc.  And if we put the instances in the EPS
    we get "duplicate instance" warnings when we compile the "real"
    instance in M itself.  Hence the strange business of just updateing
    the eps_PTE.

    This really happens in practice.  The module "GHC.Hs.Expr" gets
    "duplicate instance" errors if this hack is not present.

    This is a mess.

    Note [HPT space leak] (#15111)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In IfL, we defer some work until it is demanded using forkM, such
    as building TyThings from IfaceDecls. These thunks are stored in
    the ExternalPackageState, and they might never be poked.  If we're
    not careful, these thunks will capture the state of the loaded
    program when we read an interface file, and retain all that data
    for ever.

    Therefore, when loading a package interface file , we use a "clean"
    version of the HscEnv with all the data about the currently loaded
    program stripped out. Most of the fields can be panics because
    we'll never read them, but hsc_HPT needs to be empty because this
    interface will cause other interfaces to be loaded recursively, and
    when looking up those interfaces we use the HPT in loadInterface.
    We know that none of the interfaces below here can refer to
    home-package modules however, so it's safe for the HPT to be empty.
    -}

    dontLeakTheHPT :: IfL a -> IfL a
    dontLeakTheHPT :: forall a. IfL a -> IfL a
    dontLeakTheHPT IfL a
    thing_inside = do
      DynFlags
    dflags <- forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
      let
        cleanTopEnv :: HscEnv -> HscEnv
    cleanTopEnv HscEnv{[LoadedPlugin]
    [StaticPlugin]
    [Target]
    Maybe [UnitDatabase UnitId]
    Maybe (GenModule Unit, IORef TypeEnv)
    Maybe Interp
    IORef FinderCache
    IORef NameCache
    IORef ExternalPackageState
    Hooks
    DynFlags
    HomePackageTable
    Logger
    UnitEnv
    TmpFs
    ModuleGraph
    InteractiveContext
    hsc_unit_env :: HscEnv -> UnitEnv
    hsc_unit_dbs :: HscEnv -> Maybe [UnitDatabase UnitId]
    hsc_type_env_var :: HscEnv -> Maybe (GenModule Unit, IORef TypeEnv)
    hsc_tmpfs :: HscEnv -> TmpFs
    hsc_targets :: HscEnv -> [Target]
    hsc_static_plugins :: HscEnv -> [StaticPlugin]
    hsc_plugins :: HscEnv -> [LoadedPlugin]
    hsc_mod_graph :: HscEnv -> ModuleGraph
    hsc_logger :: HscEnv -> Logger
    hsc_interp :: HscEnv -> Maybe Interp
    hsc_hooks :: HscEnv -> Hooks
    hsc_dflags :: HscEnv -> DynFlags
    hsc_NC :: HscEnv -> IORef NameCache
    hsc_IC :: HscEnv -> InteractiveContext
    hsc_HPT :: HscEnv -> HomePackageTable
    hsc_FC :: HscEnv -> IORef FinderCache
    hsc_EPS :: HscEnv -> IORef ExternalPackageState
    hsc_tmpfs :: TmpFs
    hsc_hooks :: Hooks
    hsc_logger :: Logger
    hsc_unit_env :: UnitEnv
    hsc_unit_dbs :: Maybe [UnitDatabase UnitId]
    hsc_static_plugins :: [StaticPlugin]
    hsc_plugins :: [LoadedPlugin]
    hsc_interp :: Maybe Interp
    hsc_type_env_var :: Maybe (GenModule Unit, IORef TypeEnv)
    hsc_FC :: IORef FinderCache
    hsc_NC :: IORef NameCache
    hsc_EPS :: IORef ExternalPackageState
    hsc_HPT :: HomePackageTable
    hsc_IC :: InteractiveContext
    hsc_mod_graph :: ModuleGraph
    hsc_targets :: [Target]
    hsc_dflags :: DynFlags
    ..} =
           let
             -- wrinkle: when we're typechecking in --backpack mode, the
             -- instantiation of a signature might reside in the HPT, so
             -- this case breaks the assumption that EPS interfaces only
             -- refer to other EPS interfaces. We can detect when we're in
             -- typechecking-only mode by using backend==NoBackend, and
             -- in that case we don't empty the HPT.  (admittedly this is
             -- a bit of a hack, better suggestions welcome). A number of
             -- tests in testsuite/tests/backpack break without this
             -- tweak.
             keepFor20509 :: HomeModInfo -> Bool
    keepFor20509 HomeModInfo
    hmi
              | forall u. GenModule (GenUnit u) -> Bool
    isHoleModule (forall (phase :: ModIfacePhase). ModIface_ phase -> GenModule Unit
    mi_semantic_module (HomeModInfo -> ModIface
    hm_iface HomeModInfo
    hmi)) = Bool
    True
              | Bool
    otherwise = Bool
    False
             !hpt :: HomePackageTable
    hpt | DynFlags -> Backend
    backend DynFlags
    hsc_dflags forall a. Eq a => a -> a -> Bool
    == Backend
    NoBackend = if (HomeModInfo -> Bool) -> HomePackageTable -> Bool
    anyHpt HomeModInfo -> Bool
    keepFor20509 HomePackageTable
    hsc_HPT then HomePackageTable
    hsc_HPT
                                                                         else HomePackageTable
    emptyHomePackageTable
                  | Bool
    otherwise = HomePackageTable
    emptyHomePackageTable
           in
           HscEnv {  hsc_targets :: [Target]
    hsc_targets      = forall a. String -> a
    panic String
    "cleanTopEnv: hsc_targets"
                  ,  hsc_mod_graph :: ModuleGraph
    hsc_mod_graph    = forall a. String -> a
    panic String
    "cleanTopEnv: hsc_mod_graph"
                  ,  hsc_IC :: InteractiveContext
    hsc_IC           = forall a. String -> a
    panic String
    "cleanTopEnv: hsc_IC"
                  ,  hsc_HPT :: HomePackageTable
    hsc_HPT          = HomePackageTable
    hpt
                  , [LoadedPlugin]
    [StaticPlugin]
    Maybe [UnitDatabase UnitId]
    Maybe (GenModule Unit, IORef TypeEnv)
    Maybe Interp
    IORef FinderCache
    IORef NameCache
    IORef ExternalPackageState
    Hooks
    DynFlags
    Logger
    UnitEnv
    TmpFs
    hsc_unit_env :: UnitEnv
    hsc_unit_dbs :: Maybe [UnitDatabase UnitId]
    hsc_type_env_var :: Maybe (GenModule Unit, IORef TypeEnv)
    hsc_tmpfs :: TmpFs
    hsc_static_plugins :: [StaticPlugin]
    hsc_plugins :: [LoadedPlugin]
    hsc_logger :: Logger
    hsc_interp :: Maybe Interp
    hsc_hooks :: Hooks
    hsc_dflags :: DynFlags
    hsc_NC :: IORef NameCache
    hsc_FC :: IORef FinderCache
    hsc_EPS :: IORef ExternalPackageState
    hsc_tmpfs :: TmpFs
    hsc_hooks :: Hooks
    hsc_logger :: Logger
    hsc_unit_env :: UnitEnv
    hsc_unit_dbs :: Maybe [UnitDatabase UnitId]
    hsc_static_plugins :: [StaticPlugin]
    hsc_plugins :: [LoadedPlugin]
    hsc_interp :: Maybe Interp
    hsc_type_env_var :: Maybe (GenModule Unit, IORef TypeEnv)
    hsc_FC :: IORef FinderCache
    hsc_NC :: IORef NameCache
    hsc_EPS :: IORef ExternalPackageState
    hsc_dflags :: DynFlags
    .. }

        cleanGblEnv :: IfGblEnv -> IfGblEnv
    cleanGblEnv IfGblEnv
    gbl
          | DynFlags -> GhcMode
    ghcMode DynFlags
    dflags forall a. Eq a => a -> a -> Bool
    == GhcMode
    OneShot = IfGblEnv
    gbl
          | Bool
    otherwise = IfGblEnv
    gbl { if_rec_types :: Maybe (GenModule Unit, IfG TypeEnv)
    if_rec_types = forall a. Maybe a
    Nothing }

      forall gbl lcl a.
    (gbl -> gbl) -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
    updGblEnv IfGblEnv -> IfGblEnv
    cleanGblEnv forall a b. (a -> b) -> a -> b
    $
        forall gbl lcl a.
    (HscEnv -> HscEnv) -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
    updTopEnv HscEnv -> HscEnv
    cleanTopEnv forall a b. (a -> b) -> a -> b
    $ do
          !HscEnv
    _ <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv        -- force the updTopEnv
          !IfGblEnv
    _ <- forall gbl lcl. TcRnIf gbl lcl gbl
    getGblEnv
          IfL a
    thing_inside

    -- | Returns @True@ if a 'ModIface' comes from an external package.
    -- In this case, we should NOT load it into the EPS; the entities
    -- should instead come from the local merged signature interface.
    is_external_sig :: HomeUnit -> ModIface -> Bool
    is_external_sig :: HomeUnit -> ModIface -> Bool
    is_external_sig HomeUnit
    home_unit ModIface
    iface =
        -- It's a signature iface...
        forall (phase :: ModIfacePhase). ModIface_ phase -> GenModule Unit
    mi_semantic_module ModIface
    iface forall a. Eq a => a -> a -> Bool
    /= forall (phase :: ModIfacePhase). ModIface_ phase -> GenModule Unit
    mi_module ModIface
    iface Bool -> Bool -> Bool
    &&
        -- and it's not from the local package
        Bool -> Bool
    not (HomeUnit -> GenModule Unit -> Bool
    isHomeModule HomeUnit
    home_unit (forall (phase :: ModIfacePhase). ModIface_ phase -> GenModule Unit
    mi_module ModIface
    iface))

    -- | This is an improved version of 'findAndReadIface' which can also
    -- handle the case when a user requests @p[A=<B>]:M@ but we only
    -- have an interface for @p[A=<A>]:M@ (the indefinite interface.
    -- If we are not trying to build code, we load the interface we have,
    -- *instantiating it* according to how the holes are specified.
    -- (Of course, if we're actually building code, this is a hard error.)
    --
    -- In the presence of holes, 'computeInterface' has an important invariant:
    -- to load module M, its set of transitively reachable requirements must
    -- have an up-to-date local hi file for that requirement.  Note that if
    -- we are loading the interface of a requirement, this does not
    -- apply to the requirement itself; e.g., @p[A=<A>]:A@ does not require
    -- A.hi to be up-to-date (and indeed, we MUST NOT attempt to read A.hi, unless
    -- we are actually typechecking p.)
    computeInterface ::
           SDoc -> IsBootInterface -> Module
        -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, FilePath))
    computeInterface :: forall gbl lcl.
    SDoc
    -> IsBootInterface
    -> GenModule Unit
    -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, String))
    computeInterface SDoc
    doc_str IsBootInterface
    hi_boot_file GenModule Unit
    mod0 = do
        MASSERT( not (isHoleModule mod0) )
        HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
        let home_unit :: HomeUnit
    home_unit = HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env
        case GenModule Unit -> (InstalledModule, Maybe InstantiatedModule)
    getModuleInstantiation GenModule Unit
    mod0 of
            (InstalledModule
    imod, Just InstantiatedModule
    indef) | forall u. GenHomeUnit u -> Bool
    isHomeUnitIndefinite HomeUnit
    home_unit -> do
                MaybeErr SDoc (ModIface, String)
    r <- forall gbl lcl.
    SDoc
    -> InstalledModule
    -> GenModule Unit
    -> IsBootInterface
    -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, String))
    findAndReadIface SDoc
    doc_str InstalledModule
    imod GenModule Unit
    mod0 IsBootInterface
    hi_boot_file
                case MaybeErr SDoc (ModIface, String)
    r of
                    Succeeded (ModIface
    iface0, String
    path) -> do
                        HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
                        Either ErrorMessages ModIface
    r <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall a b. (a -> b) -> a -> b
    $
                            HscEnv
    -> [(ModuleName, GenModule Unit)]
    -> Maybe NameShape
    -> ModIface
    -> IO (Either ErrorMessages ModIface)
    rnModIface HscEnv
    hsc_env (forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts (forall unit. GenModule unit -> unit
    moduleUnit InstantiatedModule
    indef))
                                       forall a. Maybe a
    Nothing ModIface
    iface0
                        case Either ErrorMessages ModIface
    r of
                            Right ModIface
    x -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded (ModIface
    x, String
    path))
                            Left ErrorMessages
    errs -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall e a. Exception e => e -> IO a
    throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ErrorMessages -> SourceError
    mkSrcErr forall a b. (a -> b) -> a -> b
    $ ErrorMessages
    errs
                    Failed SDoc
    err -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. err -> MaybeErr err val
    Failed SDoc
    err)
            (InstalledModule
    mod, Maybe InstantiatedModule
    _) ->
                forall gbl lcl.
    SDoc
    -> InstalledModule
    -> GenModule Unit
    -> IsBootInterface
    -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, String))
    findAndReadIface SDoc
    doc_str InstalledModule
    mod GenModule Unit
    mod0 IsBootInterface
    hi_boot_file

    -- | Compute the signatures which must be compiled in order to
    -- load the interface for a 'Module'.  The output of this function
    -- is always a subset of 'moduleFreeHoles'; it is more precise
    -- because in signature @p[A=\<A>,B=\<B>]:B@, although the free holes
    -- are A and B, B might not depend on A at all!
    --
    -- If this is invoked on a signature, this does NOT include the
    -- signature itself; e.g. precise free module holes of
    -- @p[A=\<A>,B=\<B>]:B@ never includes B.
    moduleFreeHolesPrecise
        :: SDoc -> Module
        -> TcRnIf gbl lcl (MaybeErr SDoc (UniqDSet ModuleName))
    moduleFreeHolesPrecise :: forall gbl lcl.
    SDoc
    -> GenModule Unit
    -> TcRnIf gbl lcl (MaybeErr SDoc (UniqDSet ModuleName))
    moduleFreeHolesPrecise SDoc
    doc_str GenModule Unit
    mod
     | GenModule Unit -> Bool
    moduleIsDefinite GenModule Unit
    mod = forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded forall a. UniqDSet a
    emptyUniqDSet)
     | Bool
    otherwise =
       case GenModule Unit -> (InstalledModule, Maybe InstantiatedModule)
    getModuleInstantiation GenModule Unit
    mod of
        (InstalledModule
    imod, Just InstantiatedModule
    indef) -> do
            let insts :: [(ModuleName, GenModule Unit)]
    insts = forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts (forall unit. GenModule unit -> unit
    moduleUnit InstantiatedModule
    indef)
            forall m n. SDoc -> TcRnIf m n ()
    traceIf (String -> SDoc
    text String
    "Considering whether to load" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr GenModule Unit
    mod SDoc -> SDoc -> SDoc
    <+>
                     String -> SDoc
    text String
    "to compute precise free module holes")
            (ExternalPackageState
    eps, HomePackageTable
    hpt) <- forall gbl lcl.
    TcRnIf gbl lcl (ExternalPackageState, HomePackageTable)
    getEpsAndHpt
            case ExternalPackageState
    -> HomePackageTable -> Maybe (UniqDSet ModuleName)
    tryEpsAndHpt ExternalPackageState
    eps HomePackageTable
    hpt forall a. Maybe a -> Maybe a -> Maybe a
    `firstJust` ExternalPackageState
    -> InstalledModule
    -> [(ModuleName, GenModule Unit)]
    -> Maybe (UniqDSet ModuleName)
    tryDepsCache ExternalPackageState
    eps InstalledModule
    imod [(ModuleName, GenModule Unit)]
    insts of
                Just UniqDSet ModuleName
    r -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded UniqDSet ModuleName
    r)
                Maybe (UniqDSet ModuleName)
    Nothing -> InstalledModule
    -> [(ModuleName, GenModule Unit)]
    -> TcRnIf gbl lcl (MaybeErr SDoc (UniqDSet ModuleName))
    readAndCache InstalledModule
    imod [(ModuleName, GenModule Unit)]
    insts
        (InstalledModule
    _, Maybe InstantiatedModule
    Nothing) -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded forall a. UniqDSet a
    emptyUniqDSet)
      where
        tryEpsAndHpt :: ExternalPackageState
    -> HomePackageTable -> Maybe (UniqDSet ModuleName)
    tryEpsAndHpt ExternalPackageState
    eps HomePackageTable
    hpt =
            forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ModIface -> UniqDSet ModuleName
    mi_free_holes (HomePackageTable
    -> PackageIfaceTable -> GenModule Unit -> Maybe ModIface
    lookupIfaceByModule HomePackageTable
    hpt (ExternalPackageState -> PackageIfaceTable
    eps_PIT ExternalPackageState
    eps) GenModule Unit
    mod)
        tryDepsCache :: ExternalPackageState
    -> InstalledModule
    -> [(ModuleName, GenModule Unit)]
    -> Maybe (UniqDSet ModuleName)
    tryDepsCache ExternalPackageState
    eps InstalledModule
    imod [(ModuleName, GenModule Unit)]
    insts =
            case forall a. InstalledModuleEnv a -> InstalledModule -> Maybe a
    lookupInstalledModuleEnv (ExternalPackageState -> InstalledModuleEnv (UniqDSet ModuleName)
    eps_free_holes ExternalPackageState
    eps) InstalledModule
    imod of
                Just UniqDSet ModuleName
    ifhs  -> forall a. a -> Maybe a
    Just (UniqDSet ModuleName
    -> [(ModuleName, GenModule Unit)] -> UniqDSet ModuleName
    renameFreeHoles UniqDSet ModuleName
    ifhs [(ModuleName, GenModule Unit)]
    insts)
                Maybe (UniqDSet ModuleName)
    _otherwise -> forall a. Maybe a
    Nothing
        readAndCache :: InstalledModule
    -> [(ModuleName, GenModule Unit)]
    -> TcRnIf gbl lcl (MaybeErr SDoc (UniqDSet ModuleName))
    readAndCache InstalledModule
    imod [(ModuleName, GenModule Unit)]
    insts = do
            MaybeErr SDoc (ModIface, String)
    mb_iface <- forall gbl lcl.
    SDoc
    -> InstalledModule
    -> GenModule Unit
    -> IsBootInterface
    -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, String))
    findAndReadIface (String -> SDoc
    text String
    "moduleFreeHolesPrecise" SDoc -> SDoc -> SDoc
    <+> SDoc
    doc_str) InstalledModule
    imod GenModule Unit
    mod IsBootInterface
    NotBoot
            case MaybeErr SDoc (ModIface, String)
    mb_iface of
                Succeeded (ModIface
    iface, String
    _) -> do
                    let ifhs :: UniqDSet ModuleName
    ifhs = ModIface -> UniqDSet ModuleName
    mi_free_holes ModIface
    iface
                    -- Cache it
                    forall gbl lcl.
    (ExternalPackageState -> ExternalPackageState) -> TcRnIf gbl lcl ()
    updateEps_ (\ExternalPackageState
    eps ->
                        ExternalPackageState
    eps { eps_free_holes :: InstalledModuleEnv (UniqDSet ModuleName)
    eps_free_holes = forall a.
    InstalledModuleEnv a
    -> InstalledModule -> a -> InstalledModuleEnv a
    extendInstalledModuleEnv (ExternalPackageState -> InstalledModuleEnv (UniqDSet ModuleName)
    eps_free_holes ExternalPackageState
    eps) InstalledModule
    imod UniqDSet ModuleName
    ifhs })
                    forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded (UniqDSet ModuleName
    -> [(ModuleName, GenModule Unit)] -> UniqDSet ModuleName
    renameFreeHoles UniqDSet ModuleName
    ifhs [(ModuleName, GenModule Unit)]
    insts))
                Failed SDoc
    err -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. err -> MaybeErr err val
    Failed SDoc
    err)

    wantHiBootFile :: HomeUnit -> ExternalPackageState -> Module -> WhereFrom
                   -> MaybeErr SDoc IsBootInterface
    -- Figure out whether we want Foo.hi or Foo.hi-boot
    wantHiBootFile :: HomeUnit
    -> ExternalPackageState
    -> GenModule Unit
    -> WhereFrom
    -> MaybeErr SDoc IsBootInterface
    wantHiBootFile HomeUnit
    home_unit ExternalPackageState
    eps GenModule Unit
    mod WhereFrom
    from
      = case WhereFrom
    from of
           ImportByUser IsBootInterface
    usr_boot
              | IsBootInterface
    usr_boot forall a. Eq a => a -> a -> Bool
    == IsBootInterface
    IsBoot Bool -> Bool -> Bool
    && HomeUnit -> GenModule Unit -> Bool
    notHomeModule HomeUnit
    home_unit GenModule Unit
    mod
              -> forall err val. err -> MaybeErr err val
    Failed (GenModule Unit -> SDoc
    badSourceImport GenModule Unit
    mod)
              | Bool
    otherwise -> forall err val. val -> MaybeErr err val
    Succeeded IsBootInterface
    usr_boot

           WhereFrom
    ImportByPlugin
              -> forall err val. val -> MaybeErr err val
    Succeeded IsBootInterface
    NotBoot

           WhereFrom
    ImportBySystem
              | HomeUnit -> GenModule Unit -> Bool
    notHomeModule HomeUnit
    home_unit GenModule Unit
    mod
              -> forall err val. val -> MaybeErr err val
    Succeeded IsBootInterface
    NotBoot
                 -- If the module to be imported is not from this package
                 -- don't look it up in eps_is_boot, because that is keyed
                 -- on the ModuleName of *home-package* modules only.
                 -- We never import boot modules from other packages!

              | Bool
    otherwise
              -> case forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
    lookupUFM (ExternalPackageState -> ModuleNameEnv ModuleNameWithIsBoot
    eps_is_boot ExternalPackageState
    eps) (forall unit. GenModule unit -> ModuleName
    moduleName GenModule Unit
    mod) of
                    Just (GWIB { gwib_isBoot :: forall mod. GenWithIsBoot mod -> IsBootInterface
    gwib_isBoot = IsBootInterface
    is_boot }) ->
                      forall err val. val -> MaybeErr err val
    Succeeded IsBootInterface
    is_boot
                    Maybe ModuleNameWithIsBoot
    Nothing ->
                      forall err val. val -> MaybeErr err val
    Succeeded IsBootInterface
    NotBoot
                         -- The boot-ness of the requested interface,
                         -- based on the dependencies in directly-imported modules

    badSourceImport :: Module -> SDoc
    badSourceImport :: GenModule Unit -> SDoc
    badSourceImport GenModule Unit
    mod
      = SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    text String
    "You cannot {-# SOURCE #-} import a module from another package")
           Int
    2 (String -> SDoc
    text String
    "but" SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr GenModule Unit
    mod) SDoc -> SDoc -> SDoc
    <+> PtrString -> SDoc
    ptext (String -> PtrString
    sLit String
    "is from package")
              SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr (forall unit. GenModule unit -> unit
    moduleUnit GenModule Unit
    mod)))

    -----------------------------------------------------
    --      Loading type/class/value decls
    -- We pass the full Module name here, replete with
    -- its package info, so that we can build a Name for
    -- each binder with the right package info in it
    -- All subsequent lookups, including crucially lookups during typechecking
    -- the declaration itself, will find the fully-glorious Name
    --
    -- We handle ATs specially.  They are not main declarations, but also not
    -- implicit things (in particular, adding them to `implicitTyThings' would mess
    -- things up in the renaming/type checking of source programs).
    -----------------------------------------------------

    addDeclsToPTE :: PackageTypeEnv -> [(Name,TyThing)] -> PackageTypeEnv
    addDeclsToPTE :: TypeEnv -> [(Name, TyThing)] -> TypeEnv
    addDeclsToPTE TypeEnv
    pte [(Name, TyThing)]
    things = forall a. NameEnv a -> [(Name, a)] -> NameEnv a
    extendNameEnvList TypeEnv
    pte [(Name, TyThing)]
    things

    {-
    *********************************************************
    *                                                      *
    \subsection{Reading an interface file}
    *                                                      *
    *********************************************************

    Note [Home module load error]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If the sought-for interface is in the current package (as determined
    by -package-name flag) then it jolly well should already be in the HPT
    because we process home-package modules in dependency order.  (Except
    in one-shot mode; see notes with hsc_HPT decl in GHC.Driver.Env).

    It is possible (though hard) to get this error through user behaviour.
      * Suppose package P (modules P1, P2) depends on package Q (modules Q1,
        Q2, with Q2 importing Q1)
      * We compile both packages.
      * Now we edit package Q so that it somehow depends on P
      * Now recompile Q with --make (without recompiling P).
      * Then Q1 imports, say, P1, which in turn depends on Q2. So Q2
        is a home-package module which is not yet in the HPT!  Disaster.

    This actually happened with P=base, Q=ghc-prim, via the AMP warnings.
    See #8320.
    -}

    findAndReadIface :: SDoc
                     -- The unique identifier of the on-disk module we're
                     -- looking for
                     -> InstalledModule
                     -- The *actual* module we're looking for.  We use
                     -- this to check the consistency of the requirements
                     -- of the module we read out.
                     -> Module
                     -> IsBootInterface     -- True  <=> Look for a .hi-boot file
                                            -- False <=> Look for .hi file
                     -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, FilePath))
            -- Nothing <=> file not found, or unreadable, or illegible
            -- Just x  <=> successfully found and parsed

            -- It *doesn't* add an error to the monad, because
            -- sometimes it's ok to fail... see notes with loadInterface
    findAndReadIface :: forall gbl lcl.
    SDoc
    -> InstalledModule
    -> GenModule Unit
    -> IsBootInterface
    -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, String))
    findAndReadIface SDoc
    doc_str InstalledModule
    mod GenModule Unit
    wanted_mod_with_insts IsBootInterface
    hi_boot_file
      = do forall m n. SDoc -> TcRnIf m n ()
    traceIf ([SDoc] -> SDoc
    sep [[SDoc] -> SDoc
    hsep [String -> SDoc
    text String
    "Reading",
                               if IsBootInterface
    hi_boot_file forall a. Eq a => a -> a -> Bool
    == IsBootInterface
    IsBoot
                                 then String -> SDoc
    text String
    "[boot]"
                                 else SDoc
    Outputable.empty,
                               String -> SDoc
    text String
    "interface for",
                               forall a. Outputable a => a -> SDoc
    ppr InstalledModule
    mod SDoc -> SDoc -> SDoc
    <> SDoc
    semi],
                         Int -> SDoc -> SDoc
    nest Int
    4 (String -> SDoc
    text String
    "reason:" SDoc -> SDoc -> SDoc
    <+> SDoc
    doc_str)])

           -- Check for GHC.Prim, and return its static interface
           -- See Note [GHC.Prim] in primops.txt.pp.
           -- TODO: make this check a function
           if InstalledModule
    mod InstalledModule -> GenModule Unit -> Bool
    `installedModuleEq` GenModule Unit
    gHC_PRIM
               then do
                   Hooks
    hooks <- forall (m :: * -> *). HasHooks m => m Hooks
    getHooks
                   let iface :: ModIface
    iface = case Hooks -> Maybe ModIface
    ghcPrimIfaceHook Hooks
    hooks of
                                Maybe ModIface
    Nothing -> ModIface
    ghcPrimIface
                                Just ModIface
    h  -> ModIface
    h
                   forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded (ModIface
    iface, String
    "<built in interface for GHC.Prim>"))
               else do
                   DynFlags
    dflags <- forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
                   -- Look for the file
                   HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
                   InstalledFindResult
    mb_found <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (HscEnv -> InstalledModule -> IO InstalledFindResult
    findExactModule HscEnv
    hsc_env InstalledModule
    mod)
                   let home_unit :: HomeUnit
    home_unit  = HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env
                   case InstalledFindResult
    mb_found of
                       InstalledFound ModLocation
    loc InstalledModule
    mod -> do
                           -- Found file, so read it
                           let file_path :: String
    file_path = IsBootInterface -> String -> String
    addBootSuffix_maybe IsBootInterface
    hi_boot_file
                                                               (ModLocation -> String
    ml_hi_file ModLocation
    loc)

                           -- See Note [Home module load error]
                           if forall u. GenHomeUnit u -> InstalledModule -> Bool
    isHomeInstalledModule HomeUnit
    home_unit InstalledModule
    mod Bool -> Bool -> Bool
    &&
                              Bool -> Bool
    not (GhcMode -> Bool
    isOneShot (DynFlags -> GhcMode
    ghcMode DynFlags
    dflags))
                               then forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. err -> MaybeErr err val
    Failed (InstalledModule -> ModLocation -> SDoc
    homeModError InstalledModule
    mod ModLocation
    loc))
                               else do MaybeErr SDoc (ModIface, String)
    r <- String -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, String))
    read_file String
    file_path
                                       MaybeErr SDoc (ModIface, String) -> IOEnv (Env gbl lcl) ()
    checkBuildDynamicToo MaybeErr SDoc (ModIface, String)
    r
                                       forall (m :: * -> *) a. Monad m => a -> m a
    return MaybeErr SDoc (ModIface, String)
    r
                       InstalledFindResult
    err -> do
                           forall m n. SDoc -> TcRnIf m n ()
    traceIf (String -> SDoc
    text String
    "...not found")
                           HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
                           let profile :: Profile
    profile = Platform -> Ways -> Profile
    Profile (DynFlags -> Platform
    targetPlatform DynFlags
    dflags) (DynFlags -> Ways
    ways DynFlags
    dflags)
                           forall (m :: * -> *) a. Monad m => a -> m a
    return forall a b. (a -> b) -> a -> b
    $ forall err val. err -> MaybeErr err val
    Failed forall a b. (a -> b) -> a -> b
    $ UnitEnv
    -> Profile
    -> ([String] -> SDoc)
    -> ModuleName
    -> InstalledFindResult
    -> SDoc
    cannotFindInterface
                                               (HscEnv -> UnitEnv
    hsc_unit_env HscEnv
    hsc_env)
                                               Profile
    profile
                                               (DynFlags -> [String] -> SDoc
    may_show_locations (HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env))
                                               (forall unit. GenModule unit -> ModuleName
    moduleName InstalledModule
    mod)
                                               InstalledFindResult
    err
        where read_file :: String -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, String))
    read_file String
    file_path = do
                  forall m n. SDoc -> TcRnIf m n ()
    traceIf (String -> SDoc
    text String
    "readIFace" SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    file_path)
                  -- Figure out what is recorded in mi_module.  If this is
                  -- a fully definite interface, it'll match exactly, but
                  -- if it's indefinite, the inside will be uninstantiated!
                  UnitState
    unit_state <- HscEnv -> UnitState
    hsc_units forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
                  let wanted_mod :: GenModule Unit
    wanted_mod =
                        case GenModule Unit -> (InstalledModule, Maybe InstantiatedModule)
    getModuleInstantiation GenModule Unit
    wanted_mod_with_insts of
                            (InstalledModule
    _, Maybe InstantiatedModule
    Nothing) -> GenModule Unit
    wanted_mod_with_insts
                            (InstalledModule
    _, Just InstantiatedModule
    indef_mod) ->
                              UnitState -> InstantiatedModule -> GenModule Unit
    instModuleToModule UnitState
    unit_state
                                (InstantiatedModule -> InstantiatedModule
    uninstantiateInstantiatedModule InstantiatedModule
    indef_mod)
                  MaybeErr SDoc ModIface
    read_result <- forall gbl lcl.
    GenModule Unit -> String -> TcRnIf gbl lcl (MaybeErr SDoc ModIface)
    readIface GenModule Unit
    wanted_mod String
    file_path
                  case MaybeErr SDoc ModIface
    read_result of
                    Failed SDoc
    err -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. err -> MaybeErr err val
    Failed (String -> SDoc -> SDoc
    badIfaceFile String
    file_path SDoc
    err))
                    Succeeded ModIface
    iface -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded (ModIface
    iface, String
    file_path))
                                -- Don't forget to fill in the package name...

              -- Indefinite interfaces are ALWAYS non-dynamic.
              checkBuildDynamicToo :: MaybeErr SDoc (ModIface, String) -> IOEnv (Env gbl lcl) ()
    checkBuildDynamicToo (Succeeded (ModIface
    iface, String
    _filePath))
                | Bool -> Bool
    not (GenModule Unit -> Bool
    moduleIsDefinite (forall (phase :: ModIfacePhase). ModIface_ phase -> GenModule Unit
    mi_module ModIface
    iface)) = forall (m :: * -> *) a. Monad m => a -> m a
    return ()

              checkBuildDynamicToo (Succeeded (ModIface
    iface, String
    filePath)) = do
                  let load_dynamic :: IOEnv (Env gbl lcl) ()
    load_dynamic = do
                         DynFlags
    dflags <- forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
                         let dynFilePath :: String
    dynFilePath = IsBootInterface -> String -> String
    addBootSuffix_maybe IsBootInterface
    hi_boot_file
                                         forall a b. (a -> b) -> a -> b
    $ String -> String -> String
    replaceExtension String
    filePath (DynFlags -> String
    hiSuf DynFlags
    dflags)
                         MaybeErr SDoc (ModIface, String)
    r <- String -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, String))
    read_file String
    dynFilePath
                         case MaybeErr SDoc (ModIface, String)
    r of
                             Succeeded (ModIface
    dynIface, String
    _)
                              | ModIfaceBackend -> Fingerprint
    mi_mod_hash (forall (phase :: ModIfacePhase).
    ModIface_ phase -> IfaceBackendExts phase
    mi_final_exts ModIface
    iface) forall a. Eq a => a -> a -> Bool
    == ModIfaceBackend -> Fingerprint
    mi_mod_hash (forall (phase :: ModIfacePhase).
    ModIface_ phase -> IfaceBackendExts phase
    mi_final_exts ModIface
    dynIface) ->
                                 forall (m :: * -> *) a. Monad m => a -> m a
    return ()
                              | Bool
    otherwise ->
                                 do forall m n. SDoc -> TcRnIf m n ()
    traceIf (String -> SDoc
    text String
    "Dynamic hash doesn't match")
                                    forall (m :: * -> *). MonadIO m => DynFlags -> m ()
    setDynamicTooFailed DynFlags
    dflags
                             Failed SDoc
    err ->
                                 do forall m n. SDoc -> TcRnIf m n ()
    traceIf (String -> SDoc
    text String
    "Failed to load dynamic interface file:" SDoc -> SDoc -> SDoc
    $$ SDoc
    err)
                                    forall (m :: * -> *). MonadIO m => DynFlags -> m ()
    setDynamicTooFailed DynFlags
    dflags

                  DynFlags
    dflags <- forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
                  forall (m :: * -> *). MonadIO m => DynFlags -> m DynamicTooState
    dynamicTooState DynFlags
    dflags forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
                    DynamicTooState
    DT_Dont   -> forall (m :: * -> *) a. Monad m => a -> m a
    return ()
                    DynamicTooState
    DT_Failed -> forall (m :: * -> *) a. Monad m => a -> m a
    return ()
                    DynamicTooState
    DT_Dyn    -> IOEnv (Env gbl lcl) ()
    load_dynamic
                    DynamicTooState
    DT_OK     -> forall gbl lcl a. TcRnIf gbl lcl a -> TcRnIf gbl lcl a
    withDynamicNow IOEnv (Env gbl lcl) ()
    load_dynamic

              checkBuildDynamicToo MaybeErr SDoc (ModIface, String)
    _ = forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- | Write interface file
    writeIface :: Logger -> DynFlags -> FilePath -> ModIface -> IO ()
    writeIface :: Logger -> DynFlags -> String -> ModIface -> IO ()
    writeIface Logger
    logger DynFlags
    dflags String
    hi_file_path ModIface
    new_iface
        = do Bool -> String -> IO ()
    createDirectoryIfMissing Bool
    True (String -> String
    takeDirectory String
    hi_file_path)
             let printer :: TraceBinIFace
    printer = (SDoc -> IO ()) -> TraceBinIFace
    TraceBinIFace (Logger -> DynFlags -> Int -> SDoc -> IO ()
    debugTraceMsg Logger
    logger DynFlags
    dflags Int
    3)
                 profile :: Profile
    profile = DynFlags -> Profile
    targetProfile DynFlags
    dflags
             Profile -> TraceBinIFace -> String -> ModIface -> IO ()
    writeBinIface Profile
    profile TraceBinIFace
    printer String
    hi_file_path ModIface
    new_iface

    -- @readIface@ tries just the one file.
    readIface :: Module -> FilePath
              -> TcRnIf gbl lcl (MaybeErr SDoc ModIface)
            -- Failed err    <=> file not found, or unreadable, or illegible
            -- Succeeded iface <=> successfully found and parsed

    readIface :: forall gbl lcl.
    GenModule Unit -> String -> TcRnIf gbl lcl (MaybeErr SDoc ModIface)
    readIface GenModule Unit
    wanted_mod String
    file_path
      = do  { Either SomeException ModIface
    res <- forall env r. IOEnv env r -> IOEnv env (Either SomeException r)
    tryMostM forall a b. (a -> b) -> a -> b
    $
                     forall a b.
    CheckHiWay -> TraceBinIFace -> String -> TcRnIf a b ModIface
    readBinIface CheckHiWay
    CheckHiWay TraceBinIFace
    QuietBinIFace String
    file_path
            ; case Either SomeException ModIface
    res of
                Right ModIface
    iface
                    -- NB: This check is NOT just a sanity check, it is
                    -- critical for correctness of recompilation checking
                    -- (it lets us tell when -this-unit-id has changed.)
                    | GenModule Unit
    wanted_mod forall a. Eq a => a -> a -> Bool
    == GenModule Unit
    actual_mod
                                    -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. val -> MaybeErr err val
    Succeeded ModIface
    iface)
                    | Bool
    otherwise     -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. err -> MaybeErr err val
    Failed SDoc
    err)
                    where
                      actual_mod :: GenModule Unit
    actual_mod = forall (phase :: ModIfacePhase). ModIface_ phase -> GenModule Unit
    mi_module ModIface
    iface
                      err :: SDoc
    err = GenModule Unit -> GenModule Unit -> SDoc
    hiModuleNameMismatchWarn GenModule Unit
    wanted_mod GenModule Unit
    actual_mod

                Left SomeException
    exn    -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall err val. err -> MaybeErr err val
    Failed (String -> SDoc
    text (forall e. Exception e => e -> String
    showException SomeException
    exn)))
        }

    {-
    *********************************************************
    *                                                       *
            Wired-in interface for GHC.Prim
    *                                                       *
    *********************************************************
    -}

    initExternalPackageState :: ExternalPackageState
    initExternalPackageState :: ExternalPackageState
    initExternalPackageState
      = EPS {
          eps_is_boot :: ModuleNameEnv ModuleNameWithIsBoot
    eps_is_boot          = forall key elt. UniqFM key elt
    emptyUFM,
          eps_PIT :: PackageIfaceTable
    eps_PIT              = PackageIfaceTable
    emptyPackageIfaceTable,
          eps_free_holes :: InstalledModuleEnv (UniqDSet ModuleName)
    eps_free_holes       = forall a. InstalledModuleEnv a
    emptyInstalledModuleEnv,
          eps_PTE :: TypeEnv
    eps_PTE              = TypeEnv
    emptyTypeEnv,
          eps_inst_env :: PackageInstEnv
    eps_inst_env         = PackageInstEnv
    emptyInstEnv,
          eps_fam_inst_env :: PackageFamInstEnv
    eps_fam_inst_env     = PackageFamInstEnv
    emptyFamInstEnv,
          eps_rule_base :: PackageRuleBase
    eps_rule_base        = [CoreRule] -> PackageRuleBase
    mkRuleBase [CoreRule]
    builtinRules,
            -- Initialise the EPS rule pool with the built-in rules
          eps_mod_fam_inst_env :: ModuleEnv PackageFamInstEnv
    eps_mod_fam_inst_env = forall a. ModuleEnv a
    emptyModuleEnv,
          eps_complete_matches :: [CompleteMatch]
    eps_complete_matches = [],
          eps_ann_env :: PackageAnnEnv
    eps_ann_env          = PackageAnnEnv
    emptyAnnEnv,
          eps_stats :: EpsStats
    eps_stats = EpsStats { n_ifaces_in :: Int
    n_ifaces_in = Int
    0, n_decls_in :: Int
    n_decls_in = Int
    0, n_decls_out :: Int
    n_decls_out = Int
    0
                               , n_insts_in :: Int
    n_insts_in = Int
    0, n_insts_out :: Int
    n_insts_out = Int
    0
                               , n_rules_in :: Int
    n_rules_in = forall (t :: * -> *) a. Foldable t => t a -> Int
    length [CoreRule]
    builtinRules, n_rules_out :: Int
    n_rules_out = Int
    0 }
        }

    {-
    *********************************************************
    *                                                       *
            Wired-in interface for GHC.Prim
    *                                                       *
    *********************************************************
    -}

    -- See Note [GHC.Prim] in primops.txt.pp.
    ghcPrimIface :: ModIface
    ghcPrimIface :: ModIface
    ghcPrimIface
      = ModIface
    empty_iface {
            mi_exports :: [IfaceExport]
    mi_exports  = [IfaceExport]
    ghcPrimExports,
            mi_decls :: [IfaceDeclExts 'ModIfaceFinal]
    mi_decls    = [],
            mi_fixities :: [(OccName, Fixity)]
    mi_fixities = [(OccName, Fixity)]
    fixities,
            mi_final_exts :: IfaceBackendExts 'ModIfaceFinal
    mi_final_exts = (forall (phase :: ModIfacePhase).
    ModIface_ phase -> IfaceBackendExts phase
    mi_final_exts ModIface
    empty_iface){ mi_fix_fn :: OccName -> Maybe Fixity
    mi_fix_fn = [(OccName, Fixity)] -> OccName -> Maybe Fixity
    mkIfaceFixCache [(OccName, Fixity)]
    fixities },
            mi_decl_docs :: DeclDocMap
    mi_decl_docs = DeclDocMap
    ghcPrimDeclDocs -- See Note [GHC.Prim Docs]
            }
      where
        empty_iface :: ModIface
    empty_iface = GenModule Unit -> ModIface
    emptyFullModIface GenModule Unit
    gHC_PRIM

        -- The fixity listed here for @`seq`@ should match
        -- those in primops.txt.pp (from which Haddock docs are generated).
        fixities :: [(OccName, Fixity)]
    fixities = (forall a. NamedThing a => a -> OccName
    getOccName Id
    seqId, SourceText -> Int -> FixityDirection -> Fixity
    Fixity SourceText
    NoSourceText Int
    0 FixityDirection
    InfixR)
                 forall a. a -> [a] -> [a]
    : forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe PrimOp -> Maybe (OccName, Fixity)
    mkFixity [PrimOp]
    allThePrimOps
        mkFixity :: PrimOp -> Maybe (OccName, Fixity)
    mkFixity PrimOp
    op = (,) (PrimOp -> OccName
    primOpOcc PrimOp
    op) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> PrimOp -> Maybe Fixity
    primOpFixity PrimOp
    op

    {-
    *********************************************************
    *                                                      *
    \subsection{Statistics}
    *                                                      *
    *********************************************************
    -}

    ifaceStats :: ExternalPackageState -> SDoc
    ifaceStats :: ExternalPackageState -> SDoc
    ifaceStats ExternalPackageState
    eps
      = [SDoc] -> SDoc
    hcat [String -> SDoc
    text String
    "Renamer stats: ", SDoc
    msg]
      where
        stats :: EpsStats
    stats = ExternalPackageState -> EpsStats
    eps_stats ExternalPackageState
    eps
        msg :: SDoc
    msg = [SDoc] -> SDoc
    vcat
            [Int -> SDoc
    int (EpsStats -> Int
    n_ifaces_in EpsStats
    stats) SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "interfaces read",
             [SDoc] -> SDoc
    hsep [ Int -> SDoc
    int (EpsStats -> Int
    n_decls_out EpsStats
    stats), String -> SDoc
    text String
    "type/class/variable imported, out of",
                    Int -> SDoc
    int (EpsStats -> Int
    n_decls_in EpsStats
    stats), String -> SDoc
    text String
    "read"],
             [SDoc] -> SDoc
    hsep [ Int -> SDoc
    int (EpsStats -> Int
    n_insts_out EpsStats
    stats), String -> SDoc
    text String
    "instance decls imported, out of",
                    Int -> SDoc
    int (EpsStats -> Int
    n_insts_in EpsStats
    stats), String -> SDoc
    text String
    "read"],
             [SDoc] -> SDoc
    hsep [ Int -> SDoc
    int (EpsStats -> Int
    n_rules_out EpsStats
    stats), String -> SDoc
    text String
    "rule decls imported, out of",
                    Int -> SDoc
    int (EpsStats -> Int
    n_rules_in EpsStats
    stats), String -> SDoc
    text String
    "read"]
            ]

    {-
    ************************************************************************
    *                                                                      *
                    Printing interfaces
    *                                                                      *
    ************************************************************************

    Note [Name qualification with --show-iface]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In order to disambiguate between identifiers from different modules, we qualify
    all names that don't originate in the current module. In order to keep visual
    noise as low as possible, we keep local names unqualified.

    For some background on this choice see trac #15269.
    -}

    -- | Read binary interface, and print it out
    showIface :: HscEnv -> FilePath -> IO ()
    showIface :: HscEnv -> String -> IO ()
    showIface HscEnv
    hsc_env String
    filename = do
       let dflags :: DynFlags
    dflags  = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
       let logger :: Logger
    logger  = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env
           unit_state :: UnitState
    unit_state = HscEnv -> UnitState
    hsc_units HscEnv
    hsc_env
           printer :: SDoc -> IO ()
    printer = Logger -> LogAction
    putLogMsg Logger
    logger DynFlags
    dflags WarnReason
    NoReason Severity
    SevOutput SrcSpan
    noSrcSpan forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PprStyle -> SDoc -> SDoc
    withPprStyle PprStyle
    defaultDumpStyle

       -- skip the hi way check; we don't want to worry about profiled vs.
       -- non-profiled interfaces, for example.
       ModIface
    iface <- forall gbl lcl a.
    Char -> HscEnv -> gbl -> lcl -> TcRnIf gbl lcl a -> IO a
    initTcRnIf Char
    's' HscEnv
    hsc_env () () forall a b. (a -> b) -> a -> b
    $
           forall a b.
    CheckHiWay -> TraceBinIFace -> String -> TcRnIf a b ModIface
    readBinIface CheckHiWay
    IgnoreHiWay ((SDoc -> IO ()) -> TraceBinIFace
    TraceBinIFace SDoc -> IO ()
    printer) String
    filename

       let -- See Note [Name qualification with --show-iface]
           qualifyImportedNames :: GenModule Unit -> OccName -> QualifyName
    qualifyImportedNames GenModule Unit
    mod OccName
    _
               | GenModule Unit
    mod forall a. Eq a => a -> a -> Bool
    == forall (phase :: ModIfacePhase). ModIface_ phase -> GenModule Unit
    mi_module ModIface
    iface = QualifyName
    NameUnqual
               | Bool
    otherwise              = QualifyName
    NameNotInScope1
           print_unqual :: PrintUnqualified
    print_unqual = (GenModule Unit -> OccName -> QualifyName)
    -> (GenModule Unit -> Bool)
    -> QueryQualifyPackage
    -> PrintUnqualified
    QueryQualify GenModule Unit -> OccName -> QualifyName
    qualifyImportedNames
                                       GenModule Unit -> Bool
    neverQualifyModules
                                       QueryQualifyPackage
    neverQualifyPackages
       Logger -> LogAction
    putLogMsg Logger
    logger DynFlags
    dflags WarnReason
    NoReason Severity
    SevDump SrcSpan
    noSrcSpan
          forall a b. (a -> b) -> a -> b
    $ PprStyle -> SDoc -> SDoc
    withPprStyle (PrintUnqualified -> PprStyle
    mkDumpStyle PrintUnqualified
    print_unqual)
          forall a b. (a -> b) -> a -> b
    $ UnitState -> ModIface -> SDoc
    pprModIface UnitState
    unit_state ModIface
    iface

    -- | Show a ModIface but don't display details; suitable for ModIfaces stored in
    -- the EPT.
    pprModIfaceSimple :: UnitState -> ModIface -> SDoc
    pprModIfaceSimple :: UnitState -> ModIface -> SDoc
    pprModIfaceSimple UnitState
    unit_state ModIface
    iface =
        forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase). ModIface_ phase -> GenModule Unit
    mi_module ModIface
    iface)
        SDoc -> SDoc -> SDoc
    $$ UnitState -> Dependencies -> SDoc
    pprDeps UnitState
    unit_state (forall (phase :: ModIfacePhase). ModIface_ phase -> Dependencies
    mi_deps ModIface
    iface)
        SDoc -> SDoc -> SDoc
    $$ Int -> SDoc -> SDoc
    nest Int
    2 ([SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map IfaceExport -> SDoc
    pprExport (forall (phase :: ModIfacePhase). ModIface_ phase -> [IfaceExport]
    mi_exports ModIface
    iface)))

    -- | Show a ModIface
    --
    -- The UnitState is used to pretty-print units
    pprModIface :: UnitState -> ModIface -> SDoc
    pprModIface :: UnitState -> ModIface -> SDoc
    pprModIface UnitState
    unit_state iface :: ModIface
    iface@ModIface{ mi_final_exts :: forall (phase :: ModIfacePhase).
    ModIface_ phase -> IfaceBackendExts phase
    mi_final_exts = IfaceBackendExts 'ModIfaceFinal
    exts }
     = [SDoc] -> SDoc
    vcat [ String -> SDoc
    text String
    "interface"
                    SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase). ModIface_ phase -> GenModule Unit
    mi_module ModIface
    iface) SDoc -> SDoc -> SDoc
    <+> HscSource -> SDoc
    pp_hsc_src (forall (phase :: ModIfacePhase). ModIface_ phase -> HscSource
    mi_hsc_src ModIface
    iface)
                    SDoc -> SDoc -> SDoc
    <+> (if ModIfaceBackend -> Bool
    mi_orphan IfaceBackendExts 'ModIfaceFinal
    exts then String -> SDoc
    text String
    "[orphan module]" else SDoc
    Outputable.empty)
                    SDoc -> SDoc -> SDoc
    <+> (if ModIfaceBackend -> Bool
    mi_finsts IfaceBackendExts 'ModIfaceFinal
    exts then String -> SDoc
    text String
    "[family instance module]" else SDoc
    Outputable.empty)
                    SDoc -> SDoc -> SDoc
    <+> (if forall (phase :: ModIfacePhase). ModIface_ phase -> Bool
    mi_hpc ModIface
    iface then String -> SDoc
    text String
    "[hpc]" else SDoc
    Outputable.empty)
                    SDoc -> SDoc -> SDoc
    <+> Integer -> SDoc
    integer Integer
    hiVersion
            , Int -> SDoc -> SDoc
    nest Int
    2 (String -> SDoc
    text String
    "interface hash:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (ModIfaceBackend -> Fingerprint
    mi_iface_hash IfaceBackendExts 'ModIfaceFinal
    exts))
            , Int -> SDoc -> SDoc
    nest Int
    2 (String -> SDoc
    text String
    "ABI hash:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (ModIfaceBackend -> Fingerprint
    mi_mod_hash IfaceBackendExts 'ModIfaceFinal
    exts))
            , Int -> SDoc -> SDoc
    nest Int
    2 (String -> SDoc
    text String
    "export-list hash:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (ModIfaceBackend -> Fingerprint
    mi_exp_hash IfaceBackendExts 'ModIfaceFinal
    exts))
            , Int -> SDoc -> SDoc
    nest Int
    2 (String -> SDoc
    text String
    "orphan hash:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (ModIfaceBackend -> Fingerprint
    mi_orphan_hash IfaceBackendExts 'ModIfaceFinal
    exts))
            , Int -> SDoc -> SDoc
    nest Int
    2 (String -> SDoc
    text String
    "flag hash:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (ModIfaceBackend -> Fingerprint
    mi_flag_hash IfaceBackendExts 'ModIfaceFinal
    exts))
            , Int -> SDoc -> SDoc
    nest Int
    2 (String -> SDoc
    text String
    "opt_hash:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (ModIfaceBackend -> Fingerprint
    mi_opt_hash IfaceBackendExts 'ModIfaceFinal
    exts))
            , Int -> SDoc -> SDoc
    nest Int
    2 (String -> SDoc
    text String
    "hpc_hash:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (ModIfaceBackend -> Fingerprint
    mi_hpc_hash IfaceBackendExts 'ModIfaceFinal
    exts))
            , Int -> SDoc -> SDoc
    nest Int
    2 (String -> SDoc
    text String
    "plugin_hash:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (ModIfaceBackend -> Fingerprint
    mi_plugin_hash IfaceBackendExts 'ModIfaceFinal
    exts))
            , Int -> SDoc -> SDoc
    nest Int
    2 (String -> SDoc
    text String
    "sig of:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase).
    ModIface_ phase -> Maybe (GenModule Unit)
    mi_sig_of ModIface
    iface))
            , Int -> SDoc -> SDoc
    nest Int
    2 (String -> SDoc
    text String
    "used TH splices:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase). ModIface_ phase -> Bool
    mi_used_th ModIface
    iface))
            , Int -> SDoc -> SDoc
    nest Int
    2 (String -> SDoc
    text String
    "where")
            , String -> SDoc
    text String
    "exports:"
            , Int -> SDoc -> SDoc
    nest Int
    2 ([SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map IfaceExport -> SDoc
    pprExport (forall (phase :: ModIfacePhase). ModIface_ phase -> [IfaceExport]
    mi_exports ModIface
    iface)))
            , UnitState -> Dependencies -> SDoc
    pprDeps UnitState
    unit_state (forall (phase :: ModIfacePhase). ModIface_ phase -> Dependencies
    mi_deps ModIface
    iface)
            , [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map Usage -> SDoc
    pprUsage (forall (phase :: ModIfacePhase). ModIface_ phase -> [Usage]
    mi_usages ModIface
    iface))
            , [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map IfaceAnnotation -> SDoc
    pprIfaceAnnotation (forall (phase :: ModIfacePhase).
    ModIface_ phase -> [IfaceAnnotation]
    mi_anns ModIface
    iface))
            , [(OccName, Fixity)] -> SDoc
    pprFixities (forall (phase :: ModIfacePhase).
    ModIface_ phase -> [(OccName, Fixity)]
    mi_fixities ModIface
    iface)
            , [SDoc] -> SDoc
    vcat [forall a. Outputable a => a -> SDoc
    ppr Fingerprint
    ver SDoc -> SDoc -> SDoc
    $$ Int -> SDoc -> SDoc
    nest Int
    2 (forall a. Outputable a => a -> SDoc
    ppr IfaceDecl
    decl) | (Fingerprint
    ver,IfaceDecl
    decl) <- forall (phase :: ModIfacePhase).
    ModIface_ phase -> [IfaceDeclExts phase]
    mi_decls ModIface
    iface]
            , [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase). ModIface_ phase -> [IfaceClsInst]
    mi_insts ModIface
    iface))
            , [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase). ModIface_ phase -> [IfaceFamInst]
    mi_fam_insts ModIface
    iface))
            , [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase). ModIface_ phase -> [IfaceRule]
    mi_rules ModIface
    iface))
            , forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase). ModIface_ phase -> Warnings
    mi_warns ModIface
    iface)
            , IfaceTrustInfo -> SDoc
    pprTrustInfo (forall (phase :: ModIfacePhase). ModIface_ phase -> IfaceTrustInfo
    mi_trust ModIface
    iface)
            , Bool -> SDoc
    pprTrustPkg (forall (phase :: ModIfacePhase). ModIface_ phase -> Bool
    mi_trust_pkg ModIface
    iface)
            , [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase).
    ModIface_ phase -> [IfaceCompleteMatch]
    mi_complete_matches ModIface
    iface))
            , String -> SDoc
    text String
    "module header:" SDoc -> SDoc -> SDoc
    $$ Int -> SDoc -> SDoc
    nest Int
    2 (forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase).
    ModIface_ phase -> Maybe HsDocString
    mi_doc_hdr ModIface
    iface))
            , String -> SDoc
    text String
    "declaration docs:" SDoc -> SDoc -> SDoc
    $$ Int -> SDoc -> SDoc
    nest Int
    2 (forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase). ModIface_ phase -> DeclDocMap
    mi_decl_docs ModIface
    iface))
            , String -> SDoc
    text String
    "arg docs:" SDoc -> SDoc -> SDoc
    $$ Int -> SDoc -> SDoc
    nest Int
    2 (forall a. Outputable a => a -> SDoc
    ppr (forall (phase :: ModIfacePhase). ModIface_ phase -> ArgDocMap
    mi_arg_docs ModIface
    iface))
            , String -> SDoc
    text String
    "extensible fields:" SDoc -> SDoc -> SDoc
    $$ Int -> SDoc -> SDoc
    nest Int
    2 (ExtensibleFields -> SDoc
    pprExtensibleFields (forall (phase :: ModIfacePhase).
    ModIface_ phase -> ExtensibleFields
    mi_ext_fields ModIface
    iface))
            ]
      where
        pp_hsc_src :: HscSource -> SDoc
    pp_hsc_src HscSource
    HsBootFile = String -> SDoc
    text String
    "[boot]"
        pp_hsc_src HscSource
    HsigFile = String -> SDoc
    text String
    "[hsig]"
        pp_hsc_src HscSource
    HsSrcFile = SDoc
    Outputable.empty

    {-
    When printing export lists, we print like this:
            Avail   f               f
            AvailTC C [C, x, y]     C(x,y)
            AvailTC C [x, y]        C!(x,y)         -- Exporting x, y but not C
    -}

    pprExport :: IfaceExport -> SDoc
    pprExport :: IfaceExport -> SDoc
    pprExport (Avail GreName
    n)      = forall a. Outputable a => a -> SDoc
    ppr GreName
    n
    pprExport (AvailTC Name
    _ []) = SDoc
    Outputable.empty
    pprExport avail :: IfaceExport
    avail@(AvailTC Name
    n [GreName]
    _) =
        forall a. Outputable a => a -> SDoc
    ppr Name
    n SDoc -> SDoc -> SDoc
    <> SDoc
    mark SDoc -> SDoc -> SDoc
    <> forall {a}. Outputable a => [a] -> SDoc
    pp_export (IfaceExport -> [GreName]
    availSubordinateGreNames IfaceExport
    avail)
      where
        mark :: SDoc
    mark | IfaceExport -> Bool
    availExportsDecl IfaceExport
    avail = SDoc
    Outputable.empty
             | Bool
    otherwise              = SDoc
    vbar

        pp_export :: [a] -> SDoc
    pp_export []    = SDoc
    Outputable.empty
        pp_export [a]
    names = SDoc -> SDoc
    braces ([SDoc] -> SDoc
    hsep (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    ppr [a]
    names))

    pprUsage :: Usage -> SDoc
    pprUsage :: Usage -> SDoc
    pprUsage usage :: Usage
    usage@UsagePackageModule{}
      = forall a. Outputable a => Usage -> (Usage -> a) -> SDoc
    pprUsageImport Usage
    usage Usage -> GenModule Unit
    usg_mod
    pprUsage usage :: Usage
    usage@UsageHomeModule{}
      = forall a. Outputable a => Usage -> (Usage -> a) -> SDoc
    pprUsageImport Usage
    usage Usage -> ModuleName
    usg_mod_name SDoc -> SDoc -> SDoc
    $$
        Int -> SDoc -> SDoc
    nest Int
    2 (
            forall b a. b -> (a -> b) -> Maybe a -> b
    maybe SDoc
    Outputable.empty (\Fingerprint
    v -> String -> SDoc
    text String
    "exports: " SDoc -> SDoc -> SDoc
    <> forall a. Outputable a => a -> SDoc
    ppr Fingerprint
    v) (Usage -> Maybe Fingerprint
    usg_exports Usage
    usage) SDoc -> SDoc -> SDoc
    $$
            [SDoc] -> SDoc
    vcat [ forall a. Outputable a => a -> SDoc
    ppr OccName
    n SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr Fingerprint
    v | (OccName
    n,Fingerprint
    v) <- Usage -> [(OccName, Fingerprint)]
    usg_entities Usage
    usage ]
            )
    pprUsage usage :: Usage
    usage@UsageFile{}
      = [SDoc] -> SDoc
    hsep [String -> SDoc
    text String
    "addDependentFile",
              SDoc -> SDoc
    doubleQuotes (String -> SDoc
    text (Usage -> String
    usg_file_path Usage
    usage)),
              forall a. Outputable a => a -> SDoc
    ppr (Usage -> Fingerprint
    usg_file_hash Usage
    usage)]
    pprUsage usage :: Usage
    usage@UsageMergedRequirement{}
      = [SDoc] -> SDoc
    hsep [String -> SDoc
    text String
    "merged", forall a. Outputable a => a -> SDoc
    ppr (Usage -> GenModule Unit
    usg_mod Usage
    usage), forall a. Outputable a => a -> SDoc
    ppr (Usage -> Fingerprint
    usg_mod_hash Usage
    usage)]

    pprUsageImport :: Outputable a => Usage -> (Usage -> a) -> SDoc
    pprUsageImport :: forall a. Outputable a => Usage -> (Usage -> a) -> SDoc
    pprUsageImport Usage
    usage Usage -> a
    usg_mod'
      = [SDoc] -> SDoc
    hsep [String -> SDoc
    text String
    "import", SDoc
    safe, forall a. Outputable a => a -> SDoc
    ppr (Usage -> a
    usg_mod' Usage
    usage),
                           forall a. Outputable a => a -> SDoc
    ppr (Usage -> Fingerprint
    usg_mod_hash Usage
    usage)]
        where
            safe :: SDoc
    safe | Usage -> Bool
    usg_safe Usage
    usage = String -> SDoc
    text String
    "safe"
                 | Bool
    otherwise      = String -> SDoc
    text String
    " -/ "

    -- | Pretty-print unit dependencies
    pprDeps :: UnitState -> Dependencies -> SDoc
    pprDeps :: UnitState -> Dependencies -> SDoc
    pprDeps UnitState
    unit_state (Deps { dep_mods :: Dependencies -> [ModuleNameWithIsBoot]
    dep_mods = [ModuleNameWithIsBoot]
    mods, dep_pkgs :: Dependencies -> [(UnitId, Bool)]
    dep_pkgs = [(UnitId, Bool)]
    pkgs, dep_orphs :: Dependencies -> [GenModule Unit]
    dep_orphs = [GenModule Unit]
    orphs,
                               dep_finsts :: Dependencies -> [GenModule Unit]
    dep_finsts = [GenModule Unit]
    finsts })
      = UnitState -> SDoc -> SDoc
    pprWithUnitState UnitState
    unit_state forall a b. (a -> b) -> a -> b
    $
        [SDoc] -> SDoc
    vcat [String -> SDoc
    text String
    "module dependencies:" SDoc -> SDoc -> SDoc
    <+> [SDoc] -> SDoc
    fsep (forall a b. (a -> b) -> [a] -> [b]
    map forall {a}. Outputable a => GenWithIsBoot a -> SDoc
    ppr_mod [ModuleNameWithIsBoot]
    mods),
              String -> SDoc
    text String
    "package dependencies:" SDoc -> SDoc -> SDoc
    <+> [SDoc] -> SDoc
    fsep (forall a b. (a -> b) -> [a] -> [b]
    map forall {a}. Outputable a => (a, Bool) -> SDoc
    ppr_pkg [(UnitId, Bool)]
    pkgs),
              String -> SDoc
    text String
    "orphans:" SDoc -> SDoc -> SDoc
    <+> [SDoc] -> SDoc
    fsep (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    ppr [GenModule Unit]
    orphs),
              String -> SDoc
    text String
    "family instance modules:" SDoc -> SDoc -> SDoc
    <+> [SDoc] -> SDoc
    fsep (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    ppr [GenModule Unit]
    finsts)
            ]
      where
        ppr_mod :: GenWithIsBoot a -> SDoc
    ppr_mod (GWIB { gwib_mod :: forall mod. GenWithIsBoot mod -> mod
    gwib_mod = a
    mod_name, gwib_isBoot :: forall mod. GenWithIsBoot mod -> IsBootInterface
    gwib_isBoot = IsBootInterface
    boot }) = forall a. Outputable a => a -> SDoc
    ppr a
    mod_name SDoc -> SDoc -> SDoc
    <+> IsBootInterface -> SDoc
    ppr_boot IsBootInterface
    boot
        ppr_pkg :: (a, Bool) -> SDoc
    ppr_pkg (a
    pkg,Bool
    trust_req)  = forall a. Outputable a => a -> SDoc
    ppr a
    pkg SDoc -> SDoc -> SDoc
    <>
                                   (if Bool
    trust_req then String -> SDoc
    text String
    "*" else SDoc
    Outputable.empty)
        ppr_boot :: IsBootInterface -> SDoc
    ppr_boot IsBootInterface
    IsBoot  = String -> SDoc
    text String
    "[boot]"
        ppr_boot IsBootInterface
    NotBoot = SDoc
    Outputable.empty

    pprFixities :: [(OccName, Fixity)] -> SDoc
    pprFixities :: [(OccName, Fixity)] -> SDoc
    pprFixities []    = SDoc
    Outputable.empty
    pprFixities [(OccName, Fixity)]
    fixes = String -> SDoc
    text String
    "fixities" SDoc -> SDoc -> SDoc
    <+> forall a. (a -> SDoc) -> [a] -> SDoc
    pprWithCommas forall {a} {a}. (Outputable a, Outputable a) => (a, a) -> SDoc
    pprFix [(OccName, Fixity)]
    fixes
                      where
                        pprFix :: (a, a) -> SDoc
    pprFix (a
    occ,a
    fix) = forall a. Outputable a => a -> SDoc
    ppr a
    fix SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr a
    occ

    pprTrustInfo :: IfaceTrustInfo -> SDoc
    pprTrustInfo :: IfaceTrustInfo -> SDoc
    pprTrustInfo IfaceTrustInfo
    trust = String -> SDoc
    text String
    "trusted:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr IfaceTrustInfo
    trust

    pprTrustPkg :: Bool -> SDoc
    pprTrustPkg :: Bool -> SDoc
    pprTrustPkg Bool
    tpkg = String -> SDoc
    text String
    "require own pkg trusted:" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr Bool
    tpkg

    instance Outputable Warnings where
        ppr :: Warnings -> SDoc
    ppr = Warnings -> SDoc
    pprWarns

    pprWarns :: Warnings -> SDoc
    pprWarns :: Warnings -> SDoc
    pprWarns Warnings
    NoWarnings         = SDoc
    Outputable.empty
    pprWarns (WarnAll WarningTxt
    txt)  = String -> SDoc
    text String
    "Warn all" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr WarningTxt
    txt
    pprWarns (WarnSome [(OccName, WarningTxt)]
    prs) = String -> SDoc
    text String
    "Warnings"
                            SDoc -> SDoc -> SDoc
    <+> [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map forall {a} {a}. (Outputable a, Outputable a) => (a, a) -> SDoc
    pprWarning [(OccName, WarningTxt)]
    prs)
        where pprWarning :: (a, a) -> SDoc
    pprWarning (a
    name, a
    txt) = forall a. Outputable a => a -> SDoc
    ppr a
    name SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr a
    txt

    pprIfaceAnnotation :: IfaceAnnotation -> SDoc
    pprIfaceAnnotation :: IfaceAnnotation -> SDoc
    pprIfaceAnnotation (IfaceAnnotation { ifAnnotatedTarget :: IfaceAnnotation -> IfaceAnnTarget
    ifAnnotatedTarget = IfaceAnnTarget
    target, ifAnnotatedValue :: IfaceAnnotation -> AnnPayload
    ifAnnotatedValue = AnnPayload
    serialized })
      = forall a. Outputable a => a -> SDoc
    ppr IfaceAnnTarget
    target SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "annotated by" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr AnnPayload
    serialized

    pprExtensibleFields :: ExtensibleFields -> SDoc
    pprExtensibleFields :: ExtensibleFields -> SDoc
    pprExtensibleFields (ExtensibleFields Map String BinData
    fs) = [SDoc] -> SDoc
    vcat forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a b. (a -> b) -> [a] -> [b]
    map (String, BinData) -> SDoc
    pprField forall a b. (a -> b) -> a -> b
    $ forall k a. Map k a -> [(k, a)]
    toList Map String BinData
    fs
      where
        pprField :: (String, BinData) -> SDoc
    pprField (String
    name, (BinData Int
    size BinArray
    _data)) = String -> SDoc
    text String
    name SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "-" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr Int
    size SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "bytes"

    {-
    *********************************************************
    *                                                       *
    \subsection{Errors}
    *                                                       *
    *********************************************************
    -}

    badIfaceFile :: String -> SDoc -> SDoc
    badIfaceFile :: String -> SDoc -> SDoc
    badIfaceFile String
    file SDoc
    err
      = [SDoc] -> SDoc
    vcat [String -> SDoc
    text String
    "Bad interface file:" SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    file,
              Int -> SDoc -> SDoc
    nest Int
    4 SDoc
    err]

    hiModuleNameMismatchWarn :: Module -> Module -> SDoc
    hiModuleNameMismatchWarn :: GenModule Unit -> GenModule Unit -> SDoc
    hiModuleNameMismatchWarn GenModule Unit
    requested_mod GenModule Unit
    read_mod
     | forall unit. GenModule unit -> unit
    moduleUnit GenModule Unit
    requested_mod forall a. Eq a => a -> a -> Bool
    == forall unit. GenModule unit -> unit
    moduleUnit GenModule Unit
    read_mod =
        [SDoc] -> SDoc
    sep [String -> SDoc
    text String
    "Interface file contains module" SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr GenModule Unit
    read_mod) SDoc -> SDoc -> SDoc
    <> SDoc
    comma,
             String -> SDoc
    text String
    "but we were expecting module" SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr GenModule Unit
    requested_mod),
             [SDoc] -> SDoc
    sep [String -> SDoc
    text String
    "Probable cause: the source code which generated interface file",
                 String -> SDoc
    text String
    "has an incompatible module name"
                ]
            ]
     | Bool
    otherwise =
      -- ToDo: This will fail to have enough qualification when the package IDs
      -- are the same
      PprStyle -> SDoc -> SDoc
    withPprStyle (PrintUnqualified -> Depth -> PprStyle
    mkUserStyle PrintUnqualified
    alwaysQualify Depth
    AllTheWay) forall a b. (a -> b) -> a -> b
    $
        -- we want the Modules below to be qualified with package names,
        -- so reset the PrintUnqualified setting.
        [SDoc] -> SDoc
    hsep [ String -> SDoc
    text String
    "Something is amiss; requested module "
             , forall a. Outputable a => a -> SDoc
    ppr GenModule Unit
    requested_mod
             , String -> SDoc
    text String
    "differs from name found in the interface file"
             , forall a. Outputable a => a -> SDoc
    ppr GenModule Unit
    read_mod
             , SDoc -> SDoc
    parens (String -> SDoc
    text String
    "if these names look the same, try again with -dppr-debug")
             ]

    homeModError :: InstalledModule -> ModLocation -> SDoc
    -- See Note [Home module load error]
    homeModError :: InstalledModule -> ModLocation -> SDoc
    homeModError InstalledModule
    mod ModLocation
    location
      = String -> SDoc
    text String
    "attempting to use module " SDoc -> SDoc -> SDoc
    <> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr InstalledModule
    mod)
        SDoc -> SDoc -> SDoc
    <> (case ModLocation -> Maybe String
    ml_hs_file ModLocation
    location of
               Just String
    file -> SDoc
    space SDoc -> SDoc -> SDoc
    <> SDoc -> SDoc
    parens (String -> SDoc
    text String
    file)
               Maybe String
    Nothing   -> SDoc
    Outputable.empty)
        SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "which is not loaded"

    -- -----------------------------------------------------------------------------
    -- Error messages

    cannotFindInterface :: UnitEnv -> Profile -> ([FilePath] -> SDoc) -> ModuleName -> InstalledFindResult -> SDoc
    cannotFindInterface :: UnitEnv
    -> Profile
    -> ([String] -> SDoc)
    -> ModuleName
    -> InstalledFindResult
    -> SDoc
    cannotFindInterface = PtrString
    -> PtrString
    -> UnitEnv
    -> Profile
    -> ([String] -> SDoc)
    -> ModuleName
    -> InstalledFindResult
    -> SDoc
    cantFindInstalledErr (String -> PtrString
    sLit String
    "Failed to load interface for")
                                               (String -> PtrString
    sLit String
    "Ambiguous interface for")

    cantFindInstalledErr
        :: PtrString
        -> PtrString
        -> UnitEnv
        -> Profile
        -> ([FilePath] -> SDoc)
        -> ModuleName
        -> InstalledFindResult
        -> SDoc
    cantFindInstalledErr :: PtrString
    -> PtrString
    -> UnitEnv
    -> Profile
    -> ([String] -> SDoc)
    -> ModuleName
    -> InstalledFindResult
    -> SDoc
    cantFindInstalledErr PtrString
    cannot_find PtrString
    _ UnitEnv
    unit_env Profile
    profile [String] -> SDoc
    tried_these ModuleName
    mod_name InstalledFindResult
    find_result
      = PtrString -> SDoc
    ptext PtrString
    cannot_find SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod_name)
        SDoc -> SDoc -> SDoc
    $$ SDoc
    more_info
      where
        home_unit :: HomeUnit
    home_unit  = UnitEnv -> HomeUnit
    ue_home_unit UnitEnv
    unit_env
        unit_state :: UnitState
    unit_state = UnitEnv -> UnitState
    ue_units UnitEnv
    unit_env
        build_tag :: String
    build_tag  = Ways -> String
    waysBuildTag (Profile -> Ways
    profileWays Profile
    profile)

        more_info :: SDoc
    more_info
          = case InstalledFindResult
    find_result of
                InstalledNoPackage UnitId
    pkg
                    -> String -> SDoc
    text String
    "no unit id matching" SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr UnitId
    pkg) SDoc -> SDoc -> SDoc
    <+>
                       String -> SDoc
    text String
    "was found" SDoc -> SDoc -> SDoc
    $$ UnitId -> SDoc
    looks_like_srcpkgid UnitId
    pkg

                InstalledNotFound [String]
    files Maybe UnitId
    mb_pkg
                    | Just UnitId
    pkg <- Maybe UnitId
    mb_pkg, Bool -> Bool
    not (forall u. GenHomeUnit u -> UnitId -> Bool
    isHomeUnitId HomeUnit
    home_unit UnitId
    pkg)
                    -> UnitId -> [String] -> SDoc
    not_found_in_package UnitId
    pkg [String]
    files

                    | forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [String]
    files
                    -> String -> SDoc
    text String
    "It is not a module in the current program, or in any known package."

                    | Bool
    otherwise
                    -> [String] -> SDoc
    tried_these [String]
    files

                InstalledFindResult
    _ -> forall a. String -> a
    panic String
    "cantFindInstalledErr"

        looks_like_srcpkgid :: UnitId -> SDoc
        looks_like_srcpkgid :: UnitId -> SDoc
    looks_like_srcpkgid UnitId
    pk
         -- Unsafely coerce a unit id (i.e. an installed package component
         -- identifier) into a PackageId and see if it means anything.
         | (UnitInfo
    pkg:[UnitInfo]
    pkgs) <- UnitState -> PackageId -> [UnitInfo]
    searchPackageId UnitState
    unit_state (FastString -> PackageId
    PackageId (UnitId -> FastString
    unitIdFS UnitId
    pk))
         = SDoc -> SDoc
    parens (String -> SDoc
    text String
    "This unit ID looks like the source package ID;" SDoc -> SDoc -> SDoc
    $$
           String -> SDoc
    text String
    "the real unit ID is" SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (FastString -> SDoc
    ftext (UnitId -> FastString
    unitIdFS (forall compid srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo compid srcpkgid srcpkgname uid modulename mod
    -> uid
    unitId UnitInfo
    pkg))) SDoc -> SDoc -> SDoc
    $$
           (if forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [UnitInfo]
    pkgs then SDoc
    Outputable.empty
            else String -> SDoc
    text String
    "and" SDoc -> SDoc -> SDoc
    <+> Int -> SDoc
    int (forall (t :: * -> *) a. Foldable t => t a -> Int
    length [UnitInfo]
    pkgs) SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "other candidates"))
         -- Todo: also check if it looks like a package name!
         | Bool
    otherwise = SDoc
    Outputable.empty

        not_found_in_package :: UnitId -> [String] -> SDoc
    not_found_in_package UnitId
    pkg [String]
    files
           | String
    build_tag forall a. Eq a => a -> a -> Bool
    /= String
    ""
           = let
                build :: String
    build = if String
    build_tag forall a. Eq a => a -> a -> Bool
    == String
    "p" then String
    "profiling"
                                            else String
    "\"" forall a. [a] -> [a] -> [a]
    ++ String
    build_tag forall a. [a] -> [a] -> [a]
    ++ String
    "\""
             in
             String -> SDoc
    text String
    "Perhaps you haven't installed the " SDoc -> SDoc -> SDoc
    <> String -> SDoc
    text String
    build SDoc -> SDoc -> SDoc
    <>
             String -> SDoc
    text String
    " libraries for package " SDoc -> SDoc -> SDoc
    <> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr UnitId
    pkg) SDoc -> SDoc -> SDoc
    <> Char -> SDoc
    char Char
    '?' SDoc -> SDoc -> SDoc
    $$
             [String] -> SDoc
    tried_these [String]
    files

           | Bool
    otherwise
           = String -> SDoc
    text String
    "There are files missing in the " SDoc -> SDoc -> SDoc
    <> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr UnitId
    pkg) SDoc -> SDoc -> SDoc
    <>
             String -> SDoc
    text String
    " package," SDoc -> SDoc -> SDoc
    $$
             String -> SDoc
    text String
    "try running 'ghc-pkg check'." SDoc -> SDoc -> SDoc
    $$
             [String] -> SDoc
    tried_these [String]
    files

    may_show_locations :: DynFlags -> [FilePath] -> SDoc
    may_show_locations :: DynFlags -> [String] -> SDoc
    may_show_locations DynFlags
    dflags [String]
    files
        | forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [String]
    files = SDoc
    Outputable.empty
        | DynFlags -> Int
    verbosity DynFlags
    dflags forall a. Ord a => a -> a -> Bool
    < Int
    3 =
              String -> SDoc
    text String
    "Use -v (or `:set -v` in ghci) " SDoc -> SDoc -> SDoc
    <>
                  String -> SDoc
    text String
    "to see a list of the files searched for."
        | Bool
    otherwise =
              SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    text String
    "Locations searched:") Int
    2 forall a b. (a -> b) -> a -> b
    $ [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map String -> SDoc
    text [String]
    files)

    cannotFindModule :: HscEnv -> ModuleName -> FindResult -> SDoc
    cannotFindModule :: HscEnv -> ModuleName -> FindResult -> SDoc
    cannotFindModule HscEnv
    hsc_env = DynFlags -> UnitEnv -> Profile -> ModuleName -> FindResult -> SDoc
    cannotFindModule'
        (HscEnv -> DynFlags
    hsc_dflags   HscEnv
    hsc_env)
        (HscEnv -> UnitEnv
    hsc_unit_env HscEnv
    hsc_env)
        (DynFlags -> Profile
    targetProfile (HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env))

    cannotFindModule' :: DynFlags -> UnitEnv -> Profile -> ModuleName -> FindResult -> SDoc
    cannotFindModule' :: DynFlags -> UnitEnv -> Profile -> ModuleName -> FindResult -> SDoc
    cannotFindModule' DynFlags
    dflags UnitEnv
    unit_env Profile
    profile ModuleName
    mod FindResult
    res = UnitState -> SDoc -> SDoc
    pprWithUnitState (UnitEnv -> UnitState
    ue_units UnitEnv
    unit_env) forall a b. (a -> b) -> a -> b
    $
      Bool
    -> PtrString
    -> PtrString
    -> UnitEnv
    -> Profile
    -> ([String] -> SDoc)
    -> ModuleName
    -> FindResult
    -> SDoc
    cantFindErr (GeneralFlag -> DynFlags -> Bool
    gopt GeneralFlag
    Opt_BuildingCabalPackage DynFlags
    dflags)
                  (String -> PtrString
    sLit String
    cannotFindMsg)
                  (String -> PtrString
    sLit String
    "Ambiguous module name")
                  UnitEnv
    unit_env
                  Profile
    profile
                  (DynFlags -> [String] -> SDoc
    may_show_locations DynFlags
    dflags)
                  ModuleName
    mod
                  FindResult
    res
      where
        cannotFindMsg :: String
    cannotFindMsg =
          case FindResult
    res of
            NotFound { fr_mods_hidden :: FindResult -> [Unit]
    fr_mods_hidden = [Unit]
    hidden_mods
                     , fr_pkgs_hidden :: FindResult -> [Unit]
    fr_pkgs_hidden = [Unit]
    hidden_pkgs
                     , fr_unusables :: FindResult -> [(Unit, UnusableUnitReason)]
    fr_unusables = [(Unit, UnusableUnitReason)]
    unusables }
              | Bool -> Bool
    not (forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Unit]
    hidden_mods Bool -> Bool -> Bool
    && forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Unit]
    hidden_pkgs Bool -> Bool -> Bool
    && forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [(Unit, UnusableUnitReason)]
    unusables)
              -> String
    "Could not load module"
            FindResult
    _ -> String
    "Could not find module"

    cantFindErr
        :: Bool -- ^ Using Cabal?
        -> PtrString
        -> PtrString
        -> UnitEnv
        -> Profile
        -> ([FilePath] -> SDoc)
        -> ModuleName
        -> FindResult
        -> SDoc
    cantFindErr :: Bool
    -> PtrString
    -> PtrString
    -> UnitEnv
    -> Profile
    -> ([String] -> SDoc)
    -> ModuleName
    -> FindResult
    -> SDoc
    cantFindErr Bool
    _ PtrString
    _ PtrString
    multiple_found UnitEnv
    _ Profile
    _ [String] -> SDoc
    _ ModuleName
    mod_name (FoundMultiple [(GenModule Unit, ModuleOrigin)]
    mods)
      | Just [Unit]
    pkgs <- Maybe [Unit]
    unambiguousPackages
      = SDoc -> Int -> SDoc -> SDoc
    hang (PtrString -> SDoc
    ptext PtrString
    multiple_found SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod_name) SDoc -> SDoc -> SDoc
    <> SDoc
    colon) Int
    2 (
           [SDoc] -> SDoc
    sep [String -> SDoc
    text String
    "it was found in multiple packages:",
                    [SDoc] -> SDoc
    hsep (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    ppr [Unit]
    pkgs) ]
        )
      | Bool
    otherwise
      = SDoc -> Int -> SDoc -> SDoc
    hang (PtrString -> SDoc
    ptext PtrString
    multiple_found SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod_name) SDoc -> SDoc -> SDoc
    <> SDoc
    colon) Int
    2 (
           [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map forall {a}.
    (Outputable a, Outputable (GenModule a)) =>
    (GenModule a, ModuleOrigin) -> SDoc
    pprMod [(GenModule Unit, ModuleOrigin)]
    mods)
        )
      where
        unambiguousPackages :: Maybe [Unit]
    unambiguousPackages = forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' forall {a}. Maybe [a] -> (GenModule a, ModuleOrigin) -> Maybe [a]
    unambiguousPackage (forall a. a -> Maybe a
    Just []) [(GenModule Unit, ModuleOrigin)]
    mods
        unambiguousPackage :: Maybe [a] -> (GenModule a, ModuleOrigin) -> Maybe [a]
    unambiguousPackage (Just [a]
    xs) (GenModule a
    m, ModOrigin (Just Bool
    _) [UnitInfo]
    _ [UnitInfo]
    _ Bool
    _)
            = forall a. a -> Maybe a
    Just (forall unit. GenModule unit -> unit
    moduleUnit GenModule a
    m forall a. a -> [a] -> [a]
    : [a]
    xs)
        unambiguousPackage Maybe [a]
    _ (GenModule a, ModuleOrigin)
    _ = forall a. Maybe a
    Nothing

        pprMod :: (GenModule a, ModuleOrigin) -> SDoc
    pprMod (GenModule a
    m, ModuleOrigin
    o) = String -> SDoc
    text String
    "it is bound as" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr GenModule a
    m SDoc -> SDoc -> SDoc
    <+>
                                    String -> SDoc
    text String
    "by" SDoc -> SDoc -> SDoc
    <+> forall {a}. Outputable a => GenModule a -> ModuleOrigin -> SDoc
    pprOrigin GenModule a
    m ModuleOrigin
    o
        pprOrigin :: GenModule a -> ModuleOrigin -> SDoc
    pprOrigin GenModule a
    _ ModuleOrigin
    ModHidden = forall a. String -> a
    panic String
    "cantFindErr: bound by mod hidden"
        pprOrigin GenModule a
    _ (ModUnusable UnusableUnitReason
    _) = forall a. String -> a
    panic String
    "cantFindErr: bound by mod unusable"
        pprOrigin GenModule a
    m (ModOrigin Maybe Bool
    e [UnitInfo]
    res [UnitInfo]
    _ Bool
    f) = [SDoc] -> SDoc
    sep forall a b. (a -> b) -> a -> b
    $ SDoc -> [SDoc] -> [SDoc]
    punctuate SDoc
    comma (
          if Maybe Bool
    e forall a. Eq a => a -> a -> Bool
    == forall a. a -> Maybe a
    Just Bool
    True
              then [String -> SDoc
    text String
    "package" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (forall unit. GenModule unit -> unit
    moduleUnit GenModule a
    m)]
              else [] forall a. [a] -> [a] -> [a]
    ++
          forall a b. (a -> b) -> [a] -> [b]
    map ((String -> SDoc
    text String
    "a reexport in package" SDoc -> SDoc -> SDoc
    <+>)
                    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .forall a. Outputable a => a -> SDoc
    pprforall b c a. (b -> c) -> (a -> b) -> a -> c
    .UnitInfo -> Unit
    mkUnit) [UnitInfo]
    res forall a. [a] -> [a] -> [a]
    ++
          if Bool
    f then [String -> SDoc
    text String
    "a package flag"] else []
          )

    cantFindErr Bool
    using_cabal PtrString
    cannot_find PtrString
    _ UnitEnv
    unit_env Profile
    profile [String] -> SDoc
    tried_these ModuleName
    mod_name FindResult
    find_result
      = PtrString -> SDoc
    ptext PtrString
    cannot_find SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod_name)
        SDoc -> SDoc -> SDoc
    $$ SDoc
    more_info
      where
        home_unit :: HomeUnit
    home_unit  = UnitEnv -> HomeUnit
    ue_home_unit UnitEnv
    unit_env
        more_info :: SDoc
    more_info
          = case FindResult
    find_result of
                NoPackage Unit
    pkg
                    -> String -> SDoc
    text String
    "no unit id matching" SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr Unit
    pkg) SDoc -> SDoc -> SDoc
    <+>
                       String -> SDoc
    text String
    "was found"

                NotFound { fr_paths :: FindResult -> [String]
    fr_paths = [String]
    files, fr_pkg :: FindResult -> Maybe Unit
    fr_pkg = Maybe Unit
    mb_pkg
                         , fr_mods_hidden :: FindResult -> [Unit]
    fr_mods_hidden = [Unit]
    mod_hiddens, fr_pkgs_hidden :: FindResult -> [Unit]
    fr_pkgs_hidden = [Unit]
    pkg_hiddens
                         , fr_unusables :: FindResult -> [(Unit, UnusableUnitReason)]
    fr_unusables = [(Unit, UnusableUnitReason)]
    unusables, fr_suggestions :: FindResult -> [ModuleSuggestion]
    fr_suggestions = [ModuleSuggestion]
    suggest }
                    | Just Unit
    pkg <- Maybe Unit
    mb_pkg, Bool -> Bool
    not (HomeUnit -> QueryQualifyPackage
    isHomeUnit HomeUnit
    home_unit Unit
    pkg)
                    -> Unit -> [String] -> SDoc
    not_found_in_package Unit
    pkg [String]
    files

                    | Bool -> Bool
    not (forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [ModuleSuggestion]
    suggest)
                    -> [ModuleSuggestion] -> SDoc
    pp_suggestions [ModuleSuggestion]
    suggest SDoc -> SDoc -> SDoc
    $$ [String] -> SDoc
    tried_these [String]
    files

                    | forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [String]
    files Bool -> Bool -> Bool
    && forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Unit]
    mod_hiddens Bool -> Bool -> Bool
    &&
                      forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Unit]
    pkg_hiddens Bool -> Bool -> Bool
    && forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [(Unit, UnusableUnitReason)]
    unusables
                    -> String -> SDoc
    text String
    "It is not a module in the current program, or in any known package."

                    | Bool
    otherwise
                    -> [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map Unit -> SDoc
    pkg_hidden [Unit]
    pkg_hiddens) SDoc -> SDoc -> SDoc
    $$
                       [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    mod_hidden [Unit]
    mod_hiddens) SDoc -> SDoc -> SDoc
    $$
                       [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map forall {a}. Outputable a => (a, UnusableUnitReason) -> SDoc
    unusable [(Unit, UnusableUnitReason)]
    unusables) SDoc -> SDoc -> SDoc
    $$
                       [String] -> SDoc
    tried_these [String]
    files

                FindResult
    _ -> forall a. String -> a
    panic String
    "cantFindErr"

        build_tag :: String
    build_tag = Ways -> String
    waysBuildTag (Profile -> Ways
    profileWays Profile
    profile)

        not_found_in_package :: Unit -> [String] -> SDoc
    not_found_in_package Unit
    pkg [String]
    files
           | String
    build_tag forall a. Eq a => a -> a -> Bool
    /= String
    ""
           = let
                build :: String
    build = if String
    build_tag forall a. Eq a => a -> a -> Bool
    == String
    "p" then String
    "profiling"
                                            else String
    "\"" forall a. [a] -> [a] -> [a]
    ++ String
    build_tag forall a. [a] -> [a] -> [a]
    ++ String
    "\""
             in
             String -> SDoc
    text String
    "Perhaps you haven't installed the " SDoc -> SDoc -> SDoc
    <> String -> SDoc
    text String
    build SDoc -> SDoc -> SDoc
    <>
             String -> SDoc
    text String
    " libraries for package " SDoc -> SDoc -> SDoc
    <> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr Unit
    pkg) SDoc -> SDoc -> SDoc
    <> Char -> SDoc
    char Char
    '?' SDoc -> SDoc -> SDoc
    $$
             [String] -> SDoc
    tried_these [String]
    files

           | Bool
    otherwise
           = String -> SDoc
    text String
    "There are files missing in the " SDoc -> SDoc -> SDoc
    <> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr Unit
    pkg) SDoc -> SDoc -> SDoc
    <>
             String -> SDoc
    text String
    " package," SDoc -> SDoc -> SDoc
    $$
             String -> SDoc
    text String
    "try running 'ghc-pkg check'." SDoc -> SDoc -> SDoc
    $$
             [String] -> SDoc
    tried_these [String]
    files

        pkg_hidden :: Unit -> SDoc
        pkg_hidden :: Unit -> SDoc
    pkg_hidden Unit
    uid =
            String -> SDoc
    text String
    "It is a member of the hidden package"
            SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr Unit
    uid)
            --FIXME: we don't really want to show the unit id here we should
            -- show the source package id or installed package id if it's ambiguous
            SDoc -> SDoc -> SDoc
    <> SDoc
    dot SDoc -> SDoc -> SDoc
    $$ Unit -> SDoc
    pkg_hidden_hint Unit
    uid

        pkg_hidden_hint :: Unit -> SDoc
    pkg_hidden_hint Unit
    uid
         | Bool
    using_cabal
            = let pkg :: UnitInfo
    pkg = forall a. HasCallStack => String -> Maybe a -> a
    expectJust String
    "pkg_hidden" (UnitState -> Unit -> Maybe UnitInfo
    lookupUnit (UnitEnv -> UnitState
    ue_units UnitEnv
    unit_env) Unit
    uid)
               in String -> SDoc
    text String
    "Perhaps you need to add" SDoc -> SDoc -> SDoc
    <+>
                  SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr (forall compid srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo compid srcpkgid srcpkgname uid modulename mod
    -> srcpkgname
    unitPackageName UnitInfo
    pkg)) SDoc -> SDoc -> SDoc
    <+>
                  String -> SDoc
    text String
    "to the build-depends in your .cabal file."
         | Just UnitInfo
    pkg <- UnitState -> Unit -> Maybe UnitInfo
    lookupUnit (UnitEnv -> UnitState
    ue_units UnitEnv
    unit_env) Unit
    uid
             = String -> SDoc
    text String
    "You can run" SDoc -> SDoc -> SDoc
    <+>
               SDoc -> SDoc
    quotes (String -> SDoc
    text String
    ":set -package " SDoc -> SDoc -> SDoc
    <> forall a. Outputable a => a -> SDoc
    ppr (forall compid srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo compid srcpkgid srcpkgname uid modulename mod
    -> srcpkgname
    unitPackageName UnitInfo
    pkg)) SDoc -> SDoc -> SDoc
    <+>
               String -> SDoc
    text String
    "to expose it." SDoc -> SDoc -> SDoc
    $$
               String -> SDoc
    text String
    "(Note: this unloads all the modules in the current scope.)"
         | Bool
    otherwise = SDoc
    Outputable.empty

        mod_hidden :: a -> SDoc
    mod_hidden a
    pkg =
            String -> SDoc
    text String
    "it is a hidden module in the package" SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr a
    pkg)

        unusable :: (a, UnusableUnitReason) -> SDoc
    unusable (a
    pkg, UnusableUnitReason
    reason)
          = String -> SDoc
    text String
    "It is a member of the package"
          SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr a
    pkg)
          SDoc -> SDoc -> SDoc
    $$ SDoc -> UnusableUnitReason -> SDoc
    pprReason (String -> SDoc
    text String
    "which is") UnusableUnitReason
    reason

        pp_suggestions :: [ModuleSuggestion] -> SDoc
        pp_suggestions :: [ModuleSuggestion] -> SDoc
    pp_suggestions [ModuleSuggestion]
    sugs
          | forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [ModuleSuggestion]
    sugs = SDoc
    Outputable.empty
          | Bool
    otherwise = SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    text String
    "Perhaps you meant")
                           Int
    2 ([SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map ModuleSuggestion -> SDoc
    pp_sugg [ModuleSuggestion]
    sugs))

        -- NB: Prefer the *original* location, and then reexports, and then
        -- package flags when making suggestions.  ToDo: if the original package
        -- also has a reexport, prefer that one
        pp_sugg :: ModuleSuggestion -> SDoc
    pp_sugg (SuggestVisible ModuleName
    m GenModule Unit
    mod ModuleOrigin
    o) = forall a. Outputable a => a -> SDoc
    ppr ModuleName
    m SDoc -> SDoc -> SDoc
    <+> ModuleOrigin -> SDoc
    provenance ModuleOrigin
    o
          where provenance :: ModuleOrigin -> SDoc
    provenance ModuleOrigin
    ModHidden = SDoc
    Outputable.empty
                provenance (ModUnusable UnusableUnitReason
    _) = SDoc
    Outputable.empty
                provenance (ModOrigin{ fromOrigUnit :: ModuleOrigin -> Maybe Bool
    fromOrigUnit = Maybe Bool
    e,
                                       fromExposedReexport :: ModuleOrigin -> [UnitInfo]
    fromExposedReexport = [UnitInfo]
    res,
                                       fromPackageFlag :: ModuleOrigin -> Bool
    fromPackageFlag = Bool
    f })
                  | Just Bool
    True <- Maybe Bool
    e
                     = SDoc -> SDoc
    parens (String -> SDoc
    text String
    "from" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (forall unit. GenModule unit -> unit
    moduleUnit GenModule Unit
    mod))
                  | Bool
    f Bool -> Bool -> Bool
    && forall unit. GenModule unit -> ModuleName
    moduleName GenModule Unit
    mod forall a. Eq a => a -> a -> Bool
    == ModuleName
    m
                     = SDoc -> SDoc
    parens (String -> SDoc
    text String
    "from" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (forall unit. GenModule unit -> unit
    moduleUnit GenModule Unit
    mod))
                  | (UnitInfo
    pkg:[UnitInfo]
    _) <- [UnitInfo]
    res
                     = SDoc -> SDoc
    parens (String -> SDoc
    text String
    "from" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (UnitInfo -> Unit
    mkUnit UnitInfo
    pkg)
                        SDoc -> SDoc -> SDoc
    <> SDoc
    comma SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "reexporting" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr GenModule Unit
    mod)
                  | Bool
    f
                     = SDoc -> SDoc
    parens (String -> SDoc
    text String
    "defined via package flags to be"
                        SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr GenModule Unit
    mod)
                  | Bool
    otherwise = SDoc
    Outputable.empty
        pp_sugg (SuggestHidden ModuleName
    m GenModule Unit
    mod ModuleOrigin
    o) = forall a. Outputable a => a -> SDoc
    ppr ModuleName
    m SDoc -> SDoc -> SDoc
    <+> ModuleOrigin -> SDoc
    provenance ModuleOrigin
    o
          where provenance :: ModuleOrigin -> SDoc
    provenance ModuleOrigin
    ModHidden =  SDoc
    Outputable.empty
                provenance (ModUnusable UnusableUnitReason
    _) = SDoc
    Outputable.empty
                provenance (ModOrigin{ fromOrigUnit :: ModuleOrigin -> Maybe Bool
    fromOrigUnit = Maybe Bool
    e,
                                       fromHiddenReexport :: ModuleOrigin -> [UnitInfo]
    fromHiddenReexport = [UnitInfo]
    rhs })
                  | Just Bool
    False <- Maybe Bool
    e
                     = SDoc -> SDoc
    parens (String -> SDoc
    text String
    "needs flag -package-id"
                        SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (forall unit. GenModule unit -> unit
    moduleUnit GenModule Unit
    mod))
                  | (UnitInfo
    pkg:[UnitInfo]
    _) <- [UnitInfo]
    rhs
                     = SDoc -> SDoc
    parens (String -> SDoc
    text String
    "needs flag -package-id"
                        SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr (UnitInfo -> Unit
    mkUnit UnitInfo
    pkg))
                  | Bool
    otherwise = SDoc
    Outputable.empty