Overloaded method causes insufficient specialization
The foo function in the following code does not get specialized completely by ghc -O2, even though all the overloaded functions in the module are marked INLINE. Specifically, it gets compiled into a call to a function with an Eq Int dictionary passed at runtime.
module Foo where
class Eq1 f where
eq1 :: (Eq a) => f a -> f a -> Bool
data F a = F !a !a
data G f a = G !(f a) !(f a)
instance Eq1 F where
eq1 = \(F a b) (F c d) ->
-- In order to reproduce the problem, the body of this function needs to be
-- large enough to prevent GHC from voluntarily inlining it.
larger $ larger $ larger $ larger $ larger $ larger $
a == c && b == d
{-# INLINE eq1 #-}
larger :: a -> a
larger = id
{-# NOINLINE larger #-}
instance (Eq1 f) => Eq1 (G f) where
eq1 = \(G a b) (G c d) -> eq1 a c && eq1 b d
{-# INLINE eq1 #-}
foo :: G F Int -> G F Int -> Bool
foo a b = eq1 a b
Looking at the dumps, it looks like there may be a problem is the specializer. It creates a specialization of eq1 with the type
(Eq a) => G F a -> G F a -> Bool
rather than the fully-specialized type:
G F Int -> G F Int -> Bool
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.0.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |