summaryrefslogtreecommitdiff
path: root/compiler/iface
diff options
context:
space:
mode:
authorEdward Z. Yang <ezyang@cs.stanford.edu>2014-11-04 02:13:37 -0800
committerEdward Z. Yang <ezyang@cs.stanford.edu>2014-11-26 16:51:33 -0800
commit8c7d20d8c7e63a1123755aae69cfa825c749e9e8 (patch)
tree06d5bd08a1d98d95e440c9e2ac42a9c6a7b12244 /compiler/iface
parent7a6fb9833f988f5f48590d3c5d4c7827b1b13fc7 (diff)
downloadhaskell-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.lhs50
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