Simon Peyton Jones pushed to branch wip/T23162-spj at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • compiler/GHC/Tc/Solver/Dict.hs
    ... ... @@ -21,7 +21,7 @@ import GHC.Tc.Types.Constraint
    21 21
     import GHC.Tc.Types.CtLoc
    
    22 22
     import GHC.Tc.Types.Origin
    
    23 23
     import GHC.Tc.Types.EvTerm( evCallStack )
    
    24
    -import GHC.Tc.Solver.FunDeps( doDictFunDepImprovement )
    
    24
    +import GHC.Tc.Solver.FunDeps( tryDictFunDeps )
    
    25 25
     import GHC.Tc.Solver.InertSet
    
    26 26
     import GHC.Tc.Solver.Monad
    
    27 27
     import GHC.Tc.Solver.Types
    
    ... ... @@ -95,7 +95,7 @@ solveDict dict_ct@(DictCt { di_ev = ev, di_cls = cls, di_tys = tys })
    95 95
     
    
    96 96
            -- Try fundeps /after/ tryInstances:
    
    97 97
            --     see (DFL2) in Note [Do fundeps last]
    
    98
    -       ; doDictFunDepImprovement dict_ct
    
    98
    +       ; tryDictFunDeps dict_ct
    
    99 99
     
    
    100 100
            ; simpleStage (updInertDicts dict_ct)
    
    101 101
            ; stopWithStage (dictCtEvidence dict_ct) "Kept inert DictCt" }
    

  • compiler/GHC/Tc/Solver/Equality.hs
    ... ... @@ -16,9 +16,8 @@ import GHC.Tc.Solver.Irred( solveIrred )
    16 16
     import GHC.Tc.Solver.Dict( matchLocalInst, chooseInstance )
    
    17 17
     import GHC.Tc.Solver.Rewrite
    
    18 18
     import GHC.Tc.Solver.Monad
    
    19
    -import GHC.Tc.Solver.FunDeps( unifyAndEmitFunDepWanteds )
    
    19
    +import GHC.Tc.Solver.FunDeps( tryEqFunDeps )
    
    20 20
     import GHC.Tc.Solver.InertSet
    
    21
    -import GHC.Tc.Solver.Types( findFunEqsByTyCon )
    
    22 21
     import GHC.Tc.Types.Evidence
    
    23 22
     import GHC.Tc.Types.Constraint
    
    24 23
     import GHC.Tc.Types.CtLoc
    
    ... ... @@ -26,7 +25,6 @@ import GHC.Tc.Types.Origin
    26 25
     import GHC.Tc.Utils.Unify
    
    27 26
     import GHC.Tc.Utils.TcType
    
    28 27
     import GHC.Tc.Instance.Family ( tcTopNormaliseNewTypeTF_maybe )
    
    29
    -import GHC.Tc.Instance.FunDeps( FunDepEqn(..) )
    
    30 28
     import qualified GHC.Tc.Utils.Monad    as TcM
    
    31 29
     
    
    32 30
     import GHC.Core.Type
    
    ... ... @@ -36,21 +34,15 @@ import GHC.Core.DataCon ( dataConName )
    36 34
     import GHC.Core.TyCon
    
    37 35
     import GHC.Core.TyCo.Rep   -- cleverly decomposes types, good for completeness checking
    
    38 36
     import GHC.Core.Coercion
    
    39
    -import GHC.Core.Coercion.Axiom
    
    40 37
     import GHC.Core.Reduction
    
    41
    -import GHC.Core.Unify( tcUnifyTyForInjectivity )
    
    42
    -import GHC.Core.FamInstEnv ( FamInstEnvs, FamInst(..), apartnessCheck
    
    43
    -                           , lookupFamInstEnvByTyCon )
    
    38
    +import GHC.Core.FamInstEnv ( FamInstEnvs ) 
    
    44 39
     import GHC.Core
    
    45
    -
    
    46 40
     import GHC.Types.Var
    
    47 41
     import GHC.Types.Var.Env
    
    48 42
     import GHC.Types.Var.Set( anyVarSet )
    
    49 43
     import GHC.Types.Name.Reader
    
    50 44
     import GHC.Types.Basic
    
    51 45
     
    
    52
    -import GHC.Builtin.Types.Literals ( tryInteractTopFam, tryInteractInertFam )
    
    53
    -
    
    54 46
     import GHC.Utils.Outputable
    
    55 47
     import GHC.Utils.Panic
    
    56 48
     import GHC.Utils.Misc
    
    ... ... @@ -120,9 +112,9 @@ solveEquality ev eq_rel ty1 ty2
    120 112
                 Left irred_ct -> do { tryQCsIrredEqCt irred_ct
    
    121 113
                                     ; solveIrred irred_ct } ;
    
    122 114
     
    
    123
    -            Right eq_ct   -> do { tryInertEqs eq_ct
    
    124
    -                                ; tryFunDeps  eq_ct
    
    125
    -                                ; tryQCsEqCt  eq_ct
    
    115
    +            Right eq_ct   -> do { tryInertEqs  eq_ct
    
    116
    +                                ; tryEqFunDeps eq_ct
    
    117
    +                                ; tryQCsEqCt   eq_ct
    
    126 118
                                     ; simpleStage (updInertEqs eq_ct)
    
    127 119
                                     ; stopWithStage (eqCtEvidence eq_ct) "Kept inert EqCt" } } }
    
    128 120
     
    
    ... ... @@ -2025,7 +2017,7 @@ canEqCanLHSFinish_try_unification ev eq_rel swapped lhs rhs
    2025 2017
                evCoercion (mkNomReflCo final_rhs)
    
    2026 2018
     
    
    2027 2019
              -- Kick out any constraints that can now be rewritten
    
    2028
    -         ; kickOutAfterUnification [tv]
    
    2020
    +         ; recordUnification tv
    
    2029 2021
     
    
    2030 2022
              ; return (Stop new_ev (text "Solved by unification")) }
    
    2031 2023
     
    
    ... ... @@ -2996,456 +2988,3 @@ lovely quantified constraint. Alas!
    2996 2988
     This test arranges to ignore the instance-based solution under these
    
    2997 2989
     (rare) circumstances.   It's sad, but I  really don't see what else we can do.
    
    2998 2990
     -}
    2999
    -
    
    3000
    -
    
    3001
    -{-
    
    3002
    -**********************************************************************
    
    3003
    -*                                                                    *
    
    3004
    -    Functional dependencies for type families
    
    3005
    -*                                                                    *
    
    3006
    -**********************************************************************
    
    3007
    -
    
    3008
    -Note [Reverse order of fundep equations]
    
    3009
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3010
    -Consider this scenario (from dependent/should_fail/T13135_simple):
    
    3011
    -
    
    3012
    -  type Sig :: Type -> Type
    
    3013
    -  data Sig a = SigFun a (Sig a)
    
    3014
    -
    
    3015
    -  type SmartFun :: forall (t :: Type). Sig t -> Type
    
    3016
    -  type family SmartFun sig = r | r -> sig where
    
    3017
    -    SmartFun @Type (SigFun @Type a sig) = a -> SmartFun @Type sig
    
    3018
    -
    
    3019
    -  [W] SmartFun @kappa sigma ~ (Int -> Bool)
    
    3020
    -
    
    3021
    -The injectivity of SmartFun allows us to produce two new equalities:
    
    3022
    -
    
    3023
    -  [W] w1 :: Type ~ kappa
    
    3024
    -  [W] w2 :: SigFun @Type Int beta ~ sigma
    
    3025
    -
    
    3026
    -for some fresh (beta :: SigType). The second Wanted here is actually
    
    3027
    -heterogeneous: the LHS has type Sig Type while the RHS has type Sig kappa.
    
    3028
    -Of course, if we solve the first wanted first, the second becomes homogeneous.
    
    3029
    -
    
    3030
    -When looking for injectivity-inspired equalities, we work left-to-right,
    
    3031
    -producing the two equalities in the order written above. However, these
    
    3032
    -equalities are then passed into wrapUnifierTcS, which will fail, adding these
    
    3033
    -to the work list. However, crucially, the work list operates like a *stack*.
    
    3034
    -So, because we add w1 and then w2, we process w2 first. This is silly: solving
    
    3035
    -w1 would unlock w2. So we make sure to add equalities to the work
    
    3036
    -list in left-to-right order, which requires a few key calls to 'reverse'.
    
    3037
    -
    
    3038
    -This treatment is also used for class-based functional dependencies, although
    
    3039
    -we do not have a program yet known to exhibit a loop there. It just seems
    
    3040
    -like the right thing to do.
    
    3041
    -
    
    3042
    -When this was originally conceived, it was necessary to avoid a loop in T13135.
    
    3043
    -That loop is now avoided by continuing with the kind equality (not the type
    
    3044
    -equality) in canEqCanLHSHetero (see Note [Equalities with heterogeneous kinds]).
    
    3045
    -However, the idea of working left-to-right still seems worthwhile, and so the calls
    
    3046
    -to 'reverse' remain.
    
    3047
    -
    
    3048
    -Note [Improvement orientation]
    
    3049
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3050
    -See also Note [Fundeps with instances, and equality orientation], which describes
    
    3051
    -the Exact Same Problem, with the same solution, but for functional dependencies.
    
    3052
    -
    
    3053
    -A very delicate point is the orientation of equalities
    
    3054
    -arising from injectivity improvement (#12522).  Suppose we have
    
    3055
    -  type family F x = t | t -> x
    
    3056
    -  type instance F (a, Int) = (Int, G a)
    
    3057
    -where G is injective; and wanted constraints
    
    3058
    -
    
    3059
    -  [W] F (alpha, beta) ~ (Int, <some type>)
    
    3060
    -
    
    3061
    -The injectivity will give rise to constraints
    
    3062
    -
    
    3063
    -  [W] gamma1 ~ alpha
    
    3064
    -  [W] Int ~ beta
    
    3065
    -
    
    3066
    -The fresh unification variable gamma1 comes from the fact that we
    
    3067
    -can only do "partial improvement" here; see Section 5.2 of
    
    3068
    -"Injective type families for Haskell" (HS'15).
    
    3069
    -
    
    3070
    -Now, it's very important to orient the equations this way round,
    
    3071
    -so that the fresh unification variable will be eliminated in
    
    3072
    -favour of alpha.  If we instead had
    
    3073
    -   [W] alpha ~ gamma1
    
    3074
    -then we would unify alpha := gamma1; and kick out the wanted
    
    3075
    -constraint.  But when we substitute it back in, it'd look like
    
    3076
    -   [W] F (gamma1, beta) ~ fuv
    
    3077
    -and exactly the same thing would happen again!  Infinite loop.
    
    3078
    -
    
    3079
    -This all seems fragile, and it might seem more robust to avoid
    
    3080
    -introducing gamma1 in the first place, in the case where the
    
    3081
    -actual argument (alpha, beta) partly matches the improvement
    
    3082
    -template.  But that's a bit tricky, esp when we remember that the
    
    3083
    -kinds much match too; so it's easier to let the normal machinery
    
    3084
    -handle it.  Instead we are careful to orient the new
    
    3085
    -equality with the template on the left.  Delicate, but it works.
    
    3086
    -
    
    3087
    --}
    
    3088
    -
    
    3089
    ---------------------
    
    3090
    -
    
    3091
    -tryFunDeps :: EqCt -> SolverStage ()
    
    3092
    -tryFunDeps work_item@(EqCt { eq_lhs = lhs, eq_ev = ev, eq_eq_rel = eq_rel })
    
    3093
    -  | NomEq <- eq_rel
    
    3094
    -  , TyFamLHS tc args <- lhs
    
    3095
    -  = Stage $
    
    3096
    -    do { inerts <- getInertCans
    
    3097
    -       ; imp1 <- improveLocalFunEqs inerts tc args work_item
    
    3098
    -       ; imp2 <- improveTopFunEqs tc args work_item
    
    3099
    -       ; if (imp1 || imp2)
    
    3100
    -         then startAgainWith (mkNonCanonical ev)
    
    3101
    -         else continueWith () }
    
    3102
    -  | otherwise
    
    3103
    -  = nopStage ()
    
    3104
    -
    
    3105
    ---------------------
    
    3106
    -improveTopFunEqs :: TyCon -> [TcType] -> EqCt -> TcS Bool
    
    3107
    --- TyCon is definitely a type family
    
    3108
    --- See Note [FunDep and implicit parameter reactions]
    
    3109
    -improveTopFunEqs fam_tc args (EqCt { eq_ev = ev, eq_rhs = rhs_ty })
    
    3110
    -  | isGiven ev = improveGivenTopFunEqs  fam_tc args ev rhs_ty
    
    3111
    -  | otherwise  = improveWantedTopFunEqs fam_tc args ev rhs_ty
    
    3112
    -
    
    3113
    -improveGivenTopFunEqs :: TyCon -> [TcType] -> CtEvidence -> Xi -> TcS Bool
    
    3114
    --- TyCon is definitely a type family
    
    3115
    --- Work-item is a Given
    
    3116
    -improveGivenTopFunEqs fam_tc args ev rhs_ty
    
    3117
    -  | Just ops <- isBuiltInSynFamTyCon_maybe fam_tc
    
    3118
    -  = do { traceTcS "improveGivenTopFunEqs" (ppr fam_tc <+> ppr args $$ ppr ev $$ ppr rhs_ty)
    
    3119
    -       ; emitNewGivens (ctEvLoc ev) $
    
    3120
    -           [ (Nominal, new_co)
    
    3121
    -           | (ax, _) <- tryInteractTopFam ops fam_tc args rhs_ty
    
    3122
    -           , let new_co = mkAxiomCo ax [given_co] ]
    
    3123
    -       ; return False }  -- False: no unifications
    
    3124
    -  | otherwise
    
    3125
    -  = return False
    
    3126
    -  where
    
    3127
    -    given_co :: Coercion = ctEvCoercion ev
    
    3128
    -
    
    3129
    -improveWantedTopFunEqs :: TyCon -> [TcType] -> CtEvidence -> Xi -> TcS Bool
    
    3130
    --- TyCon is definitely a type family
    
    3131
    --- Work-item is a Wanted
    
    3132
    -improveWantedTopFunEqs fam_tc args ev rhs_ty
    
    3133
    -  = do { eqns <- improve_wanted_top_fun_eqs fam_tc args rhs_ty
    
    3134
    -       ; traceTcS "improveTopFunEqs" (vcat [ text "lhs:" <+> ppr fam_tc <+> ppr args
    
    3135
    -                                           , text "rhs:" <+> ppr rhs_ty
    
    3136
    -                                           , text "eqns:" <+> ppr eqns ])
    
    3137
    -       ; unifyFunDeps ev Nominal $ \uenv ->
    
    3138
    -         uPairsTcM (bump_depth uenv) (reverse eqns) }
    
    3139
    -         -- Missing that `reverse` causes T13135 and T13135_simple to loop.
    
    3140
    -         -- See Note [Reverse order of fundep equations]
    
    3141
    -
    
    3142
    -  where
    
    3143
    -    bump_depth env = env { u_loc = bumpCtLocDepth (u_loc env) }
    
    3144
    -        -- ToDo: this location is wrong; it should be FunDepOrigin2
    
    3145
    -        -- See #14778
    
    3146
    -
    
    3147
    -improve_wanted_top_fun_eqs :: TyCon -> [TcType] -> Xi
    
    3148
    -                           -> TcS [TypeEqn]
    
    3149
    --- TyCon is definitely a type family
    
    3150
    -improve_wanted_top_fun_eqs fam_tc lhs_tys rhs_ty
    
    3151
    -  | Just ops <- isBuiltInSynFamTyCon_maybe fam_tc
    
    3152
    -  = return (map snd $ tryInteractTopFam ops fam_tc lhs_tys rhs_ty)
    
    3153
    -
    
    3154
    -  -- ToDo: use ideas in #23162 for closed type families; injectivity only for open
    
    3155
    -
    
    3156
    -  -- See Note [Type inference for type families with injectivity]
    
    3157
    -  -- Open, so look for inj
    
    3158
    -  | Injective inj_args <- tyConInjectivityInfo fam_tc
    
    3159
    -  = do { fam_envs <- getFamInstEnvs
    
    3160
    -       ; top_eqns <- improve_injective_wanted_top fam_envs inj_args fam_tc lhs_tys rhs_ty
    
    3161
    -       ; let local_eqns = improve_injective_wanted_famfam  inj_args fam_tc lhs_tys rhs_ty
    
    3162
    -       ; traceTcS "improve_wanted_top_fun_eqs" $
    
    3163
    -         vcat [ ppr fam_tc, text "local_eqns" <+> ppr local_eqns, text "top_eqns" <+> ppr top_eqns ]
    
    3164
    -  -- xxx ToDo: this does both local and top => bug?
    
    3165
    -       ; return (local_eqns ++ top_eqns) }
    
    3166
    -
    
    3167
    -  | otherwise  -- No injectivity
    
    3168
    -  = return []
    
    3169
    -
    
    3170
    -improve_injective_wanted_top :: FamInstEnvs -> [Bool] -> TyCon -> [TcType] -> Xi -> TcS [TypeEqn]
    
    3171
    --- Interact with top-level instance declarations
    
    3172
    --- See Section 5.2 in the Injective Type Families paper
    
    3173
    -improve_injective_wanted_top fam_envs inj_args fam_tc lhs_tys rhs_ty
    
    3174
    -  = concatMapM do_one branches
    
    3175
    -  where
    
    3176
    -    branches :: [CoAxBranch]
    
    3177
    -    branches | isOpenTypeFamilyTyCon fam_tc
    
    3178
    -             , let fam_insts = lookupFamInstEnvByTyCon fam_envs fam_tc
    
    3179
    -             = concatMap (fromBranches . coAxiomBranches . fi_axiom) fam_insts
    
    3180
    -
    
    3181
    -             | Just ax <- isClosedSynFamilyTyConWithAxiom_maybe fam_tc
    
    3182
    -             = fromBranches (coAxiomBranches ax)
    
    3183
    -
    
    3184
    -             | otherwise
    
    3185
    -             = []
    
    3186
    -
    
    3187
    -    do_one :: CoAxBranch -> TcS [TypeEqn]
    
    3188
    -    do_one branch@(CoAxBranch { cab_tvs = branch_tvs, cab_lhs = branch_lhs_tys, cab_rhs = branch_rhs })
    
    3189
    -      | let in_scope1 = in_scope `extendInScopeSetList` branch_tvs
    
    3190
    -      , Just subst <- tcUnifyTyForInjectivity False in_scope1 branch_rhs rhs_ty
    
    3191
    -                      -- False: matching, not unifying
    
    3192
    -      = do { let inSubst tv = tv `elemVarEnv` getTvSubstEnv subst
    
    3193
    -                 unsubstTvs = filterOut inSubst branch_tvs
    
    3194
    -                 -- The order of unsubstTvs is important; it must be
    
    3195
    -                 -- in telescope order e.g. (k:*) (a:k)
    
    3196
    -
    
    3197
    -           ; (_subst_tvs, subst1) <- instFlexiX subst unsubstTvs
    
    3198
    -                -- If the current substitution bind [k -> *], and
    
    3199
    -                -- one of the un-substituted tyvars is (a::k), we'd better
    
    3200
    -                -- be sure to apply the current substitution to a's kind.
    
    3201
    -                -- Hence instFlexiX.   #13135 was an example.
    
    3202
    -
    
    3203
    -           ; traceTcS "improve_inj_top" $
    
    3204
    -             vcat [ text "branch_rhs" <+> ppr branch_rhs
    
    3205
    -                  , text "rhs_ty" <+> ppr rhs_ty
    
    3206
    -                  , text "subst" <+> ppr subst
    
    3207
    -                  , text "subst1" <+> ppr subst1 ]
    
    3208
    -           ; if apartnessCheck (substTys subst1 branch_lhs_tys) branch
    
    3209
    -             then do { traceTcS "improv_inj_top1" (ppr branch_lhs_tys)
    
    3210
    -                     ; return (mkInjectivityEqns inj_args (map (substTy subst1) branch_lhs_tys) lhs_tys) }
    
    3211
    -                  -- NB: The fresh unification variables (from unsubstTvs) are on the left
    
    3212
    -                  --     See Note [Improvement orientation]
    
    3213
    -             else do { traceTcS "improve_inj_top2" empty; return []  } }
    
    3214
    -      | otherwise
    
    3215
    -      = do { traceTcS "improve_inj_top:fail" (ppr branch_rhs $$ ppr rhs_ty $$ ppr in_scope $$ ppr branch_tvs)
    
    3216
    -           ; return [] }
    
    3217
    -
    
    3218
    -    in_scope = mkInScopeSet (tyCoVarsOfType rhs_ty)
    
    3219
    -
    
    3220
    -
    
    3221
    -improve_injective_wanted_famfam :: [Bool] -> TyCon -> [TcType] -> Xi -> [TypeEqn]
    
    3222
    --- Interact with itself, specifically  F s1 s2 ~ F t1 t2
    
    3223
    -improve_injective_wanted_famfam inj_args fam_tc lhs_tys rhs_ty
    
    3224
    -  | Just (tc, rhs_tys) <- tcSplitTyConApp_maybe rhs_ty
    
    3225
    -  , tc == fam_tc
    
    3226
    -  = mkInjectivityEqns inj_args lhs_tys rhs_tys
    
    3227
    -  | otherwise
    
    3228
    -  = []
    
    3229
    -
    
    3230
    -mkInjectivityEqns :: [Bool] -> [TcType] -> [TcType] -> [TypeEqn]
    
    3231
    --- When F s1 s2 s3 ~ F t1 t2 t3, and F has injectivity info [True,False,True]
    
    3232
    --- return the equations [Pair s1 t1, Pair s3 t3]
    
    3233
    -mkInjectivityEqns inj_args lhs_args rhs_args
    
    3234
    -  = [ Pair lhs_arg rhs_arg | (True, lhs_arg, rhs_arg) <- zip3 inj_args lhs_args rhs_args ]
    
    3235
    -
    
    3236
    ----------------------------------------------
    
    3237
    -improveLocalFunEqs :: InertCans
    
    3238
    -                   -> TyCon -> [TcType] -> EqCt   -- F args ~ rhs
    
    3239
    -                   -> TcS Bool
    
    3240
    --- Emit equalities from interaction between two equalities
    
    3241
    -improveLocalFunEqs inerts fam_tc args (EqCt { eq_ev = work_ev, eq_rhs = rhs })
    
    3242
    -  | isGiven work_ev = improveGivenLocalFunEqs  funeqs_for_tc fam_tc args work_ev rhs
    
    3243
    -  | otherwise       = improveWantedLocalFunEqs funeqs_for_tc fam_tc args work_ev rhs
    
    3244
    -  where
    
    3245
    -    funeqs = inert_funeqs inerts
    
    3246
    -    funeqs_for_tc :: [EqCt]   -- Mixture of Given and Wanted
    
    3247
    -    funeqs_for_tc = [ funeq_ct | equal_ct_list <- findFunEqsByTyCon funeqs fam_tc
    
    3248
    -                               , funeq_ct <- equal_ct_list
    
    3249
    -                               , NomEq == eq_eq_rel funeq_ct ]
    
    3250
    -                                  -- Representational equalities don't interact
    
    3251
    -                                  -- with type family dependencies
    
    3252
    -
    
    3253
    -
    
    3254
    -improveGivenLocalFunEqs :: [EqCt]    -- Inert items, mixture of Given and Wanted
    
    3255
    -                        -> TyCon -> [TcType] -> CtEvidence -> Xi  -- Work item (Given)
    
    3256
    -                        -> TcS Bool  -- Always False (no unifications)
    
    3257
    --- Emit equalities from interaction between two Given type-family equalities
    
    3258
    ---    e.g.    (x+y1~z, x+y2~z) => (y1 ~ y2)
    
    3259
    -improveGivenLocalFunEqs funeqs_for_tc fam_tc work_args work_ev work_rhs
    
    3260
    -  | Just ops <- isBuiltInSynFamTyCon_maybe fam_tc
    
    3261
    -  = do { mapM_ (do_one ops) funeqs_for_tc
    
    3262
    -       ; return False }     -- False: no unifications
    
    3263
    -  | otherwise
    
    3264
    -  = return False
    
    3265
    -  where
    
    3266
    -    given_co :: Coercion = ctEvCoercion work_ev
    
    3267
    -
    
    3268
    -    do_one :: BuiltInSynFamily -> EqCt -> TcS ()
    
    3269
    -    -- Used only work-item is Given
    
    3270
    -    do_one ops EqCt { eq_ev  = inert_ev, eq_lhs = inert_lhs, eq_rhs = inert_rhs }
    
    3271
    -      | isGiven inert_ev                    -- Given/Given interaction
    
    3272
    -      , TyFamLHS _ inert_args <- inert_lhs  -- Inert item is F inert_args ~ inert_rhs
    
    3273
    -      , work_rhs `tcEqType` inert_rhs       -- Both RHSs are the same
    
    3274
    -      , -- So we have work_ev  : F work_args  ~ rhs
    
    3275
    -        --            inert_ev : F inert_args ~ rhs
    
    3276
    -        let pairs :: [(CoAxiomRule, TypeEqn)]
    
    3277
    -            pairs = tryInteractInertFam ops fam_tc work_args inert_args
    
    3278
    -      , not (null pairs)
    
    3279
    -      = do { traceTcS "improveGivenLocalFunEqs" (vcat[ ppr fam_tc <+> ppr work_args
    
    3280
    -                                                     , text "work_ev" <+>  ppr work_ev
    
    3281
    -                                                     , text "inert_ev" <+> ppr inert_ev
    
    3282
    -                                                     , ppr work_rhs
    
    3283
    -                                                     , ppr pairs ])
    
    3284
    -           ; emitNewGivens (ctEvLoc inert_ev) (map mk_ax_co pairs) }
    
    3285
    -             -- This CtLoc for the new Givens doesn't reflect the
    
    3286
    -             -- fact that it's a combination of Givens, but I don't
    
    3287
    -             -- this that matters.
    
    3288
    -      where
    
    3289
    -        inert_co = ctEvCoercion inert_ev
    
    3290
    -        mk_ax_co (ax,_) = (Nominal, mkAxiomCo ax [combined_co])
    
    3291
    -          where
    
    3292
    -            combined_co = given_co `mkTransCo` mkSymCo inert_co
    
    3293
    -            -- given_co :: F work_args  ~ rhs
    
    3294
    -            -- inert_co :: F inert_args ~ rhs
    
    3295
    -            -- the_co :: F work_args ~ F inert_args
    
    3296
    -
    
    3297
    -    do_one _  _ = return ()
    
    3298
    -
    
    3299
    -improveWantedLocalFunEqs
    
    3300
    -    :: [EqCt]     -- Inert items (Given and Wanted)
    
    3301
    -    -> TyCon -> [TcType] -> CtEvidence -> Xi  -- Work item (Wanted)
    
    3302
    -    -> TcS Bool   -- True <=> some unifications
    
    3303
    --- Emit improvement equalities for a Wanted constraint, by comparing
    
    3304
    --- the current work item with inert CFunEqs (both Given and Wanted)
    
    3305
    --- E.g.   x + y ~ z,   x + y' ~ z   =>   [W] y ~ y'
    
    3306
    ---
    
    3307
    --- See Note [FunDep and implicit parameter reactions]
    
    3308
    -improveWantedLocalFunEqs funeqs_for_tc fam_tc args work_ev rhs
    
    3309
    -  | null improvement_eqns
    
    3310
    -  = return False
    
    3311
    -  | otherwise
    
    3312
    -  = do { traceTcS "interactFunEq improvements: " $
    
    3313
    -                   vcat [ text "Eqns:" <+> ppr improvement_eqns
    
    3314
    -                        , text "Candidates:" <+> ppr funeqs_for_tc ]
    
    3315
    -       ; unifyAndEmitFunDepWanteds work_ev improvement_eqns }
    
    3316
    -  where
    
    3317
    -    work_loc      = ctEvLoc work_ev
    
    3318
    -    work_pred     = ctEvPred work_ev
    
    3319
    -    fam_inj_info  = tyConInjectivityInfo fam_tc
    
    3320
    -
    
    3321
    -    --------------------
    
    3322
    -    improvement_eqns :: [FunDepEqn (CtLoc, RewriterSet)]
    
    3323
    -    improvement_eqns
    
    3324
    -      | Just ops <- isBuiltInSynFamTyCon_maybe fam_tc
    
    3325
    -      =    -- Try built-in families, notably for arithmethic
    
    3326
    -        concatMap (do_one_built_in ops rhs) funeqs_for_tc
    
    3327
    -
    
    3328
    -      | Injective injective_args <- fam_inj_info
    
    3329
    -      =    -- Try improvement from type families with injectivity annotations
    
    3330
    -        concatMap (do_one_injective injective_args rhs) funeqs_for_tc
    
    3331
    -
    
    3332
    -      | otherwise
    
    3333
    -      = []
    
    3334
    -
    
    3335
    -    --------------------
    
    3336
    -    do_one_built_in ops rhs (EqCt { eq_lhs = TyFamLHS _ iargs, eq_rhs = irhs, eq_ev = inert_ev })
    
    3337
    -      | irhs `tcEqType` rhs
    
    3338
    -      = mk_fd_eqns inert_ev (map snd $ tryInteractInertFam ops fam_tc args iargs)
    
    3339
    -      | otherwise
    
    3340
    -      = []
    
    3341
    -    do_one_built_in _ _ _ = pprPanic "interactFunEq 1" (ppr fam_tc) -- TyVarLHS
    
    3342
    -
    
    3343
    -    --------------------
    
    3344
    -    -- See Note [Type inference for type families with injectivity]
    
    3345
    -    do_one_injective inj_args rhs (EqCt { eq_lhs = TyFamLHS _ inert_args
    
    3346
    -                                        , eq_rhs = irhs, eq_ev = inert_ev })
    
    3347
    -      | rhs `tcEqType` irhs
    
    3348
    -      = mk_fd_eqns inert_ev $ mkInjectivityEqns inj_args args inert_args
    
    3349
    -      | otherwise
    
    3350
    -      = []
    
    3351
    -
    
    3352
    -    do_one_injective _ _ _ = pprPanic "interactFunEq 2" (ppr fam_tc)  -- TyVarLHS
    
    3353
    -
    
    3354
    -    --------------------
    
    3355
    -    mk_fd_eqns :: CtEvidence -> [TypeEqn] -> [FunDepEqn (CtLoc, RewriterSet)]
    
    3356
    -    mk_fd_eqns inert_ev eqns
    
    3357
    -      | null eqns  = []
    
    3358
    -      | otherwise  = [ FDEqn { fd_qtvs = [], fd_eqs = eqns
    
    3359
    -                             , fd_loc   = (loc, inert_rewriters) } ]
    
    3360
    -      where
    
    3361
    -        initial_loc  -- start with the location of the Wanted involved
    
    3362
    -          | isGiven work_ev = inert_loc
    
    3363
    -          | otherwise       = work_loc
    
    3364
    -        eqn_orig        = InjTFOrigin1 work_pred  (ctLocOrigin work_loc)  (ctLocSpan work_loc)
    
    3365
    -                                       inert_pred (ctLocOrigin inert_loc) (ctLocSpan inert_loc)
    
    3366
    -        eqn_loc         = setCtLocOrigin initial_loc eqn_orig
    
    3367
    -        inert_pred      = ctEvPred inert_ev
    
    3368
    -        inert_loc       = ctEvLoc inert_ev
    
    3369
    -        inert_rewriters = ctEvRewriters inert_ev
    
    3370
    -        loc = eqn_loc { ctl_depth = ctl_depth inert_loc `maxSubGoalDepth`
    
    3371
    -                                    ctl_depth work_loc }
    
    3372
    -
    
    3373
    -{- Note [Type inference for type families with injectivity]
    
    3374
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3375
    -Suppose we have a type family with an injectivity annotation:
    
    3376
    -    type family F a b = r | r -> b
    
    3377
    -
    
    3378
    -Then if we have an equality like F s1 t1 ~ F s2 t2,
    
    3379
    -we can use the injectivity to get a new Wanted constraint on
    
    3380
    -the injective argument
    
    3381
    -  [W] t1 ~ t2
    
    3382
    -
    
    3383
    -That in turn can help GHC solve constraints that would otherwise require
    
    3384
    -guessing.  For example, consider the ambiguity check for
    
    3385
    -   f :: F Int b -> Int
    
    3386
    -We get the constraint
    
    3387
    -   [W] F Int b ~ F Int beta
    
    3388
    -where beta is a unification variable.  Injectivity lets us pick beta ~ b.
    
    3389
    -
    
    3390
    -Injectivity information is also used at the call sites. For example:
    
    3391
    -   g = f True
    
    3392
    -gives rise to
    
    3393
    -   [W] F Int b ~ Bool
    
    3394
    -from which we can derive b.  This requires looking at the defining equations of
    
    3395
    -a type family, ie. finding equation with a matching RHS (Bool in this example)
    
    3396
    -and inferring values of type variables (b in this example) from the LHS patterns
    
    3397
    -of the matching equation.  For closed type families we have to perform
    
    3398
    -additional apartness check for the selected equation to check that the selected
    
    3399
    -is guaranteed to fire for given LHS arguments.
    
    3400
    -
    
    3401
    -These new constraints are Wanted constraints, but we will not use the evidence.
    
    3402
    -We could go further and offer evidence from decomposing injective type-function
    
    3403
    -applications, but that would require new evidence forms, and an extension to
    
    3404
    -FC, so we don't do that right now (Dec 14).
    
    3405
    -
    
    3406
    -We generate these Wanteds in three places, depending on how we notice the
    
    3407
    -injectivity.
    
    3408
    -
    
    3409
    -1. When we have a [W] F tys1 ~ F tys2. This is handled in canEqCanLHS2, and
    
    3410
    -described in Note [Decomposing type family applications] in GHC.Tc.Solver.Equality
    
    3411
    -
    
    3412
    -2. When we have [W] F tys1 ~ T and [W] F tys2 ~ T. Note that neither of these
    
    3413
    -constraints rewrites the other, as they have different LHSs. This is done
    
    3414
    -in improveLocalFunEqs, called during the interactWithInertsStage.
    
    3415
    -
    
    3416
    -3. When we have [W] F tys ~ T and an equation for F that looks like F tys' = T.
    
    3417
    -This is done in improve_top_fun_eqs, called from the top-level reactions stage.
    
    3418
    -
    
    3419
    -See also Note [Injective type families] in GHC.Core.TyCon
    
    3420
    -
    
    3421
    -Note [Cache-caused loops]
    
    3422
    -~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3423
    -It is very dangerous to cache a rewritten wanted family equation as 'solved' in our
    
    3424
    -solved cache (which is the default behaviour or xCtEvidence), because the interaction
    
    3425
    -may not be contributing towards a solution. Here is an example:
    
    3426
    -
    
    3427
    -Initial inert set:
    
    3428
    -  [W] g1 : F a ~ beta1
    
    3429
    -Work item:
    
    3430
    -  [W] g2 : F a ~ beta2
    
    3431
    -The work item will react with the inert yielding the _same_ inert set plus:
    
    3432
    -    (i)   Will set g2 := g1 `cast` g3
    
    3433
    -    (ii)  Will add to our solved cache that [S] g2 : F a ~ beta2
    
    3434
    -    (iii) Will emit [W] g3 : beta1 ~ beta2
    
    3435
    -Now, the g3 work item will be spontaneously solved to [G] g3 : beta1 ~ beta2
    
    3436
    -and then it will react the item in the inert ([W] g1 : F a ~ beta1). So it
    
    3437
    -will set
    
    3438
    -      g1 := g ; sym g3
    
    3439
    -and what is g? Well it would ideally be a new goal of type (F a ~ beta2) but
    
    3440
    -remember that we have this in our solved cache, and it is ... g2! In short we
    
    3441
    -created the evidence loop:
    
    3442
    -
    
    3443
    -        g2 := g1 ; g3
    
    3444
    -        g3 := refl
    
    3445
    -        g1 := g2 ; sym g3
    
    3446
    -
    
    3447
    -To avoid this situation we do not cache as solved any workitems (or inert)
    
    3448
    -which did not really made a 'step' towards proving some goal. Solved's are
    
    3449
    -just an optimization so we don't lose anything in terms of completeness of
    
    3450
    -solving.
    
    3451
    --}

  • compiler/GHC/Tc/Solver/FunDeps.hs
    ... ... @@ -4,7 +4,8 @@
    4 4
     -- | Solving Class constraints CDictCan
    
    5 5
     module GHC.Tc.Solver.FunDeps (
    
    6 6
       unifyAndEmitFunDepWanteds,
    
    7
    -  doDictFunDepImprovement,
    
    7
    +  tryDictFunDeps,
    
    8
    +  tryEqFunDeps
    
    8 9
       ) where
    
    9 10
     
    
    10 11
     import GHC.Prelude
    
    ... ... @@ -12,25 +13,34 @@ import GHC.Prelude
    12 13
     import {-# SOURCE #-} GHC.Tc.Solver.Solve( solveSimpleWanteds )
    
    13 14
     
    
    14 15
     import GHC.Tc.Instance.FunDeps
    
    15
    -import GHC.Tc.Types.Evidence
    
    16
    -import GHC.Tc.Types.Constraint
    
    17
    -import GHC.Tc.Types.CtLoc
    
    18
    -import GHC.Tc.Types.Origin
    
    19 16
     import GHC.Tc.Solver.InertSet
    
    20 17
     import GHC.Tc.Solver.Monad
    
    21 18
     import GHC.Tc.Solver.Types
    
    22 19
     import GHC.Tc.Utils.TcType
    
    23 20
     import GHC.Tc.Utils.Unify( UnifyEnv(..) )
    
    24 21
     import GHC.Tc.Utils.Monad    as TcM
    
    22
    +import GHC.Tc.Types.Evidence
    
    23
    +import GHC.Tc.Types.Constraint
    
    24
    +import GHC.Tc.Types.CtLoc
    
    25
    +import GHC.Tc.Types.Origin
    
    25 26
     
    
    26 27
     import GHC.Core.Type
    
    27
    -import GHC.Core.InstEnv     ( ClsInst(..) )
    
    28
    -import GHC.Core.Coercion.Axiom( TypeEqn )
    
    29
    -
    
    28
    +import GHC.Core.FamInstEnv
    
    29
    +import GHC.Core.Coercion
    
    30
    +import GHC.Core.Predicate( EqRel(..) )
    
    31
    +import GHC.Core.TyCon
    
    32
    +import GHC.Core.Unify( tcUnifyTyForInjectivity )
    
    33
    +import GHC.Core.InstEnv( ClsInst(..) )
    
    34
    +import GHC.Core.Coercion.Axiom
    
    35
    +
    
    36
    +import GHC.Builtin.Types.Literals( tryInteractTopFam, tryInteractInertFam )
    
    30 37
     import GHC.Types.Name
    
    31 38
     import GHC.Types.Var.Set
    
    39
    +import GHC.Types.Var.Env
    
    32 40
     
    
    33 41
     import GHC.Utils.Outputable
    
    42
    +import GHC.Utils.Panic
    
    43
    +import GHC.Utils.Misc( filterOut )
    
    34 44
     
    
    35 45
     import GHC.Data.Bag
    
    36 46
     import GHC.Data.Pair
    
    ... ... @@ -41,7 +51,7 @@ import Control.Monad
    41 51
     
    
    42 52
     {- *********************************************************************
    
    43 53
     *                                                                      *
    
    44
    -*          Functional dependencies, instantiation of equations
    
    54
    +*          Functional dependencies for dictionaries
    
    45 55
     *                                                                      *
    
    46 56
     ************************************************************************
    
    47 57
     
    
    ... ... @@ -296,24 +306,24 @@ as the fundeps.
    296 306
     #7875 is a case in point.
    
    297 307
     -}
    
    298 308
     
    
    299
    -doDictFunDepImprovement :: DictCt -> SolverStage ()
    
    300
    --- (doDictFunDepImprovement inst_envs cts)
    
    309
    +tryDictFunDeps :: DictCt -> SolverStage ()
    
    310
    +-- (tryDictFunDeps inst_envs cts)
    
    301 311
     --   * Generate the fundeps from interacting the
    
    302 312
     --     top-level `inst_envs` with the constraints `cts`
    
    303 313
     --   * Do the unifications and return any unsolved constraints
    
    304 314
     -- See Note [Fundeps with instances, and equality orientation]
    
    305 315
     
    
    306
    --- doLocalFunDepImprovement does StartAgain if there
    
    316
    +-- doLocalFunDeps does StartAgain if there
    
    307 317
     -- are any fundeps: see (DFL1) in Note [Do fundeps last]
    
    308 318
     
    
    309
    -doDictFunDepImprovement dict_ct
    
    310
    -  = do { doDictFunDepImprovementLocal dict_ct
    
    311
    -       ; doDictFunDepImprovementTop   dict_ct }
    
    319
    +tryDictFunDeps dict_ct
    
    320
    +  = do { tryDictFunDepsLocal dict_ct
    
    321
    +       ; tryDictFunDepsTop   dict_ct }
    
    312 322
     
    
    313
    -doDictFunDepImprovementLocal :: DictCt -> SolverStage ()
    
    323
    +tryDictFunDepsLocal :: DictCt -> SolverStage ()
    
    314 324
     -- Using functional dependencies, interact the DictCt with the
    
    315 325
     -- inert Givens and Wanteds, to produce new equalities
    
    316
    -doDictFunDepImprovementLocal dict_ct@(DictCt { di_cls = cls, di_ev = work_ev })
    
    326
    +tryDictFunDepsLocal dict_ct@(DictCt { di_cls = cls, di_ev = work_ev })
    
    317 327
       | isGiven work_ev
    
    318 328
       = -- If work_ev is Given, there could in principle be some inert Wanteds
    
    319 329
         -- but in practice there never are because we solve Givens first
    
    ... ... @@ -323,11 +333,11 @@ doDictFunDepImprovementLocal dict_ct@(DictCt { di_cls = cls, di_ev = work_ev })
    323 333
       = Stage $
    
    324 334
         do { inerts <- getInertCans
    
    325 335
     
    
    326
    -       ; traceTcS "doDictFunDepImprovementLocal {" (ppr dict_ct)
    
    336
    +       ; traceTcS "tryDictFunDepsLocal {" (ppr dict_ct)
    
    327 337
            ; imp <- solveFunDeps $
    
    328 338
                     foldM do_interaction emptyCts $
    
    329 339
                     findDictsByClass (inert_dicts inerts) cls
    
    330
    -       ; traceTcS "doDictFunDepImprovementLocal }" (text "imp =" <+> ppr imp)
    
    340
    +       ; traceTcS "tryDictFunDepsLocal }" (text "imp =" <+> ppr imp)
    
    331 341
     
    
    332 342
            ; if imp then startAgainWith (CDictCan dict_ct)
    
    333 343
                     else continueWith () }
    
    ... ... @@ -350,7 +360,7 @@ doDictFunDepImprovementLocal dict_ct@(DictCt { di_cls = cls, di_ev = work_ev })
    350 360
                              improveFromAnother (deriv_loc, inert_rewriters)
    
    351 361
                                                 inert_pred work_pred
    
    352 362
     
    
    353
    -           ; traceTcS "doDictFunDepImprovementLocal item" $
    
    363
    +           ; traceTcS "tryDictFunDepsLocal item" $
    
    354 364
                  vcat [ ppr work_ev, ppr new_eqs2 ]
    
    355 365
     
    
    356 366
                ; return (new_eqs1 `unionBags` new_eqs2) }
    
    ... ... @@ -369,17 +379,17 @@ doDictFunDepImprovementLocal dict_ct@(DictCt { di_cls = cls, di_ev = work_ev })
    369 379
                                          (ctLocOrigin inert_loc)
    
    370 380
                                          (ctLocSpan inert_loc)
    
    371 381
     
    
    372
    -doDictFunDepImprovementTop :: DictCt -> SolverStage ()
    
    373
    -doDictFunDepImprovementTop dict_ct@(DictCt { di_ev = ev, di_cls = cls, di_tys = xis })
    
    382
    +tryDictFunDepsTop :: DictCt -> SolverStage ()
    
    383
    +tryDictFunDepsTop dict_ct@(DictCt { di_ev = ev, di_cls = cls, di_tys = xis })
    
    374 384
       = Stage $
    
    375 385
         do { inst_envs <- getInstEnvs
    
    376 386
     
    
    377
    -       ; traceTcS "doDictFunDepImprovementTop {" (ppr dict_ct)
    
    387
    +       ; traceTcS "tryDictFunDepsTop {" (ppr dict_ct)
    
    378 388
            ; let eqns :: [FunDepEqn (CtLoc, RewriterSet)]
    
    379 389
                  eqns = improveFromInstEnv inst_envs mk_ct_loc cls xis
    
    380 390
            ; imp <- solveFunDeps $
    
    381 391
                     unifyFunDepWanteds_new ev eqns
    
    382
    -       ; traceTcS "doDictFunDepImprovementTop }" (text "imp =" <+> ppr imp)
    
    392
    +       ; traceTcS "tryDictFunDepsTop }" (text "imp =" <+> ppr imp)
    
    383 393
     
    
    384 394
            ; if imp then startAgainWith (CDictCan dict_ct)
    
    385 395
                     else continueWith () }
    
    ... ... @@ -469,6 +479,464 @@ The bottom line: since we have no evidence for them, we should ignore Given/Give
    469 479
     and Given/instance fundeps entirely.
    
    470 480
     -}
    
    471 481
     
    
    482
    +
    
    483
    +
    
    484
    +{-
    
    485
    +**********************************************************************
    
    486
    +*                                                                    *
    
    487
    +    Functional dependencies for type families
    
    488
    +*                                                                    *
    
    489
    +**********************************************************************
    
    490
    +
    
    491
    +Note [Reverse order of fundep equations]
    
    492
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    493
    +Consider this scenario (from dependent/should_fail/T13135_simple):
    
    494
    +
    
    495
    +  type Sig :: Type -> Type
    
    496
    +  data Sig a = SigFun a (Sig a)
    
    497
    +
    
    498
    +  type SmartFun :: forall (t :: Type). Sig t -> Type
    
    499
    +  type family SmartFun sig = r | r -> sig where
    
    500
    +    SmartFun @Type (SigFun @Type a sig) = a -> SmartFun @Type sig
    
    501
    +
    
    502
    +  [W] SmartFun @kappa sigma ~ (Int -> Bool)
    
    503
    +
    
    504
    +The injectivity of SmartFun allows us to produce two new equalities:
    
    505
    +
    
    506
    +  [W] w1 :: Type ~ kappa
    
    507
    +  [W] w2 :: SigFun @Type Int beta ~ sigma
    
    508
    +
    
    509
    +for some fresh (beta :: SigType). The second Wanted here is actually
    
    510
    +heterogeneous: the LHS has type Sig Type while the RHS has type Sig kappa.
    
    511
    +Of course, if we solve the first wanted first, the second becomes homogeneous.
    
    512
    +
    
    513
    +When looking for injectivity-inspired equalities, we work left-to-right,
    
    514
    +producing the two equalities in the order written above. However, these
    
    515
    +equalities are then passed into wrapUnifierTcS, which will fail, adding these
    
    516
    +to the work list. However, crucially, the work list operates like a *stack*.
    
    517
    +So, because we add w1 and then w2, we process w2 first. This is silly: solving
    
    518
    +w1 would unlock w2. So we make sure to add equalities to the work
    
    519
    +list in left-to-right order, which requires a few key calls to 'reverse'.
    
    520
    +
    
    521
    +This treatment is also used for class-based functional dependencies, although
    
    522
    +we do not have a program yet known to exhibit a loop there. It just seems
    
    523
    +like the right thing to do.
    
    524
    +
    
    525
    +When this was originally conceived, it was necessary to avoid a loop in T13135.
    
    526
    +That loop is now avoided by continuing with the kind equality (not the type
    
    527
    +equality) in canEqCanLHSHetero (see Note [Equalities with heterogeneous kinds]).
    
    528
    +However, the idea of working left-to-right still seems worthwhile, and so the calls
    
    529
    +to 'reverse' remain.
    
    530
    +
    
    531
    +Note [Improvement orientation]
    
    532
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    533
    +See also Note [Fundeps with instances, and equality orientation], which describes
    
    534
    +the Exact Same Problem, with the same solution, but for functional dependencies.
    
    535
    +
    
    536
    +A very delicate point is the orientation of equalities
    
    537
    +arising from injectivity improvement (#12522).  Suppose we have
    
    538
    +  type family F x = t | t -> x
    
    539
    +  type instance F (a, Int) = (Int, G a)
    
    540
    +where G is injective; and wanted constraints
    
    541
    +
    
    542
    +  [W] F (alpha, beta) ~ (Int, <some type>)
    
    543
    +
    
    544
    +The injectivity will give rise to constraints
    
    545
    +
    
    546
    +  [W] gamma1 ~ alpha
    
    547
    +  [W] Int ~ beta
    
    548
    +
    
    549
    +The fresh unification variable gamma1 comes from the fact that we
    
    550
    +can only do "partial improvement" here; see Section 5.2 of
    
    551
    +"Injective type families for Haskell" (HS'15).
    
    552
    +
    
    553
    +Now, it's very important to orient the equations this way round,
    
    554
    +so that the fresh unification variable will be eliminated in
    
    555
    +favour of alpha.  If we instead had
    
    556
    +   [W] alpha ~ gamma1
    
    557
    +then we would unify alpha := gamma1; and kick out the wanted
    
    558
    +constraint.  But when we substitute it back in, it'd look like
    
    559
    +   [W] F (gamma1, beta) ~ fuv
    
    560
    +and exactly the same thing would happen again!  Infinite loop.
    
    561
    +
    
    562
    +--->  ToDo: all this fragility has gone away!   Fix the Note! <---
    
    563
    +
    
    564
    +This all seems fragile, and it might seem more robust to avoid
    
    565
    +introducing gamma1 in the first place, in the case where the
    
    566
    +actual argument (alpha, beta) partly matches the improvement
    
    567
    +template.  But that's a bit tricky, esp when we remember that the
    
    568
    +kinds much match too; so it's easier to let the normal machinery
    
    569
    +handle it.  Instead we are careful to orient the new
    
    570
    +equality with the template on the left.  Delicate, but it works.
    
    571
    +
    
    572
    +-}
    
    573
    +
    
    574
    +--------------------
    
    575
    +tryEqFunDeps :: EqCt -> SolverStage ()
    
    576
    +tryEqFunDeps work_item@(EqCt { eq_lhs = lhs, eq_eq_rel = eq_rel })
    
    577
    +  | NomEq <- eq_rel
    
    578
    +  , TyFamLHS tc args <- lhs
    
    579
    +  = do { improveLocalFunEqs tc args work_item
    
    580
    +       ; improveTopFunEqs   tc args work_item }
    
    581
    +  | otherwise
    
    582
    +  = nopStage ()
    
    583
    +
    
    584
    +--------------------
    
    585
    +improveTopFunEqs :: TyCon -> [TcType] -> EqCt -> SolverStage ()
    
    586
    +-- TyCon is definitely a type family
    
    587
    +-- See Note [FunDep and implicit parameter reactions]
    
    588
    +improveTopFunEqs fam_tc args eq_ct@(EqCt { eq_ev = ev, eq_rhs = rhs_ty })
    
    589
    +  = Stage $
    
    590
    +    do { imp <- if isGiven ev
    
    591
    +                then improveGivenTopFunEqs  fam_tc args ev rhs_ty
    
    592
    +                else improveWantedTopFunEqs fam_tc args ev rhs_ty
    
    593
    +       ; if imp then startAgainWith (CEqCan eq_ct)
    
    594
    +                else continueWith () }
    
    595
    +
    
    596
    +improveGivenTopFunEqs :: TyCon -> [TcType] -> CtEvidence -> Xi -> TcS Bool
    
    597
    +-- TyCon is definitely a type family
    
    598
    +-- Work-item is a Given
    
    599
    +improveGivenTopFunEqs fam_tc args ev rhs_ty
    
    600
    +  | Just ops <- isBuiltInSynFamTyCon_maybe fam_tc
    
    601
    +  = do { traceTcS "improveGivenTopFunEqs" (ppr fam_tc <+> ppr args $$ ppr ev $$ ppr rhs_ty)
    
    602
    +       ; emitNewGivens (ctEvLoc ev) $
    
    603
    +           [ (Nominal, new_co)
    
    604
    +           | (ax, _) <- tryInteractTopFam ops fam_tc args rhs_ty
    
    605
    +           , let new_co = mkAxiomCo ax [given_co] ]
    
    606
    +       ; return False }  -- False: no unifications
    
    607
    +  | otherwise
    
    608
    +  = return False
    
    609
    +  where
    
    610
    +    given_co :: Coercion = ctEvCoercion ev
    
    611
    +
    
    612
    +improveWantedTopFunEqs :: TyCon -> [TcType] -> CtEvidence -> Xi -> TcS Bool
    
    613
    +-- TyCon is definitely a type family
    
    614
    +-- Work-item is a Wanted
    
    615
    +improveWantedTopFunEqs fam_tc args ev rhs_ty
    
    616
    +  = do { eqns <- improve_wanted_top_fun_eqs fam_tc args rhs_ty
    
    617
    +       ; traceTcS "improveTopFunEqs" (vcat [ text "lhs:" <+> ppr fam_tc <+> ppr args
    
    618
    +                                           , text "rhs:" <+> ppr rhs_ty
    
    619
    +                                           , text "eqns:" <+> ppr eqns ])
    
    620
    +       ; unifyFunDeps ev Nominal $ \uenv ->
    
    621
    +         uPairsTcM (bump_depth uenv) (reverse eqns) }
    
    622
    +         -- Missing that `reverse` causes T13135 and T13135_simple to loop.
    
    623
    +         -- See Note [Reverse order of fundep equations]
    
    624
    +
    
    625
    +  where
    
    626
    +    bump_depth env = env { u_loc = bumpCtLocDepth (u_loc env) }
    
    627
    +        -- ToDo: this location is wrong; it should be FunDepOrigin2
    
    628
    +        -- See #14778
    
    629
    +
    
    630
    +improve_wanted_top_fun_eqs :: TyCon -> [TcType] -> Xi
    
    631
    +                           -> TcS [TypeEqn]
    
    632
    +-- TyCon is definitely a type family
    
    633
    +improve_wanted_top_fun_eqs fam_tc lhs_tys rhs_ty
    
    634
    +  | Just ops <- isBuiltInSynFamTyCon_maybe fam_tc
    
    635
    +  = return (map snd $ tryInteractTopFam ops fam_tc lhs_tys rhs_ty)
    
    636
    +
    
    637
    +  -- ToDo: use ideas in #23162 for closed type families; injectivity only for open
    
    638
    +
    
    639
    +  -- See Note [Type inference for type families with injectivity]
    
    640
    +  -- Open, so look for inj
    
    641
    +  | Injective inj_args <- tyConInjectivityInfo fam_tc
    
    642
    +  = do { fam_envs <- getFamInstEnvs
    
    643
    +       ; top_eqns <- improve_injective_wanted_top fam_envs inj_args fam_tc lhs_tys rhs_ty
    
    644
    +       ; let local_eqns = improve_injective_wanted_famfam  inj_args fam_tc lhs_tys rhs_ty
    
    645
    +       ; traceTcS "improve_wanted_top_fun_eqs" $
    
    646
    +         vcat [ ppr fam_tc, text "local_eqns" <+> ppr local_eqns, text "top_eqns" <+> ppr top_eqns ]
    
    647
    +  -- xxx ToDo: this does both local and top => bug?
    
    648
    +       ; return (local_eqns ++ top_eqns) }
    
    649
    +
    
    650
    +  | otherwise  -- No injectivity
    
    651
    +  = return []
    
    652
    +
    
    653
    +improve_injective_wanted_top :: FamInstEnvs -> [Bool] -> TyCon -> [TcType] -> Xi -> TcS [TypeEqn]
    
    654
    +-- Interact with top-level instance declarations
    
    655
    +-- See Section 5.2 in the Injective Type Families paper
    
    656
    +improve_injective_wanted_top fam_envs inj_args fam_tc lhs_tys rhs_ty
    
    657
    +  = concatMapM do_one branches
    
    658
    +  where
    
    659
    +    branches :: [CoAxBranch]
    
    660
    +    branches | isOpenTypeFamilyTyCon fam_tc
    
    661
    +             , let fam_insts = lookupFamInstEnvByTyCon fam_envs fam_tc
    
    662
    +             = concatMap (fromBranches . coAxiomBranches . fi_axiom) fam_insts
    
    663
    +
    
    664
    +             | Just ax <- isClosedSynFamilyTyConWithAxiom_maybe fam_tc
    
    665
    +             = fromBranches (coAxiomBranches ax)
    
    666
    +
    
    667
    +             | otherwise
    
    668
    +             = []
    
    669
    +
    
    670
    +    do_one :: CoAxBranch -> TcS [TypeEqn]
    
    671
    +    do_one branch@(CoAxBranch { cab_tvs = branch_tvs, cab_lhs = branch_lhs_tys, cab_rhs = branch_rhs })
    
    672
    +      | let in_scope1 = in_scope `extendInScopeSetList` branch_tvs
    
    673
    +      , Just subst <- tcUnifyTyForInjectivity False in_scope1 branch_rhs rhs_ty
    
    674
    +                      -- False: matching, not unifying
    
    675
    +      = do { let inSubst tv = tv `elemVarEnv` getTvSubstEnv subst
    
    676
    +                 unsubstTvs = filterOut inSubst branch_tvs
    
    677
    +                 -- The order of unsubstTvs is important; it must be
    
    678
    +                 -- in telescope order e.g. (k:*) (a:k)
    
    679
    +
    
    680
    +           ; (_subst_tvs, subst1) <- instFlexiX subst unsubstTvs
    
    681
    +                -- If the current substitution bind [k -> *], and
    
    682
    +                -- one of the un-substituted tyvars is (a::k), we'd better
    
    683
    +                -- be sure to apply the current substitution to a's kind.
    
    684
    +                -- Hence instFlexiX.   #13135 was an example.
    
    685
    +
    
    686
    +           ; traceTcS "improve_inj_top" $
    
    687
    +             vcat [ text "branch_rhs" <+> ppr branch_rhs
    
    688
    +                  , text "rhs_ty" <+> ppr rhs_ty
    
    689
    +                  , text "subst" <+> ppr subst
    
    690
    +                  , text "subst1" <+> ppr subst1 ]
    
    691
    +           ; if apartnessCheck (substTys subst1 branch_lhs_tys) branch
    
    692
    +             then do { traceTcS "improv_inj_top1" (ppr branch_lhs_tys)
    
    693
    +                     ; return (mkInjectivityEqns inj_args (map (substTy subst1) branch_lhs_tys) lhs_tys) }
    
    694
    +                  -- NB: The fresh unification variables (from unsubstTvs) are on the left
    
    695
    +                  --     See Note [Improvement orientation]
    
    696
    +             else do { traceTcS "improve_inj_top2" empty; return []  } }
    
    697
    +      | otherwise
    
    698
    +      = do { traceTcS "improve_inj_top:fail" (ppr branch_rhs $$ ppr rhs_ty $$ ppr in_scope $$ ppr branch_tvs)
    
    699
    +           ; return [] }
    
    700
    +
    
    701
    +    in_scope = mkInScopeSet (tyCoVarsOfType rhs_ty)
    
    702
    +
    
    703
    +
    
    704
    +improve_injective_wanted_famfam :: [Bool] -> TyCon -> [TcType] -> Xi -> [TypeEqn]
    
    705
    +-- Interact with itself, specifically  F s1 s2 ~ F t1 t2
    
    706
    +improve_injective_wanted_famfam inj_args fam_tc lhs_tys rhs_ty
    
    707
    +  | Just (tc, rhs_tys) <- tcSplitTyConApp_maybe rhs_ty
    
    708
    +  , tc == fam_tc
    
    709
    +  = mkInjectivityEqns inj_args lhs_tys rhs_tys
    
    710
    +  | otherwise
    
    711
    +  = []
    
    712
    +
    
    713
    +mkInjectivityEqns :: [Bool] -> [TcType] -> [TcType] -> [TypeEqn]
    
    714
    +-- When F s1 s2 s3 ~ F t1 t2 t3, and F has injectivity info [True,False,True]
    
    715
    +-- return the equations [Pair s1 t1, Pair s3 t3]
    
    716
    +mkInjectivityEqns inj_args lhs_args rhs_args
    
    717
    +  = [ Pair lhs_arg rhs_arg | (True, lhs_arg, rhs_arg) <- zip3 inj_args lhs_args rhs_args ]
    
    718
    +
    
    719
    +---------------------------------------------
    
    720
    +improveLocalFunEqs :: TyCon -> [TcType] -> EqCt   -- F args ~ rhs
    
    721
    +                   -> SolverStage ()
    
    722
    +-- Emit equalities from interaction between two equalities
    
    723
    +improveLocalFunEqs fam_tc args eq_ct@(EqCt { eq_ev = work_ev, eq_rhs = rhs })
    
    724
    +  = Stage $
    
    725
    +    do { inerts <- getInertCans
    
    726
    +       ; let my_funeqs = get_my_funeqs inerts
    
    727
    +       ; imp <- if isGiven work_ev
    
    728
    +                then improveGivenLocalFunEqs  my_funeqs fam_tc args work_ev rhs
    
    729
    +                else improveWantedLocalFunEqs my_funeqs fam_tc args work_ev rhs
    
    730
    +       ; if imp then startAgainWith (CEqCan eq_ct)
    
    731
    +                else continueWith () }
    
    732
    +  where
    
    733
    +    get_my_funeqs :: InertCans -> [EqCt]   -- Mixture of Given and Wanted
    
    734
    +    get_my_funeqs (IC { inert_funeqs = funeqs })
    
    735
    +      = [ funeq_ct | equal_ct_list <- findFunEqsByTyCon funeqs fam_tc
    
    736
    +                   , funeq_ct <- equal_ct_list
    
    737
    +                   , NomEq == eq_eq_rel funeq_ct ]
    
    738
    +                      -- Representational equalities don't interact
    
    739
    +                      -- with type family dependencies
    
    740
    +
    
    741
    +improveGivenLocalFunEqs :: [EqCt]    -- Inert items, mixture of Given and Wanted
    
    742
    +                        -> TyCon -> [TcType] -> CtEvidence -> Xi  -- Work item (Given)
    
    743
    +                        -> TcS Bool  -- Always False (no unifications)
    
    744
    +-- Emit equalities from interaction between two Given type-family equalities
    
    745
    +--    e.g.    (x+y1~z, x+y2~z) => (y1 ~ y2)
    
    746
    +improveGivenLocalFunEqs funeqs_for_tc fam_tc work_args work_ev work_rhs
    
    747
    +  | Just ops <- isBuiltInSynFamTyCon_maybe fam_tc
    
    748
    +  = do { mapM_ (do_one ops) funeqs_for_tc
    
    749
    +       ; return False }     -- False: no unifications
    
    750
    +  | otherwise
    
    751
    +  = return False
    
    752
    +  where
    
    753
    +    given_co :: Coercion = ctEvCoercion work_ev
    
    754
    +
    
    755
    +    do_one :: BuiltInSynFamily -> EqCt -> TcS ()
    
    756
    +    -- Used only work-item is Given
    
    757
    +    do_one ops EqCt { eq_ev  = inert_ev, eq_lhs = inert_lhs, eq_rhs = inert_rhs }
    
    758
    +      | isGiven inert_ev                    -- Given/Given interaction
    
    759
    +      , TyFamLHS _ inert_args <- inert_lhs  -- Inert item is F inert_args ~ inert_rhs
    
    760
    +      , work_rhs `tcEqType` inert_rhs       -- Both RHSs are the same
    
    761
    +      , -- So we have work_ev  : F work_args  ~ rhs
    
    762
    +        --            inert_ev : F inert_args ~ rhs
    
    763
    +        let pairs :: [(CoAxiomRule, TypeEqn)]
    
    764
    +            pairs = tryInteractInertFam ops fam_tc work_args inert_args
    
    765
    +      , not (null pairs)
    
    766
    +      = do { traceTcS "improveGivenLocalFunEqs" (vcat[ ppr fam_tc <+> ppr work_args
    
    767
    +                                                     , text "work_ev" <+>  ppr work_ev
    
    768
    +                                                     , text "inert_ev" <+> ppr inert_ev
    
    769
    +                                                     , ppr work_rhs
    
    770
    +                                                     , ppr pairs ])
    
    771
    +           ; emitNewGivens (ctEvLoc inert_ev) (map mk_ax_co pairs) }
    
    772
    +             -- This CtLoc for the new Givens doesn't reflect the
    
    773
    +             -- fact that it's a combination of Givens, but I don't
    
    774
    +             -- this that matters.
    
    775
    +      where
    
    776
    +        inert_co = ctEvCoercion inert_ev
    
    777
    +        mk_ax_co (ax,_) = (Nominal, mkAxiomCo ax [combined_co])
    
    778
    +          where
    
    779
    +            combined_co = given_co `mkTransCo` mkSymCo inert_co
    
    780
    +            -- given_co :: F work_args  ~ rhs
    
    781
    +            -- inert_co :: F inert_args ~ rhs
    
    782
    +            -- the_co :: F work_args ~ F inert_args
    
    783
    +
    
    784
    +    do_one _  _ = return ()
    
    785
    +
    
    786
    +improveWantedLocalFunEqs
    
    787
    +    :: [EqCt]     -- Inert items (Given and Wanted)
    
    788
    +    -> TyCon -> [TcType] -> CtEvidence -> Xi  -- Work item (Wanted)
    
    789
    +    -> TcS Bool   -- True <=> some unifications
    
    790
    +-- Emit improvement equalities for a Wanted constraint, by comparing
    
    791
    +-- the current work item with inert CFunEqs (both Given and Wanted)
    
    792
    +-- E.g.   x + y ~ z,   x + y' ~ z   =>   [W] y ~ y'
    
    793
    +--
    
    794
    +-- See Note [FunDep and implicit parameter reactions]
    
    795
    +improveWantedLocalFunEqs funeqs_for_tc fam_tc args work_ev rhs
    
    796
    +  | null improvement_eqns
    
    797
    +  = return False
    
    798
    +  | otherwise
    
    799
    +  = do { traceTcS "interactFunEq improvements: " $
    
    800
    +                   vcat [ text "Eqns:" <+> ppr improvement_eqns
    
    801
    +                        , text "Candidates:" <+> ppr funeqs_for_tc ]
    
    802
    +       ; unifyAndEmitFunDepWanteds work_ev improvement_eqns }
    
    803
    +  where
    
    804
    +    work_loc      = ctEvLoc work_ev
    
    805
    +    work_pred     = ctEvPred work_ev
    
    806
    +    fam_inj_info  = tyConInjectivityInfo fam_tc
    
    807
    +
    
    808
    +    --------------------
    
    809
    +    improvement_eqns :: [FunDepEqn (CtLoc, RewriterSet)]
    
    810
    +    improvement_eqns
    
    811
    +      | Just ops <- isBuiltInSynFamTyCon_maybe fam_tc
    
    812
    +      =    -- Try built-in families, notably for arithmethic
    
    813
    +        concatMap (do_one_built_in ops rhs) funeqs_for_tc
    
    814
    +
    
    815
    +      | Injective injective_args <- fam_inj_info
    
    816
    +      =    -- Try improvement from type families with injectivity annotations
    
    817
    +        concatMap (do_one_injective injective_args rhs) funeqs_for_tc
    
    818
    +
    
    819
    +      | otherwise
    
    820
    +      = []
    
    821
    +
    
    822
    +    --------------------
    
    823
    +    do_one_built_in ops rhs (EqCt { eq_lhs = TyFamLHS _ iargs, eq_rhs = irhs, eq_ev = inert_ev })
    
    824
    +      | irhs `tcEqType` rhs
    
    825
    +      = mk_fd_eqns inert_ev (map snd $ tryInteractInertFam ops fam_tc args iargs)
    
    826
    +      | otherwise
    
    827
    +      = []
    
    828
    +    do_one_built_in _ _ _ = pprPanic "interactFunEq 1" (ppr fam_tc) -- TyVarLHS
    
    829
    +
    
    830
    +    --------------------
    
    831
    +    -- See Note [Type inference for type families with injectivity]
    
    832
    +    do_one_injective inj_args rhs (EqCt { eq_lhs = TyFamLHS _ inert_args
    
    833
    +                                        , eq_rhs = irhs, eq_ev = inert_ev })
    
    834
    +      | rhs `tcEqType` irhs
    
    835
    +      = mk_fd_eqns inert_ev $ mkInjectivityEqns inj_args args inert_args
    
    836
    +      | otherwise
    
    837
    +      = []
    
    838
    +
    
    839
    +    do_one_injective _ _ _ = pprPanic "interactFunEq 2" (ppr fam_tc)  -- TyVarLHS
    
    840
    +
    
    841
    +    --------------------
    
    842
    +    mk_fd_eqns :: CtEvidence -> [TypeEqn] -> [FunDepEqn (CtLoc, RewriterSet)]
    
    843
    +    mk_fd_eqns inert_ev eqns
    
    844
    +      | null eqns  = []
    
    845
    +      | otherwise  = [ FDEqn { fd_qtvs = [], fd_eqs = eqns
    
    846
    +                             , fd_loc   = (loc, inert_rewriters) } ]
    
    847
    +      where
    
    848
    +        initial_loc  -- start with the location of the Wanted involved
    
    849
    +          | isGiven work_ev = inert_loc
    
    850
    +          | otherwise       = work_loc
    
    851
    +        eqn_orig        = InjTFOrigin1 work_pred  (ctLocOrigin work_loc)  (ctLocSpan work_loc)
    
    852
    +                                       inert_pred (ctLocOrigin inert_loc) (ctLocSpan inert_loc)
    
    853
    +        eqn_loc         = setCtLocOrigin initial_loc eqn_orig
    
    854
    +        inert_pred      = ctEvPred inert_ev
    
    855
    +        inert_loc       = ctEvLoc inert_ev
    
    856
    +        inert_rewriters = ctEvRewriters inert_ev
    
    857
    +        loc = eqn_loc { ctl_depth = ctl_depth inert_loc `maxSubGoalDepth`
    
    858
    +                                    ctl_depth work_loc }
    
    859
    +
    
    860
    +{- Note [Type inference for type families with injectivity]
    
    861
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    862
    +Suppose we have a type family with an injectivity annotation:
    
    863
    +    type family F a b = r | r -> b
    
    864
    +
    
    865
    +Then if we have an equality like F s1 t1 ~ F s2 t2,
    
    866
    +we can use the injectivity to get a new Wanted constraint on
    
    867
    +the injective argument
    
    868
    +  [W] t1 ~ t2
    
    869
    +
    
    870
    +That in turn can help GHC solve constraints that would otherwise require
    
    871
    +guessing.  For example, consider the ambiguity check for
    
    872
    +   f :: F Int b -> Int
    
    873
    +We get the constraint
    
    874
    +   [W] F Int b ~ F Int beta
    
    875
    +where beta is a unification variable.  Injectivity lets us pick beta ~ b.
    
    876
    +
    
    877
    +Injectivity information is also used at the call sites. For example:
    
    878
    +   g = f True
    
    879
    +gives rise to
    
    880
    +   [W] F Int b ~ Bool
    
    881
    +from which we can derive b.  This requires looking at the defining equations of
    
    882
    +a type family, ie. finding equation with a matching RHS (Bool in this example)
    
    883
    +and inferring values of type variables (b in this example) from the LHS patterns
    
    884
    +of the matching equation.  For closed type families we have to perform
    
    885
    +additional apartness check for the selected equation to check that the selected
    
    886
    +is guaranteed to fire for given LHS arguments.
    
    887
    +
    
    888
    +These new constraints are Wanted constraints, but we will not use the evidence.
    
    889
    +We could go further and offer evidence from decomposing injective type-function
    
    890
    +applications, but that would require new evidence forms, and an extension to
    
    891
    +FC, so we don't do that right now (Dec 14).
    
    892
    +
    
    893
    +We generate these Wanteds in three places, depending on how we notice the
    
    894
    +injectivity.
    
    895
    +
    
    896
    +1. When we have a [W] F tys1 ~ F tys2. This is handled in canEqCanLHS2, and
    
    897
    +described in Note [Decomposing type family applications] in GHC.Tc.Solver.Equality
    
    898
    +
    
    899
    +2. When we have [W] F tys1 ~ T and [W] F tys2 ~ T. Note that neither of these
    
    900
    +constraints rewrites the other, as they have different LHSs. This is done
    
    901
    +in improveLocalFunEqs, called during the interactWithInertsStage.
    
    902
    +
    
    903
    +3. When we have [W] F tys ~ T and an equation for F that looks like F tys' = T.
    
    904
    +This is done in improve_top_fun_eqs, called from the top-level reactions stage.
    
    905
    +
    
    906
    +See also Note [Injective type families] in GHC.Core.TyCon
    
    907
    +
    
    908
    +Note [Cache-caused loops]
    
    909
    +~~~~~~~~~~~~~~~~~~~~~~~~~
    
    910
    +It is very dangerous to cache a rewritten wanted family equation as 'solved' in our
    
    911
    +solved cache (which is the default behaviour or xCtEvidence), because the interaction
    
    912
    +may not be contributing towards a solution. Here is an example:
    
    913
    +
    
    914
    +Initial inert set:
    
    915
    +  [W] g1 : F a ~ beta1
    
    916
    +Work item:
    
    917
    +  [W] g2 : F a ~ beta2
    
    918
    +The work item will react with the inert yielding the _same_ inert set plus:
    
    919
    +    (i)   Will set g2 := g1 `cast` g3
    
    920
    +    (ii)  Will add to our solved cache that [S] g2 : F a ~ beta2
    
    921
    +    (iii) Will emit [W] g3 : beta1 ~ beta2
    
    922
    +Now, the g3 work item will be spontaneously solved to [G] g3 : beta1 ~ beta2
    
    923
    +and then it will react the item in the inert ([W] g1 : F a ~ beta1). So it
    
    924
    +will set
    
    925
    +      g1 := g ; sym g3
    
    926
    +and what is g? Well it would ideally be a new goal of type (F a ~ beta2) but
    
    927
    +remember that we have this in our solved cache, and it is ... g2! In short we
    
    928
    +created the evidence loop:
    
    929
    +
    
    930
    +        g2 := g1 ; g3
    
    931
    +        g3 := refl
    
    932
    +        g1 := g2 ; sym g3
    
    933
    +
    
    934
    +To avoid this situation we do not cache as solved any workitems (or inert)
    
    935
    +which did not really made a 'step' towards proving some goal. Solved's are
    
    936
    +just an optimization so we don't lose anything in terms of completeness of
    
    937
    +solving.
    
    938
    +-}
    
    939
    +
    
    472 940
     {-
    
    473 941
     ************************************************************************
    
    474 942
     *                                                                      *
    

  • compiler/GHC/Tc/Solver/Monad.hs
    ... ... @@ -67,9 +67,6 @@ module GHC.Tc.Solver.Monad (
    67 67
         getTcEvTyCoVars, getTcEvBindsMap, setTcEvBindsMap,
    
    68 68
         tcLookupClass, tcLookupId, tcLookupTyCon,
    
    69 69
     
    
    70
    -    getUnifiedRef,
    
    71
    -
    
    72
    -
    
    73 70
         -- Inerts
    
    74 71
         updInertSet, updInertCans,
    
    75 72
         getHasGivenEqs, setInertCans,
    
    ... ... @@ -84,7 +81,7 @@ module GHC.Tc.Solver.Monad (
    84 81
         lookupInertDict,
    
    85 82
     
    
    86 83
         -- The Model
    
    87
    -    kickOutAfterUnification, kickOutRewritable,
    
    84
    +    recordUnification, recordUnifications, kickOutRewritable,
    
    88 85
     
    
    89 86
         -- Inert Safe Haskell safe-overlap failures
    
    90 87
         insertSafeOverlapFailureTcS,
    
    ... ... @@ -212,8 +209,6 @@ import Control.Monad
    212 209
     import Data.Foldable hiding ( foldr1 )
    
    213 210
     import Data.IORef
    
    214 211
     import Data.List ( mapAccumL )
    
    215
    -import Data.List.NonEmpty ( nonEmpty )
    
    216
    -import qualified Data.List.NonEmpty as NE
    
    217 212
     import GHC.Types.SrcLoc
    
    218 213
     import GHC.Rename.Env
    
    219 214
     import GHC.LanguageExtensions as LangExt
    
    ... ... @@ -450,33 +445,6 @@ kickOutRewritable ko_spec new_fr
    450 445
                              , text "kicked_out =" <+> ppr kicked_out
    
    451 446
                              , text "Residual inerts =" <+> ppr ics' ]) } }
    
    452 447
     
    
    453
    -kickOutAfterUnification :: [TcTyVar] -> TcS ()
    
    454
    -kickOutAfterUnification tv_list
    
    455
    -  = case nonEmpty tv_list of
    
    456
    -      Nothing  -> return ()
    
    457
    -      Just tvs -> do { traceTcS "kickOutAfterUnification" (ppr min_tv_lvl $$ ppr tv_list)
    
    458
    -                     ; setUnificationFlagTo min_tv_lvl }
    
    459
    -         where
    
    460
    -           min_tv_lvl = foldr1 minTcLevel (NE.map tcTyVarLevel tvs)
    
    461
    -
    
    462
    -{-
    
    463
    -       { let tv_set = mkVarSet tv_list
    
    464
    -
    
    465
    -       ; n_kicked <- kickOutRewritable (KOAfterUnify tv_set) (Given, NomEq)
    
    466
    -                     -- Given because the tv := xi is given; NomEq because
    
    467
    -                     -- only nominal equalities are solved by unification
    
    468
    -
    
    469
    -       -- Set the unification flag if we have done outer unifications
    
    470
    -       -- that might affect an earlier implication constraint
    
    471
    -       ; let min_tv_lvl = foldr1 minTcLevel (NE.map tcTyVarLevel tvs)
    
    472
    -       ; ambient_lvl <- getTcLevel
    
    473
    -       ; when (ambient_lvl `strictlyDeeperThan` min_tv_lvl) $
    
    474
    -         setUnificationFlagTo min_tv_lvl
    
    475
    -
    
    476
    -       ; traceTcS "kickOutAfterUnification" (ppr tvs $$ text "n_kicked =" <+> ppr n_kicked)
    
    477
    -       ; return n_kicked }
    
    478
    --}
    
    479
    -
    
    480 448
     kickOutAfterFillingCoercionHole :: CoercionHole -> TcS ()
    
    481 449
     -- See Wrinkle (URW2) in Note [Unify only if the rewriter set is empty]
    
    482 450
     -- in GHC.Tc.Solver.Equality
    
    ... ... @@ -940,11 +908,6 @@ data TcSEnv
    940 908
       = TcSEnv {
    
    941 909
           tcs_ev_binds    :: EvBindsVar,
    
    942 910
     
    
    943
    -      tcs_unified     :: IORef Int,
    
    944
    -         -- The number of unification variables we have filled
    
    945
    -         -- The important thing is whether it is non-zero, so it
    
    946
    -         -- could equally well be a Bool instead of an Int.
    
    947
    -
    
    948 911
           tcs_unif_lvl  :: IORef (Maybe TcLevel),
    
    949 912
              -- The Unification Level Flag
    
    950 913
              -- Outermost level at which we have unified a meta tyvar
    
    ... ... @@ -1131,8 +1094,7 @@ runTcSWithEvBinds' :: TcSMode
    1131 1094
                        -> TcS a
    
    1132 1095
                        -> TcM a
    
    1133 1096
     runTcSWithEvBinds' mode ev_binds_var thing_inside
    
    1134
    -  = do { unified_var <- TcM.newTcRef 0
    
    1135
    -       ; step_count  <- TcM.newTcRef 0
    
    1097
    +  = do { step_count  <- TcM.newTcRef 0
    
    1136 1098
     
    
    1137 1099
            -- Make a fresh, empty inert set
    
    1138 1100
            -- Subtle point: see (TGE6) in Note [Tracking Given equalities]
    
    ... ... @@ -1143,7 +1105,6 @@ runTcSWithEvBinds' mode ev_binds_var thing_inside
    1143 1105
            ; wl_var      <- TcM.newTcRef emptyWorkList
    
    1144 1106
            ; unif_lvl_var <- TcM.newTcRef Nothing
    
    1145 1107
            ; let env = TcSEnv { tcs_ev_binds           = ev_binds_var
    
    1146
    -                          , tcs_unified            = unified_var
    
    1147 1108
                               , tcs_unif_lvl           = unif_lvl_var
    
    1148 1109
                               , tcs_count              = step_count
    
    1149 1110
                               , tcs_inerts             = inert_var
    
    ... ... @@ -1354,9 +1315,6 @@ setTcSMode :: TcSMode -> TcS a -> TcS a
    1354 1315
     setTcSMode mode thing_inside
    
    1355 1316
       = TcS (\env -> unTcS thing_inside (env { tcs_mode = mode }))
    
    1356 1317
     
    
    1357
    -getUnifiedRef :: TcS (IORef Int)
    
    1358
    -getUnifiedRef = TcS (return . tcs_unified)
    
    1359
    -
    
    1360 1318
     -- Getter of inerts and worklist
    
    1361 1319
     getInertSetRef :: TcS (IORef InertSet)
    
    1362 1320
     getInertSetRef = TcS (return . tcs_inerts)
    
    ... ... @@ -1817,13 +1775,11 @@ produced the same Derived constraint.)
    1817 1775
     
    
    1818 1776
     unifyTyVar :: TcTyVar -> TcType -> TcS ()
    
    1819 1777
     -- Unify a meta-tyvar with a type
    
    1820
    --- We keep track of how many unifications have happened in tcs_unified,
    
    1821
    ---
    
    1822 1778
     -- We should never unify the same variable twice!
    
    1823 1779
     unifyTyVar tv ty
    
    1824 1780
       = assertPpr (isMetaTyVar tv) (ppr tv) $
    
    1825 1781
         do { liftZonkTcS (TcM.writeMetaTyVar tv ty)  -- Produces a trace message
    
    1826
    -       ; setUnificationFlagTo (tcTyVarLevel tv) }
    
    1782
    +       ; recordUnification tv }
    
    1827 1783
     
    
    1828 1784
     reportUnifications :: TcS a -> TcS (Bool, a)
    
    1829 1785
     -- Record whether any unifications are done by thing_inside
    
    ... ... @@ -1887,6 +1843,18 @@ getUnificationFlag
    1887 1843
                              -> do { TcM.writeTcRef ref Nothing
    
    1888 1844
                                    ; return True } }
    
    1889 1845
     
    
    1846
    +recordUnification :: TcTyVar -> TcS ()
    
    1847
    +recordUnification tv = setUnificationFlagTo (tcTyVarLevel tv)
    
    1848
    +
    
    1849
    +recordUnifications :: [TcTyVar] -> TcS ()
    
    1850
    +recordUnifications tvs
    
    1851
    +  = case tvs of
    
    1852
    +      [] -> return ()
    
    1853
    +      (tv:tvs) -> do { traceTcS "recordUnifications" (ppr min_tv_lvl $$ ppr tvs)
    
    1854
    +                     ; setUnificationFlagTo min_tv_lvl }
    
    1855
    +        where
    
    1856
    +          min_tv_lvl = foldr (minTcLevel . tcTyVarLevel) (tcTyVarLevel tv) tvs
    
    1857
    +
    
    1890 1858
     setUnificationFlagTo :: TcLevel -> TcS ()
    
    1891 1859
     -- (setUnificationFlag i) sets the unification level to (Just i)
    
    1892 1860
     -- unless it already is (Just j) where j <= i
    
    ... ... @@ -2251,8 +2219,8 @@ unifyForAllBody :: CtEvidence -> Role -> (UnifyEnv -> TcM a)
    2251 2219
     unifyForAllBody ev role unify_body
    
    2252 2220
       = do { (res, cts, unified) <- wrapUnifierX ev role unify_body
    
    2253 2221
     
    
    2254
    -       -- Kick out any inert constraint that we have unified
    
    2255
    -       ; kickOutAfterUnification unified
    
    2222
    +       -- Record the unificaions we have done
    
    2223
    +       ; recordUnifications unified
    
    2256 2224
     
    
    2257 2225
            ; return (res, cts) }
    
    2258 2226
     
    
    ... ... @@ -2271,6 +2239,9 @@ wrapUnifierTcS :: CtEvidence -> Role
    2271 2239
     wrapUnifierTcS ev role do_unifications
    
    2272 2240
       = do { (res, cts, unified) <- wrapUnifierX ev role do_unifications
    
    2273 2241
     
    
    2242
    +       -- Record the unificaions we have done
    
    2243
    +       ; recordUnifications unified
    
    2244
    +
    
    2274 2245
            -- Emit the deferred constraints
    
    2275 2246
            -- See Note [Work-list ordering] in GHC.Tc.Solved.Equality
    
    2276 2247
            --
    
    ... ... @@ -2280,17 +2251,13 @@ wrapUnifierTcS ev role do_unifications
    2280 2251
            ; unless (isEmptyBag cts) $
    
    2281 2252
              updWorkListTcS (extendWorkListChildEqs ev cts)
    
    2282 2253
     
    
    2283
    -       -- And kick out any inert constraint that we have unified
    
    2284
    -       ; kickOutAfterUnification unified
    
    2285
    -
    
    2286 2254
            ; return (res, cts, unified) }
    
    2287 2255
     
    
    2288 2256
     wrapUnifierX :: CtEvidence -> Role
    
    2289 2257
                  -> (UnifyEnv -> TcM a)  -- Some calls to uType
    
    2290 2258
                  -> TcS (a, Bag Ct, [TcTyVar])
    
    2291 2259
     wrapUnifierX ev role do_unifications
    
    2292
    -  = do { unif_count_ref <- getUnifiedRef
    
    2293
    -       ; given_eq_lvl <- getInnermostGivenEqLevel
    
    2260
    +  = do { given_eq_lvl <- getInnermostGivenEqLevel
    
    2294 2261
            ; wrapTcS $
    
    2295 2262
              do { defer_ref   <- TcM.newTcRef emptyBag
    
    2296 2263
                 ; unified_ref <- TcM.newTcRef []
    
    ... ... @@ -2308,12 +2275,6 @@ wrapUnifierX ev role do_unifications
    2308 2275
     
    
    2309 2276
                 ; cts     <- TcM.readTcRef defer_ref
    
    2310 2277
                 ; unified <- TcM.readTcRef unified_ref
    
    2311
    -
    
    2312
    -            -- Don't forget to update the count of variables
    
    2313
    -            -- unified, lest we forget to iterate (#24146)
    
    2314
    -            ; unless (null unified) $
    
    2315
    -              TcM.updTcRef unif_count_ref (+ (length unified))
    
    2316
    -
    
    2317 2278
                 ; return (res, cts, unified) } }
    
    2318 2279
     
    
    2319 2280