    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE KindSignatures #-}

    module GHC.Iface.Errors.Types (

        MissingInterfaceError(..)
      , InterfaceLookingFor(..)
      , IfaceMessage(..)
      , ReadInterfaceError(..)
      , CantFindInstalled(..)
      , CantFindInstalledReason(..)
      , FindingModuleOrInterface(..)

      , BuildingCabalPackage(..)

      , IfaceMessageOpts(..)

      ) where

    import GHC.Prelude

    import GHC.Types.Name (Name)
    import GHC.Types.TyThing (TyThing)
    import GHC.Unit.Types (Module, InstalledModule, UnitId, Unit)
    import GHC.Unit.State (UnitState, ModuleSuggestion, ModuleOrigin, UnusableUnit, UnitInfo)
    import GHC.Exception.Type (SomeException)
    import GHC.Unit.Types ( IsBootInterface )
    import Language.Haskell.Syntax.Module.Name ( ModuleName )

    import GHC.Generics ( Generic )
    import GHC.Unit.Module.Location

    data IfaceMessageOpts = IfaceMessageOpts { IfaceMessageOpts -> Bool
    ifaceShowTriedFiles :: !Bool -- ^ Whether to show files we tried to look for or not when printing loader errors
                                             , IfaceMessageOpts -> BuildingCabalPackage
    ifaceBuildingCabalPackage :: !BuildingCabalPackage
                                             }

    data InterfaceLookingFor
      = LookingForName   !Name
      | LookingForHiBoot !Module
      | LookingForModule !ModuleName !IsBootInterface
      | LookingForSig    !InstalledModule

    data IfaceMessage
      = Can'tFindInterface
          MissingInterfaceError
          InterfaceLookingFor
      | Can'tFindNameInInterface
          Name
          [TyThing] -- possibly relevant TyThings
      | CircularImport !Module
      deriving (forall x. IfaceMessage -> Rep IfaceMessage x)
    -> (forall x. Rep IfaceMessage x -> IfaceMessage)
    -> Generic IfaceMessage
    forall x. Rep IfaceMessage x -> IfaceMessage
    forall x. IfaceMessage -> Rep IfaceMessage x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. IfaceMessage -> Rep IfaceMessage x
    from :: forall x. IfaceMessage -> Rep IfaceMessage x
    $cto :: forall x. Rep IfaceMessage x -> IfaceMessage
    to :: forall x. Rep IfaceMessage x -> IfaceMessage
    Generic

    data MissingInterfaceError
      = BadSourceImport !Module
      | HomeModError !InstalledModule !ModLocation
      | DynamicHashMismatchError !Module !ModLocation

      | CantFindErr !UnitState FindingModuleOrInterface CantFindInstalled

      | BadIfaceFile ReadInterfaceError
      | FailedToLoadDynamicInterface Module ReadInterfaceError
        deriving (forall x. MissingInterfaceError -> Rep MissingInterfaceError x)
    -> (forall x. Rep MissingInterfaceError x -> MissingInterfaceError)
    -> Generic MissingInterfaceError
    forall x. Rep MissingInterfaceError x -> MissingInterfaceError
    forall x. MissingInterfaceError -> Rep MissingInterfaceError x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. MissingInterfaceError -> Rep MissingInterfaceError x
    from :: forall x. MissingInterfaceError -> Rep MissingInterfaceError x
    $cto :: forall x. Rep MissingInterfaceError x -> MissingInterfaceError
    to :: forall x. Rep MissingInterfaceError x -> MissingInterfaceError
    Generic

    data ReadInterfaceError
      = ExceptionOccurred        FilePath SomeException
      | HiModuleNameMismatchWarn FilePath Module Module
      deriving (forall x. ReadInterfaceError -> Rep ReadInterfaceError x)
    -> (forall x. Rep ReadInterfaceError x -> ReadInterfaceError)
    -> Generic ReadInterfaceError
    forall x. Rep ReadInterfaceError x -> ReadInterfaceError
    forall x. ReadInterfaceError -> Rep ReadInterfaceError x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. ReadInterfaceError -> Rep ReadInterfaceError x
    from :: forall x. ReadInterfaceError -> Rep ReadInterfaceError x
    $cto :: forall x. Rep ReadInterfaceError x -> ReadInterfaceError
    to :: forall x. Rep ReadInterfaceError x -> ReadInterfaceError
    Generic

    data CantFindInstalledReason
      = NoUnitIdMatching UnitId [UnitInfo]
      | MissingPackageFiles UnitId [FilePath]
      | MissingPackageWayFiles String UnitId [FilePath]
      | ModuleSuggestion [ModuleSuggestion] [FilePath]
      | NotAModule
      | CouldntFindInFiles [FilePath]
      | GenericMissing
          [(Unit, Maybe UnitInfo)] [Unit]
          [UnusableUnit] [FilePath]
      | MultiplePackages [(Module, ModuleOrigin)]
      deriving (forall x.
     CantFindInstalledReason -> Rep CantFindInstalledReason x)
    -> (forall x.
        Rep CantFindInstalledReason x -> CantFindInstalledReason)
    -> Generic CantFindInstalledReason
    forall x. Rep CantFindInstalledReason x -> CantFindInstalledReason
    forall x. CantFindInstalledReason -> Rep CantFindInstalledReason x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. CantFindInstalledReason -> Rep CantFindInstalledReason x
    from :: forall x. CantFindInstalledReason -> Rep CantFindInstalledReason x
    $cto :: forall x. Rep CantFindInstalledReason x -> CantFindInstalledReason
    to :: forall x. Rep CantFindInstalledReason x -> CantFindInstalledReason
    Generic

    data CantFindInstalled =
      CantFindInstalled ModuleName CantFindInstalledReason
      deriving (forall x. CantFindInstalled -> Rep CantFindInstalled x)
    -> (forall x. Rep CantFindInstalled x -> CantFindInstalled)
    -> Generic CantFindInstalled
    forall x. Rep CantFindInstalled x -> CantFindInstalled
    forall x. CantFindInstalled -> Rep CantFindInstalled x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. CantFindInstalled -> Rep CantFindInstalled x
    from :: forall x. CantFindInstalled -> Rep CantFindInstalled x
    $cto :: forall x. Rep CantFindInstalled x -> CantFindInstalled
    to :: forall x. Rep CantFindInstalled x -> CantFindInstalled
    Generic
    data FindingModuleOrInterface = FindingModule
                                  | FindingInterface

    -- | Pass to a 'DriverMessage' the information whether or not the
    -- '-fbuilding-cabal-package' flag is set.
    data BuildingCabalPackage
      = YesBuildingCabalPackage
      | NoBuildingCabalPackage
      deriving BuildingCabalPackage -> BuildingCabalPackage -> Bool
    (BuildingCabalPackage -> BuildingCabalPackage -> Bool)
    -> (BuildingCabalPackage -> BuildingCabalPackage -> Bool)
    -> Eq BuildingCabalPackage
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: BuildingCabalPackage -> BuildingCabalPackage -> Bool
    == :: BuildingCabalPackage -> BuildingCabalPackage -> Bool
    $c/= :: BuildingCabalPackage -> BuildingCabalPackage -> Bool
    /= :: BuildingCabalPackage -> BuildingCabalPackage -> Bool
    Eq