From 6e8d90560b4a9269c56f7c1ee4d29d1077680f7b Mon Sep 17 00:00:00 2001 From: Simon Peyton Jones Date: Wed, 29 Jun 2022 16:43:36 +0100 Subject: Edit Note [idArity varies independently of dmdTypeDepth] ...and refer to it in GHC.Core.Lint.lintLetBind. Fixes #21452 --- compiler/GHC/Core/Lint.hs | 15 +++++---------- compiler/GHC/Core/Opt/DmdAnal.hs | 32 +++++++++++++++++++++++--------- compiler/GHC/Core/Opt/Simplify.hs | 6 +++--- compiler/GHC/Types/Id/Info.hs | 5 +++-- 4 files changed, 34 insertions(+), 24 deletions(-) diff --git a/compiler/GHC/Core/Lint.hs b/compiler/GHC/Core/Lint.hs index 7486086406..00636ec444 100644 --- a/compiler/GHC/Core/Lint.hs +++ b/compiler/GHC/Core/Lint.hs @@ -640,7 +640,8 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty ppr (typeArity (idType binder)) <> colon <+> ppr binder) - -- See Note [Check arity on bottoming functions] + -- See Note [idArity varies independently of dmdTypeDepth] + -- in GHC.Core.Opt.DmdAnal ; case splitDmdSig (idDmdSig binder) of (demands, result_info) | isDeadEndDiv result_info -> checkL (demands `lengthAtLeast` idArity binder) @@ -648,6 +649,7 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty text "exceeds arity imposed by the strictness signature" <+> ppr (idDmdSig binder) <> colon <+> ppr binder) + _ -> return () ; addLoc (RuleOf binder) $ mapM_ (lintCoreRule binder binder_ty) (idCoreRules binder) @@ -724,15 +726,8 @@ lintIdUnfolding _ _ _ = return () -- Do not Lint unstable unfoldings, because that leads -- to exponential behaviour; c.f. GHC.Core.FVs.idUnfoldingVars -{- -Note [Check arity on bottoming functions] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If a function has a strictness signature like [S]b, it claims to -return bottom when applied to one argument. So its arity should not -be greater than 1! We check this claim in Lint. - -Note [Checking for INLINE loop breakers] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Checking for INLINE loop breakers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It's very suspicious if a strong loop breaker is marked INLINE. However, the desugarer generates instance methods with INLINE pragmas diff --git a/compiler/GHC/Core/Opt/DmdAnal.hs b/compiler/GHC/Core/Opt/DmdAnal.hs index 59d18fefaf..d41b97ac87 100644 --- a/compiler/GHC/Core/Opt/DmdAnal.hs +++ b/compiler/GHC/Core/Opt/DmdAnal.hs @@ -1177,18 +1177,27 @@ complexity. Note [idArity varies independently of dmdTypeDepth] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In general, an Id `f` has two independently varying attributes: + +* f's idArity, and +* the dmdTypeDepth of f's demand signature + +For example, if f's demand signature is , f's arity could be +greater than, or less than 2. Why? Because both are conservative +approximations: + +* Arity n means "does no work until applied to at least n args" + (e.g. (f x1..xm) is cheap to bring to HNF for m co @@ -1201,6 +1210,11 @@ coercion into the binding, leading to an arity decrease: With the CoreLint check, we would have to zap `go`'s perfectly viable strictness signature. +However, in the case of a /bottoming/ signature, f : b, we /can/ +say that f's arity is no greater than 2, because it'd be false to say +that f does no work when applied to 3 args. Lint checks this constraint, +in `GHC.Core.Lint.lintLetBind`. + Note [Demand analysis for trivial right-hand sides] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider diff --git a/compiler/GHC/Core/Opt/Simplify.hs b/compiler/GHC/Core/Opt/Simplify.hs index d26fd28de2..0f842be2d3 100644 --- a/compiler/GHC/Core/Opt/Simplify.hs +++ b/compiler/GHC/Core/Opt/Simplify.hs @@ -1025,9 +1025,9 @@ to eta-expand to in ...(f a b c)... But now f's strictness signature has too short an arity; see -GHC.Core.Lint Note [Check arity on bottoming functions]. -Fortuitously, the same strictness-signature-fixup code gives the -function a new strictness signature with the right number of +GHC.Core.Opt.DmdAnal Note [idArity varies independently of dmdTypeDepth]. +Fortuitously, the same strictness-signature-fixup code +gives the function a new strictness signature with the right number of arguments. Example in stranal/should_compile/EtaExpansion. Note [Setting the demand info] diff --git a/compiler/GHC/Types/Id/Info.hs b/compiler/GHC/Types/Id/Info.hs index 5834fa8b06..a35845f612 100644 --- a/compiler/GHC/Types/Id/Info.hs +++ b/compiler/GHC/Types/Id/Info.hs @@ -353,8 +353,9 @@ data IdInfo occInfo :: OccInfo, -- ^ How the 'Id' occurs in the program dmdSigInfo :: DmdSig, - -- ^ A strictness signature. Digests how a function uses its arguments - -- if applied to at least 'arityInfo' arguments. + -- ^ A strictness signature. Describes how a function uses its arguments + -- See Note [idArity varies independently of dmdTypeDepth] + -- in GHC.Core.Opt.DmdAnal cprSigInfo :: CprSig, -- ^ Information on whether the function will ultimately return a -- freshly allocated constructor. -- cgit v1.2.1