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 |