Skip to content

decomposeRuleLhs reports bogus error

Consider

f :: Int -> Int
f x = x

{-# RULES "foo" forall a (x::a) (g :: a -> Int). f (g x) = 2 #-}

Currently compiling with -O gives

Foo.hs:8:11: error:
    Rule "foo": Forall'd variable ‘a’ does not appear on left hand side
  |
8 | {-# RULES "foo" forall a (x::a) (g :: a -> Int). f (g x) = 2 #-}
  |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Diagnosis

GHC.HsToCore.Binds.decomposeRuleLhs takes the free vars of the LHS and checks that all of those free vars are among the binders. But the (shallow) free vars of f (g x) are are just {f,g,x}, but not a. Yet a is a binder.

Clearly we want the deep free vars of the LHS for this error check.

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