+tcInstCall :: InstOrigin -> TcType -> TcM (ExprCoFn, TcType)
+tcInstCall orig fun_ty -- fun_ty is usually a sigma-type
+ = tcInstType VanillaTv fun_ty `thenM` \ (tyvars, theta, tau) ->
+ newDicts orig theta `thenM` \ dicts ->
+ extendLIEs dicts `thenM_`
+ let
+ inst_fn e = DictApp (mkHsTyApp (noLoc e) (mkTyVarTys tyvars)) (map instToId dicts)
+ in
+ returnM (mkCoercion inst_fn, tau)
+
+tcInstDataCon :: InstOrigin
+ -> TyVarDetails -- Use this for the existential tyvars
+ -- ExistTv when pattern-matching,
+ -- VanillaTv at a call of the constructor
+ -> DataCon
+ -> TcM ([TcType], -- Types to instantiate at
+ [Inst], -- Existential dictionaries to apply to
+ [TcType], -- Argument types of constructor
+ TcType, -- Result type
+ [TyVar]) -- Existential tyvars
+tcInstDataCon orig ex_tv_details 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
+ mappM (tcInstTyVar VanillaTv) tvs `thenM` \ tvs' ->
+ mappM (tcInstTyVar ex_tv_details) ex_tvs `thenM` \ ex_tvs' ->
+ let
+ tv_tys' = mkTyVarTys tvs'
+ ex_tv_tys' = mkTyVarTys ex_tvs'
+ all_tys' = tv_tys' ++ ex_tv_tys'
+
+ tenv = mkTopTyVarSubst (tvs ++ ex_tvs) all_tys'
+ stupid_theta' = substTheta tenv stupid_theta
+ ex_theta' = substTheta tenv ex_theta
+ arg_tys' = map (substTy tenv) arg_tys
+ result_ty' = mkTyConApp tycon tv_tys'
+ in
+ newDicts orig stupid_theta' `thenM` \ stupid_dicts ->
+ newDicts orig ex_theta' `thenM` \ ex_dicts ->
+
+ -- Note that we return the stupid theta *only* in the LIE;
+ -- we don't otherwise use it at all
+ extendLIEs stupid_dicts `thenM_`
+
+ returnM (all_tys', ex_dicts, arg_tys', result_ty', ex_tvs')
+
+newMethodFromName :: InstOrigin -> TcType -> Name -> TcM TcId
+newMethodFromName origin ty name
+ = tcLookupId name `thenM` \ id ->
+ -- Use tcLookupId not tcLookupGlobalId; the method is almost
+ -- always a class op, but with -fno-implicit-prelude GHC is
+ -- meant to find whatever thing is in scope, and that may
+ -- be an ordinary function.
+ getInstLoc origin `thenM` \ loc ->
+ tcInstClassOp loc id [ty] `thenM` \ inst ->
+ extendLIE inst `thenM_`
+ returnM (instToId inst)
+
+newMethodWithGivenTy orig id tys theta tau
+ = getInstLoc orig `thenM` \ loc ->
+ newMethod loc id tys theta tau `thenM` \ inst ->
+ extendLIE inst `thenM_`
+ returnM (instToId inst)
+
+--------------------------------------------
+-- tcInstClassOp, and newMethod 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
+
+-- NB: the kind of the type variable to be instantiated
+-- might be a sub-kind of the type to which it is applied,
+-- notably when the latter is a type variable of kind ??
+-- Hence the call to checkKind
+-- A worry: is this needed anywhere else?
+tcInstClassOp :: InstLoc -> Id -> [TcType] -> TcM Inst
+tcInstClassOp inst_loc sel_id tys
+ = let
+ (tyvars,rho) = tcSplitForAllTys (idType sel_id)
+ rho_ty = ASSERT( length tyvars == length tys )
+ substTyWith tyvars tys rho
+ (preds,tau) = tcSplitPhiTy rho_ty
+ in
+ zipWithM_ checkKind tyvars tys `thenM_`
+ newMethod inst_loc sel_id tys preds tau
+
+checkKind :: TyVar -> TcType -> TcM ()
+-- Ensure that the type has a sub-kind of the tyvar
+checkKind tv ty
+ = do { ty1 <- zonkTcType ty
+ ; if typeKind ty1 `isSubKind` tyVarKind tv
+ then return ()
+ else do
+ { traceTc (text "checkKind: adding kind constraint" <+> ppr tv <+> ppr ty)
+ ; tv1 <- tcInstTyVar VanillaTv tv
+ ; unifyTauTy (mkTyVarTy tv1) ty1 }}
+
+
+---------------------------
+newMethod inst_loc id tys theta tau
+ = newUnique `thenM` \ new_uniq ->
+ let
+ meth_id = mkUserLocal (mkMethodOcc (getOccName id)) new_uniq tau loc
+ inst = Method meth_id id tys theta tau inst_loc
+ loc = instLocSrcLoc inst_loc
+ in
+ returnM inst