summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2022-10-26 15:07:30 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-12-08 22:45:27 -0500
commit74c9bf914b31bfdd4353b7ff31efd2d3725bd2bb (patch)
treee871e06237af1dea4880bcaa6b8e0b43036e805a
parent0a76d7d415cfa8facfa6d36101210f9e2e3ff0a6 (diff)
downloadhaskell-74c9bf914b31bfdd4353b7ff31efd2d3725bd2bb.tar.gz
backpack: Be more careful when adding together ImportAvails
There was some code in the signature merging logic which added together the ImportAvails of the signature and the signature which was merged into it. This had the side-effect of making the merged signature depend on the signature (via a normal module dependency). The intention was to propagate orphan instances through the merge but this also messed up recompilation logic because we shouldn't be attempting to load B.hi when mergeing it. The fix is to just combine the part of ImportAvails that we intended to (transitive info, orphan instances and type family instances) rather than the whole thing.
-rw-r--r--compiler/GHC/Iface/Recomp.hs3
-rw-r--r--compiler/GHC/Tc/Utils/Backpack.hs30
2 files changed, 22 insertions, 11 deletions
diff --git a/compiler/GHC/Iface/Recomp.hs b/compiler/GHC/Iface/Recomp.hs
index db923a0982..886bc12192 100644
--- a/compiler/GHC/Iface/Recomp.hs
+++ b/compiler/GHC/Iface/Recomp.hs
@@ -589,7 +589,7 @@ checkDependencies hsc_env summary iface
liftIO $
check_mods (sort hs) prev_dep_mods
`recompThen`
- let allPkgDeps = sortBy (comparing snd) $ nubOrdOn snd (ps ++ implicit_deps ++ bkpk_units)
+ let allPkgDeps = sortBy (comparing snd) $ nubOrdOn snd (ps ++ implicit_deps)
in check_packages allPkgDeps prev_dep_pkgs
where
@@ -613,7 +613,6 @@ checkDependencies hsc_env summary iface
prev_dep_mods = map (second gwib_mod) $ Set.toAscList $ dep_direct_mods (mi_deps iface)
prev_dep_pkgs = Set.toAscList (Set.union (dep_direct_pkgs (mi_deps iface))
(dep_plugin_pkgs (mi_deps iface)))
- bkpk_units = map ((fsLit "Signature",) . instUnitInstanceOf . moduleUnit) (requirementMerges units (moduleName (mi_module iface)))
implicit_deps = map (fsLit "Implicit",) (implicitPackageDeps dflags)
diff --git a/compiler/GHC/Tc/Utils/Backpack.hs b/compiler/GHC/Tc/Utils/Backpack.hs
index 7e5f339d3f..a73c01c90f 100644
--- a/compiler/GHC/Tc/Utils/Backpack.hs
+++ b/compiler/GHC/Tc/Utils/Backpack.hs
@@ -856,7 +856,6 @@ mergeSignatures
-- we hope that we get lucky / the overlapping instances never
-- get used, but it is not a very good situation to be in.
--
- hsc_env <- getTopEnv
let merge_inst (insts, inst_env) inst
| memberInstEnv inst_env inst -- test DFun Type equality
= (insts, inst_env)
@@ -867,18 +866,17 @@ mergeSignatures
(insts, inst_env) = foldl' merge_inst
(tcg_insts tcg_env, tcg_inst_env tcg_env)
(instEnvElts $ md_insts details)
- -- This is a HACK to prevent calculateAvails from including imp_mod
- -- in the listing. We don't want it because a module is NOT
+ -- Use mi_deps directly rather than calculateAvails.
+ -- because a module is NOT
-- supposed to include itself in its dep_orphs/dep_finsts. See #13214
- iface' = iface { mi_final_exts = (mi_final_exts iface){ mi_orphan = False, mi_finsts = False } }
- home_unit = hsc_home_unit hsc_env
- other_home_units = hsc_all_home_unit_ids hsc_env
- avails = plusImportAvails (tcg_imports tcg_env) $
- calculateAvails home_unit other_home_units iface' False NotBoot ImportedBySystem
+ avails = tcg_imports tcg_env
+ deps = mi_deps iface
+ avails_with_trans = addTransitiveDepInfo avails deps
+
return tcg_env {
tcg_inst_env = inst_env,
tcg_insts = insts,
- tcg_imports = avails,
+ tcg_imports = avails_with_trans,
tcg_merged =
if outer_mod == mi_module iface
-- Don't add ourselves!
@@ -912,6 +910,20 @@ mergeSignatures
return tcg_env
+-- | Add on the necessary transitive information from the merged signature to
+-- the 'ImportAvails' of the result of merging. This propagates the orphan instances
+-- which were in the transitive closure of the signature through the merge.
+addTransitiveDepInfo :: ImportAvails -- ^ From the signature resulting from the merge
+ -> Dependencies -- ^ From the original signature
+ -> ImportAvails
+addTransitiveDepInfo avails deps =
+ -- Avails for the merged in signature
+ -- Add on transitive information from the signature but nothing else..
+ -- because we do not "import" the signature.
+ avails { imp_orphs = imp_orphs avails ++ dep_orphs deps
+ , imp_finsts = imp_finsts avails ++ dep_finsts deps
+ , imp_sig_mods = imp_sig_mods avails ++ dep_sig_mods deps }
+
-- | Top-level driver for signature instantiation (run when compiling
-- an @hsig@ file.)
tcRnInstantiateSignature ::