| ... |
... |
@@ -2246,13 +2246,13 @@ etaInfoApp in_scope expr eis |
|
2246
|
2246
|
-- Beta-reduction if possible, pushing any intervening casts past
|
|
2247
|
2247
|
-- the argument. See Note [The EtaInfo mechanism]
|
|
2248
|
2248
|
go subst (Lam v e) (EI (b:bs) mco)
|
|
2249
|
|
- | Just (arg,mco') <- pushCoArg (exprType (Lam v e)) mco (varToCoreExpr b)
|
|
|
2249
|
+ | Just (arg,_, mco') <- pushCoArg (exprType (Lam v e)) mco (varToCoreExpr b)
|
|
2250
|
2250
|
= go (Core.extendSubst subst v arg) e (EI bs mco')
|
|
2251
|
2251
|
|
|
2252
|
2252
|
-- Stop pushing down; just wrap the expression up
|
|
2253
|
2253
|
-- See Note [Check for reflexive casts in eta expansion]
|
|
2254
|
2254
|
go subst e (EI bs mco) = Core.substExprSC subst e
|
|
2255
|
|
- `mkCastCo` checkReflexiveCastCo (exprType e) mco -- TODO check type
|
|
|
2255
|
+ `mkCastCo` checkReflexiveCastCo (exprType e) mco
|
|
2256
|
2256
|
`mkVarApps` bs
|
|
2257
|
2257
|
|
|
2258
|
2258
|
--------------
|
| ... |
... |
@@ -2359,12 +2359,12 @@ mkEtaWW orig_oss ppr_orig_expr in_scope orig_ty |
|
2359
|
2359
|
-- with an explicit lambda having a non-function type
|
|
2360
|
2360
|
|
|
2361
|
2361
|
mkEtaForAllMCo :: ForAllTyBinder -> Type -> CastCoercion -> CastCoercion
|
|
2362
|
|
-mkEtaForAllMCo (Bndr tcv vis) ty mco
|
|
|
2362
|
+mkEtaForAllMCo bdnr@(Bndr tcv vis) ty mco
|
|
2363
|
2363
|
= case mco of
|
|
2364
|
2364
|
ReflCastCo | vis == coreTyLamForAllTyFlag -> ReflCastCo
|
|
2365
|
2365
|
| otherwise -> mk_fco (mkRepReflCo ty)
|
|
2366
|
2366
|
CCoercion co -> mk_fco co
|
|
2367
|
|
- ZCoercion _ty2 cos -> ZCoercion ty cos -- TODO: is ty right?
|
|
|
2367
|
+ ZCoercion tyR cos -> ZCoercion (mkForAllTy bdnr tyR) cos
|
|
2368
|
2368
|
where
|
|
2369
|
2369
|
mk_fco co = CCoercion (mkForAllCo tcv vis coreTyLamForAllTyFlag MRefl co)
|
|
2370
|
2370
|
-- coreTyLamForAllTyFlag: See Note [The EtaInfo mechanism], particularly
|
| ... |
... |
@@ -2871,17 +2871,17 @@ Here we implement the "push rules" from FC papers: |
|
2871
|
2871
|
by pushing the coercion into the arguments
|
|
2872
|
2872
|
-}
|
|
2873
|
2873
|
|
|
2874
|
|
-pushCoArgs :: Type -> CastCoercion -> [CoreArg] -> Maybe ([CoreArg], CastCoercion)
|
|
2875
|
|
-pushCoArgs _ co [] = return ([], co)
|
|
|
2874
|
+pushCoArgs :: Type -> CastCoercion -> [CoreArg] -> Maybe ([CoreArg], Type, CastCoercion)
|
|
|
2875
|
+pushCoArgs fun_ty co [] = return ([], fun_ty, co)
|
|
2876
|
2876
|
pushCoArgs fun_ty co (arg:args) = do
|
|
2877
|
|
- { (arg', m_co1) <- pushCoArg fun_ty co arg
|
|
|
2877
|
+ { (arg', ty, m_co1) <- pushCoArg fun_ty co arg
|
|
2878
|
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) }
|
|
|
2879
|
+ then return (arg':args, ty, ReflCastCo)
|
|
|
2880
|
+ else do { (args', ty', m_co2) <- pushCoArgs ty m_co1 args
|
|
|
2881
|
+ ; return (arg':args', ty', m_co2) }
|
|
2882
|
2882
|
}
|
|
2883
|
2883
|
|
|
2884
|
|
-pushCoArg :: Type -> CastCoercion -> CoreArg -> Maybe (CoreArg, CastCoercion)
|
|
|
2884
|
+pushCoArg :: Type -> CastCoercion -> CoreArg -> Maybe (CoreArg, Type, CastCoercion)
|
|
2885
|
2885
|
-- We have (fun |> co) arg, and we want to transform it to
|
|
2886
|
2886
|
-- (fun arg) |> co
|
|
2887
|
2887
|
-- This may fail, e.g. if (fun :: N) where N is a newtype
|
| ... |
... |
@@ -2889,22 +2889,22 @@ pushCoArg :: Type -> CastCoercion -> CoreArg -> Maybe (CoreArg, CastCoercion) |
|
2889
|
2889
|
-- 'co' is always Representational
|
|
2890
|
2890
|
pushCoArg fun_ty co arg
|
|
2891
|
2891
|
| Type ty <- arg
|
|
2892
|
|
- = do { (ty', m_co') <- pushCastCoTyArg co ty
|
|
2893
|
|
- ; return (Type ty', m_co') }
|
|
|
2892
|
+ = do { (ty', ty, m_co') <- pushCastCoTyArg co ty
|
|
|
2893
|
+ ; return (Type ty', ty, m_co') }
|
|
2894
|
2894
|
| otherwise
|
|
2895
|
|
- = do { (arg_mco, m_co') <- pushCastCoValArg fun_ty co
|
|
2896
|
|
- ; let arg_mco' = checkReflexiveCastCo (funArgTy fun_ty) arg_mco
|
|
|
2895
|
+ = do { (arg_ty, arg_mco, res_ty, m_co') <- pushCastCoValArg fun_ty co
|
|
|
2896
|
+ ; let arg_mco' = checkReflexiveCastCo arg_ty arg_mco
|
|
2897
|
2897
|
-- checkReflexiveCastCo: see Note [Check for reflexive casts in eta expansion]
|
|
2898
|
2898
|
-- The coercion is very often (arg_co -> res_co), but without
|
|
2899
|
2899
|
-- the argument coercion actually being ReflCo
|
|
2900
|
|
- ; return (arg `mkCastCo` arg_mco', m_co') }
|
|
|
2900
|
+ ; return (arg `mkCastCo` arg_mco', res_ty, m_co') }
|
|
2901
|
2901
|
|
|
2902
|
|
-pushCastCoTyArg :: CastCoercion -> Type -> Maybe (Type, CastCoercion)
|
|
|
2902
|
+pushCastCoTyArg :: CastCoercion -> Type -> Maybe (Type, Type, CastCoercion)
|
|
2903
|
2903
|
pushCastCoTyArg (CCoercion co) ty = pushCoTyArg co ty
|
|
2904
|
|
-pushCastCoTyArg ReflCastCo ty = Just (ty, ReflCastCo)
|
|
|
2904
|
+pushCastCoTyArg ReflCastCo ty = Just (ty, error "TODO: asdasdad", ReflCastCo)
|
|
2905
|
2905
|
pushCastCoTyArg (ZCoercion _fun_ty _cos) _ty = Nothing -- TODO do better
|
|
2906
|
2906
|
|
|
2907
|
|
-pushCoTyArg :: CoercionR -> Type -> Maybe (Type, CastCoercion)
|
|
|
2907
|
+pushCoTyArg :: CoercionR -> Type -> Maybe (Type, Type, CastCoercion)
|
|
2908
|
2908
|
-- We have (fun |> co) @ty
|
|
2909
|
2909
|
-- Push the coercion through to return
|
|
2910
|
2910
|
-- (fun @ty') |> co'
|
| ... |
... |
@@ -2916,11 +2916,11 @@ pushCoTyArg co ty |
|
2916
|
2916
|
-- -- = Just (ty, Nothing)
|
|
2917
|
2917
|
|
|
2918
|
2918
|
| isReflCo co
|
|
2919
|
|
- = Just (ty, ReflCastCo)
|
|
|
2919
|
+ = Just (ty, coercionLKind co2, ReflCastCo)
|
|
2920
|
2920
|
|
|
2921
|
2921
|
| isForAllTy_ty tyL
|
|
2922
|
2922
|
= assertPpr (isForAllTy_ty tyR) (ppr co $$ ppr ty) $
|
|
2923
|
|
- Just (ty `mkCastTy` co1, CCoercion co2)
|
|
|
2923
|
+ Just (ty `mkCastTy` co1, coercionLKind co2, CCoercion co2)
|
|
2924
|
2924
|
|
|
2925
|
2925
|
| otherwise
|
|
2926
|
2926
|
= Nothing
|
| ... |
... |
@@ -2940,14 +2940,14 @@ pushCoTyArg co ty |
|
2940
|
2940
|
-- co2 :: ty1[ (ty|>co1)/a1 ] ~R ty2[ ty/a2 ]
|
|
2941
|
2941
|
-- Arg of mkInstCo is always nominal, hence Nominal
|
|
2942
|
2942
|
|
|
2943
|
|
-pushCastCoValArg :: Type -> CastCoercion -> Maybe (CastCoercion, CastCoercion)
|
|
2944
|
|
-pushCastCoValArg _ ReflCastCo = Just (ReflCastCo, ReflCastCo)
|
|
|
2943
|
+pushCastCoValArg :: Type -> CastCoercion -> Maybe (Type, CastCoercion, Type, CastCoercion)
|
|
|
2944
|
+pushCastCoValArg tyL ReflCastCo = Just (funArgTy tyL, ReflCastCo, funResultTy tyL, ReflCastCo)
|
|
2945
|
2945
|
pushCastCoValArg _ (CCoercion co) = pushCoValArg co
|
|
2946
|
2946
|
pushCastCoValArg tyL (ZCoercion tyR cos)
|
|
2947
|
2947
|
| isFunTy tyL -- TODO: do we need to check this or can we assume it?
|
|
2948
|
2948
|
, isFunTy tyR
|
|
2949
|
2949
|
, typeHasFixedRuntimeRep new_arg_ty
|
|
2950
|
|
- = Just (ZCoercion new_arg_ty cos, ZCoercion (funResultTy tyR) cos)
|
|
|
2950
|
+ = Just (funArgTy tyL, ZCoercion new_arg_ty cos, funResultTy tyL, ZCoercion (funResultTy tyR) cos)
|
|
2951
|
2951
|
| otherwise = Nothing
|
|
2952
|
2952
|
where
|
|
2953
|
2953
|
new_arg_ty = funArgTy tyR
|
| ... |
... |
@@ -2963,7 +2963,7 @@ pushCastCoValArg tyL (ZCoercion tyR cos) |
|
2963
|
2963
|
-- If the LHS is well-typed, then so is the RHS. In particular, the argument
|
|
2964
|
2964
|
-- @arg |> co_arg@ is guaranteed to have a fixed 'RuntimeRep', in the sense of
|
|
2965
|
2965
|
-- Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete.
|
|
2966
|
|
-pushCoValArg :: CoercionR -> Maybe (CastCoercion, CastCoercion)
|
|
|
2966
|
+pushCoValArg :: CoercionR -> Maybe (Type, CastCoercion, Type, CastCoercion)
|
|
2967
|
2967
|
pushCoValArg co
|
|
2968
|
2968
|
-- The following is inefficient - don't do `eqType` here, the coercion
|
|
2969
|
2969
|
-- optimizer will take care of it. See #14737.
|
| ... |
... |
@@ -2971,7 +2971,7 @@ pushCoValArg co |
|
2971
|
2971
|
-- -- = Just (mkRepReflCo arg, Nothing)
|
|
2972
|
2972
|
|
|
2973
|
2973
|
| isReflCo co
|
|
2974
|
|
- = Just (ReflCastCo, ReflCastCo)
|
|
|
2974
|
+ = Just (old_arg_ty, ReflCastCo, funResultTy tyL, ReflCastCo)
|
|
2975
|
2975
|
|
|
2976
|
2976
|
| isFunTy tyL
|
|
2977
|
2977
|
, (_, co1, co2) <- decomposeFunCo co
|
| ... |
... |
@@ -2990,7 +2990,7 @@ pushCoValArg co |
|
2990
|
2990
|
(vcat [ text "co:" <+> ppr co
|
|
2991
|
2991
|
, text "old_arg_ty:" <+> ppr old_arg_ty
|
|
2992
|
2992
|
, text "new_arg_ty:" <+> ppr new_arg_ty ]) $
|
|
2993
|
|
- Just (coToCastCo (mkSymCo co1), coToCastCo co2)
|
|
|
2993
|
+ Just (old_arg_ty, coToCastCo (mkSymCo co1), funResultTy tyL, coToCastCo co2)
|
|
2994
|
2994
|
-- Critically, coToCastCo to checks for ReflCo; the whole coercion may not
|
|
2995
|
2995
|
-- be reflexive, but either of its components might be
|
|
2996
|
2996
|
-- We could use isReflexiveCo, but it's not clear if the benefit
|