[commit: ghc] wip/T10180: New Lint check: no alternatives implies bottoming expression (a7d24cd)

git at git.haskell.org git at git.haskell.org
Sun Mar 22 19:12:26 UTC 2015


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/T10180
Link       : http://ghc.haskell.org/trac/ghc/changeset/a7d24cd9c100655b487f1911cb014fea738cd36c/ghc

>---------------------------------------------------------------

commit a7d24cd9c100655b487f1911cb014fea738cd36c
Author: Joachim Breitner <mail at joachim-breitner.de>
Date:   Sun Mar 22 17:32:26 2015 +0100

    New Lint check: no alternatives implies bottoming expression
    
    detected either by exprIsBottom or by an empty type.
    
    This was suggested by SPJ and fixes #10180.


>---------------------------------------------------------------

a7d24cd9c100655b487f1911cb014fea738cd36c
 compiler/coreSyn/CoreLint.hs |  6 +++++-
 compiler/types/TyCon.hs      | 10 ++++++++++
 compiler/types/Type.hs       | 12 +++++++++++-
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/compiler/coreSyn/CoreLint.hs b/compiler/coreSyn/CoreLint.hs
index 690836a..c615ea6 100644
--- a/compiler/coreSyn/CoreLint.hs
+++ b/compiler/coreSyn/CoreLint.hs
@@ -637,8 +637,12 @@ lintCoreExpr e@(Case scrut var alt_ty alts) =
      ; alt_ty   <- lintInTy alt_ty
      ; var_ty   <- lintInTy (idType var)
 
-     ; checkL (not (null alts && exprIsHNF scrut))
+     ; when (null alts) $
+     do { checkL (not (exprIsHNF scrut))
           (ptext (sLit "No alternatives for a case scrutinee in head-normal form:") <+> ppr scrut)
+        ; checkL (exprIsBottom scrut || isEmptyTy (exprType scrut))
+          (ptext (sLit "No alternatives for a case scrutinee not known to diverge for sure:") <+> ppr scrut)
+        }
 
      ; case tyConAppTyCon_maybe (idType var) of
          Just tycon
diff --git a/compiler/types/TyCon.hs b/compiler/types/TyCon.hs
index 8e0175a..c3723c4 100644
--- a/compiler/types/TyCon.hs
+++ b/compiler/types/TyCon.hs
@@ -42,6 +42,7 @@ module TyCon(
         promotableTyCon_maybe, promoteTyCon,
 
         isDataTyCon, isProductTyCon, isDataProductTyCon_maybe,
+        isEmptyDataTyCon,
         isEnumerationTyCon,
         isNewTyCon, isAbstractTyCon,
         isFamilyTyCon, isOpenFamilyTyCon,
@@ -1286,6 +1287,15 @@ isDataProductTyCon_maybe (TupleTyCon { dataCon = con })
   = Just con
 isDataProductTyCon_maybe _ = Nothing
 
+-- | True of datatypes with no constructors
+isEmptyDataTyCon :: TyCon -> Bool
+isEmptyDataTyCon tc
+  | AlgTyCon {algTcRhs = rhs} <- tc
+  , [] <- data_cons rhs
+  = True
+  | otherwise
+  = False
+
 -- | Is this a 'TyCon' representing a regular H98 type synonym (@type@)?
 isTypeSynonymTyCon :: TyCon -> Bool
 isTypeSynonymTyCon (SynonymTyCon {}) = True
diff --git a/compiler/types/Type.hs b/compiler/types/Type.hs
index a2d3392..9cec0bd 100644
--- a/compiler/types/Type.hs
+++ b/compiler/types/Type.hs
@@ -66,7 +66,7 @@ module Type (
 
         -- (Lifting and boxity)
         isUnLiftedType, isUnboxedTupleType, isAlgType, isClosedAlgType,
-        isPrimitiveType, isStrictType,
+        isPrimitiveType, isStrictType, isEmptyTy,
 
         -- * Main data types representing Kinds
         -- $kind_subtyping
@@ -1184,6 +1184,16 @@ isPrimitiveType ty = case splitTyConApp_maybe ty of
                                               isPrimTyCon tc
                         _                  -> False
 
+-- | True if the type has no non-bottom elements
+isEmptyTy :: Type -> Bool
+isEmptyTy ty
+    -- Data types with no constructors are empty
+    | Just (tc, _) <- splitTyConApp_maybe ty
+    , isEmptyDataTyCon tc
+    = True
+    | otherwise
+    = False
+
 {-
 ************************************************************************
 *                                                                      *



More information about the ghc-commits mailing list