Skip to content

Renamed Type Variables Leak into Error Messages and Collide

Summary

When reporting a type error, GHC may mysteriously rename certain tyvars.

Steps to reproduce

I have minimised a reproducer out of my code base:

module BadErr where

data T f a = T (f a)

class C f where
  method :: f a -> r

-- badErr :: C c1 => T c1 b -> r
-- badErr = method

worseErr :: (C c1, C c2) => T c1 b -> T c2 b -> r
worseErr = method

foo :: T c a -> r
foo = undefined

bar1, bar2 :: C f => f a -> r
bar1 = foo
bar2 = foo

Expected behavior

GHC should report a type error such as:

BadErr.hs:13:12: error: [GHC-39999]
    • Could not deduce ‘C (T c1)’ arising from a use of ‘method’
      from the context: (C c1, C c2)
        bound by the type signature for:
                   worseErr :: forall {k2} (c1 :: k2 -> *) (c2 :: k2 -> *) (b :: k2)
                                      r.
                               (C c1, C c2) =>
                               T c1 b -> T c2 b -> r
        at BadErr.hs:12:1-49
    • In the expression: method
      In an equation for ‘worseErr’: worseErr = method
   |
13 | worseErr = method
   |            ^^^^^^

Rather confusingly, it instead produces:

BadErr.hs:13:12: error: [GHC-39999]
    • Could not deduce ‘C (T c2)’ arising from a use of ‘method’
      from the context: (C c2, C c3)
        bound by the type signature for:
                   worseErr :: forall {k2} (c2 :: k2 -> *) (c3 :: k2 -> *) (b :: k2)
                                      r.
                               (C c2, C c3) =>
                               T c2 b -> T c3 b -> r
        at BadErr.hs:12:1-49
    • In the expression: method
      In an equation for ‘worseErr’: worseErr = method
   |
13 | worseErr = method
   |            ^^^^^^

Note that badErr is sufficient to produce a similar renamed error message, but worseErr produces a new name that collides with an old name, so it's much more misleading.

Removing either bar causes the issue to vanish, as does changing the name of the tyvar c in the signature of foo.

Environment

  • GHC version used: 8.4.4; 9.8.2; 9.10.1
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information