[project @ 2004-04-05 10:26:28 by simonpj]
authorsimonpj <unknown>
Mon, 5 Apr 2004 10:26:28 +0000 (10:26 +0000)
committersimonpj <unknown>
Mon, 5 Apr 2004 10:26:28 +0000 (10:26 +0000)
Don't convert Exact RdrNames into Orig ones when comparing RdrNames.
This implicit conversion (via nukeExact) was making the carefully-distinct
RdrNames conjured up by Template Haskell into the same RdrName, and
that in turn was reporting duplicate bindings.

I'm not 100% certain that the implicit conversion isn't needed
for some other purpose, but it seems unclean anyway, so I'm removing
it, and we'll see if anything else breaks.

ghc/compiler/basicTypes/RdrName.lhs

index d858dbc..e84a391 100644 (file)
@@ -86,7 +86,7 @@ data RdrName
        --  (b) when converting names to the RdrNames in IfaceTypes
        --      Here an Exact RdrName always contains an External Name
        --      (Internal Names are converted to simple Unquals)
-       --  (c) possibly, by the meta-programming stuff
+       --  (c) by Template Haskell, when TH has generated a unique name
 \end{code}
 
 
@@ -234,21 +234,28 @@ instance Ord RdrName where
     a >= b = case (a `compare` b) of { LT -> False; EQ -> True;  GT -> True  }
     a >         b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True  }
 
-       -- Unqual < Qual < Orig
-       -- We always convert Exact to Orig before comparing
-    compare (Exact n1) (Exact n2) | n1==n2 = EQ        -- Short cut
-                                 | otherwise = nukeExact n1 `compare` nukeExact n2
-    compare (Exact n1) n2                    = nukeExact n1 `compare` n2
-    compare n1       (Exact n2)              = n1 `compare` nukeExact n2
-
-
-    compare (Qual m1 o1) (Qual m2 o2) = (o1 `compare` o2) `thenCmp` (m1 `compare` m2) 
-    compare (Orig m1 o1) (Orig m2 o2) = (o1 `compare` o2) `thenCmp` (m1 `compare` m2) 
+       -- Exact < Unqual < Qual < Orig
+       -- [Note: Apr 2004] We used to use nukeExact to convert Exact to Orig 
+       --      before comparing so that Prelude.map == the exact Prelude.map, but 
+       --      that meant that we reported duplicates when renaming bindings 
+       --      generated by Template Haskell; e.g 
+       --      do { n1 <- newName "foo"; n2 <- newName "foo"; 
+       --           <decl involving n1,n2> }
+       --      I think we can do without this conversion
+    compare (Exact n1) (Exact n2) = n1 `compare` n2
+    compare (Exact n1) n2        = LT
+
+    compare (Unqual _)   (Exact _)    = GT
     compare (Unqual o1)  (Unqual  o2) = o1 `compare` o2
     compare (Unqual _)   _           = LT
+
+    compare (Qual _ _)   (Exact _)    = GT
+    compare (Qual _ _)   (Unqual _)   = GT
+    compare (Qual m1 o1) (Qual m2 o2) = (o1 `compare` o2) `thenCmp` (m1 `compare` m2) 
     compare (Qual _ _)   (Orig _ _)   = LT
-    compare _           _            = GT
+
+    compare (Orig m1 o1) (Orig m2 o2) = (o1 `compare` o2) `thenCmp` (m1 `compare` m2) 
+    compare (Orig _ _)   _           = GT
 \end{code}