Opened 2 years ago

Closed 2 years ago

#13509 closed bug (fixed)

Perplexing type error with unboxed tuples

Reported by: bgamari Owned by:
Priority: high Milestone: 8.2.1
Component: Compiler Version: 8.0.1
Keywords: LevityPolymorphism Cc: goldfire
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: GHC rejects valid program Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

The fast-digits package fails to build with 8.2.0-rc1,

[1 of 2] Compiling Data.FastDigits.Internal ( src/Data/FastDigits/Internal.hs, dist/build/Data/FastDigits/Internal.o )

src/Data/FastDigits/Internal.hs:42:34: error:
    • Couldn't match a lifted type with an unlifted type
      Expected type: Word# -> (# Word#, Word# #)
        Actual type: Word# -> (# Word#, Word# #)
    • In the expression: go pw2
      In a pattern binding: (# n, pw2n #) = go pw2
      In the expression:
        let (# n, pw2n #) = go pw2
        in
          case timesWord2# pw pw2n of
            (# 0##, pw2n1 #) -> (# n `timesWord#` 2## `plusWord#` 1##, pw2n1 #)
            _ -> (# n `timesWord#` 2##, pw2n #)
   |
42 |           -> let (# n, pw2n #) = go pw2 in
   |                                  ^^^^^^

src/Data/FastDigits/Internal.hs:43:33: error:
    • Couldn't match a lifted type with an unlifted type
      When matching the kind of ‘Word#’
    • In the second argument of ‘timesWord2#’, namely ‘pw2n’
      In the expression: timesWord2# pw pw2n
      In the expression:
        case timesWord2# pw pw2n of
          (# 0##, pw2n1 #) -> (# n `timesWord#` 2## `plusWord#` 1##, pw2n1 #)
          _ -> (# n `timesWord#` 2##, pw2n #)
   |
43 |             case timesWord2# pw pw2n of
   |                                 ^^^^

src/Data/FastDigits/Internal.hs:44:37: error:
    • Couldn't match a lifted type with an unlifted type
      When matching the kind of ‘Word#’
    • In the first argument of ‘timesWord#’, namely ‘n’
      In the first argument of ‘plusWord#’, namely ‘n `timesWord#` 2##’
      In the expression: n `timesWord#` 2## `plusWord#` 1##
   |
44 |               (# 0##, pw2n1 #) -> (#n `timesWord#` 2## `plusWord#` 1##, pw2n1 #)
   |                                     ^

Change History (10)

comment:1 Changed 2 years ago by bgamari

The function in question is,

selectPower :: Word# -> (# Word#, Word# #)
selectPower 2## = (# 63##, 9223372036854775808## #)
selectPower base = go base
  where
    go :: Word# -> (# Word#, Word# #)
    go pw = case timesWord2# pw pw of
        (# 0##, pw2 #)
          -> let (# n, pw2n #) = go pw2 in
            case timesWord2# pw pw2n of
              (# 0##, pw2n1 #) -> (#n `timesWord#` 2## `plusWord#` 1##, pw2n1 #)
              _ -> (# n `timesWord#` 2##, pw2n #)
        _           -> (# 1##, pw #)

Adding a type signature, go :: Word# -> (# Word#, Word# #), appears to allow compilation to proceed.

comment:2 Changed 2 years ago by RyanGlScott

Cc: goldfire added

The commit e7985ed23ddc68b6a2e4af753578dc1d9e8ab4c9 (Update levity polymorphism) introduced this regression.

comment:3 Changed 2 years ago by RyanGlScott

Keywords: LevityPolymorphism added

comment:4 Changed 2 years ago by simonpj

Even shorter repro case

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

import GHC.Exts
import Data.Word

selectPower :: Word# -> (# Word#, Word# #)
selectPower base = go base
  where
    go :: Word# -> (# Word#, Word# #)
    go pw = let (# n, pw2n #) = go pw
            in (# n `timesWord#` 2##, pw2n #)

This compiles. Commenting out the signature for go makes it fail.

comment:5 Changed 2 years ago by mpickering

Summary: Perplexing type errorPerplexing type error with unboxed tuples

comment:6 Changed 2 years ago by simonpj

Interestingly, comment:4 fails with GHC 7.10 and 8.0 as well. But comment:1 succeeds (I don't know why yet).

comment:7 Changed 2 years ago by Simon Peyton Jones <simonpj@…>

In bac95f9d/ghc:

Yet another attempt at inferring the right quantification

TcSimplify.decideQuantification is truly a tricky function!
Trac #13509 showed that we were being over-eager with defaulting
of runtime-rep variables (levity polymorphism), which meant that
a program was wrongly rejected, and with a very odd error message
(c.f. Trac #13530)

I spent an unreasonably long time figuring out how to fix this
in a decent way, and ended up with a major refactoring of
decideQuantification, with a kock-on effect in simplifyInfer.

It is at least a bit more comprehensible now; but I still
can't say I like it.

comment:8 Changed 2 years ago by simonpj

Status: newmerge

I think I've fixed this. Things are better.

It's a fairly big patch, so I suppose that I could have introduced some new bug (although it validates fine). I'm open-minded about whether to merge it to 8.2.

Simon

comment:9 Changed 2 years ago by simonpj

PS: this does NOT fix #11530 and #11198.

comment:10 Changed 2 years ago by bgamari

Resolution: fixed
Status: mergeclosed
Note: See TracTickets for help on using tickets.