Optimizer Casting Caf with nominal type
When you make a function with a constant result, the optimizer will turn it into a cast of a CAF, even if doing so coerces a nominal parameter into a different one.
Minimal Example program:
{-# LANGUAGE RoleAnnotations #-}
import Debug.Trace (trace)
type role Nom nominal
data Nom a = Nom Int deriving Show
class Gen g where
gen :: g
instance Gen (Nom a) where
gen = trace "genD" $ Nom 0
main = print (gen :: Nom Int) >> print (gen :: Nom ()) >> print (gen :: Nom Char)
This program shows that only one value of type Nom is created and shared, even though doing so requires coercing a nominal role
I discovered this while checking core for sharing after creating a constraint result caching mechanism. An IOref ended up being shared for multiple different constraint result holders
Trac metadata
Trac field | Value |
---|---|
Version | 8.4.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |