summaryrefslogtreecommitdiff
path: root/ghc/GHCi
diff options
context:
space:
mode:
authorVladislav Zavialov <vlad.z.4096@gmail.com>2020-02-19 00:07:22 +0300
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-02-24 02:05:30 -0500
commit26e8fff33b1b46ba559538b4519730c60c0d45e5 (patch)
tree2c9498b02db497fc6083dc80a14b8054e5b0902d /ghc/GHCi
parent1d9df9e00b021724d570a12d8c6d7870bdc054ca (diff)
downloadhaskell-26e8fff33b1b46ba559538b4519730c60c0d45e5.tar.gz
Remove Ord SrcLoc, Ord SrcSpan
Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule.
Diffstat (limited to 'ghc/GHCi')
-rw-r--r--ghc/GHCi/UI.hs7
1 files changed, 4 insertions, 3 deletions
diff --git a/ghc/GHCi/UI.hs b/ghc/GHCi/UI.hs
index 2559152954..ef78dca036 100644
--- a/ghc/GHCi/UI.hs
+++ b/ghc/GHCi/UI.hs
@@ -1325,8 +1325,9 @@ printTypeOfNames names
= mapM_ (printTypeOfName ) $ sortBy compareNames names
compareNames :: Name -> Name -> Ordering
-n1 `compareNames` n2 = compareWith n1 `compare` compareWith n2
- where compareWith n = (getOccString n, getSrcSpan n)
+n1 `compareNames` n2 =
+ (compare `on` getOccString) n1 n2 `thenCmp`
+ (SrcLoc.leftmost_smallest `on` getSrcSpan) n1 n2
printTypeOfName :: GHC.GhcMonad m => Name -> m ()
printTypeOfName n
@@ -2406,7 +2407,7 @@ browseModule bang modl exports_only = do
-- has a good source location, then they all should.
loc_sort ns
| n:_ <- ns, isGoodSrcSpan (nameSrcSpan n)
- = sortBy (compare `on` nameSrcSpan) ns
+ = sortBy (SrcLoc.leftmost_smallest `on` nameSrcSpan) ns
| otherwise
= occ_sort ns