summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc/Instance/Class.hs
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2022-05-18 12:15:39 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-05-22 21:57:47 -0400
commitea895b94afeecb111f8001fbd60f5d4c8828213c (patch)
treed7f4da05089794e796a8a805b48dc59319001988 /compiler/GHC/Tc/Instance/Class.hs
parent7edd991e5d00a1ba19f3607fe8a66bbdc3ab3181 (diff)
downloadhaskell-ea895b94afeecb111f8001fbd60f5d4c8828213c.tar.gz
Consider the stage of typeable evidence when checking stage restriction
We were considering all Typeable evidence to be "BuiltinInstance"s which meant the stage restriction was going unchecked. In-fact, typeable has evidence and so we need to apply the stage restriction. This is complicated by the fact we don't generate typeable evidence and the corresponding DFunIds until after typechecking is concluded so we introcue a new `InstanceWhat` constructor, BuiltinTypeableInstance which records whether the evidence is going to be local or not. Fixes #21547
Diffstat (limited to 'compiler/GHC/Tc/Instance/Class.hs')
-rw-r--r--compiler/GHC/Tc/Instance/Class.hs33
1 files changed, 23 insertions, 10 deletions
diff --git a/compiler/GHC/Tc/Instance/Class.hs b/compiler/GHC/Tc/Instance/Class.hs
index df7046c4fd..50a13ba901 100644
--- a/compiler/GHC/Tc/Instance/Class.hs
+++ b/compiler/GHC/Tc/Instance/Class.hs
@@ -33,6 +33,7 @@ import GHC.Types.SafeHaskell
import GHC.Types.Name ( Name, pprDefinedAt )
import GHC.Types.Var.Env ( VarEnv )
import GHC.Types.Id
+import GHC.Types.Var
import GHC.Core.Predicate
import GHC.Core.InstEnv
@@ -96,13 +97,22 @@ data ClsInstResult
| NotSure -- Multiple matches and/or one or more unifiers
-data InstanceWhat
- = BuiltinInstance
- | BuiltinEqInstance -- A built-in "equality instance"; see the
- -- GHC.Tc.Solver.InertSet Note [Solved dictionaries]
- | LocalInstance
- | TopLevInstance { iw_dfun_id :: DFunId
- , iw_safe_over :: SafeOverlapping }
+data InstanceWhat -- How did we solve this constraint?
+ = BuiltinEqInstance -- Built-in solver for (t1 ~ t2), (t1 ~~ t2), Coercible t1 t2
+ -- See GHC.Tc.Solver.InertSet Note [Solved dictionaries]
+
+ | BuiltinTypeableInstance TyCon -- Built-in solver for Typeable (T t1 .. tn)
+ -- See Note [Well-staged instance evidence]
+
+ | BuiltinInstance -- Built-in solver for (C t1 .. tn) where C is
+ -- KnownNat, .. etc (classes with no top-level evidence)
+
+ | LocalInstance -- Solved by a quantified constraint
+ -- See GHC.Tc.Solver.InertSet Note [Solved dictionaries]
+
+ | TopLevInstance -- Solved by a top-level instance decl
+ { iw_dfun_id :: DFunId
+ , iw_safe_over :: SafeOverlapping }
instance Outputable ClsInstResult where
ppr NoInstance = text "NoInstance"
@@ -113,6 +123,7 @@ instance Outputable ClsInstResult where
instance Outputable InstanceWhat where
ppr BuiltinInstance = text "a built-in instance"
+ ppr BuiltinTypeableInstance {} = text "a built-in typeable instance"
ppr BuiltinEqInstance = text "a built-in equality instance"
ppr LocalInstance = text "a locally-quantified instance"
ppr (TopLevInstance { iw_dfun_id = dfun })
@@ -127,6 +138,7 @@ instanceReturnsDictCon :: InstanceWhat -> Bool
-- See Note [Solved dictionaries] in GHC.Tc.Solver.InertSet
instanceReturnsDictCon (TopLevInstance {}) = True
instanceReturnsDictCon BuiltinInstance = True
+instanceReturnsDictCon BuiltinTypeableInstance {} = True
instanceReturnsDictCon BuiltinEqInstance = False
instanceReturnsDictCon LocalInstance = False
@@ -462,9 +474,10 @@ doFunTy clas ty mult arg_ty ret_ty
doTyConApp :: Class -> Type -> TyCon -> [Kind] -> TcM ClsInstResult
doTyConApp clas ty tc kind_args
| tyConIsTypeable tc
- = return $ OneInst { cir_new_theta = (map (mk_typeable_pred clas) kind_args)
- , cir_mk_ev = mk_ev
- , cir_what = BuiltinInstance }
+ = do
+ return $ OneInst { cir_new_theta = (map (mk_typeable_pred clas) kind_args)
+ , cir_mk_ev = mk_ev
+ , cir_what = BuiltinTypeableInstance tc }
| otherwise
= return NoInstance
where