summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Unify.hs
diff options
context:
space:
mode:
authorsheaf <sam.derbyshire@gmail.com>2022-03-24 17:09:21 +0100
committerMatthew Pickering <matthewtpickering@gmail.com>2022-04-01 10:59:58 +0100
commitf589dea3b30695701ebcc0d742488290273d8cf2 (patch)
treed0de16ea23863e35e2bc7f91067c904457827b8f /compiler/GHC/Core/Unify.hs
parent9727e5924d9b326a0113a68f7ecb396015b80bf4 (diff)
downloadhaskell-f589dea3b30695701ebcc0d742488290273d8cf2.tar.gz
Unify RuntimeRep arguments in ty_co_match
The `ty_co_match` function ignored the implicit RuntimeRep coercions that occur in a `FunCo`. Even though a comment explained that this should be fine, #21205 showed that it could result in discarding a RuntimeRep coercion, and thus discarding an important cast entirely. With this patch, we first match the kinds in `ty_co_match`. Fixes #21205 ------------------------- Metric Increase: T12227 T18223 -------------------------
Diffstat (limited to 'compiler/GHC/Core/Unify.hs')
-rw-r--r--compiler/GHC/Core/Unify.hs31
1 files changed, 19 insertions, 12 deletions
diff --git a/compiler/GHC/Core/Unify.hs b/compiler/GHC/Core/Unify.hs
index 9a6ffcb18d..27f745d980 100644
--- a/compiler/GHC/Core/Unify.hs
+++ b/compiler/GHC/Core/Unify.hs
@@ -56,6 +56,7 @@ import GHC.Data.FastString
import Data.List ( mapAccumL )
import Control.Monad
import qualified Data.Semigroup as S
+
import GHC.Builtin.Names (constraintKindTyConKey, liftedTypeKindTyConKey)
{-
@@ -1545,10 +1546,13 @@ liftCoMatch tmpls ty co
ty_co_match :: MatchEnv -- ^ ambient helpful info
-> LiftCoEnv -- ^ incoming subst
-> Type -- ^ ty, type to match
- -> Coercion -- ^ co, coercion to match against
- -> Coercion -- ^ :: kind of L type of substed ty ~N L kind of co
- -> Coercion -- ^ :: kind of R type of substed ty ~N R kind of co
+ -> Coercion -- ^ co :: lty ~r rty, coercion to match against
+ -> Coercion -- ^ :: kind(lsubst(ty)) ~N kind(lty)
+ -> Coercion -- ^ :: kind(rsubst(ty)) ~N kind(rty)
-> Maybe LiftCoEnv
+ -- ^ Just env ==> liftCoSubst Nominal env ty == co, modulo roles.
+ -- Also: Just env ==> lsubst(ty) == lty and rsubst(ty) == rty,
+ -- where lsubst = lcSubstLeft(env) and rsubst = lcSubstRight(env)
ty_co_match menv subst ty co lkco rkco
| Just ty' <- coreView ty = ty_co_match menv subst ty' co lkco rkco
-- why coreView here, not tcView? Because we're firmly after type-checking.
@@ -1618,14 +1622,17 @@ ty_co_match menv subst ty1 (AppCo co2 arg2) _lkco _rkco
ty_co_match menv subst (TyConApp tc1 tys) (TyConAppCo _ tc2 cos) _lkco _rkco
= ty_co_match_tc menv subst tc1 tys tc2 cos
ty_co_match menv subst (FunTy _ w ty1 ty2) co _lkco _rkco
- -- Despite the fact that (->) is polymorphic in five type variables (two
- -- runtime rep, a multiplicity and two types), we shouldn't need to
- -- explicitly unify the runtime reps here; unifying the types themselves
- -- should be sufficient. See Note [Representation of function types].
- | Just (tc, [co_mult, _,_,co1,co2]) <- splitTyConAppCo_maybe co
+ | Just (tc, [co_mult,rrco1,rrco2,co1,co2]) <- splitTyConAppCo_maybe co
, tc == funTyCon
- = let Pair lkcos rkcos = traverse (fmap mkNomReflCo . coercionKind) [co_mult,co1,co2]
- in ty_co_match_args menv subst [w, ty1, ty2] [co_mult, co1, co2] lkcos rkcos
+ = let rr1 = getRuntimeRep ty1
+ rr2 = getRuntimeRep ty2
+ Pair lkcos rkcos = traverse (fmap (mkNomReflCo . typeKind) . coercionKind)
+ [co_mult,rrco1, rrco2,co1,co2]
+ in -- NB: we include the RuntimeRep arguments in the matching; not doing so caused #21205.
+ ty_co_match_args menv subst
+ [w, rr1, rr2, ty1, ty2]
+ [co_mult, rrco1, rrco2, co1, co2]
+ lkcos rkcos
ty_co_match menv subst (ForAllTy (Bndr tv1 _) ty1)
(ForAllCo tv2 kind_co2 co2)
@@ -1694,7 +1701,7 @@ ty_co_match_tc menv subst tc1 tys1 tc2 cos2
; ty_co_match_args menv subst tys1 cos2 lkcos rkcos }
where
Pair lkcos rkcos
- = traverse (fmap mkNomReflCo . coercionKind) cos2
+ = traverse (fmap (mkNomReflCo . typeKind) . coercionKind) cos2
ty_co_match_app :: MatchEnv -> LiftCoEnv
-> Type -> [Type] -> Coercion -> [Coercion]
@@ -1708,7 +1715,7 @@ ty_co_match_app menv subst ty1 ty1args co2 co2args
= do { subst1 <- ty_co_match menv subst ki1 ki2 ki_ki_co ki_ki_co
; let Pair lkco rkco = mkNomReflCo <$> coercionKind ki2
; subst2 <- ty_co_match menv subst1 ty1 co2 lkco rkco
- ; let Pair lkcos rkcos = traverse (fmap mkNomReflCo . coercionKind) co2args
+ ; let Pair lkcos rkcos = traverse (fmap (mkNomReflCo . typeKind) . coercionKind) co2args
; ty_co_match_args menv subst2 ty1args co2args lkcos rkcos }
where
ki1 = typeKind ty1