pprInst, pprInsts, pprInstsInFull, tidyInsts, tidyMoreInsts,
newDictsFromOld, newDicts, cloneDict,
- newMethod, newMethodWithGivenTy, newMethodAtLoc,
- newOverloadedLit, newIPDict, tcInstCall,
+ newMethod, newMethodFromName, newMethodWithGivenTy, newMethodAtLoc,
+ newOverloadedLit, newIPDict, tcInstCall, tcInstDataCon,
tyVarsOfInst, tyVarsOfInsts, tyVarsOfLIE,
ipNamesOfInst, ipNamesOfInsts, predsOfInst, predsOfInsts,
mkHsTyApp, mkHsDictApp, mkHsConApp, zonkId
)
import TcMonad
-import TcEnv ( TcIdSet, tcGetInstEnv, tcLookupId )
+import TcEnv ( TcIdSet, tcGetInstEnv, tcLookupId, tcLookupGlobalId )
import InstEnv ( InstLookupResult(..), lookupInstEnv )
-import TcMType ( zonkTcType, zonkTcTypes, zonkTcPredType,
- zonkTcThetaType, tcInstTyVar, tcInstType,
+import TcMType ( zonkTcType, zonkTcTypes, zonkTcPredType, zapToType,
+ zonkTcThetaType, tcInstTyVar, tcInstType, tcInstTyVars
)
import TcType ( Type, TcType, TcThetaType, TcPredType, TcTauType, TcTyVarSet,
- SourceType(..), PredType, ThetaType,
- tcSplitForAllTys, tcSplitForAllTys,
- tcSplitMethodTy, tcSplitRhoTy, tcFunArgTy,
+ SourceType(..), PredType, ThetaType, TyVarDetails(VanillaTv),
+ tcSplitForAllTys, tcSplitForAllTys, mkTyConApp,
+ tcSplitMethodTy, tcSplitPhiTy, tcFunArgTy,
isIntTy,isFloatTy, isIntegerTy, isDoubleTy,
tcIsTyVarTy, mkPredTy, mkTyVarTy, mkTyVarTys,
tyVarsOfType, tyVarsOfTypes, tyVarsOfPred, tidyPred,
)
import CoreFVs ( idFreeTyVars )
import Class ( Class )
+import DataCon ( dataConSig )
import Id ( Id, idName, idType, mkUserLocal, mkSysLocal, mkLocalId, setIdUnique )
import PrelInfo ( isStandardClass, isCcallishClass, isNoDictClass )
import Name ( Name, mkMethodOcc, getOccName )
\begin{code}
tcInstCall :: InstOrigin -> TcType -> NF_TcM (TypecheckedHsExpr -> TypecheckedHsExpr, LIE, TcType)
tcInstCall orig fun_ty -- fun_ty is usually a sigma-type
- = tcInstType fun_ty `thenNF_Tc` \ (tyvars, theta, tau) ->
+ = tcInstType VanillaTv fun_ty `thenNF_Tc` \ (tyvars, theta, tau) ->
newDicts orig theta `thenNF_Tc` \ dicts ->
let
inst_fn e = mkHsDictApp (mkHsTyApp e (mkTyVarTys tyvars)) (map instToId dicts)
in
returnNF_Tc (inst_fn, mkLIE dicts, tau)
+tcInstDataCon orig data_con
+ = let
+ (tvs, stupid_theta, ex_tvs, ex_theta, arg_tys, tycon) = dataConSig data_con
+ -- We generate constraints for the stupid theta even when
+ -- pattern matching (as the Report requires)
+ in
+ tcInstTyVars VanillaTv (tvs ++ ex_tvs) `thenNF_Tc` \ (all_tvs', ty_args', tenv) ->
+ let
+ stupid_theta' = substTheta tenv stupid_theta
+ ex_theta' = substTheta tenv ex_theta
+ arg_tys' = map (substTy tenv) arg_tys
+
+ n_normal_tvs = length tvs
+ ex_tvs' = drop n_normal_tvs all_tvs'
+ result_ty = mkTyConApp tycon (take n_normal_tvs ty_args')
+ in
+ newDicts orig stupid_theta' `thenNF_Tc` \ stupid_dicts ->
+ newDicts orig ex_theta' `thenNF_Tc` \ ex_dicts ->
+
+ -- Note that we return the stupid theta *only* in the LIE;
+ -- we don't otherwise use it at all
+ returnNF_Tc (ty_args', map instToId ex_dicts, arg_tys', result_ty,
+ mkLIE stupid_dicts, mkLIE ex_dicts, ex_tvs')
+
+
+newMethodFromName :: InstOrigin -> TcType -> Name -> NF_TcM Inst
+newMethodFromName origin ty name
+ = tcLookupGlobalId name `thenNF_Tc` \ id ->
+ newMethod origin id [ty]
+
newMethod :: InstOrigin
-> TcId
-> [TcType]
(tyvars,rho) = tcSplitForAllTys (idType real_id)
rho_ty = ASSERT( equalLength tyvars tys )
substTy (mkTopTyVarSubst tyvars tys) rho
- (theta, tau) = tcSplitRhoTy rho_ty
+ (theta, tau) = tcSplitPhiTy rho_ty
in
newMethodWith inst_loc real_id tys theta tau `thenNF_Tc` \ meth_inst ->
returnNF_Tc (meth_inst, instToId meth_inst)
-> HsOverLit
-> TcType
-> NF_TcM (TcExpr, LIE)
-newOverloadedLit orig lit ty
- | Just expr <- shortCutLit lit ty
+newOverloadedLit orig lit expected_ty
+ | Just expr <- shortCutLit lit expected_ty
= returnNF_Tc (expr, emptyLIE)
| otherwise
= tcGetInstLoc orig `thenNF_Tc` \ loc ->
tcGetUnique `thenNF_Tc` \ new_uniq ->
+ zapToType expected_ty `thenNF_Tc_`
+ -- The expected type might be a 'hole' type variable,
+ -- in which case we must zap it to an ordinary type variable
let
- lit_inst = LitInst lit_id lit ty loc
- lit_id = mkSysLocal FSLIT("lit") new_uniq ty
+ lit_inst = LitInst lit_id lit expected_ty loc
+ lit_id = mkSysLocal FSLIT("lit") new_uniq expected_ty
in
returnNF_Tc (HsVar (instToId lit_inst), unitLIE lit_inst)
case lookupInstEnv dflags inst_env clas tys of
FoundInst tenv dfun_id
- -> let
+ -> -- It's possible that not all the tyvars are in
+ -- the substitution, tenv. For example:
+ -- instance C X a => D X where ...
+ -- (presumably there's a functional dependency in class C)
+ -- Hence the mk_ty_arg to instantiate any un-substituted tyvars.
+ let
(tyvars, rho) = tcSplitForAllTys (idType dfun_id)
mk_ty_arg tv = case lookupSubstEnv tenv tv of
Just (DoneTy ty) -> returnNF_Tc ty
- Nothing -> tcInstTyVar tv `thenNF_Tc` \ tc_tv ->
+ Nothing -> tcInstTyVar VanillaTv tv `thenNF_Tc` \ tc_tv ->
returnTc (mkTyVarTy tc_tv)
in
- -- It's possible that not all the tyvars are in
- -- the substitution, tenv. For example:
- -- instance C X a => D X where ...
- -- (presumably there's a functional dependency in class C)
- -- Hence the mk_ty_arg to instantiate any un-substituted tyvars.
mapNF_Tc mk_ty_arg tyvars `thenNF_Tc` \ ty_args ->
let
dfun_rho = substTy (mkTyVarSubst tyvars ty_args) rho
- (theta, _) = tcSplitRhoTy dfun_rho
+ (theta, _) = tcSplitPhiTy dfun_rho
ty_app = mkHsTyApp (HsVar dfun_id) ty_args
in
if null theta then
-> returnNF_Tc (Just (substTheta (mkSubst emptyInScopeSet tenv) theta))
where
(_, rho) = tcSplitForAllTys (idType dfun)
- (theta,_) = tcSplitRhoTy rho
+ (theta,_) = tcSplitPhiTy rho
other -> returnNF_Tc Nothing
\end{code}