summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc/TyCl/Class.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Tc/TyCl/Class.hs')
-rw-r--r--compiler/GHC/Tc/TyCl/Class.hs36
1 files changed, 27 insertions, 9 deletions
diff --git a/compiler/GHC/Tc/TyCl/Class.hs b/compiler/GHC/Tc/TyCl/Class.hs
index a55a774069..1c1f6608cd 100644
--- a/compiler/GHC/Tc/TyCl/Class.hs
+++ b/compiler/GHC/Tc/TyCl/Class.hs
@@ -13,6 +13,7 @@
module GHC.Tc.TyCl.Class
( tcClassSigs
, tcClassDecl2
+ , ClassScopedTVEnv
, findMethodBind
, instantiateMethod
, tcClassMinimalDef
@@ -39,7 +40,7 @@ import GHC.Tc.Utils.Unify
import GHC.Tc.Utils.Instantiate( tcSuperSkolTyVars )
import GHC.Tc.Gen.HsType
import GHC.Tc.Utils.TcMType
-import GHC.Core.Type ( piResultTys )
+import GHC.Core.Type ( piResultTys, substTyVar )
import GHC.Core.Predicate
import GHC.Core.Multiplicity
import GHC.Tc.Types.Origin
@@ -187,10 +188,16 @@ tcClassSigs clas sigs def_methods
************************************************************************
-}
-tcClassDecl2 :: LTyClDecl GhcRn -- The class declaration
+-- | Maps class names to the type variables that scope over their bodies.
+-- See @Note [Scoped tyvars in a TcTyCon]@ in "GHC.Core.TyCon".
+type ClassScopedTVEnv = NameEnv [(Name, TyVar)]
+
+tcClassDecl2 :: ClassScopedTVEnv -- Class scoped type variables
+ -> LTyClDecl GhcRn -- The class declaration
-> TcM (LHsBinds GhcTc)
-tcClassDecl2 (L _ (ClassDecl {tcdLName = class_name, tcdSigs = sigs,
+tcClassDecl2 class_scoped_tv_env
+ (L _ (ClassDecl {tcdLName = class_name, tcdSigs = sigs,
tcdMeths = default_binds}))
= recoverM (return emptyLHsBinds) $
setSrcSpan (getLocA class_name) $
@@ -205,20 +212,31 @@ tcClassDecl2 (L _ (ClassDecl {tcdLName = class_name, tcdSigs = sigs,
-- And since ds is big, it doesn't get inlined, so we don't get good
-- default methods. Better to make separate AbsBinds for each
; let (tyvars, _, _, op_items) = classBigSig clas
- prag_fn = mkPragEnv sigs default_binds
- sig_fn = mkHsSigFun sigs
- clas_tyvars = snd (tcSuperSkolTyVars tyvars)
- pred = mkClassPred clas (mkTyVarTys clas_tyvars)
+ prag_fn = mkPragEnv sigs default_binds
+ sig_fn = mkHsSigFun sigs
+ (skol_subst, clas_tyvars) = tcSuperSkolTyVars tyvars
+ pred = mkClassPred clas (mkTyVarTys clas_tyvars)
+ scoped_tyvars =
+ case lookupNameEnv class_scoped_tv_env (unLoc class_name) of
+ Just tvs -> tvs
+ Nothing -> pprPanic "tcClassDecl2: Class name not in tcg_class_scoped_tvs_env"
+ (ppr class_name)
+ -- The substitution returned by tcSuperSkolTyVars maps each type
+ -- variable to a TyVarTy, so it is safe to call getTyVar below.
+ scoped_clas_tyvars =
+ mapSnd ( getTyVar ("tcClassDecl2: Super-skolem substitution maps "
+ ++ "type variable to non-type variable")
+ . substTyVar skol_subst ) scoped_tyvars
; this_dict <- newEvVar pred
; let tc_item = tcDefMeth clas clas_tyvars this_dict
default_binds sig_fn prag_fn
- ; dm_binds <- tcExtendTyVarEnv clas_tyvars $
+ ; dm_binds <- tcExtendNameTyVarEnv scoped_clas_tyvars $
mapM tc_item op_items
; return (unionManyBags dm_binds) }
-tcClassDecl2 d = pprPanic "tcClassDecl2" (ppr d)
+tcClassDecl2 _ d = pprPanic "tcClassDecl2" (ppr d)
tcDefMeth :: Class -> [TyVar] -> EvVar -> LHsBinds GhcRn
-> HsSigFun -> TcPragEnv -> ClassOpItem