ghc -M fails to correctly account for indirect SOURCE imports
Consider a program such as:
--- in the unit1 unit
-- Foo.hs-boot
module Foo where
foo :: String
-- Foo.hs
module Foo where
foo :: String
foo = "hi"
-- ... additional cyclic bindings here which make `Foo.hs-boot` necessary
-- Bar.hs
module Bar where
import {-# SOURCE #-} Foo
bar = ... foo ...
--- in the unit2 unit
-- Baz.hs
module Baz where
import Bar
baz = ... bar ...
Imagine running ghc -M on Baz.hs. It will contain something like the following:
Baz.o : Baz.hs Bar.o
Bar.o : Bar.hs Foo.o-boot
Foo.o : Foo.hs
Foo.o-boot : Foo.hs-boot
This seems perfectly reasonable: it captures the dependency structure of the user's program.
However, if we consider what happens during one-shot compilation, we will see that it isn't quite right. Specifically, imagine that baz get an unfolding, which will naturally contain a reference to Bar.bar (which was SOURCE imported). When we compile Baz GHC will see that:
- we need a declaration for
Foo.fooin order to unfoldBar.bar - the user hasn't imported
Bardirectly; this means thatGHC.Iface.Load.importDeclwill callloadInterfacewithImportBySystem -
GHC.Iface.Load.loadInterfacecallsGHC.Iface.Load.wantHiBootFileto determine what it should load -
wantHiBootFilesees thatFoois not in the unit currently being compiled. Consequently, it responds withNotBoot - GHC attempts to load
Foo.hiinstead ofFoo.hi-bootas theghc -Moutput claims
Edited by Sebastian Graf