dsGRHS :: HsMatchContext Name -> [Pat Id] -> Type -> LGRHS Id -> DsM MatchResult
dsGRHS hs_ctx _ rhs_ty (L _ (GRHS guards rhs))
- = matchGuards (map unLoc guards) hs_ctx rhs rhs_ty
+ = matchGuards (map unLoc guards) (PatGuard hs_ctx) rhs rhs_ty
\end{code}
\begin{code}
matchGuards :: [Stmt Id] -- Guard
- -> HsMatchContext Name -- Context
+ -> HsStmtContext Name -- Context
-> LHsExpr Id -- RHS
-> Type -- Type of RHS of guard
-> DsM MatchResult
matchGuards (BindStmt pat bind_rhs _ _ : stmts) ctx rhs rhs_ty = do
match_result <- matchGuards stmts ctx rhs rhs_ty
core_rhs <- dsLExpr bind_rhs
- matchSinglePat core_rhs ctx pat rhs_ty match_result
+ matchSinglePat core_rhs (StmtCtxt ctx) pat rhs_ty match_result
isTrueLHsExpr :: LHsExpr Id -> Maybe (CoreExpr -> DsM CoreExpr)
import Outputable
import FastString
+import Control.Monad( when )
import qualified Data.Map as Map
\end{code}
-> [EquationInfo] -- Info about patterns, etc. (type synonym below)
-> DsM MatchResult -- Desugared result!
-matchCheck ctx vars ty qs = do
- dflags <- getDOptsDs
- matchCheck_really dflags ctx vars ty qs
+matchCheck ctx vars ty qs
+ = do { dflags <- getDOptsDs
+ ; matchCheck_really dflags ctx vars ty qs }
matchCheck_really :: DynFlags
-> DsMatchContext
-> Type
-> [EquationInfo]
-> DsM MatchResult
-matchCheck_really dflags ctx vars ty qs
- | incomplete && shadow = do
- dsShadowWarn ctx eqns_shadow
- dsIncompleteWarn ctx pats
- match vars ty qs
- | incomplete = do
- dsIncompleteWarn ctx pats
- match vars ty qs
- | shadow = do
- dsShadowWarn ctx eqns_shadow
- match vars ty qs
- | otherwise =
- match vars ty qs
- where (pats, eqns_shadow) = check qs
- incomplete = want_incomplete && (notNull pats)
- want_incomplete = case ctx of
- DsMatchContext RecUpd _ ->
- dopt Opt_WarnIncompletePatternsRecUpd dflags
- _ ->
- dopt Opt_WarnIncompletePatterns dflags
- shadow = dopt Opt_WarnOverlappingPatterns dflags
- && not (null eqns_shadow)
+matchCheck_really dflags ctx@(DsMatchContext hs_ctx _) vars ty qs
+ = do { when shadow (dsShadowWarn ctx eqns_shadow)
+ ; when incomplete (dsIncompleteWarn ctx pats)
+ ; match vars ty qs }
+ where
+ (pats, eqns_shadow) = check qs
+ incomplete = incomplete_flag hs_ctx && (notNull pats)
+ shadow = dopt Opt_WarnOverlappingPatterns dflags
+ && notNull eqns_shadow
+
+ incomplete_flag :: HsMatchContext id -> Bool
+ incomplete_flag (FunRhs {}) = dopt Opt_WarnIncompletePatterns dflags
+ incomplete_flag CaseAlt = dopt Opt_WarnIncompletePatterns dflags
+
+ incomplete_flag LambdaExpr = dopt Opt_WarnIncompleteUniPatterns dflags
+ incomplete_flag PatBindRhs = dopt Opt_WarnIncompleteUniPatterns dflags
+ incomplete_flag ProcExpr = dopt Opt_WarnIncompleteUniPatterns dflags
+
+ incomplete_flag RecUpd = dopt Opt_WarnIncompletePatternsRecUpd dflags
+
+ incomplete_flag ThPatQuote = False
+ incomplete_flag (StmtCtxt {}) = False -- Don't warn about incomplete patterns
+ -- in list comprehensions, pattern guards
+ -- etc. They are often *supposed* to be
+ -- incomplete
\end{code}
This variable shows the maximum number of lines of output generated for warnings.
match_result' <- matchSinglePat scrut hs_ctx pat rhs_ty match_result
extractMatchResult match_result' fail_expr
-
matchSinglePat :: CoreExpr -> HsMatchContext Name -> LPat Id
-> Type -> MatchResult -> DsM MatchResult
-- Do not warn about incomplete patterns
-- Used for things like [ e | pat <- stuff ], where
-- incomplete patterns are just fine
-matchSinglePat (Var var) _ (L _ pat) ty match_result
- = match [var] ty [EqnInfo { eqn_pats = [pat], eqn_rhs = match_result }]
-
-matchSinglePat scrut hs_ctx pat ty match_result = do
- var <- selectSimpleMatchVarL pat
- match_result' <- matchSinglePat (Var var) hs_ctx pat ty match_result
- return (adjustMatchResult (bindNonRec var scrut) match_result')
+matchSinglePat (Var var) ctx (L _ pat) ty match_result
+ = do { locn <- getSrcSpanDs
+ ; matchCheck (DsMatchContext ctx locn)
+ [var] ty
+ [EqnInfo { eqn_pats = [pat], eqn_rhs = match_result }] }
+
+matchSinglePat scrut hs_ctx pat ty match_result
+ = do { var <- selectSimpleMatchVarL pat
+ ; match_result' <- matchSinglePat (Var var) hs_ctx pat ty match_result
+ ; return (adjustMatchResult (bindNonRec var scrut) match_result') }
\end{code}
| LambdaExpr -- Patterns of a lambda
| CaseAlt -- Patterns and guards on a case alternative
| ProcExpr -- Patterns of a proc
- | PatBindRhs -- A pattern binding, or its guards
- -- [x] = e, or x | [y] <- e = e
+ | PatBindRhs -- A pattern binding eg [y] <- e = e
+
| RecUpd -- Record update [used only in DsExpr to
-- tell matchWrapper what sort of
-- runtime error message to generate]
- | StmtCtxt (HsStmtContext id) -- Pattern of a do-stmt or list comprehension
+
+ | StmtCtxt (HsStmtContext id) -- Pattern of a do-stmt, list comprehension,
+ -- pattern guard, etc
+
| ThPatQuote -- A Template Haskell pattern quotation [p| (a,b) |]
deriving (Data, Typeable)
| Opt_WarnHiShadows
| Opt_WarnImplicitPrelude
| Opt_WarnIncompletePatterns
+ | Opt_WarnIncompleteUniPatterns
| Opt_WarnIncompletePatternsRecUpd
| Opt_WarnMissingFields
| Opt_WarnMissingImportList
( "warn-hi-shadowing", Opt_WarnHiShadows, nop ),
( "warn-implicit-prelude", Opt_WarnImplicitPrelude, nop ),
( "warn-incomplete-patterns", Opt_WarnIncompletePatterns, nop ),
+ ( "warn-incomplete-uni-patterns", Opt_WarnIncompleteUniPatterns, nop ),
( "warn-incomplete-record-updates", Opt_WarnIncompletePatternsRecUpd, nop ),
( "warn-missing-fields", Opt_WarnMissingFields, nop ),
( "warn-missing-import-lists", Opt_WarnMissingImportList, nop ),
]
minusWOpts :: [DynFlag]
+-- Things you get with -W
minusWOpts
= standardWarnings ++
[ Opt_WarnUnusedBinds,
]
minusWallOpts :: [DynFlag]
+-- Things you get with -Wall
minusWallOpts
= minusWOpts ++
[ Opt_WarnTypeDefaults,
Opt_WarnMissingSigs,
Opt_WarnHiShadows,
Opt_WarnOrphans,
- Opt_WarnUnusedDoBind,
- Opt_WarnIdentities
+ Opt_WarnUnusedDoBind
]
--- minuswRemovesOpts should be every warning option
minuswRemovesOpts :: [DynFlag]
+-- minuswRemovesOpts should be every warning option
minuswRemovesOpts
= minusWallOpts ++
- [Opt_WarnImplicitPrelude,
+ [Opt_WarnTabs,
Opt_WarnIncompletePatternsRecUpd,
+ Opt_WarnIncompleteUniPatterns,
Opt_WarnMonomorphism,
Opt_WarnUnrecognisedPragmas,
Opt_WarnAutoOrphans,
- Opt_WarnTabs
- ]
+ Opt_WarnImplicitPrelude
+ ]
enableGlasgowExts :: DynP ()
enableGlasgowExts = do setDynFlag Opt_PrintExplicitForalls
</row>
<row>
+ <entry><option>-fwarn-incomplete-uni-patterns</option></entry>
+ <entry>warn when a pattern match in a lambda expression or pattern binding could fail</entry>
+ <entry>dynamic</entry>
+ <entry><option>-fno-warn-incomplete-uni-patterns</option></entry>
+ </row>
+
+ <row>
<entry><option>-fwarn-incomplete-record-updates</option></entry>
<entry>warn when a record update could fail</entry>
<entry>dynamic</entry>
<emphasis>not</emphasis> enabled by <option>-Wall</option>
are
<option>-fwarn-tabs</option>,
+ <option>-fwarn-incomplete-uni-patterns</option>,
<option>-fwarn-incomplete-record-updates</option>,
<option>-fwarn-monomorphism-restriction</option>,
- <option>-fwarn-unused-do-bind</option>, and
+ <option>-fwarn-unrecognised-pragmas</option>,
+ <option>-fwarn-auto-orphans</option>,
<option>-fwarn-implicit-prelude</option>.</para>
</listitem>
</varlistentry>
</varlistentry>
<varlistentry>
- <term><option>-fwarn-incomplete-patterns</option>:</term>
+ <term><option>-fwarn-incomplete-patterns</option>,
+ <option>-fwarn-incomplete-uni-patterns</option>,
<listitem>
<indexterm><primary><option>-fwarn-incomplete-patterns</option></primary></indexterm>
+ <indexterm><primary><option>-fwarn-incomplete-uni-patterns</option></primary></indexterm>
<indexterm><primary>incomplete patterns, warning</primary></indexterm>
<indexterm><primary>patterns, incomplete</primary></indexterm>
- <para>Similarly for incomplete patterns, the functions
- <function>g</function> and <function>h</function> below will fail when applied to
+ <para>The option <option>-fwarn-incomplete-patterns</option> warns
+ about places where
+ a pattern-match might fail at runtime.
+ The function
+ <function>g</function> below will fail when applied to
non-empty lists, so the compiler will emit a warning about
this when <option>-fwarn-incomplete-patterns</option> is
- enabled.</para>
-
+ enabled.
<programlisting>
g [] = 2
-h = \[] -> 2
</programlisting>
-
- <para>This option isn't enabled by default because it can be
+ This option isn't enabled by default because it can be
a bit noisy, and it doesn't always indicate a bug in the
program. However, it's generally considered good practice
- to cover all the cases in your functions.</para>
+ to cover all the cases in your functions, and it is switched
+ on by <option>-W</option>.</para>
+
+ <para>The flag <option>-fwarn-incomplete-uni-patterns</option> is
+ similar, except that it
+ applies only to lambda-expressions and pattern bindings, constructs
+ that only allow a single pattern:
+<programlisting>
+h = \[] -> 2
+Just k = f y
+</programlisting>
+ </para>
</listitem>
</varlistentry>