Unless we're in one-shot mode, emit an error if we attempt to
demand-load interfaces for home modules. This can only happen in one
way (that I'm aware of): typing a qualified name at the GHCi prompt
that refers to a module that isn't loaded. Previously you got a
cryptic message about not finding an interface file, now you get:
Prelude> Foo.a
<interactive>:1:0:
attempting to use module `Foo' (Foo.hs) which is not loaded
Of course you can still refer to package modules like this without
loading them explicitly, only home modules are affected, and the
behaviour is exactly the same as if you try to ':browse Foo' and
Foo isn't loaded.
import BinIface
import Panic
import BinIface
import Panic
+import Control.Monad (when)
import Data.List
import Data.Maybe
import Data.IORef
import Data.List
import Data.Maybe
import Data.IORef
-- The (src_imp == mi_boot iface) test checks that the already-loaded
-- interface isn't a boot iface. This can conceivably happen,
-- if an earlier import had a before we got to real imports. I think.
-- The (src_imp == mi_boot iface) test checks that the already-loaded
-- interface isn't a boot iface. This can conceivably happen,
-- if an earlier import had a before we got to real imports. I think.
- { let { hi_boot_file = case from of
+ let { hi_boot_file = case from of
ImportByUser usr_boot -> usr_boot
ImportBySystem -> sys_boot
ImportByUser usr_boot -> usr_boot
ImportBySystem -> sys_boot
-- Look for the file
; hsc_env <- getTopEnv
-- Look for the file
; hsc_env <- getTopEnv
- ; mb_found <- ioToIOEnv (findHiFile hsc_env mod hi_boot_file)
+ ; mb_found <- ioToIOEnv (findExactModule hsc_env mod)
+
+ err | notFound err -> do
{ traceIf (ptext SLIT("...not found"))
; dflags <- getDOpts
; returnM (Failed (cannotFindInterface dflags
(moduleName mod) err)) } ;
{ traceIf (ptext SLIT("...not found"))
; dflags <- getDOpts
; returnM (Failed (cannotFindInterface dflags
(moduleName mod) err)) } ;
-
- Succeeded file_path -> do
-- Found file, so read it
-- Found file, so read it
- { traceIf (ptext SLIT("readIFace") <+> text file_path)
+ { let { file_path = addBootSuffix_maybe hi_boot_file (ml_hi_file loc) }
+
+ ; if thisPackage dflags == modulePackageId mod
+ && not (isOneShot (ghcMode dflags))
+ then returnM (Failed (homeModError mod loc))
+ else do {
+
+ ; traceIf (ptext SLIT("readIFace") <+> text file_path)
; read_result <- readIface mod file_path hi_boot_file
; case read_result of
Failed err -> returnM (Failed (badIfaceFile file_path err))
; read_result <- readIface mod file_path hi_boot_file
; case read_result of
Failed err -> returnM (Failed (badIfaceFile file_path err))
| otherwise ->
returnM (Succeeded (iface, file_path))
-- Don't forget to fill in the package name...
| otherwise ->
returnM (Succeeded (iface, file_path))
-- Don't forget to fill in the package name...
- }}}
-
-findHiFile :: HscEnv -> Module -> IsBootInterface
- -> IO (MaybeErr FindResult FilePath)
-findHiFile hsc_env mod hi_boot_file
- = do
- maybe_found <- findExactModule hsc_env mod
- case maybe_found of
- Found loc mod -> return (Succeeded path)
- where
- path = addBootSuffix_maybe hi_boot_file (ml_hi_file loc)
- err -> return (Failed err)
+ }}}}
+
+notFound (Found _ _) = False
+notFound _ = True
\end{code}
@readIface@ tries just the one file.
\end{code}
@readIface@ tries just the one file.
]
]
where iface_file = doubleQuotes (text file_path)
]
]
where iface_file = doubleQuotes (text file_path)
+
+homeModError mod location
+ = ptext SLIT("attempting to use module ") <> quotes (ppr mod)
+ <> (case ml_hs_file location of
+ Just file -> space <> parens (text file)
+ Nothing -> empty)
+ <+> ptext SLIT("which is not loaded")