haskell / haddock

Haskell Documentation Tool

Home Page:www.haskell.org/haddock/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

nicuveo opened this issue · comments

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.

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.

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

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.

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:

case lookupNameEnv availEnv nm of
Just avail ->
availExportItem is_sig modMap thisMod
semMod warnings exportedNames maps fixMap
splices instIfaceMap dflags avail
Nothing -> pure [])

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:

  • in the case where the AvailInfo is not found, try to fall back to some existing information?
  • change the invocation of GHC / the type of the plugin, to get the full information?

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. :)

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

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