Impove Lint check for empty cases
The Lint check for empty case alternative looks wonky to me
; case tyConAppTyCon_maybe (idType var) of
Just tycon
| debugIsOn
, isAlgTyCon tycon
, not (isAbstractTyCon tycon)
, null (tyConDataCons tycon)
, not (exprIsDeadEnd scrut)
-> pprTrace "Lint warning: case binder's type has no constructors" (ppr var <+> ppr (idType var))
-- This can legitimately happen for type families
$ return ()
_otherwise -> return ()
For example
data T a = T1 !(F a) | T2 Int
data DataConCantHappen -- No constructors
type instance F Bool = DataConCantHappen
f (x::T Bool) = case x of
T1 v -> case (v |> co) of {}
T2 x -> blah
where co :: F Bool ~ Void
Here the T1
alternative in f
's RHS is in fact inaccessible: T1
is a strict constructor and there
are no inhabitants of (F Bool)
, which is equal to DataConCantHappen
. GHC itself uses
this a lot in HsSyn to make inactive constructors inaccessible.
So there is no hope of being sure that the scrutinee is bottoming -- except via its type. And in this test we've already checked for empty data cons.
I think we need something more like
; checkL (not (null alts) || exprIsDeadEnd scrut) $
hang (text "Illegal empty case")
2 (ppr case_bndr <+> ppr case_bndr_ty $$ ppr e)
where exprIsDeadEnd
checks for empty types (which it already does, more or less).