\begin{code}
module Inst (
- showLIE,
-
Inst,
- pprInst, pprInsts, pprDFuns, pprDictsTheta, pprDictsInFull,
+
+ pprDFuns, pprDictsTheta, pprDictsInFull, -- User error messages
+ showLIE, pprInst, pprInsts, pprInstInFull, -- Debugging messages
+
tidyInsts, tidyMoreInsts,
newDictsFromOld, newDicts, cloneDict,
import PrelInfo ( isStandardClass, isNoDictClass )
import Name ( Name, mkMethodOcc, getOccName, getSrcLoc, isHomePackageName, isInternalName )
import NameSet ( addOneToNameSet )
-import Subst ( substTy, substTyWith, substTheta, mkTyVarSubst )
+import Subst ( substTy, substTyWith, substTheta, mkTopTyVarSubst )
import Literal ( inIntRange )
import Var ( TyVar, tyVarKind )
import VarEnv ( TidyEnv, emptyTidyEnv, lookupSubstEnv, SubstResult(..) )
import PrelNames ( integerTyConName, fromIntegerName, fromRationalName, rationalTyConName )
import BasicTypes( IPName(..), mapIPName, ipNameName )
import UniqSupply( uniqsFromSupply )
-import SrcLoc ( mkSrcSpan, noLoc, Located(..) )
+import SrcLoc ( mkSrcSpan, noLoc, unLoc, Located(..) )
import CmdLineOpts( DynFlags, DynFlag( Opt_AllowUndecidableInstances ), dopt )
import Maybes ( isJust )
import Outputable
in
returnM (mkCoercion inst_fn, tau)
-tcInstDataCon :: InstOrigin -> DataCon
+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 data_con
+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
- tcInstTyVars VanillaTv (tvs ++ ex_tvs) `thenM` \ (all_tvs', ty_args', tenv) ->
+ 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
-
- n_normal_tvs = length tvs
- ex_tvs' = drop n_normal_tvs all_tvs'
- result_ty = mkTyConApp tycon (take n_normal_tvs ty_args')
+ result_ty' = mkTyConApp tycon tv_tys'
in
newDicts orig stupid_theta' `thenM` \ stupid_dicts ->
newDicts orig ex_theta' `thenM` \ ex_dicts ->
-- we don't otherwise use it at all
extendLIEs stupid_dicts `thenM_`
- returnM (ty_args', ex_dicts, arg_tys', result_ty, ex_tvs')
+ returnM (all_tys', ex_dicts, arg_tys', result_ty', ex_tvs')
newMethodFromName :: InstOrigin -> TcType -> Name -> TcM TcId
newMethodFromName origin ty name
-- Reason: tcSyntaxName does unification
-- which is very inconvenient in tcSimplify
-- ToDo: noLoc sadness
- = tcSyntaxName orig expected_ty (fromIntegerName, noLoc (HsVar fi)) `thenM` \ (_,expr) ->
- mkIntegerLit i `thenM` \ integer_lit ->
- returnM (mkHsApp expr integer_lit)
-
+ = tcSyntaxName orig expected_ty (fromIntegerName, HsVar fi) `thenM` \ (_,expr) ->
+ mkIntegerLit i `thenM` \ integer_lit ->
+ returnM (mkHsApp (noLoc expr) integer_lit)
+ -- The mkHsApp will get the loc from the literal
| Just expr <- shortCutIntLit i expected_ty
= returnM expr
newOverloadedLit orig lit@(HsFractional r fr) expected_ty
| fr /= fromRationalName -- c.f. HsIntegral case
- = tcSyntaxName orig expected_ty (fromRationalName, noLoc (HsVar fr)) `thenM` \ (_,expr) ->
- mkRatLit r `thenM` \ rat_lit ->
- returnM (mkHsApp expr rat_lit)
+ = tcSyntaxName orig expected_ty (fromRationalName, HsVar fr) `thenM` \ (_,expr) ->
+ mkRatLit r `thenM` \ rat_lit ->
+ returnM (mkHsApp (noLoc expr) rat_lit)
+ -- The mkHsApp will get the loc from the literal
| Just expr <- shortCutFracLit r expected_ty
= returnM expr
-- Dictionaries
lookupInst dict@(Dict _ pred@(ClassP clas tys) loc)
- = do { dflags <- getDOpts
- ; if all tcIsTyVarTy tys &&
- not (dopt Opt_AllowUndecidableInstances dflags)
- -- Common special case; no lookup
- -- NB: tcIsTyVarTy... don't look through newtypes!
- -- Don't take this short cut if we allow undecidable instances
- -- because we might have "instance T a where ...".
- -- [That means we need -fallow-undecidable-instances in the
- -- client module, as well as the module with the instance decl.]
- then return NoInstance
-
- else do
- { pkg_ie <- loadImportedInsts clas tys
+ = do { pkg_ie <- loadImportedInsts clas tys
-- Suck in any instance decls that may be relevant
; tcg_env <- getGblEnv
+ ; dflags <- getDOpts
; case lookupInstEnv dflags (pkg_ie, tcg_inst_env tcg_env) clas tys of {
([(tenv, (_,_,dfun_id))], []) -> instantiate_dfun tenv dfun_id pred loc ;
(matches, unifs) -> do
- { traceTc (text "lookupInst" <+> vcat [text "matches" <+> ppr matches,
- text "unifs" <+> ppr unifs])
- ; return NoInstance } } } }
+ { traceTc (text "lookupInst fail" <+> vcat [text "dict" <+> ppr pred,
+ text "matches" <+> ppr matches,
+ text "unifs" <+> ppr unifs])
+ ; return NoInstance } } }
-- In the case of overlap (multiple matches) we report
-- NoInstance here. That has the effect of making the
-- context-simplifier return the dict as an irreducible one.
-----------------
instantiate_dfun tenv dfun_id pred loc
- = -- Record that this dfun is needed
+ = traceTc (text "lookupInst success" <+>
+ vcat [text "dict" <+> ppr pred,
+ text "witness" <+> ppr dfun_id <+> ppr (idType dfun_id) ]) `thenM_`
+ -- Record that this dfun is needed
record_dfun_usage dfun_id `thenM_`
-- It's possible that not all the tyvars are in
in
mappM mk_ty_arg tyvars `thenM` \ ty_args ->
let
- dfun_rho = substTy (mkTyVarSubst tyvars ty_args) rho
+ dfun_rho = substTy (mkTopTyVarSubst tyvars ty_args) rho
+ -- Since the tyvars are freshly made,
+ -- they cannot possibly be captured by
+ -- any existing for-alls. Hence mkTopTyVarSubst
(theta, _) = tcSplitPhiTy dfun_rho
ty_app = mkHsTyApp (L (instLocSrcSpan loc) (HsVar dfun_id)) ty_args
in
dfun_name = idName dfun_id
tcGetInstEnvs :: TcM (InstEnv, InstEnv)
--- Gets both the home-pkg inst env (includes module being compiled)
--- and the external-package inst-env
+-- Gets both the external-package inst-env
+-- and the home-pkg inst env (includes module being compiled)
tcGetInstEnvs = do { eps <- getEps; env <- getGblEnv;
- return (tcg_inst_env env, eps_inst_env eps) }
+ return (eps_inst_env eps, tcg_inst_env env) }
\end{code}
\begin{code}
tcSyntaxName :: InstOrigin
-> TcType -- Type to instantiate it at
- -> (Name, LHsExpr Name) -- (Standard name, user name)
- -> TcM (Name, LHsExpr TcId) -- (Standard name, suitable expression)
+ -> (Name, HsExpr Name) -- (Standard name, user name)
+ -> TcM (Name, HsExpr TcId) -- (Standard name, suitable expression)
-- NB: tcSyntaxName calls tcExpr, and hence can do unification.
-- So we do not call it from lookupInst, which is called from tcSimplify
-tcSyntaxName orig ty (std_nm, L span (HsVar user_nm))
+tcSyntaxName orig ty (std_nm, HsVar user_nm)
| std_nm == user_nm
- = addSrcSpan span (tcStdSyntaxName orig ty std_nm)
+ = tcStdSyntaxName orig ty std_nm
tcSyntaxName orig ty (std_nm, user_nm_expr)
= tcLookupId std_nm `thenM` \ std_id ->
let
-- C.f. newMethodAtLoc
([tv], _, tau) = tcSplitSigmaTy (idType std_id)
- tau1 = substTyWith [tv] [ty] tau
+ sigma1 = substTyWith [tv] [ty] tau
-- Actually, the "tau-type" might be a sigma-type in the
-- case of locally-polymorphic methods.
in
- addErrCtxtM (syntaxNameCtxt user_nm_expr orig tau1) $
+ addErrCtxtM (syntaxNameCtxt user_nm_expr orig sigma1) $
-- Check that the user-supplied thing has the
- -- same type as the standard one
- tcCheckSigma user_nm_expr tau1 `thenM` \ expr ->
- returnM (std_nm, expr)
+ -- same type as the standard one.
+ -- Tiresome jiggling because tcCheckSigma takes a located expression
+ getSrcSpanM `thenM` \ span ->
+ tcCheckSigma (L span user_nm_expr) sigma1 `thenM` \ expr ->
+ returnM (std_nm, unLoc expr)
tcStdSyntaxName :: InstOrigin
-> TcType -- Type to instantiate it at
-> Name -- Standard name
- -> TcM (Name, LHsExpr TcId) -- (Standard name, suitable expression)
+ -> TcM (Name, HsExpr TcId) -- (Standard name, suitable expression)
tcStdSyntaxName orig ty std_nm
= newMethodFromName orig ty std_nm `thenM` \ id ->
- getSrcSpanM `thenM` \ span ->
- returnM (std_nm, L span (HsVar id))
+ returnM (std_nm, HsVar id)
syntaxNameCtxt name orig ty tidy_env
= getInstLoc orig `thenM` \ inst_loc ->