Adam Gundry pushed to branch wip/amg/castz at Glasgow Haskell Compiler / GHC

Commits:

9 changed files:

Changes:

  • compiler/GHC/Core/Coercion.hs
    ... ... @@ -63,6 +63,10 @@ module GHC.Core.Coercion (
    63 63
             applyForAllTy,
    
    64 64
             decomposeFunCastCo,
    
    65 65
     
    
    66
    +        mkSymTypedCastCo,
    
    67
    +        mkTransTypedCastCo,
    
    68
    +        typedCastCoercionKind,
    
    69
    +
    
    66 70
             -- ** Decomposition
    
    67 71
             instNewTyCon_maybe,
    
    68 72
     
    
    ... ... @@ -97,7 +101,8 @@ module GHC.Core.Coercion (
    97 101
             -- ** Free variables
    
    98 102
             tyCoVarsOfCo, tyCoVarsOfCos, coVarsOfCo,
    
    99 103
             tyCoVarsOfCastCo,
    
    100
    -        coercionSize, castCoercionSize, anyFreeVarsOfCo,
    
    104
    +        coercionSize, castCoercionSize,
    
    105
    +        anyFreeVarsOfCo, anyFreeVarsOfCastCo,
    
    101 106
     
    
    102 107
             -- ** Substitution
    
    103 108
             CvSubstEnv, emptyCvSubstEnv,
    
    ... ... @@ -123,7 +128,7 @@ module GHC.Core.Coercion (
    123 128
             eqCoercion, eqCoercionX, eqCastCoercion, eqCastCoercionX,
    
    124 129
     
    
    125 130
             -- ** Forcing evaluation of coercions
    
    126
    -        seqCo, seqCos, seqCastCoercion,
    
    131
    +        seqCo, seqCos, seqCastCoercion, seqTypedCastCoercion,
    
    127 132
     
    
    128 133
             -- * Pretty-printing
    
    129 134
             pprCo, pprParendCo,
    
    ... ... @@ -852,15 +857,16 @@ mkFunCoNoFTF r w arg_co res_co
    852 857
         Pair argl_ty argr_ty = coercionKind arg_co
    
    853 858
         Pair resl_ty resr_ty = coercionKind res_co
    
    854 859
     
    
    855
    --- AMG TODO: more cases here, or maybe better to have a FunCo constructor of CastCoercion?
    
    856
    -mkFunCastCoNoFTF :: HasDebugCallStack => Role -> Mult -> Type -> CastCoercion -> Type -> CastCoercion -> CastCoercion
    
    857
    -mkFunCastCoNoFTF _ mult _ (ZCoercion arg_ty arg_cos) _ (ZCoercion res_ty res_cos) = ZCoercion (mkFunctionType mult arg_ty res_ty) (arg_cos `unionDVarSet` res_cos)
    
    858
    -mkFunCastCoNoFTF _ mult _ (ZCoercion arg_ty arg_cos) res_ty res_co = ZCoercion (mkFunctionType mult arg_ty (castCoercionRKind res_ty res_co)) (arg_cos `unionDVarSet` coVarsOfCastCoDSet res_co)
    
    859
    -mkFunCastCoNoFTF _ mult arg_ty arg_co _ (ZCoercion res_ty res_cos) = ZCoercion (mkFunctionType mult (castCoercionRKind arg_ty arg_co) res_ty) (res_cos `unionDVarSet` coVarsOfCastCoDSet arg_co)
    
    860
    -mkFunCastCoNoFTF r mult _ (CCoercion arg_co) _ (CCoercion res_co) = CCoercion (mkFunCoNoFTF r (multToCo mult) arg_co res_co)
    
    861
    -mkFunCastCoNoFTF _ _ _ ReflCastCo _ ReflCastCo = ReflCastCo
    
    862
    -mkFunCastCoNoFTF r mult _ (CCoercion arg_co) res_ty ReflCastCo = CCoercion (mkFunCoNoFTF r (multToCo mult) arg_co (mkReflCo r res_ty))
    
    863
    -mkFunCastCoNoFTF r mult arg_ty ReflCastCo _ (CCoercion res_co) = CCoercion (mkFunCoNoFTF r (multToCo mult) (mkReflCo r arg_ty) res_co)
    
    860
    +-- AMG TODO: maybe better to have a FunCo constructor of CastCoercion?
    
    861
    +mkFunCastCoNoFTF :: HasDebugCallStack => Role -> Mult -> TypedCastCoercion -> TypedCastCoercion -> CastCoercion
    
    862
    +mkFunCastCoNoFTF r mult (TCC arg_ty0 arg_co) (TCC res_ty0 res_co) =
    
    863
    +    case (arg_co, res_co) of
    
    864
    +      (ReflCastCo, ReflCastCo)             -> ReflCastCo
    
    865
    +      (ZCoercion arg_ty1 arg_cos, _)       -> ZCoercion (mkFunctionType mult arg_ty1 (castCoercionRKind res_ty0 res_co)) (arg_cos `unionDVarSet` coVarsOfCastCoDSet res_co)
    
    866
    +      (_, ZCoercion res_ty1 res_cos)       -> ZCoercion (mkFunctionType mult (castCoercionRKind arg_ty0 arg_co) res_ty1) (res_cos `unionDVarSet` coVarsOfCastCoDSet arg_co)
    
    867
    +      (CCoercion arg_co, CCoercion res_co) -> CCoercion (mkFunCoNoFTF r (multToCo mult) arg_co res_co)
    
    868
    +      (CCoercion arg_co, ReflCastCo)       -> CCoercion (mkFunCoNoFTF r (multToCo mult) arg_co (mkReflCo r res_ty0))
    
    869
    +      (ReflCastCo, CCoercion res_co)       -> CCoercion (mkFunCoNoFTF r (multToCo mult) (mkReflCo r arg_ty0) res_co)
    
    864 870
     
    
    865 871
     
    
    866 872
     -- | Build a function 'Coercion' from two other 'Coercion's. That is,
    
    ... ... @@ -990,8 +996,8 @@ mkForAllCo v visL visR kind_co co
    990 996
       = mk_forall_co v visL visR kind_co co
    
    991 997
     
    
    992 998
     mkForAllCastCo :: HasDebugCallStack => Role -> TyCoVar -> ForAllTyFlag -> ForAllTyFlag
    
    993
    -            -> Type -> CastCoercion -> CastCoercion
    
    994
    -mkForAllCastCo r v visL visR ty cco = case cco of
    
    999
    +            -> TypedCastCoercion -> CastCoercion
    
    1000
    +mkForAllCastCo r v visL visR (TCC ty cco) = case cco of
    
    995 1001
         CCoercion co -> CCoercion (mkForAllCo v visL visR MRefl co)
    
    996 1002
         ZCoercion ty cos -> ZCoercion (mkTyCoForAllTy v visR ty) cos
    
    997 1003
         ReflCastCo | visL `eqForAllVis` visR -> ReflCastCo
    
    ... ... @@ -1224,6 +1230,9 @@ mkSymCastCo _ (CCoercion co) = CCoercion (mkSymCo co)
    1224 1230
     mkSymCastCo ty (ZCoercion _ cos) = ZCoercion ty cos
    
    1225 1231
     mkSymCastCo _  ReflCastCo        = ReflCastCo
    
    1226 1232
     
    
    1233
    +mkSymTypedCastCo :: TypedCastCoercion -> TypedCastCoercion
    
    1234
    +mkSymTypedCastCo (TCC ty co) = TCC (castCoercionRKind ty co) (mkSymCastCo ty co)
    
    1235
    +
    
    1227 1236
     -- | mkTransCo creates a new 'Coercion' by composing the two
    
    1228 1237
     --   given 'Coercion's transitively: (co1 ; co2)
    
    1229 1238
     mkTransCo :: HasDebugCallStack => Coercion -> Coercion -> Coercion
    
    ... ... @@ -2529,6 +2538,9 @@ seqCastCoercion (CCoercion co) = seqCo co
    2529 2538
     seqCastCoercion (ZCoercion ty cos) = seqType ty `seq` seqDVarSet cos
    
    2530 2539
     seqCastCoercion ReflCastCo = ()
    
    2531 2540
     
    
    2541
    +seqTypedCastCoercion :: TypedCastCoercion -> ()
    
    2542
    +seqTypedCastCoercion (TCC ty co) = seqType ty `seq` seqCastCoercion co
    
    2543
    +
    
    2532 2544
     seqCo :: Coercion -> ()
    
    2533 2545
     seqCo (Refl ty)             = seqType ty
    
    2534 2546
     seqCo (GRefl r ty mco)      = r `seq` seqType ty `seq` seqMCo mco
    
    ... ... @@ -3022,3 +3034,10 @@ coToCastCo :: Coercion -> CastCoercion
    3022 3034
     --    See #19815 for a bit of data and discussion on this point
    
    3023 3035
     coToCastCo co | isReflCo co = ReflCastCo
    
    3024 3036
                   | otherwise   = CCoercion co
    
    3037
    +
    
    3038
    +
    
    3039
    +typedCastCoercionKind :: TypedCastCoercion -> Pair Type
    
    3040
    +typedCastCoercionKind (TCC tyL co) = Pair (castCoercionLKind tyL co) (castCoercionRKind tyL co)
    
    3041
    +
    
    3042
    +mkTransTypedCastCo :: TypedCastCoercion -> TypedCastCoercion -> TypedCastCoercion
    
    3043
    +mkTransTypedCastCo (TCC ty1 co1) (TCC _ co2) = TCC ty1 (mkTransCastCo co1 co2)

  • compiler/GHC/Core/Coercion/Opt.hs
    ... ... @@ -4,7 +4,7 @@
    4 4
     
    
    5 5
     module GHC.Core.Coercion.Opt
    
    6 6
        ( optCoercion, optTransCo
    
    7
    -   , optCastCoercion
    
    7
    +   , optCastCoercion, optTransCastCo
    
    8 8
        , OptCoercionOpts (..)
    
    9 9
        )
    
    10 10
     where
    
    ... ... @@ -178,6 +178,18 @@ optTransCo opts in_scope co1 co2
    178 178
       | otherwise
    
    179 179
       = co1 `mkTransCo` co2
    
    180 180
     
    
    181
    +optTransCastCo :: HasDebugCallStack => OptCoercionOpts -> InScopeSet
    
    182
    +           -> TypedCastCoercion -> TypedCastCoercion -> TypedCastCoercion
    
    183
    +optTransCastCo opts in_scope co1 co2
    
    184
    +  | optCoercionEnabled opts
    
    185
    +  = case (co1, co2) of
    
    186
    +      (TCC ty (CCoercion co1'), TCC _ (CCoercion co2')) -> TCC ty (CCoercion (opt_trans in_scope co1' co2'))
    
    187
    +      (co1, TCC _ ReflCastCo) -> co1
    
    188
    +      (TCC _ ReflCastCo, co2) -> co2
    
    189
    +      _ -> co1 `mkTransTypedCastCo` co2
    
    190
    +  | otherwise
    
    191
    +  = co1 `mkTransTypedCastCo` co2
    
    192
    +
    
    181 193
     -- AMG TODO: not clear if coercionLKind or substTy is better choice here
    
    182 194
     optCastCoercion :: OptCoercionOpts -> Subst -> TypedCastCoercion -> TypedCastCoercion
    
    183 195
     optCastCoercion _    env (TCC tyL ReflCastCo) = TCC (substTy env tyL) ReflCastCo
    

  • compiler/GHC/Core/Opt/Arity.hs
    ... ... @@ -2702,7 +2702,6 @@ tryEtaReduce rec_ids bndrs body eval_sd
    2702 2702
       where
    
    2703 2703
         incoming_arity = count isId bndrs -- See Note [Eta reduction makes sense], point (2)
    
    2704 2704
     
    
    2705
    -    -- AMG TOOD: make this pass TypedCastCoercion so we can call ok_arg more easily?
    
    2706 2705
         go :: [Var]            -- Binders, innermost first, types [a3,a2,a1]
    
    2707 2706
            -> CoreExpr         -- Of type tr
    
    2708 2707
            -> CastCoercion     -- Of type tr ~ ts
    
    ... ... @@ -2723,7 +2722,7 @@ tryEtaReduce rec_ids bndrs body eval_sd
    2723 2722
           -- Float app ticks: \x -> Tick t (e x) ==> Tick t e
    
    2724 2723
     
    
    2725 2724
         go (b : bs) (App fun arg) co
    
    2726
    -      | Just (co', ticks) <- ok_arg b arg co (exprType fun) (exprType (App fun arg))
    
    2725
    +      | Just (co', ticks) <- ok_arg b arg (TCC (exprType (App fun arg)) co) (exprType fun)
    
    2727 2726
           = fmap (flip (foldr mkTick) ticks) $ go bs fun co'
    
    2728 2727
                 -- Float arg ticks: \x -> e (Tick t x) ==> Tick t e
    
    2729 2728
     
    
    ... ... @@ -2795,19 +2794,18 @@ tryEtaReduce rec_ids bndrs body eval_sd
    2795 2794
         ---------------
    
    2796 2795
         ok_arg :: Var              -- Of type bndr_t
    
    2797 2796
                -> CoreExpr         -- Of type arg_t
    
    2798
    -           -> CastCoercion     -- Of kind (t1~t2)
    
    2797
    +           -> TypedCastCoercion-- Of kind (t1~t2)
    
    2799 2798
                -> Type             -- Type (arg_t -> t1) of the function
    
    2800 2799
                                    --      to which the argument is supplied
    
    2801
    -           -> Type             -- Type t1 of the result (AMG TODO: use TypedCastCoercion or avoid needing to pass this?)
    
    2802 2800
                -> Maybe (CastCoercion  -- Of type (arg_t -> t1 ~  bndr_t -> t2)
    
    2803 2801
                                    --   (and similarly for tyvars, coercion args)
    
    2804 2802
                         , [CoreTickish])
    
    2805 2803
         -- See Note [Eta reduction with casted arguments]
    
    2806
    -    ok_arg bndr (Type arg_ty) co fun_ty res_ty
    
    2804
    +    ok_arg bndr (Type arg_ty) co fun_ty
    
    2807 2805
            | Just tv <- getTyVar_maybe arg_ty
    
    2808 2806
            , bndr == tv  = case splitForAllForAllTyBinder_maybe fun_ty of
    
    2809 2807
                Just (Bndr _ vis, _) -> Just (fco, [])
    
    2810
    -             where !fco = mkForAllCastCo Representational tv vis coreTyLamForAllTyFlag res_ty co
    
    2808
    +             where !fco = mkForAllCastCo Representational tv vis coreTyLamForAllTyFlag co
    
    2811 2809
                        -- The lambda we are eta-reducing always has visibility
    
    2812 2810
                        -- 'coreTyLamForAllTyFlag' which may or may not match
    
    2813 2811
                        -- the visibility on the inner function (#24014)
    
    ... ... @@ -2815,24 +2813,25 @@ tryEtaReduce rec_ids bndrs body eval_sd
    2815 2813
                                    (text "fun:" <+> ppr bndr
    
    2816 2814
                                     $$ text "arg:" <+> ppr arg_ty
    
    2817 2815
                                     $$ text "fun_ty:" <+> ppr fun_ty)
    
    2818
    -    ok_arg bndr (Var v) co fun_ty _
    
    2816
    +    ok_arg bndr (Var v) (TCC _ co) fun_ty
    
    2819 2817
            | bndr == v
    
    2820 2818
            , let mult = idMult bndr
    
    2821 2819
            , Just (_af, fun_mult, _, _) <- splitFunTy_maybe fun_ty
    
    2822 2820
            , mult `eqType` fun_mult -- There is no change in multiplicity, otherwise we must abort
    
    2823 2821
            = Just (mkFunResCastCo Representational bndr co, [])
    
    2824
    -    ok_arg bndr (Cast e co_arg) co fun_ty _
    
    2822
    +    ok_arg bndr (Cast e co_arg) co fun_ty
    
    2825 2823
            | (ticks, Var v) <- stripTicksTop tickishFloatable e
    
    2826
    -       , Just (_, fun_mult, _, res_ty) <- splitFunTy_maybe fun_ty
    
    2824
    +       , Just (_, fun_mult, _, _) <- splitFunTy_maybe fun_ty
    
    2827 2825
            , bndr == v
    
    2828 2826
            , fun_mult `eqType` idMult bndr
    
    2829
    -       = Just (mkFunCastCoNoFTF Representational fun_mult (castCoercionRKind (exprType e) co_arg) (mkSymCastCo (exprType e) co_arg) res_ty co, ticks)
    
    2827
    +       , let co_arg' = TCC (exprType e) co_arg
    
    2828
    +       = Just (mkFunCastCoNoFTF Representational fun_mult (mkSymTypedCastCo co_arg') co, ticks)
    
    2830 2829
            -- The simplifier combines multiple casts into one,
    
    2831 2830
            -- so we can have a simple-minded pattern match here
    
    2832
    -    ok_arg bndr (Tick t arg) co fun_ty res_ty
    
    2833
    -       | tickishFloatable t, Just (co', ticks) <- ok_arg bndr arg co fun_ty res_ty
    
    2831
    +    ok_arg bndr (Tick t arg) co fun_ty
    
    2832
    +       | tickishFloatable t, Just (co', ticks) <- ok_arg bndr arg co fun_ty
    
    2834 2833
            = Just (co', t:ticks)
    
    2835
    -    ok_arg _ _ _ _ _ = Nothing
    
    2834
    +    ok_arg _ _ _ _ = Nothing
    
    2836 2835
     
    
    2837 2836
     
    
    2838 2837
     {- *********************************************************************
    
    ... ... @@ -3003,18 +3002,17 @@ pushCoValArg co
    3003 3002
         old_arg_ty = funArgTy tyR
    
    3004 3003
     
    
    3005 3004
     pushCoercionIntoLambda
    
    3006
    -    :: HasDebugCallStack => InScopeSet -> Var -> CoreExpr -> Type -> CastCoercion -> Maybe (Var, CoreExpr)
    
    3005
    +    :: HasDebugCallStack => InScopeSet -> Var -> CoreExpr -> TypedCastCoercion -> Maybe (Var, CoreExpr)
    
    3007 3006
     -- This implements the Push rule from the paper on coercions
    
    3008 3007
     --    (\x. e) |> co
    
    3009 3008
     -- ===>
    
    3010 3009
     --    (\x'. e |> co')
    
    3011
    -pushCoercionIntoLambda in_scope x e ty co
    
    3010
    +pushCoercionIntoLambda in_scope x e co
    
    3012 3011
         | assert (not (isTyVar x) && not (isCoVar x)) True
    
    3013
    -    , let s1s2 = castCoercionLKind ty co
    
    3014
    -    , let t1t2 = castCoercionRKind ty co
    
    3012
    +    , Pair s1s2 t1t2 <- typedCastCoercionKind co
    
    3015 3013
         , Just (_, _, s1, _)   <- splitFunTy_maybe s1s2
    
    3016 3014
         , Just (_, w1, t1,_t2) <- splitFunTy_maybe t1t2
    
    3017
    -    , (co1, co2)  <- decomposeFunCastCo co
    
    3015
    +    , (co1, co2)  <- decomposeFunCastCo (tccCastCoercion co)
    
    3018 3016
         , typeHasFixedRuntimeRep t1
    
    3019 3017
           -- We can't push the coercion into the lambda if it would create
    
    3020 3018
           -- a representation-polymorphic binder.
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -1412,6 +1412,19 @@ simplCoercion env co
    1412 1412
         opts  = seOptCoercionOpts env
    
    1413 1413
         subst_only = isEmptyTvSubst subst || reSimplifying env
    
    1414 1414
     
    
    1415
    +simplCastCoercion :: SimplEnv -> InTypedCastCoercion -> SimplM OutTypedCastCoercion
    
    1416
    +simplCastCoercion env co
    
    1417
    +  = seqTypedCastCoercion opt_co `seq` return opt_co
    
    1418
    +  where
    
    1419
    +    -- See Note [Optimising coercions]
    
    1420
    +    -- NB: substCo has a short-cut when both type and coercion substs are empty
    
    1421
    +    opt_co | subst_only = substTypedCastCo subst co
    
    1422
    +           | otherwise  = optCastCoercion opts subst co
    
    1423
    +
    
    1424
    +    subst = getTCvSubst env
    
    1425
    +    opts  = seOptCoercionOpts env
    
    1426
    +    subst_only = isEmptyTvSubst subst || reSimplifying env
    
    1427
    +
    
    1415 1428
     {- Note [Optimising coercions]
    
    1416 1429
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1417 1430
     Some programs have very big coercions and we'd like to avoid repeatedly
    
    ... ... @@ -1440,19 +1453,6 @@ re-optimising them:
    1440 1453
     
    
    1441 1454
     -}
    
    1442 1455
     
    
    1443
    -simplCastCoercion :: SimplEnv -> InTypedCastCoercion -> SimplM OutTypedCastCoercion
    
    1444
    -simplCastCoercion env co
    
    1445
    -  = do { let opt_co | reSimplifying env = substTypedCastCo subst co
    
    1446
    -                    | otherwise         = optCastCoercion opts subst co
    
    1447
    -             -- If (reSimplifying env) is True we have already simplified
    
    1448
    -             -- this coercion once, and we don't want do so again; doing
    
    1449
    -             -- so repeatedly risks non-linear behaviour
    
    1450
    -             -- See Note [Inline depth] in GHC.Core.Opt.Simplify.Env
    
    1451
    -       ; seqCastCoercion (tccCastCoercion opt_co) `seq` return opt_co }
    
    1452
    -  where
    
    1453
    -    subst = getTCvSubst env
    
    1454
    -    opts  = seOptCoercionOpts env
    
    1455
    -
    
    1456 1456
     
    
    1457 1457
     -----------------------------------
    
    1458 1458
     -- | Push a TickIt context outwards past applications and cases, as
    
    ... ... @@ -1861,7 +1861,7 @@ simplArg :: SimplEnvIS -- ^ Used only for its InScopeSet
    1861 1861
                                         --   continuation passed to 'simplExprC'
    
    1862 1862
              -> OutType                 -- ^ Type of the function applied to this arg
    
    1863 1863
              -> StaticEnv -> CoreExpr   -- ^ Expression with its static envt
    
    1864
    -         -> OutCastCoercion         -- Wrap this around the result
    
    1864
    +         -> OutCastCoercion         -- ^ Wrap this around the result
    
    1865 1865
              -> SimplM OutExpr
    
    1866 1866
     simplArg _ _ _ (Simplified {}) arg co
    
    1867 1867
       = return $ mkCastCo arg co -- See Note [Avoid repeated simplification]
    

  • compiler/GHC/Core/Rules.hs
    ... ... @@ -57,7 +57,6 @@ import GHC.Core.Unify as Unify ( ruleMatchTyKiX )
    57 57
     import GHC.Core.Type as Type
    
    58 58
        ( Type, extendTvSubst, extendCvSubst
    
    59 59
        , substTy, getTyVar_maybe )
    
    60
    -import GHC.Core.TyCo.FVs ( anyFreeVarsOfCastCo )
    
    61 60
     import GHC.Core.TyCo.Ppr( pprParendType )
    
    62 61
     import GHC.Core.Coercion as Coercion
    
    63 62
     import GHC.Core.Tidy     ( tidyRules )
    

  • compiler/GHC/Core/SimpleOpt.hs
    ... ... @@ -29,7 +29,7 @@ import GHC.Core.Unfold.Make
    29 29
     import GHC.Core.Make
    
    30 30
     import GHC.Core.Opt.OccurAnal( occurAnalyseExpr, occurAnalysePgm, zapLambdaBndrs )
    
    31 31
     import GHC.Core.DataCon
    
    32
    -import GHC.Core.Coercion.Opt ( optCoercion, optCastCoercion, OptCoercionOpts (..) )
    
    32
    +import GHC.Core.Coercion.Opt ( optCoercion, optCastCoercion, OptCoercionOpts (..), optTransCastCo )
    
    33 33
     import GHC.Core.Type hiding ( substTy, extendTvSubst, extendCvSubst, extendTvSubstList
    
    34 34
                                 , isInScope, substTyVarBndr, cloneTyVarBndr )
    
    35 35
     import GHC.Core.Predicate( isCoVarType )
    
    ... ... @@ -303,11 +303,11 @@ simpleOptPgm opts this_mod binds rules =
    303 303
     ----------------------
    
    304 304
     type SimpleClo = (SimpleOptEnv, InExpr)
    
    305 305
     
    
    306
    -data SimpleContItem = ApplyToArg SimpleClo | CastIt OutType OutCastCoercion
    
    306
    +data SimpleContItem = ApplyToArg SimpleClo | CastIt OutTypedCastCoercion
    
    307 307
     
    
    308 308
     instance Outputable SimpleContItem where
    
    309 309
       ppr (ApplyToArg (_, arg)) = text "ARG" <+> ppr arg
    
    310
    -  ppr (CastIt _ co) = text "CAST" <+> ppr co
    
    310
    +  ppr (CastIt co) = text "CAST" <+> ppr co
    
    311 311
     
    
    312 312
     data SimpleOptEnv
    
    313 313
       = SOE { soe_opts :: {-# UNPACK #-} !SimpleOpts
    
    ... ... @@ -473,7 +473,7 @@ simple_app env e0@(Lam {}) as0@(_:_)
    473 473
           where (env', b') = subst_opt_bndr env b
    
    474 474
     
    
    475 475
         -- See Note [Eliminate casts in function position]
    
    476
    -    do_beta env e@(Lam b _) as@(CastIt ty out_co:rest)
    
    476
    +    do_beta env e@(Lam b _) as@(CastIt out_co:rest)
    
    477 477
           | isNonCoVarId b
    
    478 478
           -- Optimise the inner lambda to make it an 'OutExpr', which makes it
    
    479 479
           -- possible to call 'pushCoercionIntoLambda' with the 'OutCoercion' 'co'.
    
    ... ... @@ -482,7 +482,7 @@ simple_app env e0@(Lam {}) as0@(_:_)
    482 482
           -- we need to do this to avoid mixing 'InExpr' and 'OutExpr', or two
    
    483 483
           -- 'InExpr' with different environments (getting this wrong caused #26588 & #26589.)
    
    484 484
           , Lam out_b out_body <- simple_app env e []
    
    485
    -      , Just (b', body') <- pushCoercionIntoLambda (soeInScope env) out_b out_body ty out_co
    
    485
    +      , Just (b', body') <- pushCoercionIntoLambda (soeInScope env) out_b out_body out_co
    
    486 486
           = do_beta (soeZapSubst env) (Lam b' body') rest
    
    487 487
             -- soeZapSubst: we've already optimised everything (the lambda and 'rest') by now.
    
    488 488
           | otherwise
    
    ... ... @@ -542,19 +542,18 @@ simple_app env (Cast e co) as
    542 542
     simple_app env e as
    
    543 543
       = rebuild_app env (simple_opt_expr env e) as
    
    544 544
     
    
    545
    --- FIXME (cast-zapping rebase): HEAD added optTransCo to further optimise the
    
    546
    --- combined coercion when stacking. There is no optTransCastCo yet, so for now
    
    547
    --- we use mkTransCastCo and leave the deeper optimisation as a TODO.
    
    548 545
     add_cast :: SimpleOptEnv -> InTypedCastCoercion -> [SimpleContItem] -> [SimpleContItem]
    
    549
    -add_cast env (TCC tyL co1) as
    
    550
    -  | isReflCastCo co1'
    
    546
    +add_cast env co1 as
    
    547
    +  | isReflCastCo (tccCastCoercion co1)
    
    551 548
       = as
    
    552 549
       | otherwise
    
    553 550
       = case as of
    
    554
    -      CastIt _ co2:rest -> CastIt ty (co1' `mkTransCastCo` co2):rest
    
    555
    -      _                 -> CastIt ty co1':as
    
    551
    +      CastIt co2:rest -> CastIt (optTransCastCo opts in_scope opt_co1 co2):rest
    
    552
    +      _               -> CastIt opt_co1:as
    
    556 553
       where
    
    557
    -    TCC ty co1' = optCastCoercion (so_co_opts (soe_opts env)) (soe_subst env) (TCC tyL co1)
    
    554
    +    opts     = so_co_opts (soe_opts env)
    
    555
    +    in_scope = soeInScope env
    
    556
    +    opt_co1  = optCastCoercion opts (soe_subst env) co1
    
    558 557
     
    
    559 558
     rebuild_app :: HasDebugCallStack
    
    560 559
                 => SimpleOptEnv -> OutExpr -> [SimpleContItem] -> OutExpr
    
    ... ... @@ -563,19 +562,19 @@ rebuild_app env fun args = foldl mk_app fun args
    563 562
         in_scope = soeInScope env
    
    564 563
         mk_app out_fun = \case
    
    565 564
           ApplyToArg arg -> App out_fun (simple_opt_clo in_scope arg)
    
    566
    -      CastIt _ co    -> mk_cast out_fun co
    
    565
    +      CastIt co      -> mk_cast out_fun co
    
    567 566
     
    
    568
    -mk_cast :: CoreExpr -> CastCoercion -> CoreExpr
    
    567
    +mk_cast :: CoreExpr -> TypedCastCoercion -> CoreExpr
    
    569 568
     -- Like GHC.Core.Utils.mkCast, but does a full reflexivity check.
    
    570 569
     -- mkCast doesn't do that because the Simplifier does (in simplCast)
    
    571 570
     -- But in SimpleOpt it's nice to kill those nested casts (#18112)
    
    572
    -mk_cast (Cast e co1) co2        = mk_cast e (co1 `mkTransCastCo` co2)
    
    573
    -mk_cast (Tick t e)   co         = Tick t (mk_cast e co)
    
    571
    +mk_cast (Cast e co1) (TCC _ co2) = mk_cast e (TCC (exprType e) (co1 `mkTransCastCo` co2))
    
    572
    +mk_cast (Tick t e)   co          = Tick t (mk_cast e co)
    
    574 573
     mk_cast e co
    
    575
    -  | isReflexiveCastCo (TCC (exprType e) co)
    
    574
    +  | isReflexiveCastCo co
    
    576 575
       = e
    
    577 576
       | otherwise
    
    578
    -  = Cast e co
    
    577
    +  = Cast e (tccCastCoercion co)
    
    579 578
     
    
    580 579
     {- Note [Desugaring unlifted newtypes]
    
    581 580
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -1853,7 +1852,7 @@ exprIsLambda_maybe ise@(ISE in_scope_set _) (Cast casted_e co)
    1853 1852
         -- this implies that x is not in scope in gamma (makes this code simpler)
    
    1854 1853
         , not (isTyVar x) && not (isCoVar x)
    
    1855 1854
         , assert (not $ x `elemVarSet` tyCoVarsOfCastCo co) True
    
    1856
    -    , Just (x',e') <- pushCoercionIntoLambda in_scope_set x e (exprType casted_e) co
    
    1855
    +    , Just (x',e') <- pushCoercionIntoLambda in_scope_set x e (TCC (exprType casted_e) co)
    
    1857 1856
         , let res = Just (x',e',ts)
    
    1858 1857
         = --pprTrace "exprIsLambda_maybe:Cast" (vcat [ppr casted_e,ppr co,ppr res)])
    
    1859 1858
           res
    

  • compiler/GHC/Core/TyCo/FVs.hs
    ... ... @@ -205,11 +205,6 @@ in GHC.Tc.Solver. Yuk. This is not pretty.
    205 205
     *                                                                      *
    
    206 206
     ********************************************************************* -}
    
    207 207
     
    
    208
    -tyCoVarsOfCastCo :: CastCoercion -> TyCoVarSet
    
    209
    -tyCoVarsOfCastCo (CCoercion co)     = coVarsOfCo co
    
    210
    -tyCoVarsOfCastCo (ZCoercion ty cos) = tyCoVarsOfType ty `unionVarSet` dVarSetToVarSet cos
    
    211
    -tyCoVarsOfCastCo ReflCastCo         = emptyVarSet
    
    212
    -
    
    213 208
     tyCoVarsOfType :: Type -> TyCoVarSet
    
    214 209
     -- The "deep" TyCoVars of the the type
    
    215 210
     tyCoVarsOfType ty = runTyCoVars (deepTypeFV ty)
    
    ... ... @@ -227,6 +222,9 @@ tyCoVarsOfCo :: Coercion -> TyCoVarSet
    227 222
     -- See Note [Computing deep free variables]
    
    228 223
     tyCoVarsOfCo co = runTyCoVars (deepCoFV co)
    
    229 224
     
    
    225
    +tyCoVarsOfCastCo :: CastCoercion -> TyCoVarSet
    
    226
    +tyCoVarsOfCastCo co = runTyCoVars (deepCastCoFV co)
    
    227
    +
    
    230 228
     tyCoVarsOfMCo :: MCoercion -> TyCoVarSet
    
    231 229
     tyCoVarsOfMCo MRefl    = emptyVarSet
    
    232 230
     tyCoVarsOfMCo (MCo co) = tyCoVarsOfCo co
    
    ... ... @@ -264,7 +262,8 @@ deepTypeFV :: Type -> TyCoFV
    264 262
     deepTypesFV :: [Type]     -> TyCoFV
    
    265 263
     deepCoFV    :: Coercion   -> TyCoFV
    
    266 264
     deepCosFV   :: [Coercion] -> TyCoFV
    
    267
    -(deepTypeFV, deepTypesFV, deepCoFV, deepCosFV, _) = foldTyCo deepTcvFolder
    
    265
    +deepCastCoFV :: CastCoercion -> TyCoFV
    
    266
    +(deepTypeFV, deepTypesFV, deepCoFV, deepCosFV, deepCastCoFV) = foldTyCo deepTcvFolder
    
    268 267
     
    
    269 268
     deepTcvFolder :: TyCoFolder TyCoFV
    
    270 269
     -- It's important that we use a one-shot EndoOS, to ensure that all
    
    ... ... @@ -908,10 +907,8 @@ anyFreeVarsOfCo check_fv co = DM.getAny (runFVTop (f co))
    908 907
       where (_, _, f, _, _) = foldTyCo (afvFolder check_fv)
    
    909 908
     
    
    910 909
     anyFreeVarsOfCastCo :: (TyCoVar -> Bool) -> CastCoercion -> Bool
    
    911
    -anyFreeVarsOfCastCo check_fv (CCoercion co) = anyFreeVarsOfCo check_fv co
    
    912
    -anyFreeVarsOfCastCo check_fv (ZCoercion ty cvs) =
    
    913
    -    anyFreeVarsOfType check_fv ty || anyDVarSet check_fv cvs
    
    914
    -anyFreeVarsOfCastCo _ ReflCastCo = False
    
    910
    +anyFreeVarsOfCastCo check_fv co = DM.getAny (runFVTop (f co))
    
    911
    +  where (_, _, _, _, f) = foldTyCo (afvFolder check_fv)
    
    915 912
     
    
    916 913
     noFreeVarsOfType :: Type -> Bool
    
    917 914
     noFreeVarsOfType ty = not $ DM.getAny (runFVTop (f ty))
    

  • compiler/GHC/Core/TyCo/Rep.hs
    ... ... @@ -1058,6 +1058,9 @@ instance Outputable Coercion where
    1058 1058
     instance Outputable CastCoercion where
    
    1059 1059
       ppr = pprCastCo
    
    1060 1060
     
    
    1061
    +instance Outputable TypedCastCoercion where
    
    1062
    +  ppr (TCC ty co) = text "TCC" <> parens (ppr ty <> text "," <+> ppr co)
    
    1063
    +
    
    1061 1064
     instance Outputable CoSel where
    
    1062 1065
       ppr (SelTyCon n r) = text "Tc" <> parens (int n <> comma <> pprOneCharRole r)
    
    1063 1066
       ppr SelForAll      = text "All"
    

  • compiler/GHC/Tc/Types/Evidence.hs
    ... ... @@ -636,7 +636,7 @@ optSubTypeHsWrapper wrap
    636 636
         not_in v (WpCompose w1 w2)         = not_in v w1 && not_in v w2
    
    637 637
         not_in v (WpEvApp (EvExpr e))      = not (v `elemVarSet` exprFreeVars e)
    
    638 638
         not_in v (WpEvApp (EvCastExpr e co ty)) = not (v `elemVarSet` exprFreeVars e)
    
    639
    -                                           && not_in_cast_co v co
    
    639
    +                                           && not (anyFreeVarsOfCastCo (== v) co)
    
    640 640
                                                && not (anyFreeVarsOfType (== v) ty)
    
    641 641
         not_in _ (WpEvApp (EvTypeable {})) = False  -- Giving up; conservative
    
    642 642
         not_in _ (WpEvApp (EvFun {}))      = False  -- Giving up; conservative
    
    ... ... @@ -644,13 +644,6 @@ optSubTypeHsWrapper wrap
    644 644
         not_in _ (WpEvLam {}) = False    -- Ditto
    
    645 645
         not_in _ (WpLet {})   = False    -- Ditto
    
    646 646
     
    
    647
    -    not_in_cast_co :: TyVar -> CastCoercion -> Bool
    
    648
    -    not_in_cast_co v = \case
    
    649
    -      CCoercion co     -> not (anyFreeVarsOfCo (== v) co)
    
    650
    -      ZCoercion ty cvs -> not (anyFreeVarsOfType (== v) ty)
    
    651
    -                       && not (v `elemDVarSet` cvs)
    
    652
    -      ReflCastCo       -> True
    
    653
    -
    
    654 647
         not_in_submult :: TyVar -> SubMultCo -> Bool
    
    655 648
         not_in_submult v = \case
    
    656 649
           EqMultCo co -> not (anyFreeVarsOfCo (== v) co)