summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Gundry <adam@well-typed.com>2021-03-09 10:28:37 +0000
committerAdam Gundry <adam@well-typed.com>2021-03-09 11:53:28 +0000
commit2eed593912c71c34e91737e6f3522693c3734216 (patch)
tree9a6dfc474e41d91f061ab358586f42241cf70889
parente571eda75f979e315ff87997e58ed99eb9d874c9 (diff)
downloadhaskell-wip/amg/T19509.tar.gz
Add isInjectiveTyCon check to opt_univ (fixes #19509)wip/amg/T19509
-rw-r--r--compiler/GHC/Core/Coercion/Opt.hs18
1 files changed, 18 insertions, 0 deletions
diff --git a/compiler/GHC/Core/Coercion/Opt.hs b/compiler/GHC/Core/Coercion/Opt.hs
index 4353676af6..1cae0f55a4 100644
--- a/compiler/GHC/Core/Coercion/Opt.hs
+++ b/compiler/GHC/Core/Coercion/Opt.hs
@@ -502,6 +502,23 @@ of arguments in a `CoTyConApp` can differ. Consider
Any (*->*) Maybe Int :: *
Hence the need to compare argument lengths; see #13658
+
+Note [opt_univ needs injectivity]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If opt_univ sees a coercion between `T a1 a2` and `T b1 b2` it will optimize it
+by producing a TyConAppCo for T, and pushing the UnivCo into the arguments. But
+this works only if T is injective. Otherwise we can have something like
+
+ type family F x where
+ F Int = Int
+ F Bool = Int
+
+where `UnivCo :: F Int ~ F Bool` is reasonable (it is effectively just an
+alternative representation for a couple of uses of AxiomInstCos) but we do not
+want to produce `F (UnivCo :: Int ~ Bool)` where the inner coercion is clearly
+inconsistent. Hence the opt_univ case for TyConApps checks isInjectiveTyCon.
+See #19509.
+
-}
opt_univ :: LiftingContext -> SymFlag -> UnivCoProvenance -> Role
@@ -518,6 +535,7 @@ opt_univ env sym prov role oty1 oty2
| Just (tc1, tys1) <- splitTyConApp_maybe oty1
, Just (tc2, tys2) <- splitTyConApp_maybe oty2
, tc1 == tc2
+ , isInjectiveTyCon tc1 role -- see Note [opt_univ needs injectivity]
, equalLength tys1 tys2 -- see Note [Differing kinds]
-- NB: prov must not be the two interesting ones (ProofIrrel & Phantom);
-- Phantom is already taken care of, and ProofIrrel doesn't relate tyconapps