    {-# LANGUAGE NamedFieldPuns #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE ViewPatterns #-}

    module GHC.Tc.Gen.Export (rnExports, exports_from_avail) where

    import GHC.Prelude

    import GHC.Hs
    import GHC.Builtin.Names
    import GHC.Types.Name.Reader
    import GHC.Tc.Utils.Monad
    import GHC.Tc.Utils.Env
    import GHC.Tc.Utils.TcType
    import GHC.Rename.Names
    import GHC.Rename.Env
    import GHC.Rename.Unbound ( reportUnboundName )
    import GHC.Utils.Error
    import GHC.Types.Id
    import GHC.Types.Id.Info
    import GHC.Unit.Module
    import GHC.Types.Name
    import GHC.Types.Name.Env
    import GHC.Types.Name.Set
    import GHC.Types.Avail
    import GHC.Core.TyCon
    import GHC.Types.SrcLoc as SrcLoc
    import GHC.Driver.Types
    import GHC.Utils.Outputable
    import GHC.Core.ConLike
    import GHC.Core.DataCon
    import GHC.Core.PatSyn
    import GHC.Data.Maybe
    import GHC.Types.Unique.Set
    import GHC.Utils.Misc (capitalise)
    import GHC.Data.FastString (fsLit)

    import Control.Monad
    import GHC.Driver.Session
    import GHC.Rename.Doc         ( rnHsDoc )
    import GHC.Parser.PostProcess ( setRdrNameSpace )
    import Data.Either            ( partitionEithers )

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Export list processing}
    *                                                                      *
    ************************************************************************

    Processing the export list.

    You might think that we should record things that appear in the export
    list as ``occurrences'' (using @addOccurrenceName@), but you'd be
    wrong.  We do check (here) that they are in scope, but there is no
    need to slurp in their actual declaration (which is what
    @addOccurrenceName@ forces).

    Indeed, doing so would big trouble when compiling @PrelBase@, because
    it re-exports @GHC@, which includes @takeMVar#@, whose type includes
    @ConcBase.StateAndSynchVar#@, and so on...

    Note [Exports of data families]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Suppose you see (#5306)
            module M where
              import X( F )
              data instance F Int = FInt
    What does M export?  AvailTC F [FInt]
                      or AvailTC F [F,FInt]?
    The former is strictly right because F isn't defined in this module.
    But then you can never do an explicit import of M, thus
        import M( F( FInt ) )
    because F isn't exported by M.  Nor can you import FInt alone from here
        import M( FInt )
    because we don't have syntax to support that.  (It looks like an import of
    the type FInt.)

    At one point I implemented a compromise:
      * When constructing exports with no export list, or with module M(
        module M ), we add the parent to the exports as well.
      * But not when you see module M( f ), even if f is a
        class method with a parent.
      * Nor when you see module M( module N ), with N /= M.

    But the compromise seemed too much of a hack, so we backed it out.
    You just have to use an explicit export list:
        module M( F(..) ) where ...

    Note [Avails of associated data families]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Suppose you have (#16077)

        {-# LANGUAGE TypeFamilies #-}
        module A (module A) where

        class    C a  where { data T a }
        instance C () where { data T () = D }

    Because @A@ is exported explicitly, GHC tries to produce an export list
    from the @GlobalRdrEnv@. In this case, it pulls out the following:

        [ C defined at A.hs:4:1
        , T parent:C defined at A.hs:4:23
        , D parent:T defined at A.hs:5:35 ]

    If map these directly into avails, (via 'availFromGRE'), we get
    @[C{C;}, C{T;}, T{D;}]@, which eventually gets merged into @[C{C, T;}, T{D;}]@.
    That's not right, because @T{D;}@ violates the AvailTC invariant: @T@ is
    exported, but it isn't the first entry in the avail!

    We work around this issue by expanding GREs where the parent and child
    are both type constructors into two GRES.

        T parent:C defined at A.hs:4:23

          =>

        [ T parent:C defined at A.hs:4:23
        , T defined at A.hs:4:23 ]

    Then, we get  @[C{C;}, C{T;}, T{T;}, T{D;}]@, which eventually gets merged
    into @[C{C, T;}, T{T, D;}]@ (which satsifies the AvailTC invariant).
    -}

    data ExportAccum        -- The type of the accumulating parameter of
                            -- the main worker function in rnExports
         = ExportAccum
            ExportOccMap           --  Tracks exported occurrence names
            (UniqSet ModuleName)   --  Tracks (re-)exported module names

    emptyExportAccum :: ExportAccum
    emptyExportAccum :: ExportAccum
    emptyExportAccum = ExportOccMap -> UniqSet ModuleName -> ExportAccum
    ExportAccum ExportOccMap
    forall a. OccEnv a
    emptyOccEnv UniqSet ModuleName
    forall a. UniqSet a
    emptyUniqSet

    accumExports :: (ExportAccum -> x -> TcRn (Maybe (ExportAccum, y)))
                 -> [x]
                 -> TcRn [y]
    accumExports :: forall x y.
    (ExportAccum -> x -> TcRn (Maybe (ExportAccum, y)))
    -> [x] -> TcRn [y]
    accumExports ExportAccum -> x -> TcRn (Maybe (ExportAccum, y))
    f = ((ExportAccum, [Maybe y]) -> [y])
    -> IOEnv (Env TcGblEnv TcLclEnv) (ExportAccum, [Maybe y])
    -> IOEnv (Env TcGblEnv TcLclEnv) [y]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ([Maybe y] -> [y]
    forall a. [Maybe a] -> [a]
    catMaybes ([Maybe y] -> [y])
    -> ((ExportAccum, [Maybe y]) -> [Maybe y])
    -> (ExportAccum, [Maybe y])
    -> [y]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ExportAccum, [Maybe y]) -> [Maybe y]
    forall a b. (a, b) -> b
    snd) (IOEnv (Env TcGblEnv TcLclEnv) (ExportAccum, [Maybe y])
     -> IOEnv (Env TcGblEnv TcLclEnv) [y])
    -> ([x] -> IOEnv (Env TcGblEnv TcLclEnv) (ExportAccum, [Maybe y]))
    -> [x]
    -> IOEnv (Env TcGblEnv TcLclEnv) [y]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ExportAccum
     -> x -> IOEnv (Env TcGblEnv TcLclEnv) (ExportAccum, Maybe y))
    -> ExportAccum
    -> [x]
    -> IOEnv (Env TcGblEnv TcLclEnv) (ExportAccum, [Maybe y])
    forall (m :: * -> *) acc x y.
    Monad m =>
    (acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
    mapAccumLM ExportAccum
    -> x -> IOEnv (Env TcGblEnv TcLclEnv) (ExportAccum, Maybe y)
    f' ExportAccum
    emptyExportAccum
      where f' :: ExportAccum
    -> x -> IOEnv (Env TcGblEnv TcLclEnv) (ExportAccum, Maybe y)
    f' ExportAccum
    acc x
    x = do
              Maybe (Maybe (ExportAccum, y))
    m <- TcRn (Maybe (ExportAccum, y))
    -> TcRn (Maybe (Maybe (ExportAccum, y)))
    forall r. TcRn r -> TcRn (Maybe r)
    attemptM (ExportAccum -> x -> TcRn (Maybe (ExportAccum, y))
    f ExportAccum
    acc x
    x)
              (ExportAccum, Maybe y)
    -> IOEnv (Env TcGblEnv TcLclEnv) (ExportAccum, Maybe y)
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ((ExportAccum, Maybe y)
     -> IOEnv (Env TcGblEnv TcLclEnv) (ExportAccum, Maybe y))
    -> (ExportAccum, Maybe y)
    -> IOEnv (Env TcGblEnv TcLclEnv) (ExportAccum, Maybe y)
    forall a b. (a -> b) -> a -> b
    $ case Maybe (Maybe (ExportAccum, y))
    m of
                Just (Just (ExportAccum
    acc', y
    y)) -> (ExportAccum
    acc', y -> Maybe y
    forall a. a -> Maybe a
    Just y
    y)
                Maybe (Maybe (ExportAccum, y))
    _                     -> (ExportAccum
    acc, Maybe y
    forall a. Maybe a
    Nothing)

    type ExportOccMap = OccEnv (Name, IE GhcPs)
            -- Tracks what a particular exported OccName
            --   in an export list refers to, and which item
            --   it came from.  It's illegal to export two distinct things
            --   that have the same occurrence name

    rnExports :: Bool       -- False => no 'module M(..) where' header at all
              -> Maybe (Located [LIE GhcPs]) -- Nothing => no explicit export list
              -> RnM TcGblEnv

            -- Complains if two distinct exports have same OccName
            -- Warns about identical exports.
            -- Complains about exports items not in scope

    rnExports :: Bool -> Maybe (Located [LIE GhcPs]) -> RnM TcGblEnv
    rnExports Bool
    explicit_mod Maybe (Located [LIE GhcPs])
    exports
     = RnM TcGblEnv -> RnM TcGblEnv
    forall r. TcM r -> TcM r
    checkNoErrs (RnM TcGblEnv -> RnM TcGblEnv) -> RnM TcGblEnv -> RnM TcGblEnv
    forall a b. (a -> b) -> a -> b
    $   -- Fail if anything in rnExports finds
                       -- an error fails, to avoid error cascade
       WarningFlag -> RnM TcGblEnv -> RnM TcGblEnv
    forall gbl lcl a.
    WarningFlag -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
    unsetWOptM WarningFlag
    Opt_WarnWarningsDeprecations (RnM TcGblEnv -> RnM TcGblEnv) -> RnM TcGblEnv -> RnM TcGblEnv
    forall a b. (a -> b) -> a -> b
    $
           -- Do not report deprecations arising from the export
           -- list, to avoid bleating about re-exporting a deprecated
           -- thing (especially via 'module Foo' export item)
       do   { DynFlags
    dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
            ; TcGblEnv
    tcg_env <- RnM TcGblEnv
    forall gbl lcl. TcRnIf gbl lcl gbl
    getGblEnv
            ; let TcGblEnv { tcg_mod :: TcGblEnv -> Module
    tcg_mod     = Module
    this_mod
                           , tcg_rdr_env :: TcGblEnv -> GlobalRdrEnv
    tcg_rdr_env = GlobalRdrEnv
    rdr_env
                           , tcg_imports :: TcGblEnv -> ImportAvails
    tcg_imports = ImportAvails
    imports
                           , tcg_src :: TcGblEnv -> HscSource
    tcg_src     = HscSource
    hsc_src } = TcGblEnv
    tcg_env
                  default_main :: RdrName
    default_main | DynFlags -> Module
    mainModIs DynFlags
    dflags Module -> Module -> Bool
    forall a. Eq a => a -> a -> Bool
    == Module
    this_mod
                               , Just String
    main_fun <- DynFlags -> Maybe String
    mainFunIs DynFlags
    dflags
                               = NameSpace -> FastString -> RdrName
    mkUnqual NameSpace
    varName (String -> FastString
    fsLit String
    main_fun)
                               | Bool
    otherwise
                               = RdrName
    main_RDR_Unqual
            ; Bool
    has_main <- (Bool -> Bool
    not (Bool -> Bool) -> ([Name] -> Bool) -> [Name] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Name] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null) ([Name] -> Bool)
    -> IOEnv (Env TcGblEnv TcLclEnv) [Name]
    -> IOEnv (Env TcGblEnv TcLclEnv) Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> RdrName -> IOEnv (Env TcGblEnv TcLclEnv) [Name]
    lookupInfoOccRn RdrName
    default_main -- #17832

            -- If a module has no explicit header, and it has one or more main
            -- functions in scope, then add a header like
            -- "module Main(main) where ..."                               #13839
            -- See Note [Modules without a module header]
            ; let real_exports :: Maybe (Located [LIE GhcPs])
    real_exports
                     | Bool
    explicit_mod = Maybe (Located [LIE GhcPs])
    exports
                     | Bool
    has_main = Located [LIE GhcPs] -> Maybe (Located [LIE GhcPs])
    forall a. a -> Maybe a
    Just ([LIE GhcPs] -> Located [LIE GhcPs]
    forall e. e -> Located e
    noLoc [IE GhcPs -> LIE GhcPs
    forall e. e -> Located e
    noLoc (XIEVar GhcPs -> LIEWrappedName (IdP GhcPs) -> IE GhcPs
    forall pass. XIEVar pass -> LIEWrappedName (IdP pass) -> IE pass
    IEVar NoExtField
    XIEVar GhcPs
    noExtField
                                         (IEWrappedName RdrName -> Located (IEWrappedName RdrName)
    forall e. e -> Located e
    noLoc (Located RdrName -> IEWrappedName RdrName
    forall name. Located name -> IEWrappedName name
    IEName (Located RdrName -> IEWrappedName RdrName)
    -> Located RdrName -> IEWrappedName RdrName
    forall a b. (a -> b) -> a -> b
    $ RdrName -> Located RdrName
    forall e. e -> Located e
    noLoc RdrName
    default_main)))])
                                  -- ToDo: the 'noLoc' here is unhelpful if 'main'
                                  --       turns out to be out of scope
                     | Bool
    otherwise = Maybe (Located [LIE GhcPs])
    forall a. Maybe a
    Nothing

            -- Rename the export list
            ; let do_it :: RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    do_it = Maybe (Located [LIE GhcPs])
    -> GlobalRdrEnv
    -> ImportAvails
    -> Module
    -> RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    exports_from_avail Maybe (Located [LIE GhcPs])
    real_exports GlobalRdrEnv
    rdr_env ImportAvails
    imports Module
    this_mod
            ; (Maybe [(LIE GhcRn, [AvailInfo])]
    rn_exports, [AvailInfo]
    final_avails)
                <- if HscSource
    hsc_src HscSource -> HscSource -> Bool
    forall a. Eq a => a -> a -> Bool
    == HscSource
    HsigFile
                    then do (Maybe (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    mb_r, Messages
    msgs) <- RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    -> TcRn
         (Maybe (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo]), Messages)
    forall a. TcRn a -> TcRn (Maybe a, Messages)
    tryTc RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    do_it
                            case Maybe (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    mb_r of
                                Just (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    r  -> (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    -> RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    r
                                Maybe (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    Nothing -> Messages -> TcRn ()
    addMessages Messages
    msgs TcRn ()
    -> RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    -> RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    forall env a. IOEnv env a
    failM
                    else RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    -> RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    forall r. TcM r -> TcM r
    checkNoErrs RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    do_it

            -- Final processing
            ; let final_ns :: NameSet
    final_ns = [AvailInfo] -> NameSet
    availsToNameSetWithSelectors [AvailInfo]
    final_avails

            ; String -> SDoc -> TcRn ()
    traceRn String
    "rnExports: Exports:" ([AvailInfo] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [AvailInfo]
    final_avails)

            ; TcGblEnv -> RnM TcGblEnv
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TcGblEnv
    tcg_env { tcg_exports :: [AvailInfo]
    tcg_exports    = [AvailInfo]
    final_avails
                              , tcg_rn_exports :: Maybe [(LIE GhcRn, [AvailInfo])]
    tcg_rn_exports = case TcGblEnv -> Maybe [(LIE GhcRn, [AvailInfo])]
    tcg_rn_exports TcGblEnv
    tcg_env of
                                                    Maybe [(LIE GhcRn, [AvailInfo])]
    Nothing -> Maybe [(LIE GhcRn, [AvailInfo])]
    forall a. Maybe a
    Nothing
                                                    Just [(LIE GhcRn, [AvailInfo])]
    _  -> Maybe [(LIE GhcRn, [AvailInfo])]
    rn_exports
                              , tcg_dus :: DefUses
    tcg_dus = TcGblEnv -> DefUses
    tcg_dus TcGblEnv
    tcg_env DefUses -> DefUses -> DefUses
    `plusDU`
                                          NameSet -> DefUses
    usesOnly NameSet
    final_ns }) }

    exports_from_avail :: Maybe (Located [LIE GhcPs])
                             -- ^ 'Nothing' means no explicit export list
                       -> GlobalRdrEnv
                       -> ImportAvails
                             -- ^ Imported modules; this is used to test if a
                             -- @module Foo@ export is valid (it's not valid
                             -- if we didn't import @Foo@!)
                       -> Module
                       -> RnM (Maybe [(LIE GhcRn, Avails)], Avails)
                             -- (Nothing, _) <=> no explicit export list
                             -- if explicit export list is present it contains
                             -- each renamed export item together with its exported
                             -- names.

    exports_from_avail :: Maybe (Located [LIE GhcPs])
    -> GlobalRdrEnv
    -> ImportAvails
    -> Module
    -> RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    exports_from_avail Maybe (Located [LIE GhcPs])
    Nothing GlobalRdrEnv
    rdr_env ImportAvails
    _imports Module
    _this_mod
       -- The same as (module M) where M is the current module name,
       -- so that's how we handle it, except we also export the data family
       -- when a data instance is exported.
      = do {
        ; Bool
    warnMissingExportList <- WarningFlag -> IOEnv (Env TcGblEnv TcLclEnv) Bool
    forall gbl lcl. WarningFlag -> TcRnIf gbl lcl Bool
    woptM WarningFlag
    Opt_WarnMissingExportList
        ; WarningFlag -> Bool -> SDoc -> TcRn ()
    warnIfFlag WarningFlag
    Opt_WarnMissingExportList
            Bool
    warnMissingExportList
            (ModuleName -> SDoc
    missingModuleExportWarn (ModuleName -> SDoc) -> ModuleName -> SDoc
    forall a b. (a -> b) -> a -> b
    $ Module -> ModuleName
    forall unit. GenModule unit -> ModuleName
    moduleName Module
    _this_mod)
        ; let avails :: [AvailInfo]
    avails =
                (AvailInfo -> AvailInfo) -> [AvailInfo] -> [AvailInfo]
    forall a b. (a -> b) -> [a] -> [b]
    map AvailInfo -> AvailInfo
    fix_faminst ([AvailInfo] -> [AvailInfo])
    -> (GlobalRdrEnv -> [AvailInfo]) -> GlobalRdrEnv -> [AvailInfo]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [GlobalRdrElt] -> [AvailInfo]
    gresToAvailInfo
                  ([GlobalRdrElt] -> [AvailInfo])
    -> (GlobalRdrEnv -> [GlobalRdrElt]) -> GlobalRdrEnv -> [AvailInfo]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (GlobalRdrElt -> Bool) -> [GlobalRdrElt] -> [GlobalRdrElt]
    forall a. (a -> Bool) -> [a] -> [a]
    filter GlobalRdrElt -> Bool
    isLocalGRE ([GlobalRdrElt] -> [GlobalRdrElt])
    -> (GlobalRdrEnv -> [GlobalRdrElt])
    -> GlobalRdrEnv
    -> [GlobalRdrElt]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GlobalRdrEnv -> [GlobalRdrElt]
    globalRdrEnvElts (GlobalRdrEnv -> [AvailInfo]) -> GlobalRdrEnv -> [AvailInfo]
    forall a b. (a -> b) -> a -> b
    $ GlobalRdrEnv
    rdr_env
        ; (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    -> RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe [(LIE GhcRn, [AvailInfo])]
    forall a. Maybe a
    Nothing, [AvailInfo]
    avails) }
      where
        -- #11164: when we define a data instance
        -- but not data family, re-export the family
        -- Even though we don't check whether this is actually a data family
        -- only data families can locally define subordinate things (`ns` here)
        -- without locally defining (and instead importing) the parent (`n`)
        fix_faminst :: AvailInfo -> AvailInfo
    fix_faminst (AvailTC Name
    n [Name]
    ns [FieldLabel]
    flds) =
          let new_ns :: [Name]
    new_ns =
                case [Name]
    ns of
                  [] -> [Name
    n]
                  (Name
    p:[Name]
    _) -> if Name
    p Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    n then [Name]
    ns else Name
    nName -> [Name] -> [Name]
    forall a. a -> [a] -> [a]
    :[Name]
    ns
          in Name -> [Name] -> [FieldLabel] -> AvailInfo
    AvailTC Name
    n [Name]
    new_ns [FieldLabel]
    flds

        fix_faminst AvailInfo
    avail = AvailInfo
    avail

    exports_from_avail (Just (L SrcSpan
    _ [LIE GhcPs]
    rdr_items)) GlobalRdrEnv
    rdr_env ImportAvails
    imports Module
    this_mod
      = do [(LIE GhcRn, [AvailInfo])]
    ie_avails <- (ExportAccum
     -> LIE GhcPs
     -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo]))))
    -> [LIE GhcPs] -> TcRn [(LIE GhcRn, [AvailInfo])]
    forall x y.
    (ExportAccum -> x -> TcRn (Maybe (ExportAccum, y)))
    -> [x] -> TcRn [y]
    accumExports ExportAccum
    -> LIE GhcPs
    -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo])))
    do_litem [LIE GhcPs]
    rdr_items
           let final_exports :: [AvailInfo]
    final_exports = [AvailInfo] -> [AvailInfo]
    nubAvails (((LIE GhcRn, [AvailInfo]) -> [AvailInfo])
    -> [(LIE GhcRn, [AvailInfo])] -> [AvailInfo]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (LIE GhcRn, [AvailInfo]) -> [AvailInfo]
    forall a b. (a, b) -> b
    snd [(LIE GhcRn, [AvailInfo])]
    ie_avails) -- Combine families
           (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    -> RnM (Maybe [(LIE GhcRn, [AvailInfo])], [AvailInfo])
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([(LIE GhcRn, [AvailInfo])] -> Maybe [(LIE GhcRn, [AvailInfo])]
    forall a. a -> Maybe a
    Just [(LIE GhcRn, [AvailInfo])]
    ie_avails, [AvailInfo]
    final_exports)
      where
        do_litem :: ExportAccum -> LIE GhcPs
                 -> RnM (Maybe (ExportAccum, (LIE GhcRn, Avails)))
        do_litem :: ExportAccum
    -> LIE GhcPs
    -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo])))
    do_litem ExportAccum
    acc LIE GhcPs
    lie = SrcSpan
    -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo])))
    -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo])))
    forall a. SrcSpan -> TcRn a -> TcRn a
    setSrcSpan (LIE GhcPs -> SrcSpan
    forall l e. GenLocated l e -> l
    getLoc LIE GhcPs
    lie) (ExportAccum
    -> LIE GhcPs
    -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo])))
    exports_from_item ExportAccum
    acc LIE GhcPs
    lie)

        -- Maps a parent to its in-scope children
        kids_env :: NameEnv [GlobalRdrElt]
        kids_env :: NameEnv [GlobalRdrElt]
    kids_env = [GlobalRdrElt] -> NameEnv [GlobalRdrElt]
    mkChildEnv (GlobalRdrEnv -> [GlobalRdrElt]
    globalRdrEnvElts GlobalRdrEnv
    rdr_env)

        -- See Note [Avails of associated data families]
        expand_tyty_gre :: GlobalRdrElt -> [GlobalRdrElt]
        expand_tyty_gre :: GlobalRdrElt -> [GlobalRdrElt]
    expand_tyty_gre (gre :: GlobalRdrElt
    gre@GRE { gre_name :: GlobalRdrElt -> Name
    gre_name = Name
    me, gre_par :: GlobalRdrElt -> Parent
    gre_par = ParentIs Name
    p })
          | Name -> Bool
    isTyConName Name
    p, Name -> Bool
    isTyConName Name
    me = [GlobalRdrElt
    gre, GlobalRdrElt
    gre{ gre_par :: Parent
    gre_par = Parent
    NoParent }]
        expand_tyty_gre GlobalRdrElt
    gre = [GlobalRdrElt
    gre]

        imported_modules :: [ModuleName]
    imported_modules = [ ImportedModsVal -> ModuleName
    imv_name ImportedModsVal
    imv
                           | [ImportedBy]
    xs <- ModuleEnv [ImportedBy] -> [[ImportedBy]]
    forall a. ModuleEnv a -> [a]
    moduleEnvElts (ModuleEnv [ImportedBy] -> [[ImportedBy]])
    -> ModuleEnv [ImportedBy] -> [[ImportedBy]]
    forall a b. (a -> b) -> a -> b
    $ ImportAvails -> ModuleEnv [ImportedBy]
    imp_mods ImportAvails
    imports
                           , ImportedModsVal
    imv <- [ImportedBy] -> [ImportedModsVal]
    importedByUser [ImportedBy]
    xs ]

        exports_from_item :: ExportAccum -> LIE GhcPs
                          -> RnM (Maybe (ExportAccum, (LIE GhcRn, Avails)))
        exports_from_item :: ExportAccum
    -> LIE GhcPs
    -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo])))
    exports_from_item (ExportAccum ExportOccMap
    occs UniqSet ModuleName
    earlier_mods)
                          (L SrcSpan
    loc ie :: IE GhcPs
    ie@(IEModuleContents XIEModuleContents GhcPs
    _ lmod :: Located ModuleName
    lmod@(L SrcSpan
    _ ModuleName
    mod)))
            | ModuleName
    mod ModuleName -> UniqSet ModuleName -> Bool
    forall a. Uniquable a => a -> UniqSet a -> Bool
    `elementOfUniqSet` UniqSet ModuleName
    earlier_mods    -- Duplicate export of M
            = do { WarningFlag -> Bool -> SDoc -> TcRn ()
    warnIfFlag WarningFlag
    Opt_WarnDuplicateExports Bool
    True
                              (ModuleName -> SDoc
    dupModuleExport ModuleName
    mod) ;
                   Maybe (ExportAccum, (LIE GhcRn, [AvailInfo]))
    -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo])))
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (ExportAccum, (LIE GhcRn, [AvailInfo]))
    forall a. Maybe a
    Nothing }

            | Bool
    otherwise
            = do { let { exportValid :: Bool
    exportValid = (ModuleName
    mod ModuleName -> [ModuleName] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [ModuleName]
    imported_modules)
                                    Bool -> Bool -> Bool
    || (Module -> ModuleName
    forall unit. GenModule unit -> ModuleName
    moduleName Module
    this_mod ModuleName -> ModuleName -> Bool
    forall a. Eq a => a -> a -> Bool
    == ModuleName
    mod)
                       ; gre_prs :: [(GlobalRdrElt, GlobalRdrElt)]
    gre_prs     = ModuleName -> [GlobalRdrElt] -> [(GlobalRdrElt, GlobalRdrElt)]
    pickGREsModExp ModuleName
    mod (GlobalRdrEnv -> [GlobalRdrElt]
    globalRdrEnvElts GlobalRdrEnv
    rdr_env)
                       ; new_exports :: [AvailInfo]
    new_exports = [ GlobalRdrElt -> AvailInfo
    availFromGRE GlobalRdrElt
    gre'
                                       | (GlobalRdrElt
    gre, GlobalRdrElt
    _) <- [(GlobalRdrElt, GlobalRdrElt)]
    gre_prs
                                       , GlobalRdrElt
    gre' <- GlobalRdrElt -> [GlobalRdrElt]
    expand_tyty_gre GlobalRdrElt
    gre ]
                       ; all_gres :: [GlobalRdrElt]
    all_gres    = ((GlobalRdrElt, GlobalRdrElt) -> [GlobalRdrElt] -> [GlobalRdrElt])
    -> [GlobalRdrElt]
    -> [(GlobalRdrElt, GlobalRdrElt)]
    -> [GlobalRdrElt]
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\(GlobalRdrElt
    gre1,GlobalRdrElt
    gre2) [GlobalRdrElt]
    gres -> GlobalRdrElt
    gre1 GlobalRdrElt -> [GlobalRdrElt] -> [GlobalRdrElt]
    forall a. a -> [a] -> [a]
    : GlobalRdrElt
    gre2 GlobalRdrElt -> [GlobalRdrElt] -> [GlobalRdrElt]
    forall a. a -> [a] -> [a]
    : [GlobalRdrElt]
    gres) [] [(GlobalRdrElt, GlobalRdrElt)]
    gre_prs
                       ; mods :: UniqSet ModuleName
    mods        = UniqSet ModuleName -> ModuleName -> UniqSet ModuleName
    forall a. Uniquable a => UniqSet a -> a -> UniqSet a
    addOneToUniqSet UniqSet ModuleName
    earlier_mods ModuleName
    mod
                       }

                 ; Bool -> SDoc -> TcRn ()
    checkErr Bool
    exportValid (ModuleName -> SDoc
    moduleNotImported ModuleName
    mod)
                 ; WarningFlag -> Bool -> SDoc -> TcRn ()
    warnIfFlag WarningFlag
    Opt_WarnDodgyExports
                              (Bool
    exportValid Bool -> Bool -> Bool
    && [(GlobalRdrElt, GlobalRdrElt)] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [(GlobalRdrElt, GlobalRdrElt)]
    gre_prs)
                              (ModuleName -> SDoc
    nullModuleExport ModuleName
    mod)

                 ; String -> SDoc -> TcRn ()
    traceRn String
    "efa" (ModuleName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod SDoc -> SDoc -> SDoc
    $$ [GlobalRdrElt] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [GlobalRdrElt]
    all_gres)
                 ; [GlobalRdrElt] -> TcRn ()
    addUsedGREs [GlobalRdrElt]
    all_gres

                 ; ExportOccMap
    occs' <- IE GhcPs -> ExportOccMap -> [AvailInfo] -> RnM ExportOccMap
    check_occs IE GhcPs
    ie ExportOccMap
    occs [AvailInfo]
    new_exports
                          -- This check_occs not only finds conflicts
                          -- between this item and others, but also
                          -- internally within this item.  That is, if
                          -- 'M.x' is in scope in several ways, we'll have
                          -- several members of mod_avails with the same
                          -- OccName.
                 ; String -> SDoc -> TcRn ()
    traceRn String
    "export_mod"
                           ([SDoc] -> SDoc
    vcat [ ModuleName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod
                                 , [AvailInfo] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [AvailInfo]
    new_exports ])

                 ; Maybe (ExportAccum, (LIE GhcRn, [AvailInfo]))
    -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo])))
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((ExportAccum, (LIE GhcRn, [AvailInfo]))
    -> Maybe (ExportAccum, (LIE GhcRn, [AvailInfo]))
    forall a. a -> Maybe a
    Just ( ExportOccMap -> UniqSet ModuleName -> ExportAccum
    ExportAccum ExportOccMap
    occs' UniqSet ModuleName
    mods
                                , ( SrcSpan -> IE GhcRn -> LIE GhcRn
    forall l e. l -> e -> GenLocated l e
    L SrcSpan
    loc (XIEModuleContents GhcRn -> Located ModuleName -> IE GhcRn
    forall pass.
    XIEModuleContents pass -> Located ModuleName -> IE pass
    IEModuleContents NoExtField
    XIEModuleContents GhcRn
    noExtField Located ModuleName
    lmod)
                                  , [AvailInfo]
    new_exports))) }

        exports_from_item acc :: ExportAccum
    acc@(ExportAccum ExportOccMap
    occs UniqSet ModuleName
    mods) (L SrcSpan
    loc IE GhcPs
    ie)
            | IE GhcPs -> Bool
    isDoc IE GhcPs
    ie
            = do IE GhcRn
    new_ie <- IE GhcPs -> RnM (IE GhcRn)
    lookup_doc_ie IE GhcPs
    ie
                 Maybe (ExportAccum, (LIE GhcRn, [AvailInfo]))
    -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo])))
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((ExportAccum, (LIE GhcRn, [AvailInfo]))
    -> Maybe (ExportAccum, (LIE GhcRn, [AvailInfo]))
    forall a. a -> Maybe a
    Just (ExportAccum
    acc, (SrcSpan -> IE GhcRn -> LIE GhcRn
    forall l e. l -> e -> GenLocated l e
    L SrcSpan
    loc IE GhcRn
    new_ie, [])))

            | Bool
    otherwise
            = do (IE GhcRn
    new_ie, AvailInfo
    avail) <- IE GhcPs -> RnM (IE GhcRn, AvailInfo)
    lookup_ie IE GhcPs
    ie
                 if Name -> Bool
    isUnboundName (IE GhcRn -> IdP GhcRn
    forall (p :: Pass). IE (GhcPass p) -> IdP (GhcPass p)
    ieName IE GhcRn
    new_ie)
                      then Maybe (ExportAccum, (LIE GhcRn, [AvailInfo]))
    -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo])))
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (ExportAccum, (LIE GhcRn, [AvailInfo]))
    forall a. Maybe a
    Nothing    -- Avoid error cascade
                      else do

                        ExportOccMap
    occs' <- IE GhcPs -> ExportOccMap -> [AvailInfo] -> RnM ExportOccMap
    check_occs IE GhcPs
    ie ExportOccMap
    occs [AvailInfo
    avail]

                        Maybe (ExportAccum, (LIE GhcRn, [AvailInfo]))
    -> TcRn (Maybe (ExportAccum, (LIE GhcRn, [AvailInfo])))
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((ExportAccum, (LIE GhcRn, [AvailInfo]))
    -> Maybe (ExportAccum, (LIE GhcRn, [AvailInfo]))
    forall a. a -> Maybe a
    Just ( ExportOccMap -> UniqSet ModuleName -> ExportAccum
    ExportAccum ExportOccMap
    occs' UniqSet ModuleName
    mods
                                     , (SrcSpan -> IE GhcRn -> LIE GhcRn
    forall l e. l -> e -> GenLocated l e
    L SrcSpan
    loc IE GhcRn
    new_ie, [AvailInfo
    avail])))

        -------------
        lookup_ie :: IE GhcPs -> RnM (IE GhcRn, AvailInfo)
        lookup_ie :: IE GhcPs -> RnM (IE GhcRn, AvailInfo)
    lookup_ie (IEVar XIEVar GhcPs
    _ (L SrcSpan
    l IEWrappedName (IdP GhcPs)
    rdr))
            = do (Name
    name, AvailInfo
    avail) <- RdrName -> RnM (Name, AvailInfo)
    lookupGreAvailRn (RdrName -> RnM (Name, AvailInfo))
    -> RdrName -> RnM (Name, AvailInfo)
    forall a b. (a -> b) -> a -> b
    $ IEWrappedName RdrName -> RdrName
    forall name. IEWrappedName name -> name
    ieWrappedName IEWrappedName RdrName
    IEWrappedName (IdP GhcPs)
    rdr
                 (IE GhcRn, AvailInfo) -> RnM (IE GhcRn, AvailInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (XIEVar GhcRn -> LIEWrappedName (IdP GhcRn) -> IE GhcRn
    forall pass. XIEVar pass -> LIEWrappedName (IdP pass) -> IE pass
    IEVar NoExtField
    XIEVar GhcRn
    noExtField (SrcSpan
    -> IEWrappedName Name -> GenLocated SrcSpan (IEWrappedName Name)
    forall l e. l -> e -> GenLocated l e
    L SrcSpan
    l (IEWrappedName RdrName -> Name -> IEWrappedName Name
    forall name1 name2.
    IEWrappedName name1 -> name2 -> IEWrappedName name2
    replaceWrappedName IEWrappedName RdrName
    IEWrappedName (IdP GhcPs)
    rdr Name
    name)), AvailInfo
    avail)

        lookup_ie (IEThingAbs XIEThingAbs GhcPs
    _ (L SrcSpan
    l IEWrappedName (IdP GhcPs)
    rdr))
            = do (Name
    name, AvailInfo
    avail) <- RdrName -> RnM (Name, AvailInfo)
    lookupGreAvailRn (RdrName -> RnM (Name, AvailInfo))
    -> RdrName -> RnM (Name, AvailInfo)
    forall a b. (a -> b) -> a -> b
    $ IEWrappedName RdrName -> RdrName
    forall name. IEWrappedName name -> name
    ieWrappedName IEWrappedName RdrName
    IEWrappedName (IdP GhcPs)
    rdr
                 (IE GhcRn, AvailInfo) -> RnM (IE GhcRn, AvailInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (XIEThingAbs GhcRn -> LIEWrappedName (IdP GhcRn) -> IE GhcRn
    forall pass.
    XIEThingAbs pass -> LIEWrappedName (IdP pass) -> IE pass
    IEThingAbs NoExtField
    XIEThingAbs GhcRn
    noExtField (SrcSpan
    -> IEWrappedName Name -> GenLocated SrcSpan (IEWrappedName Name)
    forall l e. l -> e -> GenLocated l e
    L SrcSpan
    l (IEWrappedName RdrName -> Name -> IEWrappedName Name
    forall name1 name2.
    IEWrappedName name1 -> name2 -> IEWrappedName name2
    replaceWrappedName IEWrappedName RdrName
    IEWrappedName (IdP GhcPs)
    rdr Name
    name))
                        , AvailInfo
    avail)

        lookup_ie ie :: IE GhcPs
    ie@(IEThingAll XIEThingAll GhcPs
    _ LIEWrappedName (IdP GhcPs)
    n')
            = do
                (Located Name
    n, [Name]
    avail, [FieldLabel]
    flds) <- IE GhcPs
    -> Located (IEWrappedName RdrName)
    -> RnM (Located Name, [Name], [FieldLabel])
    lookup_ie_all IE GhcPs
    ie Located (IEWrappedName RdrName)
    LIEWrappedName (IdP GhcPs)
    n'
                let name :: Name
    name = Located Name -> Name
    forall l e. GenLocated l e -> e
    unLoc Located Name
    n
                (IE GhcRn, AvailInfo) -> RnM (IE GhcRn, AvailInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (XIEThingAll GhcRn -> LIEWrappedName (IdP GhcRn) -> IE GhcRn
    forall pass.
    XIEThingAll pass -> LIEWrappedName (IdP pass) -> IE pass
    IEThingAll NoExtField
    XIEThingAll GhcRn
    noExtField (Located (IEWrappedName RdrName)
    -> Name -> GenLocated SrcSpan (IEWrappedName Name)
    forall name1 name2.
    LIEWrappedName name1 -> name2 -> LIEWrappedName name2
    replaceLWrappedName Located (IEWrappedName RdrName)
    LIEWrappedName (IdP GhcPs)
    n' (Located Name -> Name
    forall l e. GenLocated l e -> e
    unLoc Located Name
    n))
                       , Name -> [Name] -> [FieldLabel] -> AvailInfo
    AvailTC Name
    name (Name
    nameName -> [Name] -> [Name]
    forall a. a -> [a] -> [a]
    :[Name]
    avail) [FieldLabel]
    flds)

        lookup_ie ie :: IE GhcPs
    ie@(IEThingWith XIEThingWith GhcPs
    _ LIEWrappedName (IdP GhcPs)
    l IEWildcard
    wc [LIEWrappedName (IdP GhcPs)]
    sub_rdrs [Located (FieldLbl (IdP GhcPs))]
    _)
            = do
                (Located Name
    lname, [GenLocated SrcSpan (IEWrappedName Name)]
    subs, [Name]
    avails, [Located FieldLabel]
    flds)
                  <- IE GhcPs
    -> TcM
         (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
          [Located FieldLabel])
    -> TcM
         (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
          [Located FieldLabel])
    forall (p :: Pass) a.
    OutputableBndrId p =>
    IE (GhcPass p) -> TcM a -> TcM a
    addExportErrCtxt IE GhcPs
    ie (TcM
       (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
        [Located FieldLabel])
     -> TcM
          (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
           [Located FieldLabel]))
    -> TcM
         (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
          [Located FieldLabel])
    -> TcM
         (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
          [Located FieldLabel])
    forall a b. (a -> b) -> a -> b
    $ Located (IEWrappedName RdrName)
    -> [Located (IEWrappedName RdrName)]
    -> TcM
         (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
          [Located FieldLabel])
    lookup_ie_with Located (IEWrappedName RdrName)
    LIEWrappedName (IdP GhcPs)
    l [Located (IEWrappedName RdrName)]
    [LIEWrappedName (IdP GhcPs)]
    sub_rdrs
                (Located Name
    _, [Name]
    all_avail, [FieldLabel]
    all_flds) <-
                  case IEWildcard
    wc of
                    IEWildcard
    NoIEWildcard -> (Located Name, [Name], [FieldLabel])
    -> RnM (Located Name, [Name], [FieldLabel])
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Located Name
    lname, [], [])
                    IEWildcard Int
    _ -> IE GhcPs
    -> Located (IEWrappedName RdrName)
    -> RnM (Located Name, [Name], [FieldLabel])
    lookup_ie_all IE GhcPs
    ie Located (IEWrappedName RdrName)
    LIEWrappedName (IdP GhcPs)
    l
                let name :: Name
    name = Located Name -> Name
    forall l e. GenLocated l e -> e
    unLoc Located Name
    lname
                (IE GhcRn, AvailInfo) -> RnM (IE GhcRn, AvailInfo)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (XIEThingWith GhcRn
    -> LIEWrappedName (IdP GhcRn)
    -> IEWildcard
    -> [LIEWrappedName (IdP GhcRn)]
    -> [Located (FieldLbl (IdP GhcRn))]
    -> IE GhcRn
    forall pass.
    XIEThingWith pass
    -> LIEWrappedName (IdP pass)
    -> IEWildcard
    -> [LIEWrappedName (IdP pass)]
    -> [Located (FieldLbl (IdP pass))]
    -> IE pass
    IEThingWith NoExtField
    XIEThingWith GhcRn
    noExtField (Located (IEWrappedName RdrName)
    -> Name -> GenLocated SrcSpan (IEWrappedName Name)
    forall name1 name2.
    LIEWrappedName name1 -> name2 -> LIEWrappedName name2
    replaceLWrappedName Located (IEWrappedName RdrName)
    LIEWrappedName (IdP GhcPs)
    l Name
    name) IEWildcard
    wc [GenLocated SrcSpan (IEWrappedName Name)]
    [LIEWrappedName (IdP GhcRn)]
    subs
                                    ([Located FieldLabel]
    flds [Located FieldLabel]
    -> [Located FieldLabel] -> [Located FieldLabel]
    forall a. [a] -> [a] -> [a]
    ++ ((FieldLabel -> Located FieldLabel)
    -> [FieldLabel] -> [Located FieldLabel]
    forall a b. (a -> b) -> [a] -> [b]
    map FieldLabel -> Located FieldLabel
    forall e. e -> Located e
    noLoc [FieldLabel]
    all_flds)),
                        Name -> [Name] -> [FieldLabel] -> AvailInfo
    AvailTC Name
    name (Name
    name Name -> [Name] -> [Name]
    forall a. a -> [a] -> [a]
    : [Name]
    avails [Name] -> [Name] -> [Name]
    forall a. [a] -> [a] -> [a]
    ++ [Name]
    all_avail)
                                     ((Located FieldLabel -> FieldLabel)
    -> [Located FieldLabel] -> [FieldLabel]
    forall a b. (a -> b) -> [a] -> [b]
    map Located FieldLabel -> FieldLabel
    forall l e. GenLocated l e -> e
    unLoc [Located FieldLabel]
    flds [FieldLabel] -> [FieldLabel] -> [FieldLabel]
    forall a. [a] -> [a] -> [a]
    ++ [FieldLabel]
    all_flds))

        lookup_ie IE GhcPs
    _ = String -> RnM (IE GhcRn, AvailInfo)
    forall a. String -> a
    panic String
    "lookup_ie"    -- Other cases covered earlier

        lookup_ie_with :: LIEWrappedName RdrName -> [LIEWrappedName RdrName]
                       -> RnM (Located Name, [LIEWrappedName Name], [Name],
                               [Located FieldLabel])
        lookup_ie_with :: Located (IEWrappedName RdrName)
    -> [Located (IEWrappedName RdrName)]
    -> TcM
         (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
          [Located FieldLabel])
    lookup_ie_with (L SrcSpan
    l IEWrappedName RdrName
    rdr) [Located (IEWrappedName RdrName)]
    sub_rdrs
            = do Name
    name <- RdrName -> RnM Name
    lookupGlobalOccRn (RdrName -> RnM Name) -> RdrName -> RnM Name
    forall a b. (a -> b) -> a -> b
    $ IEWrappedName RdrName -> RdrName
    forall name. IEWrappedName name -> name
    ieWrappedName IEWrappedName RdrName
    rdr
                 ([GenLocated SrcSpan (IEWrappedName Name)]
    non_flds, [Located FieldLabel]
    flds) <- Name
    -> [Located (IEWrappedName RdrName)]
    -> RnM
         ([GenLocated SrcSpan (IEWrappedName Name)], [Located FieldLabel])
    lookupChildrenExport Name
    name [Located (IEWrappedName RdrName)]
    sub_rdrs
                 if Name -> Bool
    isUnboundName Name
    name
                    then (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
     [Located FieldLabel])
    -> TcM
         (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
          [Located FieldLabel])
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SrcSpan -> Name -> Located Name
    forall l e. l -> e -> GenLocated l e
    L SrcSpan
    l Name
    name, [], [Name
    name], [])
                    else (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
     [Located FieldLabel])
    -> TcM
         (Located Name, [GenLocated SrcSpan (IEWrappedName Name)], [Name],
          [Located FieldLabel])
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SrcSpan -> Name -> Located Name
    forall l e. l -> e -> GenLocated l e
    L SrcSpan
    l Name
    name, [GenLocated SrcSpan (IEWrappedName Name)]
    non_flds
                                , (GenLocated SrcSpan (IEWrappedName Name) -> Name)
    -> [GenLocated SrcSpan (IEWrappedName Name)] -> [Name]
    forall a b. (a -> b) -> [a] -> [b]
    map (IEWrappedName Name -> Name
    forall name. IEWrappedName name -> name
    ieWrappedName (IEWrappedName Name -> Name)
    -> (GenLocated SrcSpan (IEWrappedName Name) -> IEWrappedName Name)
    -> GenLocated SrcSpan (IEWrappedName Name)
    -> Name
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GenLocated SrcSpan (IEWrappedName Name) -> IEWrappedName Name
    forall l e. GenLocated l e -> e
    unLoc) [GenLocated SrcSpan (IEWrappedName Name)]
    non_flds
                                , [Located FieldLabel]
    flds)

        lookup_ie_all :: IE GhcPs -> LIEWrappedName RdrName
                      -> RnM (Located Name, [Name], [FieldLabel])
        lookup_ie_all :: IE GhcPs
    -> Located (IEWrappedName RdrName)
    -> RnM (Located Name, [Name], [FieldLabel])
    lookup_ie_all IE GhcPs
    ie (L SrcSpan
    l IEWrappedName RdrName
    rdr) =
              do Name
    name <- RdrName -> RnM Name
    lookupGlobalOccRn (RdrName -> RnM Name) -> RdrName -> RnM Name
    forall a b. (a -> b) -> a -> b
    $ IEWrappedName RdrName -> RdrName
    forall name. IEWrappedName name -> name
    ieWrappedName IEWrappedName RdrName
    rdr
                 let gres :: [GlobalRdrElt]
    gres = NameEnv [GlobalRdrElt] -> Name -> [GlobalRdrElt]
    forall a. NameEnv [a] -> Name -> [a]
    findChildren NameEnv [GlobalRdrElt]
    kids_env Name
    name
                     ([Name]
    non_flds, [FieldLabel]
    flds) = [GlobalRdrElt] -> ([Name], [FieldLabel])
    classifyGREs [GlobalRdrElt]
    gres
                 RdrName -> [GlobalRdrElt] -> TcRn ()
    addUsedKids (IEWrappedName RdrName -> RdrName
    forall name. IEWrappedName name -> name
    ieWrappedName IEWrappedName RdrName
    rdr) [GlobalRdrElt]
    gres
                 Bool
    warnDodgyExports <- WarningFlag -> IOEnv (Env TcGblEnv TcLclEnv) Bool
    forall gbl lcl. WarningFlag -> TcRnIf gbl lcl Bool
    woptM WarningFlag
    Opt_WarnDodgyExports
                 Bool -> TcRn () -> TcRn ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when ([GlobalRdrElt] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [GlobalRdrElt]
    gres) (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $
                      if Name -> Bool
    isTyConName Name
    name
                      then Bool -> TcRn () -> TcRn ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when Bool
    warnDodgyExports (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $
                               WarnReason -> SDoc -> TcRn ()
    addWarn (WarningFlag -> WarnReason
    Reason WarningFlag
    Opt_WarnDodgyExports)
                                       (Name -> SDoc
    dodgyExportWarn Name
    name)
                      else -- This occurs when you export T(..), but
                           -- only import T abstractly, or T is a synonym.
                           SDoc -> TcRn ()
    addErr (IE GhcPs -> SDoc
    exportItemErr IE GhcPs
    ie)
                 (Located Name, [Name], [FieldLabel])
    -> RnM (Located Name, [Name], [FieldLabel])
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SrcSpan -> Name -> Located Name
    forall l e. l -> e -> GenLocated l e
    L SrcSpan
    l Name
    name, [Name]
    non_flds, [FieldLabel]
    flds)

        -------------
        lookup_doc_ie :: IE GhcPs -> RnM (IE GhcRn)
        lookup_doc_ie :: IE GhcPs -> RnM (IE GhcRn)
    lookup_doc_ie (IEGroup XIEGroup GhcPs
    _ Int
    lev HsDocString
    doc) = do HsDocString
    rn_doc <- HsDocString -> RnM HsDocString
    rnHsDoc HsDocString
    doc
                                               IE GhcRn -> RnM (IE GhcRn)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (XIEGroup GhcRn -> Int -> HsDocString -> IE GhcRn
    forall pass. XIEGroup pass -> Int -> HsDocString -> IE pass
    IEGroup NoExtField
    XIEGroup GhcRn
    noExtField Int
    lev HsDocString
    rn_doc)
        lookup_doc_ie (IEDoc XIEDoc GhcPs
    _ HsDocString
    doc)       = do HsDocString
    rn_doc <- HsDocString -> RnM HsDocString
    rnHsDoc HsDocString
    doc
                                               IE GhcRn -> RnM (IE GhcRn)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (XIEDoc GhcRn -> HsDocString -> IE GhcRn
    forall pass. XIEDoc pass -> HsDocString -> IE pass
    IEDoc NoExtField
    XIEDoc GhcRn
    noExtField HsDocString
    rn_doc)
        lookup_doc_ie (IEDocNamed XIEDocNamed GhcPs
    _ String
    str)  = IE GhcRn -> RnM (IE GhcRn)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (XIEDocNamed GhcRn -> String -> IE GhcRn
    forall pass. XIEDocNamed pass -> String -> IE pass
    IEDocNamed NoExtField
    XIEDocNamed GhcRn
    noExtField String
    str)
        lookup_doc_ie IE GhcPs
    _ = String -> RnM (IE GhcRn)
    forall a. String -> a
    panic String
    "lookup_doc_ie"    -- Other cases covered earlier

        -- In an export item M.T(A,B,C), we want to treat the uses of
        -- A,B,C as if they were M.A, M.B, M.C
        -- Happily pickGREs does just the right thing
        addUsedKids :: RdrName -> [GlobalRdrElt] -> RnM ()
        addUsedKids :: RdrName -> [GlobalRdrElt] -> TcRn ()
    addUsedKids RdrName
    parent_rdr [GlobalRdrElt]
    kid_gres = [GlobalRdrElt] -> TcRn ()
    addUsedGREs (RdrName -> [GlobalRdrElt] -> [GlobalRdrElt]
    pickGREs RdrName
    parent_rdr [GlobalRdrElt]
    kid_gres)

    classifyGREs :: [GlobalRdrElt] -> ([Name], [FieldLabel])
    classifyGREs :: [GlobalRdrElt] -> ([Name], [FieldLabel])
    classifyGREs = [Either Name FieldLabel] -> ([Name], [FieldLabel])
    forall a b. [Either a b] -> ([a], [b])
    partitionEithers ([Either Name FieldLabel] -> ([Name], [FieldLabel]))
    -> ([GlobalRdrElt] -> [Either Name FieldLabel])
    -> [GlobalRdrElt]
    -> ([Name], [FieldLabel])
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (GlobalRdrElt -> Either Name FieldLabel)
    -> [GlobalRdrElt] -> [Either Name FieldLabel]
    forall a b. (a -> b) -> [a] -> [b]
    map GlobalRdrElt -> Either Name FieldLabel
    classifyGRE

    classifyGRE :: GlobalRdrElt -> Either Name FieldLabel
    classifyGRE :: GlobalRdrElt -> Either Name FieldLabel
    classifyGRE GlobalRdrElt
    gre = case GlobalRdrElt -> Parent
    gre_par GlobalRdrElt
    gre of
      FldParent Name
    _ Maybe FastString
    Nothing -> FieldLabel -> Either Name FieldLabel
    forall a b. b -> Either a b
    Right (FastString -> Bool -> Name -> FieldLabel
    forall a. FastString -> Bool -> a -> FieldLbl a
    FieldLabel (OccName -> FastString
    occNameFS (Name -> OccName
    nameOccName Name
    n)) Bool
    False Name
    n)
      FldParent Name
    _ (Just FastString
    lbl) -> FieldLabel -> Either Name FieldLabel
    forall a b. b -> Either a b
    Right (FastString -> Bool -> Name -> FieldLabel
    forall a. FastString -> Bool -> a -> FieldLbl a
    FieldLabel FastString
    lbl Bool
    True Name
    n)
      Parent
    _                      -> Name -> Either Name FieldLabel
    forall a b. a -> Either a b
    Left  Name
    n
      where
        n :: Name
    n = GlobalRdrElt -> Name
    gre_name GlobalRdrElt
    gre

    isDoc :: IE GhcPs -> Bool
    isDoc :: IE GhcPs -> Bool
    isDoc (IEDoc {})      = Bool
    True
    isDoc (IEDocNamed {}) = Bool
    True
    isDoc (IEGroup {})    = Bool
    True
    isDoc IE GhcPs
    _ = Bool
    False

    -- Renaming and typechecking of exports happens after everything else has
    -- been typechecked.

    {-
    Note [Modules without a module header]
    --------------------------------------------------

    The Haskell 2010 report says in section 5.1:

    >> An abbreviated form of module, consisting only of the module body, is
    >> permitted. If this is used, the header is assumed to be
    >> ‘module Main(main) where’.

    For modules without a module header, this is implemented the
    following way:

    If the module has a main function in scope:
       Then create a module header and export the main function,
       as if a module header like ‘module Main(main) where...’ would exist.
       This has the effect to mark the main function and all top level
       functions called directly or indirectly via main as 'used',
       and later on, unused top-level functions can be reported correctly.
       There is no distinction between GHC and GHCi.
    If the module has several main functions in scope:
       Then generate a header as above. The ambiguity is reported later in
       module  `GHC.Tc.Module` function `check_main`.
    If the module has NO main function:
       Then export all top-level functions. This marks all top level
       functions as 'used'.
       In GHCi this has the effect, that we don't get any 'non-used' warnings.
       In GHC, however, the 'has-main-module' check in GHC.Tc.Module.checkMain
       fires, and we get the error:
          The IO action ‘main’ is not defined in module ‘Main’
    -}

    -- Renaming exports lists is a minefield. Five different things can appear in
    -- children export lists ( T(A, B, C) ).
    -- 1. Record selectors
    -- 2. Type constructors
    -- 3. Data constructors
    -- 4. Pattern Synonyms
    -- 5. Pattern Synonym Selectors
    --
    -- However, things get put into weird name spaces.
    -- 1. Some type constructors are parsed as variables (-.->) for example.
    -- 2. All data constructors are parsed as type constructors
    -- 3. When there is ambiguity, we default type constructors to data
    -- constructors and require the explicit `type` keyword for type
    -- constructors.
    --
    -- This function first establishes the possible namespaces that an
    -- identifier might be in (`choosePossibleNameSpaces`).
    --
    -- Then for each namespace in turn, tries to find the correct identifier
    -- there returning the first positive result or the first terminating
    -- error.
    --

    lookupChildrenExport :: Name -> [LIEWrappedName RdrName]
                         -> RnM ([LIEWrappedName Name], [Located FieldLabel])
    lookupChildrenExport :: Name
    -> [Located (IEWrappedName RdrName)]
    -> RnM
         ([GenLocated SrcSpan (IEWrappedName Name)], [Located FieldLabel])
    lookupChildrenExport Name
    spec_parent [Located (IEWrappedName RdrName)]
    rdr_items =
      do
        [Either
       (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)]
    xs <- (Located (IEWrappedName RdrName)
     -> TcRn
          (Either
             (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)))
    -> [Located (IEWrappedName RdrName)]
    -> TcRn
         [Either
            (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)]
    forall a b. (a -> TcRn b) -> [a] -> TcRn [b]
    mapAndReportM Located (IEWrappedName RdrName)
    -> TcRn
         (Either
            (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel))
    doOne [Located (IEWrappedName RdrName)]
    rdr_items
        ([GenLocated SrcSpan (IEWrappedName Name)], [Located FieldLabel])
    -> RnM
         ([GenLocated SrcSpan (IEWrappedName Name)], [Located FieldLabel])
    forall (m :: * -> *) a. Monad m => a -> m a
    return (([GenLocated SrcSpan (IEWrappedName Name)], [Located FieldLabel])
     -> RnM
          ([GenLocated SrcSpan (IEWrappedName Name)], [Located FieldLabel]))
    -> ([GenLocated SrcSpan (IEWrappedName Name)],
        [Located FieldLabel])
    -> RnM
         ([GenLocated SrcSpan (IEWrappedName Name)], [Located FieldLabel])
    forall a b. (a -> b) -> a -> b
    $ [Either
       (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)]
    -> ([GenLocated SrcSpan (IEWrappedName Name)],
        [Located FieldLabel])
    forall a b. [Either a b] -> ([a], [b])
    partitionEithers [Either
       (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)]
    xs
        where
            -- Pick out the possible namespaces in order of priority
            -- This is a consequence of how the parser parses all
            -- data constructors as type constructors.
            choosePossibleNamespaces :: NameSpace -> [NameSpace]
            choosePossibleNamespaces :: NameSpace -> [NameSpace]
    choosePossibleNamespaces NameSpace
    ns
              | NameSpace
    ns NameSpace -> NameSpace -> Bool
    forall a. Eq a => a -> a -> Bool
    == NameSpace
    varName = [NameSpace
    varName, NameSpace
    tcName]
              | NameSpace
    ns NameSpace -> NameSpace -> Bool
    forall a. Eq a => a -> a -> Bool
    == NameSpace
    tcName  = [NameSpace
    dataName, NameSpace
    tcName]
              | Bool
    otherwise = [NameSpace
    ns]
            -- Process an individual child
            doOne :: LIEWrappedName RdrName
                  -> RnM (Either (LIEWrappedName Name) (Located FieldLabel))
            doOne :: Located (IEWrappedName RdrName)
    -> TcRn
         (Either
            (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel))
    doOne Located (IEWrappedName RdrName)
    n = do

              let bareName :: RdrName
    bareName = (IEWrappedName RdrName -> RdrName
    forall name. IEWrappedName name -> name
    ieWrappedName (IEWrappedName RdrName -> RdrName)
    -> (Located (IEWrappedName RdrName) -> IEWrappedName RdrName)
    -> Located (IEWrappedName RdrName)
    -> RdrName
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Located (IEWrappedName RdrName) -> IEWrappedName RdrName
    forall l e. GenLocated l e -> e
    unLoc) Located (IEWrappedName RdrName)
    n
                  lkup :: NameSpace -> RnM ChildLookupResult
    lkup NameSpace
    v = Bool -> Bool -> Name -> RdrName -> RnM ChildLookupResult
    lookupSubBndrOcc_helper Bool
    False Bool
    True
                            Name
    spec_parent (RdrName -> NameSpace -> RdrName
    setRdrNameSpace RdrName
    bareName NameSpace
    v)

              ChildLookupResult
    name <-  [RnM ChildLookupResult] -> RnM ChildLookupResult
    combineChildLookupResult ([RnM ChildLookupResult] -> RnM ChildLookupResult)
    -> [RnM ChildLookupResult] -> RnM ChildLookupResult
    forall a b. (a -> b) -> a -> b
    $ (NameSpace -> RnM ChildLookupResult)
    -> [NameSpace] -> [RnM ChildLookupResult]
    forall a b. (a -> b) -> [a] -> [b]
    map NameSpace -> RnM ChildLookupResult
    lkup ([NameSpace] -> [RnM ChildLookupResult])
    -> [NameSpace] -> [RnM ChildLookupResult]
    forall a b. (a -> b) -> a -> b
    $
                       NameSpace -> [NameSpace]
    choosePossibleNamespaces (RdrName -> NameSpace
    rdrNameSpace RdrName
    bareName)
              String -> SDoc -> TcRn ()
    traceRn String
    "lookupChildrenExport" (ChildLookupResult -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ChildLookupResult
    name)
              -- Default to data constructors for slightly better error
              -- messages
              let unboundName :: RdrName
                  unboundName :: RdrName
    unboundName = if RdrName -> NameSpace
    rdrNameSpace RdrName
    bareName NameSpace -> NameSpace -> Bool
    forall a. Eq a => a -> a -> Bool
    == NameSpace
    varName
                                    then RdrName
    bareName
                                    else RdrName -> NameSpace -> RdrName
    setRdrNameSpace RdrName
    bareName NameSpace
    dataName

              case ChildLookupResult
    name of
                ChildLookupResult
    NameNotFound -> do { Name
    ub <- RdrName -> RnM Name
    reportUnboundName RdrName
    unboundName
                                   ; let l :: SrcSpan
    l = Located (IEWrappedName RdrName) -> SrcSpan
    forall l e. GenLocated l e -> l
    getLoc Located (IEWrappedName RdrName)
    n
                                   ; Either
      (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)
    -> TcRn
         (Either
            (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (GenLocated SrcSpan (IEWrappedName Name)
    -> Either
         (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)
    forall a b. a -> Either a b
    Left (SrcSpan
    -> IEWrappedName Name -> GenLocated SrcSpan (IEWrappedName Name)
    forall l e. l -> e -> GenLocated l e
    L SrcSpan
    l (Located Name -> IEWrappedName Name
    forall name. Located name -> IEWrappedName name
    IEName (SrcSpan -> Name -> Located Name
    forall l e. l -> e -> GenLocated l e
    L SrcSpan
    l Name
    ub))))}
                FoundFL FieldLabel
    fls -> Either
      (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)
    -> TcRn
         (Either
            (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either
       (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)
     -> TcRn
          (Either
             (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)))
    -> Either
         (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)
    -> TcRn
         (Either
            (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel))
    forall a b. (a -> b) -> a -> b
    $ Located FieldLabel
    -> Either
         (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)
    forall a b. b -> Either a b
    Right (SrcSpan -> FieldLabel -> Located FieldLabel
    forall l e. l -> e -> GenLocated l e
    L (Located (IEWrappedName RdrName) -> SrcSpan
    forall l e. GenLocated l e -> l
    getLoc Located (IEWrappedName RdrName)
    n) FieldLabel
    fls)
                FoundName Parent
    par Name
    name -> do { Name -> Parent -> Name -> TcRn ()
    checkPatSynParent Name
    spec_parent Parent
    par Name
    name
                                         ; Either
      (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)
    -> TcRn
         (Either
            (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel))
    forall (m :: * -> *) a. Monad m => a -> m a
    return
                                           (Either
       (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)
     -> TcRn
          (Either
             (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)))
    -> Either
         (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)
    -> TcRn
         (Either
            (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel))
    forall a b. (a -> b) -> a -> b
    $ GenLocated SrcSpan (IEWrappedName Name)
    -> Either
         (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel)
    forall a b. a -> Either a b
    Left (Located (IEWrappedName RdrName)
    -> Name -> GenLocated SrcSpan (IEWrappedName Name)
    forall name1 name2.
    LIEWrappedName name1 -> name2 -> LIEWrappedName name2
    replaceLWrappedName Located (IEWrappedName RdrName)
    n Name
    name) }
                IncorrectParent Name
    p Name
    g SDoc
    td [Name]
    gs -> Name
    -> Name
    -> SDoc
    -> [Name]
    -> TcRn
         (Either
            (GenLocated SrcSpan (IEWrappedName Name)) (Located FieldLabel))
    forall a. Name -> Name -> SDoc -> [Name] -> TcM a
    failWithDcErr Name
    p Name
    g SDoc
    td [Name]
    gs

    -- Note: [Typing Pattern Synonym Exports]
    -- It proved quite a challenge to precisely specify which pattern synonyms
    -- should be allowed to be bundled with which type constructors.
    -- In the end it was decided to be quite liberal in what we allow. Below is
    -- how Simon described the implementation.
    --
    -- "Personally I think we should Keep It Simple.  All this talk of
    --  satisfiability makes me shiver.  I suggest this: allow T( P ) in all
    --   situations except where `P`'s type is ''visibly incompatible'' with
    --   `T`.
    --
    --    What does "visibly incompatible" mean?  `P` is visibly incompatible
    --    with
    --     `T` if
    --       * `P`'s type is of form `... -> S t1 t2`
    --       * `S` is a data/newtype constructor distinct from `T`
    --
    --  Nothing harmful happens if we allow `P` to be exported with
    --  a type it can't possibly be useful for, but specifying a tighter
    --  relationship is very awkward as you have discovered."
    --
    -- Note that this allows *any* pattern synonym to be bundled with any
    -- datatype type constructor. For example, the following pattern `P` can be
    -- bundled with any type.
    --
    -- ```
    -- pattern P :: (A ~ f) => f
    -- ```
    --
    -- So we provide basic type checking in order to help the user out, most
    -- pattern synonyms are defined with definite type constructors, but don't
    -- actually prevent a library author completely confusing their users if
    -- they want to.
    --
    -- So, we check for exactly four things
    -- 1. The name arises from a pattern synonym definition. (Either a pattern
    --    synonym constructor or a pattern synonym selector)
    -- 2. The pattern synonym is only bundled with a datatype or newtype.
    -- 3. Check that the head of the result type constructor is an actual type
    --    constructor and not a type variable. (See above example)
    -- 4. Is so, check that this type constructor is the same as the parent
    --    type constructor.
    --
    --
    -- Note: [Types of TyCon]
    --
    -- This check appears to be overlly complicated, Richard asked why it
    -- is not simply just `isAlgTyCon`. The answer for this is that
    -- a classTyCon is also an `AlgTyCon` which we explicitly want to disallow.
    -- (It is either a newtype or data depending on the number of methods)
    --

    -- | Given a resolved name in the children export list and a parent. Decide
    -- whether we are allowed to export the child with the parent.
    -- Invariant: gre_par == NoParent
    -- See note [Typing Pattern Synonym Exports]
    checkPatSynParent :: Name    -- ^ Alleged parent type constructor
                                 -- User wrote T( P, Q )
                      -> Parent  -- The parent of P we discovered
                      -> Name    -- ^ Either a
                                 --   a) Pattern Synonym Constructor
                                 --   b) A pattern synonym selector
                      -> TcM ()  -- Fails if wrong parent
    checkPatSynParent :: Name -> Parent -> Name -> TcRn ()
    checkPatSynParent Name
    _ (ParentIs {}) Name
    _
      = () -> TcRn ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    checkPatSynParent Name
    _ (FldParent {}) Name
    _
      = () -> TcRn ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    checkPatSynParent Name
    parent Parent
    NoParent Name
    mpat_syn
      | Name -> Bool
    isUnboundName Name
    parent -- Avoid an error cascade
      = () -> TcRn ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

      | Bool
    otherwise
      = do { TyCon
    parent_ty_con  <- Name -> TcM TyCon
    tcLookupTyCon Name
    parent
           ; TyThing
    mpat_syn_thing <- Name -> TcM TyThing
    tcLookupGlobal Name
    mpat_syn

            -- 1. Check that the Id was actually from a thing associated with patsyns
           ; case TyThing
    mpat_syn_thing of
                AnId Id
    i | Id -> Bool
    isId Id
    i
                       , RecSelId { sel_tycon :: IdDetails -> RecSelParent
    sel_tycon = RecSelPatSyn PatSyn
    p } <- Id -> IdDetails
    idDetails Id
    i
                       -> SDoc -> TyCon -> PatSyn -> TcRn ()
    handle_pat_syn (Id -> SDoc
    selErr Id
    i) TyCon
    parent_ty_con PatSyn
    p

                AConLike (PatSynCon PatSyn
    p) -> SDoc -> TyCon -> PatSyn -> TcRn ()
    handle_pat_syn (PatSyn -> SDoc
    psErr PatSyn
    p) TyCon
    parent_ty_con PatSyn
    p

                TyThing
    _ -> Name -> Name -> SDoc -> [Name] -> TcRn ()
    forall a. Name -> Name -> SDoc -> [Name] -> TcM a
    failWithDcErr Name
    parent Name
    mpat_syn (Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Name
    mpat_syn) [] }
      where
        psErr :: PatSyn -> SDoc
    psErr  = String -> PatSyn -> SDoc
    forall o. Outputable o => String -> o -> SDoc
    exportErrCtxt String
    "pattern synonym"
        selErr :: Id -> SDoc
    selErr = String -> Id -> SDoc
    forall o. Outputable o => String -> o -> SDoc
    exportErrCtxt String
    "pattern synonym record selector"

        assocClassErr :: SDoc
        assocClassErr :: SDoc
    assocClassErr = String -> SDoc
    text String
    "Pattern synonyms can be bundled only with datatypes."

        handle_pat_syn :: SDoc
                       -> TyCon      -- ^ Parent TyCon
                       -> PatSyn     -- ^ Corresponding bundled PatSyn
                                     --   and pretty printed origin
                       -> TcM ()
        handle_pat_syn :: SDoc -> TyCon -> PatSyn -> TcRn ()
    handle_pat_syn SDoc
    doc TyCon
    ty_con PatSyn
    pat_syn

          -- 2. See note [Types of TyCon]
          | Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ TyCon -> Bool
    isTyConWithSrcDataCons TyCon
    ty_con
          = SDoc -> TcRn () -> TcRn ()
    forall a. SDoc -> TcM a -> TcM a
    addErrCtxt SDoc
    doc (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $ SDoc -> TcRn ()
    forall a. SDoc -> TcM a
    failWithTc SDoc
    assocClassErr

          -- 3. Is the head a type variable?
          | Maybe TyCon
    Nothing <- Maybe TyCon
    mtycon
          = () -> TcRn ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          -- 4. Ok. Check they are actually the same type constructor.

          | Just TyCon
    p_ty_con <- Maybe TyCon
    mtycon, TyCon
    p_ty_con TyCon -> TyCon -> Bool
    forall a. Eq a => a -> a -> Bool
    /= TyCon
    ty_con
          = SDoc -> TcRn () -> TcRn ()
    forall a. SDoc -> TcM a -> TcM a
    addErrCtxt SDoc
    doc (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
    forall a b. (a -> b) -> a -> b
    $ SDoc -> TcRn ()
    forall a. SDoc -> TcM a
    failWithTc SDoc
    typeMismatchError

          -- 5. We passed!
          | Bool
    otherwise
          = () -> TcRn ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

          where
            expected_res_ty :: Type
    expected_res_ty = TyCon -> [Type] -> Type
    mkTyConApp TyCon
    ty_con ([Id] -> [Type]
    mkTyVarTys (TyCon -> [Id]
    tyConTyVars TyCon
    ty_con))
            ([Id]
    _, [Type]
    _, [Id]
    _, [Type]
    _, [Scaled Type]
    _, Type
    res_ty) = PatSyn -> ([Id], [Type], [Id], [Type], [Scaled Type], Type)
    patSynSig PatSyn
    pat_syn
            mtycon :: Maybe TyCon
    mtycon = (TyCon, [Type]) -> TyCon
    forall a b. (a, b) -> a
    fst ((TyCon, [Type]) -> TyCon) -> Maybe (TyCon, [Type]) -> Maybe TyCon
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> HasCallStack => Type -> Maybe (TyCon, [Type])
    Type -> Maybe (TyCon, [Type])
    tcSplitTyConApp_maybe Type
    res_ty
            typeMismatchError :: SDoc
            typeMismatchError :: SDoc
    typeMismatchError =
              String -> SDoc
    text String
    "Pattern synonyms can only be bundled with matching type constructors"
                  SDoc -> SDoc -> SDoc
    $$ String -> SDoc
    text String
    "Couldn't match expected type of"
                  SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (Type -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Type
    expected_res_ty)
                  SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "with actual type of"
                  SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (Type -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Type
    res_ty)

    {-===========================================================================-}
    check_occs :: IE GhcPs -> ExportOccMap -> [AvailInfo]
               -> RnM ExportOccMap
    check_occs :: IE GhcPs -> ExportOccMap -> [AvailInfo] -> RnM ExportOccMap
    check_occs IE GhcPs
    ie ExportOccMap
    occs [AvailInfo]
    avails
      -- 'names' and 'fls' are the entities specified by 'ie'
      = (ExportOccMap -> (Name, OccName) -> RnM ExportOccMap)
    -> ExportOccMap -> [(Name, OccName)] -> RnM ExportOccMap
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldlM ExportOccMap -> (Name, OccName) -> RnM ExportOccMap
    check ExportOccMap
    occs [(Name, OccName)]
    names_with_occs
      where
        -- Each Name specified by 'ie', paired with the OccName used to
        -- refer to it in the GlobalRdrEnv
        -- (see Note [Representing fields in AvailInfo] in GHC.Types.Avail).
        --
        -- We check for export clashes using the selector Name, but need
        -- the field label OccName for presenting error messages.
        names_with_occs :: [(Name, OccName)]
    names_with_occs = [AvailInfo] -> [(Name, OccName)]
    availsNamesWithOccs [AvailInfo]
    avails

        check :: ExportOccMap -> (Name, OccName) -> RnM ExportOccMap
    check ExportOccMap
    occs (Name
    name, OccName
    occ)
          = case ExportOccMap -> OccName -> Maybe (Name, IE GhcPs)
    forall a. OccEnv a -> OccName -> Maybe a
    lookupOccEnv ExportOccMap
    occs OccName
    name_occ of
              Maybe (Name, IE GhcPs)
    Nothing -> ExportOccMap -> RnM ExportOccMap
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ExportOccMap -> OccName -> (Name, IE GhcPs) -> ExportOccMap
    forall a. OccEnv a -> OccName -> a -> OccEnv a
    extendOccEnv ExportOccMap
    occs OccName
    name_occ (Name
    name, IE GhcPs
    ie))

              Just (Name
    name', IE GhcPs
    ie')
                | Name
    name Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    name'   -- Duplicate export
                -- But we don't want to warn if the same thing is exported
                -- by two different module exports. See ticket #4478.
                -> do { WarningFlag -> Bool -> SDoc -> TcRn ()
    warnIfFlag WarningFlag
    Opt_WarnDuplicateExports
                                   (Bool -> Bool
    not (Name -> IE GhcPs -> IE GhcPs -> Bool
    dupExport_ok Name
    name IE GhcPs
    ie IE GhcPs
    ie'))
                                   (OccName -> IE GhcPs -> IE GhcPs -> SDoc
    dupExportWarn OccName
    occ IE GhcPs
    ie IE GhcPs
    ie')
                      ; ExportOccMap -> RnM ExportOccMap
    forall (m :: * -> *) a. Monad m => a -> m a
    return ExportOccMap
    occs }

                | Bool
    otherwise    -- Same occ name but different names: an error
                ->  do { GlobalRdrEnv
    global_env <- TcRn GlobalRdrEnv
    getGlobalRdrEnv ;
                         SDoc -> TcRn ()
    addErr (GlobalRdrEnv
    -> OccName -> Name -> Name -> IE GhcPs -> IE GhcPs -> SDoc
    exportClashErr GlobalRdrEnv
    global_env OccName
    occ Name
    name' Name
    name IE GhcPs
    ie' IE GhcPs
    ie) ;
                         ExportOccMap -> RnM ExportOccMap
    forall (m :: * -> *) a. Monad m => a -> m a
    return ExportOccMap
    occs }
          where
            name_occ :: OccName
    name_occ = Name -> OccName
    nameOccName Name
    name

    dupExport_ok :: Name -> IE GhcPs -> IE GhcPs -> Bool
    -- The Name is exported by both IEs. Is that ok?
    -- "No"  iff the name is mentioned explicitly in both IEs
    --        or one of the IEs mentions the name *alone*
    -- "Yes" otherwise
    --
    -- Examples of "no":  module M( f, f )
    --                    module M( fmap, Functor(..) )
    --                    module M( module Data.List, head )
    --
    -- Example of "yes"
    --    module M( module A, module B ) where
    --        import A( f )
    --        import B( f )
    --
    -- Example of "yes" (#2436)
    --    module M( C(..), T(..) ) where
    --         class C a where { data T a }
    --         instance C Int where { data T Int = TInt }
    --
    -- Example of "yes" (#2436)
    --    module Foo ( T ) where
    --      data family T a
    --    module Bar ( T(..), module Foo ) where
    --        import Foo
    --        data instance T Int = TInt

    dupExport_ok :: Name -> IE GhcPs -> IE GhcPs -> Bool
    dupExport_ok Name
    n IE GhcPs
    ie1 IE GhcPs
    ie2
      = Bool -> Bool
    not (  IE GhcPs -> Bool
    forall {pass}. IE pass -> Bool
    single IE GhcPs
    ie1 Bool -> Bool -> Bool
    || IE GhcPs -> Bool
    forall {pass}. IE pass -> Bool
    single IE GhcPs
    ie2
            Bool -> Bool -> Bool
    || (IE GhcPs -> Bool
    explicit_in IE GhcPs
    ie1 Bool -> Bool -> Bool
    && IE GhcPs -> Bool
    explicit_in IE GhcPs
    ie2) )
      where
        explicit_in :: IE GhcPs -> Bool
    explicit_in (IEModuleContents {}) = Bool
    False                   -- module M
        explicit_in (IEThingAll XIEThingAll GhcPs
    _ LIEWrappedName (IdP GhcPs)
    r)
          = Name -> OccName
    nameOccName Name
    n OccName -> OccName -> Bool
    forall a. Eq a => a -> a -> Bool
    == RdrName -> OccName
    rdrNameOcc (IEWrappedName RdrName -> RdrName
    forall name. IEWrappedName name -> name
    ieWrappedName (IEWrappedName RdrName -> RdrName)
    -> IEWrappedName RdrName -> RdrName
    forall a b. (a -> b) -> a -> b
    $ Located (IEWrappedName RdrName) -> IEWrappedName RdrName
    forall l e. GenLocated l e -> e
    unLoc Located (IEWrappedName RdrName)
    LIEWrappedName (IdP GhcPs)
    r)  -- T(..)
        explicit_in IE GhcPs
    _              = Bool
    True

        single :: IE pass -> Bool
    single IEVar {}      = Bool
    True
        single IEThingAbs {} = Bool
    True
        single IE pass
    _               = Bool
    False

    dupModuleExport :: ModuleName -> SDoc
    dupModuleExport :: ModuleName -> SDoc
    dupModuleExport ModuleName
    mod
      = [SDoc] -> SDoc
    hsep [String -> SDoc
    text String
    "Duplicate",
              SDoc -> SDoc
    quotes (String -> SDoc
    text String
    "Module" SDoc -> SDoc -> SDoc
    <+> ModuleName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod),
              String -> SDoc
    text String
    "in export list"]

    moduleNotImported :: ModuleName -> SDoc
    moduleNotImported :: ModuleName -> SDoc
    moduleNotImported ModuleName
    mod
      = [SDoc] -> SDoc
    hsep [String -> SDoc
    text String
    "The export item",
              SDoc -> SDoc
    quotes (String -> SDoc
    text String
    "module" SDoc -> SDoc -> SDoc
    <+> ModuleName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod),
              String -> SDoc
    text String
    "is not imported"]

    nullModuleExport :: ModuleName -> SDoc
    nullModuleExport :: ModuleName -> SDoc
    nullModuleExport ModuleName
    mod
      = [SDoc] -> SDoc
    hsep [String -> SDoc
    text String
    "The export item",
              SDoc -> SDoc
    quotes (String -> SDoc
    text String
    "module" SDoc -> SDoc -> SDoc
    <+> ModuleName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod),
              String -> SDoc
    text String
    "exports nothing"]

    missingModuleExportWarn :: ModuleName -> SDoc
    missingModuleExportWarn :: ModuleName -> SDoc
    missingModuleExportWarn ModuleName
    mod
      = [SDoc] -> SDoc
    hsep [String -> SDoc
    text String
    "The export item",
              SDoc -> SDoc
    quotes (String -> SDoc
    text String
    "module" SDoc -> SDoc -> SDoc
    <+> ModuleName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleName
    mod),
              String -> SDoc
    text String
    "is missing an export list"]

    dodgyExportWarn :: Name -> SDoc
    dodgyExportWarn :: Name -> SDoc
    dodgyExportWarn Name
    item
      = SDoc -> Name -> IE GhcRn -> SDoc
    forall a b. (Outputable a, Outputable b) => SDoc -> a -> b -> SDoc
    dodgyMsg (String -> SDoc
    text String
    "export") Name
    item (IdP GhcRn -> IE GhcRn
    forall (p :: Pass). IdP (GhcPass p) -> IE (GhcPass p)
    dodgyMsgInsert Name
    IdP GhcRn
    item :: IE GhcRn)

    exportErrCtxt :: Outputable o => String -> o -> SDoc
    exportErrCtxt :: forall o. Outputable o => String -> o -> SDoc
    exportErrCtxt String
    herald o
    exp =
      String -> SDoc
    text String
    "In the" SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text (String
    herald String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    ":") SDoc -> SDoc -> SDoc
    <+> o -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr o
    exp

    addExportErrCtxt :: (OutputableBndrId p)
                     => IE (GhcPass p) -> TcM a -> TcM a
    addExportErrCtxt :: forall (p :: Pass) a.
    OutputableBndrId p =>
    IE (GhcPass p) -> TcM a -> TcM a
    addExportErrCtxt IE (GhcPass p)
    ie = SDoc -> TcM a -> TcM a
    forall a. SDoc -> TcM a -> TcM a
    addErrCtxt SDoc
    exportCtxt
      where
        exportCtxt :: SDoc
    exportCtxt = String -> SDoc
    text String
    "In the export:" SDoc -> SDoc -> SDoc
    <+> IE (GhcPass p) -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr IE (GhcPass p)
    ie

    exportItemErr :: IE GhcPs -> SDoc
    exportItemErr :: IE GhcPs -> SDoc
    exportItemErr IE GhcPs
    export_item
      = [SDoc] -> SDoc
    sep [ String -> SDoc
    text String
    "The export item" SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (IE GhcPs -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr IE GhcPs
    export_item),
              String -> SDoc
    text String
    "attempts to export constructors or class methods that are not visible here" ]

    dupExportWarn :: OccName -> IE GhcPs -> IE GhcPs -> SDoc
    dupExportWarn :: OccName -> IE GhcPs -> IE GhcPs -> SDoc
    dupExportWarn OccName
    occ_name IE GhcPs
    ie1 IE GhcPs
    ie2
      = [SDoc] -> SDoc
    hsep [SDoc -> SDoc
    quotes (OccName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr OccName
    occ_name),
              String -> SDoc
    text String
    "is exported by", SDoc -> SDoc
    quotes (IE GhcPs -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr IE GhcPs
    ie1),
              String -> SDoc
    text String
    "and",            SDoc -> SDoc
    quotes (IE GhcPs -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr IE GhcPs
    ie2)]

    dcErrMsg :: Name -> String -> SDoc -> [SDoc] -> SDoc
    dcErrMsg :: Name -> String -> SDoc -> [SDoc] -> SDoc
    dcErrMsg Name
    ty_con String
    what_is SDoc
    thing [SDoc]
    parents =
              String -> SDoc
    text String
    "The type constructor" SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Name
    ty_con)
                    SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "is not the parent of the" SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    what_is
                    SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes SDoc
    thing SDoc -> SDoc -> SDoc
    <> Char -> SDoc
    char Char
    '.'
                    SDoc -> SDoc -> SDoc
    $$ String -> SDoc
    text (String -> String
    capitalise String
    what_is)
                       SDoc -> SDoc -> SDoc
    <> String -> SDoc
    text String
    "s can only be exported with their parent type constructor."
                    SDoc -> SDoc -> SDoc
    $$ (case [SDoc]
    parents of
                          [] -> SDoc
    empty
                          [SDoc
    _] -> String -> SDoc
    text String
    "Parent:"
                          [SDoc]
    _  -> String -> SDoc
    text String
    "Parents:") SDoc -> SDoc -> SDoc
    <+> [SDoc] -> SDoc
    fsep (SDoc -> [SDoc] -> [SDoc]
    punctuate SDoc
    comma [SDoc]
    parents)

    failWithDcErr :: Name -> Name -> SDoc -> [Name] -> TcM a
    failWithDcErr :: forall a. Name -> Name -> SDoc -> [Name] -> TcM a
    failWithDcErr Name
    parent Name
    thing SDoc
    thing_doc [Name]
    parents = do
      TyThing
    ty_thing <- Name -> TcM TyThing
    tcLookupGlobal Name
    thing
      SDoc -> TcM a
    forall a. SDoc -> TcM a
    failWithTc (SDoc -> TcM a) -> SDoc -> TcM a
    forall a b. (a -> b) -> a -> b
    $ Name -> String -> SDoc -> [SDoc] -> SDoc
    dcErrMsg Name
    parent (TyThing -> String
    pp_category TyThing
    ty_thing)
                            SDoc
    thing_doc ((Name -> SDoc) -> [Name] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [Name]
    parents)
      where
        pp_category :: TyThing -> String
        pp_category :: TyThing -> String
    pp_category (AnId Id
    i)
          | Id -> Bool
    isRecordSelector Id
    i = String
    "record selector"
        pp_category TyThing
    i = TyThing -> String
    tyThingCategory TyThing
    i

    exportClashErr :: GlobalRdrEnv -> OccName
                   -> Name -> Name
                   -> IE GhcPs -> IE GhcPs
                   -> MsgDoc
    exportClashErr :: GlobalRdrEnv
    -> OccName -> Name -> Name -> IE GhcPs -> IE GhcPs -> SDoc
    exportClashErr GlobalRdrEnv
    global_env OccName
    occ Name
    name1 Name
    name2 IE GhcPs
    ie1 IE GhcPs
    ie2
      = [SDoc] -> SDoc
    vcat [ String -> SDoc
    text String
    "Conflicting exports for" SDoc -> SDoc -> SDoc
    <+> SDoc -> SDoc
    quotes (OccName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr OccName
    occ) SDoc -> SDoc -> SDoc
    <> SDoc
    colon
             , IE GhcPs -> Name -> SDoc
    ppr_export IE GhcPs
    ie1' Name
    name1'
             , IE GhcPs -> Name -> SDoc
    ppr_export IE GhcPs
    ie2' Name
    name2' ]
      where
        ppr_export :: IE GhcPs -> Name -> SDoc
    ppr_export IE GhcPs
    ie Name
    name = Int -> SDoc -> SDoc
    nest Int
    3 (SDoc -> Int -> SDoc -> SDoc
    hang (SDoc -> SDoc
    quotes (IE GhcPs -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr IE GhcPs
    ie) SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "exports" SDoc -> SDoc -> SDoc
    <+>
                                           SDoc -> SDoc
    quotes (Name -> SDoc
    ppr_name Name
    name))
                                        Int
    2 (GlobalRdrElt -> SDoc
    pprNameProvenance (Name -> GlobalRdrElt
    get_gre Name
    name)))

        -- DuplicateRecordFields means that nameOccName might be a mangled
        -- $sel-prefixed thing, in which case show the correct OccName alone
        ppr_name :: Name -> SDoc
    ppr_name Name
    name
          | Name -> OccName
    nameOccName Name
    name OccName -> OccName -> Bool
    forall a. Eq a => a -> a -> Bool
    == OccName
    occ = Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Name
    name
          | Bool
    otherwise               = OccName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr OccName
    occ

        -- get_gre finds a GRE for the Name, so that we can show its provenance
        get_gre :: Name -> GlobalRdrElt
    get_gre Name
    name
            = GlobalRdrElt -> Maybe GlobalRdrElt -> GlobalRdrElt
    forall a. a -> Maybe a -> a
    fromMaybe (String -> SDoc -> GlobalRdrElt
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "exportClashErr" (Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Name
    name))
                        (GlobalRdrEnv -> Name -> OccName -> Maybe GlobalRdrElt
    lookupGRE_Name_OccName GlobalRdrEnv
    global_env Name
    name OccName
    occ)
        get_loc :: Name -> SrcSpan
    get_loc Name
    name = GlobalRdrElt -> SrcSpan
    greSrcSpan (Name -> GlobalRdrElt
    get_gre Name
    name)
        (Name
    name1', IE GhcPs
    ie1', Name
    name2', IE GhcPs
    ie2') =
          case SrcSpan -> SrcSpan -> Ordering
    SrcLoc.leftmost_smallest (Name -> SrcSpan
    get_loc Name
    name1) (Name -> SrcSpan
    get_loc Name
    name2) of
            Ordering
    LT -> (Name
    name1, IE GhcPs
    ie1, Name
    name2, IE GhcPs
    ie2)
            Ordering
    GT -> (Name
    name2, IE GhcPs
    ie2, Name
    name1, IE GhcPs
    ie1)
            Ordering
    EQ -> String -> (Name, IE GhcPs, Name, IE GhcPs)
    forall a. String -> a
    panic String
    "exportClashErr: clashing exports have idential location"