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

Commits:

4 changed files:

Changes:

  • compiler/GHC/Tc/Gen/App.hs
    ... ... @@ -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
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

  • compiler/GHC/Tc/Utils/Unify.hs
    ... ... @@ -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
     *                                                                      *
    

  • testsuite/tests/impredicative/T26543.hs
    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

  • testsuite/tests/impredicative/all.T
    ... ... @@ -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, [''])