Opened 4 years ago

Last modified 3 years ago

#10333 new bug

hs-boot modification doesn't induce recompilation

Reported by: ezyang Owned by: ezyang
Priority: normal Milestone:
Component: Compiler Version: 7.11
Keywords: hs-boot Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: GHC accepts invalid program Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description (last modified by ezyang)

Consider these modules:


module X where


module Y where
import {-# SOURCE #-} X
data T = T
data S = S T


module X where
import Y

ghc --make Y.hs will compile fine. Now, modify X.hs-boot to add a data T (which will cause an ambiguous identifier error in Y.hx. Run ghc --make Y.hs and nothing happens!

(You might also notice something else a bit funny, which is that X.hs gets compiled, even though it's not directly in the import chain of Y. I think this might be intentional but I'm not sure.)

Discovered this while poking around #10182.

Change History (6)

comment:1 Changed 4 years ago by ezyang

Description: modified (diff)

comment:2 Changed 4 years ago by ezyang

I've diagnosed why this is occurring.

GhcMake does some fancy business to determine if an object is stable. Essentially, object stability is a timestamped based check which tries to let GhcMake avoid recompiling source files which didn't change at all.

However, stability is computed on a per module name basis, preferentially checking to see if hs files have been updated. This means that if you modify an hs-boot file but not the hs file, GHC will still consider it "stable" because the stability check was done on hs; and will proceed to tell the one-shot compiler that the file was not modified.

I'm not sure what the correct solution to this problem is.

You might also notice something else a bit funny, which is that X.hs gets compiled, even though it's not directly in the import chain of Y. I think this might be intentional but I'm not sure.

This is because there is explicit logic in GhcMake to make this be the case.

comment:3 Changed 4 years ago by Edward Z. Yang <ezyang@…>

In 06d46b1e/ghc:

Unify hsig and hs-boot; add preliminary "hs-boot" merging.

This patch drops the file level distinction between hs-boot and hsig;
we figure out which one we are compiling based on whether or not there
is a corresponding hs file lying around.

To make the "import A" syntax continue to work for bare hs-boot
files, we also introduce hs-boot merging, which takes an A.hi-boot
and converts it to an A.hi when there is no A.hs file in scope.
This will be generalized in Backpack to merge multiple A.hi files together;
which means we can jettison the "load multiple interface files" functionality.

This works automatically for --make, but for one-shot compilation
we need a new mode: ghc --merge-requirements A will generate an A.hi/A.o
from a local A.hi-boot file; Backpack will extend this mechanism further.

Has Haddock submodule update to deal with change in msHsFilePath behavior.

    - This commit drops support for the hsig extension. Can
      we support it?  It's annoying because the finder code is
      written with the assumption that where there's an hs-boot
      file, there's always an hs file too.  To support hsig, you'd
      have to probe two locations.  Easier to just not support it.

    - #10333 affects us, modifying an hs-boot still doesn't trigger

    - See compiler/main/Finder.hs: this diff is very skeevy, but
      it seems to work.

    - This code cunningly doesn't drop hs-boot files from the
      "drop hs-boot files" module graph, if they don't have a
      corresponding hs file.  I have no idea if this actually is useful.

Signed-off-by: Edward Z. Yang <>

Test Plan: validate

Reviewers: simonpj, austin, bgamari, spinda

Subscribers: thomie

Differential Revision:

comment:4 Changed 4 years ago by ezyang

Related: #11013

comment:5 Changed 4 years ago by ezyang

Owner: set to ezyang

comment:6 Changed 3 years ago by simonpj

Keywords: hs-boot added
Note: See TracTickets for help on using tickets.