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

Commits:

21 changed files:

Changes:

  • compiler/GHC/Core/Coercion.hs
    ... ... @@ -54,10 +54,7 @@ module GHC.Core.Coercion (
    54 54
     
    
    55 55
             -- ** Cast coercions
    
    56 56
             castCoToCo,
    
    57
    -        mkSymCastCo,
    
    58 57
             mkTransCastCo, mkTransCastCoCo, mkTransCoCastCo,
    
    59
    -        mkPisCastCo,
    
    60
    -        zapCo, zapCos, zapCastCo,
    
    61 58
     
    
    62 59
             -- ** Decomposition
    
    63 60
             instNewTyCon_maybe,
    
    ... ... @@ -76,7 +73,7 @@ module GHC.Core.Coercion (
    76 73
             pickLR,
    
    77 74
     
    
    78 75
             isGReflCo, isReflCo, isReflCo_maybe, isGReflCo_maybe, isReflexiveCo, isReflexiveCo_maybe,
    
    79
    -        isReflCastCo, isReflexiveCastCo,
    
    76
    +        isReflexiveCastCo,
    
    80 77
             isReflCoVar_maybe, isGReflMCo, mkGReflLeftMCo, mkGReflRightMCo,
    
    81 78
             mkCoherenceRightMCo,
    
    82 79
     
    
    ... ... @@ -2421,7 +2418,7 @@ seqMCo (MCo co) = seqCo co
    2421 2418
     
    
    2422 2419
     seqCastCoercion :: CastCoercion -> ()
    
    2423 2420
     seqCastCoercion (CCoercion co) = seqCo co
    
    2424
    -seqCastCoercion (ZCoercion ty cos) = seqType ty `seq` seqCos cos
    
    2421
    +seqCastCoercion (ZCoercion ty cos) = seqType ty `seq` seqVarSet cos
    
    2425 2422
     
    
    2426 2423
     seqCo :: Coercion -> ()
    
    2427 2424
     seqCo (Refl ty)             = seqType ty
    
    ... ... @@ -2858,54 +2855,23 @@ eqCastCoercionX env = eqTypeX env `on` castCoercionRKind
    2858 2855
     -- have discarded the original 'Coercion'.
    
    2859 2856
     castCoToCo :: Type -> CastCoercion -> CoercionR
    
    2860 2857
     castCoToCo _      (CCoercion co)         = co
    
    2861
    -castCoToCo lhs_ty (ZCoercion rhs_ty cos) = mkUnivCo ZCoercionProv cos Representational lhs_ty rhs_ty
    
    2862
    -
    
    2863
    -mkSymCastCo :: Type -> CastCoercion -> Coercion
    
    2864
    -mkSymCastCo lhs_ty cco = mkSymCo (castCoToCo lhs_ty cco)
    
    2858
    +castCoToCo lhs_ty (ZCoercion rhs_ty cos) = mkUnivCo ZCoercionProv (map CoVarCo (nonDetEltsUniqSet cos)) Representational lhs_ty rhs_ty
    
    2865 2859
     
    
    2866 2860
     -- | Compose two 'CastCoercion's transitively, like 'mkTransCo'.  If either is
    
    2867 2861
     -- zapped the whole result will be zapped.
    
    2868 2862
     mkTransCastCo :: HasDebugCallStack => CastCoercion -> CastCoercion -> CastCoercion
    
    2869 2863
     mkTransCastCo cco (CCoercion co)     = mkTransCastCoCo cco co
    
    2870
    -mkTransCastCo cco (ZCoercion ty cos) = ZCoercion ty (zapCastCo cco ++ cos)
    
    2864
    +mkTransCastCo cco (ZCoercion ty cos) = ZCoercion ty (shallowCoVarsOfCastCo cco `unionVarSet` cos)
    
    2871 2865
     
    
    2872 2866
     -- | Transitively compose a 'CastCoercion' followed by a 'Coercion'.
    
    2873 2867
     mkTransCastCoCo :: HasDebugCallStack => CastCoercion -> Coercion -> CastCoercion
    
    2874 2868
     mkTransCastCoCo (CCoercion co1)   co2 = CCoercion (mkTransCo co1 co2)
    
    2875
    -mkTransCastCoCo (ZCoercion _ cos) co2 = ZCoercion (coercionRKind co2) (zapCo co2 ++ cos)
    
    2869
    +mkTransCastCoCo (ZCoercion _ cos) co2 = ZCoercion (coercionRKind co2) (shallowCoVarsOfCo co2 `unionVarSet` cos)
    
    2876 2870
     
    
    2877 2871
     -- | Transitively compose a 'Coercion' followed by a 'CastCoercion'.
    
    2878 2872
     mkTransCoCastCo :: HasDebugCallStack => Coercion -> CastCoercion -> CastCoercion
    
    2879 2873
     mkTransCoCastCo co1 (CCoercion co2)    = CCoercion (mkTransCo co1 co2)
    
    2880
    -mkTransCoCastCo co1 (ZCoercion ty cos) = ZCoercion ty (zapCo co1 ++ cos)
    
    2881
    -
    
    2882
    --- TODO: Adapt this or rebuildLam to work for ZCoercion
    
    2883
    -mkPisCastCo :: Role -> [Var] -> Type -> CastCoercion -> CastCoercion
    
    2884
    -mkPisCastCo r vs expr_ty = CCoercion . mkPiCos r vs . castCoToCo expr_ty
    
    2885
    -
    
    2886
    -
    
    2887
    -zapCo :: Coercion -> [Coercion]
    
    2888
    -zapCo co = zapCos [co]
    
    2889
    -
    
    2890
    --- | Throw away the structure of coercions, retaining only the set of variables
    
    2891
    --- on which they depend.
    
    2892
    ---
    
    2893
    --- It is important we use only the *shallow* free CoVars here, because those are
    
    2894
    --- the ones on which the original coercions necessarily depended and which may
    
    2895
    --- be substituted away later. If we use the deep CoVars here, we can end up
    
    2896
    --- retaining references to CoVars that are no longer in scope (see Note [Shallow
    
    2897
    --- and deep free variables] in GHC.Core.TyCo.FVs).
    
    2898
    -zapCos :: [Coercion] -> [Coercion]
    
    2899
    -zapCos cos = map mkCoVarCo $ nonDetEltsUniqSet (shallowCoVarsOfCos cos) -- TODO nonDetEltsUniqSet justified?
    
    2900
    -
    
    2901
    -zapCastCo :: CastCoercion -> [Coercion]
    
    2902
    -zapCastCo (CCoercion co)    = zapCo co
    
    2903
    -zapCastCo (ZCoercion _ cos) = cos
    
    2904
    -
    
    2905
    -
    
    2906
    -isReflCastCo :: CastCoercion -> Bool
    
    2907
    -isReflCastCo (CCoercion co) = isReflCo co
    
    2908
    -isReflCastCo (ZCoercion _ _) = False -- TODO: track this?
    
    2874
    +mkTransCoCastCo co1 (ZCoercion ty cos) = ZCoercion ty (shallowCoVarsOfCo co1 `unionVarSet` cos)
    
    2909 2875
     
    
    2910 2876
     -- | Slowly checks if the coercion is reflexive. Don't call this in a loop,
    
    2911 2877
     -- as it walks over the entire coercion.
    

  • compiler/GHC/Core/FVs.hs
    ... ... @@ -279,7 +279,7 @@ expr_fvs (Let (Rec pairs) body) fv_cand in_scope acc
    279 279
     
    
    280 280
     cast_co_fvs :: CastCoercion -> FV
    
    281 281
     cast_co_fvs (CCoercion co)     fv_cand in_scope acc = (tyCoFVsOfCo co) fv_cand in_scope acc
    
    282
    -cast_co_fvs (ZCoercion ty cos) fv_cand in_scope acc = (tyCoFVsOfType ty `unionFV` mapUnionFV tyCoFVsOfCo cos) fv_cand in_scope acc
    
    282
    +cast_co_fvs (ZCoercion ty cos) fv_cand in_scope acc = (tyCoFVsOfType ty `unionFV` tyCoFVsOfCoVarSet cos) fv_cand in_scope acc
    
    283 283
     
    
    284 284
     ---------
    
    285 285
     rhs_fvs :: (Id, CoreExpr) -> FV
    

  • compiler/GHC/Core/Opt/Arity.hs
    ... ... @@ -2221,9 +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 (CCoercion co)) (EI bs mco) -- TODO: etaInfoApp ZCoercion
    
    2224
    +    go subst (Cast e cco) (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?
    
    2227 2228
             mco' = checkReflexiveMCo (Core.substCo subst co `mkTransMCoR` mco)
    
    2228 2229
                    -- See Note [Check for reflexive casts in eta expansion]
    
    2229 2230
     
    
    ... ... @@ -2701,13 +2702,13 @@ same fix.
    2701 2702
     tryEtaReduce :: UnVarSet -> [Var] -> CoreExpr -> SubDemand -> Maybe CoreExpr
    
    2702 2703
     -- Return an expression equal to (\bndrs. body)
    
    2703 2704
     tryEtaReduce rec_ids bndrs body eval_sd
    
    2704
    -  = go (reverse bndrs) body (CCoercion (mkRepReflCo (exprType body)))
    
    2705
    +  = go (reverse bndrs) body (mkRepReflCo (exprType body))
    
    2705 2706
       where
    
    2706 2707
         incoming_arity = count isId bndrs -- See Note [Eta reduction makes sense], point (2)
    
    2707 2708
     
    
    2708 2709
         go :: [Var]            -- Binders, innermost first, types [a3,a2,a1]
    
    2709 2710
            -> CoreExpr         -- Of type tr
    
    2710
    -       -> CastCoercion     -- Of type tr ~ ts
    
    2711
    +       -> Coercion         -- Of type tr ~ ts
    
    2711 2712
            -> Maybe CoreExpr   -- Of type a1 -> a2 -> a3 -> ts
    
    2712 2713
         -- See Note [Eta reduction with casted arguments]
    
    2713 2714
         -- for why we have an accumulating coercion
    
    ... ... @@ -2717,7 +2718,7 @@ tryEtaReduce rec_ids bndrs body eval_sd
    2717 2718
     
    
    2718 2719
         -- See Note [Eta reduction with casted function]
    
    2719 2720
         go bs (Cast e co1) co2
    
    2720
    -      = go bs e (co1 `mkTransCastCo` co2)
    
    2721
    +      = go bs e (castCoToCo (exprType e) co1 `mkTransCo` co2)
    
    2721 2722
     
    
    2722 2723
         go bs (Tick t e) co
    
    2723 2724
           | tickishFloatable t
    
    ... ... @@ -2740,7 +2741,7 @@ tryEtaReduce rec_ids bndrs body eval_sd
    2740 2741
           , remaining_bndrs `ltLength` bndrs
    
    2741 2742
                 -- Only reply Just if /something/ has happened
    
    2742 2743
           , ok_fun fun
    
    2743
    -      , let used_vars     = exprFreeVars fun `unionVarSet` tyCoVarsOfCastCo co
    
    2744
    +      , let used_vars     = exprFreeVars fun `unionVarSet` tyCoVarsOfCo co
    
    2744 2745
                 reduced_bndrs = mkVarSet (dropList remaining_bndrs bndrs)
    
    2745 2746
                 -- reduced_bndrs are the ones we are eta-reducing away
    
    2746 2747
           , used_vars `disjointVarSet` reduced_bndrs
    
    ... ... @@ -2749,7 +2750,7 @@ tryEtaReduce rec_ids bndrs body eval_sd
    2749 2750
               -- See Note [Eta reduction makes sense], intro and point (1)
    
    2750 2751
               -- NB: don't compute used_vars from exprFreeVars (mkCast fun co)
    
    2751 2752
               --     because the latter may be ill formed if the guard fails (#21801)
    
    2752
    -      = Just (mkLams (reverse remaining_bndrs) (mkCastCo fun co))
    
    2753
    +      = Just (mkLams (reverse remaining_bndrs) (mkCast fun co))
    
    2753 2754
     
    
    2754 2755
         go _remaining_bndrs _fun  _  = -- pprTrace "tER fail" (ppr _fun $$ ppr _remaining_bndrs) $
    
    2755 2756
                                        Nothing
    
    ... ... @@ -2797,17 +2798,17 @@ tryEtaReduce rec_ids bndrs body eval_sd
    2797 2798
         ---------------
    
    2798 2799
         ok_arg :: Var              -- Of type bndr_t
    
    2799 2800
                -> CoreExpr         -- Of type arg_t
    
    2800
    -           -> CastCoercion     -- Of kind (t1~t2)
    
    2801
    +           -> Coercion         -- Of kind (t1~t2)
    
    2801 2802
                -> Type             -- Type (arg_t -> t1) of the function
    
    2802 2803
                                    --      to which the argument is supplied
    
    2803
    -           -> Maybe (CastCoercion  -- Of type (arg_t -> t1 ~  bndr_t -> t2)
    
    2804
    -                                   --   (and similarly for tyvars, coercion args)
    
    2804
    +           -> Maybe (Coercion  -- Of type (arg_t -> t1 ~  bndr_t -> t2)
    
    2805
    +                               --   (and similarly for tyvars, coercion args)
    
    2805 2806
                         , [CoreTickish])
    
    2806 2807
         -- See Note [Eta reduction with casted arguments]
    
    2807
    -    ok_arg bndr (Type arg_ty) (CCoercion co) fun_ty
    
    2808
    +    ok_arg bndr (Type arg_ty) co fun_ty
    
    2808 2809
            | Just tv <- getTyVar_maybe arg_ty
    
    2809 2810
            , bndr == tv  = case splitForAllForAllTyBinder_maybe fun_ty of
    
    2810
    -           Just (Bndr _ vis, _) -> Just (CCoercion fco, [])
    
    2811
    +           Just (Bndr _ vis, _) -> Just (fco, [])
    
    2811 2812
                  where !fco = mkForAllCo tv vis coreTyLamForAllTyFlag kco co
    
    2812 2813
                        -- The lambda we are eta-reducing always has visibility
    
    2813 2814
                        -- 'coreTyLamForAllTyFlag' which may or may not match
    
    ... ... @@ -2817,24 +2818,23 @@ tryEtaReduce rec_ids bndrs body eval_sd
    2817 2818
                                    (text "fun:" <+> ppr bndr
    
    2818 2819
                                     $$ text "arg:" <+> ppr arg_ty
    
    2819 2820
                                     $$ text "fun_ty:" <+> ppr fun_ty)
    
    2820
    -    ok_arg bndr (Var v) (CCoercion co) fun_ty
    
    2821
    +    ok_arg bndr (Var v) co fun_ty
    
    2821 2822
            | bndr == v
    
    2822 2823
            , let mult = idMult bndr
    
    2823 2824
            , Just (_af, fun_mult, _, _) <- splitFunTy_maybe fun_ty
    
    2824 2825
            , mult `eqType` fun_mult -- There is no change in multiplicity, otherwise we must abort
    
    2825
    -       = Just (CCoercion $ mkFunResCo Representational bndr co, [])
    
    2826
    -    ok_arg bndr (Cast e co_arg) (CCoercion co) fun_ty
    
    2826
    +       = Just (mkFunResCo Representational bndr co, [])
    
    2827
    +    ok_arg bndr (Cast e co_arg) co fun_ty
    
    2827 2828
            | (ticks, Var v) <- stripTicksTop tickishFloatable e
    
    2828 2829
            , Just (_, fun_mult, _, _) <- splitFunTy_maybe fun_ty
    
    2829 2830
            , bndr == v
    
    2830 2831
            , fun_mult `eqType` idMult bndr
    
    2831
    -       = Just (CCoercion $ mkFunCoNoFTF Representational (multToCo fun_mult) (mkSymCastCo (exprType e) co_arg) co, ticks)
    
    2832
    +       = Just (mkFunCoNoFTF Representational (multToCo fun_mult) (mkSymCo (castCoToCo (exprType e) co_arg)) co, ticks)
    
    2832 2833
            -- The simplifier combines multiple casts into one,
    
    2833 2834
            -- so we can have a simple-minded pattern match here
    
    2834 2835
         ok_arg bndr (Tick t arg) co fun_ty
    
    2835 2836
            | tickishFloatable t, Just (co', ticks) <- ok_arg bndr arg co fun_ty
    
    2836 2837
            = Just (co', t:ticks)
    
    2837
    -    -- TODO ok_arg for ZCoercion?
    
    2838 2838
         ok_arg _ _ _ _ = Nothing
    
    2839 2839
     
    
    2840 2840
     -- | Can we eta-reduce the given function
    
    ... ... @@ -3107,13 +3107,13 @@ collectBindersPushingCo e
    3107 3107
         go :: [Var] -> CoreExpr -> ([Var], CoreExpr)
    
    3108 3108
         -- The accumulator is in reverse order
    
    3109 3109
         go bs (Lam b e)   = go (b:bs) e
    
    3110
    -    go bs (Cast e (CCoercion co)) = go_c bs e co  -- TODO: ought to have ZCoercion case or go_c generalised
    
    3110
    +    go bs (Cast e co) = go_c bs e (castCoToCo (exprType e) co) -- TODO: can we do better?
    
    3111 3111
         go bs e           = (reverse bs, e)
    
    3112 3112
     
    
    3113 3113
         -- We are in a cast; peel off casts until we hit a lambda.
    
    3114 3114
         go_c :: [Var] -> CoreExpr -> Coercion -> ([Var], CoreExpr)
    
    3115 3115
         -- (go_c bs e c) is same as (go bs e (e |> c))
    
    3116
    -    go_c bs (Cast e (CCoercion co1)) co2 = go_c bs e (co1 `mkTransCo` co2) -- TODO ditto
    
    3116
    +    go_c bs (Cast e co1) co2 = go_c bs e (castCoToCo (exprType e) co1 `mkTransCo` co2) -- TODO: can we do better?
    
    3117 3117
         go_c bs (Lam b e)    co  = go_lam bs b e co
    
    3118 3118
         go_c bs e            co  = (reverse bs, mkCast e co)
    
    3119 3119
     
    

  • compiler/GHC/Core/Opt/DmdAnal.hs
    ... ... @@ -2405,13 +2405,17 @@ coercionDmdEnv co = coercionsDmdEnv [co]
    2405 2405
     
    
    2406 2406
     castCoercionDmdEnv :: CastCoercion -> DmdEnv
    
    2407 2407
     castCoercionDmdEnv (CCoercion co)    = coercionDmdEnv co
    
    2408
    -castCoercionDmdEnv (ZCoercion _ cos) = coercionsDmdEnv cos
    
    2408
    +castCoercionDmdEnv (ZCoercion _ cos) = coVarSetDmdEnv cos
    
    2409 2409
     
    
    2410 2410
     coercionsDmdEnv :: [Coercion] -> DmdEnv
    
    2411 2411
     coercionsDmdEnv cos
    
    2412 2412
       = mkTermDmdEnv $ mapVarEnv (const topDmd) $ getUniqSet $ coVarsOfCos cos
    
    2413 2413
       -- The VarSet from coVarsOfCos is really a VarEnv Var
    
    2414 2414
     
    
    2415
    +coVarSetDmdEnv :: CoVarSet -> DmdEnv
    
    2416
    +coVarSetDmdEnv cos
    
    2417
    +  = mkTermDmdEnv $ mapVarEnv (const topDmd) $ getUniqSet cos -- TODO shallow/deep confusion?
    
    2418
    +
    
    2415 2419
     addVarDmd :: DmdType -> Var -> Demand -> DmdType
    
    2416 2420
     addVarDmd (DmdType fv ds) var dmd
    
    2417 2421
       = DmdType (addVarDmdEnv fv var dmd) ds
    

  • compiler/GHC/Core/Opt/OccurAnal.hs
    ... ... @@ -3435,8 +3435,8 @@ scrutOkForBinderSwap :: OutExpr -> BinderSwapDecision
    3435 3435
     -- We use this same function in SpecConstr, and Simplify.Iteration,
    
    3436 3436
     -- when something binder-swap-like is happening
    
    3437 3437
     scrutOkForBinderSwap (Var v)    = DoBinderSwap v MRefl
    
    3438
    -scrutOkForBinderSwap (Cast (Var v) (CCoercion co)) -- TODO scrutOkForBinderSwap for ZCoercion
    
    3439
    -  | not (isDictId v)             = DoBinderSwap v (MCo (mkSymCo co))
    
    3438
    +scrutOkForBinderSwap (Cast (Var v) co)
    
    3439
    +  | not (isDictId v)             = DoBinderSwap v (MCo (mkSymCo (castCoToCo (idType v) co))) -- TODO: can we do better?
    
    3440 3440
             -- Cast: see Note [Case of cast]
    
    3441 3441
             -- isDictId: see Note [Care with binder-swap on dictionaries]
    
    3442 3442
             -- The isDictId rejects a Constraint/Constraint binder-swap, perhaps
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -644,7 +644,7 @@ tryCastWorkerWrapper env bind_cxt old_bndr bndr (Cast rhs co)
    644 644
         mk_worker_unfolding top_lvl work_id work_rhs
    
    645 645
           = case realUnfoldingInfo info of -- NB: the real one, even for loop-breakers
    
    646 646
                unf@(CoreUnfolding { uf_tmpl = unf_rhs, uf_src = src })
    
    647
    -             | isStableSource src -> return (unf { uf_tmpl = mkCast unf_rhs (mkSymCastCo (exprType rhs) co) })
    
    647
    +             | isStableSource src -> return (unf { uf_tmpl = mkCast unf_rhs (mkSymCo (castCoToCo (exprType rhs) co)) })
    
    648 648
                _ -> mkLetUnfolding env top_lvl VanillaSrc work_id False work_rhs
    
    649 649
     
    
    650 650
     tryCastWorkerWrapper env _ _ bndr rhs  -- All other bindings
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -1836,7 +1836,7 @@ rebuildLam env bndrs@(bndr:_) body cont
    1836 1836
           | -- Note [Casts and lambdas]
    
    1837 1837
             seCastSwizzle env
    
    1838 1838
           , not (any bad bndrs)
    
    1839
    -      = mkCastCo (mk_lams bndrs body) (mkPisCastCo Representational bndrs (exprType body) co)
    
    1839
    +      = mkCast (mk_lams bndrs body) (mkPiCos Representational bndrs (castCoToCo (exprType body) co))
    
    1840 1840
           where
    
    1841 1841
             co_vars  = tyCoVarsOfCastCo co
    
    1842 1842
             bad bndr = isCoVar bndr && bndr `elemVarSet` co_vars
    

  • compiler/GHC/Core/Ppr.hs
    ... ... @@ -35,6 +35,7 @@ import GHC.Types.Fixity (LexicalFixity(..))
    35 35
     import GHC.Types.Literal( pprLiteral )
    
    36 36
     import GHC.Types.Name( pprInfixName, pprPrefixName )
    
    37 37
     import GHC.Types.Var
    
    38
    +import GHC.Types.Var.Set
    
    38 39
     import GHC.Types.Id
    
    39 40
     import GHC.Types.Id.Info
    
    40 41
     import GHC.Types.Demand
    
    ... ... @@ -171,10 +172,12 @@ noParens pp = pp
    171 172
     
    
    172 173
     pprOptCastCoercion :: CastCoercion -> SDoc
    
    173 174
     pprOptCastCoercion (CCoercion co) = pprOptCo co
    
    174
    -pprOptCastCoercion (ZCoercion ty cos) = -- TODO review ppr format
    
    175
    -    sdocOption sdocSuppressCoercions $ \case
    
    176
    -              True  -> angleBrackets (text "ZapCo:" <> int (sum (map coercionSize cos))) <+> dcolon <+> co_type
    
    177
    -              False -> parens $ sep [text "Zap", ppr cos, dcolon <+> co_type]
    
    175
    +pprOptCastCoercion (ZCoercion ty cos) = pprOptZappedCo ty cos
    
    176
    +
    
    177
    +pprOptZappedCo :: Type -> CoVarSet -> SDoc
    
    178
    +pprOptZappedCo ty cos = sdocOption sdocSuppressCoercions $ \case
    
    179
    +              True  -> angleBrackets (text "ZapCo:" <> int (sizeVarSet cos)) <+> dcolon <+> co_type
    
    180
    +              False -> parens $ sep [text "ZapCo", ppr cos, dcolon <+> co_type]
    
    178 181
         where
    
    179 182
           co_type = sdocOption sdocSuppressCoercionTypes $ \case
    
    180 183
               True -> int (typeSize ty) <+> text "..."
    

  • compiler/GHC/Core/Rules.hs
    ... ... @@ -1108,15 +1108,13 @@ match renv subst (Coercion co1) (Coercion co2) MRefl
    1108 1108
     --     Note [Casts in the target]
    
    1109 1109
     --     Note [Cancel reflexive casts]
    
    1110 1110
     
    
    1111
    -match renv subst e1 (Cast e2 (CCoercion co2)) mco
    
    1112
    -  = match renv subst e1 e2 (checkReflexiveMCo (mkTransMCoR co2 mco))
    
    1111
    +match renv subst e1 (Cast e2 co2) mco
    
    1112
    +  = match renv subst e1 e2 (checkReflexiveMCo (mkTransMCoR (castCoToCo (exprType e2) co2) mco))
    
    1113 1113
         -- checkReflexiveMCo: cancel casts if possible
    
    1114 1114
         -- This is important: see Note [Cancel reflexive casts]
    
    1115 1115
     
    
    1116
    -match renv subst (Cast e1 (CCoercion co1)) e2 mco
    
    1117
    -  = matchTemplateCast renv subst e1 co1 e2 mco
    
    1118
    -
    
    1119
    --- TODO: rule matching for ZCoercion
    
    1116
    +match renv subst (Cast e1 co1) e2 mco
    
    1117
    +  = matchTemplateCast renv subst e1 (castCoToCo (exprType e1) co1) e2 mco
    
    1120 1118
     
    
    1121 1119
     ------------------------ Literals ---------------------
    
    1122 1120
     match _ subst (Lit lit1) (Lit lit2) mco
    

  • compiler/GHC/Core/SimpleOpt.hs
    ... ... @@ -33,6 +33,7 @@ import GHC.Core.DataCon
    33 33
     import GHC.Core.Coercion.Opt ( optCoercion, OptCoercionOpts (..) )
    
    34 34
     import GHC.Core.Type hiding ( substTy, extendTvSubst, extendCvSubst, extendTvSubstList
    
    35 35
                                 , isInScope, substTyVarBndr, cloneTyVarBndr )
    
    36
    +import GHC.Core.TyCo.Subst
    
    36 37
     import GHC.Core.Predicate( isCoVarType )
    
    37 38
     import GHC.Core.Coercion hiding ( substCo, substCoVarBndr )
    
    38 39
     
    
    ... ... @@ -324,7 +325,7 @@ simple_opt_expr env expr
    324 325
     
    
    325 326
         ----------------------
    
    326 327
         go_cast_co (CCoercion co) = CCoercion (go_co co)
    
    327
    -    go_cast_co (ZCoercion ty cos) = ZCoercion (substTyUnchecked subst ty) (substCos subst cos)
    
    328
    +    go_cast_co (ZCoercion ty cos) = ZCoercion (substTyUnchecked subst ty) (substCoVarSet subst cos)
    
    328 329
     
    
    329 330
         go_co co = optCoercion (so_co_opts (soe_opts env)) subst co
    
    330 331
     
    
    ... ... @@ -439,14 +440,13 @@ simple_app env e as
    439 440
     finish_app :: HasDebugCallStack
    
    440 441
                => SimpleOptEnv -> OutExpr -> [SimpleClo] -> OutExpr
    
    441 442
     -- See Note [Eliminate casts in function position]
    
    442
    -finish_app env (Cast (Lam x e) (CCoercion co)) as@(_:_)
    
    443
    +finish_app env (Cast (Lam x e) cco) as@(_:_)
    
    443 444
       | not (isTyVar x) && not (isCoVar x)
    
    445
    +  , let co = castCoToCo (exprType (Lam x e)) cco
    
    444 446
       , assert (not $ x `elemVarSet` tyCoVarsOfCo co) True
    
    445 447
       , Just (x',e') <- pushCoercionIntoLambda (soeInScope env) x e co
    
    446 448
       = simple_app (soeZapSubst env) (Lam x' e') as
    
    447 449
     
    
    448
    --- TODO: ZCoercion version of the finish_app
    
    449
    -
    
    450 450
     finish_app env fun args
    
    451 451
       = foldl mk_app fun args
    
    452 452
       where
    
    ... ... @@ -1297,13 +1297,11 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
    1297 1297
         go subst floats (Tick t expr) cont
    
    1298 1298
            | not (tickishIsCode t) = go subst floats expr cont
    
    1299 1299
     
    
    1300
    -    go subst floats (Cast expr (CCoercion co1)) (CC args m_co2)
    
    1301
    -       | Just (args', m_co1') <- pushCoArgs (subst_co subst co1) args
    
    1300
    +    go subst floats (Cast expr co1) (CC args m_co2)
    
    1301
    +       | Just (args', m_co1') <- pushCoArgs (subst_co subst (castCoToCo (exprType expr) co1)) args
    
    1302 1302
                 -- See Note [Push coercions in exprIsConApp_maybe]
    
    1303 1303
            = go subst floats expr (CC args' (m_co1' `mkTransMCo` m_co2))
    
    1304 1304
     
    
    1305
    -    -- TODO: ZCoercion in exprIsConApp_maybe
    
    1306
    -
    
    1307 1305
         go subst floats (App fun arg) (CC args mco)
    
    1308 1306
            | let arg_type = exprType arg
    
    1309 1307
            , not (isTypeArg arg) && needsCaseBinding arg_type arg
    
    ... ... @@ -1590,19 +1588,18 @@ exprIsLambda_maybe ise (Tick t e)
    1590 1588
         = Just (x, e, t:ts)
    
    1591 1589
     
    
    1592 1590
     -- Also possible: A casted lambda. Push the coercion inside
    
    1593
    -exprIsLambda_maybe ise@(ISE in_scope_set _) (Cast casted_e (CCoercion co))
    
    1591
    +exprIsLambda_maybe ise@(ISE in_scope_set _) (Cast casted_e cco)
    
    1594 1592
         | Just (x, e,ts) <- exprIsLambda_maybe ise casted_e
    
    1595 1593
         -- Only do value lambdas.
    
    1596 1594
         -- this implies that x is not in scope in gamma (makes this code simpler)
    
    1597 1595
         , not (isTyVar x) && not (isCoVar x)
    
    1596
    +    , let co = castCoToCo (exprType casted_e) cco
    
    1598 1597
         , assert (not $ x `elemVarSet` tyCoVarsOfCo co) True
    
    1599 1598
         , Just (x',e') <- pushCoercionIntoLambda in_scope_set x e co
    
    1600 1599
         , let res = Just (x',e',ts)
    
    1601 1600
         = --pprTrace "exprIsLambda_maybe:Cast" (vcat [ppr casted_e,ppr co,ppr res)])
    
    1602 1601
           res
    
    1603 1602
     
    
    1604
    --- TODO: exprIsLambda_maybe for ZCoercion
    
    1605
    -
    
    1606 1603
     -- Another attempt: See if we find a partial unfolding
    
    1607 1604
     exprIsLambda_maybe ise@(ISE in_scope_set id_unf) e
    
    1608 1605
         | (Var f, as, ts) <- collectArgsTicks tickishFloatable e
    

  • compiler/GHC/Core/TyCo/FVs.hs
    ... ... @@ -18,10 +18,10 @@ module GHC.Core.TyCo.FVs
    18 18
             coVarsOfType, coVarsOfTypes,
    
    19 19
             coVarsOfCo, coVarsOfCos,
    
    20 20
             coVarsOfCastCo,
    
    21
    -        shallowCoVarsOfCos,
    
    21
    +        shallowCoVarsOfCo, shallowCoVarsOfCos, shallowCoVarsOfCastCo,
    
    22 22
             tyCoVarsOfCastCoercionDSet,
    
    23 23
             tyCoVarsOfCoDSet,
    
    24
    -        tyCoFVsOfCo, tyCoFVsOfCos,
    
    24
    +        tyCoFVsOfCo, tyCoFVsOfCos, tyCoFVsOfCoVarSet,
    
    25 25
             tyCoVarsOfCoList,
    
    26 26
             coVarsOfCoDSet, coVarsOfCosDSet,
    
    27 27
     
    
    ... ... @@ -303,7 +303,7 @@ runTyCoVars f = appEndo f emptyVarSet
    303 303
     
    
    304 304
     tyCoVarsOfCastCo :: CastCoercion -> TyCoVarSet
    
    305 305
     tyCoVarsOfCastCo (CCoercion co)     = coVarsOfCo co
    
    306
    -tyCoVarsOfCastCo (ZCoercion ty cos) = tyCoVarsOfType ty `unionVarSet` tyCoVarsOfCos cos -- TODO: more efficient?
    
    306
    +tyCoVarsOfCastCo (ZCoercion ty cos) = tyCoVarsOfType ty `unionVarSet` cos
    
    307 307
     
    
    308 308
     tyCoVarsOfType :: Type -> TyCoVarSet
    
    309 309
     -- The "deep" TyCoVars of the the type
    
    ... ... @@ -412,6 +412,16 @@ shallowTcvFolder = TyCoFolder { tcf_view = noView -- See Note [Free vars and sy
    412 412
     shallowCoVarsOfCos :: [Coercion] -> CoVarSet
    
    413 413
     shallowCoVarsOfCos cos = filterVarSet isCoVar $ shallowTyCoVarsOfCos cos
    
    414 414
     
    
    415
    +shallowCoVarsOfCo :: Coercion -> CoVarSet
    
    416
    +shallowCoVarsOfCo co = filterVarSet isCoVar $ shallowTyCoVarsOfCo co
    
    417
    +
    
    418
    +shallowCoVarsOfType :: Type -> CoVarSet
    
    419
    +shallowCoVarsOfType ty = filterVarSet isCoVar $ shallowTyCoVarsOfType ty
    
    420
    +
    
    421
    +shallowCoVarsOfCastCo :: CastCoercion -> CoVarSet
    
    422
    +shallowCoVarsOfCastCo (CCoercion co) = shallowCoVarsOfCo co
    
    423
    +shallowCoVarsOfCastCo (ZCoercion ty cos) = shallowCoVarsOfType ty `unionVarSet` cos
    
    424
    +
    
    415 425
     
    
    416 426
     {- *********************************************************************
    
    417 427
     *                                                                      *
    
    ... ... @@ -432,7 +442,7 @@ See #14880.
    432 442
     
    
    433 443
     coVarsOfCastCo :: CastCoercion -> CoVarSet
    
    434 444
     coVarsOfCastCo (CCoercion co) = coVarsOfCo co
    
    435
    -coVarsOfCastCo (ZCoercion ty cos) = coVarsOfType ty `unionVarSet` coVarsOfCos cos -- TODO: more efficient?
    
    445
    +coVarsOfCastCo (ZCoercion ty cos) = coVarsOfType ty `unionVarSet` cos -- TODO cos doesn't include deep, this isn't enough?
    
    436 446
     
    
    437 447
     -- See Note [Finding free coercion variables]
    
    438 448
     coVarsOfType  :: Type       -> CoVarSet
    
    ... ... @@ -666,7 +676,10 @@ tyCoFVsOfMCo (MCo co) = tyCoFVsOfCo co
    666 676
     
    
    667 677
     tyCoFVsOfCastCoercion :: CastCoercion -> FV
    
    668 678
     tyCoFVsOfCastCoercion (CCoercion co) = tyCoFVsOfCo co
    
    669
    -tyCoFVsOfCastCoercion (ZCoercion ty cos) = unionsFV (tyCoFVsOfType ty : map tyCoFVsOfCo cos)
    
    679
    +tyCoFVsOfCastCoercion (ZCoercion ty cos) = tyCoFVsOfType ty `unionFV` tyCoFVsOfCoVarSet cos
    
    680
    +
    
    681
    +tyCoFVsOfCoVarSet :: CoVarSet -> FV
    
    682
    +tyCoFVsOfCoVarSet = nonDetStrictFoldVarSet (unionFV . tyCoFVsOfCoVar) emptyFV -- TODO better way? Nondeterminism?
    
    670 683
     
    
    671 684
     tyCoFVsOfCo :: Coercion -> FV
    
    672 685
     -- Extracts type and coercion variables from a coercion
    

  • compiler/GHC/Core/TyCo/Ppr.hs
    ... ... @@ -48,6 +48,7 @@ import GHC.Types.Var
    48 48
     
    
    49 49
     import GHC.Iface.Type
    
    50 50
     
    
    51
    +import GHC.Types.Unique.Set
    
    51 52
     import GHC.Types.Var.Set
    
    52 53
     import GHC.Types.Var.Env
    
    53 54
     
    
    ... ... @@ -138,7 +139,7 @@ pprCastCo co = getPprStyle $ \ sty -> pprIfaceCastCoercion (tidyToIfaceCastCoSty
    138 139
     
    
    139 140
     tidyToIfaceCastCoSty :: CastCoercion -> PprStyle -> IfaceCastCoercion
    
    140 141
     tidyToIfaceCastCoSty (CCoercion co)     sty = IfaceCCoercion (tidyToIfaceCoSty co sty)
    
    141
    -tidyToIfaceCastCoSty (ZCoercion ty cos) sty = IfaceZCoercion (tidyToIfaceType ty) (map (flip tidyToIfaceCoSty sty) cos) -- TODO
    
    142
    +tidyToIfaceCastCoSty (ZCoercion ty cos) sty = IfaceZCoercion (tidyToIfaceType ty) (map (flip tidyToIfaceCoSty sty . CoVarCo) (nonDetEltsUniqSet cos)) -- TODO
    
    142 143
     
    
    143 144
     tidyToIfaceCoSty :: Coercion -> PprStyle -> IfaceCoercion
    
    144 145
     tidyToIfaceCoSty co sty
    

  • compiler/GHC/Core/TyCo/Rep.hs
    ... ... @@ -77,7 +77,7 @@ import {-# SOURCE #-} GHC.Core.Type( chooseFunTyFlag, typeKind, typeTypeOrConstr
    77 77
     
    
    78 78
     -- friends:
    
    79 79
     import GHC.Types.Var
    
    80
    -import GHC.Types.Var.Set( elemVarSet )
    
    80
    +import GHC.Types.Var.Set
    
    81 81
     import GHC.Core.TyCon
    
    82 82
     import GHC.Core.Coercion.Axiom
    
    83 83
     
    
    ... ... @@ -847,16 +847,17 @@ Note [Zapped casts]
    847 847
     ~~~~~~~~~~~~~~~~~~~
    
    848 848
     A "zapped cast" is a Cast that does not store the full Coercion being used to
    
    849 849
     cast, but instead stores the type resulting from the cast and a set of CoVars
    
    850
    -used in the original coercion.  This reduces the effectiveness of Core Lint,
    
    851
    -because it cannot check the original coercion.
    
    850
    +used in the original coercion.  The CastCoercion type is used to represent
    
    851
    +the coercion argument to a cast; it may be either a full coercion (CCoercion)
    
    852
    +or zapped (ZCoercion).
    
    852 853
     
    
    853 854
     Zapping casts is motivated by performance (see #8095 and related tickets).
    
    854 855
     Sometimes the structure of the coercion can be very large, for example when
    
    855 856
     using type families that take many reduction steps, and when Core Lint is
    
    856 857
     not being used, the full structure of the coercion is not needed.  We merely
    
    857 858
     need the result type (to support exprType) and the set of coercion variables
    
    858
    -(to avoid floating a coercion out of the scope in which it is valid).
    
    859
    -TODO: reference another note about this.
    
    859
    +(to avoid floating a coercion out of the scope in which it is valid, see
    
    860
    +Note [The importance of tracking UnivCo dependencies]).
    
    860 861
     
    
    861 862
     Zapped casts are introduced in exactly one place: finish_rewrite in
    
    862 863
     GHC.Tc.Solver.Solve. This uses a heuristic (isSmallCo) to determine whether
    
    ... ... @@ -870,15 +871,32 @@ which is much smaller than:
    870 871
     
    
    871 872
     This arises in practice with the Rep type family from GHC Generics.
    
    872 873
     
    
    874
    +We can convert a ZCoercion back into a normal Coercion using castCoToCo to
    
    875
    +produce a UnivCo; such coercions can be identified for debugging with the
    
    876
    +ZCoercionProv provenance. This is sometimes necessary in the optimizer, when a
    
    877
    +Cast needs to be moved elsewhere.  Since a UnivCo must store both the left and
    
    878
    +right hand side types, it is less compact than a ZCoercion, so it is best to
    
    879
    +avoid castCoToCo where possible.
    
    880
    +
    
    873 881
     The `-fzap-casts` and `-fno-zap-casts` flags can be used to enable or disable
    
    874 882
     cast zapping, for comparative performance testing or to ensure casts are not
    
    875
    -zapped when debugging the compiler.  In addition, using `-dcore-lint` will
    
    876
    -automatically imply `-fno-zap-casts`.
    
    883
    +zapped when debugging the compiler.
    
    884
    +
    
    885
    +Zapping reduces the effectiveness of Core Lint, because it cannot check that
    
    886
    +the original coercion was well-typed.  Thus `-dcore-lint` will automatically
    
    887
    +imply `-fno-zap-casts` for the same module.  However, imported modules may still
    
    888
    +include zapped casts.
    
    877 889
     TODO: probably the boot libraries ought to be distributed with `-fno-zap-casts`,
    
    878 890
     so users can get full checks from `-dcore-lint`.
    
    879 891
     
    
    880
    -TODO: for simplicity ZCoercion currently stores a list of Coercions, but in
    
    881
    -principle we need only the CoVars.
    
    892
    +ZCoercion discards the structure of the coercion, retaining only the set of variables
    
    893
    +on which it depends.  It is important we store only the "shallow" free CoVars in the
    
    894
    +set, because those are the ones on which the original coercions necessarily depended
    
    895
    +and which may be substituted away later. If we use the deep CoVars, we can end up
    
    896
    +retaining references to CoVars that are no longer in scope. See also
    
    897
    +Note [Shallow and deep free variables] in GHC.Core.TyCo.FVs.
    
    898
    +
    
    899
    +TODO: review determinism; are our uses of nonDetEltsUniqSet and similar safe?
    
    882 900
     
    
    883 901
     -}
    
    884 902
     
    
    ... ... @@ -887,7 +905,7 @@ principle we need only the CoVars.
    887 905
     -- and free CoVars.  See Note [Zapped casts].
    
    888 906
     data CastCoercion
    
    889 907
       = CCoercion CoercionR        -- Not zapped; the Coercion has Representational role
    
    890
    -  | ZCoercion Type [Coercion]  -- Zapped; the Coercions are just variables (TODO: use CoVarSet instead?)
    
    908
    +  | ZCoercion Type CoVarSet    -- Zapped; stores only the RHS type and free CoVars
    
    891 909
       deriving Data.Data
    
    892 910
     
    
    893 911
     -- | A 'Coercion' is concrete evidence of the equality/convertibility
    
    ... ... @@ -2069,7 +2087,7 @@ typesSize tys = foldr ((+) . typeSize) 0 tys
    2069 2087
     
    
    2070 2088
     castCoercionSize :: CastCoercion -> Int
    
    2071 2089
     castCoercionSize (CCoercion co) = coercionSize co
    
    2072
    -castCoercionSize (ZCoercion ty cos) = typeSize ty + sum (map coercionSize cos)
    
    2090
    +castCoercionSize (ZCoercion ty cos) = typeSize ty + sizeVarSet cos
    
    2073 2091
     
    
    2074 2092
     coercionSize :: Coercion -> Int
    
    2075 2093
     coercionSize (Refl ty)             = typeSize ty
    

  • compiler/GHC/Core/TyCo/Subst.hs
    ... ... @@ -34,7 +34,7 @@ module GHC.Core.TyCo.Subst
    34 34
             substTyUnchecked, substTysUnchecked, substScaledTysUnchecked, substThetaUnchecked,
    
    35 35
             substTyWithUnchecked, substScaledTyUnchecked,
    
    36 36
             substCoUnchecked, substCoWithUnchecked,
    
    37
    -        substCastCo, substCastCoUnchecked,
    
    37
    +        substCastCo, substCoVarSet,
    
    38 38
             substTyWithInScope,
    
    39 39
             substTys, substScaledTys, substTheta,
    
    40 40
             lookupTyVar,
    
    ... ... @@ -846,12 +846,12 @@ lookupTyVar (Subst _ _ tenv _) tv
    846 846
         lookupVarEnv tenv tv
    
    847 847
     
    
    848 848
     substCastCo :: HasDebugCallStack => Subst -> CastCoercion -> CastCoercion
    
    849
    -substCastCo subst (CCoercion co) = CCoercion (substCo subst co)
    
    850
    -substCastCo subst (ZCoercion ty cos) = ZCoercion (substTy subst ty) (map (substCo subst) cos) -- TODO: zap?
    
    849
    +substCastCo subst (CCoercion co)     = CCoercion (substCo subst co)
    
    850
    +substCastCo subst (ZCoercion ty cos) = ZCoercion (substTy subst ty) (substCoVarSet subst cos)
    
    851
    +
    
    852
    +substCoVarSet :: HasDebugCallStack => Subst -> CoVarSet -> CoVarSet
    
    853
    +substCoVarSet subst = nonDetStrictFoldVarSet (unionVarSet . shallowCoVarsOfCo . substCoVar subst) emptyVarSet -- TODO better impl; determinism?
    
    851 854
     
    
    852
    -substCastCoUnchecked :: Subst -> CastCoercion -> CastCoercion
    
    853
    -substCastCoUnchecked subst (CCoercion co) = CCoercion (substCoUnchecked subst co)
    
    854
    -substCastCoUnchecked subst (ZCoercion ty cos) = ZCoercion (substTyUnchecked subst ty) (map (substCoUnchecked subst) cos) -- TODO: zap?
    
    855 855
     
    
    856 856
     -- | Substitute within a 'Coercion'
    
    857 857
     -- The substitution has to satisfy the invariants described in
    

  • compiler/GHC/Core/TyCo/Tidy.hs
    ... ... @@ -26,6 +26,7 @@ import GHC.Core.TyCo.FVs
    26 26
     import GHC.Types.Name hiding (varName)
    
    27 27
     import GHC.Types.Var
    
    28 28
     import GHC.Types.Var.Env
    
    29
    +import GHC.Types.Var.Set
    
    29 30
     import GHC.Utils.Misc (strictMap)
    
    30 31
     
    
    31 32
     import Data.List (mapAccumL)
    
    ... ... @@ -366,4 +367,4 @@ tidyCos env = strictMap (tidyCo env)
    366 367
     
    
    367 368
     tidyCastCo :: TidyEnv -> CastCoercion -> CastCoercion
    
    368 369
     tidyCastCo env (CCoercion co) = CCoercion (tidyCo env co)
    
    369
    -tidyCastCo env (ZCoercion ty cos) = ZCoercion (tidyType env ty) (tidyCos env cos)
    370
    +tidyCastCo env (ZCoercion ty cos) = ZCoercion (tidyType env ty) (mapVarSet (tidyTyCoVarOcc env) cos)

  • compiler/GHC/Core/Utils.hs
    ... ... @@ -77,6 +77,7 @@ import GHC.Core.Type as Type
    77 77
     import GHC.Core.Predicate( isCoVarType )
    
    78 78
     import GHC.Core.FamInstEnv
    
    79 79
     import GHC.Core.TyCo.Compare( eqType, eqTypeX )
    
    80
    +import GHC.Core.TyCo.FVs
    
    80 81
     import GHC.Core.Coercion
    
    81 82
     import GHC.Core.Reduction
    
    82 83
     import GHC.Core.TyCon
    
    ... ... @@ -297,13 +298,13 @@ mkCast expr co
    297 298
     
    
    298 299
     -- | Wrap the given expression in a zapped cast (see Note [Zapped casts] in
    
    299 300
     -- GHC.Core.TyCo.Rep).
    
    300
    -mkCastZ :: HasDebugCallStack => CoreExpr -> Type -> [Coercion] -> CoreExpr
    
    301
    +mkCastZ :: HasDebugCallStack => CoreExpr -> Type -> CoVarSet -> CoreExpr
    
    301 302
     mkCastZ expr ty cos =
    
    302 303
         case expr of
    
    303
    -      Cast expr co -> mkCastZ expr ty (zapCastCo co ++ cos)
    
    304
    +      Cast expr co -> mkCastZ expr ty (shallowCoVarsOfCastCo co `unionVarSet` cos)
    
    304 305
           Tick t expr -> Tick t (mkCastZ expr ty cos)
    
    305
    -      -- TODO: do we need other cases from mkCast?
    
    306
    -      _ -> Cast expr (ZCoercion ty (zapCos cos))
    
    306
    +      Coercion e_co | isCoVarType ty -> Coercion (mkCoCastCo e_co (ZCoercion ty cos))
    
    307
    +      _ -> Cast expr (ZCoercion ty cos)
    
    307 308
     
    
    308 309
     
    
    309 310
     
    

  • compiler/GHC/CoreToIface.hs
    ... ... @@ -85,6 +85,7 @@ import GHC.Types.Tickish
    85 85
     import GHC.Types.Demand ( isNopSig )
    
    86 86
     import GHC.Types.Cpr ( topCprSig )
    
    87 87
     import GHC.Types.SrcLoc (unLoc)
    
    88
    +import GHC.Types.Unique.Set
    
    88 89
     
    
    89 90
     import GHC.Utils.Outputable
    
    90 91
     import GHC.Utils.Panic
    
    ... ... @@ -275,7 +276,7 @@ toIfaceTyLit (CharTyLit x) = IfaceCharTyLit x
    275 276
     ----------------
    
    276 277
     toIfaceCastCoercion :: CastCoercion -> IfaceCastCoercion
    
    277 278
     toIfaceCastCoercion (CCoercion co) = IfaceCCoercion (toIfaceCoercion co)
    
    278
    -toIfaceCastCoercion (ZCoercion ty cos) = IfaceZCoercion (toIfaceType ty) (map toIfaceCoercion cos)
    
    279
    +toIfaceCastCoercion (ZCoercion ty cos) = IfaceZCoercion (toIfaceType ty) (map (toIfaceCoercion . CoVarCo) (nonDetEltsUniqSet cos)) -- TODO determinism
    
    279 280
     
    
    280 281
     toIfaceCoercion :: Coercion -> IfaceCoercion
    
    281 282
     toIfaceCoercion = toIfaceCoercionX emptyVarSet
    

  • compiler/GHC/IfaceToCore.hs
    ... ... @@ -63,6 +63,7 @@ import GHC.Core.Type
    63 63
     import GHC.Core.Coercion
    
    64 64
     import GHC.Core.Coercion.Axiom
    
    65 65
     import GHC.Core.FVs
    
    66
    +import GHC.Core.TyCo.FVs
    
    66 67
     import GHC.Core.TyCo.Rep    -- needs to build types & coercions in a knot
    
    67 68
     import GHC.Core.TyCo.Subst ( substTyCoVars )
    
    68 69
     import GHC.Core.InstEnv
    
    ... ... @@ -1566,7 +1567,7 @@ tcIfaceTyLit (IfaceCharTyLit n) = return (CharTyLit n)
    1566 1567
     
    
    1567 1568
     tcIfaceCastCoercion :: IfaceCastCoercion -> IfL CastCoercion
    
    1568 1569
     tcIfaceCastCoercion (IfaceCCoercion co)     = CCoercion <$> tcIfaceCo co
    
    1569
    -tcIfaceCastCoercion (IfaceZCoercion ty cos) = ZCoercion <$> tcIfaceType ty <*> mapM tcIfaceCo cos
    
    1570
    +tcIfaceCastCoercion (IfaceZCoercion ty cos) = ZCoercion <$> tcIfaceType ty <*> (shallowCoVarsOfCos <$> mapM tcIfaceCo cos)
    
    1570 1571
     
    
    1571 1572
     tcIfaceCo :: IfaceCoercion -> IfL Coercion
    
    1572 1573
     tcIfaceCo = go
    

  • compiler/GHC/Tc/Solver/Solve.hs
    ... ... @@ -36,6 +36,7 @@ import GHC.Core.Predicate
    36 36
     import GHC.Core.Reduction
    
    37 37
     import GHC.Core.Coercion
    
    38 38
     import GHC.Core.Class( classHasSCs )
    
    39
    +import GHC.Core.TyCo.FVs
    
    39 40
     import GHC.Core.TyCo.Rep (Coercion(..))
    
    40 41
     
    
    41 42
     import GHC.Types.Id(  idType )
    
    ... ... @@ -1494,7 +1495,7 @@ finish_rewrite
    1494 1495
     mkCastCoercion :: Bool -> Type -> Coercion -> CastCoercion
    
    1495 1496
     mkCastCoercion zap_casts lhs_ty co
    
    1496 1497
        | isSmallCo co || not zap_casts = CCoercion co
    
    1497
    -   | otherwise                     = ZCoercion lhs_ty (zapCo co)
    
    1498
    +   | otherwise                     = ZCoercion lhs_ty (shallowCoVarsOfCo co)
    
    1498 1499
     
    
    1499 1500
     -- | Is this coercion probably smaller than its type? This is a rough heuristic,
    
    1500 1501
     -- but crucially we treat axioms (perhaps wrapped in Sym/Sub/etc.) as small
    

  • compiler/GHC/Tc/Zonk/Type.hs
    ... ... @@ -64,6 +64,7 @@ import GHC.Tc.Zonk.TcType
    64 64
     import GHC.Core.Type
    
    65 65
     import GHC.Core.Coercion
    
    66 66
     import GHC.Core.TyCon
    
    67
    +import GHC.Core.TyCo.FVs
    
    67 68
     
    
    68 69
     import GHC.Utils.Outputable
    
    69 70
     import GHC.Utils.Misc
    
    ... ... @@ -78,11 +79,13 @@ import GHC.Types.Name
    78 79
     import GHC.Types.Name.Env
    
    79 80
     import GHC.Types.Var
    
    80 81
     import GHC.Types.Var.Env
    
    82
    +import GHC.Types.Var.Set
    
    81 83
     import GHC.Types.Id
    
    82 84
     import GHC.Types.TypeEnv
    
    83 85
     import GHC.Types.Basic
    
    84 86
     import GHC.Types.SrcLoc
    
    85 87
     import GHC.Types.Unique.FM
    
    88
    +import GHC.Types.Unique.Set
    
    86 89
     import GHC.Types.TyThing
    
    87 90
     
    
    88 91
     import GHC.Tc.Types.BasicTypes
    
    ... ... @@ -532,15 +535,18 @@ zonkScaledTcTypeToTypeX (Scaled m ty) = Scaled <$> zonkTcTypeToTypeX m
    532 535
     zonkTcTypeToTypeX   :: TcType   -> ZonkTcM Type
    
    533 536
     zonkTcTypesToTypesX :: [TcType] -> ZonkTcM [Type]
    
    534 537
     zonkCoToCo          :: Coercion -> ZonkTcM Coercion
    
    535
    -zonkCosToCos        :: [Coercion] -> ZonkTcM [Coercion]
    
    536
    -(zonkTcTypeToTypeX, zonkTcTypesToTypesX, zonkCoToCo, zonkCosToCos)
    
    538
    +_zonkCosToCos        :: [Coercion] -> ZonkTcM [Coercion]
    
    539
    +(zonkTcTypeToTypeX, zonkTcTypesToTypesX, zonkCoToCo, _zonkCosToCos)
    
    537 540
       = case mapTyCoX zonk_tycomapper of
    
    538 541
           (zty, ztys, zco, zcos) ->
    
    539 542
             (ZonkT . flip zty, ZonkT . flip ztys, ZonkT . flip zco, ZonkT. flip zcos)
    
    540 543
     
    
    541 544
     zonkCastCo :: CastCoercion -> ZonkTcM CastCoercion
    
    542 545
     zonkCastCo (CCoercion co) = CCoercion <$> zonkCoToCo co
    
    543
    -zonkCastCo (ZCoercion ty cos) = ZCoercion <$> zonkTcTypeToTypeX ty <*> zonkCosToCos cos
    
    546
    +zonkCastCo (ZCoercion ty cos) = ZCoercion <$> zonkTcTypeToTypeX ty <*> zonkCoVarSet cos
    
    547
    +
    
    548
    +zonkCoVarSet :: CoVarSet -> ZonkTcM CoVarSet
    
    549
    +zonkCoVarSet = fmap shallowCoVarsOfCos . mapM zonkCoVarOcc . nonDetEltsUniqSet
    
    544 550
     
    
    545 551
     zonkScaledTcTypesToTypesX :: [Scaled TcType] -> ZonkTcM [Scaled Type]
    
    546 552
     zonkScaledTcTypesToTypesX scaled_tys =
    

  • docs/users_guide/debugging.rst
    ... ... @@ -1223,14 +1223,16 @@ Other
    1223 1223
         :type: dynamic
    
    1224 1224
     
    
    1225 1225
         :since: TODO
    
    1226
    +    :default: enabled
    
    1226 1227
     
    
    1227 1228
         Reduce the size of Core terms by discarding coercion proofs that are needed
    
    1228 1229
         only for debugging the compiler.  This usually helps improve compile-time
    
    1229 1230
         performance for some programs that make heavy use of type families.
    
    1230 1231
     
    
    1231
    -    When this flag is enabled, Core Lint will be less effective at verifying the
    
    1232
    -    correctness of Core programs involving casts. Hence this is automatically
    
    1233
    -    switched off by :ghc-flag:`-dcore-lint`.
    
    1232
    +    This is enabled by default. When it is enabled, Core Lint will be less
    
    1233
    +    effective at verifying the correctness of Core programs involving casts.
    
    1234
    +    Hence it is automatically switched off by :ghc-flag:`-dcore-lint`, or you
    
    1235
    +    can disable it using ``-fno-zap-casts``.
    
    1234 1236
     
    
    1235 1237
     .. ghc-flag:: -dno-typeable-binds
    
    1236 1238
         :shortdesc: Don't generate bindings for Typeable methods