Adam Gundry pushed to branch wip/amg/castz at Glasgow Haskell Compiler / GHC
Commits:
-
0868a190
by Adam Gundry at 2025-11-24T16:22:48+00:00
-
6596d839
by Adam Gundry at 2025-11-25T10:22:41+00:00
-
58a31cb9
by Adam Gundry at 2025-11-25T10:23:02+00:00
12 changed files:
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Core/Map/Type.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/Utils.hs
Changes:
| ... | ... | @@ -56,6 +56,14 @@ module GHC.Core.Coercion ( |
| 56 | 56 | -- ** Cast coercions
|
| 57 | 57 | castCoToCo,
|
| 58 | 58 | mkTransCastCo, mkTransCastCoCo, mkTransCoCastCo,
|
| 59 | + mkSymCastCo,
|
|
| 60 | + mkPiCastCos,
|
|
| 61 | + isReflCastCo,
|
|
| 62 | + checkReflexiveCastCo,
|
|
| 63 | + coToCastCo,
|
|
| 64 | + mkForAllCastCo,
|
|
| 65 | + mkFunResCastCo,
|
|
| 66 | + mkFunCastCoNoFTF,
|
|
| 59 | 67 | |
| 60 | 68 | -- ** Decomposition
|
| 61 | 69 | instNewTyCon_maybe,
|
| ... | ... | @@ -82,7 +90,7 @@ module GHC.Core.Coercion ( |
| 82 | 90 | |
| 83 | 91 | coToMCo, kindCoToMKindCo,
|
| 84 | 92 | mkTransMCo, mkTransMCoL, mkTransMCoR, mkCastTyMCo, mkSymMCo,
|
| 85 | - mkFunResMCo, mkPiMCos,
|
|
| 93 | + mkFunResMCo,
|
|
| 86 | 94 | isReflMCo, checkReflexiveMCo,
|
| 87 | 95 | |
| 88 | 96 | -- ** Coercion variables
|
| ... | ... | @@ -389,13 +397,10 @@ mkCastTyMCo :: Type -> MCoercion -> Type |
| 389 | 397 | mkCastTyMCo ty MRefl = ty
|
| 390 | 398 | mkCastTyMCo ty (MCo co) = ty `mkCastTy` co
|
| 391 | 399 | |
| 392 | -mkPiMCos :: [Var] -> MCoercion -> MCoercion
|
|
| 393 | -mkPiMCos _ MRefl = MRefl
|
|
| 394 | -mkPiMCos vs (MCo co) = MCo (mkPiCos Representational vs co)
|
|
| 395 | - |
|
| 396 | -mkFunResMCo :: Id -> MCoercionR -> MCoercionR
|
|
| 397 | -mkFunResMCo _ MRefl = MRefl
|
|
| 398 | -mkFunResMCo arg_id (MCo co) = MCo (mkFunResCo Representational arg_id co)
|
|
| 400 | +mkFunResMCo :: Id -> CastCoercion -> CastCoercion
|
|
| 401 | +mkFunResMCo _ ReflCastCo = ReflCastCo
|
|
| 402 | +mkFunResMCo arg_id (CCoercion co) = CCoercion (mkFunResCo Representational arg_id co)
|
|
| 403 | +mkFunResMCo arg_id (ZCoercion ty cos) = ZCoercion (mkFunctionType (idMult arg_id) (varType arg_id) ty) cos -- TODO check type
|
|
| 399 | 404 | |
| 400 | 405 | mkGReflLeftMCo :: Role -> Type -> MCoercionN -> Coercion
|
| 401 | 406 | mkGReflLeftMCo r ty MRefl = mkReflCo r ty
|
| ... | ... | @@ -842,6 +847,17 @@ mkFunCoNoFTF r w arg_co res_co |
| 842 | 847 | Pair argl_ty argr_ty = coercionKind arg_co
|
| 843 | 848 | Pair resl_ty resr_ty = coercionKind res_co
|
| 844 | 849 | |
| 850 | +-- AMG TODO: more cases here, or maybe better to have a FunCo constructor of CastCoercion?
|
|
| 851 | +mkFunCastCoNoFTF :: HasDebugCallStack => Role -> Mult -> Type -> CastCoercion -> Type -> CastCoercion -> CastCoercion
|
|
| 852 | +mkFunCastCoNoFTF _ mult _ (ZCoercion arg_ty arg_cos) _ (ZCoercion res_ty res_cos) = ZCoercion (mkFunctionType mult arg_ty res_ty) (arg_cos `unionVarSet` res_cos)
|
|
| 853 | +mkFunCastCoNoFTF _ mult _ (ZCoercion arg_ty arg_cos) res_ty res_co = ZCoercion (mkFunctionType mult arg_ty (castCoercionRKind res_ty res_co)) (arg_cos `unionVarSet` coVarsOfCastCo res_co)
|
|
| 854 | +mkFunCastCoNoFTF _ mult arg_ty arg_co _ (ZCoercion res_ty res_cos) = ZCoercion (mkFunctionType mult (castCoercionRKind arg_ty arg_co) res_ty) (res_cos `unionVarSet` coVarsOfCastCo arg_co)
|
|
| 855 | +mkFunCastCoNoFTF r mult _ (CCoercion arg_co) _ (CCoercion res_co) = CCoercion (mkFunCoNoFTF r (multToCo mult) arg_co res_co)
|
|
| 856 | +mkFunCastCoNoFTF _ _ _ ReflCastCo _ ReflCastCo = ReflCastCo
|
|
| 857 | +mkFunCastCoNoFTF r mult _ (CCoercion arg_co) res_ty ReflCastCo = CCoercion (mkFunCoNoFTF r (multToCo mult) arg_co (mkReflCo r res_ty))
|
|
| 858 | +mkFunCastCoNoFTF r mult arg_ty ReflCastCo _ (CCoercion res_co) = CCoercion (mkFunCoNoFTF r (multToCo mult) (mkReflCo r arg_ty) res_co)
|
|
| 859 | + |
|
| 860 | + |
|
| 845 | 861 | -- | Build a function 'Coercion' from two other 'Coercion's. That is,
|
| 846 | 862 | -- given @co1 :: a ~ b@ and @co2 :: x ~ y@ produce @co :: (a -> x) ~ (b -> y)@
|
| 847 | 863 | -- or @(a => x) ~ (b => y)@, depending on the kind of @a@/@b@.
|
| ... | ... | @@ -968,6 +984,13 @@ mkForAllCo v visL visR kind_co co |
| 968 | 984 | | otherwise
|
| 969 | 985 | = mk_forall_co v visL visR kind_co co
|
| 970 | 986 | |
| 987 | +mkForAllCastCo :: HasDebugCallStack => TyCoVar -> ForAllTyFlag -> ForAllTyFlag
|
|
| 988 | + -> CastCoercion -> CastCoercion
|
|
| 989 | +mkForAllCastCo v visL visR cco = case cco of
|
|
| 990 | + CCoercion co -> CCoercion (mkForAllCo v visL visR MRefl co)
|
|
| 991 | + ZCoercion ty cos -> ZCoercion (mkTyCoForAllTy v visL ty) cos
|
|
| 992 | + ReflCastCo -> ReflCastCo
|
|
| 993 | + |
|
| 971 | 994 | -- mkForAllVisCos [tv{vis}] constructs a cast
|
| 972 | 995 | -- forall tv. res ~R# forall tv{vis} res`.
|
| 973 | 996 | -- See Note [Required foralls in Core] in GHC.Core.TyCo.Rep
|
| ... | ... | @@ -1187,6 +1210,14 @@ mkSymCo co@(ForAllCo { fco_kind = kco, fco_body = body_co }) |
| 1187 | 1210 | | isReflMCo kco = co { fco_body = mkSymCo body_co }
|
| 1188 | 1211 | mkSymCo co = SymCo co
|
| 1189 | 1212 | |
| 1213 | +-- | Variant of 'mkSymCo' that works on 'CastCoercion', and expects the LHS type
|
|
| 1214 | +-- of the input coercion (and hence the RHS type of the result coercion) to be
|
|
| 1215 | +-- passed in.
|
|
| 1216 | +mkSymCastCo :: Type -> CastCoercion -> CastCoercion
|
|
| 1217 | +mkSymCastCo _ (CCoercion co) = CCoercion (mkSymCo co)
|
|
| 1218 | +mkSymCastCo ty (ZCoercion _ cos) = ZCoercion ty cos
|
|
| 1219 | +mkSymCastCo _ ReflCastCo = ReflCastCo
|
|
| 1220 | + |
|
| 1190 | 1221 | -- | mkTransCo creates a new 'Coercion' by composing the two
|
| 1191 | 1222 | -- given 'Coercion's transitively: (co1 ; co2)
|
| 1192 | 1223 | mkTransCo :: HasDebugCallStack => Coercion -> Coercion -> Coercion
|
| ... | ... | @@ -1765,6 +1796,9 @@ castCoercionKind g h1 h2 |
| 1765 | 1796 | mkPiCos :: Role -> [Var] -> Coercion -> Coercion
|
| 1766 | 1797 | mkPiCos r vs co = foldr (mkPiCo r) co vs
|
| 1767 | 1798 | |
| 1799 | +mkPiCastCos :: Role -> [Var] -> CastCoercion -> CastCoercion
|
|
| 1800 | +mkPiCastCos r vs co = foldr (mkPiCastCo r) co vs
|
|
| 1801 | + |
|
| 1768 | 1802 | -- | Make a forall 'Coercion', where both types related by the coercion
|
| 1769 | 1803 | -- are quantified over the same variable.
|
| 1770 | 1804 | mkPiCo :: Role -> Var -> Coercion -> Coercion
|
| ... | ... | @@ -1778,6 +1812,16 @@ mkPiCo r v co | isTyVar v = mkHomoForAllCo v co |
| 1778 | 1812 | mkFunResCo r v co
|
| 1779 | 1813 | | otherwise = mkFunResCo r v co
|
| 1780 | 1814 | |
| 1815 | +mkPiCastCo :: Role -> Var -> CastCoercion -> CastCoercion
|
|
| 1816 | +mkPiCastCo _ _ ReflCastCo = ReflCastCo
|
|
| 1817 | +mkPiCastCo r v (CCoercion co) = CCoercion (mkPiCo r v co)
|
|
| 1818 | +mkPiCastCo r v (ZCoercion ty cos)
|
|
| 1819 | + | isTyVar v = ZCoercion (mkForAllTy (Bndr v vis) ty) cos
|
|
| 1820 | + | otherwise = ZCoercion (mkFunctionType (idMult v) (varType v) ty) cos
|
|
| 1821 | + where
|
|
| 1822 | + vis = coreTyLamForAllTyFlag
|
|
| 1823 | + |
|
| 1824 | + |
|
| 1781 | 1825 | mkFunResCo :: Role -> Id -> Coercion -> Coercion
|
| 1782 | 1826 | -- Given res_co :: res1 ~ res2,
|
| 1783 | 1827 | -- mkFunResCo r m arg res_co :: (arg -> res1) ~r (arg -> res2)
|
| ... | ... | @@ -1788,6 +1832,13 @@ mkFunResCo role id res_co |
| 1788 | 1832 | arg_co = mkReflCo role (varType id)
|
| 1789 | 1833 | mult = multToCo (idMult id)
|
| 1790 | 1834 | |
| 1835 | +mkFunResCastCo :: Role -> Id -> CastCoercion -> CastCoercion
|
|
| 1836 | +mkFunResCastCo role id res_cco = case res_cco of
|
|
| 1837 | + CCoercion res_co -> CCoercion (mkFunResCo role id res_co)
|
|
| 1838 | + ZCoercion ty cos -> ZCoercion (mkFunctionType (idMult id) (varType id) ty) cos
|
|
| 1839 | + ReflCastCo -> ReflCastCo
|
|
| 1840 | + |
|
| 1841 | + |
|
| 1791 | 1842 | -- mkCoCast (c :: s1 ~?r t1) (g :: (s1 ~?r t1) ~#R (s2 ~?r t2)) :: s2 ~?r t2
|
| 1792 | 1843 | -- The first coercion might be lifted or unlifted; thus the ~? above
|
| 1793 | 1844 | -- Lifted and unlifted equalities take different numbers of arguments,
|
| ... | ... | @@ -2873,7 +2924,7 @@ See Note [Zapped casts] in GHC.Core.TyCo.Rep. |
| 2873 | 2924 | -- but requires the type to be supplied by the caller because it cannot be
|
| 2874 | 2925 | -- recovered in the 'ZCoercion' case.
|
| 2875 | 2926 | castCoercionLKind :: HasDebugCallStack => Type -> CastCoercion -> Type
|
| 2876 | -castCoercionLKind _ (CCoercion co) = coercionLKind co
|
|
| 2927 | +castCoercionLKind _ (CCoercion co) = coercionLKind co -- TODO: should we use provided lhs_ty instead? Not sure which is cheaper?
|
|
| 2877 | 2928 | castCoercionLKind lhs_ty (ZCoercion _ _) = lhs_ty
|
| 2878 | 2929 | castCoercionLKind lhs_ty ReflCastCo = lhs_ty
|
| 2879 | 2930 | |
| ... | ... | @@ -2922,9 +2973,27 @@ mkTransCoCastCo co1 (CCoercion co2) = CCoercion (mkTransCo co1 co2) |
| 2922 | 2973 | mkTransCoCastCo co1 (ZCoercion ty cos) = ZCoercion ty (shallowCoVarsOfCo co1 `unionVarSet` cos)
|
| 2923 | 2974 | mkTransCoCastCo co1 ReflCastCo = CCoercion co1
|
| 2924 | 2975 | |
| 2976 | +-- | Quickly check if a 'CastCoercion' is obviously reflexive.
|
|
| 2977 | +isReflCastCo :: CastCoercion -> Bool
|
|
| 2978 | +isReflCastCo (CCoercion co) = isReflCo co
|
|
| 2979 | +isReflCastCo ZCoercion{} = False -- it might be, but we can't tell
|
|
| 2980 | +isReflCastCo ReflCastCo = True
|
|
| 2981 | + |
|
| 2925 | 2982 | -- | Slowly checks if the coercion is reflexive. Don't call this in a loop,
|
| 2926 | 2983 | -- as it walks over the entire coercion.
|
| 2927 | 2984 | isReflexiveCastCo :: Type -> CastCoercion -> Bool
|
| 2928 | 2985 | isReflexiveCastCo _ (CCoercion co) = isReflexiveCo co
|
| 2929 | 2986 | isReflexiveCastCo lhs_ty (ZCoercion rhs_ty _) = lhs_ty `eqType` rhs_ty
|
| 2930 | 2987 | isReflexiveCastCo _ ReflCastCo = True
|
| 2988 | + |
|
| 2989 | +checkReflexiveCastCo :: Type -> CastCoercion -> CastCoercion
|
|
| 2990 | +checkReflexiveCastCo ty cco
|
|
| 2991 | + | isReflexiveCastCo ty cco = ReflCastCo
|
|
| 2992 | + | otherwise = cco
|
|
| 2993 | + |
|
| 2994 | +coToCastCo :: Coercion -> CastCoercion
|
|
| 2995 | +-- Convert a coercion to a CastCoercion, checking if it is obviously reflexive.
|
|
| 2996 | +-- It's not clear whether or not isReflexiveCo would be better here
|
|
| 2997 | +-- See #19815 for a bit of data and discussion on this point
|
|
| 2998 | +coToCastCo co | isReflCo co = ReflCastCo
|
|
| 2999 | + | otherwise = CCoercion co |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | |
| 5 | 5 | module GHC.Core.Coercion.Opt
|
| 6 | 6 | ( optCoercion
|
| 7 | + , optCastCoercion
|
|
| 7 | 8 | , OptCoercionOpts (..)
|
| 8 | 9 | )
|
| 9 | 10 | where
|
| ... | ... | @@ -169,6 +170,13 @@ newtype OptCoercionOpts = OptCoercionOpts |
| 169 | 170 | { optCoercionEnabled :: Bool -- ^ Enable coercion optimisation (reduce its size)
|
| 170 | 171 | }
|
| 171 | 172 | |
| 173 | +optCastCoercion :: OptCoercionOpts -> Subst -> Type -> CastCoercion -> CastCoercion
|
|
| 174 | +optCastCoercion opts env _ (CCoercion co) = CCoercion (optCoercion opts env co)
|
|
| 175 | +optCastCoercion opts env _ ReflCastCo = ReflCastCo
|
|
| 176 | +optCastCoercion opts env tyL (ZCoercion tyR cos)
|
|
| 177 | + | tyL `eqTypeIgnoringMultiplicity` tyR = ReflCastCo
|
|
| 178 | + | otherwise = ZCoercion (substTy env tyR) (substCoVarSet env cos)
|
|
| 179 | + |
|
| 172 | 180 | optCoercion :: OptCoercionOpts -> Subst -> Coercion -> NormalCo
|
| 173 | 181 | -- ^ optCoercion applies a substitution to a coercion,
|
| 174 | 182 | -- *and* optimises it to reduce its size
|
| ... | ... | @@ -139,6 +139,7 @@ xtC (D env co) f (CoercionMapX m) |
| 139 | 139 | |
| 140 | 140 | -- We should really never care about the contents of a cast coercion. Instead,
|
| 141 | 141 | -- just look up the coercion's RHS type.
|
| 142 | +-- TODO: do we need this type, or can we just use TypeMap?
|
|
| 142 | 143 | newtype CastCoercionMap a = CastCoercionMap (CastCoercionMapG a)
|
| 143 | 144 | |
| 144 | 145 | -- TODO(22292): derive
|
| ... | ... | @@ -42,7 +42,7 @@ module GHC.Core.Opt.Arity |
| 42 | 42 | , etaExpandToJoinPoint, etaExpandToJoinPointRule
|
| 43 | 43 | |
| 44 | 44 | -- ** Coercions and casts
|
| 45 | - , pushCoArg, pushCoArgs, pushCoValArg, pushCoTyArg
|
|
| 45 | + , pushCoArg, pushCoArgs, pushCastCoValArg, pushCastCoTyArg
|
|
| 46 | 46 | , pushCoercionIntoLambda, pushCoDataCon, collectBindersPushingCo
|
| 47 | 47 | )
|
| 48 | 48 | where
|
| ... | ... | @@ -2195,7 +2195,7 @@ Now, when we push that eta_co inward in etaInfoApp: |
| 2195 | 2195 | -}
|
| 2196 | 2196 | |
| 2197 | 2197 | --------------
|
| 2198 | -data EtaInfo = EI [Var] MCoercionR
|
|
| 2198 | +data EtaInfo = EI [Var] CastCoercion
|
|
| 2199 | 2199 | -- See Note [The EtaInfo mechanism]
|
| 2200 | 2200 | |
| 2201 | 2201 | instance Outputable EtaInfo where
|
| ... | ... | @@ -2221,11 +2221,10 @@ etaInfoApp in_scope expr eis |
| 2221 | 2221 | go subst (Tick t e) eis
|
| 2222 | 2222 | = Tick (substTickish subst t) (go subst e eis)
|
| 2223 | 2223 | |
| 2224 | - go subst (Cast e cco) (EI bs mco)
|
|
| 2224 | + go subst (Cast e co) (EI bs mco)
|
|
| 2225 | 2225 | = go subst e (EI bs mco')
|
| 2226 | 2226 | where
|
| 2227 | - co = castCoToCo (exprType e) cco -- TODO: can we avoid this?
|
|
| 2228 | - mco' = checkReflexiveMCo (Core.substCo subst co `mkTransMCoR` mco)
|
|
| 2227 | + mco' = checkReflexiveCastCo (exprType (Core.substExpr subst e)) (Core.substCastCo subst co `mkTransCastCo` mco)
|
|
| 2229 | 2228 | -- See Note [Check for reflexive casts in eta expansion]
|
| 2230 | 2229 | |
| 2231 | 2230 | go subst (Case e b ty alts) eis
|
| ... | ... | @@ -2247,13 +2246,13 @@ etaInfoApp in_scope expr eis |
| 2247 | 2246 | -- Beta-reduction if possible, pushing any intervening casts past
|
| 2248 | 2247 | -- the argument. See Note [The EtaInfo mechanism]
|
| 2249 | 2248 | go subst (Lam v e) (EI (b:bs) mco)
|
| 2250 | - | Just (arg,mco') <- pushMCoArg mco (varToCoreExpr b)
|
|
| 2249 | + | Just (arg,mco') <- pushCoArg (exprType (Lam v e)) mco (varToCoreExpr b)
|
|
| 2251 | 2250 | = go (Core.extendSubst subst v arg) e (EI bs mco')
|
| 2252 | 2251 | |
| 2253 | 2252 | -- Stop pushing down; just wrap the expression up
|
| 2254 | 2253 | -- See Note [Check for reflexive casts in eta expansion]
|
| 2255 | 2254 | go subst e (EI bs mco) = Core.substExprSC subst e
|
| 2256 | - `mkCastMCo` checkReflexiveMCo mco
|
|
| 2255 | + `mkCastCo` checkReflexiveCastCo (exprType e) mco -- TODO check type
|
|
| 2257 | 2256 | `mkVarApps` bs
|
| 2258 | 2257 | |
| 2259 | 2258 | --------------
|
| ... | ... | @@ -2263,14 +2262,12 @@ etaInfoAppTy :: Type -> EtaInfo -> Type |
| 2263 | 2262 | etaInfoAppTy ty (EI bs mco)
|
| 2264 | 2263 | = applyTypeToArgs ty1 (map varToCoreExpr bs)
|
| 2265 | 2264 | where
|
| 2266 | - ty1 = case mco of
|
|
| 2267 | - MRefl -> ty
|
|
| 2268 | - MCo co -> coercionRKind co
|
|
| 2265 | + ty1 = castCoercionRKind ty mco
|
|
| 2269 | 2266 | |
| 2270 | 2267 | --------------
|
| 2271 | 2268 | etaInfoAbs :: EtaInfo -> CoreExpr -> CoreExpr
|
| 2272 | 2269 | -- See Note [The EtaInfo mechanism]
|
| 2273 | -etaInfoAbs (EI bs mco) expr = (mkLams bs expr) `mkCastMCo` mkSymMCo mco
|
|
| 2270 | +etaInfoAbs (EI bs mco) expr = (mkLams bs expr) `mkCastCo` mkSymCastCo (error "AMG TODO: etaInfoAbs") mco
|
|
| 2274 | 2271 | |
| 2275 | 2272 | --------------
|
| 2276 | 2273 | -- | @mkEtaWW n _ fvs ty@ will compute the 'EtaInfo' necessary for eta-expanding
|
| ... | ... | @@ -2307,7 +2304,7 @@ mkEtaWW orig_oss ppr_orig_expr in_scope orig_ty |
| 2307 | 2304 | |
| 2308 | 2305 | go _ [] subst _
|
| 2309 | 2306 | ----------- Done! No more expansion needed
|
| 2310 | - = (substInScopeSet subst, EI [] MRefl)
|
|
| 2307 | + = (substInScopeSet subst, EI [] ReflCastCo)
|
|
| 2311 | 2308 | |
| 2312 | 2309 | go n oss@(one_shot:oss1) subst ty
|
| 2313 | 2310 | ----------- Forall types (forall a. ty)
|
| ... | ... | @@ -2348,27 +2345,28 @@ mkEtaWW orig_oss ppr_orig_expr in_scope orig_ty |
| 2348 | 2345 | -- we'd have had to zap it for the recursive call)
|
| 2349 | 2346 | , (in_scope, EI bs mco) <- go n oss subst ty'
|
| 2350 | 2347 | -- mco :: subst(ty') ~ b1_ty -> ... -> bn_ty -> tr
|
| 2351 | - = (in_scope, EI bs (mkTransMCoR co' mco))
|
|
| 2348 | + = (in_scope, EI bs (mkTransCoCastCo co' mco))
|
|
| 2352 | 2349 | |
| 2353 | 2350 | | otherwise -- We have an expression of arity > 0,
|
| 2354 | 2351 | -- but its type isn't a function, or a binder
|
| 2355 | 2352 | -- does not have a fixed runtime representation
|
| 2356 | 2353 | = warnPprTrace True "mkEtaWW" ((ppr orig_oss <+> ppr orig_ty) $$ ppr_orig_expr)
|
| 2357 | - (substInScopeSet subst, EI [] MRefl)
|
|
| 2354 | + (substInScopeSet subst, EI [] ReflCastCo)
|
|
| 2358 | 2355 | -- This *can* legitimately happen:
|
| 2359 | 2356 | -- e.g. coerce Int (\x. x) Essentially the programmer is
|
| 2360 | 2357 | -- playing fast and loose with types (Happy does this a lot).
|
| 2361 | 2358 | -- So we simply decline to eta-expand. Otherwise we'd end up
|
| 2362 | 2359 | -- with an explicit lambda having a non-function type
|
| 2363 | 2360 | |
| 2364 | -mkEtaForAllMCo :: ForAllTyBinder -> Type -> MCoercion -> MCoercion
|
|
| 2361 | +mkEtaForAllMCo :: ForAllTyBinder -> Type -> CastCoercion -> CastCoercion
|
|
| 2365 | 2362 | mkEtaForAllMCo (Bndr tcv vis) ty mco
|
| 2366 | 2363 | = case mco of
|
| 2367 | - MRefl | vis == coreTyLamForAllTyFlag -> MRefl
|
|
| 2368 | - | otherwise -> mk_fco (mkRepReflCo ty)
|
|
| 2369 | - MCo co -> mk_fco co
|
|
| 2364 | + ReflCastCo | vis == coreTyLamForAllTyFlag -> ReflCastCo
|
|
| 2365 | + | otherwise -> mk_fco (mkRepReflCo ty)
|
|
| 2366 | + CCoercion co -> mk_fco co
|
|
| 2367 | + ZCoercion ty2 cos -> ZCoercion ty cos -- TODO: is ty right?
|
|
| 2370 | 2368 | where
|
| 2371 | - mk_fco co = MCo (mkForAllCo tcv vis coreTyLamForAllTyFlag MRefl co)
|
|
| 2369 | + mk_fco co = CCoercion (mkForAllCo tcv vis coreTyLamForAllTyFlag MRefl co)
|
|
| 2372 | 2370 | -- coreTyLamForAllTyFlag: See Note [The EtaInfo mechanism], particularly
|
| 2373 | 2371 | -- the (EtaInfo Invariant). (sym co) wraps a lambda that always has
|
| 2374 | 2372 | -- a ForAllTyFlag of coreTyLamForAllTyFlag; see Note [Required foralls in Core]
|
| ... | ... | @@ -2701,13 +2699,13 @@ same fix. |
| 2701 | 2699 | tryEtaReduce :: UnVarSet -> [Var] -> CoreExpr -> SubDemand -> Maybe CoreExpr
|
| 2702 | 2700 | -- Return an expression equal to (\bndrs. body)
|
| 2703 | 2701 | tryEtaReduce rec_ids bndrs body eval_sd
|
| 2704 | - = go (reverse bndrs) body (mkRepReflCo (exprType body))
|
|
| 2702 | + = go (reverse bndrs) body ReflCastCo
|
|
| 2705 | 2703 | where
|
| 2706 | 2704 | incoming_arity = count isId bndrs -- See Note [Eta reduction makes sense], point (2)
|
| 2707 | 2705 | |
| 2708 | 2706 | go :: [Var] -- Binders, innermost first, types [a3,a2,a1]
|
| 2709 | 2707 | -> CoreExpr -- Of type tr
|
| 2710 | - -> Coercion -- Of type tr ~ ts
|
|
| 2708 | + -> CastCoercion -- Of type tr ~ ts
|
|
| 2711 | 2709 | -> Maybe CoreExpr -- Of type a1 -> a2 -> a3 -> ts
|
| 2712 | 2710 | -- See Note [Eta reduction with casted arguments]
|
| 2713 | 2711 | -- for why we have an accumulating coercion
|
| ... | ... | @@ -2717,7 +2715,7 @@ tryEtaReduce rec_ids bndrs body eval_sd |
| 2717 | 2715 | |
| 2718 | 2716 | -- See Note [Eta reduction with casted function]
|
| 2719 | 2717 | go bs (Cast e co1) co2
|
| 2720 | - = go bs e (castCoToCo (exprType e) co1 `mkTransCo` co2)
|
|
| 2718 | + = go bs e (co1 `mkTransCastCo` co2)
|
|
| 2721 | 2719 | |
| 2722 | 2720 | go bs (Tick t e) co
|
| 2723 | 2721 | | tickishFloatable t
|
| ... | ... | @@ -2740,7 +2738,7 @@ tryEtaReduce rec_ids bndrs body eval_sd |
| 2740 | 2738 | , remaining_bndrs `ltLength` bndrs
|
| 2741 | 2739 | -- Only reply Just if /something/ has happened
|
| 2742 | 2740 | , ok_fun fun
|
| 2743 | - , let used_vars = exprFreeVars fun `unionVarSet` tyCoVarsOfCo co
|
|
| 2741 | + , let used_vars = exprFreeVars fun `unionVarSet` tyCoVarsOfCastCo co
|
|
| 2744 | 2742 | reduced_bndrs = mkVarSet (dropList remaining_bndrs bndrs)
|
| 2745 | 2743 | -- reduced_bndrs are the ones we are eta-reducing away
|
| 2746 | 2744 | , used_vars `disjointVarSet` reduced_bndrs
|
| ... | ... | @@ -2749,7 +2747,7 @@ tryEtaReduce rec_ids bndrs body eval_sd |
| 2749 | 2747 | -- See Note [Eta reduction makes sense], intro and point (1)
|
| 2750 | 2748 | -- NB: don't compute used_vars from exprFreeVars (mkCast fun co)
|
| 2751 | 2749 | -- because the latter may be ill formed if the guard fails (#21801)
|
| 2752 | - = Just (mkLams (reverse remaining_bndrs) (mkCast fun co))
|
|
| 2750 | + = Just (mkLams (reverse remaining_bndrs) (mkCastCo fun co))
|
|
| 2753 | 2751 | |
| 2754 | 2752 | go _remaining_bndrs _fun _ = -- pprTrace "tER fail" (ppr _fun $$ ppr _remaining_bndrs) $
|
| 2755 | 2753 | Nothing
|
| ... | ... | @@ -2797,10 +2795,10 @@ tryEtaReduce rec_ids bndrs body eval_sd |
| 2797 | 2795 | ---------------
|
| 2798 | 2796 | ok_arg :: Var -- Of type bndr_t
|
| 2799 | 2797 | -> CoreExpr -- Of type arg_t
|
| 2800 | - -> Coercion -- Of kind (t1~t2)
|
|
| 2798 | + -> CastCoercion -- Of kind (t1~t2)
|
|
| 2801 | 2799 | -> Type -- Type (arg_t -> t1) of the function
|
| 2802 | 2800 | -- to which the argument is supplied
|
| 2803 | - -> Maybe (Coercion -- Of type (arg_t -> t1 ~ bndr_t -> t2)
|
|
| 2801 | + -> Maybe (CastCoercion -- Of type (arg_t -> t1 ~ bndr_t -> t2)
|
|
| 2804 | 2802 | -- (and similarly for tyvars, coercion args)
|
| 2805 | 2803 | , [CoreTickish])
|
| 2806 | 2804 | -- See Note [Eta reduction with casted arguments]
|
| ... | ... | @@ -2808,7 +2806,7 @@ tryEtaReduce rec_ids bndrs body eval_sd |
| 2808 | 2806 | | Just tv <- getTyVar_maybe arg_ty
|
| 2809 | 2807 | , bndr == tv = case splitForAllForAllTyBinder_maybe fun_ty of
|
| 2810 | 2808 | Just (Bndr _ vis, _) -> Just (fco, [])
|
| 2811 | - where !fco = mkForAllCo tv vis coreTyLamForAllTyFlag MRefl co
|
|
| 2809 | + where !fco = mkForAllCastCo tv vis coreTyLamForAllTyFlag co
|
|
| 2812 | 2810 | -- The lambda we are eta-reducing always has visibility
|
| 2813 | 2811 | -- 'coreTyLamForAllTyFlag' which may or may not match
|
| 2814 | 2812 | -- the visibility on the inner function (#24014)
|
| ... | ... | @@ -2821,13 +2819,13 @@ tryEtaReduce rec_ids bndrs body eval_sd |
| 2821 | 2819 | , let mult = idMult bndr
|
| 2822 | 2820 | , Just (_af, fun_mult, _, _) <- splitFunTy_maybe fun_ty
|
| 2823 | 2821 | , mult `eqType` fun_mult -- There is no change in multiplicity, otherwise we must abort
|
| 2824 | - = Just (mkFunResCo Representational bndr co, [])
|
|
| 2822 | + = Just (mkFunResCastCo Representational bndr co, [])
|
|
| 2825 | 2823 | ok_arg bndr (Cast e co_arg) co fun_ty
|
| 2826 | 2824 | | (ticks, Var v) <- stripTicksTop tickishFloatable e
|
| 2827 | - , Just (_, fun_mult, _, _) <- splitFunTy_maybe fun_ty
|
|
| 2825 | + , Just (_, fun_mult, _, res_ty) <- splitFunTy_maybe fun_ty
|
|
| 2828 | 2826 | , bndr == v
|
| 2829 | 2827 | , fun_mult `eqType` idMult bndr
|
| 2830 | - = Just (mkFunCoNoFTF Representational (multToCo fun_mult) (mkSymCo (castCoToCo (exprType e) co_arg)) co, ticks)
|
|
| 2828 | + = Just (mkFunCastCoNoFTF Representational fun_mult (castCoercionRKind (exprType e) co_arg) (mkSymCastCo (exprType e) co_arg) res_ty co, ticks) -- TODO check types
|
|
| 2831 | 2829 | -- The simplifier combines multiple casts into one,
|
| 2832 | 2830 | -- so we can have a simple-minded pattern match here
|
| 2833 | 2831 | ok_arg bndr (Tick t arg) co fun_ty
|
| ... | ... | @@ -2873,43 +2871,44 @@ Here we implement the "push rules" from FC papers: |
| 2873 | 2871 | by pushing the coercion into the arguments
|
| 2874 | 2872 | -}
|
| 2875 | 2873 | |
| 2876 | -pushCoArgs :: CoercionR -> [CoreArg] -> Maybe ([CoreArg], MCoercion)
|
|
| 2877 | -pushCoArgs co [] = return ([], MCo co)
|
|
| 2878 | -pushCoArgs co (arg:args) = do { (arg', m_co1) <- pushCoArg co arg
|
|
| 2879 | - ; case m_co1 of
|
|
| 2880 | - MCo co1 -> do { (args', m_co2) <- pushCoArgs co1 args
|
|
| 2881 | - ; return (arg':args', m_co2) }
|
|
| 2882 | - MRefl -> return (arg':args, MRefl) }
|
|
| 2883 | - |
|
| 2884 | -pushMCoArg :: MCoercionR -> CoreArg -> Maybe (CoreArg, MCoercion)
|
|
| 2885 | -pushMCoArg MRefl arg = Just (arg, MRefl)
|
|
| 2886 | -pushMCoArg (MCo co) arg = pushCoArg co arg
|
|
| 2887 | - |
|
| 2888 | -pushCoArg :: CoercionR -> CoreArg -> Maybe (CoreArg, MCoercion)
|
|
| 2874 | +pushCoArgs :: Type -> CastCoercion -> [CoreArg] -> Maybe ([CoreArg], CastCoercion)
|
|
| 2875 | +pushCoArgs _ co [] = return ([], co)
|
|
| 2876 | +pushCoArgs fun_ty co (arg:args) = do
|
|
| 2877 | + { (arg', m_co1) <- pushCoArg fun_ty co arg
|
|
| 2878 | + ; if isReflCastCo m_co1
|
|
| 2879 | + then return (arg':args, ReflCastCo)
|
|
| 2880 | + else do { (args', m_co2) <- pushCoArgs (funResultTy fun_ty) m_co1 args -- TODO check type
|
|
| 2881 | + ; return (arg':args', m_co2) }
|
|
| 2882 | + }
|
|
| 2883 | + |
|
| 2884 | +pushCoArg :: Type -> CastCoercion -> CoreArg -> Maybe (CoreArg, CastCoercion)
|
|
| 2889 | 2885 | -- We have (fun |> co) arg, and we want to transform it to
|
| 2890 | 2886 | -- (fun arg) |> co
|
| 2891 | 2887 | -- This may fail, e.g. if (fun :: N) where N is a newtype
|
| 2892 | 2888 | -- C.f. simplCast in GHC.Core.Opt.Simplify
|
| 2893 | 2889 | -- 'co' is always Representational
|
| 2894 | -pushCoArg co arg
|
|
| 2890 | +pushCoArg fun_ty co arg
|
|
| 2895 | 2891 | | Type ty <- arg
|
| 2896 | - = do { (ty', m_co') <- pushCoTyArg co ty
|
|
| 2892 | + = do { (ty', m_co') <- pushCastCoTyArg co ty
|
|
| 2897 | 2893 | ; return (Type ty', m_co') }
|
| 2898 | 2894 | | otherwise
|
| 2899 | - = do { (arg_mco, m_co') <- pushCoValArg co
|
|
| 2900 | - ; let arg_mco' = checkReflexiveMCo arg_mco
|
|
| 2901 | - -- checkReflexiveMCo: see Note [Check for reflexive casts in eta expansion]
|
|
| 2895 | + = do { (arg_mco, m_co') <- pushCastCoValArg fun_ty co
|
|
| 2896 | + ; let arg_mco' = checkReflexiveCastCo (funArgTy fun_ty) arg_mco
|
|
| 2897 | + -- checkReflexiveCastCo: see Note [Check for reflexive casts in eta expansion]
|
|
| 2902 | 2898 | -- The coercion is very often (arg_co -> res_co), but without
|
| 2903 | 2899 | -- the argument coercion actually being ReflCo
|
| 2904 | - ; return (arg `mkCastMCo` arg_mco', m_co') }
|
|
| 2900 | + ; return (arg `mkCastCo` arg_mco', m_co') }
|
|
| 2901 | + |
|
| 2902 | +pushCastCoTyArg :: CastCoercion -> Type -> Maybe (Type, CastCoercion)
|
|
| 2903 | +pushCastCoTyArg (CCoercion co) ty = pushCoTyArg co ty
|
|
| 2904 | +pushCastCoTyArg ReflCastCo ty = Just (ty, ReflCastCo)
|
|
| 2905 | +pushCastCoTyArg (ZCoercion fun_ty cos) ty = Nothing -- TODO do better
|
|
| 2905 | 2906 | |
| 2906 | -pushCoTyArg :: CoercionR -> Type -> Maybe (Type, MCoercionR)
|
|
| 2907 | +pushCoTyArg :: CoercionR -> Type -> Maybe (Type, CastCoercion)
|
|
| 2907 | 2908 | -- We have (fun |> co) @ty
|
| 2908 | 2909 | -- Push the coercion through to return
|
| 2909 | 2910 | -- (fun @ty') |> co'
|
| 2910 | 2911 | -- 'co' is always Representational
|
| 2911 | --- If the returned coercion is Nothing, then it would have been reflexive;
|
|
| 2912 | --- it's faster not to compute it, though.
|
|
| 2913 | 2912 | pushCoTyArg co ty
|
| 2914 | 2913 | -- The following is inefficient - don't do `eqType` here, the coercion
|
| 2915 | 2914 | -- optimizer will take care of it. See #14737.
|
| ... | ... | @@ -2917,11 +2916,11 @@ pushCoTyArg co ty |
| 2917 | 2916 | -- -- = Just (ty, Nothing)
|
| 2918 | 2917 | |
| 2919 | 2918 | | isReflCo co
|
| 2920 | - = Just (ty, MRefl)
|
|
| 2919 | + = Just (ty, ReflCastCo)
|
|
| 2921 | 2920 | |
| 2922 | 2921 | | isForAllTy_ty tyL
|
| 2923 | 2922 | = assertPpr (isForAllTy_ty tyR) (ppr co $$ ppr ty) $
|
| 2924 | - Just (ty `mkCastTy` co1, MCo co2)
|
|
| 2923 | + Just (ty `mkCastTy` co1, CCoercion co2)
|
|
| 2925 | 2924 | |
| 2926 | 2925 | | otherwise
|
| 2927 | 2926 | = Nothing
|
| ... | ... | @@ -2941,6 +2940,18 @@ pushCoTyArg co ty |
| 2941 | 2940 | -- co2 :: ty1[ (ty|>co1)/a1 ] ~R ty2[ ty/a2 ]
|
| 2942 | 2941 | -- Arg of mkInstCo is always nominal, hence Nominal
|
| 2943 | 2942 | |
| 2943 | +pushCastCoValArg :: Type -> CastCoercion -> Maybe (CastCoercion, CastCoercion)
|
|
| 2944 | +pushCastCoValArg _ ReflCastCo = Just (ReflCastCo, ReflCastCo)
|
|
| 2945 | +pushCastCoValArg _ (CCoercion co) = pushCoValArg co
|
|
| 2946 | +pushCastCoValArg tyL (ZCoercion tyR cos)
|
|
| 2947 | + | isFunTy tyL -- TODO: do we need to check this or can we assume it?
|
|
| 2948 | + , isFunTy tyR
|
|
| 2949 | + , typeHasFixedRuntimeRep new_arg_ty
|
|
| 2950 | + = Just (ZCoercion new_arg_ty cos, ZCoercion (funResultTy tyR) cos)
|
|
| 2951 | + | otherwise = Nothing
|
|
| 2952 | + where
|
|
| 2953 | + new_arg_ty = funArgTy tyR
|
|
| 2954 | + |
|
| 2944 | 2955 | -- | If @pushCoValArg co = Just (co_arg, co_res)@, then
|
| 2945 | 2956 | --
|
| 2946 | 2957 | -- > (\x.body) |> co = (\y. let { x = y |> co_arg } in body) |> co_res)
|
| ... | ... | @@ -2952,7 +2963,7 @@ pushCoTyArg co ty |
| 2952 | 2963 | -- If the LHS is well-typed, then so is the RHS. In particular, the argument
|
| 2953 | 2964 | -- @arg |> co_arg@ is guaranteed to have a fixed 'RuntimeRep', in the sense of
|
| 2954 | 2965 | -- Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete.
|
| 2955 | -pushCoValArg :: CoercionR -> Maybe (MCoercionR, MCoercionR)
|
|
| 2966 | +pushCoValArg :: CoercionR -> Maybe (CastCoercion, CastCoercion)
|
|
| 2956 | 2967 | pushCoValArg co
|
| 2957 | 2968 | -- The following is inefficient - don't do `eqType` here, the coercion
|
| 2958 | 2969 | -- optimizer will take care of it. See #14737.
|
| ... | ... | @@ -2960,7 +2971,7 @@ pushCoValArg co |
| 2960 | 2971 | -- -- = Just (mkRepReflCo arg, Nothing)
|
| 2961 | 2972 | |
| 2962 | 2973 | | isReflCo co
|
| 2963 | - = Just (MRefl, MRefl)
|
|
| 2974 | + = Just (ReflCastCo, ReflCastCo)
|
|
| 2964 | 2975 | |
| 2965 | 2976 | | isFunTy tyL
|
| 2966 | 2977 | , (_, co1, co2) <- decomposeFunCo co
|
| ... | ... | @@ -2979,8 +2990,8 @@ pushCoValArg co |
| 2979 | 2990 | (vcat [ text "co:" <+> ppr co
|
| 2980 | 2991 | , text "old_arg_ty:" <+> ppr old_arg_ty
|
| 2981 | 2992 | , text "new_arg_ty:" <+> ppr new_arg_ty ]) $
|
| 2982 | - Just (coToMCo (mkSymCo co1), coToMCo co2)
|
|
| 2983 | - -- Critically, coToMCo to checks for ReflCo; the whole coercion may not
|
|
| 2993 | + Just (coToCastCo (mkSymCo co1), coToCastCo co2)
|
|
| 2994 | + -- Critically, coToCastCo to checks for ReflCo; the whole coercion may not
|
|
| 2984 | 2995 | -- be reflexive, but either of its components might be
|
| 2985 | 2996 | -- We could use isReflexiveCo, but it's not clear if the benefit
|
| 2986 | 2997 | -- is worth the cost, and it makes no difference in #18223
|
| ... | ... | @@ -2993,13 +3004,14 @@ pushCoValArg co |
| 2993 | 3004 | Pair tyL tyR = coercionKind co
|
| 2994 | 3005 | |
| 2995 | 3006 | pushCoercionIntoLambda
|
| 2996 | - :: HasDebugCallStack => Subst -> InVar -> InExpr -> OutCoercionR -> Maybe (OutVar, OutExpr)
|
|
| 3007 | + :: HasDebugCallStack => Subst -> InVar -> InExpr -> OutCastCoercion -> Maybe (OutVar, OutExpr)
|
|
| 2997 | 3008 | -- This implements the Push rule from the paper on coercions
|
| 2998 | 3009 | -- (\x. e) |> co
|
| 2999 | 3010 | -- ===>
|
| 3000 | 3011 | -- (\x'. e |> co')
|
| 3001 | -pushCoercionIntoLambda subst x e co
|
|
| 3012 | +pushCoercionIntoLambda subst x e cco
|
|
| 3002 | 3013 | | assert (not (isTyVar x) && not (isCoVar x)) True
|
| 3014 | + , CCoercion co <- cco -- AMG TODO: support for other CastCoercions
|
|
| 3003 | 3015 | , Pair s1s2 t1t2 <- coercionKind co
|
| 3004 | 3016 | , Just {} <- splitFunTy_maybe s1s2
|
| 3005 | 3017 | , Just (_, w1, t1,_t2) <- splitFunTy_maybe t1t2
|
| ... | ... | @@ -3024,7 +3036,7 @@ pushCoercionIntoLambda subst x e co |
| 3024 | 3036 | | otherwise
|
| 3025 | 3037 | = Nothing
|
| 3026 | 3038 | |
| 3027 | -pushCoDataCon :: DataCon -> [CoreExpr] -> MCoercionR
|
|
| 3039 | +pushCoDataCon :: DataCon -> [CoreExpr] -> CastCoercion
|
|
| 3028 | 3040 | -> Maybe (DataCon
|
| 3029 | 3041 | , [Type] -- Universal type args
|
| 3030 | 3042 | , [CoreExpr]) -- All other args incl existentials
|
| ... | ... | @@ -3034,8 +3046,9 @@ pushCoDataCon :: DataCon -> [CoreExpr] -> MCoercionR |
| 3034 | 3046 | -- where co :: (T t1 .. tn) ~ (T s1 .. sn)
|
| 3035 | 3047 | -- The left-hand one must be a T, because exprIsConApp returned True
|
| 3036 | 3048 | -- but the right-hand one might not be. (Though it usually will.)
|
| 3037 | -pushCoDataCon dc dc_args MRefl = Just $! (push_dc_refl dc dc_args)
|
|
| 3038 | -pushCoDataCon dc dc_args (MCo co) = push_dc_gen dc dc_args co (coercionKind co)
|
|
| 3049 | +pushCoDataCon dc dc_args ReflCastCo = Just $! (push_dc_refl dc dc_args)
|
|
| 3050 | +pushCoDataCon dc dc_args (CCoercion co) = push_dc_gen dc dc_args co (coercionKind co)
|
|
| 3051 | +pushCoDataCon dc dc_args (ZCoercion ty cos) = Nothing -- AMG TODO: pushCoDataCon
|
|
| 3039 | 3052 | |
| 3040 | 3053 | push_dc_refl :: DataCon -> [CoreExpr] -> (DataCon, [Type], [CoreExpr])
|
| 3041 | 3054 | push_dc_refl dc dc_args
|
| ... | ... | @@ -36,7 +36,7 @@ import GHC.Prelude hiding ( head, init, last, tail ) |
| 36 | 36 | import GHC.Core
|
| 37 | 37 | import GHC.Core.FVs
|
| 38 | 38 | import GHC.Core.Utils ( exprIsTrivial, isDefaultAlt, isExpandableApp,
|
| 39 | - mkCastMCo, mkTicks )
|
|
| 39 | + mkCastCo, mkTicks )
|
|
| 40 | 40 | import GHC.Core.Opt.Arity ( joinRhsArity, isOneShotBndr )
|
| 41 | 41 | import GHC.Core.Coercion
|
| 42 | 42 | import GHC.Core.Type
|
| ... | ... | @@ -2853,7 +2853,7 @@ data OccEnv |
| 2853 | 2853 | -- If x :-> (y, co) is in the env,
|
| 2854 | 2854 | -- then please replace x by (y |> mco)
|
| 2855 | 2855 | -- Invariant of course: idType x = exprType (y |> mco)
|
| 2856 | - , occ_bs_env :: !(IdEnv (OutId, MCoercion))
|
|
| 2856 | + , occ_bs_env :: !(IdEnv (OutId, CastCoercion))
|
|
| 2857 | 2857 | -- Domain is Global and Local Ids
|
| 2858 | 2858 | -- Range is just Local Ids
|
| 2859 | 2859 | , occ_bs_rng :: !VarSet
|
| ... | ... | @@ -3455,7 +3455,7 @@ addBndrSwap scrut case_bndr |
| 3455 | 3455 | -- Do not add [x :-> x] to occ_bs_env, else lookupBndrSwap will loop
|
| 3456 | 3456 | = env { occ_bs_env = extendVarEnv swap_env scrut_var (case_bndr', mco)
|
| 3457 | 3457 | , occ_bs_rng = rng_vars `extendVarSet` case_bndr'
|
| 3458 | - `unionVarSet` tyCoVarsOfMCo mco }
|
|
| 3458 | + `unionVarSet` tyCoVarsOfCastCo mco }
|
|
| 3459 | 3459 | |
| 3460 | 3460 | | otherwise
|
| 3461 | 3461 | = env
|
| ... | ... | @@ -3466,7 +3466,7 @@ addBndrSwap scrut case_bndr |
| 3466 | 3466 | -- | See bBinderSwaOk.
|
| 3467 | 3467 | data BinderSwapDecision
|
| 3468 | 3468 | = NoBinderSwap
|
| 3469 | - | DoBinderSwap OutVar MCoercion
|
|
| 3469 | + | DoBinderSwap OutVar CastCoercion
|
|
| 3470 | 3470 | |
| 3471 | 3471 | scrutOkForBinderSwap :: OutExpr -> BinderSwapDecision
|
| 3472 | 3472 | -- If (scrutOkForBinderSwap e = DoBinderSwap v mco, then
|
| ... | ... | @@ -3479,8 +3479,8 @@ scrutOkForBinderSwap :: OutExpr -> BinderSwapDecision |
| 3479 | 3479 | scrutOkForBinderSwap e
|
| 3480 | 3480 | = case e of
|
| 3481 | 3481 | Tick _ e -> scrutOkForBinderSwap e -- Drop ticks
|
| 3482 | - Var v -> DoBinderSwap v MRefl
|
|
| 3483 | - Cast (Var v) co -> DoBinderSwap v (MCo (mkSymCo (castCoToCo (idType v) co))) -- TODO: can we do better?
|
|
| 3482 | + Var v -> DoBinderSwap v ReflCastCo
|
|
| 3483 | + Cast (Var v) co -> DoBinderSwap v (mkSymCastCo (idType v) co)
|
|
| 3484 | 3484 | -- Cast: see Note [Case of cast]
|
| 3485 | 3485 | _ -> NoBinderSwap
|
| 3486 | 3486 | |
| ... | ... | @@ -3495,7 +3495,7 @@ lookupBndrSwap env@(OccEnv { occ_bs_env = bs_env }) bndr |
| 3495 | 3495 | -- Why do we iterate here?
|
| 3496 | 3496 | -- See (BS2) in Note [The binder-swap substitution]
|
| 3497 | 3497 | case lookupBndrSwap env bndr1 of
|
| 3498 | - (fun, fun_id) -> (mkCastMCo fun mco, fun_id) }
|
|
| 3498 | + (fun, fun_id) -> (mkCastCo fun mco, fun_id) }
|
|
| 3499 | 3499 | |
| 3500 | 3500 | {- Historical note [Proxy let-bindings]
|
| 3501 | 3501 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -19,6 +19,7 @@ import GHC.Core.Opt.Simplify.Monad |
| 19 | 19 | import GHC.Core.Opt.ConstantFold
|
| 20 | 20 | import GHC.Core.Type hiding ( substCo, substTy, substTyVar, extendTvSubst, extendCvSubst )
|
| 21 | 21 | import GHC.Core.TyCo.Compare( eqType )
|
| 22 | +import GHC.Core.TyCo.Subst ( substCoVarSet )
|
|
| 22 | 23 | import GHC.Core.Opt.Simplify.Env
|
| 23 | 24 | import GHC.Core.Opt.Simplify.Inline
|
| 24 | 25 | import GHC.Core.Opt.Simplify.Utils
|
| ... | ... | @@ -36,7 +37,7 @@ import GHC.Core.Unfold |
| 36 | 37 | import GHC.Core.Unfold.Make
|
| 37 | 38 | import GHC.Core.Utils
|
| 38 | 39 | import GHC.Core.Opt.Arity ( ArityType, exprArity, arityTypeBotSigs_maybe
|
| 39 | - , pushCoTyArg, pushCoValArg, exprIsDeadEnd
|
|
| 40 | + , pushCastCoTyArg, pushCastCoValArg, exprIsDeadEnd
|
|
| 40 | 41 | , typeArity, arityTypeArity, etaExpandAT )
|
| 41 | 42 | import GHC.Core.SimpleOpt ( exprIsConApp_maybe, joinPointBinding_maybe, joinPointBindings_maybe )
|
| 42 | 43 | import GHC.Core.FVs ( mkRuleInfo {- exprsFreeIds -} )
|
| ... | ... | @@ -54,6 +55,7 @@ import GHC.Types.Unique ( hasKey ) |
| 54 | 55 | import GHC.Types.Basic
|
| 55 | 56 | import GHC.Types.Tickish
|
| 56 | 57 | import GHC.Types.Var ( isTyCoVar )
|
| 58 | +import GHC.Types.Var.Set
|
|
| 57 | 59 | import GHC.Builtin.Types.Prim( realWorldStatePrimTy )
|
| 58 | 60 | import GHC.Builtin.Names( runRWKey, seqHashKey )
|
| 59 | 61 | |
| ... | ... | @@ -644,7 +646,7 @@ tryCastWorkerWrapper env bind_cxt old_bndr bndr (Cast rhs co) |
| 644 | 646 | mk_worker_unfolding top_lvl work_id work_rhs
|
| 645 | 647 | = case realUnfoldingInfo info of -- NB: the real one, even for loop-breakers
|
| 646 | 648 | unf@(CoreUnfolding { uf_tmpl = unf_rhs, uf_src = src })
|
| 647 | - | isStableSource src -> return (unf { uf_tmpl = mkCast unf_rhs (mkSymCo (castCoToCo (exprType rhs) co)) })
|
|
| 649 | + | isStableSource src -> return (unf { uf_tmpl = mkCastCo unf_rhs (mkSymCastCo (exprType rhs) co) })
|
|
| 648 | 650 | _ -> mkLetUnfolding env top_lvl VanillaSrc work_id False work_rhs
|
| 649 | 651 | |
| 650 | 652 | tryCastWorkerWrapper env _ _ bndr rhs -- All other bindings
|
| ... | ... | @@ -1361,6 +1363,15 @@ simplCoercion env co |
| 1361 | 1363 | subst = getTCvSubst env
|
| 1362 | 1364 | opts = seOptCoercionOpts env
|
| 1363 | 1365 | |
| 1366 | +simplCastCoercion :: SimplEnv -> InType -> InCastCoercion -> SimplM (OutType, OutCastCoercion)
|
|
| 1367 | +simplCastCoercion env _ (CCoercion co) = (\co -> (coercionLKind co, CCoercion co)) <$> simplCoercion env co
|
|
| 1368 | +simplCastCoercion env tyL (ZCoercion tyR cos) = (,) <$> simplType env tyL <*> (ZCoercion <$> simplType env tyR <*> simplCoVars env cos)
|
|
| 1369 | +simplCastCoercion env tyL ReflCastCo = (,) <$> simplType env tyL <*> pure ReflCastCo
|
|
| 1370 | + |
|
| 1371 | +simplCoVars :: SimplEnv -> CoVarSet -> SimplM CoVarSet
|
|
| 1372 | +simplCoVars env covars = pure $ substCoVarSet (getTCvSubst env) covars
|
|
| 1373 | + |
|
| 1374 | + |
|
| 1364 | 1375 | -----------------------------------
|
| 1365 | 1376 | -- | Push a TickIt context outwards past applications and cases, as
|
| 1366 | 1377 | -- long as this is a non-scoping tick, to let case and application
|
| ... | ... | @@ -1531,10 +1542,10 @@ rebuild_go env expr cont |
| 1531 | 1542 | Stop {} -> return (emptyFloats env, expr)
|
| 1532 | 1543 | TickIt t cont -> rebuild_go env (mkTick t expr) cont
|
| 1533 | 1544 | CastIt { sc_co = co, sc_opt = opt, sc_cont = cont }
|
| 1534 | - -> rebuild_go env (mkCast expr co') cont
|
|
| 1545 | + -> rebuild_go env (mkCastCo expr co') cont
|
|
| 1535 | 1546 | -- NB: mkCast implements the (Coercion co |> g) optimisation
|
| 1536 | 1547 | where
|
| 1537 | - co' = optOutCoercion env co opt
|
|
| 1548 | + co' = optOutCastCoercion env co opt
|
|
| 1538 | 1549 | |
| 1539 | 1550 | Select { sc_bndr = bndr, sc_alts = alts, sc_env = se, sc_cont = cont }
|
| 1540 | 1551 | -> rebuildCase (se `setInScopeFromE` env) expr bndr alts cont
|
| ... | ... | @@ -1663,6 +1674,12 @@ on each successive composition -- that's at least quadratic. So: |
| 1663 | 1674 | -}
|
| 1664 | 1675 | |
| 1665 | 1676 | |
| 1677 | +optOutCastCoercion :: SimplEnvIS -> OutCastCoercion -> Bool -> OutCastCoercion
|
|
| 1678 | +optOutCastCoercion env cco already_optimised = case cco of
|
|
| 1679 | + ReflCastCo -> ReflCastCo
|
|
| 1680 | + CCoercion co -> CCoercion (optOutCoercion env co already_optimised)
|
|
| 1681 | + ZCoercion{} -> cco
|
|
| 1682 | + |
|
| 1666 | 1683 | optOutCoercion :: SimplEnvIS -> OutCoercion -> Bool -> OutCoercion
|
| 1667 | 1684 | -- See Note [Avoid re-simplifying coercions]
|
| 1668 | 1685 | optOutCoercion env co already_optimised
|
| ... | ... | @@ -1675,72 +1692,74 @@ optOutCoercion env co already_optimised |
| 1675 | 1692 | simplCast :: SimplEnv -> InExpr -> InCastCoercion -> SimplCont
|
| 1676 | 1693 | -> SimplM (SimplFloats, OutExpr)
|
| 1677 | 1694 | simplCast env body co0 cont0
|
| 1678 | - = do { co1 <- {-#SCC "simplCast-simplCoercion" #-} simplCoercion env (castCoToCo (exprType body) co0) -- TODO better way?
|
|
| 1695 | + = do { (tyL, co1) <- {-#SCC "simplCast-simplCoercion" #-} simplCastCoercion env (exprType body) co0
|
|
| 1679 | 1696 | ; cont1 <- {-#SCC "simplCast-addCoerce" #-}
|
| 1680 | - if isReflCo co1
|
|
| 1697 | + if isReflCastCo co1
|
|
| 1681 | 1698 | then return cont0 -- See Note [Optimising reflexivity]
|
| 1682 | - else addCoerce co1 True cont0
|
|
| 1699 | + else addCoerce tyL co1 True cont0
|
|
| 1683 | 1700 | -- True <=> co1 is optimised
|
| 1684 | 1701 | ; {-#SCC "simplCast-simplExprF" #-} simplExprF env body cont1 }
|
| 1685 | 1702 | where
|
| 1686 | 1703 | |
| 1687 | 1704 | -- If the first parameter is MRefl, then simplifying revealed a
|
| 1688 | 1705 | -- reflexive coercion. Omit.
|
| 1689 | - addCoerceM :: MOutCoercion -> Bool -> SimplCont -> SimplM SimplCont
|
|
| 1690 | - addCoerceM MRefl _ cont = return cont
|
|
| 1691 | - addCoerceM (MCo co) opt cont = addCoerce co opt cont
|
|
| 1692 | - |
|
| 1693 | - addCoerce :: OutCoercion -> Bool -> SimplCont -> SimplM SimplCont
|
|
| 1694 | - addCoerce co1 _ (CastIt { sc_co = co2, sc_cont = cont }) -- See Note [Optimising reflexivity]
|
|
| 1695 | - = addCoerce (mkTransCo co1 co2) False cont
|
|
| 1706 | + -- TODO: probably can simplify this further now?
|
|
| 1707 | + addCoerceM :: OutType -> OutCastCoercion -> Bool -> SimplCont -> SimplM SimplCont
|
|
| 1708 | + addCoerceM _ ReflCastCo _ cont = return cont
|
|
| 1709 | + addCoerceM tyL co opt cont = addCoerce tyL co opt cont
|
|
| 1710 | + |
|
| 1711 | + -- Type tyL is the coercionLKind of the coercion
|
|
| 1712 | + addCoerce :: OutType -> OutCastCoercion -> Bool -> SimplCont -> SimplM SimplCont
|
|
| 1713 | + addCoerce tyL co1 _ (CastIt { sc_co = co2, sc_cont = cont }) -- See Note [Optimising reflexivity]
|
|
| 1714 | + = addCoerce tyL (mkTransCastCo co1 co2) False cont
|
|
| 1696 | 1715 | -- False: (mkTransCo co1 co2) is not fully optimised
|
| 1697 | 1716 | -- See Note [Avoid re-simplifying coercions]
|
| 1698 | 1717 | |
| 1699 | - addCoerce co co_is_opt (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = tail })
|
|
| 1700 | - | Just (arg_ty', m_co') <- pushCoTyArg co arg_ty
|
|
| 1718 | + addCoerce tyL co co_is_opt (ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = tail })
|
|
| 1719 | + | Just (arg_ty', m_co') <- pushCastCoTyArg co arg_ty
|
|
| 1701 | 1720 | = {-#SCC "addCoerce-pushCoTyArg" #-}
|
| 1702 | - do { tail' <- addCoerceM m_co' co_is_opt tail
|
|
| 1721 | + do { tail' <- addCoerceM hole_ty m_co' co_is_opt tail -- TODO is hole_ty right?
|
|
| 1703 | 1722 | ; return (ApplyToTy { sc_arg_ty = arg_ty'
|
| 1704 | 1723 | , sc_cont = tail'
|
| 1705 | - , sc_hole_ty = coercionLKind co }) }
|
|
| 1724 | + , sc_hole_ty = tyL }) }
|
|
| 1706 | 1725 | -- NB! As the cast goes past, the
|
| 1707 | 1726 | -- type of the hole changes (#16312)
|
| 1708 | 1727 | -- (f |> co) e ===> (f (e |> co1)) |> co2
|
| 1709 | 1728 | -- where co :: (s1->s2) ~ (t1->t2)
|
| 1710 | 1729 | -- co1 :: t1 ~ s1
|
| 1711 | 1730 | -- co2 :: s2 ~ t2
|
| 1712 | - addCoerce co co_is_opt cont@(ApplyToVal { sc_arg = arg, sc_env = arg_se
|
|
| 1731 | + addCoerce tyL co co_is_opt cont@(ApplyToVal { sc_arg = arg, sc_env = arg_se
|
|
| 1713 | 1732 | , sc_dup = dup, sc_cont = tail
|
| 1714 | 1733 | , sc_hole_ty = fun_ty })
|
| 1715 | 1734 | | not co_is_opt -- pushCoValArg duplicates the coercion, so optimise first
|
| 1716 | - = addCoerce (optOutCoercion (zapSubstEnv env) co co_is_opt) True cont
|
|
| 1735 | + = addCoerce tyL (optOutCastCoercion (zapSubstEnv env) co co_is_opt) True cont
|
|
| 1717 | 1736 | |
| 1718 | - | Just (m_co1, m_co2) <- pushCoValArg co
|
|
| 1737 | + | Just (m_co1, m_co2) <- pushCastCoValArg fun_ty co -- TODO check fun_ty
|
|
| 1719 | 1738 | = {-#SCC "addCoerce-pushCoValArg" #-}
|
| 1720 | - do { tail' <- addCoerceM m_co2 co_is_opt tail
|
|
| 1721 | - ; case m_co1 of {
|
|
| 1722 | - MRefl -> return (cont { sc_cont = tail'
|
|
| 1723 | - , sc_hole_ty = coercionLKind co }) ;
|
|
| 1739 | + do { tail' <- addCoerceM (funResultTy fun_ty) m_co2 co_is_opt tail -- TODO check funResultTy fun_ty
|
|
| 1740 | + ; if isReflCastCo m_co1
|
|
| 1741 | + then return (cont { sc_cont = tail'
|
|
| 1742 | + , sc_hole_ty = tyL }) ;
|
|
| 1724 | 1743 | -- See Note [Avoiding simplifying repeatedly]
|
| 1725 | 1744 | |
| 1726 | - MCo co1 ->
|
|
| 1745 | + else
|
|
| 1727 | 1746 | do { (dup', arg_se', arg') <- simplLazyArg env dup fun_ty Nothing arg_se arg
|
| 1728 | 1747 | -- When we build the ApplyTo we can't mix the OutCoercion
|
| 1729 | 1748 | -- 'co' with the InExpr 'arg', so we simplify
|
| 1730 | 1749 | -- to make it all consistent. It's a bit messy.
|
| 1731 | 1750 | -- But it isn't a common case.
|
| 1732 | 1751 | -- Example of use: #995
|
| 1733 | - ; return (ApplyToVal { sc_arg = mkCast arg' co1
|
|
| 1752 | + ; return (ApplyToVal { sc_arg = mkCastCo arg' m_co1
|
|
| 1734 | 1753 | , sc_env = arg_se'
|
| 1735 | 1754 | , sc_dup = dup'
|
| 1736 | 1755 | , sc_cont = tail'
|
| 1737 | - , sc_hole_ty = coercionLKind co }) } } }
|
|
| 1756 | + , sc_hole_ty = tyL }) } }
|
|
| 1738 | 1757 | |
| 1739 | - addCoerce co co_is_opt cont
|
|
| 1740 | - | isReflCo co = return cont -- Having this at the end makes a huge
|
|
| 1758 | + addCoerce tyL co co_is_opt cont
|
|
| 1759 | + | isReflCastCo co = return cont -- Having this at the end makes a huge
|
|
| 1741 | 1760 | -- difference in T12227, for some reason
|
| 1742 | 1761 | -- See Note [Optimising reflexivity]
|
| 1743 | - | otherwise = return (CastIt { sc_co = co, sc_opt = co_is_opt, sc_cont = cont })
|
|
| 1762 | + | otherwise = return (CastIt { sc_co = co, sc_hole_ty = tyL, sc_opt = co_is_opt, sc_cont = cont })
|
|
| 1744 | 1763 | |
| 1745 | 1764 | simplLazyArg :: SimplEnvIS -- ^ Used only for its InScopeSet
|
| 1746 | 1765 | -> DupFlag
|
| ... | ... | @@ -3595,9 +3614,9 @@ addAltUnfoldings env case_bndr bndr_swap con_app |
| 3595 | 3614 | -- See Note [Add unfolding for scrutinee]
|
| 3596 | 3615 | env2 | DoBinderSwap v mco <- bndr_swap
|
| 3597 | 3616 | = addBinderUnfolding env1 v $
|
| 3598 | - if isReflMCo mco -- isReflMCo: avoid calling mk_simple_unf
|
|
| 3617 | + if isReflCastCo mco -- isReflCastCo: avoid calling mk_simple_unf
|
|
| 3599 | 3618 | then con_app_unf -- twice in the common case
|
| 3600 | - else mk_simple_unf (mkCastMCo con_app mco)
|
|
| 3619 | + else mk_simple_unf (mkCastCo con_app mco)
|
|
| 3601 | 3620 | |
| 3602 | 3621 | | otherwise = env1
|
| 3603 | 3622 | |
| ... | ... | @@ -3865,9 +3884,10 @@ mkDupableContWithDmds env _ cont |
| 3865 | 3884 | |
| 3866 | 3885 | mkDupableContWithDmds _ _ (Stop {}) = panic "mkDupableCont" -- Handled by previous eqn
|
| 3867 | 3886 | |
| 3868 | -mkDupableContWithDmds env dmds (CastIt { sc_co = co, sc_opt = opt, sc_cont = cont })
|
|
| 3887 | +mkDupableContWithDmds env dmds (CastIt { sc_co = co, sc_hole_ty = ty, sc_opt = opt, sc_cont = cont })
|
|
| 3869 | 3888 | = do { (floats, cont') <- mkDupableContWithDmds env dmds cont
|
| 3870 | - ; return (floats, CastIt { sc_co = optOutCoercion env co opt
|
|
| 3889 | + ; return (floats, CastIt { sc_co = optOutCastCoercion env co opt
|
|
| 3890 | + , sc_hole_ty = ty
|
|
| 3871 | 3891 | , sc_opt = True, sc_cont = cont' }) }
|
| 3872 | 3892 | -- optOutCoercion: see Note [Avoid re-simplifying coercions]
|
| 3873 | 3893 |
| ... | ... | @@ -52,7 +52,7 @@ import GHC.Core.Opt.Simplify.Inline( smallEnoughToInline ) |
| 52 | 52 | import GHC.Core.Opt.Stats ( Tick(..) )
|
| 53 | 53 | import qualified GHC.Core.Subst
|
| 54 | 54 | import GHC.Core.Ppr
|
| 55 | -import GHC.Core.TyCo.Ppr ( pprParendType )
|
|
| 55 | +import GHC.Core.TyCo.Ppr ( pprParendType, pprCastCo )
|
|
| 56 | 56 | import GHC.Core.FVs
|
| 57 | 57 | import GHC.Core.Utils
|
| 58 | 58 | import GHC.Core.Opt.Arity
|
| ... | ... | @@ -162,8 +162,9 @@ data SimplCont |
| 162 | 162 | |
| 163 | 163 | |
| 164 | 164 | | CastIt -- (CastIt co K)[e] = K[ e `cast` co ]
|
| 165 | - { sc_co :: OutCoercion -- The coercion simplified
|
|
| 165 | + { sc_co :: OutCastCoercion -- The coercion simplified
|
|
| 166 | 166 | -- Invariant: never an identity coercion
|
| 167 | + , sc_hole_ty :: OutType -- LHS kind of sc_co
|
|
| 167 | 168 | , sc_opt :: Bool -- True <=> sc_co has had optCoercion applied to it
|
| 168 | 169 | -- See Note [Avoid re-simplifying coercions]
|
| 169 | 170 | -- in GHC.Core.Opt.Simplify.Iteration
|
| ... | ... | @@ -277,7 +278,7 @@ instance Outputable SimplCont where |
| 277 | 278 | where
|
| 278 | 279 | pps = [ppr interesting] ++ [ppr eval_sd | eval_sd /= topSubDmd]
|
| 279 | 280 | ppr (CastIt { sc_co = co, sc_cont = cont })
|
| 280 | - = (text "CastIt" <+> pprOptCo co) $$ ppr cont
|
|
| 281 | + = (text "CastIt" <+> pprCastCo co) $$ ppr cont
|
|
| 281 | 282 | ppr (TickIt t cont)
|
| 282 | 283 | = (text "TickIt" <+> ppr t) $$ ppr cont
|
| 283 | 284 | ppr (ApplyToTy { sc_arg_ty = ty, sc_cont = cont })
|
| ... | ... | @@ -474,7 +475,7 @@ contResultType (TickIt _ k) = contResultType k |
| 474 | 475 | contHoleType :: SimplCont -> OutType
|
| 475 | 476 | contHoleType (Stop ty _ _) = ty
|
| 476 | 477 | contHoleType (TickIt _ k) = contHoleType k
|
| 477 | -contHoleType (CastIt { sc_co = co }) = coercionLKind co
|
|
| 478 | +contHoleType (CastIt { sc_hole_ty = ty }) = ty
|
|
| 478 | 479 | contHoleType (StrictBind { sc_bndr = b, sc_dup = dup, sc_env = se })
|
| 479 | 480 | = perhapsSubstTy dup se (idType b)
|
| 480 | 481 | contHoleType (StrictArg { sc_fun_ty = ty }) = funArgTy ty
|
| ... | ... | @@ -1896,7 +1897,7 @@ rebuildLam env bndrs@(bndr:_) body cont |
| 1896 | 1897 | | -- Note [Casts and lambdas]
|
| 1897 | 1898 | seCastSwizzle env
|
| 1898 | 1899 | , not (any bad bndrs)
|
| 1899 | - = mkCast (mk_lams bndrs body) (mkPiCos Representational bndrs (castCoToCo (exprType body) co))
|
|
| 1900 | + = mkCastCo (mk_lams bndrs body) (mkPiCastCos Representational bndrs co)
|
|
| 1900 | 1901 | where
|
| 1901 | 1902 | co_vars = tyCoVarsOfCastCo co
|
| 1902 | 1903 | bad bndr = isCoVar bndr && bndr `elemVarSet` co_vars
|
| ... | ... | @@ -1120,7 +1120,7 @@ extendCaseBndrs env scrut case_bndr con alt_bndrs |
| 1120 | 1120 | where
|
| 1121 | 1121 | live_case_bndr = not (isDeadBinder case_bndr)
|
| 1122 | 1122 | env1 | DoBinderSwap v mco <- scrutOkForBinderSwap scrut
|
| 1123 | - , isReflMCo mco = extendValEnv env v cval
|
|
| 1123 | + , isReflCastCo mco = extendValEnv env v cval
|
|
| 1124 | 1124 | | otherwise = env -- See Note [Add scrutinee to ValueEnv too]
|
| 1125 | 1125 | env2 | live_case_bndr = extendValEnv env1 case_bndr cval
|
| 1126 | 1126 | | otherwise = env1
|
| ... | ... | @@ -52,13 +52,14 @@ import GHC.Core.FVs ( exprFreeVars, bindFreeVars |
| 52 | 52 | , rulesFreeVarsDSet, orphNamesOfExprs )
|
| 53 | 53 | import GHC.Core.Utils ( exprType, mkTick, mkTicks
|
| 54 | 54 | , stripTicksTopT, stripTicksTopE
|
| 55 | - , isJoinBind, mkCastMCo )
|
|
| 55 | + , isJoinBind, mkCastCo )
|
|
| 56 | 56 | import GHC.Core.Ppr ( pprRules )
|
| 57 | 57 | import GHC.Core.Unify as Unify ( ruleMatchTyKiX )
|
| 58 | 58 | import GHC.Core.Type as Type
|
| 59 | 59 | ( Type, extendTvSubst, extendCvSubst
|
| 60 | 60 | , substTy, getTyVar_maybe )
|
| 61 | 61 | import GHC.Core.TyCo.Ppr( pprParendType )
|
| 62 | +import GHC.Core.TyCo.FVs ( tyCoFVsOfCastCoercion )
|
|
| 62 | 63 | import GHC.Core.Coercion as Coercion
|
| 63 | 64 | import GHC.Core.Tidy ( tidyRules )
|
| 64 | 65 | import GHC.Core.Map.Expr ( eqCoreExpr )
|
| ... | ... | @@ -815,7 +816,7 @@ match_exprs :: HasDebugCallStack |
| 815 | 816 | match_exprs _ subst [] _
|
| 816 | 817 | = Just subst
|
| 817 | 818 | match_exprs renv subst (e1:es1) (e2:es2)
|
| 818 | - = do { subst' <- match renv subst e1 e2 MRefl
|
|
| 819 | + = do { subst' <- match renv subst e1 e2 ReflCastCo
|
|
| 819 | 820 | ; match_exprs renv subst' es1 es2 }
|
| 820 | 821 | match_exprs _ _ _ _ = Nothing
|
| 821 | 822 | |
| ... | ... | @@ -1065,7 +1066,7 @@ match :: HasDebugCallStack |
| 1065 | 1066 | -> RuleSubst -- Substitution applies to template only
|
| 1066 | 1067 | -> CoreExpr -- Template
|
| 1067 | 1068 | -> CoreExpr -- Target
|
| 1068 | - -> MCoercion
|
|
| 1069 | + -> CastCoercion
|
|
| 1069 | 1070 | -> Maybe RuleSubst
|
| 1070 | 1071 | |
| 1071 | 1072 | -- Postcondition (TypeInv): if matching succeeds, then
|
| ... | ... | @@ -1102,8 +1103,8 @@ match renv subst (Type ty1) (Type ty2) _mco |
| 1102 | 1103 | |
| 1103 | 1104 | ------------------------ Coercions ---------------------
|
| 1104 | 1105 | -- See Note [Coercion arguments] for why this isn't really right
|
| 1105 | -match renv subst (Coercion co1) (Coercion co2) MRefl
|
|
| 1106 | - = match_co renv subst co1 co2
|
|
| 1106 | +match renv subst (Coercion co1) (Coercion co2) ReflCastCo
|
|
| 1107 | + = match_co renv subst (CCoercion co1) (CCoercion co2) -- TODO should probably have match_cast_co and match_co separately?
|
|
| 1107 | 1108 | -- The MCo case corresponds to matching co ~ (co2 |> co3)
|
| 1108 | 1109 | -- and I have no idea what to do there -- or even if it can occur
|
| 1109 | 1110 | -- Failing seems the simplest thing to do; it's certainly safe.
|
| ... | ... | @@ -1114,23 +1115,23 @@ match renv subst (Coercion co1) (Coercion co2) MRefl |
| 1114 | 1115 | -- Note [Cancel reflexive casts]
|
| 1115 | 1116 | |
| 1116 | 1117 | match renv subst e1 (Cast e2 co2) mco
|
| 1117 | - = match renv subst e1 e2 (checkReflexiveMCo (mkTransMCoR (castCoToCo (exprType e2) co2) mco))
|
|
| 1118 | + = match renv subst e1 e2 (checkReflexiveCastCo (exprType e2) (mkTransCastCo co2 mco))
|
|
| 1118 | 1119 | -- checkReflexiveMCo: cancel casts if possible
|
| 1119 | 1120 | -- This is important: see Note [Cancel reflexive casts]
|
| 1120 | 1121 | |
| 1121 | 1122 | match renv subst (Cast e1 co1) e2 mco
|
| 1122 | - = matchTemplateCast renv subst e1 (castCoToCo (exprType e1) co1) e2 mco
|
|
| 1123 | + = matchTemplateCast renv subst e1 co1 e2 mco
|
|
| 1123 | 1124 | |
| 1124 | 1125 | ------------------------ Literals ---------------------
|
| 1125 | 1126 | match _ subst (Lit lit1) (Lit lit2) mco
|
| 1126 | 1127 | | lit1 == lit2
|
| 1127 | - = assertPpr (isReflMCo mco) (ppr mco) $
|
|
| 1128 | + = assertPpr (isReflCastCo mco) (ppr mco) $
|
|
| 1128 | 1129 | Just subst
|
| 1129 | 1130 | |
| 1130 | 1131 | ------------------------ Variables ---------------------
|
| 1131 | 1132 | -- The Var case follows closely what happens in GHC.Core.Unify.match
|
| 1132 | 1133 | match renv subst (Var v1) e2 mco
|
| 1133 | - = match_var renv subst v1 (mkCastMCo e2 mco)
|
|
| 1134 | + = match_var renv subst v1 (mkCastCo e2 mco)
|
|
| 1134 | 1135 | |
| 1135 | 1136 | match renv subst e1 (Var v2) mco -- Note [Expanding variables]
|
| 1136 | 1137 | | not (inRnEnvR rn_env v2) -- Note [Do not expand locally-bound variables]
|
| ... | ... | @@ -1148,7 +1149,7 @@ match renv subst e1 (Var v2) mco -- Note [Expanding variables] |
| 1148 | 1149 | -- See Note [Matching higher order patterns]
|
| 1149 | 1150 | match renv@(RV { rv_tmpls = tmpls, rv_lcl = rn_env })
|
| 1150 | 1151 | subst e1@App{} e2
|
| 1151 | - MRefl -- Like the App case we insist on Refl here
|
|
| 1152 | + ReflCastCo -- Like the App case we insist on Refl here
|
|
| 1152 | 1153 | -- See Note [Casts in the target]
|
| 1153 | 1154 | | (Var f, args) <- collectArgs e1
|
| 1154 | 1155 | , let f' = rnOccL rn_env f -- See similar rnOccL in match_var
|
| ... | ... | @@ -1308,9 +1309,9 @@ Two wrinkles: |
| 1308 | 1309 | -- (e1 e2) ~ (d1 d2) |> co
|
| 1309 | 1310 | -- See Note [Cancel reflexive casts]: in the Cast equations for 'match'
|
| 1310 | 1311 | -- we aggressively ensure that if MCo is reflective, it really is MRefl.
|
| 1311 | -match renv subst (App f1 a1) (App f2 a2) MRefl
|
|
| 1312 | - = do { subst' <- match renv subst f1 f2 MRefl
|
|
| 1313 | - ; match renv subst' a1 a2 MRefl }
|
|
| 1312 | +match renv subst (App f1 a1) (App f2 a2) ReflCastCo
|
|
| 1313 | + = do { subst' <- match renv subst f1 f2 ReflCastCo
|
|
| 1314 | + ; match renv subst' a1 a2 ReflCastCo }
|
|
| 1314 | 1315 | |
| 1315 | 1316 | ------------------------ Float lets ---------------------
|
| 1316 | 1317 | match renv subst e1 (Let bind e2) mco
|
| ... | ... | @@ -1336,7 +1337,7 @@ match renv subst e1 (Let bind e2) mco |
| 1336 | 1337 | |
| 1337 | 1338 | ------------------------ Lambdas ---------------------
|
| 1338 | 1339 | match renv subst (Lam x1 e1) e2 mco
|
| 1339 | - | let casted_e2 = mkCastMCo e2 mco
|
|
| 1340 | + | let casted_e2 = mkCastCo e2 mco
|
|
| 1340 | 1341 | in_scope = extendInScopeSetSet (rnInScopeSet (rv_lcl renv))
|
| 1341 | 1342 | (exprFreeVars casted_e2)
|
| 1342 | 1343 | in_scope_env = ISE in_scope (rv_unf renv)
|
| ... | ... | @@ -1349,7 +1350,7 @@ match renv subst (Lam x1 e1) e2 mco |
| 1349 | 1350 | -- See Note [Lambdas in the template]
|
| 1350 | 1351 | = let renv' = rnMatchBndr2 renv x1 x2
|
| 1351 | 1352 | subst' = subst { rs_binds = rs_binds subst . flip (foldr mkTick) ts }
|
| 1352 | - in match renv' subst' e1 e2' MRefl
|
|
| 1353 | + in match renv' subst' e1 e2' ReflCastCo
|
|
| 1353 | 1354 | |
| 1354 | 1355 | match renv subst e1 e2@(Lam {}) mco
|
| 1355 | 1356 | | Just (renv', e2') <- eta_reduce renv e2 -- See Note [Eta reduction in the target]
|
| ... | ... | @@ -1400,7 +1401,7 @@ match renv (tv_subst, id_subst, binds) e1 |
| 1400 | 1401 | |
| 1401 | 1402 | match renv subst (Case e1 x1 ty1 alts1) (Case e2 x2 ty2 alts2) mco
|
| 1402 | 1403 | = do { subst1 <- match_ty renv subst ty1 ty2
|
| 1403 | - ; subst2 <- match renv subst1 e1 e2 MRefl
|
|
| 1404 | + ; subst2 <- match renv subst1 e1 e2 ReflCastCo
|
|
| 1404 | 1405 | ; let renv' = rnMatchBndr2 renv x1 x2
|
| 1405 | 1406 | ; match_alts renv' subst2 alts1 alts2 mco -- Alts are both sorted
|
| 1406 | 1407 | }
|
| ... | ... | @@ -1503,29 +1504,29 @@ Hence |
| 1503 | 1504 | -------------
|
| 1504 | 1505 | matchTemplateCast
|
| 1505 | 1506 | :: RuleMatchEnv -> RuleSubst
|
| 1506 | - -> CoreExpr -> Coercion
|
|
| 1507 | - -> CoreExpr -> MCoercion
|
|
| 1507 | + -> CoreExpr -> CastCoercion
|
|
| 1508 | + -> CoreExpr -> CastCoercion
|
|
| 1508 | 1509 | -> Maybe RuleSubst
|
| 1509 | 1510 | matchTemplateCast renv subst e1 co1 e2 mco
|
| 1510 | 1511 | | isEmptyVarSet $ fvVarSet $
|
| 1511 | 1512 | filterFV (`elemVarSet` rv_tmpls renv) $ -- Check that the coercion does not
|
| 1512 | - tyCoFVsOfCo substed_co -- mention any of the template variables
|
|
| 1513 | + tyCoFVsOfCastCoercion substed_co -- mention any of the template variables
|
|
| 1513 | 1514 | = -- This is the good path
|
| 1514 | 1515 | -- See Note [Casts in the template] wrinkle (CT0)
|
| 1515 | - match renv subst e1 e2 (checkReflexiveMCo (mkTransMCoL mco (mkSymCo substed_co)))
|
|
| 1516 | + match renv subst e1 e2 (checkReflexiveCastCo substed_ty (mkTransCastCo mco (mkSymCastCo substed_ty substed_co)))
|
|
| 1517 | + -- AMG TODO: should be able to make checkReflexiveCastCo cheaper here?
|
|
| 1516 | 1518 | |
| 1517 | 1519 | | otherwise
|
| 1518 | 1520 | = -- This is the Deeply Suspicious Path
|
| 1519 | 1521 | -- See Note [Casts in the template]
|
| 1520 | - do { let co2 = case mco of
|
|
| 1521 | - MRefl -> mkRepReflCo (exprType e2)
|
|
| 1522 | - MCo co2 -> co2
|
|
| 1522 | + do { let co2 = mco
|
|
| 1523 | 1523 | ; subst1 <- match_co renv subst co1 co2
|
| 1524 | 1524 | -- If match_co succeeds, then (exprType e1) = (exprType e2)
|
| 1525 | - -- Hence the MRefl in the next line
|
|
| 1526 | - ; match renv subst1 e1 e2 MRefl }
|
|
| 1525 | + -- Hence the ReflCastCo in the next line
|
|
| 1526 | + ; match renv subst1 e1 e2 ReflCastCo }
|
|
| 1527 | 1527 | where
|
| 1528 | - substed_co = substCo current_subst co1
|
|
| 1528 | + substed_ty = substTy current_subst (exprType e1)
|
|
| 1529 | + substed_co = substCastCo current_subst co1
|
|
| 1529 | 1530 | |
| 1530 | 1531 | current_subst :: Subst
|
| 1531 | 1532 | current_subst = mkTCvSubst (rnInScopeSet (rv_lcl renv))
|
| ... | ... | @@ -1538,8 +1539,8 @@ matchTemplateCast renv subst e1 co1 e2 mco |
| 1538 | 1539 | |
| 1539 | 1540 | match_co :: RuleMatchEnv
|
| 1540 | 1541 | -> RuleSubst
|
| 1541 | - -> Coercion
|
|
| 1542 | - -> Coercion
|
|
| 1542 | + -> CastCoercion
|
|
| 1543 | + -> CastCoercion
|
|
| 1543 | 1544 | -> Maybe RuleSubst
|
| 1544 | 1545 | -- We only match if the template is a coercion variable or Refl:
|
| 1545 | 1546 | -- see Note [Casts in the template]
|
| ... | ... | @@ -1548,7 +1549,7 @@ match_co :: RuleMatchEnv |
| 1548 | 1549 | -- But if match_co succeeds, it /is/ guaranteed that
|
| 1549 | 1550 | -- coercionKind (subst template) = coercionKind target
|
| 1550 | 1551 | |
| 1551 | -match_co renv subst co1 co2
|
|
| 1552 | +match_co renv subst (CCoercion co1) (CCoercion co2)
|
|
| 1552 | 1553 | | Just cv <- getCoVar_maybe co1
|
| 1553 | 1554 | = match_var renv subst cv (Coercion co2)
|
| 1554 | 1555 | |
| ... | ... | @@ -1563,6 +1564,7 @@ match_co renv subst co1 co2 |
| 1563 | 1564 | |
| 1564 | 1565 | | otherwise
|
| 1565 | 1566 | = Nothing
|
| 1567 | +match_co renv subst _ _ = Nothing -- TODO: support non-CCoercions in rule matcher
|
|
| 1566 | 1568 | |
| 1567 | 1569 | -------------
|
| 1568 | 1570 | rnMatchBndr2 :: RuleMatchEnv -> Var -> Var -> RuleMatchEnv
|
| ... | ... | @@ -1575,7 +1577,7 @@ rnMatchBndr2 renv x1 x2 |
| 1575 | 1577 | match_alts :: RuleMatchEnv
|
| 1576 | 1578 | -> RuleSubst
|
| 1577 | 1579 | -> [CoreAlt] -- Template
|
| 1578 | - -> [CoreAlt] -> MCoercion -- Target
|
|
| 1580 | + -> [CoreAlt] -> CastCoercion -- Target
|
|
| 1579 | 1581 | -> Maybe RuleSubst
|
| 1580 | 1582 | match_alts _ subst [] [] _
|
| 1581 | 1583 | = return subst
|
| ... | ... | @@ -2018,7 +2020,7 @@ ruleAppCheck_help env fn args rules |
| 2018 | 2020 | mismatches = [i | (rule_arg, (arg,i)) <- rule_args `zip` i_args,
|
| 2019 | 2021 | not (isJust (match_fn rule_arg arg))]
|
| 2020 | 2022 | |
| 2021 | - match_fn rule_arg arg = match renv emptyRuleSubst rule_arg arg MRefl
|
|
| 2023 | + match_fn rule_arg arg = match renv emptyRuleSubst rule_arg arg ReflCastCo
|
|
| 2022 | 2024 | where
|
| 2023 | 2025 | renv = RV { rv_lcl = mkRnEnv2 in_scope
|
| 2024 | 2026 | , rv_tmpls = mkVarSet rule_bndrs
|
| ... | ... | @@ -31,8 +31,8 @@ import GHC.Core.Unfold.Make |
| 31 | 31 | import GHC.Core.Make ( FloatBind(..), mkWildValBinder )
|
| 32 | 32 | import GHC.Core.Opt.OccurAnal( occurAnalyseExpr, occurAnalysePgm, zapLambdaBndrs )
|
| 33 | 33 | import GHC.Core.DataCon
|
| 34 | -import GHC.Core.Coercion.Opt ( optCoercion, OptCoercionOpts (..) )
|
|
| 35 | -import GHC.Core.Type hiding ( substTy, extendTvSubst, extendCvSubst, extendTvSubstList
|
|
| 34 | +import GHC.Core.Coercion.Opt ( optCoercion, optCastCoercion, OptCoercionOpts (..) )
|
|
| 35 | +import GHC.Core.Type hiding ( extendTvSubst, extendCvSubst, extendTvSubstList
|
|
| 36 | 36 | , isInScope, substTyVarBndr, cloneTyVarBndr )
|
| 37 | 37 | import GHC.Core.Predicate( isCoVarType )
|
| 38 | 38 | import GHC.Core.Coercion hiding ( substCo, substCoVarBndr )
|
| ... | ... | @@ -213,7 +213,7 @@ simpleOptPgm opts this_mod binds rules = |
| 213 | 213 | ----------------------
|
| 214 | 214 | type SimpleClo = (SimpleOptEnv, InExpr)
|
| 215 | 215 | |
| 216 | -data SimpleContItem = ApplyToArg SimpleClo | CastIt OutCoercion
|
|
| 216 | +data SimpleContItem = ApplyToArg SimpleClo | CastIt OutCastCoercion
|
|
| 217 | 217 | |
| 218 | 218 | instance Outputable SimpleContItem where
|
| 219 | 219 | ppr (ApplyToArg (_, arg)) = text "ARG" <+> ppr arg
|
| ... | ... | @@ -402,7 +402,7 @@ simple_app env e0@(Lam {}) as0@(_:_) |
| 402 | 402 | = rebuild_app env (simple_opt_expr env e) as
|
| 403 | 403 | |
| 404 | 404 | do_beta env (Cast e co) as =
|
| 405 | - do_beta env e (add_cast env (castCoToCo (exprType e) co) as) -- TODO eliminate castCoToCo?
|
|
| 405 | + do_beta env e (add_cast env (exprType e) co as)
|
|
| 406 | 406 | |
| 407 | 407 | do_beta env body as
|
| 408 | 408 | = simple_app env body as
|
| ... | ... | @@ -450,21 +450,21 @@ simple_app env (Let bind body) args |
| 450 | 450 | expr' = Let bind' (simple_opt_expr env' body)
|
| 451 | 451 | |
| 452 | 452 | simple_app env (Cast e co) as
|
| 453 | - = simple_app env e (add_cast env (castCoToCo (exprType e) co) as) -- TODO eliminate castCoToCo?
|
|
| 453 | + = simple_app env e (add_cast env (exprType e) co as)
|
|
| 454 | 454 | |
| 455 | 455 | simple_app env e as
|
| 456 | 456 | = rebuild_app env (simple_opt_expr env e) as
|
| 457 | 457 | |
| 458 | -add_cast :: SimpleOptEnv -> InCoercion -> [SimpleContItem] -> [SimpleContItem]
|
|
| 459 | -add_cast env co1 as
|
|
| 460 | - | isReflCo co1'
|
|
| 458 | +add_cast :: SimpleOptEnv -> InType -> InCastCoercion -> [SimpleContItem] -> [SimpleContItem]
|
|
| 459 | +add_cast env tyL co1 as
|
|
| 460 | + | isReflCastCo co1'
|
|
| 461 | 461 | = as
|
| 462 | 462 | | otherwise
|
| 463 | 463 | = case as of
|
| 464 | - CastIt co2:rest -> CastIt (co1' `mkTransCo` co2):rest
|
|
| 464 | + CastIt co2:rest -> CastIt (co1' `mkTransCastCo` co2):rest
|
|
| 465 | 465 | _ -> CastIt co1':as
|
| 466 | 466 | where
|
| 467 | - co1' = optCoercion (so_co_opts (soe_opts env)) (soe_subst env) co1
|
|
| 467 | + co1' = optCastCoercion (so_co_opts (soe_opts env)) (soe_subst env) tyL co1
|
|
| 468 | 468 | |
| 469 | 469 | rebuild_app :: HasDebugCallStack
|
| 470 | 470 | => SimpleOptEnv -> OutExpr -> [SimpleContItem] -> OutExpr
|
| ... | ... | @@ -473,7 +473,7 @@ rebuild_app env fun args = foldl mk_app fun args |
| 473 | 473 | in_scope = soeInScope env
|
| 474 | 474 | mk_app out_fun = \case
|
| 475 | 475 | ApplyToArg arg -> App out_fun (simple_opt_clo in_scope arg)
|
| 476 | - CastIt co -> mk_cast out_fun (CCoercion co)
|
|
| 476 | + CastIt co -> mk_cast out_fun co
|
|
| 477 | 477 | |
| 478 | 478 | {- Note [Desugaring unlifted newtypes]
|
| 479 | 479 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -1340,7 +1340,7 @@ data-con wrappers, and that cure would be worse than the disease. |
| 1340 | 1340 | This Note exists solely to document the problem.
|
| 1341 | 1341 | -}
|
| 1342 | 1342 | |
| 1343 | -data ConCont = CC [CoreExpr] MCoercion
|
|
| 1343 | +data ConCont = CC [CoreExpr] CastCoercion
|
|
| 1344 | 1344 | -- Substitution already applied
|
| 1345 | 1345 | |
| 1346 | 1346 | -- | Returns @Just ([b1..bp], dc, [t1..tk], [x1..xn])@ if the argument
|
| ... | ... | @@ -1362,7 +1362,7 @@ exprIsConApp_maybe :: HasDebugCallStack |
| 1362 | 1362 | => InScopeEnv -> CoreExpr
|
| 1363 | 1363 | -> Maybe (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr])
|
| 1364 | 1364 | exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
|
| 1365 | - = go (Left in_scope) [] expr (CC [] MRefl)
|
|
| 1365 | + = go (Left in_scope) [] expr (CC [] ReflCastCo)
|
|
| 1366 | 1366 | where
|
| 1367 | 1367 | go :: Either InScopeSet Subst
|
| 1368 | 1368 | -- Left in-scope means "empty substitution"
|
| ... | ... | @@ -1375,10 +1375,10 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr |
| 1375 | 1375 | go subst floats (Tick t expr) cont
|
| 1376 | 1376 | | not (tickishIsCode t) = go subst floats expr cont
|
| 1377 | 1377 | |
| 1378 | - go subst floats (Cast expr co1) (CC args m_co2)
|
|
| 1379 | - | Just (args', m_co1') <- pushCoArgs (subst_co subst (castCoToCo (exprType expr) co1)) args
|
|
| 1378 | + go subst floats (Cast expr co1) (CC args m_co2) -- TODO: is the subst_ty below needed?
|
|
| 1379 | + | Just (args', m_co1') <- pushCoArgs (subst_ty subst (exprType expr)) (subst_cast_co subst co1) args
|
|
| 1380 | 1380 | -- See Note [Push coercions in exprIsConApp_maybe]
|
| 1381 | - = go subst floats expr (CC args' (m_co1' `mkTransMCo` m_co2))
|
|
| 1381 | + = go subst floats expr (CC args' (m_co1' `mkTransCastCo` m_co2))
|
|
| 1382 | 1382 | |
| 1383 | 1383 | go subst floats (App fun arg) (CC args mco)
|
| 1384 | 1384 | | let arg_type = exprType arg
|
| ... | ... | @@ -1515,6 +1515,12 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr |
| 1515 | 1515 | subst_co (Left {}) co = co
|
| 1516 | 1516 | subst_co (Right s) co = GHC.Core.Subst.substCo s co
|
| 1517 | 1517 | |
| 1518 | + subst_cast_co (Left {}) co = co
|
|
| 1519 | + subst_cast_co (Right s) co = substCastCo s co
|
|
| 1520 | + |
|
| 1521 | + subst_ty (Left {}) ty = ty
|
|
| 1522 | + subst_ty (Right s) ty = substTy s ty
|
|
| 1523 | + |
|
| 1518 | 1524 | subst_expr (Left {}) e = e
|
| 1519 | 1525 | subst_expr (Right s) e = substExpr s e
|
| 1520 | 1526 | |
| ... | ... | @@ -1565,7 +1571,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr |
| 1565 | 1571 | (right, _, _) -> pprPanic "case_bind did not preserve Left" (ppr in_scope $$ ppr arg $$ ppr right)
|
| 1566 | 1572 | |
| 1567 | 1573 | -- See Note [exprIsConApp_maybe on literal strings]
|
| 1568 | -dealWithStringLiteral :: Var -> BS.ByteString -> MCoercion
|
|
| 1574 | +dealWithStringLiteral :: Var -> BS.ByteString -> CastCoercion
|
|
| 1569 | 1575 | -> Maybe (DataCon, [Type], [CoreExpr])
|
| 1570 | 1576 | |
| 1571 | 1577 | -- This is not possible with user-supplied empty literals, GHC.Core.Make.mkStringExprFS
|
| ... | ... | @@ -1666,13 +1672,12 @@ exprIsLambda_maybe ise (Tick t e) |
| 1666 | 1672 | = Just (x, e, t:ts)
|
| 1667 | 1673 | |
| 1668 | 1674 | -- Also possible: A casted lambda. Push the coercion inside
|
| 1669 | -exprIsLambda_maybe ise@(ISE in_scope_set _) (Cast casted_e cco)
|
|
| 1675 | +exprIsLambda_maybe ise@(ISE in_scope_set _) (Cast casted_e co)
|
|
| 1670 | 1676 | | Just (x, e,ts) <- exprIsLambda_maybe ise casted_e
|
| 1671 | 1677 | -- Only do value lambdas.
|
| 1672 | 1678 | -- this implies that x is not in scope in gamma (makes this code simpler)
|
| 1673 | 1679 | , not (isTyVar x) && not (isCoVar x)
|
| 1674 | - , let co = castCoToCo (exprType casted_e) cco
|
|
| 1675 | - , assert (not $ x `elemVarSet` tyCoVarsOfCo co) True
|
|
| 1680 | + , assert (not $ x `elemVarSet` tyCoVarsOfCastCo co) True
|
|
| 1676 | 1681 | , Just (x',e') <- pushCoercionIntoLambda (mkEmptySubst in_scope_set) x e co
|
| 1677 | 1682 | , let res = Just (x',e',ts)
|
| 1678 | 1683 | = --pprTrace "exprIsLambda_maybe:Cast" (vcat [ppr casted_e,ppr co,ppr res)])
|
| ... | ... | @@ -21,7 +21,7 @@ module GHC.Core.TyCo.FVs |
| 21 | 21 | shallowCoVarsOfCo, shallowCoVarsOfCos, shallowCoVarsOfCastCo,
|
| 22 | 22 | tyCoVarsOfCastCoercionDSet,
|
| 23 | 23 | tyCoVarsOfCoDSet,
|
| 24 | - tyCoFVsOfCo, tyCoFVsOfCos, tyCoFVsOfCoVarSet,
|
|
| 24 | + tyCoFVsOfCo, tyCoFVsOfCos, tyCoFVsOfCoVarSet, tyCoFVsOfCastCoercion,
|
|
| 25 | 25 | tyCoVarsOfCoList,
|
| 26 | 26 | coVarsOfCoDSet, coVarsOfCosDSet,
|
| 27 | 27 |
| ... | ... | @@ -22,7 +22,7 @@ module GHC.Core.Utils ( |
| 22 | 22 | |
| 23 | 23 | -- * Properties of expressions
|
| 24 | 24 | exprType, coreAltType, coreAltsType,
|
| 25 | - mkLamType, mkLamTypes,
|
|
| 25 | + mkLamType, mkLamTypes, mkPiMCos,
|
|
| 26 | 26 | mkFunctionType,
|
| 27 | 27 | exprIsTrivial, getIdFromTrivialExpr, getIdFromTrivialExpr_maybe,
|
| 28 | 28 | trivial_expr_fold,
|
| ... | ... | @@ -188,6 +188,12 @@ mkLamType v body_ty |
| 188 | 188 | |
| 189 | 189 | mkLamTypes vs ty = foldr mkLamType ty vs
|
| 190 | 190 | |
| 191 | +mkPiMCos :: [Var] -> CastCoercion -> CastCoercion
|
|
| 192 | +mkPiMCos _ ReflCastCo = ReflCastCo
|
|
| 193 | +mkPiMCos vs (CCoercion co) = CCoercion (mkPiCos Representational vs co)
|
|
| 194 | +mkPiMCos vs (ZCoercion ty cos) = ZCoercion (mkLamTypes vs ty) cos
|
|
| 195 | + |
|
| 196 | + |
|
| 191 | 197 | {-
|
| 192 | 198 | Note [Type bindings]
|
| 193 | 199 | ~~~~~~~~~~~~~~~~~~~~
|