import TcClassDcl ( tcMethodBind, mkMethodBind, badMethodErr,
tcClassDecl2, getGenericInstances )
import TcRnMonad
-import TcMType ( tcInstType, checkValidTheta, checkValidInstHead, instTypeErr,
+import TcMType ( tcSkolSigType, checkValidTheta, checkValidInstHead, instTypeErr,
checkAmbiguity, SourceTyCtxt(..) )
-import TcType ( mkClassPred, tcSplitForAllTys, tyVarsOfType,
- tcSplitSigmaTy, getClassPredTys, tcSplitPredTy_maybe, mkTyVarTys,
- TyVarDetails(..), tcSplitDFunTy, pprClassPred )
-import Inst ( tcInstClassOp, newDicts, instToId, showLIE, tcExtendLocalInstEnv )
+import TcType ( mkClassPred, tyVarsOfType,
+ tcSplitSigmaTy, tcSplitDFunHead, mkTyVarTys,
+ SkolemInfo(InstSkol), tcSplitDFunTy, pprClassPred )
+import Inst ( tcInstClassOp, newDicts, instToId, showLIE,
+ getOverlapFlag, tcExtendLocalInstEnv )
+import InstEnv ( mkLocalInstance, instanceDFunId )
import TcDeriv ( tcDeriving )
-import TcEnv ( tcExtendGlobalValEnv, tcExtendTyVarEnv2,
+import TcEnv ( tcExtendGlobalValEnv, tcExtendTyVarEnv,
InstInfo(..), InstBindings(..),
- newDFunName, tcExtendLocalValEnv
+ newDFunName, tcExtendIdEnv
)
import TcHsType ( kcHsSigType, tcHsKindedType )
import TcUnify ( checkSigTyVars )
-import TcSimplify ( tcSimplifyCheck, tcSimplifyTop )
-import Subst ( mkTyVarSubst, substTheta, substTy )
+import TcSimplify ( tcSimplifyCheck, tcSimplifySuperClasses )
+import Type ( zipOpenTvSubst, substTheta, substTys )
import DataCon ( classDataCon )
import Class ( classBigSig )
import Var ( Id, idName, idType )
import MkId ( mkDictFunId, rUNTIME_ERROR_ID )
import FunDeps ( checkInstFDs )
import Name ( Name, getSrcLoc )
-import NameSet ( unitNameSet, emptyNameSet, nameSetToList, unionNameSets )
+import NameSet ( unitNameSet, emptyNameSet )
import UnicodeUtil ( stringToUtf8 )
import Maybe ( catMaybes )
import SrcLoc ( srcLocSpan, unLoc, noLoc, Located(..), srcSpanStart )
clas_decls = filter (isClassDecl.unLoc) tycl_decls
in
-- (2) Instances from generic class declarations
- getGenericInstances clas_decls `thenM` \ generic_inst_info ->
+ getGenericInstances clas_decls `thenM` \ generic_inst_info ->
-- Next, construct the instance environment so far, consisting of
-- a) local instance decls
-- (3) Compute instances from "deriving" clauses;
-- This stuff computes a context for the derived instance decl, so it
-- needs to know about all the instances possible; hence inst_env4
- tcDeriving tycl_decls `thenM` \ (deriv_inst_info, deriv_binds, keep_alive) ->
+ tcDeriving tycl_decls `thenM` \ (deriv_inst_info, deriv_binds) ->
addInsts deriv_inst_info $
getGblEnv `thenM` \ gbl_env ->
- returnM (gbl_env { tcg_keep = tcg_keep gbl_env `unionNameSets` keep_alive },
+ returnM (gbl_env,
generic_inst_info ++ deriv_inst_info ++ local_inst_info,
deriv_binds)
addInsts :: [InstInfo] -> TcM a -> TcM a
addInsts infos thing_inside
- = tcExtendLocalInstEnv (map iDFunId infos) thing_inside
+ = tcExtendLocalInstEnv (map iSpec infos) thing_inside
\end{code}
\begin{code}
tcLocalInstDecl1 decl@(L loc (InstDecl poly_ty binds uprags))
= -- Prime error recovery, set source location
recoverM (returnM Nothing) $
- addSrcSpan loc $
+ setSrcSpan loc $
addErrCtxt (instDeclCtxt1 poly_ty) $
-- Typecheck the instance type itself. We can't use
checkTc (checkInstFDs theta clas inst_tys)
(instTypeErr (pprClassPred clas inst_tys) msg) `thenM_`
newDFunName clas inst_tys (srcSpanStart loc) `thenM` \ dfun_name ->
- returnM (Just (InstInfo { iDFunId = mkDictFunId dfun_name tyvars theta clas inst_tys,
- iBinds = VanillaInst binds uprags }))
+ getOverlapFlag `thenM` \ overlap_flag ->
+ let dfun = mkDictFunId dfun_name tyvars theta clas inst_tys
+ ispec = mkLocalInstance dfun overlap_flag
+ in
+ returnM (Just (InstInfo { iSpec = ispec, iBinds = VanillaInst binds uprags }))
where
msg = parens (ptext SLIT("the instance types do not agree with the functional dependencies of the class"))
\end{code}
= do { -- (a) Default methods from class decls
(dm_binds_s, dm_ids_s) <- mapAndUnzipM tcClassDecl2 $
filter (isClassDecl.unLoc) tycl_decls
- ; tcExtendLocalValEnv (concat dm_ids_s) $ do
+ ; tcExtendIdEnv (concat dm_ids_s) $ do
-- (b) instance declarations
; inst_binds_s <- mappM tcInstDecl2 inst_decls
\begin{code}
tcInstDecl2 :: InstInfo -> TcM (LHsBinds Id)
-tcInstDecl2 (InstInfo { iDFunId = dfun_id, iBinds = binds })
- = -- Prime error recovery
- recoverM (returnM emptyBag) $
- addSrcSpan (srcLocSpan (getSrcLoc dfun_id)) $
+tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = binds })
+ = let
+ dfun_id = instanceDFunId ispec
+ rigid_info = InstSkol dfun_id
+ inst_ty = idType dfun_id
+ in
+ -- Prime error recovery
+ recoverM (returnM emptyLHsBinds) $
+ setSrcSpan (srcLocSpan (getSrcLoc dfun_id)) $
addErrCtxt (instDeclCtxt2 (idType dfun_id)) $
- let
- inst_ty = idType dfun_id
- (inst_tyvars, _) = tcSplitForAllTys inst_ty
- -- The tyvars of the instance decl scope over the 'where' part
+
+ -- Instantiate the instance decl with skolem constants
+ tcSkolSigType rigid_info inst_ty `thenM` \ (inst_tyvars', dfun_theta', inst_head') ->
+ -- These inst_tyvars' scope over the 'where' part
-- Those tyvars are inside the dfun_id's type, which is a bit
-- bizarre, but OK so long as you realise it!
- in
-
- -- Instantiate the instance decl with tc-style type variables
- tcInstType InstTv inst_ty `thenM` \ (inst_tyvars', dfun_theta', inst_head') ->
let
- Just pred = tcSplitPredTy_maybe inst_head'
- (clas, inst_tys') = getClassPredTys pred
+ (clas, inst_tys') = tcSplitDFunHead inst_head'
(class_tyvars, sc_theta, _, op_items) = classBigSig clas
-- Instantiate the super-class context with inst_tys
- sc_theta' = substTheta (mkTyVarSubst class_tyvars inst_tys') sc_theta
- origin = InstanceDeclOrigin
+ sc_theta' = substTheta (zipOpenTvSubst class_tyvars inst_tys') sc_theta
+ origin = SigOrigin rigid_info
in
-- Create dictionary Ids from the specified instance contexts.
- newDicts origin sc_theta' `thenM` \ sc_dicts ->
- newDicts origin dfun_theta' `thenM` \ dfun_arg_dicts ->
- newDicts origin [pred] `thenM` \ [this_dict] ->
+ newDicts InstScOrigin sc_theta' `thenM` \ sc_dicts ->
+ newDicts origin dfun_theta' `thenM` \ dfun_arg_dicts ->
+ newDicts origin [mkClassPred clas inst_tys'] `thenM` \ [this_dict] ->
-- Default-method Ids may be mentioned in synthesised RHSs,
-- but they'll already be in the environment.
- ------------------
-- Typecheck the methods
let -- These insts are in scope; quite a few, eh?
avail_insts = [this_dict] ++ dfun_arg_dicts ++ sc_dicts
in
- tcMethods clas inst_tyvars inst_tyvars'
+ tcMethods origin clas inst_tyvars'
dfun_theta' inst_tys' avail_insts
op_items binds `thenM` \ (meth_ids, meth_binds) ->
-- Figure out bindings for the superclass context
- tcSuperClasses inst_tyvars' dfun_arg_dicts sc_dicts
- `thenM` \ (zonked_inst_tyvars, sc_binds_inner, sc_binds_outer) ->
+ -- Don't include this_dict in the 'givens', else
+ -- sc_dicts get bound by just selecting from this_dict!!
+ addErrCtxt superClassCtxt
+ (tcSimplifySuperClasses inst_tyvars'
+ dfun_arg_dicts
+ sc_dicts) `thenM` \ sc_binds ->
+
+ -- It's possible that the superclass stuff might unified one
+ -- of the inst_tyavars' with something in the envt
+ checkSigTyVars inst_tyvars' `thenM_`
-- Deal with 'SPECIALISE instance' pragmas by making them
-- look like SPECIALISE pragmas for the dfun
other -> []
spec_prags = [ L loc (SpecSig (L loc (idName dfun_id)) ty)
| L loc (SpecInstSig ty) <- uprags ]
- xtve = inst_tyvars `zip` inst_tyvars'
in
tcExtendGlobalValEnv [dfun_id] (
- tcExtendTyVarEnv2 xtve $
+ tcExtendTyVarEnv inst_tyvars' $
tcSpecSigs spec_prags
) `thenM` \ prag_binds ->
msg = "Compiler error: bad dictionary " ++ showSDoc (ppr clas)
dict_bind = noLoc (VarBind this_dict_id dict_rhs)
- all_binds = dict_bind `consBag` (sc_binds_inner `unionBags` meth_binds)
+ all_binds = dict_bind `consBag` (sc_binds `unionBags` meth_binds)
main_bind = noLoc $ AbsBinds
- zonked_inst_tyvars
- (map instToId dfun_arg_dicts)
- [(inst_tyvars', dfun_id, this_dict_id)]
- inlines all_binds
+ inst_tyvars'
+ (map instToId dfun_arg_dicts)
+ [(inst_tyvars', dfun_id, this_dict_id)]
+ inlines all_binds
in
showLIE (text "instance") `thenM_`
returnM (unitBag main_bind `unionBags`
- prag_binds `unionBags`
- sc_binds_outer)
+ prag_binds )
-tcMethods clas inst_tyvars inst_tyvars' dfun_theta' inst_tys'
+tcMethods origin clas inst_tyvars' dfun_theta' inst_tys'
avail_insts op_items (VanillaInst monobinds uprags)
= -- Check that all the method bindings come from this class
let
-- Make the method bindings
let
- mk_method_bind = mkMethodBind InstanceDeclOrigin clas inst_tys' monobinds
+ mk_method_bind = mkMethodBind origin clas inst_tys' monobinds
in
mapAndUnzipM mk_method_bind op_items `thenM` \ (meth_insts, meth_infos) ->
-- looks like 'op at Int'. But they are not the same.
let
all_insts = avail_insts ++ catMaybes meth_insts
- xtve = inst_tyvars `zip` inst_tyvars'
- tc_method_bind = tcMethodBind xtve inst_tyvars' dfun_theta' all_insts uprags
+ tc_method_bind = tcMethodBind inst_tyvars' dfun_theta' all_insts uprags
+ meth_ids = [meth_id | (_,meth_id,_) <- meth_infos]
in
+
mapM tc_method_bind meth_infos `thenM` \ meth_binds_s ->
- returnM ([meth_id | (_,meth_id,_) <- meth_infos],
- unionManyBags meth_binds_s)
+ returnM (meth_ids, unionManyBags meth_binds_s)
-- Derived newtype instances
-tcMethods clas inst_tyvars inst_tyvars' dfun_theta' inst_tys'
+tcMethods origin clas inst_tyvars' dfun_theta' inst_tys'
avail_insts op_items (NewTypeDerived rep_tys)
- = getInstLoc InstanceDeclOrigin `thenM` \ inst_loc ->
+ = getInstLoc origin `thenM` \ inst_loc ->
mapAndUnzip3M (do_one inst_loc) op_items `thenM` \ (meth_ids, meth_binds, rhs_insts) ->
tcSimplifyCheck
return (meth_id, noLoc (VarBind meth_id (nlHsVar (instToId rhs_inst))), rhs_inst)
-- Instantiate rep_tys with the relevant type variables
- rep_tys' = map (substTy subst) rep_tys
- subst = mkTyVarSubst inst_tyvars (mkTyVarTys inst_tyvars')
-\end{code}
-
-Note: [Superclass loops]
-~~~~~~~~~~~~~~~~~~~~~~~~~
-We have to be very, very careful when generating superclasses, lest we
-accidentally build a loop. Here's an example:
-
- class S a
-
- class S a => C a where { opc :: a -> a }
- class S b => D b where { opd :: b -> b }
-
- instance C Int where
- opc = opd
-
- instance D Int where
- opd = opc
-
-From (instance C Int) we get the constraint set {ds1:S Int, dd:D Int}
-Simplifying, we may well get:
- $dfCInt = :C ds1 (opd dd)
- dd = $dfDInt
- ds1 = $p1 dd
-Notice that we spot that we can extract ds1 from dd.
-
-Alas! Alack! We can do the same for (instance D Int):
-
- $dfDInt = :D ds2 (opc dc)
- dc = $dfCInt
- ds2 = $p1 dc
-
-And now we've defined the superclass in terms of itself.
-
-
-Solution: treat the superclass context separately, and simplify it
-all the way down to nothing on its own. Don't toss any 'free' parts
-out to be simplified together with other bits of context.
-Hence the tcSimplifyTop below.
-
-At a more basic level, don't include this_dict in the context wrt
-which we simplify sc_dicts, else sc_dicts get bound by just selecting
-from this_dict!!
-
-\begin{code}
-tcSuperClasses inst_tyvars' dfun_arg_dicts sc_dicts
- = addErrCtxt superClassCtxt $
- getLIE (tcSimplifyCheck doc inst_tyvars'
- dfun_arg_dicts
- sc_dicts) `thenM` \ (sc_binds1, sc_lie) ->
-
- -- It's possible that the superclass stuff might have done unification
- checkSigTyVars inst_tyvars' `thenM` \ zonked_inst_tyvars ->
-
- -- We must simplify this all the way down
- -- lest we build superclass loops
- -- See Note [Superclass loops] above
- tcSimplifyTop sc_lie `thenM` \ sc_binds2 ->
-
- returnM (zonked_inst_tyvars, sc_binds1, sc_binds2)
-
- where
- doc = ptext SLIT("instance declaration superclass context")
+ -- This looks a bit odd, because inst_tyvars' are the skolemised version
+ -- of the type variables in the instance declaration; but rep_tys doesn't
+ -- have the skolemised version, so we substitute them in here
+ rep_tys' = substTys subst rep_tys
+ subst = zipOpenTvSubst inst_tyvars' (mkTyVarTys inst_tyvars')
\end{code}