getSynTyConDefn, tyConGenInfo, tyConDataConDetails, tyConArity )
import Class ( classExtraBigSig, classTyCon, DefMeth(..) )
import FieldLabel ( fieldLabelType )
-import TcType ( tcSplitSigmaTy, tidyTopType, deNoteType, tyClsNamesOfDFunHead )
+import TcType ( tcSplitForAllTys, tcFunResultTy, tidyTopType, deNoteType, tyClsNamesOfDFunHead )
import SrcLoc ( noSrcLoc )
import Module ( Module, ModuleName, moduleNameFS, moduleName, isHomeModule,
ModLocation(..), mkSysModuleNameFS,
= ASSERT(sel_tyvars == clas_tyvars)
ClassOpSig (getName sel_id) def_meth' (toHsType op_ty) noSrcLoc
where
- (sel_tyvars, _, op_ty) = tcSplitSigmaTy (idType sel_id)
+ -- Be careful when splitting the type, because of things
+ -- like class Foo a where
+ -- op :: (?x :: String) => a -> a
+ -- and class Baz a where
+ -- op :: (Ord a) => a -> a
+ (sel_tyvars, rho_ty) = tcSplitForAllTys (idType sel_id)
+ op_ty = tcFunResultTy rho_ty
def_meth' = case def_meth of
NoDefMeth -> NoDefMeth
GenDefMeth -> GenDefMeth
newDictsFromOld, newDicts, cloneDict,
newMethod, newMethodFromName, newMethodWithGivenTy,
- newMethodWith, newMethodAtLoc,
+ newMethodWith, tcInstClassOp,
newOverloadedLit, newIPDict,
tcInstCall, tcInstDataCon, tcSyntaxName,
tyVarsOfType, tyVarsOfTypes, tyVarsOfPred, tidyPred,
isClassPred, isTyVarClassPred, isLinearPred, predHasFDs,
getClassPredTys, getClassPredTys_maybe, mkPredName,
- isInheritablePred, isIPPred,
+ isInheritablePred, isIPPred, tcSplitFunTy_maybe, tcSplitPredTy_maybe,
tidyType, tidyTypes, tidyFreeTyVars, tcSplitSigmaTy
)
import CoreFVs ( idFreeTyVars )
returnM (instToId inst)
--------------------------------------------
--- newMethodWith and newMethodAtLoc do *not* drop the
+-- tcInstClassOp, and newMethodWith do *not* drop the
-- Inst into the LIE; they just returns the Inst
-- This is important because they are used by TcSimplify
-- to simplify Insts
+tcInstClassOp :: InstLoc -> Id -> [TcType] -> TcM Inst
+ -- Instantiate the specified class op, but *only* with the main
+ -- class dictionary. For example, given 'op' defined thus:
+ -- class Foo a where
+ -- op :: (?x :: String) => a -> a
+ -- (tcInstClassOp op T) should return an Inst with type
+ -- (?x :: String) => T -> T
+ -- That is, the class-op's context is still there.
+ -- This is really important in the use of tcInstClassOp in TcClassDcls.mkMethodBind
+tcInstClassOp inst_loc sel_id tys
+ = let
+ (tyvars,rho) = tcSplitForAllTys (idType sel_id)
+ rho_ty = ASSERT( equalLength tyvars tys )
+ substTy (mkTopTyVarSubst tyvars tys) rho
+ Just (pred_ty,tau) = tcSplitFunTy_maybe rho_ty
+ Just pred = tcSplitPredTy_maybe pred_ty
+ -- Split off exactly one predicate (see the example above)
+ in
+ ASSERT( isClassPred pred )
+ newMethodWith inst_loc sel_id tys [pred] tau
+
newMethodWith inst_loc@(_,loc,_) id tys theta tau
= newUnique `thenM` \ new_uniq ->
let
inst = Method meth_id id tys theta tau inst_loc
in
returnM inst
-
-newMethodAtLoc :: InstLoc
- -> Id -> [TcType]
- -> TcM Inst
-newMethodAtLoc inst_loc real_id tys
- -- This actually builds the Inst
- = -- Get the Id type and instantiate it at the specified types
- let
- (tyvars,rho) = tcSplitForAllTys (idType real_id)
- rho_ty = ASSERT( equalLength tyvars tys )
- substTy (mkTopTyVarSubst tyvars tys) rho
- (theta, tau) = tcSplitPhiTy rho_ty
- in
- newMethodWith inst_loc real_id tys theta tau
\end{code}
In newOverloadedLit we convert directly to an Int or Integer if we
| otherwise
= ASSERT( from_integer_name == fromIntegerName ) -- A LitInst invariant
tcLookupId fromIntegerName `thenM` \ from_integer ->
- newMethodAtLoc loc from_integer [ty] `thenM` \ method_inst ->
+ tcInstClassOp loc from_integer [ty] `thenM` \ method_inst ->
returnM (GenInst [method_inst]
(HsApp (HsVar (instToId method_inst)) (HsLit (HsInteger i))))
| otherwise
= ASSERT( from_rat_name == fromRationalName ) -- A LitInst invariant
tcLookupId fromRationalName `thenM` \ from_rational ->
- newMethodAtLoc loc from_rational [ty] `thenM` \ method_inst ->
+ tcInstClassOp loc from_rational [ty] `thenM` \ method_inst ->
mkRatLit f `thenM` \ rat_lit ->
returnM (GenInst [method_inst] (HsApp (HsVar (instToId method_inst)) rat_lit))
\end{code}
import RnEnv ( lookupSysName )
import TcHsSyn ( TcMonoBinds )
-import Inst ( Inst, InstOrigin(..), instToId, newDicts, newMethodAtLoc )
+import Inst ( Inst, InstOrigin(..), instToId, newDicts, tcInstClassOp )
import TcEnv ( TyThingDetails(..),
tcLookupClass, tcExtendTyVarEnv2,
tcExtendTyVarEnv
mkMethodBind origin clas inst_tys meth_binds (sel_id, dm_info)
= getInstLoc origin `thenM` \ inst_loc ->
- newMethodAtLoc inst_loc sel_id inst_tys `thenM` \ meth_inst ->
+ tcInstClassOp inst_loc sel_id inst_tys `thenM` \ meth_inst ->
-- Do not dump anything into the LIE
let
meth_id = instToId meth_inst
tcSplitSigmaTy, getClassPredTys, tcSplitPredTy_maybe, mkTyVarTys,
TyVarDetails(..)
)
-import Inst ( InstOrigin(..), newMethod, newMethodAtLoc,
+import Inst ( InstOrigin(..), newMethod, tcInstClassOp,
newDicts, instToId, showLIE )
import TcDeriv ( tcDeriving )
import TcEnv ( tcExtendGlobalValEnv,
where
do_one inst_loc (sel_id, _)
- = newMethodAtLoc inst_loc sel_id inst_tys' `thenM` \ meth_inst ->
- -- Like in mkMethodBind
+ = -- The binding is like "op @ NewTy = op @ RepTy"
+ -- Make the *binder*, like in mkMethodBind
+ tcInstClassOp inst_loc sel_id inst_tys' `thenM` \ meth_inst ->
+
+ -- Make the *occurrence on the rhs*
newMethod InstanceDeclOrigin sel_id rep_tys' `thenM` \ rhs_id ->
- -- The binding is like "op @ NewTy = op @ RepTy"
let
meth_id = instToId meth_inst
in
instToId, tyVarsOfInsts, cloneDict,
ipNamesOfInsts, ipNamesOfInst, dictPred,
instBindingRequired, instCanBeGeneralised,
- newDictsFromOld, newMethodAtLoc,
+ newDictsFromOld, tcInstClassOp,
getDictClassTys, isTyVarDict,
instLoc, pprInst, zonkInst, tidyInsts, tidyMoreInsts,
Inst, pprInsts, pprInstsInFull,
| otherwise
= tcLookupId splitName `thenM` \ split_id ->
- newMethodAtLoc (instLoc wanted) split_id
- [linearInstType wanted] `thenM` \ split_inst ->
+ tcInstClassOp (instLoc wanted) split_id
+ [linearInstType wanted] `thenM` \ split_inst ->
returnM (addToFM avails wanted (Linear 2 split_inst avail), [split_inst])
where