Skip to content
  • Ryan Scott's avatar
    Make validDerivPred ignore non-visible arguments to a class type constructor · fa86ac7c
    Ryan Scott authored
    Summary:
    GHC choked when trying to derive the following:
    
    ```
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE PolyKinds #-}
    module Example where
    
    class Category (cat :: k -> k -> *) where
      catId   :: cat a a
      catComp :: cat b c -> cat a b -> cat a c
    
    newtype T (c :: * -> * -> *) a b = MkT (c a b) deriving Category
    ```
    
    Unlike in #8865, where we were deriving `Category` for a concrete type like
    `Either`, in the above example we are attempting to derive an instance of the
    form:
    
    ```
    instance Category * c => Category (T * c) where ...
    ```
    
    (using `-fprint-explicit-kinds` syntax). But `validDerivPred` is checking if
    `sizePred (Category * c)` equals the number of free type variables in
    `Category * c`. But note that `sizePred` counts both type variables //and//
    type constructors, and `*` is a type constructor! So `validDerivPred`
    erroneously rejects the above instance.
    
    The fix is to make `validDerivPred` ignore non-visible arguments to the class
    type constructor (e.g., ignore `*` is `Category * c`) by using
    `filterOutInvisibleTypes`.
    
    Fixes #11833.
    
    Test Plan: ./validate
    
    Reviewers: goldfire, hvr, simonpj, austin, bgamari
    
    Reviewed By: bgamari
    
    Subscribers: thomie
    
    Differential Revision: https://phabricator.haskell.org/D2112
    
    GHC Trac Issues: #11833
    fa86ac7c