Commit a89e0d45 authored by Fredrik Wieczerkowski's avatar Fredrik Wieczerkowski

Apply basic heuristic to check whether guard is always true in WarnCheck

When checking whether a case arm is reachable, consider wildcard
patterns with a guard containing 'True', 'success' or 'otherwise' to be
exhaustive.
parent 2467c2dc
......@@ -709,16 +709,22 @@ type EqnSet = IntSet.IntSet
processEqs :: [EqnInfo] -> WCM ([ExhaustivePats], EqnSet, Bool)
processEqs [] = return ([], IntSet.empty, False)
processEqs eqs@((n, ps, gs):eqs')
| null ps = if null gs then return ([], IntSet.singleton n, length eqs > 1)
else do -- Current expression is guarded, thus potentially
-- non-exhaustive. Therefore process remaining expressions.
(missing', used', _) <- processEqs eqs'
return (missing', IntSet.insert n used', length eqs > 1)
| any isLitPat firstPats = processLits eqs
| any isConPat firstPats = processCons eqs
| all isVarPat firstPats = processVars eqs
| otherwise = internalError "Checks.WarnCheck.processEqs"
| null ps = if guardsExhaustive then return ([], IntSet.singleton n, length eqs > 1)
else do -- Current expression is guarded, thus potentially
-- non-exhaustive. Therefore process remaining expressions.
(missing', used', _) <- processEqs eqs'
return (missing', IntSet.insert n used', length eqs > 1)
| any isLitPat firstPats = processLits eqs
| any isConPat firstPats = processCons eqs
| all isVarPat firstPats = processVars eqs
| otherwise = internalError "Checks.WarnCheck.processEqs"
where firstPats = map firstPat eqs
guardsExhaustive = null gs || all alwaysTrue gs
alwaysTrue :: CondExpr () -> Bool
alwaysTrue (CondExpr _ (Constructor _ _ q) _) = elem ident ["True", "success", "otherwise"]
where ident = idName $ qidIdent q
alwaysTrue _ = False
-- |Literal patterns are checked by extracting the matched literals
-- and constructing a pattern for any missing case.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment