Skip to content

Typechecker plugins aren't run when doing pattern-match checks

Very common code with type-level natural numbers:

{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}

data Vec :: Nat -> Type -> Type where
  Nil  :: Vec 0 a
  (:>) :: a -> Vec n a -> Vec (n + 1) a

infixr 5 :>

merge :: Vec n a -> Vec n a -> Vec (n + n) a
merge Nil       Nil       = Nil
merge (x :> xs) (y :> ys) = x :> y :> merge xs ys

(or zip, zipWith etc).

This will, with -Wincomplete-patterns, lead to spurious "incomplete pattern match" errors.

What happens during pattern match checking is that we try to find whether the following Givens are inconsistent:

[G] n1 ~ 0
[G] n2 + 1 ~ n1

If we ran the usual type-checker plugins on this, we'd expect these Givens to be reported as inconsistent.

However, this wasn't happening. After a quick investigation, it seems that the tcg_tc_plugin_solvers field of TcGblEnv is empty in this context. Here's what I see in the tc-trace:

solveSimpleGivens {
  [[G] pm_d10l_d10l {0} :: n1 ~# 0 (CNonCanonical)]
Emitting fresh work
  {[G] pm_d10l_d10l {0} :: n1 ~# 0 (CNonCanonical)}
----------------------------- 
Start solver pipeline {
  tclevel = 0
  work item = [G] pm_d10l_d10l {0} :: n1 ~# 0 (CNonCanonical)
  inerts = {Type-function equalities = {[G] co_a10c {0}
                                              :: n2 + 1 ~# n1}
            Innermost given equalities = 0
            Given eqs at this level = True}
  rest of worklist = WL {}
[...]
End solver pipeline }
runTcPluginsGiven: no solvers -- trace I added in runTcPluginsGiven
End solveSimpleGivens }

So it looks to me that typechecker plugins are incorrectly initialised for calls within the pattern match checker.

Edited by sheaf
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information