{-# LANGUAGE CPP #-}

-- | Dynamically lookup up values from modules and loading them.
module GHC.Runtime.Loader (
        initializePlugins,
        -- * Loading plugins
        loadFrontendPlugin,

        -- * Force loading information
        forceLoadModuleInterfaces,
        forceLoadNameModuleInterface,
        forceLoadTyCon,

        -- * Finding names
        lookupRdrNameInModuleForPlugins,

        -- * Loading values
        getValueSafely,
        getHValueSafely,
        lessUnsafeCoerce
    ) where

import GHC.Prelude

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

import GHC.Linker.Loader       ( loadModule, loadName )
import GHC.Runtime.Interpreter ( wormhole, hscInterp )
import GHC.Runtime.Interpreter.Types

import GHC.Tc.Utils.Monad      ( initTcInteractive, initIfaceTcRn )
import GHC.Iface.Load          ( loadPluginInterface, cannotFindModule )
import GHC.Rename.Names ( gresFromAvails )
import GHC.Builtin.Names ( pluginTyConName, frontendPluginTyConName )

import GHC.Driver.Env
import GHCi.RemoteTypes  ( HValue )
import GHC.Core.Type     ( Type, eqType, mkTyConTy )
import GHC.Core.TyCon    ( TyCon )

import GHC.Types.SrcLoc        ( noSrcSpan )
import GHC.Types.Name    ( Name, nameModule_maybe )
import GHC.Types.Id      ( idType )
import GHC.Types.TyThing
import GHC.Types.Name.Occurrence ( OccName, mkVarOcc )
import GHC.Types.Name.Reader   ( RdrName, ImportSpec(..), ImpDeclSpec(..)
                               , ImpItemSpec(..), mkGlobalRdrEnv, lookupGRE_RdrName
                               , greMangledName, mkRdrQual )

import GHC.Unit.Finder         ( findPluginModule, FindResult(..) )
import GHC.Unit.Module   ( Module, ModuleName )
import GHC.Unit.Module.ModIface

import GHC.Utils.Panic
import GHC.Utils.Logger
import GHC.Utils.Error
import GHC.Utils.Outputable
import GHC.Utils.Exception

import GHC.Data.FastString

import Control.Monad     ( unless )
import Data.Maybe        ( mapMaybe )
import Unsafe.Coerce     ( unsafeCoerce )

-- | Loads the plugins specified in the pluginModNames field of the dynamic
-- flags. Should be called after command line arguments are parsed, but before
-- actual compilation starts. Idempotent operation. Should be re-called if
-- pluginModNames or pluginModNameOpts changes.
initializePlugins :: HscEnv -> IO HscEnv
initializePlugins :: HscEnv -> IO HscEnv
initializePlugins HscEnv
hsc_env
    -- plugins not changed
  | forall a b. (a -> b) -> [a] -> [b]
map LoadedPlugin -> ModuleName
lpModuleName (HscEnv -> [LoadedPlugin]
hsc_plugins HscEnv
hsc_env) forall a. Eq a => a -> a -> Bool
== DynFlags -> [ModuleName]
pluginModNames DynFlags
dflags
   -- arguments not changed
  , forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all LoadedPlugin -> Bool
same_args (HscEnv -> [LoadedPlugin]
hsc_plugins HscEnv
hsc_env)
  = forall (m :: * -> *) a. Monad m => a -> m a
return HscEnv
hsc_env -- no need to reload plugins
  | Bool
otherwise
  = do [LoadedPlugin]
loaded_plugins <- HscEnv -> IO [LoadedPlugin]
loadPlugins HscEnv
hsc_env
       let hsc_env' :: HscEnv
hsc_env' = HscEnv
hsc_env { hsc_plugins :: [LoadedPlugin]
hsc_plugins = [LoadedPlugin]
loaded_plugins }
       forall (m :: * -> *) a.
Monad m =>
HscEnv -> PluginOperation m a -> a -> m a
withPlugins HscEnv
hsc_env' Plugin -> [CommandLineOption] -> HscEnv -> IO HscEnv
driverPlugin HscEnv
hsc_env'
  where
    plugin_args :: [(ModuleName, CommandLineOption)]
plugin_args = DynFlags -> [(ModuleName, CommandLineOption)]
pluginModNameOpts DynFlags
dflags
    same_args :: LoadedPlugin -> Bool
same_args LoadedPlugin
p = PluginWithArgs -> [CommandLineOption]
paArguments (LoadedPlugin -> PluginWithArgs
lpPlugin LoadedPlugin
p) forall a. Eq a => a -> a -> Bool
== forall {b}. LoadedPlugin -> [(ModuleName, b)] -> [b]
argumentsForPlugin LoadedPlugin
p [(ModuleName, CommandLineOption)]
plugin_args
    argumentsForPlugin :: LoadedPlugin -> [(ModuleName, b)] -> [b]
argumentsForPlugin LoadedPlugin
p = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter ((forall a. Eq a => a -> a -> Bool
== LoadedPlugin -> ModuleName
lpModuleName LoadedPlugin
p) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst)
    dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env

loadPlugins :: HscEnv -> IO [LoadedPlugin]
loadPlugins :: HscEnv -> IO [LoadedPlugin]
loadPlugins HscEnv
hsc_env
  = do { forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ModuleName]
to_load) forall a b. (a -> b) -> a -> b
$
           HscEnv -> IO ()
checkExternalInterpreter HscEnv
hsc_env
       ; [(Plugin, ModIface)]
plugins <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ModuleName -> IO (Plugin, ModIface)
loadPlugin [ModuleName]
to_load
       ; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ModuleName -> (Plugin, ModIface) -> LoadedPlugin
attachOptions [ModuleName]
to_load [(Plugin, ModIface)]
plugins }
  where
    dflags :: DynFlags
dflags  = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
    to_load :: [ModuleName]
to_load = DynFlags -> [ModuleName]
pluginModNames DynFlags
dflags

    attachOptions :: ModuleName -> (Plugin, ModIface) -> LoadedPlugin
attachOptions ModuleName
mod_nm (Plugin
plug, ModIface
mod) =
        PluginWithArgs -> ModIface -> LoadedPlugin
LoadedPlugin (Plugin -> [CommandLineOption] -> PluginWithArgs
PluginWithArgs Plugin
plug (forall a. [a] -> [a]
reverse [CommandLineOption]
options)) ModIface
mod
      where
        options :: [CommandLineOption]
options = [ CommandLineOption
option | (ModuleName
opt_mod_nm, CommandLineOption
option) <- DynFlags -> [(ModuleName, CommandLineOption)]
pluginModNameOpts DynFlags
dflags
                            , ModuleName
opt_mod_nm forall a. Eq a => a -> a -> Bool
== ModuleName
mod_nm ]
    loadPlugin :: ModuleName -> IO (Plugin, ModIface)
loadPlugin = forall a.
OccName -> Name -> HscEnv -> ModuleName -> IO (a, ModIface)
loadPlugin' (CommandLineOption -> OccName
mkVarOcc CommandLineOption
"plugin") Name
pluginTyConName HscEnv
hsc_env


loadFrontendPlugin :: HscEnv -> ModuleName -> IO FrontendPlugin
loadFrontendPlugin :: HscEnv -> ModuleName -> IO FrontendPlugin
loadFrontendPlugin HscEnv
hsc_env ModuleName
mod_name = do
    HscEnv -> IO ()
checkExternalInterpreter HscEnv
hsc_env
    forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a.
OccName -> Name -> HscEnv -> ModuleName -> IO (a, ModIface)
loadPlugin' (CommandLineOption -> OccName
mkVarOcc CommandLineOption
"frontendPlugin") Name
frontendPluginTyConName
                HscEnv
hsc_env ModuleName
mod_name

-- #14335
checkExternalInterpreter :: HscEnv -> IO ()
checkExternalInterpreter :: HscEnv -> IO ()
checkExternalInterpreter HscEnv
hsc_env = case Interp -> InterpInstance
interpInstance forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HscEnv -> Maybe Interp
hsc_interp HscEnv
hsc_env of
  Just (ExternalInterp {})
    -> forall e a. Exception e => e -> IO a
throwIO (CommandLineOption -> GhcException
InstallationError CommandLineOption
"Plugins require -fno-external-interpreter")
  Maybe InterpInstance
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

loadPlugin' :: OccName -> Name -> HscEnv -> ModuleName -> IO (a, ModIface)
loadPlugin' :: forall a.
OccName -> Name -> HscEnv -> ModuleName -> IO (a, ModIface)
loadPlugin' OccName
occ_name Name
plugin_name HscEnv
hsc_env ModuleName
mod_name
  = do { let plugin_rdr_name :: RdrName
plugin_rdr_name = ModuleName -> OccName -> RdrName
mkRdrQual ModuleName
mod_name OccName
occ_name
             dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
       ; Maybe (Name, ModIface)
mb_name <- HscEnv -> ModuleName -> RdrName -> IO (Maybe (Name, ModIface))
lookupRdrNameInModuleForPlugins HscEnv
hsc_env ModuleName
mod_name
                        RdrName
plugin_rdr_name
       ; case Maybe (Name, ModIface)
mb_name of {
            Maybe (Name, ModIface)
Nothing ->
                forall a. GhcException -> IO a
throwGhcExceptionIO (CommandLineOption -> GhcException
CmdLineError forall a b. (a -> b) -> a -> b
$ DynFlags -> SDoc -> CommandLineOption
showSDoc DynFlags
dflags forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
hsep
                          [ CommandLineOption -> SDoc
text CommandLineOption
"The module", forall a. Outputable a => a -> SDoc
ppr ModuleName
mod_name
                          , CommandLineOption -> SDoc
text CommandLineOption
"did not export the plugin name"
                          , forall a. Outputable a => a -> SDoc
ppr RdrName
plugin_rdr_name ]) ;
            Just (Name
name, ModIface
mod_iface) ->

     do { TyCon
plugin_tycon <- HscEnv -> Name -> IO TyCon
forceLoadTyCon HscEnv
hsc_env Name
plugin_name
        ; Maybe a
mb_plugin <- forall a. HscEnv -> Name -> Type -> IO (Maybe a)
getValueSafely HscEnv
hsc_env Name
name (TyCon -> Type
mkTyConTy TyCon
plugin_tycon)
        ; case Maybe a
mb_plugin of
            Maybe a
Nothing ->
                forall a. GhcException -> IO a
throwGhcExceptionIO (CommandLineOption -> GhcException
CmdLineError forall a b. (a -> b) -> a -> b
$ DynFlags -> SDoc -> CommandLineOption
showSDoc DynFlags
dflags forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
hsep
                          [ CommandLineOption -> SDoc
text CommandLineOption
"The value", forall a. Outputable a => a -> SDoc
ppr Name
name
                          , CommandLineOption -> SDoc
text CommandLineOption
"did not have the type"
                          , forall a. Outputable a => a -> SDoc
ppr Name
pluginTyConName, CommandLineOption -> SDoc
text CommandLineOption
"as required"])
            Just a
plugin -> forall (m :: * -> *) a. Monad m => a -> m a
return (a
plugin, ModIface
mod_iface) } } }


-- | Force the interfaces for the given modules to be loaded. The 'SDoc' parameter is used
-- for debugging (@-ddump-if-trace@) only: it is shown as the reason why the module is being loaded.
forceLoadModuleInterfaces :: HscEnv -> SDoc -> [Module] -> IO ()
forceLoadModuleInterfaces :: HscEnv -> SDoc -> [Module] -> IO ()
forceLoadModuleInterfaces HscEnv
hsc_env SDoc
doc [Module]
modules
    = (forall a. HscEnv -> TcM a -> IO (Messages DecoratedSDoc, Maybe a)
initTcInteractive HscEnv
hsc_env forall a b. (a -> b) -> a -> b
$
       forall a. IfG a -> TcRn a
initIfaceTcRn forall a b. (a -> b) -> a -> b
$
       forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall lcl. SDoc -> Module -> IfM lcl ModIface
loadPluginInterface SDoc
doc) [Module]
modules)
      forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | Force the interface for the module containing the name to be loaded. The 'SDoc' parameter is used
-- for debugging (@-ddump-if-trace@) only: it is shown as the reason why the module is being loaded.
forceLoadNameModuleInterface :: HscEnv -> SDoc -> Name -> IO ()
forceLoadNameModuleInterface :: HscEnv -> SDoc -> Name -> IO ()
forceLoadNameModuleInterface HscEnv
hsc_env SDoc
reason Name
name = do
    let name_modules :: [Module]
name_modules = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Name -> Maybe Module
nameModule_maybe [Name
name]
    HscEnv -> SDoc -> [Module] -> IO ()
forceLoadModuleInterfaces HscEnv
hsc_env SDoc
reason [Module]
name_modules

-- | Load the 'TyCon' associated with the given name, come hell or high water. Fails if:
--
-- * The interface could not be loaded
-- * The name is not that of a 'TyCon'
-- * The name did not exist in the loaded module
forceLoadTyCon :: HscEnv -> Name -> IO TyCon
forceLoadTyCon :: HscEnv -> Name -> IO TyCon
forceLoadTyCon HscEnv
hsc_env Name
con_name = do
    HscEnv -> SDoc -> Name -> IO ()
forceLoadNameModuleInterface HscEnv
hsc_env (CommandLineOption -> SDoc
text CommandLineOption
"contains a name used in an invocation of loadTyConTy") Name
con_name

    Maybe TyThing
mb_con_thing <- HscEnv -> Name -> IO (Maybe TyThing)
lookupType HscEnv
hsc_env Name
con_name
    case Maybe TyThing
mb_con_thing of
        Maybe TyThing
Nothing -> forall a. DynFlags -> SDoc -> IO a
throwCmdLineErrorS DynFlags
dflags forall a b. (a -> b) -> a -> b
$ Name -> SDoc
missingTyThingError Name
con_name
        Just (ATyCon TyCon
tycon) -> forall (m :: * -> *) a. Monad m => a -> m a
return TyCon
tycon
        Just TyThing
con_thing -> forall a. DynFlags -> SDoc -> IO a
throwCmdLineErrorS DynFlags
dflags forall a b. (a -> b) -> a -> b
$ Name -> TyThing -> SDoc
wrongTyThingError Name
con_name TyThing
con_thing
  where dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env

-- | Loads the value corresponding to a 'Name' if that value has the given 'Type'. This only provides limited safety
-- in that it is up to the user to ensure that that type corresponds to the type you try to use the return value at!
--
-- If the value found was not of the correct type, returns @Nothing@. Any other condition results in an exception:
--
-- * If we could not load the names module
-- * If the thing being loaded is not a value
-- * If the Name does not exist in the module
-- * If the link failed

getValueSafely :: HscEnv -> Name -> Type -> IO (Maybe a)
getValueSafely :: forall a. HscEnv -> Name -> Type -> IO (Maybe a)
getValueSafely HscEnv
hsc_env Name
val_name Type
expected_type = do
  Maybe HValue
mb_hval <- case Hooks -> Maybe (HscEnv -> Name -> Type -> IO (Maybe HValue))
getValueSafelyHook Hooks
hooks of
    Maybe (HscEnv -> Name -> Type -> IO (Maybe HValue))
Nothing -> Interp -> HscEnv -> Name -> Type -> IO (Maybe HValue)
getHValueSafely Interp
interp HscEnv
hsc_env Name
val_name Type
expected_type
    Just HscEnv -> Name -> Type -> IO (Maybe HValue)
h  -> HscEnv -> Name -> Type -> IO (Maybe HValue)
h                      HscEnv
hsc_env Name
val_name Type
expected_type
  case Maybe HValue
mb_hval of
    Maybe HValue
Nothing   -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Just HValue
hval -> do
      a
value <- forall a b. Logger -> DynFlags -> CommandLineOption -> a -> IO b
lessUnsafeCoerce Logger
logger DynFlags
dflags CommandLineOption
"getValueSafely" HValue
hval
      forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just a
value)
  where
    interp :: Interp
interp = HscEnv -> Interp
hscInterp HscEnv
hsc_env
    dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
    logger :: Logger
logger = HscEnv -> Logger
hsc_logger HscEnv
hsc_env
    hooks :: Hooks
hooks  = HscEnv -> Hooks
hsc_hooks HscEnv
hsc_env

getHValueSafely :: Interp -> HscEnv -> Name -> Type -> IO (Maybe HValue)
getHValueSafely :: Interp -> HscEnv -> Name -> Type -> IO (Maybe HValue)
getHValueSafely Interp
interp HscEnv
hsc_env Name
val_name Type
expected_type = do
    HscEnv -> SDoc -> Name -> IO ()
forceLoadNameModuleInterface HscEnv
hsc_env (CommandLineOption -> SDoc
text CommandLineOption
"contains a name used in an invocation of getHValueSafely") Name
val_name
    -- Now look up the names for the value and type constructor in the type environment
    Maybe TyThing
mb_val_thing <- HscEnv -> Name -> IO (Maybe TyThing)
lookupType HscEnv
hsc_env Name
val_name
    case Maybe TyThing
mb_val_thing of
        Maybe TyThing
Nothing -> forall a. DynFlags -> SDoc -> IO a
throwCmdLineErrorS DynFlags
dflags forall a b. (a -> b) -> a -> b
$ Name -> SDoc
missingTyThingError Name
val_name
        Just (AnId Id
id) -> do
            -- Check the value type in the interface against the type recovered from the type constructor
            -- before finally casting the value to the type we assume corresponds to that constructor
            if Type
expected_type Type -> Type -> Bool
`eqType` Id -> Type
idType Id
id
             then do
                -- Link in the module that contains the value, if it has such a module
                case Name -> Maybe Module
nameModule_maybe Name
val_name of
                    Just Module
mod -> do Interp -> HscEnv -> Module -> IO ()
loadModule Interp
interp HscEnv
hsc_env Module
mod
                                   forall (m :: * -> *) a. Monad m => a -> m a
return ()
                    Maybe Module
Nothing ->  forall (m :: * -> *) a. Monad m => a -> m a
return ()
                -- Find the value that we just linked in and cast it given that we have proved it's type
                HValue
hval <- do
                  ForeignHValue
v <- Interp -> HscEnv -> Name -> IO ForeignHValue
loadName Interp
interp HscEnv
hsc_env Name
val_name
                  forall a. Interp -> ForeignRef a -> IO a
wormhole Interp
interp ForeignHValue
v
                forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just HValue
hval)
             else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
        Just TyThing
val_thing -> forall a. DynFlags -> SDoc -> IO a
throwCmdLineErrorS DynFlags
dflags forall a b. (a -> b) -> a -> b
$ Name -> TyThing -> SDoc
wrongTyThingError Name
val_name TyThing
val_thing
   where dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env

-- | Coerce a value as usual, but:
--
-- 1) Evaluate it immediately to get a segfault early if the coercion was wrong
--
-- 2) Wrap it in some debug messages at verbosity 3 or higher so we can see what happened
--    if it /does/ segfault
lessUnsafeCoerce :: Logger -> DynFlags -> String -> a -> IO b
lessUnsafeCoerce :: forall a b. Logger -> DynFlags -> CommandLineOption -> a -> IO b
lessUnsafeCoerce Logger
logger DynFlags
dflags CommandLineOption
context a
what = do
    Logger -> DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg Logger
logger DynFlags
dflags Int
3 forall a b. (a -> b) -> a -> b
$
        (CommandLineOption -> SDoc
text CommandLineOption
"Coercing a value in") SDoc -> SDoc -> SDoc
<+> (CommandLineOption -> SDoc
text CommandLineOption
context) SDoc -> SDoc -> SDoc
<> (CommandLineOption -> SDoc
text CommandLineOption
"...")
    b
output <- forall a. a -> IO a
evaluate (forall a b. a -> b
unsafeCoerce a
what)
    Logger -> DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg Logger
logger DynFlags
dflags Int
3 (CommandLineOption -> SDoc
text CommandLineOption
"Successfully evaluated coercion")
    forall (m :: * -> *) a. Monad m => a -> m a
return b
output


-- | Finds the 'Name' corresponding to the given 'RdrName' in the
-- context of the 'ModuleName'. Returns @Nothing@ if no such 'Name'
-- could be found. Any other condition results in an exception:
--
-- * If the module could not be found
-- * If we could not determine the imports of the module
--
-- Can only be used for looking up names while loading plugins (and is
-- *not* suitable for use within plugins).  The interface file is
-- loaded very partially: just enough that it can be used, without its
-- rules and instances affecting (and being linked from!) the module
-- being compiled.  This was introduced by 57d6798.
--
-- Need the module as well to record information in the interface file
lookupRdrNameInModuleForPlugins :: HscEnv -> ModuleName -> RdrName
                                -> IO (Maybe (Name, ModIface))
lookupRdrNameInModuleForPlugins :: HscEnv -> ModuleName -> RdrName -> IO (Maybe (Name, ModIface))
lookupRdrNameInModuleForPlugins HscEnv
hsc_env ModuleName
mod_name RdrName
rdr_name = do
    -- First find the unit the module resides in by searching exposed units and home modules
    FindResult
found_module <- HscEnv -> ModuleName -> IO FindResult
findPluginModule HscEnv
hsc_env ModuleName
mod_name
    case FindResult
found_module of
        Found ModLocation
_ Module
mod -> do
            -- Find the exports of the module
            (Messages DecoratedSDoc
_, Maybe ModIface
mb_iface) <- forall a. HscEnv -> TcM a -> IO (Messages DecoratedSDoc, Maybe a)
initTcInteractive HscEnv
hsc_env forall a b. (a -> b) -> a -> b
$
                             forall a. IfG a -> TcRn a
initIfaceTcRn forall a b. (a -> b) -> a -> b
$
                             forall lcl. SDoc -> Module -> IfM lcl ModIface
loadPluginInterface SDoc
doc Module
mod
            case Maybe ModIface
mb_iface of
                Just ModIface
iface -> do
                    -- Try and find the required name in the exports
                    let decl_spec :: ImpDeclSpec
decl_spec = ImpDeclSpec { is_mod :: ModuleName
is_mod = ModuleName
mod_name, is_as :: ModuleName
is_as = ModuleName
mod_name
                                                , is_qual :: Bool
is_qual = Bool
False, is_dloc :: SrcSpan
is_dloc = SrcSpan
noSrcSpan }
                        imp_spec :: ImportSpec
imp_spec = ImpDeclSpec -> ImpItemSpec -> ImportSpec
ImpSpec ImpDeclSpec
decl_spec ImpItemSpec
ImpAll
                        env :: GlobalRdrEnv
env = [GlobalRdrElt] -> GlobalRdrEnv
mkGlobalRdrEnv (Maybe ImportSpec -> [AvailInfo] -> [GlobalRdrElt]
gresFromAvails (forall a. a -> Maybe a
Just ImportSpec
imp_spec) (forall (phase :: ModIfacePhase). ModIface_ phase -> [AvailInfo]
mi_exports ModIface
iface))
                    case RdrName -> GlobalRdrEnv -> [GlobalRdrElt]
lookupGRE_RdrName RdrName
rdr_name GlobalRdrEnv
env of
                        [GlobalRdrElt
gre] -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (GlobalRdrElt -> Name
greMangledName GlobalRdrElt
gre, ModIface
iface))
                        []    -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
                        [GlobalRdrElt]
_     -> forall a. CommandLineOption -> a
panic CommandLineOption
"lookupRdrNameInModule"

                Maybe ModIface
Nothing -> forall a. DynFlags -> SDoc -> IO a
throwCmdLineErrorS DynFlags
dflags forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
hsep [CommandLineOption -> SDoc
text CommandLineOption
"Could not determine the exports of the module", forall a. Outputable a => a -> SDoc
ppr ModuleName
mod_name]
        FindResult
err -> forall a. DynFlags -> SDoc -> IO a
throwCmdLineErrorS DynFlags
dflags forall a b. (a -> b) -> a -> b
$ HscEnv -> ModuleName -> FindResult -> SDoc
cannotFindModule HscEnv
hsc_env ModuleName
mod_name FindResult
err
  where
    dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
    doc :: SDoc
doc = CommandLineOption -> SDoc
text CommandLineOption
"contains a name used in an invocation of lookupRdrNameInModule"

wrongTyThingError :: Name -> TyThing -> SDoc
wrongTyThingError :: Name -> TyThing -> SDoc
wrongTyThingError Name
name TyThing
got_thing = [SDoc] -> SDoc
hsep [CommandLineOption -> SDoc
text CommandLineOption
"The name", forall a. Outputable a => a -> SDoc
ppr Name
name, PtrString -> SDoc
ptext (CommandLineOption -> PtrString
sLit CommandLineOption
"is not that of a value but rather a"), TyThing -> SDoc
pprTyThingCategory TyThing
got_thing]

missingTyThingError :: Name -> SDoc
missingTyThingError :: Name -> SDoc
missingTyThingError Name
name = [SDoc] -> SDoc
hsep [CommandLineOption -> SDoc
text CommandLineOption
"The name", forall a. Outputable a => a -> SDoc
ppr Name
name, PtrString -> SDoc
ptext (CommandLineOption -> PtrString
sLit CommandLineOption
"is not in the type environment: are you sure it exists?")]

throwCmdLineErrorS :: DynFlags -> SDoc -> IO a
throwCmdLineErrorS :: forall a. DynFlags -> SDoc -> IO a
throwCmdLineErrorS DynFlags
dflags = forall a. CommandLineOption -> IO a
throwCmdLineError forall b c a. (b -> c) -> (a -> b) -> a -> c
. DynFlags -> SDoc -> CommandLineOption
showSDoc DynFlags
dflags

throwCmdLineError :: String -> IO a
throwCmdLineError :: forall a. CommandLineOption -> IO a
throwCmdLineError = forall a. GhcException -> IO a
throwGhcExceptionIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandLineOption -> GhcException
CmdLineError