desugar: Ensure that a module's dep_orphs doesn't contain itself
authorBen Gamari <bgamari.foss@gmail.com>
Sat, 26 Aug 2017 20:17:18 +0000 (16:17 -0400)
committerBen Gamari <ben@smart-cactus.org>
Tue, 19 Sep 2017 20:16:05 +0000 (16:16 -0400)
commit609f48547367cfb1f0d263bb2b6aaec88a528182
tree69915adc4eae3b5c623b794ce41dcf670645d125
parent717240921c440852b748cc26c60142243c51e4d1
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

(cherry picked from commit db3a8e168ad81f54ec58eebc4c75a0eaad889daf)
compiler/deSugar/DsUsage.hs