summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2021-03-16 22:56:56 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-03-22 09:23:04 -0400
commita9129f9fdfbd358e76aa197ba00bfe75012d6b4f (patch)
treecddc5ce80c611213555b914f83c813c7cfb17305
parenteeba7a3a13b6cd26a50eece4e18594b99ad1f9a8 (diff)
downloadhaskell-a9129f9fdfbd358e76aa197ba00bfe75012d6b4f.tar.gz
Short-circuit warning generation for partial type signatures
This Note says it all: Note [Skip type holes rapidly] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose we have module with a /lot/ of partial type signatures, and we compile it while suppressing partial-type-signature warnings. Then we don't want to spend ages constructing error messages and lists of relevant bindings that we never display! This happened in #14766, in which partial type signatures in a Happy-generated parser cause a huge increase in compile time. The function ignoreThisHole short-circuits the error/warning generation machinery, in cases where it is definitely going to be a no-op. It makes a pretty big difference on the Sigs.hs example in #14766: Compile-time allocation GHC 8.10 5.6G Before this patch 937G With this patch 4.7G Yes, that's more than two orders of magnitude!
-rw-r--r--compiler/GHC/Tc/Errors.hs30
1 files changed, 28 insertions, 2 deletions
diff --git a/compiler/GHC/Tc/Errors.hs b/compiler/GHC/Tc/Errors.hs
index f5641766d3..f1325446f0 100644
--- a/compiler/GHC/Tc/Errors.hs
+++ b/compiler/GHC/Tc/Errors.hs
@@ -66,7 +66,7 @@ import GHC.Data.Maybe
import qualified GHC.LanguageExtensions as LangExt
import GHC.Utils.FV ( fvVarList, unionFV )
-import Control.Monad ( when )
+import Control.Monad ( when, unless )
import Data.Foldable ( toList )
import Data.List ( partition, mapAccumL, sortBy, unfoldr )
@@ -740,10 +740,36 @@ mkSkolReporter ctxt cts
reportHoles :: [Ct] -- other (tidied) constraints
-> ReportErrCtxt -> [Hole] -> TcM ()
reportHoles tidy_cts ctxt
- = mapM_ $ \hole -> do { err <- mkHoleError tidy_cts ctxt hole
+ = mapM_ $ \hole -> unless (ignoreThisHole ctxt hole) $
+ do { err <- mkHoleError tidy_cts ctxt hole
; maybeReportHoleError ctxt hole err
; maybeAddDeferredHoleBinding ctxt err hole }
+ignoreThisHole :: ReportErrCtxt -> Hole -> Bool
+-- See Note [Skip type holes rapidly]
+ignoreThisHole ctxt hole
+ = case hole_sort hole of
+ ExprHole {} -> False
+ TypeHole -> ignore_type_hole
+ ConstraintHole -> ignore_type_hole
+ where
+ ignore_type_hole = case cec_type_holes ctxt of
+ HoleDefer -> True
+ _ -> False
+
+{- Note [Skip type holes rapidly]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Suppose we have module with a /lot/ of partial type signatures, and we
+compile it while suppressing partial-type-signature warnings. Then
+we don't want to spend ages constructing error messages and lists of
+relevant bindings that we never display! This happened in #14766, in
+which partial type signatures in a Happy-generated parser cause a huge
+increase in compile time.
+
+The function ignoreThisHole short-circuits the error/warning generation
+machinery, in cases where it is definitely going to be a no-op.
+-}
+
mkUserTypeErrorReporter :: Reporter
mkUserTypeErrorReporter ctxt
= mapM_ $ \ct -> do { err <- mkUserTypeError ctxt ct