Simon Peyton Jones pushed to branch wip/T26543b at Glasgow Haskell Compiler / GHC

Commits:

6 changed files:

Changes:

  • changelog.d/T26543
    1
    +section: compiler
    
    2
    +synopsis: Fix a bug in ImpredicativeTypes
    
    3
    +description:
    
    4
    +  The QuickLook algorithm (which implements `ImpredicativeTypes`) was defeated if there
    
    5
    +  was a kind coercion in the types being unified.  That bug is now fixed.
    
    6
    +mrs: !16566
    
    7
    +issues: #26543

  • compiler/GHC/Core/TyCo/FVs.hs
    ... ... @@ -850,15 +850,15 @@ invisibleVarsOfTypes = foldr (unionVarSet . invisibleVarsOfType) emptyVarSet
    850 850
     {-# INLINE afvFolder #-}   -- so that specialization to (const True) works
    
    851 851
     afvFolder :: (TyCoVar -> Bool) -> TyCoFolder (FV TyCoVarSet DM.Any)
    
    852 852
     -- 'afvFolder' is short for "any-free-var folder", good for checking
    
    853
    --- if any free var of a type satisfies a predicate `check_fv`
    
    853
    +-- if any shallow free var of a type satisfies a predicate `check_fv`
    
    854 854
     afvFolder check_fv = TyCoFolder { tcf_view = noView  -- See Note [Free vars and synonyms]
    
    855 855
                                     , tcf_tyvar = do_tcv, tcf_covar = do_tcv
    
    856 856
                                     , tcf_hole = do_hole
    
    857 857
                                     , tcf_tycobinder = addBndrFV }
    
    858 858
       where
    
    859
    -    do_tcv tv = MkFV $ \ bvs ->
    
    860
    -                Any (not (tv `elemVarSet` bvs) && check_fv tv)
    
    861
    -    do_hole _ = mempty    -- I'm unsure; probably never happens
    
    859
    +    do_tcv tv    = MkFV $ \ bvs ->
    
    860
    +                   Any (not (tv `elemVarSet` bvs) && check_fv tv)
    
    861
    +    do_hole hole = do_tcv (coHoleCoVar hole)
    
    862 862
     
    
    863 863
     anyFreeVarsOfType :: (TyCoVar -> Bool) -> Type -> Bool
    
    864 864
     anyFreeVarsOfType check_fv ty = DM.getAny (runFVTop (f ty))
    

  • compiler/GHC/Tc/Gen/App.hs
    ... ... @@ -631,11 +631,13 @@ tcInstFun :: QLFlag
    631 631
     -- plus the modification in Fig 5, of the QL paper:
    
    632 632
     -- "A quick look at impredicativity" (ICFP'20).
    
    633 633
     tcInstFun do_ql inst_final rn_head@(_, fun_lspan) tc_fun fun_sigma rn_args
    
    634
    -  = do { traceTc "tcInstFun" (vcat [ text "tc_fun" <+> ppr tc_fun
    
    634
    +  = do { lvl <- getTcLevel
    
    635
    +       ; traceTc "tcInstFun" (vcat [ text "tc_fun" <+> ppr tc_fun
    
    635 636
                                        , text "rn_fun" <+> ppr rn_head
    
    636 637
                                        , text "fun_sigma" <+> ppr fun_sigma
    
    637 638
                                        , text "args:" <+> ppr rn_args
    
    638
    -                                   , text "do_ql" <+> ppr do_ql])
    
    639
    +                                   , text "do_ql" <+> ppr do_ql
    
    640
    +                                   , text "lvl:" <+> ppr lvl ])
    
    639 641
            ; fun_origin <- mk_origin rn_head
    
    640 642
            ; res@(_, fun_ty) <- go fun_origin 1 [] fun_sigma rn_args
    
    641 643
            ; traceTc "tcInstFun:ret" (ppr fun_ty)
    
    ... ... @@ -1377,13 +1379,15 @@ tc_inst_forall_arg conc_tvs (tvb, inner_ty) hs_ty
    1377 1379
                    -- is not fully zonked, because ty_arg is fully zonked.
    
    1378 1380
                    -- See Note [Type application substitution].
    
    1379 1381
     
    
    1382
    +       ; lvl <- getTcLevel
    
    1380 1383
            ; traceTc "tc_inst_forall_arg (VTA/VDQ)" (
    
    1381 1384
                       vcat [ text "fun_ty" <+> ppr fun_ty
    
    1382 1385
                            , text "tv" <+> ppr tv <+> dcolon <+> debugPprType kind
    
    1383 1386
                            , text "ty_arg" <+> debugPprType ty_arg <+> dcolon
    
    1384 1387
                                            <+> debugPprType (typeKind ty_arg)
    
    1385 1388
                            , text "inner_ty" <+> debugPprType inner_ty
    
    1386
    -                       , text "insted_ty" <+> debugPprType insted_ty ])
    
    1389
    +                       , text "insted_ty" <+> debugPprType insted_ty
    
    1390
    +                       , text "lvl:" <+> ppr lvl ])
    
    1387 1391
            ; return (ty_arg, insted_ty) }
    
    1388 1392
     
    
    1389 1393
     {- Note [Visible type application and abstraction]
    
    ... ... @@ -1934,11 +1938,13 @@ quickLookArg1 pos app_lspan rn_head larg@(L _ arg) sc_arg_ty@(Scaled _ orig_arg_
    1934 1938
              -- capture and save it in the `EValArgQL`.  See (QLA6) in
    
    1935 1939
              -- Note [Quick Look at value arguments]
    
    1936 1940
     
    
    1941
    +       ; lvl <- getTcLevel
    
    1937 1942
            ; traceTc "quickLookArg {" $
    
    1938 1943
              vcat [ text "arg:" <+> ppr arg
    
    1939 1944
                   , text "orig_arg_rho:" <+> ppr orig_arg_rho
    
    1940 1945
                   , text "head:" <+> ppr rn_fun_arg <+> dcolon <+> ppr mb_fun_ty
    
    1941
    -              , text "args:" <+> ppr rn_args ]
    
    1946
    +              , text "args:" <+> ppr rn_args
    
    1947
    +              , text "level:" <+> ppr lvl ]
    
    1942 1948
     
    
    1943 1949
            ; case mb_fun_ty of {
    
    1944 1950
                Nothing -> skipQuickLook app_lspan larg sc_arg_ty ;    -- fun is too complicated
    
    ... ... @@ -2158,18 +2164,23 @@ qlUnify :: TcType -> TcType -> TcM ()
    2158 2164
     --   * It may return without having made the argument types equal, of course;
    
    2159 2165
     --     it just makes best efforts.
    
    2160 2166
     qlUnify ty1 ty2
    
    2161
    -  = do { traceTc "qlUnify" (ppr ty1 $$ ppr ty2)
    
    2167
    +  = do { lvl <- getTcLevel
    
    2168
    +       ; traceTc "qlUnify" (ppr lvl $$ ppr ty1 $$ ppr ty2)
    
    2162 2169
            ; go ty1 ty2 }
    
    2163 2170
       where
    
    2164 2171
         go :: TcType -> TcType -> TcM ()
    
    2165 2172
     
    
    2173
    +    go t1 t2 = do { traceTc "qlUinfy:go" (ppr t1 <+> char '~' <+> ppr t2)
    
    2174
    +                  ; go' t1 t2 }
    
    2175
    +
    
    2166 2176
         -- Decompose (arg1 -> res1) ~ (arg2 -> res2)
    
    2167 2177
         -- and         (c1 => res1) ~   (c2 => res2)
    
    2168 2178
         -- But for the latter we only learn instantiation info from res1~res2
    
    2169
    -    go (FunTy { ft_af = af1, ft_arg = arg1, ft_res = res1 })
    
    2179
    +    go' (FunTy { ft_af = af1, ft_arg = arg1, ft_res = res1 })
    
    2170 2180
            (FunTy { ft_af = af2, ft_arg = arg2, ft_res = res2 })
    
    2171 2181
           | af1 == af2 -- Match the arrow TyCon
    
    2172
    -      = do { when (isVisibleFunArg af1) (go arg1 arg2)
    
    2182
    +      = do { traceTc "go_fun" (ppr arg1 $$ ppr arg2)
    
    2183
    +           ; when (isVisibleFunArg af1) (go arg1 arg2)
    
    2173 2184
     
    
    2174 2185
             -- NB: we do not unify the multiplicities; that would be too strong.
    
    2175 2186
             -- We might only require mult1 ⩽ mult2, as in Note [Multiplicity in deep subsumption].
    
    ... ... @@ -2178,30 +2189,30 @@ qlUnify ty1 ty2
    2178 2189
                ; go res1 res2 }
    
    2179 2190
     
    
    2180 2191
         -- Make sure to not unify "kappa := (a %1 -> b)". See (UQL5).
    
    2181
    -    go (FunTy { ft_mult = OneTy }) _ = return ()
    
    2182
    -    go _ (FunTy { ft_mult = OneTy }) = return ()
    
    2192
    +    go' (FunTy { ft_mult = OneTy }) _ = return ()
    
    2193
    +    go' _ (FunTy { ft_mult = OneTy }) = return ()
    
    2183 2194
           -- NB: we do want to be able to unify "kappa := a => b", as that's
    
    2184 2195
           -- the main point of QuickLook (allowing meta-variables to be unified
    
    2185 2196
           -- with qualified types).
    
    2186 2197
     
    
    2187
    -    go (TyVarTy tv) ty2
    
    2198
    +    go' (TyVarTy tv) ty2
    
    2188 2199
           | isMetaTyVar tv = go_kappa tv ty2
    
    2189
    -    go ty1 (TyVarTy tv)
    
    2200
    +    go' ty1 (TyVarTy tv)
    
    2190 2201
           | isMetaTyVar tv = go_kappa tv ty1
    
    2191 2202
     
    
    2192
    -    go (CastTy ty1 _) ty2 = go ty1 ty2
    
    2193
    -    go ty1 (CastTy ty2 _) = go ty1 ty2
    
    2203
    +    go' (CastTy ty1 _) ty2 = go ty1 ty2
    
    2204
    +    go' ty1 (CastTy ty2 _) = go ty1 ty2
    
    2194 2205
     
    
    2195
    -    go (TyConApp tc1 []) (TyConApp tc2 [])
    
    2206
    +    go' (TyConApp tc1 []) (TyConApp tc2 [])
    
    2196 2207
           | tc1 == tc2 -- See GHC.Tc.Utils.Unify
    
    2197 2208
           = return ()  -- Note [Expanding synonyms during unification]
    
    2198 2209
     
    
    2199 2210
         -- Now, and only now, expand synonyms
    
    2200
    -    go rho1 rho2
    
    2211
    +    go' rho1 rho2
    
    2201 2212
           | Just rho1 <- coreView rho1 = go rho1 rho2
    
    2202 2213
           | Just rho2 <- coreView rho2 = go rho1 rho2
    
    2203 2214
     
    
    2204
    -    go (TyConApp tc1 tys1) (TyConApp tc2 tys2)
    
    2215
    +    go' (TyConApp tc1 tys1) (TyConApp tc2 tys2)
    
    2205 2216
           | tc1 == tc2
    
    2206 2217
           , not (isTypeFamilyTyCon tc1)
    
    2207 2218
           , tys1 `equalLength` tys2
    
    ... ... @@ -2209,14 +2220,14 @@ qlUnify ty1 ty2
    2209 2220
     
    
    2210 2221
         -- Don't allow unifying (a => b) with the AppTy 'arr[tau] a b'.
    
    2211 2222
         -- To ensure this, use 'tcSplitAppTyNoView_maybe' which does not split (=>).
    
    2212
    -    go (AppTy t1a t1b) ty2
    
    2223
    +    go' (AppTy t1a t1b) ty2
    
    2213 2224
           | Just (t2a, t2b) <- tcSplitAppTyNoView_maybe ty2
    
    2214 2225
           = do { go t1a t2a; go t1b t2b }
    
    2215
    -    go ty1 (AppTy t2a t2b)
    
    2226
    +    go' ty1 (AppTy t2a t2b)
    
    2216 2227
           | Just (t1a, t1b) <- tcSplitAppTyNoView_maybe ty1
    
    2217 2228
           = do { go t1a t2a; go t1b t2b }
    
    2218 2229
     
    
    2219
    -    go _ _ = return ()
    
    2230
    +    go' _ _ = return ()
    
    2220 2231
            -- Don't look under foralls; see (UQL4) of Note [QuickLook unification]
    
    2221 2232
     
    
    2222 2233
         ----------------
    
    ... ... @@ -2244,7 +2255,11 @@ qlUnify ty1 ty2
    2244 2255
                   -- Here we are in the TcM monad, which does not track enclosing
    
    2245 2256
                   -- Given equalities; so for quick-look unification we conservatively
    
    2246 2257
                   -- treat /any/ level outside this one as untouchable. Hence cur_lvl.
    
    2258
    +           ; traceTc "go_flexi1" (ppr kappa $$ ppr ty2)
    
    2247 2259
                ; case simpleUnifyCheck UC_QuickLook cur_lvl kappa ty2 of
    
    2260
    +              -- qlUnify depends, regrettably delicately, on the exact choices made
    
    2261
    +              --  by `simpleUnifyCheck`.  See (SUC1) in
    
    2262
    +              --  Note [simpleUnifyCheck] in GHC.Tc.Utils.Unify
    
    2248 2263
                   SUC_CanUnify ->
    
    2249 2264
                     do { co <- unifyKind (Just (TypeThing ty2)) ty2_kind kappa_kind
    
    2250 2265
                                -- unifyKind: see (UQL2) in Note [QuickLook unification]
    
    ... ... @@ -2253,7 +2268,8 @@ qlUnify ty1 ty2
    2253 2268
                        ; traceTc "qlUnify:update" $
    
    2254 2269
                          ppr kappa <+> text ":=" <+> ppr ty2
    
    2255 2270
                        ; liftZonkM $ writeMetaTyVar kappa ty2' }
    
    2256
    -              _ -> return () -- e.g. occurs-check or forall-bound variable
    
    2271
    +              suc -> do { traceTc "go_flexi2" (ppr suc $$ ppr kappa $$ ppr ty2)
    
    2272
    +                        ; return () } -- e.g. occurs-check or forall-bound variable
    
    2257 2273
                }
    
    2258 2274
           where
    
    2259 2275
             kappa_kind = tyVarKind kappa
    

  • compiler/GHC/Tc/Utils/Unify.hs
    ... ... @@ -103,7 +103,6 @@ import GHC.Types.Id( idType )
    103 103
     import GHC.Types.Var as Var
    
    104 104
     import GHC.Types.Var.Set
    
    105 105
     import GHC.Types.Var.Env
    
    106
    -import GHC.Types.Var.FV
    
    107 106
     import GHC.Types.Basic
    
    108 107
     import GHC.Types.Unique.Set (nonDetEltsUniqSet)
    
    109 108
     
    
    ... ... @@ -120,7 +119,6 @@ import GHC.Data.Maybe (firstJusts)
    120 119
     import Control.Monad
    
    121 120
     import Data.Functor.Identity (Identity(..))
    
    122 121
     import qualified Data.List.NonEmpty as NE
    
    123
    -import Data.Monoid as DM ( Any(..) )
    
    124 122
     import qualified Data.Semigroup as S ( (<>) )
    
    125 123
     import Data.Traversable (for)
    
    126 124
     
    
    ... ... @@ -3143,6 +3141,7 @@ uUnfilledVar2 env@(UE { u_defer = def_eq_ref, u_given_eq_lvl = given_eq_lvl })
    3143 3141
         do { traceTc "uUnfilledVar2 not ok" $
    
    3144 3142
                  vcat [ text "tv1:" <+> ppr tv1
    
    3145 3143
                       , text "ty2:" <+> ppr ty2
    
    3144
    +                  , text "given_eq_lvl:" <+> ppr given_eq_lvl
    
    3146 3145
                       , text "simple-unify-chk:" <+> ppr (simpleUnifyCheck UC_OnTheFly given_eq_lvl tv1 ty2)
    
    3147 3146
                       ]
    
    3148 3147
                    -- Occurs check or an untouchable: just defer
    
    ... ... @@ -3246,6 +3245,7 @@ lhsPriority tv
    3246 3245
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3247 3246
     Question: given a homogeneous equality (alpha ~# ty), when is it OK to
    
    3248 3247
     unify alpha := ty?
    
    3248
    +
    
    3249 3249
     (This note only applies to /homogeneous/ equalities, in which both
    
    3250 3250
     sides have the same kind.)
    
    3251 3251
     
    
    ... ... @@ -3354,6 +3354,14 @@ Needless to say, all there are wrinkles:
    3354 3354
         GHC.Tc.Solver.floatEqualities, around Nov 2020.  It's much easier
    
    3355 3355
         to unify in-place, with no floating.
    
    3356 3356
     
    
    3357
    +* (COERCIONS) What if there are coercions in the RHS?  E.g.
    
    3358
    +        alpha ~ (ty |> co)
    
    3359
    +   or   alpha ~ (ty co)
    
    3360
    +   We only recurse into the `coercionType` of `co` rather than `co` itself.
    
    3361
    +   Why? Mainly because `co` might be a coercion hole, in which case we /can't/
    
    3362
    +   recurse into the coercion that will eventually fill the hole.  This came
    
    3363
    +   up in #26543.
    
    3364
    +
    
    3357 3365
     Note [TyVar/TyVar orientation]
    
    3358 3366
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3359 3367
     See also Note [Fundeps with instances, and equality orientation]
    
    ... ... @@ -3619,6 +3627,8 @@ simpleUnifyCheck :: UnifyCheckCaller -> TcLevel -> TcTyVar -> TcType -> SimpleUn
    3619 3627
     -- unification might still be OK, but it'll take more work to do
    
    3620 3628
     -- (use the full 'checkTypeEq').
    
    3621 3629
     --
    
    3630
    +-- See Note [simpleUnifyCheck]
    
    3631
    +--
    
    3622 3632
     -- * Rejects if lhs_tv occurs in rhs_ty (occurs check)
    
    3623 3633
     -- * Rejects foralls unless
    
    3624 3634
     --      lhs_tv is RuntimeUnk (used by GHCi debugger)
    
    ... ... @@ -3638,10 +3648,7 @@ simpleUnifyCheck caller given_eq_lvl lhs_tv rhs
    3638 3648
       | otherwise
    
    3639 3649
       = SUC_NotSure
    
    3640 3650
       where
    
    3641
    -    lhs_info = metaTyVarInfo lhs_tv
    
    3642
    -
    
    3643
    -    !(occ_in_ty, occ_in_co) = mkOccFolders (tyVarName lhs_tv)
    
    3644
    -
    
    3651
    +    lhs_info           = metaTyVarInfo lhs_tv
    
    3645 3652
         lhs_tv_lvl         = tcTyVarLevel lhs_tv
    
    3646 3653
         lhs_tv_is_concrete = isConcreteTyVar lhs_tv
    
    3647 3654
     
    
    ... ... @@ -3660,11 +3667,12 @@ simpleUnifyCheck caller given_eq_lvl lhs_tv rhs
    3660 3667
                    UC_OnTheFly   -> False
    
    3661 3668
     
    
    3662 3669
         rhs_is_ok (TyVarTy tv)
    
    3663
    -      | lhs_tv == tv                                    = False
    
    3664
    -      | tcTyVarLevel tv `strictlyDeeperThan` lhs_tv_lvl = False
    
    3665
    -      | lhs_tv_is_concrete, not (isConcreteTyVar tv)    = False
    
    3666
    -      | occ_in_ty $! (tyVarKind tv)                     = False
    
    3667
    -      | otherwise                                       = True
    
    3670
    +       | lhs_tv == tv                                    = False -- Occurs check
    
    3671
    +       | tcTyVarLevel tv `strictlyDeeperThan` lhs_tv_lvl = False
    
    3672
    +       | lhs_tv_is_concrete, not (isConcreteTyVar tv)    = False
    
    3673
    +       | not (rhs_is_ok $! tyVarKind tv)                 = False
    
    3674
    +       | otherwise                                       = True
    
    3675
    +       -- Hmm.  We probably don't need the level check inside the kind, but no harm
    
    3668 3676
     
    
    3669 3677
         rhs_is_ok (FunTy {ft_af = af, ft_mult = w, ft_arg = a, ft_res = r})
    
    3670 3678
           | not forall_ok, isInvisibleFunArg af = False
    
    ... ... @@ -3681,33 +3689,44 @@ simpleUnifyCheck caller given_eq_lvl lhs_tv rhs
    3681 3689
           | otherwise = False
    
    3682 3690
     
    
    3683 3691
         rhs_is_ok (AppTy t1 t2)    = rhs_is_ok t1 && rhs_is_ok t2
    
    3684
    -    rhs_is_ok (CastTy ty co)   = not (occ_in_co co) && rhs_is_ok ty
    
    3685
    -    rhs_is_ok (CoercionTy co)  = not (occ_in_co co)
    
    3692
    +    rhs_is_ok (CastTy ty co)   = co_is_ok co && rhs_is_ok ty
    
    3693
    +    rhs_is_ok (CoercionTy co)  = co_is_ok co
    
    3686 3694
         rhs_is_ok (LitTy {})       = True
    
    3687 3695
     
    
    3696
    +    -- For coercions we look only in the /type/ of the coercion
    
    3697
    +    -- See (SUC1) in Note [simpleUnifyCheck]
    
    3698
    +    co_is_ok co = rhs_is_ok (coercionType co)
    
    3688 3699
     
    
    3689
    -mkOccFolders :: Name -> (TcType -> Bool, TcCoercion -> Bool)
    
    3690
    --- These functions return True
    
    3691
    ---   * if lhs_tv occurs (incl deeply, in the kind of variable)
    
    3692
    ---   * if there is a coercion hole
    
    3693
    --- No expansion of type synonyms
    
    3694
    -mkOccFolders lhs_tv = ( getAny . runFVTop . check_ty
    
    3695
    -                      , getAny . runFVTop . check_co)
    
    3696
    -  where
    
    3697
    -    check_ty :: Type -> FV BoundVars Any
    
    3698
    -    !(check_ty, _, check_co, _) = foldTyCo occ_folder
    
    3699
    -
    
    3700
    -    occ_folder :: TyCoFolder (FV BoundVars Any)
    
    3701
    -    occ_folder = TyCoFolder { tcf_view  = noView  -- Don't expand synonyms
    
    3702
    -                            , tcf_tyvar = do_tcv, tcf_covar = do_tcv
    
    3703
    -                            , tcf_hole  = do_hole
    
    3704
    -                            , tcf_tycobinder = addBndrFV }
    
    3705
    -
    
    3706
    -    do_tcv v = (MkFV $ \ bvs ->
    
    3707
    -                Any (not (v `elemVarSet` bvs) && tyVarName v == lhs_tv))
    
    3708
    -               `mappend` check_ty (varType v)
    
    3709
    -
    
    3710
    -    do_hole _hole = MkFV $ \ _bvs -> DM.Any True  -- Reject coercion holes
    
    3700
    +{- Note [simpleUnifyCheck]
    
    3701
    +~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3702
    +The function `simpleUnifyCheck` is asimple, /fast/ check for unifying (tv ~ rhs).
    
    3703
    +It can return a definite decision (SUC_CannotUnify of SUC_CanUnify), or uncertainty
    
    3704
    +(SUC_NotSure).  In the latter case we will later use `checkTyEqRhs` to resolve.
    
    3705
    +In particular, `simpleUnifyCheck`:
    
    3706
    +
    
    3707
    +* Rejects if lhs_tv occurs in rhs_ty (occurs check)
    
    3708
    +* Rejects foralls unless
    
    3709
    +      lhs_tv is RuntimeUnk (used by GHCi debugger)
    
    3710
    +          or is a QL instantiation variable
    
    3711
    +* Rejects a non-concrete type if lhs_tv is concrete
    
    3712
    +* Rejects type families unless fam_ok=True
    
    3713
    +* Does a level-check for type variables, to avoid skolem escape
    
    3714
    +
    
    3715
    +This function is pretty heavily used, so it's optimised not to allocate.
    
    3716
    +
    
    3717
    +(SUC1) `simpleUnifyCheck` used by QuickLook's `qlUnify`, and anything other than
    
    3718
    +  SUC_CanUnify will tell `qlUnify` not to proceed.  That makes QuickLook depend
    
    3719
    +  (regrettably, delicately) on the exact choices made by `simpleUnifyCheck`.
    
    3720
    +
    
    3721
    +  A case in point: in #26543. In the repro case in the Descriptions, `qlUnify` failed
    
    3722
    +  because there was a coercion hole in the RHS; but one that was ultimately Refl.
    
    3723
    +
    
    3724
    +  So we only look at the /kind/ of a coercion, not the evidence itself.  I'm a bit
    
    3725
    +  worried about building a loop, if the evidence mentions the LHS unification
    
    3726
    +  variable; but I can't see how that can happen, and I /really/ don't want to be
    
    3727
    +  super-conservative for coercion holes (#26543).  So, for now at least, we look
    
    3728
    +  just at the kind of the coercion.
    
    3729
    +-}
    
    3711 3730
     
    
    3712 3731
     {- *********************************************************************
    
    3713 3732
     *                                                                      *
    
    ... ... @@ -4337,7 +4356,11 @@ checkCo flags co =
    4337 4356
             -- Occurs check (can promote)
    
    4338 4357
             | OC_Check lhs_tv occ_prob <- occ
    
    4339 4358
             , LC_Promote { lc_lvlp = lhs_tv_lvl } <- lc
    
    4340
    -        -> do { reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfCo co)
    
    4359
    +        -> do { reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl $
    
    4360
    +                          tyCoVarsOfCo co
    
    4361
    +                          -- Maybe we should just check the free vars of the
    
    4362
    +                          -- /type/ of the coercion, to line up with
    
    4363
    +                          -- (SUC1) in Note [simpleUnifyCheck]
    
    4341 4364
                   ; return $
    
    4342 4365
                     if cterHasNoProblem reason
    
    4343 4366
                     then pure co
    
    ... ... @@ -4697,12 +4720,14 @@ simpleOccursCheck :: OccursCheck -> TcTyVar -> TyVarCheckResult m
    4697 4720
     simpleOccursCheck OC_None _
    
    4698 4721
       = TyVarCheck_Success
    
    4699 4722
     simpleOccursCheck (OC_Check lhs_tv occ_prob) occ_tv
    
    4700
    -  | lhs_tv == tyVarName occ_tv || check_kind (tyVarKind occ_tv)
    
    4701
    -  = TyVarCheck_Error (cteProblem occ_prob)
    
    4702
    -  | otherwise
    
    4703
    -  = TyVarCheck_Success
    
    4723
    +  | check_fv occ_tv = TyVarCheck_Error (cteProblem occ_prob)
    
    4724
    +  | otherwise       = TyVarCheck_Success
    
    4704 4725
       where
    
    4705
    -    (check_kind, _) = mkOccFolders lhs_tv
    
    4726
    +    check_fv :: TyCoVar -> Bool  -- True <=> occurs check
    
    4727
    +    check_fv occ_tcv
    
    4728
    +       | lhs_tv == tyVarName occ_tcv                    = True
    
    4729
    +       | anyFreeVarsOfType check_fv (tyVarKind occ_tcv) = True
    
    4730
    +       | otherwise                                      = False
    
    4706 4731
     
    
    4707 4732
     -------------------------
    
    4708 4733
     tyVarLevelCheck :: LevelCheck m -> TcTyVar -> TyVarCheckResult m
    

  • testsuite/tests/typecheck/should_compile/T26543_orig.hs
    1
    +-- This test is from the Description of #26543
    
    2
    +
    
    3
    +{-# LANGUAGE GHC2024, TypeAbstractions, AllowAmbiguousTypes, NoImplicitPrelude,
    
    4
    +                      TypeFamilies, UndecidableInstances #-}
    
    5
    +module T26543_orig where
    
    6
    +
    
    7
    +import Data.Kind
    
    8
    +import Control.Applicative (Applicative(..))
    
    9
    +import Prelude (type (~), ($))
    
    10
    +
    
    11
    +type CAT k = k -> k -> Type
    
    12
    +
    
    13
    +type family (~>) :: CAT k
    
    14
    +type family Ob (a :: k) :: Constraint
    
    15
    +type family UN (w :: j -> k) (wa :: k) :: j
    
    16
    +
    
    17
    +class HasBinaryProducts k where
    
    18
    +  type (a :: k) && (b :: k) :: k
    
    19
    +  withObProd :: (Ob (a :: k), Ob b) => ((Ob (a && b)) => r) -> r
    
    20
    +  (&&&) :: ((a :: k) ~> x) -> (a ~> y) -> (a ~> (x && y))
    
    21
    +
    
    22
    +data AP (f :: Type -> Type) k = A k
    
    23
    +type instance UN A (A k) = k
    
    24
    +
    
    25
    +type Ap :: CAT (AP f k)
    
    26
    +data Ap a b where
    
    27
    +  Ap :: forall {k} a b f. (Ob a, Ob b) => f (a ~> b) -> Ap (A a :: AP f k) (A b)
    
    28
    +
    
    29
    +type instance (~>) = Ap
    
    30
    +type instance Ob a = (a ~ A (UN A a), Ob (UN A a))
    
    31
    +
    
    32
    +instance (Applicative f, HasBinaryProducts k) => HasBinaryProducts (AP f k) where
    
    33
    +  type a && b = A (UN A a && UN A b)
    
    34
    +  withObProd @(A a) @(A b) r = withObProd @k @a @b r
    
    35
    +  -- (&&&) :: Ap (a :: AP f k) x -> Ap a y -> Ap a (x && y)
    
    36
    +  Ap @_ @x f &&& Ap @_ @y g = withObProd @k @x @y $ Ap (liftA2 (&&&) f g)

  • testsuite/tests/typecheck/should_compile/all.T
    ... ... @@ -969,3 +969,4 @@ test('ExpansionQLIm', normal, compile, [''])
    969 969
     test('T23135', normal, compile, [''])
    
    970 970
     test('LazyFieldAnnotations', normal, compile, [''])
    
    971 971
     test('T27557', normal, compile, [''])
    
    972
    +test('T26543_orig', normal, compile, [''])