Commit 5949ff2d authored by Simon Peyton Jones's avatar Simon Peyton Jones
Browse files

Refine 'type_determines_value' in Specialise. Fix Trac #7785.

See Note [Type determines value] in Specialise.
parent 1ed04090
...@@ -10,7 +10,7 @@ module Specialise ( specProgram ) where ...@@ -10,7 +10,7 @@ module Specialise ( specProgram ) where
import Id import Id
import TcType hiding( substTy, extendTvSubstList ) import TcType hiding( substTy, extendTvSubstList )
import Type( TyVar, isDictTy, mkPiTypes ) import Type( TyVar, isDictTy, mkPiTypes, classifyPredType, PredTree(..), isIPClass )
import Coercion( Coercion ) import Coercion( Coercion )
import CoreMonad import CoreMonad
import qualified CoreSubst import qualified CoreSubst
...@@ -1597,7 +1597,9 @@ mkCallUDs :: SpecEnv -> Id -> [CoreExpr] -> UsageDetails ...@@ -1597,7 +1597,9 @@ mkCallUDs :: SpecEnv -> Id -> [CoreExpr] -> UsageDetails
mkCallUDs env f args mkCallUDs env f args
| not (want_calls_for f) -- Imported from elsewhere | not (want_calls_for f) -- Imported from elsewhere
|| null theta -- Not overloaded || null theta -- Not overloaded
|| not (all type_determines_value theta) = emptyUDs
| not (all type_determines_value theta)
|| not (spec_tys `lengthIs` n_tyvars) || not (spec_tys `lengthIs` n_tyvars)
|| not ( dicts `lengthIs` n_dicts) || not ( dicts `lengthIs` n_dicts)
|| not (any (interestingDict env) dicts) -- Note [Interesting dictionary arguments] || not (any (interestingDict env) dicts) -- Note [Interesting dictionary arguments]
...@@ -1625,14 +1627,36 @@ mkCallUDs env f args ...@@ -1625,14 +1627,36 @@ mkCallUDs env f args
want_calls_for f = isLocalId f || isInlinablePragma (idInlinePragma f) want_calls_for f = isLocalId f || isInlinablePragma (idInlinePragma f)
type_determines_value pred = isClassPred pred && not (isIPPred pred) type_determines_value pred -- See Note [Type determines value]
-- Only specialise if all overloading is on non-IP *class* params, = case classifyPredType pred of
-- because these are the ones whose *type* determines their *value*. ClassPred cls _ -> not (isIPClass cls)
-- In ptic, with implicit params, the type args TuplePred ps -> all type_determines_value ps
-- *don't* say what the value of the implicit param is! EqPred {} -> True
-- See Trac #7101 IrredPred {} -> True -- Things like (D []) where D is a
-- Constraint-ranged family; Trac #7785
\end{code} \end{code}
Note [Type determines value]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Only specialise if all overloading is on non-IP *class* params,
because these are the ones whose *type* determines their *value*. In
parrticular, with implicit params, the type args *don't* say what the
value of the implicit param is! See Trac #7101
However, 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 Trac #7785.
Note [Interesting dictionary arguments] Note [Interesting dictionary arguments]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider this Consider this
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment