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

Commits:

3 changed files:

Changes:

  • compiler/GHC/Tc/Instance/FunDeps.hs
    ... ... @@ -11,7 +11,7 @@
    11 11
     --
    
    12 12
     -- It's better to read it as: "if we know these, then we're going to know these"
    
    13 13
     module GHC.Tc.Instance.FunDeps
    
    14
    -   ( FunDepEqn(..)
    
    14
    +   ( FunDepEqns(..)
    
    15 15
        , pprEquation
    
    16 16
        , improveFromInstEnv
    
    17 17
        , improveFromAnother
    
    ... ... @@ -63,17 +63,17 @@ Each functional dependency with one variable in the RHS is responsible
    63 63
     for generating a single equality. For instance:
    
    64 64
          class C a b | a -> b
    
    65 65
     The constraints ([Wanted] C Int Bool) and [Wanted] C Int alpha
    
    66
    -will generate the following FunDepEqn
    
    67
    -     FDEqn { fd_qtvs = []
    
    68
    -           , fd_eqs  = [Pair Bool alpha] }
    
    66
    +will generate the following FunDepEqns
    
    67
    +     FDEqns { fd_qtvs = []
    
    68
    +            , fd_eqs  = [Pair Bool alpha] }
    
    69 69
     However notice that a functional dependency may have more than one variable
    
    70 70
     in the RHS which will create more than one pair of types in fd_eqs. Example:
    
    71 71
          class C a b c | a -> b c
    
    72 72
          [Wanted] C Int alpha alpha
    
    73 73
          [Wanted] C Int Bool beta
    
    74 74
     Will generate:
    
    75
    -     FDEqn { fd_qtvs = []
    
    76
    -           , fd_eqs  = [Pair Bool alpha, Pair alpha beta] }
    
    75
    +     FDEqns { fd_qtvs = []
    
    76
    +            , fd_eqs  = [Pair Bool alpha, Pair alpha beta] }
    
    77 77
     
    
    78 78
     INVARIANT: Corresponding types aren't already equal
    
    79 79
     That is, there exists at least one non-identity equality in FDEqs.
    
    ... ... @@ -85,8 +85,8 @@ Assume:
    85 85
        instance C Int Bool
    
    86 86
        [W] C Int ty
    
    87 87
     
    
    88
    -Then `improveFromInstEnv` should return a FDEqn with
    
    89
    -   FDEqno { fd_qtvs = [], fd_eqs = [Pair Bool ty] }
    
    88
    +Then `improveFromInstEnv` should return a FunDepEqns with
    
    89
    +   FDEqns { fd_qtvs = [], fd_eqs = [Pair Bool ty] }
    
    90 90
     
    
    91 91
     describing an equality (Bool ~ ty).  To do this we /match/ the instance head
    
    92 92
     against the [W], using just the LHS of the fundep; if we match, we return
    
    ... ... @@ -103,8 +103,8 @@ Wrinkles:
    103 103
     
    
    104 104
         Note that although the `Int` parts match, that does not fix what `x` is.
    
    105 105
         So we just make up a fresh unification variable (a meta_tv), to give the
    
    106
    -    "shape" of the RHS.  So we emit the FDEqun
    
    107
    -       FDEqn { fd_qtvs = [x], fd_eqs = [Pair (Maybe x) ty] }
    
    106
    +    "shape" of the RHS.  So we emit the FunDepEqns
    
    107
    +       FDEqns { fd_qtvs = [x], fd_eqs = [Pair (Maybe x) ty] }
    
    108 108
     
    
    109 109
         Note that the fd_qtvs can be free in the /first/ component of the Pair,
    
    110 110
         but not in the second (which comes from the [W] constraint).
    
    ... ... @@ -116,36 +116,39 @@ Wrinkles:
    116 116
            instance D Int x (Maybe x)
    
    117 117
            [W] D Int Bool ty
    
    118 118
     
    
    119
    -    Then we'll generate
    
    119
    +    Then we'll generate one FunDepEqns with two TypeEqns in it:
    
    120 120
            FDEqn { fd_qtvs = [x0], fd_eqs = [ x0 ~ Bool, Maybe x0 ~ ty] }
    
    121 121
         which generates one fresh unification variable x0
    
    122 122
     
    
    123
    -    But if the fundeps had been (a->b, a->c) we'd generate two FDEqns
    
    124
    -       FDEqn { fd_qtvs = [x1], fd_eqs = [ x1 ~ Bool ] }
    
    125
    -       FDEqn { fd_qtvs = [x2], fd_eqs = [ Maybe x2 ~ ty ] }
    
    123
    +    But if the fundeps had been (a->b, a->c) we'd generate two separate FDEqns
    
    124
    +       FDEqns { fd_qtvs = [x1], fd_eqs = [ x1 ~ Bool ] }
    
    125
    +       FDEqns { fd_qtvs = [x2], fd_eqs = [ Maybe x2 ~ ty ] }
    
    126 126
         with two FDEqns, generating two separate unification variables.
    
    127 127
     
    
    128
    +    This is why fd_eqs is a [TypeEqn] not just a TypeEqn
    
    129
    +
    
    128 130
     (IMP3) improveFromInstEnv doesn't return any equations that already hold.
    
    129 131
         Reason: just an optimisation; the caller does the same thing, but
    
    130 132
         with a bit more ceremony.
    
    131 133
     -}
    
    132 134
     
    
    133
    -data FunDepEqn
    
    134
    -  = FDEqn { fd_qtvs :: [TyVar]   -- Instantiate these type and kind vars
    
    135
    +data FunDepEqns  -- Plural becuase fd_eqs has multiple equations
    
    136
    +                 -- See (IMP2) above
    
    137
    +  = FDEqns { fd_qtvs :: [TyVar]   -- Instantiate these type and kind vars
    
    135 138
                                      --   to fresh unification vars,
    
    136 139
                                      -- See (IMP2) in Note [Improving against instances]
    
    137 140
     
    
    138
    -          , fd_eqs   :: [TypeEqn]  -- Make these pairs of types equal
    
    141
    +           , fd_eqs   :: [TypeEqn]  -- Make these pairs of types equal
    
    139 142
                                        -- Invariant: In each (Pair ty1 ty2), the fd_qtvs may be
    
    140 143
                                        -- free in ty1 but not in ty2.  See Wrinkle (1) of
    
    141 144
                                        -- Note [Improving against instances]
    
    142
    -          }
    
    145
    +           }
    
    143 146
     
    
    144
    -instance Outputable FunDepEqn where
    
    147
    +instance Outputable FunDepEqns where
    
    145 148
       ppr = pprEquation
    
    146 149
     
    
    147
    -pprEquation :: FunDepEqn -> SDoc
    
    148
    -pprEquation (FDEqn { fd_qtvs = qtvs, fd_eqs = pairs })
    
    150
    +pprEquation :: FunDepEqns -> SDoc
    
    151
    +pprEquation (FDEqns { fd_qtvs = qtvs, fd_eqs = pairs })
    
    149 152
       = vcat [text "forall" <+> braces (pprWithCommas ppr qtvs),
    
    150 153
               nest 2 (vcat [ ppr t1 <+> text "~" <+> ppr t2
    
    151 154
                            | Pair t1 t2 <- pairs])]
    
    ... ... @@ -202,14 +205,14 @@ zipAndComputeFDEqs _ _ _ = []
    202 205
     -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    203 206
     improveFromAnother :: PredType -- Template item (usually given, or inert)
    
    204 207
                        -> PredType -- Workitem [that can be improved]
    
    205
    -                   -> [FunDepEqn]
    
    208
    +                   -> [FunDepEqns]
    
    206 209
     -- Post: FDEqs always oriented from the other to the workitem
    
    207 210
     --       Equations have empty quantified variables
    
    208 211
     improveFromAnother pred1 pred2
    
    209 212
       | Just (cls1, tys1) <- getClassPredTys_maybe pred1
    
    210 213
       , Just (cls2, tys2) <- getClassPredTys_maybe pred2
    
    211 214
       , cls1 == cls2
    
    212
    -  = [ FDEqn { fd_qtvs = [], fd_eqs = eqs }
    
    215
    +  = [ FDEqns { fd_qtvs = [], fd_eqs = eqs }
    
    213 216
         | let (cls_tvs, cls_fds) = classTvsFds cls1
    
    214 217
         , fd <- cls_fds
    
    215 218
         , let (ltys1, rs1) = instFD fd cls_tvs tys1
    
    ... ... @@ -226,12 +229,12 @@ improveFromAnother _ _ = []
    226 229
     
    
    227 230
     improveFromInstEnv :: InstEnvs
    
    228 231
                        -> Class -> [Type]
    
    229
    -                   -> [FunDepEqn] -- Needs to be a FunDepEqn because
    
    230
    -                                  -- of quantified variables
    
    232
    +                   -> [FunDepEqns] -- Needs to be a FunDepEqn because
    
    233
    +                                   -- of quantified variables
    
    231 234
     -- See Note [Improving against instances]
    
    232 235
     -- Post: Equations oriented from the template (matching instance) to the workitem!
    
    233 236
     improveFromInstEnv inst_env cls tys
    
    234
    -  = [ FDEqn { fd_qtvs = meta_tvs, fd_eqs = eqs }
    
    237
    +  = [ FDEqns { fd_qtvs = meta_tvs, fd_eqs = eqs }
    
    235 238
         | fd <- cls_fds             -- Iterate through the fundeps first,
    
    236 239
                                     -- because there often are none!
    
    237 240
         , let trimmed_tcs = trimRoughMatchTcs cls_tvs fd rough_tcs
    

  • compiler/GHC/Tc/Solver/FunDeps.hs
    ... ... @@ -45,19 +45,19 @@ import Data.Maybe( mapMaybe )
    45 45
     Here is our plan for dealing with functional dependencies
    
    46 46
     
    
    47 47
     * When we have failed to solve a Wanted constraint, do this
    
    48
    -  1. Generate any fundep-equalities [FunDepEqn] from that constraint.
    
    49
    -  2. Try to solve that [FunDepEqn]
    
    48
    +  1. Generate any fundep-equalities [FunDepEqns] from that constraint.
    
    49
    +  2. Try to solve that [FunDepEqns]
    
    50 50
       3. If any unifications happened, send the constraint back to the
    
    51 51
          start of the pipeline
    
    52 52
     
    
    53
    -* Step (1) How we generate those [FunDepEqn] varies:
    
    53
    +* Step (1) How we generate those [FunDepEqns] varies:
    
    54 54
            - tryDictFunDeps: for class constraints (C t1 .. tn)
    
    55 55
              we look at top-level instances and inert Givens
    
    56 56
            - tryEqFunDeps: for type-family equalities (F t1 .. tn ~ ty)
    
    57 57
              we look at top-level family instances
    
    58 58
                         and inert Given family equalities
    
    59 59
     
    
    60
    -* Step (2). We use `solveFunDeps` to solve the [FunDepEqn] in a nested
    
    60
    +* Step (2). We use `solveFunDeps` to solve the [FunDepEqns] in a nested
    
    61 61
       solver.  Key property:
    
    62 62
     
    
    63 63
           The ONLY effect of `solveFunDeps` is possibly to perform unifications:
    
    ... ... @@ -169,14 +169,14 @@ Why? Because if we do (YES) we'll think we have made some progress
    169 169
     (some unification has happened), and hence go round again; but actually all we
    
    170 170
     have done is to replace `alpha` with `gamma1`.
    
    171 171
     
    
    172
    -These "fresh unification variables" in fundep-equalities are ubituitous.
    
    172
    +These "fresh unification variables" in fundep-equalities are ubiquitous.
    
    173 173
     For example
    
    174 174
           class C a b | a -> b
    
    175 175
           instance .. => C Int [x]
    
    176 176
     If we see
    
    177 177
           [W] C Int alpha
    
    178 178
     we'll generate a fundep-equality   [W] alpha ~ [beta1]
    
    179
    -where `beta1` is one of those "fresh unification variables
    
    179
    +where `beta1` is one of those "fresh unification variables"
    
    180 180
     
    
    181 181
     This problem shows up in several guises; see (at the bottom)
    
    182 182
       * Historical Note [Improvement orientation]
    
    ... ... @@ -184,10 +184,10 @@ This problem shows up in several guises; see (at the bottom)
    184 184
     
    
    185 185
     The solution is super-simple:
    
    186 186
     
    
    187
    -  * A fundep-equality is described by `FunDepEqn`, whose `fd_qtvs` field explicitly
    
    187
    +  * A fundep-equality is described by `FunDepEqns`, whose `fd_qtvs` field explicitly
    
    188 188
         lists the "fresh variables"
    
    189 189
     
    
    190
    -  * Function `instantiateFunDepEqn` instantiates a `FunDepEqn`, and CRUCIALLY
    
    190
    +  * Function `instantiateFunDepEqn` instantiates a `FunDepEqns`, and CRUCIALLY
    
    191 191
         gives the new unification variables a level one deeper than the current
    
    192 192
         level.
    
    193 193
     
    
    ... ... @@ -196,8 +196,8 @@ The solution is super-simple:
    196 196
         Note [Deeper level on the left].  That ensures that the fresh `gamma1`
    
    197 197
         will be eliminated in favour of `alpha`. Hooray.
    
    198 198
     
    
    199
    -  * Better still, we solve the [FunDepEqn] with
    
    200
    -      solveFunDeps :: CtEvidence -> [FunDepEqn] -> TcS Bool
    
    199
    +  * Better still, we solve the [FunDepEqns] with
    
    200
    +      solveFunDeps :: CtEvidence -> [FunDepEqns] -> TcS Bool
    
    201 201
         It uses `reportUnifications` to see if any unification happened at this
    
    202 202
         level or outside -- that is, it does NOT report unifications to the fresh
    
    203 203
         unification variables.  So `solveFunDeps` returns True only if it
    
    ... ... @@ -320,7 +320,7 @@ tryDictFunDepsLocal dict_ct@(DictCt { di_cls = cls, di_ev = work_ev })
    320 320
     
    
    321 321
            ; traceTcS "tryDictFunDepsLocal {" (ppr dict_ct)
    
    322 322
     
    
    323
    -       ; let eqns :: [FunDepEqn]
    
    323
    +       ; let eqns :: [FunDepEqns]
    
    324 324
                  eqns = foldr ((++) . do_interaction) [] $
    
    325 325
                         findDictsByClass (inert_dicts inerts) cls
    
    326 326
            ; imp <- solveFunDeps work_ev eqns
    
    ... ... @@ -335,7 +335,7 @@ tryDictFunDepsLocal dict_ct@(DictCt { di_cls = cls, di_ev = work_ev })
    335 335
         work_pred     = ctEvPred work_ev
    
    336 336
         work_is_given = isGiven work_ev
    
    337 337
     
    
    338
    -    do_interaction :: DictCt -> [FunDepEqn]
    
    338
    +    do_interaction :: DictCt -> [FunDepEqns]
    
    339 339
         do_interaction (DictCt { di_ev = inert_ev }) -- This can be Given or Wanted
    
    340 340
           | work_is_given && isGiven inert_ev
    
    341 341
             -- Do not create FDs from Given/Given interactions
    
    ... ... @@ -353,7 +353,7 @@ tryDictFunDepsTop dict_ct@(DictCt { di_ev = ev, di_cls = cls, di_tys = xis })
    353 353
         do { inst_envs <- getInstEnvs
    
    354 354
     
    
    355 355
            ; traceTcS "tryDictFunDepsTop {" (ppr dict_ct)
    
    356
    -       ; let eqns :: [FunDepEqn]
    
    356
    +       ; let eqns :: [FunDepEqns]
    
    357 357
                  eqns = improveFromInstEnv inst_envs cls xis
    
    358 358
            ; imp <- solveFunDeps ev eqns
    
    359 359
            ; traceTcS "tryDictFunDepsTop }" (text "imp =" <+> ppr imp)
    
    ... ... @@ -466,7 +466,7 @@ tryFamEqFunDeps fam_tc args work_item@(EqCt { eq_ev = ev, eq_rhs = rhs })
    466 466
       | otherwise
    
    467 467
       = nopStage ()
    
    468 468
     
    
    469
    -tryFDEqns :: TyCon -> [TcType] -> EqCt -> TcS [FunDepEqn] -> SolverStage ()
    
    469
    +tryFDEqns :: TyCon -> [TcType] -> EqCt -> TcS [FunDepEqns] -> SolverStage ()
    
    470 470
     tryFDEqns fam_tc work_args work_item@(EqCt { eq_ev = ev, eq_rhs= rhs }) mk_fd_eqns
    
    471 471
       = Stage $
    
    472 472
         do { fd_eqns <- mk_fd_eqns
    
    ... ... @@ -481,7 +481,7 @@ tryFDEqns fam_tc work_args work_item@(EqCt { eq_ev = ev, eq_rhs= rhs }) mk_fd_eq
    481 481
     -----------------------------------------
    
    482 482
     --  User-defined type families
    
    483 483
     -----------------------------------------
    
    484
    -mkTopUserFamEqFDs :: TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqn]
    
    484
    +mkTopUserFamEqFDs :: TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    485 485
     -- Implements (INJFAM:Wanted/top)
    
    486 486
     mkTopUserFamEqFDs fam_tc inj_flags work_args work_rhs
    
    487 487
       = do { fam_envs <- getFamInstEnvs
    
    ... ... @@ -499,7 +499,7 @@ mkTopUserFamEqFDs fam_tc inj_flags work_args work_rhs
    499 499
           | otherwise
    
    500 500
           = []
    
    501 501
     
    
    502
    -    do_one :: CoAxBranch -> Maybe FunDepEqn
    
    502
    +    do_one :: CoAxBranch -> Maybe FunDepEqns
    
    503 503
         do_one branch@(CoAxBranch { cab_tvs = branch_tvs
    
    504 504
                                   , cab_lhs = branch_lhs_tys
    
    505 505
                                   , cab_rhs = branch_rhs })
    
    ... ... @@ -525,7 +525,7 @@ mkTopUserFamEqFDs fam_tc inj_flags work_args work_rhs
    525 525
                                        !(subst', tvs') = trim_qtvs subst1 tvs
    
    526 526
                                    in (subst', tv':tvs')
    
    527 527
     
    
    528
    -mkLocalUserFamEqFDs :: TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqn]
    
    528
    +mkLocalUserFamEqFDs :: TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    529 529
     mkLocalUserFamEqFDs fam_tc inj_flags work_args work_rhs
    
    530 530
       = do { fun_eqs_for_me <- getInertFamEqsFor fam_tc
    
    531 531
     
    
    ... ... @@ -538,7 +538,7 @@ mkLocalUserFamEqFDs fam_tc inj_flags work_args work_rhs
    538 538
     
    
    539 539
            ; return (eqns_from_inerts ++ eqns_from_self) }
    
    540 540
       where
    
    541
    -    do_one :: EqCt -> Maybe FunDepEqn
    
    541
    +    do_one :: EqCt -> Maybe FunDepEqns
    
    542 542
         do_one (EqCt { eq_lhs = TyFamLHS _ inert_args, eq_rhs = inert_rhs })
    
    543 543
           | work_rhs `tcEqType` inert_rhs = Just (mk_eqn inert_args)
    
    544 544
           | otherwise                     = Nothing
    
    ... ... @@ -604,24 +604,24 @@ tryGivenBuiltinFamEqFDs fam_tc ops work_args (EqCt { eq_ev = work_ev, eq_rhs = w
    604 604
     
    
    605 605
         do_one _ = return ()
    
    606 606
     
    
    607
    -mkTopBuiltinFamEqFDs :: TyCon -> BuiltInSynFamily -> [TcType] -> Xi -> TcS [FunDepEqn]
    
    607
    +mkTopBuiltinFamEqFDs :: TyCon -> BuiltInSynFamily -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    608 608
     mkTopBuiltinFamEqFDs fam_tc ops work_args work_rhs
    
    609
    -  = return [FDEqn { fd_qtvs = []
    
    610
    -                  , fd_eqs = map snd $ tryInteractTopFam ops fam_tc work_args work_rhs }]
    
    609
    +  = return [FDEqns { fd_qtvs = []
    
    610
    +                   , fd_eqs = map snd $ tryInteractTopFam ops fam_tc work_args work_rhs }]
    
    611 611
     
    
    612
    -mkLocalBuiltinFamEqFDs :: TyCon -> BuiltInSynFamily -> [TcType] -> Xi -> TcS [FunDepEqn]
    
    612
    +mkLocalBuiltinFamEqFDs :: TyCon -> BuiltInSynFamily -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    613 613
     mkLocalBuiltinFamEqFDs fam_tc ops work_args work_rhs
    
    614 614
       = do { fun_eqs_for_me <- getInertFamEqsFor fam_tc
    
    615 615
     
    
    616
    -       ; let do_one :: EqCt -> [FunDepEqn]
    
    616
    +       ; let do_one :: EqCt -> [FunDepEqns]
    
    617 617
                  do_one (EqCt { eq_lhs = TyFamLHS _ inert_args, eq_rhs = inert_rhs })
    
    618 618
                    | inert_rhs `tcEqType` work_rhs = [mk_eqn inert_args]
    
    619 619
                    | otherwise                     = []
    
    620 620
                  do_one _ = pprPanic "interactFunEq 1" (ppr fam_tc) -- TyVarLHS
    
    621 621
     
    
    622
    -             mk_eqn :: [TcType] -> FunDepEqn
    
    623
    -             mk_eqn iargs = FDEqn { fd_qtvs = []
    
    624
    -                                  , fd_eqs = map snd $ tryInteractInertFam ops fam_tc
    
    622
    +             mk_eqn :: [TcType] -> FunDepEqns
    
    623
    +             mk_eqn iargs = FDEqns { fd_qtvs = []
    
    624
    +                                   , fd_eqs = map snd $ tryInteractInertFam ops fam_tc
    
    625 625
                                                                          work_args iargs }
    
    626 626
     
    
    627 627
            ; let eqns_from_inerts = concatMap do_one fun_eqs_for_me
    
    ... ... @@ -634,12 +634,12 @@ mkLocalBuiltinFamEqFDs fam_tc ops work_args work_rhs
    634 634
     mkInjectivityFDEqn :: [Bool]       -- Injectivity flags
    
    635 635
                        -> [TcTyVar]    -- Quantify these
    
    636 636
                        -> [TcType] -> [TcType]  -- Make these equal
    
    637
    -                   -> FunDepEqn
    
    637
    +                   -> FunDepEqns
    
    638 638
     -- When F s1 s2 s3 ~ F t1 t2 t3, and F has injectivity info [True,False,True]
    
    639
    ---   return the FDEqn { fd_eqs = [Pair s1 t1, Pair s3 t3] }
    
    639
    +--   return the FDEqns { fd_eqs = [Pair s1 t1, Pair s3 t3] }
    
    640 640
     -- The injectivity flags [Bool] will not all be False, but nothing goes wrong if they are
    
    641 641
     mkInjectivityFDEqn inj_args qtvs lhs_args rhs_args
    
    642
    -  = FDEqn { fd_qtvs = qtvs, fd_eqs = eqs }
    
    642
    +  = FDEqns { fd_qtvs = qtvs, fd_eqs = eqs }
    
    643 643
       where
    
    644 644
         eqs = [ Pair lhs_arg rhs_arg
    
    645 645
               | (True, lhs_arg, rhs_arg) <- zip3 inj_args lhs_args rhs_args ]
    
    ... ... @@ -669,19 +669,19 @@ For /injective/, /user-defined/ type families
    669 669
     
    
    670 670
     * (INJFAM:Wanted/Self) see `mkLocalUserFamEqFDs`
    
    671 671
         work item: [W] F s1 s2 ~ F t1 t2
    
    672
    -  We can generate FDEqn (s2 ~ t2)
    
    672
    +  We can generate FunDepEqns: (s2 ~ t2)
    
    673 673
     
    
    674 674
     * (INJFAM:Wanted/other) see `mkLocalUserFamEqFDs`
    
    675 675
         work item: [W]   F s1 s2 ~ rhs   -- Wanted
    
    676 676
         inert:     [G/W] F t2 t2 ~ rhs   -- Same `rhs`, Given or Wanted
    
    677
    -  We can generate FDEqn (s2 ~ t2)
    
    677
    +  We can generate FunDepEqns: (s2 ~ t2)
    
    678 678
     
    
    679 679
     * (INJFAM:Wanted/top) see `mkTopUserFamEqFDs`
    
    680 680
         work item: [W] F s1 s2 ~ rhs
    
    681 681
         type instance forall a b c. F t1 t2 ~ top_rhs
    
    682 682
       and we can /match/ the LHS, so that
    
    683 683
          S(top_rhs) = rhs
    
    684
    -  then we can generate the FDEqn  forall a c. s2 ~ S(t2)
    
    684
    +  then we can generate the FunDepEqns:  forall a c. s2 ~ S(t2)
    
    685 685
       But see wrinkle (TIF1), (TIF2)
    
    686 686
     
    
    687 687
     For /built-in/ type families, it's pretty similar, except that
    
    ... ... @@ -703,10 +703,10 @@ For /built-in/ type families, it's pretty similar, except that
    703 703
          [W] F @kappa alpha beta ~ Maybe (Proxy @kappa (delta::kappa))
    
    704 704
     
    
    705 705
       we match (Proxy @kappa delta) against the template (Proxy k a), succeeding
    
    706
    -  with substitution [k:->kappa, a:->delta].  We want to generate this FunDepEqn
    
    706
    +  with substitution [k:->kappa, a:->delta].  We want to generate this FunDepEqns
    
    707 707
         FDEqn { fd_qtvs = [b:kappa], fd_eqs = [ beta ~ Proxy @kappa b ] }
    
    708 708
       Notice that
    
    709
    -    * we must quantify the FunDepEqn over `b`, which is not matched; for this
    
    709
    +    * we must quantify the FunDepEqns over `b`, which is not matched; for this
    
    710 710
           we will generate a fresh unfication variable in `instantiateFunDepEqn`.
    
    711 711
         * we must substitute `k:->kappa` in the kind of `b`.
    
    712 712
       This fancy footwork for `fd_qtvs` is done by `trim_qtvs` in
    
    ... ... @@ -756,7 +756,7 @@ solving.
    756 756
     ********************************************************************* -}
    
    757 757
     
    
    758 758
     solveFunDeps :: CtEvidence  -- The work item
    
    759
    -             -> [FunDepEqn]
    
    759
    +             -> [FunDepEqns]
    
    760 760
                  -> TcS Bool
    
    761 761
     -- Solve a bunch of type-equality equations, generated by functional dependencies
    
    762 762
     -- By "solve" we mean: (only) do unifications.  We do not generate evidence, and
    
    ... ... @@ -784,12 +784,12 @@ solveFunDeps work_ev fd_eqns
    784 784
         do_fundeps :: UnifyEnv -> TcM ()
    
    785 785
         do_fundeps env = mapM_ (do_one env) fd_eqns
    
    786 786
     
    
    787
    -    do_one :: UnifyEnv -> FunDepEqn -> TcM ()
    
    787
    +    do_one :: UnifyEnv -> FunDepEqns -> TcM ()
    
    788 788
         do_one uenv eqn = do { eqs <- instantiateFunDepEqn eqn
    
    789 789
                              ; uPairsTcM uenv eqs }
    
    790 790
     
    
    791
    -instantiateFunDepEqn :: FunDepEqn -> TcM [TypeEqn]
    
    792
    -instantiateFunDepEqn (FDEqn { fd_qtvs = tvs, fd_eqs = eqs })
    
    791
    +instantiateFunDepEqn :: FunDepEqns -> TcM [TypeEqn]
    
    792
    +instantiateFunDepEqn (FDEqns { fd_qtvs = tvs, fd_eqs = eqs })
    
    793 793
       | null tvs
    
    794 794
       = return rev_eqs
    
    795 795
       | otherwise
    

  • compiler/GHC/Tc/Solver/Monad.hs
    ... ... @@ -1227,9 +1227,10 @@ nestFunDepsTcS (TcS thing_inside)
    1227 1227
         TcM.pushTcLevelM_  $
    
    1228 1228
              -- pushTcLevelTcM: increase the level so that unification variables
    
    1229 1229
              -- allocated by the fundep-creation itself don't count as useful unifications
    
    1230
    +         -- See Note [Partial functional dependencies] in GHC.Tc.Solver.FunDeps
    
    1230 1231
         do { inerts <- TcM.readTcRef inerts_var
    
    1231 1232
            ; let nest_inerts = resetInertCans inerts
    
    1232
    -                 -- resetInertCasns: like nestImplicTcS
    
    1233
    +                 -- resetInertCans: like nestImplicTcS
    
    1233 1234
            ; new_inert_var <- TcM.newTcRef nest_inerts
    
    1234 1235
            ; new_wl_var    <- TcM.newTcRef emptyWorkList
    
    1235 1236
            ; let nest_env = env { tcs_inerts   = new_inert_var