In module B
I have documentation with a link 'A.foo'
, linking to the foo
member of module A
. In module A
I import module B
. Haddock renders this as a link to A.html#t:foo
, namely pointing at the type foo
(which does not exist) not the function foo
, which is at A.html#v:foo
.
t:
for variables that start with a lower case letter? Is that a bug? For 'A.Foo'
I can see that it could be a type or a constructor, so there are namespacing issues. For foo
it seems a variable is at least most plausible.foo
. I tried anchors, but they render as the module name, and for direct hyperlinks you have no control over the displayed text.t:[a-z]
with v:
), but that requires a custom Setup.hs which causes problems and is quite ugly.foo
is a variable.A
to B
without introducing circular imports, which is vile to add purely for documentation.I am running into this problem in the Shake documentation, where as an example removeFilesAfter
does not get the right link.
I can partially answer the the first question (Why?); not sure if it is a bug or desired behaviour.
When haddock resolves references in LexParseRn.rename
, it tries to look up the identifier in the environment (via lookupGRE_RdrName
). This ought to fail. Next it looks as what the thing could mean (using dataTcOccs
from GHC’s RnEnv
). The relevant lines are:
dataTcOccs :: RdrName -> [RdrName]
-- Return both the given name and the same name promoted to the TcClsName
-- namespace. This is useful when we aren't sure which we are looking at.
dataTcOccs rdr_name
[...]
| isDataOcc occ || isVarOcc occ
= [rdr_name, rdr_name_tc]
[...]
where
occ = rdrNameOcc rdr_name
rdr_name_tc = setRdrNameSpace rdr_name tcName
so it returns the name first interpreted as whatever it was before (likely a link to a value), and then interpreted as a type constructor. How can a regular name be a type constructor? My guess is that this was added when TypeOperators were reformed in GHC 7.6, which now do share the namespace with value-level operators.
Then haddock matches on the result: If the first one is a type constructor, use that, otherwise use the second. So either it was a type constructor before, then this is used. Or it was not, but then the modified version generated by dataTcOccs
is to be used.
It seems to me that haddock should just always use the first option here, and the code is just a mislead copy from how multiple results are used when they can actually be resolved.
This was a Haddock bug #228 and Neil's Haddock bug #253 and the fix has been upstream for few months. You can build GHC HEAD and rebuild your documentation or wait for 7.8 and do it then.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With