content: {-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-}
  {-# LANGUAGE PatternSynonyms #-}
  {-# LANGUAGE ViewPatterns #-}
  {-# LANGUAGE BangPatterns #-}
  module Lib where
  
  import Data.Void
  
  strictConst :: a -> b -> a
  strictConst a b = seq b a
  
  pattern F  <- (const       False -> True)
  pattern SF <- (strictConst False -> True)
  
  -- | The second clause is redundant, really, because (the matcher of) 'F' is
  -- not strict in its argument. As a result, the third clause is *not*
  -- redundant, but inaccessible RHS! Deleting the third clause would be unsound.
  -- This is bad, especially because this outcome depends entirely on the
  -- strictness of 'F's matcher.
  f :: Bool -> Bool -> ()
  f _  True = ()
  f F  True = ()
  f !_ True = ()
  f _  _    = ()
  
  -- | In this example, the second clause really is inaccessible RHS (because SF
  -- is a strict match). And as a result, the third clause *is* redundant.
  f2 :: Bool -> Bool -> ()
  f2 _  True = ()
  f2 SF True = ()
  f2 !_ True = ()
  f2 _  _    = ()
  
  pattern T <- (const True -> True)
  {-# COMPLETE T, F :: Void #-}
  
  -- | But we consider COMPLETE signatures to cover bottom. Hence the last clause
  -- here should be redundant, not inaccessible RHS.
  f3 :: Void -> ()
  f3 T  = ()
  f3 F  = ()
  f3 !_ = ()
  
  -- The following is related to the same issue:
  
  -- | The following function definition is exhaustive.
  -- Its clauses are *not* inaccessible RHS, because neither
  -- pattern synonym is strict.
  g :: Void -> ()
  g F = ()
  g T = ()
  