Skip to content

Remove Ord SrcLoc, Ord SrcSpan

Vladislav Zavialov requested to merge wip/rm-ord-loc into master

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.

Edited by Vladislav Zavialov

Merge request reports