haskell / haddock

Haskell Documentation Tool
www.haskell.org/haddock/
BSD 2-Clause "Simplified" License
362 stars 242 forks source link

haddock 2.26.0 ignores both `--ignore-all-exports` and `{-# OPTIONS_HADDOCK ignore-exports #-}` #1531

Open nicuveo opened 1 year ago

nicuveo commented 1 year ago

Hi y'all; here's a regression in 2.26.0. In short: both the ignore-exports pragma and the --ignore-all-exports option are ignored.

Small repro case

Given a file Foo.hs containing the following:

{-# OPTIONS_HADDOCK ignore-exports #-}
module Foo (foo) where

foo :: Int
foo = 42
bar :: Int
bar = 42

invoking haddock yields the following:

$ haddock-9.2.4 -V
Haddock version 2.26.0, (c) Simon Marlow 2006
Ported to use the GHC API by David Waern 2006-2008

$ haddock-9.2.4 --ignore-all-exports --html Foo.hs
   0% (  0 /  2) in 'Foo'
  Missing documentation for:
    Module header
    foo (Foo.hs:5)

$ grep -q bar Foo.html && echo found || echo not found
not found

and the generated HTML file does not contain bar.

Expected behaviour

Running the same command on the same file with haddock version 2.25.1 yields the following:

$ haddock-9.0 -V
Haddock version 2.25.1, (c) Simon Marlow 2006
Ported to use the GHC API by David Waern 2006-2008

$ haddock-9.0 --ignore-all-exports --html Foo.hs
   0% (  0 /  2) in 'Foo'
  Missing documentation for:
    Module header
    foo (Foo.hs:5)
    bar (Foo.hs:8)

$ grep -q bar Foo.html && echo found || echo not found
found

and the generated file correctly contains bar.

nicuveo commented 1 year ago

I have just tried with haddock 2.27.0, installed with ghc 9.4.2, and the bug is still there, FWIW. I have cloned the repo, I'll test to see if it is also broken on main.

Kleidukos commented 1 year ago

Hi @nicuveo, and thank you very much for this report.

nicuveo commented 1 year ago

NP! I have just checked, that bug is also present on main. I'll have a quick look to see if I can figure it out myself.

nicuveo commented 1 year ago

I have found the issue, I think: Haddock.Interface.Create.fullModuleContents does correctly iterate over all declarations in the file, including the non-exported ones if the flag is set. However, if the declaration is not part of the AvailInfo list obtained from GHC, the element is skipped: https://github.com/haskell/haddock/blob/d6b30b11b60543f0a48665f9581af81d25aa9fec/haddock-api/src/Haddock/Interface/Create.hs#L1041-L1046

And indeed, if i trace the list of AvailInfo, obtained from the tcg_exports field of the TcGblEnv, i can see it only contains foo, not bar.

My working hypothesis is therefore that, between 9.0 and 9.2, GHC dropped non-exported "avails" from that list. If that's correct, then there are several possible avenues to explore to fix this bug:

nicuveo commented 1 year ago

Ahah! In branch ghc-9.0, there was a actual_exports list that made an AvailInfo for everything in the case where the option was set; so this is not a new GHC behaviour, just a regression in haddock. I'll open a PR. :)

nicuveo commented 1 year ago

Oh this is infuriating: a test was introduced in #1082 when this option was last fixed, and bf8ba2525e95319bdbcfc81d06448b646eba3a57 JUST BROKE THE TEST (see this diff).

nicuveo commented 1 year ago

Ah, interesting: actual_exports was introduced in b93c6351afdfaf452ad9830a5f8536a353320a84, but apparently it never made it into main? I'm a bit confused by branch management in this project, I have to admit.