Opened 23 months ago

Last modified 8 months ago

#8318 new bug

GHC does not infer type of `tagToEnum#` expression

Reported by: jstolarek Owned by:
Priority: normal Milestone:
Component: Compiler (Type checker) Version: 7.7
Keywords: Cc: patrick@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: GHC rejects valid program Test Case:
Blocked By: Blocking:
Related Tickets: Differential Revisions:

Description

Compiling this program:

{-# LANGUAGE MagicHash #-}
module TTE where

import GHC.Prim

f = case tagToEnum# 1# of
      True  -> "True"
      False -> "False"

gives a compilation error:

[1 of 1] Compiling TTE              ( tte.hs, tte.o )

tte.hs:6:10:
    tagToEnum# must appear applied to one argument
    In the expression: tagToEnum# 1#
    In the expression:
      case tagToEnum# 1# of {
        True -> "True"
        False -> "False" }
    In an equation for ‛f’:
        f = case tagToEnum# 1# of {
              True -> "True"
              False -> "False" }

To make it work one needs to supply type annotation for tagToEnum#: case tagToEnum# 1# :: Bool of. I would expect however that type will be inferred from type of patterns in the branches. Although I can imagine that things might get complicated for an ill-typed program:

f = case tagToEnum# 1# of
      True -> "True"
      3    -> "What now?"

If it is not possible to infer type of scrutinee based on patterns then I would expect to get more informative error message. Current one - tagToEnum# must appear applied to one argument - is very misleading. When I saw it for the first time it took me about 15 minutes to actually figure out what GHC expects me to do.

Change History (3)

comment:1 Changed 23 months ago by jstolarek

Compiling this program:

{-# LANGUAGE MagicHash, UnboxedTuples #-}
module TTE where

import GHC.Prim
import GHC.Base

g :: IO Bool
g = IO $ \s# -> (# s#, tagToEnum# 1# #)

produces:

[1 of 1] Compiling TTE              ( tte.hs, tte.o )

tte.hs:11:24:
    Bad call to tagToEnum# at type a_azp
      Specify the type by giving a type signature
      e.g. (tagToEnum# x) :: Bool
    In the expression: tagToEnum# 1#
    In the expression: (# s#, tagToEnum# 1# #)
    In the second argument of ‛($)’, namely
      ‛\ s# -> (# s#, tagToEnum# 1# #)

So the informative error message is already somewhere in the compiler. I wonder why don't we infer the type here? After all the error message clearly states what type is necessary.

Version 0, edited 23 months ago by jstolarek (next)

comment:2 Changed 20 months ago by parcs

  • Cc patrick@… added

comment:3 Changed 8 months ago by thomie

  • Component changed from Compiler to Compiler (Type checker)

The error message for the code from the description is improved using ghc HEAD. A regression test should be added.

$ ghc-7.9.20141115 test.hs
[1 of 1] Compiling TTE              ( test.hs, test.o )

test.hs:6:10:
    Bad call to tagToEnum# at type r_alE
      Specify the type by giving a type signature
      e.g. (tagToEnum# x) :: Bool
    In the expression: tagToEnum# 1#
    In the expression:
      case tagToEnum# 1# of {
        True -> "True"
        False -> "False" }
    In an equation for ‘f’:
        f = case tagToEnum# 1# of {
              True -> "True"
              False -> "False" }

See also commit 706c439fb5d3f1e30ad7b3953fde17dd01dae1bc:

Author: simonpj <[email protected]>
Date:   Wed Aug 16 20:30:23 2006 +0000

    Add test for tagToEnum#
Note: See TracTickets for help on using tickets.