summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2021-02-08 22:46:32 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-02-13 21:32:38 -0500
commitbe3c0d62c73361b8805a51a88770991c3b6f9331 (patch)
tree3b80955de8b3499c95259cc1294ea825cefaac36 /compiler/GHC/Tc
parentdcc4b2de37f73a05a106b78bae0b99eb9715cf01 (diff)
downloadhaskell-be3c0d62c73361b8805a51a88770991c3b6f9331.tar.gz
Fix a serious bug in roughMatchTcs
The roughMatchTcs function enables a quick definitely-no-match test in lookupInstEnv. Unfortunately, it didn't account for type families. This didn't matter when type families were flattened away, but now they aren't flattened it matters a lot. The fix is very easy. See INVARIANT in GHC.Core.InstEnv Note [ClsInst laziness and the rough-match fields] Fixes #19336 The change makes compiler perf worse on two very-type-family-heavy benchmarks, T9872{a,d}: T9872a(normal) ghc/alloc 2172536442.7 2216337648.0 +2.0% T9872d(normal) ghc/alloc 614584024.0 621081384.0 +1.1% (Everything else is 0.0% or at most 0.1%.) I think we just have to put up with this. Some cases were being wrongly filtered out by roughMatchTcs that might actually match, which could lead to false apartness checks. And it only affects these very type-family-heavy cases. Metric Increase: T9872a T9872d
Diffstat (limited to 'compiler/GHC/Tc')
-rw-r--r--compiler/GHC/Tc/Instance/FunDeps.hs6
-rw-r--r--compiler/GHC/Tc/Module.hs3
2 files changed, 5 insertions, 4 deletions
diff --git a/compiler/GHC/Tc/Instance/FunDeps.hs b/compiler/GHC/Tc/Instance/FunDeps.hs
index 3abb0140b1..623ed147ff 100644
--- a/compiler/GHC/Tc/Instance/FunDeps.hs
+++ b/compiler/GHC/Tc/Instance/FunDeps.hs
@@ -236,7 +236,7 @@ improveFromInstEnv _ _ _ = []
improveClsFD :: [TyVar] -> FunDep TyVar -- One functional dependency from the class
-> ClsInst -- An instance template
- -> [Type] -> [Maybe Name] -- Arguments of this (C tys) predicate
+ -> [Type] -> [RoughMatchTc] -- Arguments of this (C tys) predicate
-> [([TyCoVar], [TypeEqn])] -- Empty or singleton
improveClsFD clas_tvs fd
@@ -666,7 +666,7 @@ checkFunDeps inst_envs (ClsInst { is_tvs = qtvs1, is_cls = cls
-- instance C Int Char Char
-- The second instance conflicts with the first by *both* fundeps
-trimRoughMatchTcs :: [TyVar] -> FunDep TyVar -> [Maybe Name] -> [Maybe Name]
+trimRoughMatchTcs :: [TyVar] -> FunDep TyVar -> [RoughMatchTc] -> [RoughMatchTc]
-- Computing rough_tcs for a particular fundep
-- class C a b c | a -> b where ...
-- For each instance .... => C ta tb tc
@@ -679,4 +679,4 @@ trimRoughMatchTcs clas_tvs (ltvs, _) mb_tcs
= zipWith select clas_tvs mb_tcs
where
select clas_tv mb_tc | clas_tv `elem` ltvs = mb_tc
- | otherwise = Nothing
+ | otherwise = OtherTc
diff --git a/compiler/GHC/Tc/Module.hs b/compiler/GHC/Tc/Module.hs
index 084a98883d..42f0a3fddc 100644
--- a/compiler/GHC/Tc/Module.hs
+++ b/compiler/GHC/Tc/Module.hs
@@ -114,6 +114,7 @@ import GHC.Core.DataCon
import GHC.Core.Type
import GHC.Core.Class
import GHC.Core.Coercion.Axiom
+import GHC.Core.Unify( RoughMatchTc(..) )
import GHC.Core.FamInstEnv
( FamInst, pprFamInst, famInstsRepTyCons
, famInstEnvElts, extendFamInstEnvList, normaliseType )
@@ -1681,7 +1682,7 @@ tcMissingParentClassWarn warnFlag isName shouldName
-- "<location>: Warning: <type> is an instance of <is> but not
-- <should>" e.g. "Foo is an instance of Monad but not Applicative"
; let instLoc = srcLocSpan . nameSrcLoc $ getName isInst
- warnMsg (Just name:_) =
+ warnMsg (KnownTc name:_) =
addWarnAt (Reason warnFlag) instLoc $
hsep [ (quotes . ppr . nameOccName) name
, text "is an instance of"