summaryrefslogtreecommitdiff
path: root/compiler/main/DriverPipeline.hs
diff options
context:
space:
mode:
authorEdward Z. Yang <ezyang@cs.stanford.edu>2014-08-07 18:32:12 +0100
committerEdward Z. Yang <ezyang@cs.stanford.edu>2014-10-24 15:49:41 -0700
commitaa4799534225e3fc6bbde0d5e5eeab8868cc3111 (patch)
tree60d77acae2286263a1c75d87d93d333bce5b01c0 /compiler/main/DriverPipeline.hs
parent5bb73d79a83bca57dc431421ca1e022f34b8dec9 (diff)
downloadhaskell-aa4799534225e3fc6bbde0d5e5eeab8868cc3111.tar.gz
Implementation of hsig (module signatures), per #9252
Summary: Module signatures, like hs-boot files, are Haskell modules which omit value definitions and contain only signatures. This patchset implements one particular aspect of module signature, namely compiling them against a concrete implementation. It works like this: when we compile an hsig file, we must be told (via the -sig-of flag) what module this signature is implementing. The signature is compiled into an interface file which reexports precisely the entities mentioned in the signature file. We also verify that the interface is compatible with the implementation. This feature is useful in a few situations: 1. Like explicit import lists, signatures can be used to reduce sensitivity to upstream changes. However, a signature can be defined once and then reused by many modules. 2. Signatures can be used to quickly check if a new upstream version is compatible, by typechecking just the signatures and not the actual modules. 3. A signature can be used to mediate separate modular development, where the signature is used as a placeholder for functionality which is loaded in later. (This is only half useful at the moment, since typechecking against signatures without implementations is not implemented in this patchset.) Unlike hs-boot files, hsig files impose no performance overhead. This patchset punts on the type class instances (and type families) problem: instances simply leak from the implementation to the signature. You can explicitly specify what instances you expect to have, and those will be checked, but you may get more instances than you asked for. Our eventual plan is to allow hiding instances, but to consider all transitively reachable instances when considering overlap and soundness. ToDo: signature merging: when a module is provided by multiple signatures for the same base implementation, we should not consider this ambiguous. ToDo: at the moment, signatures do not constitute use-sites, so if you write a signature for a deprecated function, you won't get a warning when you compile the signature. Future work: The ability to feed in shaping information so that we can take advantage of more type equalities than might be immediately evident. Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu> Test Plan: validate and new tests Reviewers: simonpj, simonmar, hvr, austin Subscribers: simonmar, relrod, ezyang, carter, goldfire Differential Revision: https://phabricator.haskell.org/D130 GHC Trac Issues: #9252
Diffstat (limited to 'compiler/main/DriverPipeline.hs')
-rw-r--r--compiler/main/DriverPipeline.hs17
1 files changed, 11 insertions, 6 deletions
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index 43f31e6f2c..870d99409e 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -197,7 +197,7 @@ compileOne' m_tc_result mHscMessage
case hsc_lang of
HscInterpreted ->
case ms_hsc_src summary of
- HsBootFile ->
+ t | isHsBootOrSig t ->
do (iface, _changed, details) <- hscSimpleIface hsc_env tc_result mb_old_hash
return (HomeModInfo{ hm_details = details,
hm_iface = iface,
@@ -231,7 +231,7 @@ compileOne' m_tc_result mHscMessage
do (iface, changed, details) <- hscSimpleIface hsc_env tc_result mb_old_hash
when (gopt Opt_WriteInterface dflags) $
hscWriteIface dflags iface changed summary
- let linkable = if isHsBoot src_flavour
+ let linkable = if isHsBootOrSig src_flavour
then maybe_old_linkable
else Just (LM (ms_hs_date summary) this_mod [])
return (HomeModInfo{ hm_details = details,
@@ -240,7 +240,7 @@ compileOne' m_tc_result mHscMessage
_ ->
case ms_hsc_src summary of
- HsBootFile ->
+ t | isHsBootOrSig t ->
do (iface, changed, details) <- hscSimpleIface hsc_env tc_result mb_old_hash
hscWriteIface dflags iface changed summary
touchObjectFile dflags object_filename
@@ -341,7 +341,11 @@ link' dflags batch_attempt_linking hpt
LinkStaticLib -> True
_ -> platformBinariesAreStaticLibs (targetPlatform dflags)
- home_mod_infos = eltsUFM hpt
+ -- Don't attempt to link hsigs; they don't actually produce objects.
+ -- This is in contrast to hs-boot files, which will /eventually/
+ -- get objects.
+ home_mod_infos =
+ filter ((==Nothing).mi_sig_of.hm_iface) (eltsUFM hpt)
-- the packages we depend on
pkg_deps = concatMap (map fst . dep_pkgs . mi_deps . hm_iface) home_mod_infos
@@ -1511,8 +1515,8 @@ getLocation src_flavour mod_name = do
location1 <- liftIO $ mkHomeModLocation2 dflags mod_name basename suff
-- Boot-ify it if necessary
- let location2 | isHsBoot src_flavour = addBootSuffixLocn location1
- | otherwise = location1
+ let location2 | HsBootFile <- src_flavour = addBootSuffixLocn location1
+ | otherwise = location1
-- Take -ohi into account if present
@@ -2199,6 +2203,7 @@ joinObjectFiles dflags o_files output_fn = do
-- | What phase to run after one of the backend code generators has run
hscPostBackendPhase :: DynFlags -> HscSource -> HscTarget -> Phase
hscPostBackendPhase _ HsBootFile _ = StopLn
+hscPostBackendPhase _ HsigFile _ = StopLn
hscPostBackendPhase dflags _ hsc_lang =
case hsc_lang of
HscC -> HCc