From 9ae28873f14d41f00f45242a697f7790c978505b Mon Sep 17 00:00:00 2001 From: Ryan Scott Date: Sat, 2 Apr 2022 07:45:00 -0400 Subject: Make mkFunCo take AnonArgFlags into account 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. --- compiler/GHC/Core/Coercion.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'compiler/GHC/Core') 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'. -- cgit v1.2.1