summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Opt
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2020-09-08 19:25:11 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2020-09-11 09:14:58 +0100
commitf0789d995cd92304f8ddcbfba90da5b75f83754d (patch)
treefe3db65a9bb6e7b66a4f973c110ed69ecc74ee4d /compiler/GHC/Core/Opt
parent95455982df1ef15c6d4585a7d3e93b5e75146a07 (diff)
downloadhaskell-wip/T18649.tar.gz
Care with implicit-parameter superclasseswip/T18649
Two bugs, #18627 and #18649, had the same cause: we were not account for the fact that a constaint tuple might hide an implicit parameter. The solution is not hard: look for implicit parameters in superclasses. See Note [Local implicit parameters] in GHC.Core.Predicate. Then we use this new function in two places * The "short-cut solver" in GHC.Tc.Solver.Interact.shortCutSolver which simply didn't handle implicit parameters properly at all. This fixes #18627 * The specialiser, which should not specialise on implicit parameters This fixes #18649 There are some lingering worries (see Note [Local implicit parameters]) but things are much better.
Diffstat (limited to 'compiler/GHC/Core/Opt')
-rw-r--r--compiler/GHC/Core/Opt/Specialise.hs42
1 files changed, 11 insertions, 31 deletions
diff --git a/compiler/GHC/Core/Opt/Specialise.hs b/compiler/GHC/Core/Opt/Specialise.hs
index f489ac2eff..8e9e35d208 100644
--- a/compiler/GHC/Core/Opt/Specialise.hs
+++ b/compiler/GHC/Core/Opt/Specialise.hs
@@ -2514,9 +2514,12 @@ mkCallUDs' env f args
-- we decide on a case by case basis if we want to specialise
-- on this argument; if so, SpecDict, if not UnspecArg
mk_spec_arg arg (Anon InvisArg pred)
- | type_determines_value (scaledThing pred)
- , interestingDict env arg -- Note [Interesting dictionary arguments]
+ | not (isIPLikePred (scaledThing pred))
+ -- See Note [Type determines value]
+ , interestingDict env arg
+ -- See Note [Interesting dictionary arguments]
= SpecDict arg
+
| otherwise = UnspecArg
mk_spec_arg _ (Anon VisArg _)
@@ -2529,41 +2532,18 @@ mkCallUDs' env f args
-- in specImports
-- Use 'realIdUnfolding' to ignore the loop-breaker flag!
- type_determines_value pred -- See Note [Type determines value]
- = case classifyPredType pred of
- ClassPred cls _ -> not (isIPClass cls) -- Superclasses can't be IPs
- EqPred {} -> True
- IrredPred {} -> True -- Things like (D []) where D is a
- -- Constraint-ranged family; #7785
- ForAllPred {} -> True
-
-{-
-Note [Type determines value]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Only specialise on non-IP *class* params, because these are the ones
-whose *type* determines their *value*. In particular, with implicit
-params, the type args *don't* say what the value of the implicit param
-is! See #7101.
+{- Note [Type determines value]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Only specialise on non-impicit-parameter predicates, because these
+are the ones whose *type* determines their *value*. In particular,
+with implicit params, the type args *don't* say what the value of the
+implicit param is! See #7101.
So we treat implicit params just like ordinary arguments for the
purposes of specialisation. Note that we still want to specialise
functions with implicit params if they have *other* dicts which are
class params; see #17930.
-One apparent additional complexity involves type families. For
-example, consider
- type family D (v::*->*) :: Constraint
- type instance D [] = ()
- f :: D v => v Char -> Int
-If we see a call (f "foo"), we'll pass a "dictionary"
- () |> (g :: () ~ D [])
-and it's good to specialise f at this dictionary.
-
-So the question is: can an implicit parameter "hide inside" a
-type-family constraint like (D a). Well, no. We don't allow
- type instance D Maybe = ?x:Int
-Hence the IrredPred case in type_determines_value. See #7785.
-
Note [Interesting dictionary arguments]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider this