From b682041ed1cbeaf5aa501f85e4e46a6d2e39da3a Mon Sep 17 00:00:00 2001
From: Alec Theriault <alec.theriault@gmail.com>
Date: Tue, 26 Feb 2019 08:46:45 -0800
Subject: [PATCH] Fix bogus identifier defaulting

This avoids a situation in which an identifier would get defaulted to
a completely different identifier. Prior to this commit, the 'Bug1035'
test case would hyperlink 'Foo' into 'Bar'!

Fixes #1035.
---
 .../src/Haddock/Interface/LexParseRn.hs       |  14 +-
 html-test/ref/Bug1035.html                    | 146 ++++++++++++++++++
 html-test/src/Bug1035.hs                      |   9 ++
 3 files changed, 160 insertions(+), 9 deletions(-)
 create mode 100644 html-test/ref/Bug1035.html
 create mode 100644 html-test/src/Bug1035.hs

diff --git a/haddock-api/src/Haddock/Interface/LexParseRn.hs b/haddock-api/src/Haddock/Interface/LexParseRn.hs
index faf23728a0..0b40ed3cde 100644
--- a/haddock-api/src/Haddock/Interface/LexParseRn.hs
+++ b/haddock-api/src/Haddock/Interface/LexParseRn.hs
@@ -19,7 +19,6 @@ module Haddock.Interface.LexParseRn
   , processModuleHeader
   ) where
 
-import Avail
 import Control.Arrow
 import Control.Monad
 import Data.Functor (($>))
@@ -200,10 +199,9 @@ ambiguous :: DynFlags
           -> [GlobalRdrElt] -- ^ More than one @gre@s sharing the same `RdrName` above.
           -> ErrMsgM (Doc Name)
 ambiguous dflags x gres = do
-  let noChildren = map availName (gresToAvailInfo gres)
-      dflt = maximumBy (comparing (isLocalName &&& isTyConName)) noChildren
+  let dflt = maximumBy (comparing (gre_lcl &&& isTyConName . gre_name)) gres
       msg = "Warning: " ++ showNsRdrName dflags x ++ " is ambiguous. It is defined\n" ++
-            concatMap (\n -> "    * " ++ defnLoc n ++ "\n") (map gre_name gres) ++
+            concatMap (\n -> "    * " ++ defnLoc n ++ "\n") gres ++
             "    You may be able to disambiguate the identifier by qualifying it or\n" ++
             "    by specifying the type/value namespace explicitly.\n" ++
             "    Defaulting to the one defined " ++ defnLoc dflt
@@ -212,12 +210,10 @@ ambiguous dflags x gres = do
   -- of the same name, but not the only constructor.
   -- For example, for @data D = C | D@, someone may want to reference the @D@
   -- constructor.
-  when (length noChildren > 1) $ tell [msg]
-  pure (DocIdentifier (x $> dflt))
+  when (length (gresToAvailInfo gres) > 1) $ tell [msg]
+  pure (DocIdentifier (x $> gre_name dflt))
   where
-    isLocalName (nameSrcLoc -> RealSrcLoc {}) = True
-    isLocalName _ = False
-    defnLoc = showSDoc dflags . pprNameDefnLoc
+    defnLoc = showSDoc dflags . pprNameDefnLoc . gre_name
 
 -- | Handle value-namespaced names that cannot be for values.
 --
diff --git a/html-test/ref/Bug1035.html b/html-test/ref/Bug1035.html
new file mode 100644
index 0000000000..946fc2354b
--- /dev/null
+++ b/html-test/ref/Bug1035.html
@@ -0,0 +1,146 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+><head
+  ><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
+     /><meta name="viewport" content="width=device-width, initial-scale=1"
+     /><title
+    >Bug1035</title
+    ><link href="#" rel="stylesheet" type="text/css" title="NewOcean"
+     /><link rel="stylesheet" type="text/css" href="#"
+     /><link rel="stylesheet" type="text/css" href="#"
+     /><script src="haddock-bundle.min.js" async="async" type="text/javascript"
+    ></script
+    ><script type="text/x-mathjax-config"
+    >MathJax.Hub.Config({ tex2jax: { processClass: &quot;mathjax&quot;, ignoreClass: &quot;.*&quot; } });</script
+    ><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"
+    ></script
+    ></head
+  ><body
+  ><div id="package-header"
+    ><span class="caption empty"
+      ></span
+      ><ul class="links" id="page-menu"
+      ><li
+	><a href="#"
+	  >Contents</a
+	  ></li
+	><li
+	><a href="#"
+	  >Index</a
+	  ></li
+	></ul
+      ></div
+    ><div id="content"
+    ><div id="module-header"
+      ><table class="info"
+	><tr
+	  ><th
+	    >Safe Haskell</th
+	    ><td
+	    >Safe</td
+	    ></tr
+	  ></table
+	><p class="caption"
+	>Bug1035</p
+	></div
+      ><div id="synopsis"
+      ><details id="syn"
+	><summary
+	  >Synopsis</summary
+	  ><ul class="details-toggle" data-details-id="syn"
+	  ><li class="src short"
+	    ><span class="keyword"
+	      >data</span
+	      > <a href="#"
+	      >Foo</a
+	      > = <a href="#"
+	      >Bar</a
+	      ></li
+	    ><li class="src short"
+	    ><span class="keyword"
+	      >data</span
+	      > <a href="#"
+	      >Bar</a
+	      > = <a href="#"
+	      >Foo</a
+	      ></li
+	    ><li class="src short"
+	    ><a href="#"
+	      >foo</a
+	      > :: ()</li
+	    ></ul
+	  ></details
+	></div
+      ><div id="interface"
+      ><h1
+	>Documentation</h1
+	><div class="top"
+	><p class="src"
+	  ><span class="keyword"
+	    >data</span
+	    > <a id="t:Foo" class="def"
+	    >Foo</a
+	    > <a href="#" class="selflink"
+	    >#</a
+	    ></p
+	  ><div class="subs constructors"
+	  ><p class="caption"
+	    >Constructors</p
+	    ><table
+	    ><tr
+	      ><td class="src"
+		><a id="v:Bar" class="def"
+		  >Bar</a
+		  ></td
+		><td class="doc empty"
+		></td
+		></tr
+	      ></table
+	    ></div
+	  ></div
+	><div class="top"
+	><p class="src"
+	  ><span class="keyword"
+	    >data</span
+	    > <a id="t:Bar" class="def"
+	    >Bar</a
+	    > <a href="#" class="selflink"
+	    >#</a
+	    ></p
+	  ><div class="subs constructors"
+	  ><p class="caption"
+	    >Constructors</p
+	    ><table
+	    ><tr
+	      ><td class="src"
+		><a id="v:Foo" class="def"
+		  >Foo</a
+		  ></td
+		><td class="doc empty"
+		></td
+		></tr
+	      ></table
+	    ></div
+	  ></div
+	><div class="top"
+	><p class="src"
+	  ><a id="v:foo" class="def"
+	    >foo</a
+	    > :: () <a href="#" class="selflink"
+	    >#</a
+	    ></p
+	  ><div class="doc"
+	  ><p
+	    >A link to <code
+	      ><a href="#" title="Bug1035"
+		>Bar</a
+		></code
+	      ></p
+	    ></div
+	  ></div
+	></div
+      ></div
+    ><div id="footer"
+    ></div
+    ></body
+  ></html
+>
\ No newline at end of file
diff --git a/html-test/src/Bug1035.hs b/html-test/src/Bug1035.hs
new file mode 100644
index 0000000000..3516c08f27
--- /dev/null
+++ b/html-test/src/Bug1035.hs
@@ -0,0 +1,9 @@
+module Bug1035 where
+
+data Foo = Bar
+
+data Bar = Foo
+
+-- | A link to 'Bar'
+foo :: ()
+foo = ()
-- 
GitLab