Skip to content

Suggest `-XScopedTypeVariables` in error messages

ScopedTypeVariables error message

Location of documentation issue: GHC error message output

Consider the following module:

module ErrMsg where

f :: a -> a
f x = y
  where
    y :: a
    y = x
ErrMsg.hs:8:9: error:
    • Couldn't match expected type ‘a1’ with actual type ‘a’
      ‘a1’ is a rigid type variable bound by
        the type signature for:
          y :: forall a1. a1
        at ErrMsg.hs:7:5-10
      ‘a’ is a rigid type variable bound by
        the type signature for:
          f :: forall a. Num Int => a -> a
        at ErrMsg.hs:4:1-22
    • In the expression: x
      In an equation for ‘y’: y = x
      In an equation for ‘f’:
          f x
            = y
            where
                y :: a
                y = x
    • Relevant bindings include
        y :: a1 (bound at ErrMsg.hs:8:5)
        x :: a (bound at ErrMsg.hs:5:3)
        (Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)
  |
8 |     y = x
  |         ^

ScopedTypeVariables is never even mentioned. Also, note that the same error message is produced with ScopedTypeVariables enabled, and doesn't mention using an explicit forall.

Proposed error message (thanks @rae):

When ScopedTypeVariables is off:

• Couldn't match expected type ‘a1’ with actual type ‘a’
  The type variable ‘a’ is not in scope in the type signature
  for ‘y’; it therefore is considered a fresh variable, not equal
  to any other. To bring ‘a’ into scope:
    1. Enable the ScopedTypeVariables extension
    2. Rewrite 'f :: a -> a' to 'f :: forall a. a -> a'.        
• In the expression: x
  In an equation for ‘y’: y = x
  In an equation for ‘f’:
      f x
        = y
        where
            y :: a
            y = x
• Relevant type variables include
    ‘a1’ (bound at ErrMsg.hs:6:5-10, in the signature for ‘y’)
    ‘a’ (bound at ErrMsg.hs:3:1-11, in the signature for ‘f’)
• Relevant bindings include
    y :: a1 (bound at ErrMsg.hs:7:5)
    x :: a (bound at ErrMsg.hs:4:3)
    f :: a -> a (bound at ErrMsg.hs:4:1)
  |
7 |     y = x
  |         ^

When ScopedTypeVariables is on:

• Couldn't match expected type ‘a1’ with actual type ‘a’
  The type variable ‘a’ is not in scope in the type signature
  for ‘y’; it therefore is considered a fresh variable, not equal
  to any other. To bring ‘a’ into scope:
    Rewrite 'f :: a -> a' to 'f :: forall a. a -> a'.
• In the expression: x
  In an equation for ‘y’: y = x
  In an equation for ‘f’:
      f x
        = y
        where
            y :: a
            y = x 
• Relevant type variables include
    ‘a1’ (bound at ErrMsg.hs:6:5-10, in the signature for ‘y’)
    ‘a’ (bound at ErrMsg.hs:3:1-11, in the signature for ‘f’)
• Relevant bindings include
    y :: a1 (bound at ErrMsg.hs:7:5)
    x :: a (bound at ErrMsg.hs:4:3)
    f :: a -> a (bound at ErrMsg.hs:4:1)
  |
7 |     y = x
  |         ^

See https://github.com/haskell/error-messages/issues/6

Environment

  • GHC version used (if appropriate): 9.0.1
Edited by MorrowM
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information