diff options
author | Ben Gamari <bgamari.foss@gmail.com> | 2017-08-26 16:17:18 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-08-29 09:54:07 -0400 |
commit | db3a8e168ad81f54ec58eebc4c75a0eaad889daf (patch) | |
tree | 929a7878218f5bbf609d74788e74e5e5a255f06c | |
parent | 248ad30385acc0f81f1959b6345a7388be76dc85 (diff) | |
download | haskell-db3a8e168ad81f54ec58eebc4c75a0eaad889daf.tar.gz |
desugar: Ensure that a module's dep_orphs doesn't contain itself
Consider that we have two modules, A and B, both with hs-boot files,
* A.hs contains a SOURCE import of B
* B.hs-boot contains a SOURCE import of A
* A.hs-boot declares an orphan instance
* A.hs defines the orphan instance
In this case, B's dep_orphs will contain A due to its SOURCE import of
A. Consequently, A will contain itself in its imp_orphs due to its
import of B. This fact would end up being recorded in A's interface
file. This would then break the invariant asserted by calculateAvails
that a module does not itself in its dep_orphs. This was the cause
of #14128.
The solution is to remove self-references from imp_orphs when
constructing dep_orphs; we already did a similar thing for dep_mods. I
believe we should do the same for dep_finsts, although I'm treating this
as a separate bug.
Reviewers: austin
Subscribers: rwbarton, thomie
Differential Revision: https://phabricator.haskell.org/D3892
-rw-r--r-- | compiler/deSugar/DsUsage.hs | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/compiler/deSugar/DsUsage.hs b/compiler/deSugar/DsUsage.hs index 8158a8e122..3f302fadf6 100644 --- a/compiler/deSugar/DsUsage.hs +++ b/compiler/deSugar/DsUsage.hs @@ -38,7 +38,7 @@ mkDependencies -- Template Haskell used? th_used <- readIORef th_var let dep_mods = modDepsElts (delFromUFM (imp_dep_mods imports) - (moduleName mod)) + (moduleName mod)) -- M.hi-boot can be in the imp_dep_mods, but we must remove -- it before recording the modules on which this one depends! -- (We want to retain M.hi-boot in imp_dep_mods so that @@ -46,6 +46,10 @@ mkDependencies -- on M.hi-boot, and hence that we should do the hi-boot consistency -- check.) + dep_orphs = filter (/= mod) (imp_orphs imports) + -- We must also remove self-references from imp_orphs. See + -- #14128. + pkgs | th_used = Set.insert (toInstalledUnitId thUnitId) (imp_dep_pkgs imports) | otherwise = imp_dep_pkgs imports @@ -57,7 +61,7 @@ mkDependencies return Deps { dep_mods = dep_mods, dep_pkgs = dep_pkgs', - dep_orphs = sortBy stableModuleCmp (imp_orphs imports), + dep_orphs = dep_orphs, dep_finsts = sortBy stableModuleCmp (imp_finsts imports) } -- sort to get into canonical order -- NB. remember to use lexicographic ordering |