Simon Peyton Jones pushed to branch wip/T26543b at Glasgow Haskell Compiler / GHC
Commits:
-
defc3eae
by Simon Peyton Jones at 2026-08-23T00:01:34+01:00
6 changed files:
- + changelog.d/T26543
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Utils/Unify.hs
- + testsuite/tests/typecheck/should_compile/T26543_orig.hs
- testsuite/tests/typecheck/should_compile/all.T
Changes:
| 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 |
| ... | ... | @@ -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))
|
| ... | ... | @@ -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
|
| ... | ... | @@ -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
|
| 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) |
| ... | ... | @@ -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, ['']) |