Skip to content

Type patterns (#22478, #18986)

Andrei Borzenkov requested to merge wip/sand-witch/pattern-@a-binders into master

Improved name resolution and type checking of type patterns in constructors:

  1. HsTyPat: a new dedicated data type that represents type patterns in HsConPatDetails instead of reusing HsPatSigType

  2. rnHsTyPat: a new function that renames a type pattern and collects its binders into three groups:

    • explicitly bound type variables, excluding locally bound variables
    • implicitly bound type variables from kind signatures (only if ScopedTypeVariables are enabled)
    • named wildcards (only from kind signatures)

    a. rnHsPatSigTypeBindingVars: removed in favor of rnHsTyPat

    b. rnImplcitTvBndrs: removed because no longer needed

  3. collect_pat: updated to collect type variable binders from type patterns (this means that types and terms use the same infrastructure to detect conflicting bindings, unused variables and name shadowing)

    a. CollVarTyVarBinders: a new CollectFlag constructor that enables collection of type variables

  4. tcHsTyPat: a new function that typechecks type patterns, capable of handling polymorphic kinds. See Note [Type patterns: binders and unifiers]

Examples of code that is now accepted:

   f = \(P @a) -> \(P @a) -> ...  -- triggers -Wname-shadowing

   g :: forall a. Proxy a -> ...
   g (P @a) = ...                 -- also triggers -Wname-shadowing

   h (P @($(TH.varT (TH.mkName "t")))) = ...
                                  -- t is bound at splice time

   j (P @(a :: (x,x))) = ...      -- (x,x) is no longer rejected

   data T where
     MkT :: forall (f :: forall k. k -> Type).
       f Int -> f Maybe -> T
   k :: T -> ()
   k (MkT @f (x :: f Int) (y :: f Maybe)) = ()
                                  -- f :: forall k. k -> Type

Examples of code that is rejected with better error messages:

  f (Left @a @a _) = ...
  -- new message:
  --     • Conflicting definitions for ‘a’
  --       Bound at: Test.hs:1:11
  --                 Test.hs:1:14

Examples of code that is now rejected:

  {-# OPTIONS_GHC -Werror=unused-matches #-}
  f (P @a) = ()
  -- Defined but not used: type variable ‘a’
Edited by Andrei Borzenkov

Merge request reports