Opened 6 months ago

Closed 6 months ago

Last modified 6 months ago

#8428 closed bug (fixed)

Incorrect type formatting in error messages

Reported by: klao Owned by: monoidal
Priority: normal Milestone:
Component: Compiler Version: 7.6.3
Keywords: Cc: gergely@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Easy (less than 1 hour)
Test Case: typecheck/should_fail/T8428 Blocked By:
Blocking: Related Tickets:

Description

I've been trying to write a type signature to something completely analogous to runST . runIdentityT, and failing miserably for a long time.

At some point I had the following:

{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ImpredicativeTypes #-}

module Test where

import Control.Monad.ST
import Control.Monad.Trans.Identity

runIdST :: IdentityT (forall s. ST s) a -> a
runIdST = runST . runIdentityT

You can see that I was very confused about forall here (probably still am), but what makes it much worse is the error message with which this fails:

src/Test.hs:10:19:
    Couldn't match type `forall s. ST s a' with `forall s. ST s a'
    Expected type: IdentityT (forall s. ST s) a -> forall s. ST s a
      Actual type: IdentityT (forall s. ST s) a -> forall s. ST s a
    In the second argument of `(.)', namely `runIdentityT'
    In the expression: runST . runIdentityT
    In an equation for `runIdST': runIdST = runST . runIdentityT

It says it couldn't match forall s. ST s a with forall s. ST s a. What's up with that?!

This has lead me to a long diversion. Finally, we found the right type for this function (and discovered that the problem is also in the (.), which doesn't have the same special treatment as ($)), and afterwards we realized, that types in the above error message are actually different.

One is (forall s. (ST s)) a, and the other is forall s. ((ST s) a). But they are presented in exactly the same way!

The issue is in the instance Outputable Type, which has too simplistic precedence rules, I guess.

Thanks to @errge for help with debugging this.

Attachments (1)

ghc_forall_ppr.patch (983 bytes) - added by klao 6 months ago.

Download all attachments as: .zip

Change History (7)

Changed 6 months ago by klao

comment:1 Changed 6 months ago by klao

  • Difficulty changed from Unknown to Easy (less than 1 hour)
  • Status changed from new to patch

The more I look at the code in TypeRep.lhs, the more it looks like a simple omission. I attach a trivial patch that fixes the issue (and doesn't seem to break anything else; at least not according to the test suite).

Note that I also removed a spurious \end{code} label, which broke emacs' literate Haskell syntax highlighting on this file.

comment:2 Changed 6 months ago by monoidal

  • Owner set to monoidal

comment:3 Changed 6 months ago by Krzysztof Gogolewski <krz.gogolewski@…>

In a83652ed4aee321063c17df1ad8560712b33103a/ghc:

Show parentheses when printing type (forall x. T1) T2 (#8428)

Patch by klao

comment:4 Changed 6 months ago by Krzysztof Gogolewski <krz.gogolewski@…>

comment:5 Changed 6 months ago by monoidal

  • Resolution set to fixed
  • Status changed from patch to closed
  • Test Case set to typecheck/should_fail/T8428

Looks good, I've pushed it. Thanks for the patch.

The type (forall s. ST s) should be rejected as a kind error, because under the forall there should be a type of kind *, not * -> * or similar. However, we currently do not detect this (#8388).

comment:6 Changed 6 months ago by simonpj

Thank you. Absolutely right.

Simon

Note: See TracTickets for help on using tickets.