Fix Trac #4498: bang-pattern bindings are monomorphic
authorsimonpj@microsoft.com <unknown>
Wed, 17 Nov 2010 10:10:58 +0000 (10:10 +0000)
committersimonpj@microsoft.com <unknown>
Wed, 17 Nov 2010 10:10:58 +0000 (10:10 +0000)
This patch forces bang patterns to be monomorphic,
and documents this fact.

compiler/typecheck/TcBinds.lhs
docs/users_guide/glasgow_exts.xml

index 80a773c..4872a80 100644 (file)
@@ -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:
index 7bb33c6..161371b 100644 (file)
@@ -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