    {-# LANGUAGE CPP                      #-}
    {-# LANGUAGE NondecreasingIndentation #-}
    {-# LANGUAGE ScopedTypeVariables      #-}
    {-# LANGUAGE TypeFamilies             #-}

    module GHC.Tc.Utils.Backpack (
        findExtraSigImports',
        findExtraSigImports,
        implicitRequirements',
        implicitRequirements,
        implicitRequirementsShallow,
        checkUnit,
        tcRnCheckUnit,
        tcRnMergeSignatures,
        mergeSignatures,
        tcRnInstantiateSignature,
        instantiateSignature,
    ) where

    import GHC.Prelude

    import GHC.Driver.Env
    import GHC.Driver.Ppr

    import GHC.Types.Basic (TypeOrKind(..))
    import GHC.Types.Fixity (defaultFixity)
    import GHC.Types.Fixity.Env
    import GHC.Types.TypeEnv
    import GHC.Types.Name.Reader
    import GHC.Types.Id
    import GHC.Types.Name
    import GHC.Types.Name.Env
    import GHC.Types.Name.Set
    import GHC.Types.Avail
    import GHC.Types.SrcLoc
    import GHC.Types.SourceFile
    import GHC.Types.Var
    import GHC.Types.Unique.DSet
    import GHC.Types.Name.Shape

    import GHC.Unit
    import GHC.Unit.State
    import GHC.Unit.Finder
    import GHC.Unit.Module.Warnings
    import GHC.Unit.Module.ModIface
    import GHC.Unit.Module.ModDetails
    import GHC.Unit.Module.Imported
    import GHC.Unit.Module.Deps

    import GHC.Tc.Gen.Export
    import GHC.Tc.Solver
    import GHC.Tc.TyCl.Utils
    import GHC.Tc.Types.Constraint
    import GHC.Tc.Types.Origin
    import GHC.Tc.Utils.Monad
    import GHC.Tc.Utils.Instantiate
    import GHC.Tc.Utils.TcMType
    import GHC.Tc.Utils.TcType

    import GHC.Hs

    import GHC.Core.InstEnv
    import GHC.Core.FamInstEnv
    import GHC.Core.Type
    import GHC.Core.Multiplicity

    import GHC.IfaceToCore
    import GHC.Iface.Load
    import GHC.Iface.Rename
    import GHC.Iface.Syntax

    import GHC.Rename.Names
    import GHC.Rename.Fixity ( lookupFixityRn )

    import GHC.Tc.Utils.Env
    import GHC.Tc.Errors
    import GHC.Tc.Utils.Unify

    import GHC.Utils.Misc
    import GHC.Utils.Error
    import GHC.Utils.Outputable
    import GHC.Utils.Panic

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

    import Control.Monad
    import Data.List (find)

    import {-# SOURCE #-} GHC.Tc.Module

    #include "HsVersions.h"

    fixityMisMatch :: TyThing -> Fixity -> Fixity -> SDoc
    fixityMisMatch :: TyThing -> Fixity -> Fixity -> SDoc
    fixityMisMatch TyThing
    real_thing Fixity
    real_fixity Fixity
    sig_fixity =
        [SDoc] -> SDoc
    vcat [forall a. Outputable a => a -> SDoc
    ppr TyThing
    real_thing SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "has conflicting fixities in the module",
              String -> SDoc
    text String
    "and its hsig file",
              String -> SDoc
    text String
    "Main module:" SDoc -> SDoc -> SDoc
    <+> Fixity -> SDoc
    ppr_fix Fixity
    real_fixity,
              String -> SDoc
    text String
    "Hsig file:" SDoc -> SDoc -> SDoc
    <+> Fixity -> SDoc
    ppr_fix Fixity
    sig_fixity]
      where
        ppr_fix :: Fixity -> SDoc
    ppr_fix Fixity
    f =
            forall a. Outputable a => a -> SDoc
    ppr Fixity
    f SDoc -> SDoc -> SDoc
    <+>
            (if Fixity
    f forall a. Eq a => a -> a -> Bool
    == Fixity
    defaultFixity
                then SDoc -> SDoc
    parens (String -> SDoc
    text String
    "default")
                else SDoc
    empty)

    checkHsigDeclM :: ModIface -> TyThing -> TyThing -> TcRn ()
    checkHsigDeclM :: ModIface -> TyThing -> TyThing -> TcRn ()
    checkHsigDeclM ModIface
    sig_iface TyThing
    sig_thing TyThing
    real_thing = do
        let name :: Name
    name = forall a. NamedThing a => a -> Name
    getName TyThing
    real_thing
        -- TODO: Distinguish between signature merging and signature
        -- implementation cases.
        Bool -> TyThing -> TyThing -> TcRn ()
    checkBootDeclM Bool
    False TyThing
    sig_thing TyThing
    real_thing
        Fixity
    real_fixity <- Name -> RnM Fixity
    lookupFixityRn Name
    name
        let sig_fixity :: Fixity
    sig_fixity = case ModIfaceBackend -> OccName -> Maybe Fixity
    mi_fix_fn (forall (phase :: ModIfacePhase).
    ModIface_ phase -> IfaceBackendExts phase
    mi_final_exts ModIface
    sig_iface) (forall name. HasOccName name => name -> OccName
    occName Name
    name) of
                            Maybe Fixity
    Nothing -> Fixity
    defaultFixity
                            Just Fixity
    f -> Fixity
    f
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Fixity
    real_fixity forall a. Eq a => a -> a -> Bool
    /= Fixity
    sig_fixity) forall a b. (a -> b) -> a -> b
    $
          SrcSpan -> SDoc -> TcRn ()
    addErrAt (Name -> SrcSpan
    nameSrcSpan Name
    name)
            (TyThing -> Fixity -> Fixity -> SDoc
    fixityMisMatch TyThing
    real_thing Fixity
    real_fixity Fixity
    sig_fixity)

    -- | Given a 'ModDetails' of an instantiated signature (note that the
    -- 'ModDetails' must be knot-tied consistently with the actual implementation)
    -- and a 'GlobalRdrEnv' constructed from the implementor of this interface,
    -- verify that the actual implementation actually matches the original
    -- interface.
    --
    -- Note that it is already assumed that the implementation *exports*
    -- a sufficient set of entities, since otherwise the renaming and then
    -- typechecking of the signature 'ModIface' would have failed.
    checkHsigIface :: TcGblEnv -> GlobalRdrEnv -> ModIface -> ModDetails -> TcRn ()
    checkHsigIface :: TcGblEnv -> GlobalRdrEnv -> ModIface -> ModDetails -> TcRn ()
    checkHsigIface TcGblEnv
    tcg_env GlobalRdrEnv
    gr ModIface
    sig_iface
      ModDetails { md_insts :: ModDetails -> [ClsInst]
    md_insts = [ClsInst]
    sig_insts, md_fam_insts :: ModDetails -> [FamInst]
    md_fam_insts = [FamInst]
    sig_fam_insts,
                   md_types :: ModDetails -> TypeEnv
    md_types = TypeEnv
    sig_type_env, md_exports :: ModDetails -> [AvailInfo]
    md_exports = [AvailInfo]
    sig_exports   } = do
        String -> SDoc -> TcRn ()
    traceTc String
    "checkHsigIface" forall a b. (a -> b) -> a -> b
    $ [SDoc] -> SDoc
    vcat
            [ forall a. Outputable a => a -> SDoc
    ppr TypeEnv
    sig_type_env, forall a. Outputable a => a -> SDoc
    ppr [ClsInst]
    sig_insts, forall a. Outputable a => a -> SDoc
    ppr [AvailInfo]
    sig_exports ]
        forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ Name -> TcRn ()
    check_export (forall a b. (a -> b) -> [a] -> [b]
    map AvailInfo -> Name
    availName [AvailInfo]
    sig_exports)
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless (forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [FamInst]
    sig_fam_insts) forall a b. (a -> b) -> a -> b
    $
            forall a. String -> a
    panic (String
    "GHC.Tc.Module.checkHsigIface: Cannot handle family " forall a. [a] -> [a] -> [a]
    ++
                   String
    "instances in hsig files yet...")
        -- Delete instances so we don't look them up when
        -- checking instance satisfiability
        -- TODO: this should not be necessary
        TcGblEnv
    tcg_env <- forall gbl lcl. TcRnIf gbl lcl gbl
    getGblEnv
        forall gbl lcl a. gbl -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
    setGblEnv TcGblEnv
    tcg_env { tcg_inst_env :: InstEnv
    tcg_inst_env = InstEnv
    emptyInstEnv,
                            tcg_fam_inst_env :: FamInstEnv
    tcg_fam_inst_env = FamInstEnv
    emptyFamInstEnv,
                            tcg_insts :: [ClsInst]
    tcg_insts = [],
                            tcg_fam_insts :: [FamInst]
    tcg_fam_insts = [] } forall a b. (a -> b) -> a -> b
    $ do
        forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ ClsInst -> TcRn ()
    check_inst [ClsInst]
    sig_insts
        TcRn ()
    failIfErrsM
      where
        -- NB: the Names in sig_type_env are bogus.  Let's say we have H.hsig
        -- in package p that defines T; and we implement with himpl:H.  Then the
        -- Name is p[himpl:H]:H.T, NOT himplH:H.T.  That's OK but we just
        -- have to look up the right name.
        sig_type_occ_env :: OccEnv TyThing
    sig_type_occ_env = forall a. [(OccName, a)] -> OccEnv a
    mkOccEnv
                         forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a b. (a -> b) -> [a] -> [b]
    map (\TyThing
    t -> (Name -> OccName
    nameOccName (forall a. NamedThing a => a -> Name
    getName TyThing
    t), TyThing
    t))
                         forall a b. (a -> b) -> a -> b
    $ forall a. NameEnv a -> [a]
    nameEnvElts TypeEnv
    sig_type_env
        dfun_names :: [Name]
    dfun_names = forall a b. (a -> b) -> [a] -> [b]
    map forall a. NamedThing a => a -> Name
    getName [ClsInst]
    sig_insts
        check_export :: Name -> TcRn ()
    check_export Name
    name
          -- Skip instances, we'll check them later
          -- TODO: Actually this should never happen, because DFuns are
          -- never exported...
          | Name
    name forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Name]
    dfun_names = forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          -- See if we can find the type directly in the hsig ModDetails
          -- TODO: need to special case wired in names
          | Just TyThing
    sig_thing <- forall a. OccEnv a -> OccName -> Maybe a
    lookupOccEnv OccEnv TyThing
    sig_type_occ_env (Name -> OccName
    nameOccName Name
    name) = do
            -- NB: We use tcLookupImported_maybe because we want to EXCLUDE
            -- tcg_env (TODO: but maybe this isn't relevant anymore).
            MaybeErr SDoc TyThing
    r <- Name -> TcM (MaybeErr SDoc TyThing)
    tcLookupImported_maybe Name
    name
            case MaybeErr SDoc TyThing
    r of
              Failed SDoc
    err -> SDoc -> TcRn ()
    addErr SDoc
    err
              Succeeded TyThing
    real_thing -> ModIface -> TyThing -> TyThing -> TcRn ()
    checkHsigDeclM ModIface
    sig_iface TyThing
    sig_thing TyThing
    real_thing

          -- The hsig did NOT define this function; that means it must
          -- be a reexport.  In this case, make sure the 'Name' of the
          -- reexport matches the 'Name exported here.
          | [GlobalRdrElt
    gre] <- GlobalRdrEnv -> OccName -> [GlobalRdrElt]
    lookupGlobalRdrEnv GlobalRdrEnv
    gr (Name -> OccName
    nameOccName Name
    name) = do
            let name' :: Name
    name' = GlobalRdrElt -> Name
    greMangledName GlobalRdrElt
    gre
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Name
    name forall a. Eq a => a -> a -> Bool
    /= Name
    name') forall a b. (a -> b) -> a -> b
    $ do
                -- See Note [Error reporting bad reexport]
                -- TODO: Actually this error swizzle doesn't work
                let p :: GenLocated
      (SrcSpanAnn' (EpAnn AnnListItem)) (IE (GhcPass 'Renamed))
    -> Bool
    p (L SrcSpanAnn' (EpAnn AnnListItem)
    _ IE (GhcPass 'Renamed)
    ie) = Name
    name forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` forall (p :: Pass). IE (GhcPass p) -> [IdP (GhcPass p)]
    ieNames IE (GhcPass 'Renamed)
    ie
                    loc :: SrcSpan
    loc = case TcGblEnv -> Maybe [(LIE (GhcPass 'Renamed), [AvailInfo])]
    tcg_rn_exports TcGblEnv
    tcg_env of
                           Just [(LIE (GhcPass 'Renamed), [AvailInfo])]
    es | Just GenLocated
      (SrcSpanAnn' (EpAnn AnnListItem)) (IE (GhcPass 'Renamed))
    e <- forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    find GenLocated
      (SrcSpanAnn' (EpAnn AnnListItem)) (IE (GhcPass 'Renamed))
    -> Bool
    p (forall a b. (a -> b) -> [a] -> [b]
    map forall a b. (a, b) -> a
    fst [(LIE (GhcPass 'Renamed), [AvailInfo])]
    es)
                             -- TODO: maybe we can be a little more
                             -- precise here and use the Located
                             -- info for the *specific* name we matched.
                             -> forall a e. GenLocated (SrcSpanAnn' a) e -> SrcSpan
    getLocA GenLocated
      (SrcSpanAnn' (EpAnn AnnListItem)) (IE (GhcPass 'Renamed))
    e
                           Maybe [(LIE (GhcPass 'Renamed), [AvailInfo])]
    _ -> Name -> SrcSpan
    nameSrcSpan Name
    name
                SrcSpan -> SDoc -> TcRn ()
    addErrAt SrcSpan
    loc
                    (Bool -> Name -> Name -> SDoc
    badReexportedBootThing Bool
    False Name
    name Name
    name')
          -- This should actually never happen, but whatever...
          | Bool
    otherwise =
            SrcSpan -> SDoc -> TcRn ()
    addErrAt (Name -> SrcSpan
    nameSrcSpan Name
    name)
                (Bool -> Name -> String -> SDoc
    missingBootThing Bool
    False Name
    name String
    "exported by")

    -- Note [Error reporting bad reexport]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- NB: You want to be a bit careful about what location you report on reexports.
    -- If the name was declared in the hsig file, 'nameSrcSpan name' is indeed the
    -- correct source location.  However, if it was *reexported*, obviously the name
    -- is not going to have the right location.  In this case, we need to grovel in
    -- tcg_rn_exports to figure out where the reexport came from.

    -- | Checks if a 'ClsInst' is "defined". In general, for hsig files we can't
    -- assume that the implementing file actually implemented the instances (they
    -- may be reexported from elsewhere).  Where should we look for the instances?
    -- We do the same as we would otherwise: consult the EPS.  This isn't perfect
    -- (we might conclude the module exports an instance when it doesn't, see
    -- #9422), but we will never refuse to compile something.
    check_inst :: ClsInst -> TcM ()
    check_inst :: ClsInst -> TcRn ()
    check_inst ClsInst
    sig_inst = do
        -- TODO: This could be very well generalized to support instance
        -- declarations in boot files.
        TcGblEnv
    tcg_env <- forall gbl lcl. TcRnIf gbl lcl gbl
    getGblEnv
        -- NB: Have to tug on the interface, not necessarily
        -- tugged... but it didn't work?
        forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ Name -> TcM (MaybeErr SDoc TyThing)
    tcLookupImported_maybe (NameSet -> [Name]
    nameSetElemsStable (ClsInst -> NameSet
    orphNamesOfClsInst ClsInst
    sig_inst))
        -- Based off of 'simplifyDeriv'
        let ty :: Kind
    ty = Id -> Kind
    idType (ClsInst -> Id
    instanceDFunId ClsInst
    sig_inst)
            skol_info :: SkolemInfo
    skol_info = SkolemInfo
    InstSkol
            -- Based off of tcSplitDFunTy
            ([Id]
    tvs, [Scaled Kind]
    theta, Kind
    pred) =
               case Kind -> ([Id], Kind)
    tcSplitForAllInvisTyVars Kind
    ty of { ([Id]
    tvs, Kind
    rho)    ->
               case Kind -> ([Scaled Kind], Kind)
    splitFunTys Kind
    rho             of { ([Scaled Kind]
    theta, Kind
    pred) ->
               ([Id]
    tvs, [Scaled Kind]
    theta, Kind
    pred) }}
            origin :: CtOrigin
    origin = Module -> ClsInst -> CtOrigin
    InstProvidedOrigin (TcGblEnv -> Module
    tcg_semantic_mod TcGblEnv
    tcg_env) ClsInst
    sig_inst
        (TCvSubst
    skol_subst, [Id]
    tvs_skols) <- [Id] -> TcM (TCvSubst, [Id])
    tcInstSkolTyVars [Id]
    tvs -- Skolemize
        (TcLevel
    tclvl,[CtEvidence]
    cts) <- forall a. TcM a -> TcM (TcLevel, a)
    pushTcLevelM forall a b. (a -> b) -> a -> b
    $ do
           CtEvidence
    wanted <- CtOrigin -> Maybe TypeOrKind -> Kind -> TcM CtEvidence
    newWanted CtOrigin
    origin
                               (forall a. a -> Maybe a
    Just TypeOrKind
    TypeLevel)
                               (HasCallStack => TCvSubst -> Kind -> Kind
    substTy TCvSubst
    skol_subst Kind
    pred)
           [CtEvidence]
    givens <- forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM [Scaled Kind]
    theta forall a b. (a -> b) -> a -> b
    $ \Scaled Kind
    given -> do
               CtLoc
    loc <- CtOrigin -> Maybe TypeOrKind -> TcM CtLoc
    getCtLocM CtOrigin
    origin (forall a. a -> Maybe a
    Just TypeOrKind
    TypeLevel)
               let given_pred :: Kind
    given_pred = HasCallStack => TCvSubst -> Kind -> Kind
    substTy TCvSubst
    skol_subst (forall a. Scaled a -> a
    scaledThing Scaled Kind
    given)
               Id
    new_ev <- forall gbl lcl. Kind -> TcRnIf gbl lcl Id
    newEvVar Kind
    given_pred
               forall (m :: * -> *) a. Monad m => a -> m a
    return CtGiven { ctev_pred :: Kind
    ctev_pred = Kind
    given_pred
                              -- Doesn't matter, make something up
                              , ctev_evar :: Id
    ctev_evar = Id
    new_ev
                              , ctev_loc :: CtLoc
    ctev_loc = CtLoc
    loc
                              }
           forall (m :: * -> *) a. Monad m => a -> m a
    return forall a b. (a -> b) -> a -> b
    $ CtEvidence
    wanted forall a. a -> [a] -> [a]
    : [CtEvidence]
    givens
        WantedConstraints
    unsolved <- [CtEvidence] -> TcM WantedConstraints
    simplifyWantedsTcM [CtEvidence]
    cts

        (Bag Implication
    implic, TcEvBinds
    _) <- TcLevel
    -> SkolemInfo
    -> [Id]
    -> [Id]
    -> WantedConstraints
    -> TcM (Bag Implication, TcEvBinds)
    buildImplicationFor TcLevel
    tclvl SkolemInfo
    skol_info [Id]
    tvs_skols [] WantedConstraints
    unsolved
        WantedConstraints -> TcRn ()
    reportAllUnsolved (Bag Implication -> WantedConstraints
    mkImplicWC Bag Implication
    implic)

    -- | For a module @modname@ of type 'HscSource', determine the list
    -- of extra "imports" of other requirements which should be considered part of
    -- the import of the requirement, because it transitively depends on those
    -- requirements by imports of modules from other packages.  The situation
    -- is something like this:
    --
    --      unit p where
    --          signature X
    --          signature Y
    --              import X
    --
    --      unit q where
    --          dependency p[X=\<A>,Y=\<B>]
    --          signature A
    --          signature B
    --
    -- Although q's B does not directly import A, we still have to make sure we
    -- process A first, because the merging process will cause B to indirectly
    -- import A.  This function finds the TRANSITIVE closure of all such imports
    -- we need to make.
    findExtraSigImports' :: HscEnv
                         -> HscSource
                         -> ModuleName
                         -> IO (UniqDSet ModuleName)
    findExtraSigImports' :: HscEnv -> HscSource -> ModuleName -> IO (UniqDSet ModuleName)
    findExtraSigImports' HscEnv
    hsc_env HscSource
    HsigFile ModuleName
    modname =
        forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap forall a. [UniqDSet a] -> UniqDSet a
    unionManyUniqDSets (forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM [InstantiatedModule]
    reqs forall a b. (a -> b) -> a -> b
    $ \(Module InstantiatedUnit
    iuid ModuleName
    mod_name) ->
            (forall a. HscEnv -> IfG a -> IO a
    initIfaceLoad HscEnv
    hsc_env
                forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall gbl lcl a.
    TcRnIf gbl lcl (MaybeErr SDoc a) -> TcRnIf gbl lcl a
    withException
                forall a b. (a -> b) -> a -> b
    $ forall gbl lcl.
    SDoc
    -> Module -> TcRnIf gbl lcl (MaybeErr SDoc (UniqDSet ModuleName))
    moduleFreeHolesPrecise (String -> SDoc
    text String
    "findExtraSigImports")
                    (forall u. u -> ModuleName -> GenModule u
    mkModule (forall uid. GenInstantiatedUnit uid -> GenUnit uid
    VirtUnit InstantiatedUnit
    iuid) ModuleName
    mod_name)))
      where
        unit_state :: UnitState
    unit_state = HscEnv -> UnitState
    hsc_units HscEnv
    hsc_env
        reqs :: [InstantiatedModule]
    reqs = UnitState -> ModuleName -> [InstantiatedModule]
    requirementMerges UnitState
    unit_state ModuleName
    modname

    findExtraSigImports' HscEnv
    _ HscSource
    _ ModuleName
    _ = forall (m :: * -> *) a. Monad m => a -> m a
    return forall a. UniqDSet a
    emptyUniqDSet

    -- | 'findExtraSigImports', but in a convenient form for "GHC.Driver.Make" and
    -- "GHC.Tc.Module".
    findExtraSigImports :: HscEnv -> HscSource -> ModuleName
                        -> IO [(Maybe FastString, Located ModuleName)]
    findExtraSigImports :: HscEnv
    -> HscSource
    -> ModuleName
    -> IO [(Maybe FastString, Located ModuleName)]
    findExtraSigImports HscEnv
    hsc_env HscSource
    hsc_src ModuleName
    modname = do
        UniqDSet ModuleName
    extra_requirements <- HscEnv -> HscSource -> ModuleName -> IO (UniqDSet ModuleName)
    findExtraSigImports' HscEnv
    hsc_env HscSource
    hsc_src ModuleName
    modname
        forall (m :: * -> *) a. Monad m => a -> m a
    return [ (forall a. Maybe a
    Nothing, forall e. e -> Located e
    noLoc ModuleName
    mod_name)
               | ModuleName
    mod_name <- forall a. UniqDSet a -> [a]
    uniqDSetToList UniqDSet ModuleName
    extra_requirements ]

    -- A version of 'implicitRequirements'' which is more friendly
    -- for "GHC.Tc.Module".
    implicitRequirements :: HscEnv
                         -> [(Maybe FastString, Located ModuleName)]
                         -> IO [(Maybe FastString, Located ModuleName)]
    implicitRequirements :: HscEnv
    -> [(Maybe FastString, Located ModuleName)]
    -> IO [(Maybe FastString, Located ModuleName)]
    implicitRequirements HscEnv
    hsc_env [(Maybe FastString, Located ModuleName)]
    normal_imports
      = do [ModuleName]
    mns <- HscEnv
    -> [(Maybe FastString, Located ModuleName)] -> IO [ModuleName]
    implicitRequirements' HscEnv
    hsc_env [(Maybe FastString, Located ModuleName)]
    normal_imports
           forall (m :: * -> *) a. Monad m => a -> m a
    return [ (forall a. Maybe a
    Nothing, forall e. e -> Located e
    noLoc ModuleName
    mn) | ModuleName
    mn <- [ModuleName]
    mns ]

    -- Given a list of 'import M' statements in a module, figure out
    -- any extra implicit requirement imports they may have.  For
    -- example, if they 'import M' and M resolves to p[A=<B>,C=D], then
    -- they actually also import the local requirement B.
    implicitRequirements' :: HscEnv
                         -> [(Maybe FastString, Located ModuleName)]
                         -> IO [ModuleName]
    implicitRequirements' :: HscEnv
    -> [(Maybe FastString, Located ModuleName)] -> IO [ModuleName]
    implicitRequirements' HscEnv
    hsc_env [(Maybe FastString, Located ModuleName)]
    normal_imports
      = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat forall a b. (a -> b) -> a -> b
    $
        forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM [(Maybe FastString, Located ModuleName)]
    normal_imports forall a b. (a -> b) -> a -> b
    $ \(Maybe FastString
    mb_pkg, L SrcSpan
    _ ModuleName
    imp) -> do
            FindResult
    found <- HscEnv -> ModuleName -> Maybe FastString -> IO FindResult
    findImportedModule HscEnv
    hsc_env ModuleName
    imp Maybe FastString
    mb_pkg
            case FindResult
    found of
                Found ModLocation
    _ Module
    mod | Bool -> Bool
    not (HomeUnit -> Module -> Bool
    isHomeModule HomeUnit
    home_unit Module
    mod) ->
                    forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a. UniqDSet a -> [a]
    uniqDSetToList (forall u. GenModule (GenUnit u) -> UniqDSet ModuleName
    moduleFreeHoles Module
    mod))
                FindResult
    _ -> forall (m :: * -> *) a. Monad m => a -> m a
    return []
      where home_unit :: HomeUnit
    home_unit = HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env

    -- | Like @implicitRequirements'@, but returns either the module name, if it is
    -- a free hole, or the instantiated unit the imported module is from, so that
    -- that instantiated unit can be processed and via the batch mod graph (rather
    -- than a transitive closure done here) all the free holes are still reachable.
    implicitRequirementsShallow
      :: HscEnv
      -> [(Maybe FastString, Located ModuleName)]
      -> IO ([ModuleName], [InstantiatedUnit])
    implicitRequirementsShallow :: HscEnv
    -> [(Maybe FastString, Located ModuleName)]
    -> IO ([ModuleName], [InstantiatedUnit])
    implicitRequirementsShallow HscEnv
    hsc_env [(Maybe FastString, Located ModuleName)]
    normal_imports = ([ModuleName], [InstantiatedUnit])
    -> [(Maybe FastString, Located ModuleName)]
    -> IO ([ModuleName], [InstantiatedUnit])
    go ([], []) [(Maybe FastString, Located ModuleName)]
    normal_imports
     where
      go :: ([ModuleName], [InstantiatedUnit])
    -> [(Maybe FastString, Located ModuleName)]
    -> IO ([ModuleName], [InstantiatedUnit])
    go ([ModuleName], [InstantiatedUnit])
    acc [] = forall (f :: * -> *) a. Applicative f => a -> f a
    pure ([ModuleName], [InstantiatedUnit])
    acc
      go ([ModuleName]
    accL, [InstantiatedUnit]
    accR) ((Maybe FastString
    mb_pkg, L SrcSpan
    _ ModuleName
    imp):[(Maybe FastString, Located ModuleName)]
    imports) = do
        FindResult
    found <- HscEnv -> ModuleName -> Maybe FastString -> IO FindResult
    findImportedModule HscEnv
    hsc_env ModuleName
    imp Maybe FastString
    mb_pkg
        let acc' :: ([ModuleName], [InstantiatedUnit])
    acc' = case FindResult
    found of
              Found ModLocation
    _ Module
    mod | Bool -> Bool
    not (HomeUnit -> Module -> Bool
    isHomeModule (HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env) Module
    mod) ->
                  case forall unit. GenModule unit -> unit
    moduleUnit Module
    mod of
                      Unit
    HoleUnit -> (forall unit. GenModule unit -> ModuleName
    moduleName Module
    mod forall a. a -> [a] -> [a]
    : [ModuleName]
    accL, [InstantiatedUnit]
    accR)
                      RealUnit Definite UnitId
    _ -> ([ModuleName]
    accL, [InstantiatedUnit]
    accR)
                      VirtUnit InstantiatedUnit
    u -> ([ModuleName]
    accL, InstantiatedUnit
    uforall a. a -> [a] -> [a]
    :[InstantiatedUnit]
    accR)
              FindResult
    _ -> ([ModuleName]
    accL, [InstantiatedUnit]
    accR)
        ([ModuleName], [InstantiatedUnit])
    -> [(Maybe FastString, Located ModuleName)]
    -> IO ([ModuleName], [InstantiatedUnit])
    go ([ModuleName], [InstantiatedUnit])
    acc' [(Maybe FastString, Located ModuleName)]
    imports

    -- | Given a 'Unit', make sure it is well typed.  This is because
    -- unit IDs come from Cabal, which does not know if things are well-typed or
    -- not; a component may have been filled with implementations for the holes
    -- that don't actually fulfill the requirements.
    checkUnit :: Unit -> TcM ()
    checkUnit :: Unit -> TcRn ()
    checkUnit Unit
    HoleUnit         = forall (m :: * -> *) a. Monad m => a -> m a
    return ()
    checkUnit (RealUnit Definite UnitId
    _)     = forall (m :: * -> *) a. Monad m => a -> m a
    return () -- if it's already compiled, must be well-typed
    checkUnit (VirtUnit InstantiatedUnit
    indef) = do
       let insts :: GenInstantiations UnitId
    insts = forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts InstantiatedUnit
    indef
       forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ GenInstantiations UnitId
    insts forall a b. (a -> b) -> a -> b
    $ \(ModuleName
    mod_name, Module
    mod) ->
           -- NB: direct hole instantiations are well-typed by construction
           -- (because we FORCE things to be merged in), so don't check them
           forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Bool -> Bool
    not (forall u. GenModule (GenUnit u) -> Bool
    isHoleModule Module
    mod)) forall a b. (a -> b) -> a -> b
    $ do
               Unit -> TcRn ()
    checkUnit (forall unit. GenModule unit -> unit
    moduleUnit Module
    mod)
               TcGblEnv
    _ <- Module
    mod Module -> InstantiatedModule -> TcRn TcGblEnv
    `checkImplements` forall u. u -> ModuleName -> GenModule u
    Module InstantiatedUnit
    indef ModuleName
    mod_name
               forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- | Top-level driver for signature instantiation (run when compiling
    -- an @hsig@ file.)
    tcRnCheckUnit ::
        HscEnv -> Unit ->
        IO (Messages DecoratedSDoc, Maybe ())
    tcRnCheckUnit :: HscEnv -> Unit -> IO (Messages DecoratedSDoc, Maybe ())
    tcRnCheckUnit HscEnv
    hsc_env Unit
    uid =
       forall (m :: * -> *) a.
    MonadIO m =>
    Logger -> DynFlags -> SDoc -> (a -> ()) -> m a -> m a
    withTiming Logger
    logger DynFlags
    dflags
                  (String -> SDoc
    text String
    "Check unit id" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr Unit
    uid)
                  (forall a b. a -> b -> a
    const ()) forall a b. (a -> b) -> a -> b
    $
       forall r.
    HscEnv
    -> HscSource
    -> Bool
    -> Module
    -> RealSrcSpan
    -> TcM r
    -> IO (Messages DecoratedSDoc, Maybe r)
    initTc HscEnv
    hsc_env
              HscSource
    HsigFile -- bogus
              Bool
    False
              (HscEnv -> Module
    mainModIs HscEnv
    hsc_env)
              (RealSrcLoc -> RealSrcSpan
    realSrcLocSpan (FastString -> Int -> Int -> RealSrcLoc
    mkRealSrcLoc (String -> FastString
    fsLit String
    loc_str) Int
    0 Int
    0)) -- bogus
        forall a b. (a -> b) -> a -> b
    $ Unit -> TcRn ()
    checkUnit Unit
    uid
      where
       dflags :: DynFlags
    dflags = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
       logger :: Logger
    logger = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env
       loc_str :: String
    loc_str = String
    "Command line argument: -unit-id " forall a. [a] -> [a] -> [a]
    ++ DynFlags -> SDoc -> String
    showSDoc DynFlags
    dflags (forall a. Outputable a => a -> SDoc
    ppr Unit
    uid)

    -- TODO: Maybe lcl_iface0 should be pre-renamed to the right thing? Unclear...

    -- | Top-level driver for signature merging (run after typechecking
    -- an @hsig@ file).
    tcRnMergeSignatures :: HscEnv -> HsParsedModule -> TcGblEnv {- from local sig -} -> ModIface
                        -> IO (Messages DecoratedSDoc, Maybe TcGblEnv)
    tcRnMergeSignatures :: HscEnv
    -> HsParsedModule
    -> TcGblEnv
    -> ModIface
    -> IO (Messages DecoratedSDoc, Maybe TcGblEnv)
    tcRnMergeSignatures HscEnv
    hsc_env HsParsedModule
    hpm TcGblEnv
    orig_tcg_env ModIface
    iface =
      forall (m :: * -> *) a.
    MonadIO m =>
    Logger -> DynFlags -> SDoc -> (a -> ()) -> m a -> m a
    withTiming Logger
    logger DynFlags
    dflags
                 (String -> SDoc
    text String
    "Signature merging" SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    brackets (forall a. Outputable a => a -> SDoc
    ppr Module
    this_mod))
                 (forall a b. a -> b -> a
    const ()) forall a b. (a -> b) -> a -> b
    $
      forall r.
    HscEnv
    -> HscSource
    -> Bool
    -> Module
    -> RealSrcSpan
    -> TcM r
    -> IO (Messages DecoratedSDoc, Maybe r)
    initTc HscEnv
    hsc_env HscSource
    HsigFile Bool
    False Module
    this_mod RealSrcSpan
    real_loc forall a b. (a -> b) -> a -> b
    $
        HsParsedModule -> TcGblEnv -> ModIface -> TcRn TcGblEnv
    mergeSignatures HsParsedModule
    hpm TcGblEnv
    orig_tcg_env ModIface
    iface
     where
      dflags :: DynFlags
    dflags   = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
      logger :: Logger
    logger   = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env
      this_mod :: Module
    this_mod = forall (phase :: ModIfacePhase). ModIface_ phase -> Module
    mi_module ModIface
    iface
      real_loc :: RealSrcSpan
    real_loc = TcGblEnv -> RealSrcSpan
    tcg_top_loc TcGblEnv
    orig_tcg_env

    thinModIface :: [AvailInfo] -> ModIface -> ModIface
    thinModIface :: [AvailInfo] -> ModIface -> ModIface
    thinModIface [AvailInfo]
    avails ModIface
    iface =
        ModIface
    iface {
            mi_exports :: [AvailInfo]
    mi_exports = [AvailInfo]
    avails,
            -- mi_fixities = ...,
            -- mi_warns = ...,
            -- mi_anns = ...,
            -- TODO: The use of nameOccName here is a bit dodgy, because
            -- perhaps there might be two IfaceTopBndr that are the same
            -- OccName but different Name.  Requires better understanding
            -- of invariants here.
            mi_decls :: [IfaceDeclExts 'ModIfaceFinal]
    mi_decls = [(Fingerprint, IfaceDecl)]
    exported_decls forall a. [a] -> [a] -> [a]
    ++ [(Fingerprint, IfaceDecl)]
    non_exported_decls forall a. [a] -> [a] -> [a]
    ++ [(Fingerprint, IfaceDecl)]
    dfun_decls
            -- mi_insts = ...,
            -- mi_fam_insts = ...,
        }
      where
        decl_pred :: OccSet -> IfaceDecl -> Bool
    decl_pred OccSet
    occs IfaceDecl
    decl = Name -> OccName
    nameOccName (IfaceDecl -> Name
    ifName IfaceDecl
    decl) OccName -> OccSet -> Bool
    `elemOccSet` OccSet
    occs
        filter_decls :: OccSet -> [(Fingerprint, IfaceDecl)]
    filter_decls OccSet
    occs = forall a. (a -> Bool) -> [a] -> [a]
    filter (OccSet -> IfaceDecl -> Bool
    decl_pred OccSet
    occs forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a b. (a, b) -> b
    snd) (forall (phase :: ModIfacePhase).
    ModIface_ phase -> [IfaceDeclExts phase]
    mi_decls ModIface
    iface)

        exported_occs :: OccSet
    exported_occs = [OccName] -> OccSet
    mkOccSet [ forall name. HasOccName name => name -> OccName
    occName Name
    n
                                 | AvailInfo
    a <- [AvailInfo]
    avails
                                 , Name
    n <- AvailInfo -> [Name]
    availNames AvailInfo
    a ]
        exported_decls :: [(Fingerprint, IfaceDecl)]
    exported_decls = OccSet -> [(Fingerprint, IfaceDecl)]
    filter_decls OccSet
    exported_occs

        non_exported_occs :: OccSet
    non_exported_occs = [OccName] -> OccSet
    mkOccSet [ forall name. HasOccName name => name -> OccName
    occName Name
    n
                                     | (Fingerprint
    _, IfaceDecl
    d) <- [(Fingerprint, IfaceDecl)]
    exported_decls
                                     , Name
    n <- IfaceDecl -> [Name]
    ifaceDeclNeverExportedRefs IfaceDecl
    d ]
        non_exported_decls :: [(Fingerprint, IfaceDecl)]
    non_exported_decls = OccSet -> [(Fingerprint, IfaceDecl)]
    filter_decls OccSet
    non_exported_occs

        dfun_pred :: IfaceDecl -> Bool
    dfun_pred IfaceId{ ifIdDetails :: IfaceDecl -> IfaceIdDetails
    ifIdDetails = IfaceIdDetails
    IfDFunId } = Bool
    True
        dfun_pred IfaceDecl
    _ = Bool
    False
        dfun_decls :: [(Fingerprint, IfaceDecl)]
    dfun_decls = forall a. (a -> Bool) -> [a] -> [a]
    filter (IfaceDecl -> Bool
    dfun_pred forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a b. (a, b) -> b
    snd) (forall (phase :: ModIfacePhase).
    ModIface_ phase -> [IfaceDeclExts phase]
    mi_decls ModIface
    iface)

    -- | The list of 'Name's of *non-exported* 'IfaceDecl's which this
    -- 'IfaceDecl' may refer to.  A non-exported 'IfaceDecl' should be kept
    -- after thinning if an *exported* 'IfaceDecl' (or 'mi_insts', perhaps)
    -- refers to it; we can't decide to keep it by looking at the exports
    -- of a module after thinning.  Keep this synchronized with
    -- 'rnIfaceDecl'.
    ifaceDeclNeverExportedRefs :: IfaceDecl -> [Name]
    ifaceDeclNeverExportedRefs :: IfaceDecl -> [Name]
    ifaceDeclNeverExportedRefs d :: IfaceDecl
    d@IfaceFamily{} =
        case IfaceDecl -> IfaceFamTyConFlav
    ifFamFlav IfaceDecl
    d of
            IfaceClosedSynFamilyTyCon (Just (Name
    n, [IfaceAxBranch]
    _))
                -> [Name
    n]
            IfaceFamTyConFlav
    _   -> []
    ifaceDeclNeverExportedRefs IfaceDecl
    _ = []

    -- Note [Blank hsigs for all requirements]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- One invariant that a client of GHC must uphold is that there
    -- must be an hsig file for every requirement (according to
    -- @-this-unit-id@); this ensures that for every interface
    -- file (hi), there is a source file (hsig), which helps grease
    -- the wheels of recompilation avoidance which assumes that
    -- source files always exist.

    {-
    inheritedSigPvpWarning :: WarningTxt
    inheritedSigPvpWarning =
        WarningTxt (noLoc NoSourceText) [noLoc (StringLiteral NoSourceText (fsLit msg))]
      where
        msg = "Inherited requirements from non-signature libraries (libraries " ++
              "with modules) should not be used, as this mode of use is not " ++
              "compatible with PVP-style version bounds.  Instead, copy the " ++
              "declaration to the local hsig file or move the signature to a " ++
              "library of its own and add that library as a dependency."
    -}

    -- Note [Handling never-exported TyThings under Backpack]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    --   DEFINITION: A "never-exported TyThing" is a TyThing whose 'Name' will
    --   never be mentioned in the export list of a module (mi_avails).
    --   Unlike implicit TyThings (Note [Implicit TyThings]), non-exported
    --   TyThings DO have a standalone IfaceDecl declaration in their
    --   interface file.
    --
    -- Originally, Backpack was designed under the assumption that anything
    -- you could declare in a module could also be exported; thus, merging
    -- the export lists of two signatures is just merging the declarations
    -- of two signatures writ small.  Of course, in GHC Haskell, there are a
    -- few important things which are not explicitly exported but still can
    -- be used:  in particular, dictionary functions for instances, Typeable
    -- TyCon bindings, and coercion axioms for type families also count.
    --
    -- When handling these non-exported things, there two primary things
    -- we need to watch out for:
    --
    --  * Signature matching/merging is done by comparing each
    --    of the exported entities of a signature and a module.  These exported
    --    entities may refer to non-exported TyThings which must be tested for
    --    consistency.  For example, an instance (ClsInst) will refer to a
    --    non-exported DFunId.  In this case, 'checkBootDeclM' directly compares the
    --    embedded 'DFunId' in 'is_dfun'.
    --
    --    For this to work at all, we must ensure that pointers in 'is_dfun' refer
    --    to DISTINCT 'DFunId's, even though the 'Name's (may) be the same.
    --    Unfortunately, this is the OPPOSITE of how we treat most other references
    --    to 'Name's, so this case needs to be handled specially.
    --
    --    The details are in the documentation for 'typecheckIfacesForMerging'.
    --    and the Note [Resolving never-exported Names] in GHC.IfaceToCore.
    --
    --  * When we rename modules and signatures, we use the export lists to
    --    decide how the declarations should be renamed.  However, this
    --    means we don't get any guidance for how to rename non-exported
    --    entities.  Fortunately, we only need to rename these entities
    --    *consistently*, so that 'typecheckIfacesForMerging' can wire them
    --    up as needed.
    --
    --    The details are in Note [rnIfaceNeverExported] in 'GHC.Iface.Rename'.
    --
    -- The root cause for all of these complications is the fact that these
    -- logically "implicit" entities are defined indirectly in an interface
    -- file.  #13151 gives a proposal to make these *truly* implicit.

    merge_msg :: ModuleName -> [InstantiatedModule] -> SDoc
    merge_msg :: ModuleName -> [InstantiatedModule] -> SDoc
    merge_msg ModuleName
    mod_name [] =
        String -> SDoc
    text String
    "while checking the local signature" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod_name SDoc -> SDoc -> SDoc
    <+>
        String -> SDoc
    text String
    "for consistency"
    merge_msg ModuleName
    mod_name [InstantiatedModule]
    reqs =
      SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    text String
    "while merging the signatures from" SDoc -> SDoc -> SDoc
    <> SDoc
    colon)
       Int
    2 ([SDoc] -> SDoc
    vcat [ SDoc
    bullet SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr InstantiatedModule
    req | InstantiatedModule
    req <- [InstantiatedModule]
    reqs ] SDoc -> SDoc -> SDoc
    $$
          SDoc
    bullet SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "...and the local signature for" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod_name)

    -- | Given a local 'ModIface', merge all inherited requirements
    -- from 'requirementMerges' into this signature, producing
    -- a final 'TcGblEnv' that matches the local signature and
    -- all required signatures.
    mergeSignatures :: HsParsedModule -> TcGblEnv -> ModIface -> TcRn TcGblEnv
    mergeSignatures :: HsParsedModule -> TcGblEnv -> ModIface -> TcRn TcGblEnv
    mergeSignatures
      (HsParsedModule { hpm_module :: HsParsedModule -> Located HsModule
    hpm_module = L SrcSpan
    loc (HsModule { hsmodExports :: HsModule -> Maybe (LocatedL [LIE GhcPs])
    hsmodExports = Maybe (LocatedL [LIE GhcPs])
    mb_exports }),
                        hpm_src_files :: HsParsedModule -> [String]
    hpm_src_files = [String]
    src_files })
      TcGblEnv
    orig_tcg_env ModIface
    lcl_iface0 = forall a. SrcSpan -> TcRn a -> TcRn a
    setSrcSpan SrcSpan
    loc forall a b. (a -> b) -> a -> b
    $ do
        -- The lcl_iface0 is the ModIface for the local hsig
        -- file, which is guaranteed to exist, see
        -- Note [Blank hsigs for all requirements]
        HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv

        -- Copy over some things from the original TcGblEnv that
        -- we want to preserve
        forall gbl lcl a.
    (gbl -> gbl) -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
    updGblEnv (\TcGblEnv
    env -> TcGblEnv
    env {
            -- Renamed imports/declarations are often used
            -- by programs that use the GHC API, e.g., Haddock.
            -- These won't get filled by the merging process (since
            -- we don't actually rename the parsed module again) so
            -- we need to take them directly from the previous
            -- typechecking.
            --
            -- NB: the export declarations aren't in their final
            -- form yet.  We'll fill those in when we reprocess
            -- the export declarations.
            tcg_rn_imports :: [LImportDecl (GhcPass 'Renamed)]
    tcg_rn_imports = TcGblEnv -> [LImportDecl (GhcPass 'Renamed)]
    tcg_rn_imports TcGblEnv
    orig_tcg_env,
            tcg_rn_decls :: Maybe (HsGroup (GhcPass 'Renamed))
    tcg_rn_decls   = TcGblEnv -> Maybe (HsGroup (GhcPass 'Renamed))
    tcg_rn_decls   TcGblEnv
    orig_tcg_env,
            -- Annotations
            tcg_ann_env :: AnnEnv
    tcg_ann_env    = TcGblEnv -> AnnEnv
    tcg_ann_env    TcGblEnv
    orig_tcg_env,
            -- Documentation header
            tcg_doc_hdr :: Maybe LHsDocString
    tcg_doc_hdr    = TcGblEnv -> Maybe LHsDocString
    tcg_doc_hdr TcGblEnv
    orig_tcg_env
            -- tcg_dus?
            -- tcg_th_used           = tcg_th_used orig_tcg_env,
            -- tcg_th_splice_used    = tcg_th_splice_used orig_tcg_env
           }) forall a b. (a -> b) -> a -> b
    $ do
        TcGblEnv
    tcg_env <- forall gbl lcl. TcRnIf gbl lcl gbl
    getGblEnv

        let outer_mod :: Module
    outer_mod  = TcGblEnv -> Module
    tcg_mod TcGblEnv
    tcg_env
            inner_mod :: Module
    inner_mod  = TcGblEnv -> Module
    tcg_semantic_mod TcGblEnv
    tcg_env
            mod_name :: ModuleName
    mod_name   = forall unit. GenModule unit -> ModuleName
    moduleName (TcGblEnv -> Module
    tcg_mod TcGblEnv
    tcg_env)
            unit_state :: UnitState
    unit_state = HscEnv -> UnitState
    hsc_units HscEnv
    hsc_env
            home_unit :: HomeUnit
    home_unit  = HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env

        -- STEP 1: Figure out all of the external signature interfaces
        -- we are going to merge in.
        let reqs :: [InstantiatedModule]
    reqs = UnitState -> ModuleName -> [InstantiatedModule]
    requirementMerges UnitState
    unit_state ModuleName
    mod_name

        forall a. SDoc -> TcM a -> TcM a
    addErrCtxt (UnitState -> SDoc -> SDoc
    pprWithUnitState UnitState
    unit_state forall a b. (a -> b) -> a -> b
    $ ModuleName -> [InstantiatedModule] -> SDoc
    merge_msg ModuleName
    mod_name [InstantiatedModule]
    reqs) forall a b. (a -> b) -> a -> b
    $ do

        -- STEP 2: Read in the RAW forms of all of these interfaces
        [ModIface]
    ireq_ifaces0 <- forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM [InstantiatedModule]
    reqs forall a b. (a -> b) -> a -> b
    $ \(Module InstantiatedUnit
    iuid ModuleName
    mod_name) ->
            let m :: Module
    m = forall u. u -> ModuleName -> GenModule u
    mkModule (forall uid. GenInstantiatedUnit uid -> GenUnit uid
    VirtUnit InstantiatedUnit
    iuid) ModuleName
    mod_name
                im :: InstalledModule
    im = forall a b. (a, b) -> a
    fst (Module -> (InstalledModule, Maybe InstantiatedModule)
    getModuleInstantiation Module
    m)
            in forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap forall a b. (a, b) -> a
    fst
             forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall gbl lcl a.
    TcRnIf gbl lcl (MaybeErr SDoc a) -> TcRnIf gbl lcl a
    withException
             forall a b. (a -> b) -> a -> b
    $ forall gbl lcl.
    SDoc
    -> InstalledModule
    -> Module
    -> IsBootInterface
    -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, String))
    findAndReadIface (String -> SDoc
    text String
    "mergeSignatures") InstalledModule
    im Module
    m IsBootInterface
    NotBoot

        -- STEP 3: Get the unrenamed exports of all these interfaces,
        -- thin it according to the export list, and do shaping on them.
        let extend_ns :: NameShape
    -> [AvailInfo]
    -> IOEnv (Env TcGblEnv TcLclEnv) (Either SDoc NameShape)
    extend_ns NameShape
    nsubst [AvailInfo]
    as = forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall a b. (a -> b) -> a -> b
    $ HscEnv -> NameShape -> [AvailInfo] -> IO (Either SDoc NameShape)
    extendNameShape HscEnv
    hsc_env NameShape
    nsubst [AvailInfo]
    as
            -- This function gets run on every inherited interface, and
            -- it's responsible for:
            --
            --  1. Merging the exports of the interface into @nsubst@,
            --  2. Adding these exports to the "OK to import" set (@oks@)
            --  if they came from a package with no exposed modules
            --  (this means we won't report a PVP error in this case), and
            --  3. Thinning the interface according to an explicit export
            --  list.
            --
            gen_subst :: (NameShape, OccSet, [(InstantiatedModule, ModIface)])
    -> (InstantiatedModule, ModIface)
    -> IOEnv
         (Env TcGblEnv TcLclEnv)
         (NameShape, OccSet, [(InstantiatedModule, ModIface)])
    gen_subst (NameShape
    nsubst,OccSet
    oks,[(InstantiatedModule, ModIface)]
    ifaces) (imod :: InstantiatedModule
    imod@(Module InstantiatedUnit
    iuid ModuleName
    _), ModIface
    ireq_iface) = do
                let insts :: GenInstantiations UnitId
    insts = forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts InstantiatedUnit
    iuid
                    isFromSignaturePackage :: Bool
    isFromSignaturePackage =
                        let inst_uid :: Indefinite UnitId
    inst_uid = forall unit. GenInstantiatedUnit unit -> Indefinite unit
    instUnitInstanceOf InstantiatedUnit
    iuid
                            pkg :: UnitInfo
    pkg = HasDebugCallStack => UnitState -> UnitId -> UnitInfo
    unsafeLookupUnitId UnitState
    unit_state (forall unit. Indefinite unit -> unit
    indefUnit Indefinite UnitId
    inst_uid)
                        in forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (forall compid srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo compid srcpkgid srcpkgname uid modulename mod
    -> [(modulename, Maybe mod)]
    unitExposedModules UnitInfo
    pkg)
                -- 3(a). Rename the exports according to how the dependency
                -- was instantiated.  The resulting export list will be accurate
                -- except for exports *from the signature itself* (which may
                -- be subsequently updated by exports from other signatures in
                -- the merge.
                [AvailInfo]
    as1 <- GenInstantiations UnitId -> ModIface -> TcM [AvailInfo]
    tcRnModExports GenInstantiations UnitId
    insts ModIface
    ireq_iface
                -- 3(b). Thin the interface if it comes from a signature package.
                (ModIface
    thinned_iface, [AvailInfo]
    as2) <- case Maybe (LocatedL [LIE GhcPs])
    mb_exports of
                        Just (L SrcSpanAnnL
    loc [LIE GhcPs]
    _)
                          -- Check if the package containing this signature is
                          -- a signature package (i.e., does not expose any
                          -- modules.)  If so, we can thin it.
                          | Bool
    isFromSignaturePackage
                          -> forall ann a. SrcSpanAnn' ann -> TcRn a -> TcRn a
    setSrcSpanA SrcSpanAnnL
    loc forall a b. (a -> b) -> a -> b
    $ do
                            -- Suppress missing errors; they might be used to refer
                            -- to entities from other signatures we are merging in.
                            -- If an identifier truly doesn't exist in any of the
                            -- signatures that are merged in, we will discover this
                            -- when we run exports_from_avail on the final merged
                            -- export list.
                            (Maybe
      (Maybe
         [(GenLocated
             (SrcSpanAnn' (EpAnn AnnListItem)) (IE (GhcPass 'Renamed)),
           [AvailInfo])],
       [AvailInfo])
    mb_r, Messages DecoratedSDoc
    msgs) <- forall a. TcRn a -> TcRn (Maybe a, Messages DecoratedSDoc)
    tryTc forall a b. (a -> b) -> a -> b
    $ do
                                -- Suppose that we have written in a signature:
                                --  signature A ( module A ) where {- empty -}
                                -- If I am also inheriting a signature from a
                                -- signature package, does 'module A' scope over
                                -- all of its exports?
                                --
                                -- There are two possible interpretations:
                                --
                                --  1. For non self-reexports, a module reexport
                                --  is interpreted only in terms of the local
                                --  signature module, and not any of the inherited
                                --  ones.  The reason for this is because after
                                --  typechecking, module exports are completely
                                --  erased from the interface of a file, so we
                                --  have no way of "interpreting" a module reexport.
                                --  Thus, it's only useful for the local signature
                                --  module (where we have a useful GlobalRdrEnv.)
                                --
                                --  2. On the other hand, a common idiom when
                                --  you want to "export everything, plus a reexport"
                                --  in modules is to say module A ( module A, reex ).
                                --  This applies to signature modules too; and in
                                --  particular, you probably still want the entities
                                --  from the inherited signatures to be preserved
                                --  too.
                                --
                                -- We think it's worth making a special case for
                                -- self reexports to make use case (2) work.  To
                                -- do this, we take the exports of the inherited
                                -- signature @as1@, and bundle them into a
                                -- GlobalRdrEnv where we treat them as having come
                                -- from the import @import A@.  Thus, we will
                                -- pick them up if they are referenced explicitly
                                -- (@foo@) or even if we do a module reexport
                                -- (@module A@).
                                let ispec :: ImportSpec
    ispec = ImpDeclSpec -> ImpItemSpec -> ImportSpec
    ImpSpec ImpDeclSpec{
                                                -- NB: This needs to be mod name
                                                -- of the local signature, not
                                                -- the (original) module name of
                                                -- the inherited signature,
                                                -- because we need module
                                                -- LocalSig (from the local
                                                -- export list) to match it!
                                                is_mod :: ModuleName
    is_mod  = ModuleName
    mod_name,
                                                is_as :: ModuleName
    is_as   = ModuleName
    mod_name,
                                                is_qual :: Bool
    is_qual = Bool
    False,
                                                is_dloc :: SrcSpan
    is_dloc = forall a. SrcSpanAnn' a -> SrcSpan
    locA SrcSpanAnnL
    loc
                                              } ImpItemSpec
    ImpAll
                                    rdr_env :: GlobalRdrEnv
    rdr_env = [GlobalRdrElt] -> GlobalRdrEnv
    mkGlobalRdrEnv (Maybe ImportSpec -> [AvailInfo] -> [GlobalRdrElt]
    gresFromAvails (forall a. a -> Maybe a
    Just ImportSpec
    ispec) [AvailInfo]
    as1)
                                forall gbl lcl a. gbl -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
    setGblEnv TcGblEnv
    tcg_env {
                                    tcg_rdr_env :: GlobalRdrEnv
    tcg_rdr_env = GlobalRdrEnv
    rdr_env
                                } forall a b. (a -> b) -> a -> b
    $ Maybe (LocatedL [LIE GhcPs])
    -> GlobalRdrEnv
    -> ImportAvails
    -> Module
    -> TcRnIf
         TcGblEnv
         TcLclEnv
         (Maybe [(LIE (GhcPass 'Renamed), [AvailInfo])], [AvailInfo])
    exports_from_avail Maybe (LocatedL [LIE GhcPs])
    mb_exports GlobalRdrEnv
    rdr_env
                                        -- NB: tcg_imports is also empty!
                                        ImportAvails
    emptyImportAvails
                                        (TcGblEnv -> Module
    tcg_semantic_mod TcGblEnv
    tcg_env)
                            case Maybe
      (Maybe
         [(GenLocated
             (SrcSpanAnn' (EpAnn AnnListItem)) (IE (GhcPass 'Renamed)),
           [AvailInfo])],
       [AvailInfo])
    mb_r of
                                Just (Maybe
      [(GenLocated
          (SrcSpanAnn' (EpAnn AnnListItem)) (IE (GhcPass 'Renamed)),
        [AvailInfo])]
    _, [AvailInfo]
    as2) -> forall (m :: * -> *) a. Monad m => a -> m a
    return ([AvailInfo] -> ModIface -> ModIface
    thinModIface [AvailInfo]
    as2 ModIface
    ireq_iface, [AvailInfo]
    as2)
                                Maybe
      (Maybe
         [(GenLocated
             (SrcSpanAnn' (EpAnn AnnListItem)) (IE (GhcPass 'Renamed)),
           [AvailInfo])],
       [AvailInfo])
    Nothing -> Messages DecoratedSDoc -> TcRn ()
    addMessages Messages DecoratedSDoc
    msgs forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> forall env a. IOEnv env a
    failM
                        -- We can't think signatures from non signature packages
                        Maybe (LocatedL [LIE GhcPs])
    _ -> forall (m :: * -> *) a. Monad m => a -> m a
    return (ModIface
    ireq_iface, [AvailInfo]
    as1)
                -- 3(c). Only identifiers from signature packages are "ok" to
                -- import (that is, they are safe from a PVP perspective.)
                -- (NB: This code is actually dead right now.)
                let oks' :: OccSet
    oks' | Bool
    isFromSignaturePackage
                         = OccSet -> [OccName] -> OccSet
    extendOccSetList OccSet
    oks ([AvailInfo] -> [OccName]
    exportOccs [AvailInfo]
    as2)
                         | Bool
    otherwise
                         = OccSet
    oks
                -- 3(d). Extend the name substitution (performing shaping)
                Either SDoc NameShape
    mb_r <- NameShape
    -> [AvailInfo]
    -> IOEnv (Env TcGblEnv TcLclEnv) (Either SDoc NameShape)
    extend_ns NameShape
    nsubst [AvailInfo]
    as2
                case Either SDoc NameShape
    mb_r of
                    Left SDoc
    err -> forall a. SDoc -> TcM a
    failWithTc SDoc
    err
                    Right NameShape
    nsubst' -> forall (m :: * -> *) a. Monad m => a -> m a
    return (NameShape
    nsubst',OccSet
    oks',(InstantiatedModule
    imod, ModIface
    thinned_iface)forall a. a -> [a] -> [a]
    :[(InstantiatedModule, ModIface)]
    ifaces)
            nsubst0 :: NameShape
    nsubst0 = ModuleName -> [AvailInfo] -> NameShape
    mkNameShape (forall unit. GenModule unit -> ModuleName
    moduleName Module
    inner_mod) (forall (phase :: ModIfacePhase). ModIface_ phase -> [AvailInfo]
    mi_exports ModIface
    lcl_iface0)
            ok_to_use0 :: OccSet
    ok_to_use0 = [OccName] -> OccSet
    mkOccSet ([AvailInfo] -> [OccName]
    exportOccs (forall (phase :: ModIfacePhase). ModIface_ phase -> [AvailInfo]
    mi_exports ModIface
    lcl_iface0))
        -- Process each interface, getting the thinned interfaces as well as
        -- the final, full set of exports @nsubst@ and the exports which are
        -- "ok to use" (we won't attach 'inheritedSigPvpWarning' to them.)
        (NameShape
    nsubst, OccSet
    ok_to_use, [(InstantiatedModule, ModIface)]
    rev_thinned_ifaces)
            <- forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldM (NameShape, OccSet, [(InstantiatedModule, ModIface)])
    -> (InstantiatedModule, ModIface)
    -> IOEnv
         (Env TcGblEnv TcLclEnv)
         (NameShape, OccSet, [(InstantiatedModule, ModIface)])
    gen_subst (NameShape
    nsubst0, OccSet
    ok_to_use0, []) (forall a b. [a] -> [b] -> [(a, b)]
    zip [InstantiatedModule]
    reqs [ModIface]
    ireq_ifaces0)
        let thinned_ifaces :: [(InstantiatedModule, ModIface)]
    thinned_ifaces = forall a. [a] -> [a]
    reverse [(InstantiatedModule, ModIface)]
    rev_thinned_ifaces
            exports :: [AvailInfo]
    exports        = NameShape -> [AvailInfo]
    nameShapeExports NameShape
    nsubst
            rdr_env :: GlobalRdrEnv
    rdr_env        = [GlobalRdrElt] -> GlobalRdrEnv
    mkGlobalRdrEnv (Maybe ImportSpec -> [AvailInfo] -> [GlobalRdrElt]
    gresFromAvails forall a. Maybe a
    Nothing [AvailInfo]
    exports)
            _warn_occs :: [OccName]
    _warn_occs     = forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (OccName -> OccSet -> Bool
    `elemOccSet` OccSet
    ok_to_use)) ([AvailInfo] -> [OccName]
    exportOccs [AvailInfo]
    exports)
            warns :: Warnings
    warns          = Warnings
    NoWarnings
            {-
            -- TODO: Warnings are transitive, but this is not what we want here:
            -- if a module reexports an entity from a signature, that should be OK.
            -- Not supported in current warning framework
            warns | null warn_occs = NoWarnings
                  | otherwise = WarnSome $ map (\o -> (o, inheritedSigPvpWarning)) warn_occs
            -}
        forall gbl lcl a. gbl -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
    setGblEnv TcGblEnv
    tcg_env {
            -- The top-level GlobalRdrEnv is quite interesting.  It consists
            -- of two components:
            --  1. First, we reuse the GlobalRdrEnv of the local signature.
            --     This is very useful, because it means that if we have
            --     to print a message involving some entity that the local
            --     signature imported, we'll qualify it accordingly.
            --  2. Second, we need to add all of the declarations we are
            --     going to merge in (as they need to be in scope for the
            --     final test of the export list.)
            tcg_rdr_env :: GlobalRdrEnv
    tcg_rdr_env = GlobalRdrEnv
    rdr_env GlobalRdrEnv -> GlobalRdrEnv -> GlobalRdrEnv
    `plusGlobalRdrEnv` TcGblEnv -> GlobalRdrEnv
    tcg_rdr_env TcGblEnv
    orig_tcg_env,
            -- Inherit imports from the local signature, so that module
            -- reexports are picked up correctly
            tcg_imports :: ImportAvails
    tcg_imports = TcGblEnv -> ImportAvails
    tcg_imports TcGblEnv
    orig_tcg_env,
            tcg_exports :: [AvailInfo]
    tcg_exports = [AvailInfo]
    exports,
            tcg_dus :: DefUses
    tcg_dus     = NameSet -> DefUses
    usesOnly ([AvailInfo] -> NameSet
    availsToNameSetWithSelectors [AvailInfo]
    exports),
            tcg_warns :: Warnings
    tcg_warns   = Warnings
    warns
            } forall a b. (a -> b) -> a -> b
    $ do
        TcGblEnv
    tcg_env <- forall gbl lcl. TcRnIf gbl lcl gbl
    getGblEnv

        -- Make sure we didn't refer to anything that doesn't actually exist
        -- pprTrace "mergeSignatures: exports_from_avail" (ppr exports) $ return ()
        (Maybe
      [(GenLocated
          (SrcSpanAnn' (EpAnn AnnListItem)) (IE (GhcPass 'Renamed)),
        [AvailInfo])]
    mb_lies, [AvailInfo]
    _) <- Maybe (LocatedL [LIE GhcPs])
    -> GlobalRdrEnv
    -> ImportAvails
    -> Module
    -> TcRnIf
         TcGblEnv
         TcLclEnv
         (Maybe [(LIE (GhcPass 'Renamed), [AvailInfo])], [AvailInfo])
    exports_from_avail Maybe (LocatedL [LIE GhcPs])
    mb_exports GlobalRdrEnv
    rdr_env
                            (TcGblEnv -> ImportAvails
    tcg_imports TcGblEnv
    tcg_env) (TcGblEnv -> Module
    tcg_semantic_mod TcGblEnv
    tcg_env)

        {- -- NB: This is commented out, because warns above is disabled.
        -- If you tried to explicitly export an identifier that has a warning
        -- attached to it, that's probably a mistake.  Warn about it.
        case mb_lies of
          Nothing -> return ()
          Just lies ->
            forM_ (concatMap (\(L loc x) -> map (L loc) (ieNames x)) lies) $ \(L loc n) ->
              setSrcSpan loc $
                unless (nameOccName n `elemOccSet` ok_to_use) $
                    addWarn NoReason $ vcat [
                        text "Exported identifier" <+> quotes (ppr n) <+> text "will cause warnings if used.",
                        parens (text "To suppress this warning, remove" <+> quotes (ppr n) <+> text "from the export list of this signature.")
                        ]
        -}

        TcRn ()
    failIfErrsM

        -- Save the exports
        forall gbl lcl a. gbl -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
    setGblEnv TcGblEnv
    tcg_env { tcg_rn_exports :: Maybe [(LIE (GhcPass 'Renamed), [AvailInfo])]
    tcg_rn_exports = Maybe
      [(GenLocated
          (SrcSpanAnn' (EpAnn AnnListItem)) (IE (GhcPass 'Renamed)),
        [AvailInfo])]
    mb_lies } forall a b. (a -> b) -> a -> b
    $ do
        TcGblEnv
    tcg_env <- forall gbl lcl. TcRnIf gbl lcl gbl
    getGblEnv

        -- STEP 4: Rename the interfaces
        [ModIface]
    ext_ifaces <- forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM [(InstantiatedModule, ModIface)]
    thinned_ifaces forall a b. (a -> b) -> a -> b
    $ \((Module InstantiatedUnit
    iuid ModuleName
    _), ModIface
    ireq_iface) ->
            GenInstantiations UnitId
    -> Maybe NameShape
    -> ModIface
    -> IOEnv (Env TcGblEnv TcLclEnv) ModIface
    tcRnModIface (forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts InstantiatedUnit
    iuid) (forall a. a -> Maybe a
    Just NameShape
    nsubst) ModIface
    ireq_iface
        ModIface
    lcl_iface <- GenInstantiations UnitId
    -> Maybe NameShape
    -> ModIface
    -> IOEnv (Env TcGblEnv TcLclEnv) ModIface
    tcRnModIface (forall u. GenHomeUnit u -> GenInstantiations u
    homeUnitInstantiations HomeUnit
    home_unit) (forall a. a -> Maybe a
    Just NameShape
    nsubst) ModIface
    lcl_iface0
        let ifaces :: [ModIface]
    ifaces = ModIface
    lcl_iface forall a. a -> [a] -> [a]
    : [ModIface]
    ext_ifaces

        -- STEP 4.1: Merge fixities (we'll verify shortly) tcg_fix_env
        let fix_env :: NameEnv FixItem
    fix_env = forall a. [(Name, a)] -> NameEnv a
    mkNameEnv [ (GlobalRdrElt -> Name
    greMangledName GlobalRdrElt
    rdr_elt, OccName -> Fixity -> FixItem
    FixItem OccName
    occ Fixity
    f)
                                | (OccName
    occ, Fixity
    f) <- forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap forall (phase :: ModIfacePhase).
    ModIface_ phase -> [(OccName, Fixity)]
    mi_fixities [ModIface]
    ifaces
                                , GlobalRdrElt
    rdr_elt <- GlobalRdrEnv -> OccName -> [GlobalRdrElt]
    lookupGlobalRdrEnv GlobalRdrEnv
    rdr_env OccName
    occ ]

        -- STEP 5: Typecheck the interfaces
        let type_env_var :: TcRef TypeEnv
    type_env_var = TcGblEnv -> TcRef TypeEnv
    tcg_type_env_var TcGblEnv
    tcg_env

        -- typecheckIfacesForMerging does two things:
        --      1. It merges the all of the ifaces together, and typechecks the
        --      result to type_env.
        --      2. It typechecks each iface individually, but with their 'Name's
        --      resolving to the merged type_env from (1).
        -- See typecheckIfacesForMerging for more details.
        (TypeEnv
    type_env, [ModDetails]
    detailss) <- forall a. IfG a -> TcRn a
    initIfaceTcRn forall a b. (a -> b) -> a -> b
    $
                                forall lcl.
    Module
    -> [ModIface] -> TcRef TypeEnv -> IfM lcl (TypeEnv, [ModDetails])
    typecheckIfacesForMerging Module
    inner_mod [ModIface]
    ifaces TcRef TypeEnv
    type_env_var
        let infos :: [(ModIface, ModDetails)]
    infos = forall a b. [a] -> [b] -> [(a, b)]
    zip [ModIface]
    ifaces [ModDetails]
    detailss

        -- Test for cycles
        Unit -> [TyCon] -> [LTyClDecl (GhcPass 'Renamed)] -> TcRn ()
    checkSynCycles (HomeUnit -> Unit
    homeUnitAsUnit HomeUnit
    home_unit) (TypeEnv -> [TyCon]
    typeEnvTyCons TypeEnv
    type_env) []

        -- NB on type_env: it contains NO dfuns.  DFuns are recorded inside
        -- detailss, and given a Name that doesn't correspond to anything real.  See
        -- also Note [Signature merging DFuns]

        -- Add the merged type_env to TcGblEnv, so that it gets serialized
        -- out when we finally write out the interface.
        --
        -- NB: Why do we set tcg_tcs/tcg_patsyns/tcg_type_env directly,
        -- rather than use tcExtendGlobalEnv (the normal method to add newly
        -- defined types to TcGblEnv?)  tcExtendGlobalEnv adds these
        -- TyThings to 'tcg_type_env_var', which is consulted when
        -- we read in interfaces to tie the knot.  But *these TyThings themselves
        -- come from interface*, so that would result in deadlock.  Don't
        -- update it!
        forall gbl lcl a. gbl -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
    setGblEnv TcGblEnv
    tcg_env {
            tcg_tcs :: [TyCon]
    tcg_tcs = TypeEnv -> [TyCon]
    typeEnvTyCons TypeEnv
    type_env,
            tcg_patsyns :: [PatSyn]
    tcg_patsyns = TypeEnv -> [PatSyn]
    typeEnvPatSyns TypeEnv
    type_env,
            tcg_type_env :: TypeEnv
    tcg_type_env = TypeEnv
    type_env,
            tcg_fix_env :: NameEnv FixItem
    tcg_fix_env = NameEnv FixItem
    fix_env
            } forall a b. (a -> b) -> a -> b
    $ do
        TcGblEnv
    tcg_env <- forall gbl lcl. TcRnIf gbl lcl gbl
    getGblEnv

        -- STEP 6: Check for compatibility/merge things
        TcGblEnv
    tcg_env <- (\TcGblEnv -> (ModIface, ModDetails) -> TcRn TcGblEnv
    x -> forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldM TcGblEnv -> (ModIface, ModDetails) -> TcRn TcGblEnv
    x TcGblEnv
    tcg_env [(ModIface, ModDetails)]
    infos)
                 forall a b. (a -> b) -> a -> b
    $ \TcGblEnv
    tcg_env (ModIface
    iface, ModDetails
    details) -> do

            let check_export :: Name -> TcRn ()
    check_export Name
    name
                  | Just TyThing
    sig_thing <- TypeEnv -> Name -> Maybe TyThing
    lookupTypeEnv (ModDetails -> TypeEnv
    md_types ModDetails
    details) Name
    name
                  = case TypeEnv -> Name -> Maybe TyThing
    lookupTypeEnv TypeEnv
    type_env (forall a. NamedThing a => a -> Name
    getName TyThing
    sig_thing) of
                      Just TyThing
    thing -> ModIface -> TyThing -> TyThing -> TcRn ()
    checkHsigDeclM ModIface
    iface TyThing
    sig_thing TyThing
    thing
                      Maybe TyThing
    Nothing -> forall a. String -> a
    panic String
    "mergeSignatures: check_export"
                  -- Oops! We're looking for this export but it's
                  -- not actually in the type environment of the signature's
                  -- ModDetails.
                  --
                  -- NB: This case happens because the we're iterating
                  -- over the union of all exports, so some interfaces
                  -- won't have everything.  Note that md_exports is nonsense
                  -- (it's the same as exports); maybe we should fix this
                  -- eventually.
                  | Bool
    otherwise
                  = forall (m :: * -> *) a. Monad m => a -> m a
    return ()
            forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ Name -> TcRn ()
    check_export (forall a b. (a -> b) -> [a] -> [b]
    map AvailInfo -> Name
    availName [AvailInfo]
    exports)

            -- Note [Signature merging instances]
            -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            -- Merge instances into the global environment.  The algorithm here is
            -- dumb and simple: if an instance has exactly the same DFun type
            -- (tested by 'memberInstEnv') as an existing instance, we drop it;
            -- otherwise, we add it even, even if this would cause overlap.
            --
            -- Why don't we deduplicate instances with identical heads?  There's no
            -- good choice if they have premises:
            --
            --      instance K1 a => K (T a)
            --      instance K2 a => K (T a)
            --
            -- Why not eagerly error in this case?  The overlapping head does not
            -- necessarily mean that the instances are unimplementable: in fact,
            -- they may be implemented without overlap (if, for example, the
            -- implementing module has 'instance K (T a)'; both are implemented in
            -- this case.)  The implements test just checks that the wanteds are
            -- derivable assuming the givens.
            --
            -- Still, overlapping instances with hypotheses like above are going
            -- to be a bad deal, because instance resolution when we're typechecking
            -- against the merged signature is going to have a bad time when
            -- there are overlapping heads like this: we never backtrack, so it
            -- may be difficult to see that a wanted is derivable.  For now,
            -- we hope that we get lucky / the overlapping instances never
            -- get used, but it is not a very good situation to be in.
            --
            HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
            let merge_inst :: ([ClsInst], InstEnv) -> ClsInst -> ([ClsInst], InstEnv)
    merge_inst ([ClsInst]
    insts, InstEnv
    inst_env) ClsInst
    inst
                    | InstEnv -> ClsInst -> Bool
    memberInstEnv InstEnv
    inst_env ClsInst
    inst -- test DFun Type equality
                    = ([ClsInst]
    insts, InstEnv
    inst_env)
                    | Bool
    otherwise
                    -- NB: is_dfun_name inst is still nonsense here,
                    -- see Note [Signature merging DFuns]
                    = (ClsInst
    instforall a. a -> [a] -> [a]
    :[ClsInst]
    insts, InstEnv -> ClsInst -> InstEnv
    extendInstEnv InstEnv
    inst_env ClsInst
    inst)
                ([ClsInst]
    insts, InstEnv
    inst_env) = forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' ([ClsInst], InstEnv) -> ClsInst -> ([ClsInst], InstEnv)
    merge_inst
                                        (TcGblEnv -> [ClsInst]
    tcg_insts TcGblEnv
    tcg_env, TcGblEnv -> InstEnv
    tcg_inst_env TcGblEnv
    tcg_env)
                                        (ModDetails -> [ClsInst]
    md_insts ModDetails
    details)
                -- This is a HACK to prevent calculateAvails from including imp_mod
                -- in the listing.  We don't want it because a module is NOT
                -- supposed to include itself in its dep_orphs/dep_finsts.  See #13214
                iface' :: ModIface
    iface' = ModIface
    iface { mi_final_exts :: IfaceBackendExts 'ModIfaceFinal
    mi_final_exts = (forall (phase :: ModIfacePhase).
    ModIface_ phase -> IfaceBackendExts phase
    mi_final_exts ModIface
    iface){ mi_orphan :: Bool
    mi_orphan = Bool
    False, mi_finsts :: Bool
    mi_finsts = Bool
    False } }
                home_unit :: HomeUnit
    home_unit = HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env
                avails :: ImportAvails
    avails = ImportAvails -> ImportAvails -> ImportAvails
    plusImportAvails (TcGblEnv -> ImportAvails
    tcg_imports TcGblEnv
    tcg_env) forall a b. (a -> b) -> a -> b
    $
                            HomeUnit
    -> ModIface
    -> Bool
    -> IsBootInterface
    -> ImportedBy
    -> ImportAvails
    calculateAvails HomeUnit
    home_unit ModIface
    iface' Bool
    False IsBootInterface
    NotBoot ImportedBy
    ImportedBySystem
            forall (m :: * -> *) a. Monad m => a -> m a
    return TcGblEnv
    tcg_env {
                tcg_inst_env :: InstEnv
    tcg_inst_env = InstEnv
    inst_env,
                tcg_insts :: [ClsInst]
    tcg_insts    = [ClsInst]
    insts,
                tcg_imports :: ImportAvails
    tcg_imports  = ImportAvails
    avails,
                tcg_merged :: [(Module, Fingerprint)]
    tcg_merged   =
                    if Module
    outer_mod forall a. Eq a => a -> a -> Bool
    == forall (phase :: ModIfacePhase). ModIface_ phase -> Module
    mi_module ModIface
    iface
                        -- Don't add ourselves!
                        then TcGblEnv -> [(Module, Fingerprint)]
    tcg_merged TcGblEnv
    tcg_env
                        else (forall (phase :: ModIfacePhase). ModIface_ phase -> Module
    mi_module ModIface
    iface, ModIfaceBackend -> Fingerprint
    mi_mod_hash (forall (phase :: ModIfacePhase).
    ModIface_ phase -> IfaceBackendExts phase
    mi_final_exts ModIface
    iface)) forall a. a -> [a] -> [a]
    : TcGblEnv -> [(Module, Fingerprint)]
    tcg_merged TcGblEnv
    tcg_env
                }

        -- Note [Signature merging DFuns]
        -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        -- Once we know all of instances which will be defined by this merged
        -- signature, we go through each of the DFuns and rename them with a fresh,
        -- new, unique DFun Name, and add these DFuns to tcg_type_env (thus fixing
        -- up the "bogus" names that were setup in 'typecheckIfacesForMerging'.
        --
        -- We can't do this fixup earlier, because we need a way to identify each
        -- source DFun (from each of the signatures we are merging in) so that
        -- when we have a ClsInst, we can pull up the correct DFun to check if
        -- the types match.
        --
        -- See also Note [rnIfaceNeverExported] in GHC.Iface.Rename
        [(Id, ClsInst)]
    dfun_insts <- forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM (TcGblEnv -> [ClsInst]
    tcg_insts TcGblEnv
    tcg_env) forall a b. (a -> b) -> a -> b
    $ \ClsInst
    inst -> do
            Name
    n <- Class -> [Kind] -> SrcSpan -> TcM Name
    newDFunName (ClsInst -> Class
    is_cls ClsInst
    inst) (ClsInst -> [Kind]
    is_tys ClsInst
    inst) (Name -> SrcSpan
    nameSrcSpan (ClsInst -> Name
    is_dfun_name ClsInst
    inst))
            let dfun :: Id
    dfun = Id -> Name -> Id
    setVarName (ClsInst -> Id
    is_dfun ClsInst
    inst) Name
    n
            forall (m :: * -> *) a. Monad m => a -> m a
    return (Id
    dfun, ClsInst
    inst { is_dfun_name :: Name
    is_dfun_name = Name
    n, is_dfun :: Id
    is_dfun = Id
    dfun })
        TcGblEnv
    tcg_env <- forall (m :: * -> *) a. Monad m => a -> m a
    return TcGblEnv
    tcg_env {
                tcg_insts :: [ClsInst]
    tcg_insts = forall a b. (a -> b) -> [a] -> [b]
    map forall a b. (a, b) -> b
    snd [(Id, ClsInst)]
    dfun_insts,
                tcg_type_env :: TypeEnv
    tcg_type_env = TypeEnv -> [Id] -> TypeEnv
    extendTypeEnvWithIds (TcGblEnv -> TypeEnv
    tcg_type_env TcGblEnv
    tcg_env) (forall a b. (a -> b) -> [a] -> [b]
    map forall a b. (a, b) -> a
    fst [(Id, ClsInst)]
    dfun_insts)
            }

        [String] -> TcRn ()
    addDependentFiles [String]
    src_files

        forall (m :: * -> *) a. Monad m => a -> m a
    return TcGblEnv
    tcg_env

    -- | Top-level driver for signature instantiation (run when compiling
    -- an @hsig@ file.)
    tcRnInstantiateSignature ::
        HscEnv -> Module -> RealSrcSpan ->
        IO (Messages DecoratedSDoc, Maybe TcGblEnv)
    tcRnInstantiateSignature :: HscEnv
    -> Module
    -> RealSrcSpan
    -> IO (Messages DecoratedSDoc, Maybe TcGblEnv)
    tcRnInstantiateSignature HscEnv
    hsc_env Module
    this_mod RealSrcSpan
    real_loc =
       forall (m :: * -> *) a.
    MonadIO m =>
    Logger -> DynFlags -> SDoc -> (a -> ()) -> m a -> m a
    withTiming Logger
    logger DynFlags
    dflags
                  (String -> SDoc
    text String
    "Signature instantiation"SDoc -> SDoc -> SDoc
    <+>SDoc -> SDoc
    brackets (forall a. Outputable a => a -> SDoc
    ppr Module
    this_mod))
                  (forall a b. a -> b -> a
    const ()) forall a b. (a -> b) -> a -> b
    $
       forall r.
    HscEnv
    -> HscSource
    -> Bool
    -> Module
    -> RealSrcSpan
    -> TcM r
    -> IO (Messages DecoratedSDoc, Maybe r)
    initTc HscEnv
    hsc_env HscSource
    HsigFile Bool
    False Module
    this_mod RealSrcSpan
    real_loc forall a b. (a -> b) -> a -> b
    $ TcRn TcGblEnv
    instantiateSignature
      where
       dflags :: DynFlags
    dflags = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
       logger :: Logger
    logger = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env

    exportOccs :: [AvailInfo] -> [OccName]
    exportOccs :: [AvailInfo] -> [OccName]
    exportOccs = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (forall a b. (a -> b) -> [a] -> [b]
    map forall name. HasOccName name => name -> OccName
    occName forall b c a. (b -> c) -> (a -> b) -> a -> c
    . AvailInfo -> [Name]
    availNames)

    impl_msg :: UnitState -> Module -> InstantiatedModule -> SDoc
    impl_msg :: UnitState -> Module -> InstantiatedModule -> SDoc
    impl_msg UnitState
    unit_state Module
    impl_mod (Module InstantiatedUnit
    req_uid ModuleName
    req_mod_name)
       = UnitState -> SDoc -> SDoc
    pprWithUnitState UnitState
    unit_state forall a b. (a -> b) -> a -> b
    $
          String -> SDoc
    text String
    "while checking that" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr Module
    impl_mod SDoc -> SDoc -> SDoc
    <+>
          String -> SDoc
    text String
    "implements signature" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr ModuleName
    req_mod_name SDoc -> SDoc -> SDoc
    <+>
          String -> SDoc
    text String
    "in" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr InstantiatedUnit
    req_uid

    -- | Check if module implements a signature.  (The signature is
    -- always un-hashed, which is why its components are specified
    -- explicitly.)
    checkImplements :: Module -> InstantiatedModule -> TcRn TcGblEnv
    checkImplements :: Module -> InstantiatedModule -> TcRn TcGblEnv
    checkImplements Module
    impl_mod req_mod :: InstantiatedModule
    req_mod@(Module InstantiatedUnit
    uid ModuleName
    mod_name) = do
      HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
      let unit_state :: UnitState
    unit_state = HscEnv -> UnitState
    hsc_units HscEnv
    hsc_env
          home_unit :: HomeUnit
    home_unit  = HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env
      forall a. SDoc -> TcM a -> TcM a
    addErrCtxt (UnitState -> Module -> InstantiatedModule -> SDoc
    impl_msg UnitState
    unit_state Module
    impl_mod InstantiatedModule
    req_mod) forall a b. (a -> b) -> a -> b
    $ do
        let insts :: GenInstantiations UnitId
    insts = forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts InstantiatedUnit
    uid

        -- STEP 1: Load the implementing interface, and make a RdrEnv
        -- for its exports.  Also, add its 'ImportAvails' to 'tcg_imports',
        -- so that we treat all orphan instances it provides as visible
        -- when we verify that all instances are checked (see #12945), and so that
        -- when we eventually write out the interface we record appropriate
        -- dependency information.
        ModIface
    impl_iface <- forall a. IfG a -> TcRn a
    initIfaceTcRn forall a b. (a -> b) -> a -> b
    $
            forall lcl. SDoc -> Module -> IfM lcl ModIface
    loadSysInterface (String -> SDoc
    text String
    "checkImplements 1") Module
    impl_mod
        let impl_gr :: GlobalRdrEnv
    impl_gr = [GlobalRdrElt] -> GlobalRdrEnv
    mkGlobalRdrEnv
                        (Maybe ImportSpec -> [AvailInfo] -> [GlobalRdrElt]
    gresFromAvails forall a. Maybe a
    Nothing (forall (phase :: ModIfacePhase). ModIface_ phase -> [AvailInfo]
    mi_exports ModIface
    impl_iface))
            nsubst :: NameShape
    nsubst = ModuleName -> [AvailInfo] -> NameShape
    mkNameShape (forall unit. GenModule unit -> ModuleName
    moduleName Module
    impl_mod) (forall (phase :: ModIfacePhase). ModIface_ phase -> [AvailInfo]
    mi_exports ModIface
    impl_iface)

        -- Load all the orphans, so the subsequent 'checkHsigIface' sees
        -- all the instances it needs to
        SDoc -> [Module] -> TcRn ()
    loadModuleInterfaces (String -> SDoc
    text String
    "Loading orphan modules (from implementor of hsig)")
                             (Dependencies -> [Module]
    dep_orphs (forall (phase :: ModIfacePhase). ModIface_ phase -> Dependencies
    mi_deps ModIface
    impl_iface))

        let avails :: ImportAvails
    avails = HomeUnit
    -> ModIface
    -> Bool
    -> IsBootInterface
    -> ImportedBy
    -> ImportAvails
    calculateAvails HomeUnit
    home_unit
                        ModIface
    impl_iface Bool
    False{- safe -} IsBootInterface
    NotBoot ImportedBy
    ImportedBySystem
            fix_env :: NameEnv FixItem
    fix_env = forall a. [(Name, a)] -> NameEnv a
    mkNameEnv [ (GlobalRdrElt -> Name
    greMangledName GlobalRdrElt
    rdr_elt, OccName -> Fixity -> FixItem
    FixItem OccName
    occ Fixity
    f)
                                | (OccName
    occ, Fixity
    f) <- forall (phase :: ModIfacePhase).
    ModIface_ phase -> [(OccName, Fixity)]
    mi_fixities ModIface
    impl_iface
                                , GlobalRdrElt
    rdr_elt <- GlobalRdrEnv -> OccName -> [GlobalRdrElt]
    lookupGlobalRdrEnv GlobalRdrEnv
    impl_gr OccName
    occ ]
        forall gbl lcl a.
    (gbl -> gbl) -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
    updGblEnv (\TcGblEnv
    tcg_env -> TcGblEnv
    tcg_env {
            -- Setting tcg_rdr_env to treat all exported entities from
            -- the implementing module as in scope improves error messages,
            -- as it reduces the amount of qualification we need.  Unfortunately,
            -- we still end up qualifying references to external modules
            -- (see bkpfail07 for an example); we'd need to record more
            -- information in ModIface to solve this.
            tcg_rdr_env :: GlobalRdrEnv
    tcg_rdr_env = TcGblEnv -> GlobalRdrEnv
    tcg_rdr_env TcGblEnv
    tcg_env GlobalRdrEnv -> GlobalRdrEnv -> GlobalRdrEnv
    `plusGlobalRdrEnv` GlobalRdrEnv
    impl_gr,
            tcg_imports :: ImportAvails
    tcg_imports = TcGblEnv -> ImportAvails
    tcg_imports TcGblEnv
    tcg_env ImportAvails -> ImportAvails -> ImportAvails
    `plusImportAvails` ImportAvails
    avails,
            -- This is here so that when we call 'lookupFixityRn' for something
            -- directly implemented by the module, we grab the right thing
            tcg_fix_env :: NameEnv FixItem
    tcg_fix_env = NameEnv FixItem
    fix_env
            }) forall a b. (a -> b) -> a -> b
    $ do

        -- STEP 2: Load the *unrenamed, uninstantiated* interface for
        -- the ORIGINAL signature.  We are going to eventually rename it,
        -- but we must proceed slowly, because it is NOT known if the
        -- instantiation is correct.
        let sig_mod :: Module
    sig_mod = forall u. u -> ModuleName -> GenModule u
    mkModule (forall uid. GenInstantiatedUnit uid -> GenUnit uid
    VirtUnit InstantiatedUnit
    uid) ModuleName
    mod_name
            isig_mod :: InstalledModule
    isig_mod = forall a b. (a, b) -> a
    fst (Module -> (InstalledModule, Maybe InstantiatedModule)
    getModuleInstantiation Module
    sig_mod)
        MaybeErr SDoc (ModIface, String)
    mb_isig_iface <- forall gbl lcl.
    SDoc
    -> InstalledModule
    -> Module
    -> IsBootInterface
    -> TcRnIf gbl lcl (MaybeErr SDoc (ModIface, String))
    findAndReadIface (String -> SDoc
    text String
    "checkImplements 2") InstalledModule
    isig_mod Module
    sig_mod IsBootInterface
    NotBoot
        ModIface
    isig_iface <- case MaybeErr SDoc (ModIface, String)
    mb_isig_iface of
            Succeeded (ModIface
    iface, String
    _) -> forall (m :: * -> *) a. Monad m => a -> m a
    return ModIface
    iface
            Failed SDoc
    err -> forall a. SDoc -> TcM a
    failWithTc forall a b. (a -> b) -> a -> b
    $
                SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    text String
    "Could not find hi interface for signature" SDoc -> SDoc -> SDoc
    <+>
                      SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr InstalledModule
    isig_mod) SDoc -> SDoc -> SDoc
    <> SDoc
    colon) Int
    4 SDoc
    err

        -- STEP 3: Check that the implementing interface exports everything
        -- we need.  (Notice we IGNORE the Modules in the AvailInfos.)
        forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ ([AvailInfo] -> [OccName]
    exportOccs (forall (phase :: ModIfacePhase). ModIface_ phase -> [AvailInfo]
    mi_exports ModIface
    isig_iface)) forall a b. (a -> b) -> a -> b
    $ \OccName
    occ ->
            case GlobalRdrEnv -> OccName -> [GlobalRdrElt]
    lookupGlobalRdrEnv GlobalRdrEnv
    impl_gr OccName
    occ of
                [] -> SDoc -> TcRn ()
    addErr forall a b. (a -> b) -> a -> b
    $ SDoc -> SDoc
    quotes (forall a. Outputable a => a -> SDoc
    ppr OccName
    occ)
                        SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "is exported by the hsig file, but not exported by the implementing module"
                        SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (UnitState -> SDoc -> SDoc
    pprWithUnitState UnitState
    unit_state forall a b. (a -> b) -> a -> b
    $ forall a. Outputable a => a -> SDoc
    ppr Module
    impl_mod)
                [GlobalRdrElt]
    _ -> forall (m :: * -> *) a. Monad m => a -> m a
    return ()
        TcRn ()
    failIfErrsM

        -- STEP 4: Now that the export is complete, rename the interface...
        ModIface
    sig_iface <- GenInstantiations UnitId
    -> Maybe NameShape
    -> ModIface
    -> IOEnv (Env TcGblEnv TcLclEnv) ModIface
    tcRnModIface GenInstantiations UnitId
    insts (forall a. a -> Maybe a
    Just NameShape
    nsubst) ModIface
    isig_iface

        -- STEP 5: ...and typecheck it.  (Note that in both cases, the nsubst
        -- lets us determine how top-level identifiers should be handled.)
        ModDetails
    sig_details <- forall a. IfG a -> TcRn a
    initIfaceTcRn forall a b. (a -> b) -> a -> b
    $ forall lcl. NameShape -> ModIface -> IfM lcl ModDetails
    typecheckIfaceForInstantiate NameShape
    nsubst ModIface
    sig_iface

        -- STEP 6: Check that it's sufficient
        TcGblEnv
    tcg_env <- forall gbl lcl. TcRnIf gbl lcl gbl
    getGblEnv
        TcGblEnv -> GlobalRdrEnv -> ModIface -> ModDetails -> TcRn ()
    checkHsigIface TcGblEnv
    tcg_env GlobalRdrEnv
    impl_gr ModIface
    sig_iface ModDetails
    sig_details

        -- STEP 7: Return the updated 'TcGblEnv' with the signature exports,
        -- so we write them out.
        forall (m :: * -> *) a. Monad m => a -> m a
    return TcGblEnv
    tcg_env {
            tcg_exports :: [AvailInfo]
    tcg_exports = forall (phase :: ModIfacePhase). ModIface_ phase -> [AvailInfo]
    mi_exports ModIface
    sig_iface
            }

    -- | Given 'tcg_mod', instantiate a 'ModIface' from the indefinite
    -- library to use the actual implementations of the relevant entities,
    -- checking that the implementation matches the signature.
    instantiateSignature :: TcRn TcGblEnv
    instantiateSignature :: TcRn TcGblEnv
    instantiateSignature = do
        HscEnv
    hsc_env <- forall gbl lcl. TcRnIf gbl lcl HscEnv
    getTopEnv
        TcGblEnv
    tcg_env <- forall gbl lcl. TcRnIf gbl lcl gbl
    getGblEnv
        let outer_mod :: Module
    outer_mod = TcGblEnv -> Module
    tcg_mod TcGblEnv
    tcg_env
            inner_mod :: Module
    inner_mod = TcGblEnv -> Module
    tcg_semantic_mod TcGblEnv
    tcg_env
            home_unit :: HomeUnit
    home_unit = HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env
        -- TODO: setup the local RdrEnv so the error messages look a little better.
        -- But this information isn't stored anywhere. Should we RETYPECHECK
        -- the local one just to get the information?  Hmm...
        MASSERT( isHomeModule home_unit outer_mod )
        MASSERT( isHomeUnitInstantiating home_unit)
        let uid :: Indefinite UnitId
    uid = forall unit. unit -> Indefinite unit
    Indefinite (HomeUnit -> UnitId
    homeUnitInstanceOf HomeUnit
    home_unit)
        Module
    inner_mod Module -> InstantiatedModule -> TcRn TcGblEnv
    `checkImplements`
            forall u. u -> ModuleName -> GenModule u
    Module
                (forall u.
    IsUnitId u =>
    Indefinite u -> GenInstantiations u -> GenInstantiatedUnit u
    mkInstantiatedUnit Indefinite UnitId
    uid (forall u. GenHomeUnit u -> GenInstantiations u
    homeUnitInstantiations HomeUnit
    home_unit))
                (forall unit. GenModule unit -> ModuleName
    moduleName Module
    outer_mod)