Simon Peyton Jones pushed to branch wip/26543 at Glasgow Haskell Compiler / GHC
Commits:
-
2d55348a
by Simon Peyton Jones at 2025-11-03T23:40:29+00:00
4 changed files:
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Utils/Unify.hs
- + testsuite/tests/impredicative/T26543.hs
- testsuite/tests/impredicative/all.T
Changes:
| ... | ... | @@ -2057,6 +2057,7 @@ qlUnify ty1 ty2 |
| 2057 | 2057 | -- Here we are in the TcM monad, which does not track enclosing
|
| 2058 | 2058 | -- Given equalities; so for quick-look unification we conservatively
|
| 2059 | 2059 | -- treat /any/ level outside this one as untouchable. Hence cur_lvl.
|
| 2060 | + -- See (UQL5) in Note [QuickLook unification]
|
|
| 2060 | 2061 | ; case simpleUnifyCheck UC_QuickLook cur_lvl kappa ty2 of
|
| 2061 | 2062 | SUC_CanUnify ->
|
| 2062 | 2063 | do { co <- unifyKind (Just (TypeThing ty2)) ty2_kind kappa_kind
|
| ... | ... | @@ -2129,6 +2130,17 @@ That is the entire point of qlUnify! Wrinkles: |
| 2129 | 2130 | |
| 2130 | 2131 | It's just not worth the trouble, we think (for now at least).
|
| 2131 | 2132 | |
| 2133 | +(UQL5) We call `simpleUnifyCheck` for the occurs-check etc; see (UQL1). Usually it's fine
|
|
| 2134 | + for `simpleUnifyCheck` to bale out saying `SUC_NotSure`, because usually we'll just generate
|
|
| 2135 | + an equality we solve later. But in QuickLook, baling out may mean we don't find a good
|
|
| 2136 | + type for an instantiation variable, which in turn may make the program fail to typecheck.
|
|
| 2137 | + So `simpleUnifyCheck` is more than just an erfficiency thing.
|
|
| 2138 | + Example (#26543): we get qlUnify( (Eq (alpha |> {co}) => beta) -> Int
|
|
| 2139 | + , kappa1 -> Int )
|
|
| 2140 | + where `{co}` is a coercion hole. We want to unify
|
|
| 2141 | + kappa1 := Eq (alpha |> {co}) => beta
|
|
| 2142 | + Failing to do so rejects the program. To allow this, we just check the /kind/ of the
|
|
| 2143 | + coercion hole {co}; see
|
|
| 2132 | 2144 | |
| 2133 | 2145 | Sadly discarded design alternative
|
| 2134 | 2146 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -3194,6 +3194,8 @@ simpleUnifyCheck :: UnifyCheckCaller -> TcLevel -> TcTyVar -> TcType -> SimpleUn |
| 3194 | 3194 | -- * Rejects type families unless fam_ok=True
|
| 3195 | 3195 | -- * Does a level-check for type variables, to avoid skolem escape
|
| 3196 | 3196 | --
|
| 3197 | +-- See also (UQL5) in Note [QuickLook unification]
|
|
| 3198 | +--
|
|
| 3197 | 3199 | -- This function is pretty heavily used, so it's optimised not to allocate
|
| 3198 | 3200 | simpleUnifyCheck caller given_eq_lvl lhs_tv rhs
|
| 3199 | 3201 | | not $ touchabilityTest given_eq_lvl lhs_tv
|
| ... | ... | @@ -3254,9 +3256,11 @@ simpleUnifyCheck caller given_eq_lvl lhs_tv rhs |
| 3254 | 3256 | |
| 3255 | 3257 | |
| 3256 | 3258 | mkOccFolders :: Name -> (TcType -> Bool, TcCoercion -> Bool)
|
| 3257 | --- These functions return True
|
|
| 3258 | --- * if lhs_tv occurs (incl deeply, in the kind of variable)
|
|
| 3259 | --- * if there is a coercion hole
|
|
| 3259 | +-- These functions are used when doing an occurs check.
|
|
| 3260 | +-- They return True if lhs_tv occurs in the type, or coercion resp,
|
|
| 3261 | +-- including deeply,
|
|
| 3262 | +-- - in the kind of type variable
|
|
| 3263 | +-- - in the kind of a coercion hole
|
|
| 3260 | 3264 | -- No expansion of type synonyms
|
| 3261 | 3265 | mkOccFolders lhs_tv = (getAny . check_ty, getAny . check_co)
|
| 3262 | 3266 | where
|
| ... | ... | @@ -3270,7 +3274,14 @@ mkOccFolders lhs_tv = (getAny . check_ty, getAny . check_co) |
| 3270 | 3274 | `mappend` check_ty (varType v)
|
| 3271 | 3275 | |
| 3272 | 3276 | do_bndr is tcv _faf = extendVarSet is tcv
|
| 3273 | - do_hole _is _hole = DM.Any True -- Reject coercion holes
|
|
| 3277 | + |
|
| 3278 | + do_hole _is hole = check_ty (varType (coHoleCoVar hole))
|
|
| 3279 | + -- For coercion holes, look in the kind of the hole
|
|
| 3280 | + -- I worry that the coercion hole could be filled with a coercion that
|
|
| 3281 | + -- mentions `lhs_tv` in the coercion, but not in the /kind/ of that
|
|
| 3282 | + -- coercion. But that seems remote; and it is the /same/ choice that is
|
|
| 3283 | + -- made in `GHC.Tc.Utils.Unify.checkCo`.
|
|
| 3284 | + -- See (UQL5) in Note [QuickLook unification]
|
|
| 3274 | 3285 | |
| 3275 | 3286 | {- *********************************************************************
|
| 3276 | 3287 | * *
|
| 1 | +{-# LANGUAGE GHC2024, TypeAbstractions, AllowAmbiguousTypes, TypeFamilies #-}
|
|
| 2 | +module T26543 where
|
|
| 3 | + |
|
| 4 | +import Data.Kind (Type)
|
|
| 5 | + |
|
| 6 | +withObProd :: forall a r. ((Eq a) => r) -> r
|
|
| 7 | +withObProd = withObProd
|
|
| 8 | + |
|
| 9 | +type Ap :: k -> Type
|
|
| 10 | +data Ap a where
|
|
| 11 | + Ap :: forall {k} (a :: k). Ap a
|
|
| 12 | + |
|
| 13 | +type family Ap2 :: Type -> Type
|
|
| 14 | +type instance Ap2 = Ap
|
|
| 15 | + |
|
| 16 | +f :: forall (a :: Type). Ap2 a -> Bool
|
|
| 17 | +f (Ap @x') = withObProd @x' $ True
|
|
| 18 | + |
|
| 19 | + |
|
| 20 | +-- ($) :: (p->q) -> p -> q
|
|
| 21 | +-- QL sees that: p = Eq a => Bool
|
|
| 22 | +-- q = Bool |
| ... | ... | @@ -22,3 +22,4 @@ test('T17332', normal, compile_fail, ['']) |
| 22 | 22 | test('expr-sig', normal, compile, [''])
|
| 23 | 23 | test('Dict', normal, compile, [''])
|
| 24 | 24 | test('T24676', normal, compile, [''])
|
| 25 | +test('T26543', normal, compile, ['']) |