diff options
author | Edward Z. Yang <ezyang@cs.stanford.edu> | 2015-07-20 20:16:35 -0700 |
---|---|---|
committer | Edward Z. Yang <ezyang@cs.stanford.edu> | 2015-07-20 20:16:35 -0700 |
commit | 0c6c015d42c2bd0ee008f790c7c0cb4c5b78ca6b (patch) | |
tree | ce6b716a99806eb3b3e60a8e1aaecce8799e7593 /compiler/iface/LoadIface.hs | |
parent | b4ef8b8badaa43872a843778e8fa9da943955d38 (diff) | |
download | haskell-0c6c015d42c2bd0ee008f790c7c0cb4c5b78ca6b.tar.gz |
Revert "Revert "Change loadSrcInterface to return a list of ModIface""
This reverts commit c60704fc405149407c155e297433f1cc299ae58a.
Diffstat (limited to 'compiler/iface/LoadIface.hs')
-rw-r--r-- | compiler/iface/LoadIface.hs | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/compiler/iface/LoadIface.hs b/compiler/iface/LoadIface.hs index 2a8943ca11..bdfba7c9bd 100644 --- a/compiler/iface/LoadIface.hs +++ b/compiler/iface/LoadIface.hs @@ -234,26 +234,61 @@ needWiredInHomeIface _ = False ************************************************************************ -} +-- 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 @@ -262,9 +297,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 |