Commit 92b30c6b authored by simonpj@microsoft.com's avatar simonpj@microsoft.com

Fix Trac #4498: bang-pattern bindings are monomorphic

This patch forces bang patterns to be monomorphic,
and documents this fact.
parent 04b17d61
......@@ -1076,6 +1076,7 @@ instance Outputable GeneralisationPlan where
decideGeneralisationPlan
:: DynFlags -> TopLevelFlag -> [Name] -> [LHsBind Name] -> TcSigFun -> GeneralisationPlan
decideGeneralisationPlan dflags top_lvl _bndrs binds sig_fn
| bang_pat_binds = NoGen
| mono_pat_binds = NoGen
| Just sig <- one_funbind_with_sig binds = if null (sig_tvs sig) && null (sig_theta sig)
then NoGen -- Optimise common case
......@@ -1085,7 +1086,12 @@ decideGeneralisationPlan dflags top_lvl _bndrs binds sig_fn
| otherwise = InferGen mono_restriction
where
mono_pat_binds = xopt Opt_MonoPatBinds dflags
bang_pat_binds = any (isBangHsBind . unLoc) binds
-- Bang patterns must not be polymorphic,
-- because we are going to force them
-- See Trac #4498
mono_pat_binds = xopt Opt_MonoPatBinds dflags
&& any (is_pat_bind . unLoc) binds
mono_restriction = xopt Opt_MonomorphismRestriction dflags
......@@ -1129,7 +1135,7 @@ checkStrictBinds top_lvl rec_group binds poly_ids
; checkTc (isNonRec rec_group)
(strictBindErr "Recursive" unlifted binds)
; checkTc (isSingleton binds)
(strictBindErr "Multiple" unlifted binds)
(strictBindErr "Multiple" unlifted binds)
-- This should be a checkTc, not a warnTc, but as of GHC 6.11
-- the versions of alex and happy available have non-conforming
-- templates, so the GHC build fails if it's an error:
......
......@@ -7200,16 +7200,23 @@ forces evaluation anyway does nothing.
There is one (apparent) exception to this general rule that a bang only
makes a difference when it precedes a variable or wild-card: a bang at the
top level of a <literal>let</literal> or <literal>where</literal>
binding makes the binding strict, regardless of the pattern. For example:
binding makes the binding strict, regardless of the pattern.
(We say "apparent" exception because the Right Way to think of it is that the bang
at the top of a binding is not part of the <emphasis>pattern</emphasis>; rather it
is part of the syntax of the <emphasis>binding</emphasis>,
creating a "bang-pattern binding".)
For example:
<programlisting>
let ![x,y] = e in b
</programlisting>
is a strict binding: operationally, it evaluates <literal>e</literal>, matches
it against the pattern <literal>[x,y]</literal>, and then evaluates <literal>b</literal>.
(We say "apparent" exception because the Right Way to think of it is that the bang
at the top of a binding is not part of the <emphasis>pattern</emphasis>; rather it
is part of the syntax of the <emphasis>binding</emphasis>.)
Nested bangs in a pattern binding behave uniformly with all other forms of
is a bang-pattern binding. Operationally, it behaves just like a case expression:
<programlisting>
case e of [x,y] -> b
</programlisting>
Like a case expression, a bang-pattern binding must be non-recursive, and
is monomorphic.
However, <emphasis>nested</emphasis> bangs in a pattern binding behave uniformly with all other forms of
pattern matching. For example
<programlisting>
let (!x,[y]) = e in b
......
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