Skip to content

Instances getting incorrect IPE data

Code:

{-# LANGUAGE AllowAmbiguousTypes  #-}

module Main where

import GHC.InfoProv
import Unsafe.Coerce

-- Boilerplate to help us access the literal dictionaries

data Dict c where
    Dict :: forall c. c => Dict c

data Box where
    Box :: forall a. a -> Box

mkBox :: forall a. a => Box
mkBox = unsafeCoerce (Dict @a)

-- Interesting bit

data A = A

instance Eq A where
  A == A = True

instance Ord A where
   A <= A = undefined

main :: IO ()
main = do
    (\(Box d) -> print =<< whereFrom d) $ mkBox @(Eq A)
    (\(Box d) -> print =<< whereFrom d) $ mkBox @(Ord A)

This program prints the IPE data of the Eq A and Ord A dictionaries. The Eq A dictionary looks as we would expect, with ipLabel = $fEqA. The Ord A dictionary, however, gets the label <. Compile with:

ghc -O -fforce-recomp -finfo-table-map -fdistinct-constructor-tables Main.hs

The program outputs:

Just (InfoProv {ipName = "C:Eq_Main_0_con_info", ipDesc = CONSTR_2_0, ipTyDesc = "Eq", ipLabel = "$fEqA", ipMod = "Main", ipSrcFile = "Main.hs", ipSrcSpan = "23:10-13"})
Just (InfoProv {ipName = "C:Ord_Main_0_con_info", ipDesc = CONSTR, ipTyDesc = "Ord", ipLabel = "<", ipMod = "Main", ipSrcFile = "Main.hs", ipSrcSpan = "26:10-14"})

I would expect the Ord label to be $fOrdA, not <.

Interestingly, if we add more explicit definitions to the Ord A instance, the label changes. Changing the instance to:

instance Ord A where
   A <= A = undefined
   compare = undefined

Changes the label to > instead of <:

Just (InfoProv {ipName = "C:Ord_Main_0_con_info", ipDesc = CONSTR, ipTyDesc = "Ord", ipLabel = ">", ipMod = "Main", ipSrcFile = "Main.hs", ipSrcSpan = "26:10-14"})
Edited by Finley McIlwaine
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information