diff options
author | Edward Z. Yang <ezyang@cs.stanford.edu> | 2014-11-04 02:13:37 -0800 |
---|---|---|
committer | Edward Z. Yang <ezyang@cs.stanford.edu> | 2014-11-26 16:51:33 -0800 |
commit | 8c7d20d8c7e63a1123755aae69cfa825c749e9e8 (patch) | |
tree | 06d5bd08a1d98d95e440c9e2ac42a9c6a7b12244 /compiler/iface | |
parent | 7a6fb9833f988f5f48590d3c5d4c7827b1b13fc7 (diff) | |
download | haskell-8c7d20d8c7e63a1123755aae69cfa825c749e9e8.tar.gz |
Change loadSrcInterface to return a list of ModIface
Summary:
This change is in preparation to support signature imports, which may pull in
multiple interface files. At the moment, the list always contains only one
element, but in a later patch it may contain more.
I also adjusted some error reporting code so that it didn't take the full
iface, but just whether or not the iface in question was a boot module.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
Test Plan: validate
Reviewers: simonpj, austin
Subscribers: thomie, carter
Differential Revision: https://phabricator.haskell.org/D436
Diffstat (limited to 'compiler/iface')
-rw-r--r-- | compiler/iface/LoadIface.lhs | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/compiler/iface/LoadIface.lhs b/compiler/iface/LoadIface.lhs index 3b2f7f25c9..250ef2f182 100644 --- a/compiler/iface/LoadIface.lhs +++ b/compiler/iface/LoadIface.lhs @@ -78,26 +78,61 @@ import System.FilePath %************************************************************************ \begin{code} +-- Note [Un-ambiguous multiple interfaces] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- When a user writes an import statement, this usually causes a *single* +-- interface file to be loaded. However, the game is different when +-- signatures are being imported. Suppose in packages p and q we have +-- signatures: +-- +-- module A where +-- foo :: Int +-- +-- module A where +-- bar :: Int +-- +-- If both packages are exposed and I am importing A, I should see a +-- "unified" signature: +-- +-- module A where +-- foo :: Int +-- bar :: Int +-- +-- The way we achieve this is having the module lookup for A load and return +-- multiple interface files, which we will then process as if there were +-- "multiple" imports: +-- +-- import "p" A +-- import "q" A +-- +-- Doing so does not cause any ambiguity, because any overlapping identifiers +-- are guaranteed to have the same name if the backing implementations of the +-- two signatures are the same (a condition which is checked by 'Packages'.) + + -- | Load the interface corresponding to an @import@ directive in -- source code. On a failure, fail in the monad with an error message. +-- See Note [Un-ambiguous multiple interfaces] for why the return type +-- is @[ModIface]@ loadSrcInterface :: SDoc -> ModuleName -> IsBootInterface -- {-# SOURCE #-} ? -> Maybe FastString -- "package", if any - -> RnM ModIface + -> RnM [ModIface] loadSrcInterface doc mod want_boot maybe_pkg = do { res <- loadSrcInterface_maybe doc mod want_boot maybe_pkg ; case res of - Failed err -> failWithTc err - Succeeded iface -> return iface } + Failed err -> failWithTc err + Succeeded ifaces -> return ifaces } --- | Like 'loadSrcInterface', but returns a 'MaybeErr'. +-- | Like 'loadSrcInterface', but returns a 'MaybeErr'. See also +-- Note [Un-ambiguous multiple interfaces] loadSrcInterface_maybe :: SDoc -> ModuleName -> IsBootInterface -- {-# SOURCE #-} ? -> Maybe FastString -- "package", if any - -> RnM (MaybeErr MsgDoc ModIface) + -> RnM (MaybeErr MsgDoc [ModIface]) loadSrcInterface_maybe doc mod want_boot maybe_pkg -- We must first find which Module this import refers to. This involves @@ -106,9 +141,12 @@ loadSrcInterface_maybe doc mod want_boot maybe_pkg -- interface; it will call the Finder again, but the ModLocation will be -- cached from the first search. = do { hsc_env <- getTopEnv + -- ToDo: findImportedModule should return a list of interfaces ; res <- liftIO $ findImportedModule hsc_env mod maybe_pkg ; case res of - Found _ mod -> initIfaceTcRn $ loadInterface doc mod (ImportByUser want_boot) + Found _ mod -> fmap (fmap (:[])) + . initIfaceTcRn + $ loadInterface doc mod (ImportByUser want_boot) err -> return (Failed (cannotFindInterface (hsc_dflags hsc_env) mod err)) } -- | Load interface directly for a fully qualified 'Module'. (This is a fairly |