From 92b30c6bd5123897b154aa158a0cd05b8b76f67a Mon Sep 17 00:00:00 2001 From: "simonpj@microsoft.com" Date: Wed, 17 Nov 2010 10:10:58 +0000 Subject: [PATCH] Fix Trac #4498: bang-pattern bindings are monomorphic This patch forces bang patterns to be monomorphic, and documents this fact. --- compiler/typecheck/TcBinds.lhs | 10 ++++++++-- docs/users_guide/glasgow_exts.xml | 21 ++++++++++++++------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/compiler/typecheck/TcBinds.lhs b/compiler/typecheck/TcBinds.lhs index 80a773c..4872a80 100644 --- a/compiler/typecheck/TcBinds.lhs +++ b/compiler/typecheck/TcBinds.lhs @@ -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: diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 7bb33c6..161371b 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -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 let or where -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 pattern; rather it +is part of the syntax of the binding, +creating a "bang-pattern binding".) +For example: let ![x,y] = e in b -is a strict binding: operationally, it evaluates e, matches -it against the pattern [x,y], and then evaluates b. -(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 pattern; rather it -is part of the syntax of the binding.) -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: + +case e of [x,y] -> b + +Like a case expression, a bang-pattern binding must be non-recursive, and +is monomorphic. + +However, nested bangs in a pattern binding behave uniformly with all other forms of pattern matching. For example let (!x,[y]) = e in b -- 1.7.10.4