summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Coercion.hs
diff options
context:
space:
mode:
authorRyan Scott <ryan.gl.scott@gmail.com>2022-04-02 07:45:00 -0400
committerRyan Scott <ryan.gl.scott@gmail.com>2022-04-30 07:12:14 -0400
commit9ae28873f14d41f00f45242a697f7790c978505b (patch)
tree55d4a1f0591e0359c56c4c36f2c615350010a351 /compiler/GHC/Core/Coercion.hs
parent5630dde68185f96da026a4e0c722fe6631633299 (diff)
downloadhaskell-wip/T21328.tar.gz
Make mkFunCo take AnonArgFlags into accountwip/T21328
Previously, whenever `mkFunCo` would produce reflexive coercions, it would use `mkVisFunTy` to produce the kind of the coercion. However, `mkFunCo` is also used to produce coercions between types of the form `ty1 => ty2` in certain places. This has the unfortunate side effect of causing the type of the coercion to appear as `ty1 -> ty2` in certain error messages, as spotted in #21328. This patch address this by changing replacing the use of `mkVisFunTy` with `mkFunctionType` in `mkFunCo`. `mkFunctionType` checks the kind of `ty1` and makes the function arrow `=>` instead of `->` if `ty1` has kind `Constraint`, so this should always produce the correct `AnonArgFlag`. As a result, this patch fixes part (2) of #21328. This is not the only possible way to fix #21328, as the discussion on that issue lists some possible alternatives. Ultimately, it was concluded that the alternatives would be difficult to maintain, and since we already use `mkFunctionType` in `coercionLKind` and `coercionRKind`, using `mkFunctionType` in `mkFunCo` is consistent with this choice. Moreover, using `mkFunctionType` does not regress the performance of any test case we have in GHC's test suite.
Diffstat (limited to 'compiler/GHC/Core/Coercion.hs')
-rw-r--r--compiler/GHC/Core/Coercion.hs5
1 files changed, 3 insertions, 2 deletions
diff --git a/compiler/GHC/Core/Coercion.hs b/compiler/GHC/Core/Coercion.hs
index 4cfdc3ee82..235e8c65fb 100644
--- a/compiler/GHC/Core/Coercion.hs
+++ b/compiler/GHC/Core/Coercion.hs
@@ -792,14 +792,15 @@ mkTyConAppCo r tc cos
| otherwise = TyConAppCo r tc cos
-- | Build a function 'Coercion' from two other 'Coercion's. That is,
--- given @co1 :: a ~ b@ and @co2 :: x ~ y@ produce @co :: (a -> x) ~ (b -> y)@.
+-- given @co1 :: a ~ b@ and @co2 :: x ~ y@ produce @co :: (a -> x) ~ (b -> y)@
+-- or @(a => x) ~ (b => y)@, depending on the kind of @a@/@b@.
mkFunCo :: Role -> CoercionN -> Coercion -> Coercion -> Coercion
mkFunCo r w co1 co2
-- See Note [Refl invariant]
| Just (ty1, _) <- isReflCo_maybe co1
, Just (ty2, _) <- isReflCo_maybe co2
, Just (w, _) <- isReflCo_maybe w
- = mkReflCo r (mkVisFunTy w ty1 ty2)
+ = mkReflCo r (mkFunctionType w ty1 ty2)
| otherwise = FunCo r w co1 co2
-- | Apply a 'Coercion' to another 'Coercion'.