\section[Inst]{The @Inst@ type: dictionaries or method instances}
\begin{code}
-module Inst (
+module Inst (
LIE, emptyLIE, unitLIE, plusLIE, consLIE, zonkLIE,
plusLIEs, mkLIE, isEmptyLIE,
InstanceMapper,
newDictFromOld, newDicts, newDictsAtLoc,
- newMethod, newMethodWithGivenTy, newOverloadedLit,
+ newMethod, newMethodWithGivenTy, newOverloadedLit, instOverloadedFun,
tyVarsOfInst, instLoc, getDictClassTys,
zonkInst, instToId, instToIdBndr,
- InstOrigin(..), pprOrigin
+ InstOrigin(..), InstLoc, pprInstLoc
) where
#include "HsVersions.h"
import HsSyn ( HsLit(..), HsExpr(..) )
import RnHsSyn ( RenamedArithSeqInfo, RenamedHsExpr, RenamedPat )
-import TcHsSyn ( TcExpr, TcIdOcc(..), TcIdBndr,
- mkHsTyApp, mkHsDictApp, tcIdTyVars, zonkTcId
+import TcHsSyn ( TcExpr, TcId,
+ mkHsTyApp, mkHsDictApp, zonkId
)
import TcMonad
-import TcEnv ( TcIdSet, tcLookupGlobalValueByKey, tcLookupTyConByKey,
- tidyType, tidyTypes
- )
+import TcEnv ( TcIdSet, tcLookupValueByKey, tcLookupTyConByKey )
import TcType ( TcThetaType,
TcType, TcTauType, TcTyVarSet,
zonkTcType, zonkTcTypes,
zonkTcThetaType
)
import Bag
-import Class ( classInstEnv,
- Class, ClassInstEnv
- )
-import Id ( Id, idType, mkUserLocal, mkSysLocal )
+import Class ( classInstEnv, Class )
+import Id ( Id, idFreeTyVars, idType, mkUserLocal, mkSysLocal )
import VarSet ( elemVarSet )
import PrelInfo ( isStandardClass, isCcallishClass, isNoDictClass )
-import Name ( OccName(..), Name, occNameString, getOccName )
+import Name ( OccName, Name, mkDictOcc, mkMethodOcc, getOccName )
import PprType ( pprConstraint )
-import SpecEnv ( SpecEnv, lookupSpecEnv )
+import InstEnv ( InstEnv, lookupInstEnv )
import SrcLoc ( SrcLoc )
-import Type ( Type, ThetaType, substTy,
- isTyVarTy, mkDictTy, splitForAllTys, splitSigmaTy,
+import Type ( Type, ThetaType,
+ mkTyVarTy, isTyVarTy, mkDictTy, splitForAllTys, splitSigmaTy,
splitRhoTy, tyVarsOfType, tyVarsOfTypes,
- mkSynTy, substFlexiTy, substFlexiTheta
+ mkSynTy, tidyOpenType, tidyOpenTypes
+ )
+import InstEnv ( InstEnv )
+import Subst ( emptyInScopeSet, mkSubst,
+ substTy, substTheta, mkTyVarSubst, mkTopTyVarSubst
)
import TyCon ( TyCon )
-import VarEnv ( zipVarEnv, lookupVarEnv )
+import Subst ( mkTyVarSubst )
+import VarEnv ( lookupVarEnv, TidyEnv,
+ lookupSubstEnv, SubstResult(..)
+ )
import VarSet ( unionVarSet )
import TysPrim ( intPrimTy, floatPrimTy, doublePrimTy )
import TysWiredIn ( intDataCon, isIntTy, inIntRange,
%************************************************************************
\begin{code}
-type LIE s = Bag (Inst s)
+type LIE = Bag Inst
isEmptyLIE = isEmptyBag
emptyLIE = emptyBag
consLIE inst lie = inst `consBag` lie
plusLIEs lies = unionManyBags lies
-zonkLIE :: LIE s -> NF_TcM s (LIE s)
+zonkLIE :: LIE -> NF_TcM s LIE
zonkLIE lie = mapBagNF_Tc zonkInst lie
-pprInsts :: [Inst s] -> SDoc
-pprInsts insts = parens (hsep (punctuate comma (map pprInst insts)))
+pprInsts :: [Inst] -> SDoc
+pprInsts insts = parens (sep (punctuate comma (map pprInst insts)))
pprInstsInFull insts
= vcat (map go insts)
where
- go inst = quotes (ppr inst) <+> pprOrigin inst
+ go inst = quotes (ppr inst) <+> pprInstLoc (instLoc inst)
\end{code}
%************************************************************************
Method 34 doubleId [Int] origin
\begin{code}
-data Inst s
+data Inst
= Dict
Unique
Class -- The type of the dict is (c ts), where
- [TcType s] -- c is the class and ts the types;
- (InstOrigin s)
- SrcLoc
+ [TcType] -- c is the class and ts the types;
+ InstLoc
| Method
Unique
- (TcIdOcc s) -- The overloaded function
+ TcId -- The overloaded function
-- This function will be a global, local, or ClassOpId;
-- inside instance decls (only) it can also be an InstId!
-- The id needn't be completely polymorphic.
-- You'll probably find its name (for documentation purposes)
-- inside the InstOrigin
- [TcType s] -- The types to which its polymorphic tyvars
+ [TcType] -- The types to which its polymorphic tyvars
-- should be instantiated.
-- These types must saturate the Id's foralls.
- (TcThetaType s) -- The (types of the) dictionaries to which the function
+ TcThetaType -- The (types of the) dictionaries to which the function
-- must be applied to get the method
- (TcTauType s) -- The type of the method
+ TcTauType -- The type of the method
- (InstOrigin s)
- SrcLoc
+ InstLoc
-- INVARIANT: in (Method u f tys theta tau loc)
-- type of (f tys dicts(from theta)) = tau
| LitInst
Unique
OverloadedLit
- (TcType s) -- The type at which the literal is used
- (InstOrigin s) -- Always a literal; but more convenient to carry this around
- SrcLoc
+ TcType -- The type at which the literal is used
+ InstLoc
data OverloadedLit
= OverloadedIntegral Integer -- The number
maps to do their stuff.
\begin{code}
-instance Ord (Inst s) where
+instance Ord Inst where
compare = cmpInst
-instance Eq (Inst s) where
+instance Eq Inst where
(==) i1 i2 = case i1 `cmpInst` i2 of
EQ -> True
other -> False
-cmpInst (Dict _ clas1 tys1 _ _) (Dict _ clas2 tys2 _ _)
+cmpInst (Dict _ clas1 tys1 _) (Dict _ clas2 tys2 _)
= (clas1 `compare` clas2) `thenCmp` (tys1 `compare` tys2)
-cmpInst (Dict _ _ _ _ _) other
+cmpInst (Dict _ _ _ _) other
= LT
-cmpInst (Method _ _ _ _ _ _ _) (Dict _ _ _ _ _)
+cmpInst (Method _ _ _ _ _ _) (Dict _ _ _ _)
= GT
-cmpInst (Method _ id1 tys1 _ _ _ _) (Method _ id2 tys2 _ _ _ _)
+cmpInst (Method _ id1 tys1 _ _ _) (Method _ id2 tys2 _ _ _)
= (id1 `compare` id2) `thenCmp` (tys1 `compare` tys2)
-cmpInst (Method _ _ _ _ _ _ _) other
+cmpInst (Method _ _ _ _ _ _) other
= LT
-cmpInst (LitInst _ lit1 ty1 _ _) (LitInst _ lit2 ty2 _ _)
+cmpInst (LitInst _ lit1 ty1 _) (LitInst _ lit2 ty2 _)
= (lit1 `cmpOverLit` lit2) `thenCmp` (ty1 `compare` ty2)
-cmpInst (LitInst _ _ _ _ _) other
+cmpInst (LitInst _ _ _ _) other
= GT
cmpOverLit (OverloadedIntegral i1) (OverloadedIntegral i2) = i1 `compare` i2
Selection
~~~~~~~~~
\begin{code}
-instOrigin (Dict u clas tys origin loc) = origin
-instOrigin (Method u clas ty _ _ origin loc) = origin
-instOrigin (LitInst u lit ty origin loc) = origin
-
-instLoc (Dict u clas tys origin loc) = loc
-instLoc (Method u clas ty _ _ origin loc) = loc
-instLoc (LitInst u lit ty origin loc) = loc
+instLoc (Dict u clas tys loc) = loc
+instLoc (Method u _ _ _ _ loc) = loc
+instLoc (LitInst u lit ty loc) = loc
-getDictClassTys (Dict u clas tys _ _) = (clas, tys)
+getDictClassTys (Dict u clas tys _) = (clas, tys)
-tyVarsOfInst :: Inst s -> TcTyVarSet s
-tyVarsOfInst (Dict _ _ tys _ _) = tyVarsOfTypes tys
-tyVarsOfInst (Method _ id tys _ _ _ _) = tyVarsOfTypes tys `unionVarSet` tcIdTyVars id
- -- The id might not be a RealId; in the case of
+tyVarsOfInst :: Inst -> TcTyVarSet
+tyVarsOfInst (Dict _ _ tys _) = tyVarsOfTypes tys
+tyVarsOfInst (Method _ id tys _ _ _) = tyVarsOfTypes tys `unionVarSet` idFreeTyVars id
+ -- The id might have free type variables; in the case of
-- locally-overloaded class methods, for example
-tyVarsOfInst (LitInst _ _ ty _ _) = tyVarsOfType ty
+tyVarsOfInst (LitInst _ _ ty _) = tyVarsOfType ty
\end{code}
Predicates
~~~~~~~~~~
\begin{code}
-isDict :: Inst s -> Bool
-isDict (Dict _ _ _ _ _) = True
-isDict other = False
+isDict :: Inst -> Bool
+isDict (Dict _ _ _ _) = True
+isDict other = False
-isMethodFor :: TcIdSet s -> Inst s -> Bool
-isMethodFor ids (Method uniq (TcId id) tys _ _ orig loc)
+isMethodFor :: TcIdSet -> Inst -> Bool
+isMethodFor ids (Method uniq id tys _ _ loc)
= id `elemVarSet` ids
isMethodFor ids inst
= False
-isTyVarDict :: Inst s -> Bool
-isTyVarDict (Dict _ _ tys _ _) = all isTyVarTy tys
-isTyVarDict other = False
+isTyVarDict :: Inst -> Bool
+isTyVarDict (Dict _ _ tys _) = all isTyVarTy tys
+isTyVarDict other = False
-isStdClassTyVarDict (Dict _ clas [ty] _ _) = isStandardClass clas && isTyVarTy ty
-isStdClassTyVarDict other = False
+isStdClassTyVarDict (Dict _ clas [ty] _) = isStandardClass clas && isTyVarTy ty
+isStdClassTyVarDict other = False
\end{code}
Two predicates which deal with the case where class constraints don't
@Inst@ can be generalised over.
\begin{code}
-instBindingRequired :: Inst s -> Bool
-instBindingRequired (Dict _ clas _ _ _) = not (isNoDictClass clas)
-instBindingRequired other = True
+instBindingRequired :: Inst -> Bool
+instBindingRequired (Dict _ clas _ _) = not (isNoDictClass clas)
+instBindingRequired other = True
-instCanBeGeneralised :: Inst s -> Bool
-instCanBeGeneralised (Dict _ clas _ _ _) = not (isCcallishClass clas)
-instCanBeGeneralised other = True
+instCanBeGeneralised :: Inst -> Bool
+instCanBeGeneralised (Dict _ clas _ _) = not (isCcallishClass clas)
+instCanBeGeneralised other = True
\end{code}
~~~~~~~~~~~~
\begin{code}
-newDicts :: InstOrigin s
- -> TcThetaType s
- -> NF_TcM s (LIE s, [TcIdOcc s])
+newDicts :: InstOrigin
+ -> TcThetaType
+ -> NF_TcM s (LIE, [TcId])
newDicts orig theta
- = tcGetSrcLoc `thenNF_Tc` \ loc ->
- newDictsAtLoc orig loc theta `thenNF_Tc` \ (dicts, ids) ->
+ = tcGetInstLoc orig `thenNF_Tc` \ loc ->
+ newDictsAtLoc loc theta `thenNF_Tc` \ (dicts, ids) ->
returnNF_Tc (listToBag dicts, ids)
-- Local function, similar to newDicts,
-- but with slightly different interface
-newDictsAtLoc :: InstOrigin s
- -> SrcLoc
- -> TcThetaType s
- -> NF_TcM s ([Inst s], [TcIdOcc s])
-newDictsAtLoc orig loc theta =
+newDictsAtLoc :: InstLoc
+ -> TcThetaType
+ -> NF_TcM s ([Inst], [TcId])
+newDictsAtLoc loc theta =
tcGetUniques (length theta) `thenNF_Tc` \ new_uniqs ->
let
- mk_dict u (clas, tys) = Dict u clas tys orig loc
+ mk_dict u (clas, tys) = Dict u clas tys loc
dicts = zipWithEqual "newDictsAtLoc" mk_dict new_uniqs theta
in
returnNF_Tc (dicts, map instToId dicts)
-newDictFromOld :: Inst s -> Class -> [TcType s] -> NF_TcM s (Inst s)
-newDictFromOld (Dict _ _ _ orig loc) clas tys
+newDictFromOld :: Inst -> Class -> [TcType] -> NF_TcM s Inst
+newDictFromOld (Dict _ _ _ loc) clas tys
= tcGetUnique `thenNF_Tc` \ uniq ->
- returnNF_Tc (Dict uniq clas tys orig loc)
+ returnNF_Tc (Dict uniq clas tys loc)
-newMethod :: InstOrigin s
- -> TcIdOcc s
- -> [TcType s]
- -> NF_TcM s (LIE s, TcIdOcc s)
+newMethod :: InstOrigin
+ -> TcId
+ -> [TcType]
+ -> NF_TcM s (LIE, TcId)
newMethod orig id tys
= -- Get the Id type and instantiate it at the specified types
- (case id of
- RealId id -> let
- (tyvars, rho) = splitForAllTys (idType id)
- in
- ASSERT( length tyvars == length tys)
- returnNF_Tc (substFlexiTy (zipVarEnv tyvars tys) rho)
-
- TcId id -> let
- (tyvars, rho) = splitForAllTys (idType id)
- in
- returnNF_Tc (substTy (zipVarEnv tyvars tys) rho)
- ) `thenNF_Tc` \ rho_ty ->
let
- (theta, tau) = splitRhoTy rho_ty
+ (tyvars, rho) = splitForAllTys (idType id)
+ rho_ty = substTy (mkTyVarSubst tyvars tys) rho
+ (theta, tau) = splitRhoTy rho_ty
in
newMethodWithGivenTy orig id tys theta tau `thenNF_Tc` \ meth_inst ->
returnNF_Tc (unitLIE meth_inst, instToId meth_inst)
+instOverloadedFun orig (HsVar v) arg_tys theta tau
+ = newMethodWithGivenTy orig v arg_tys theta tau `thenNF_Tc` \ inst ->
+ returnNF_Tc (HsVar (instToId inst), unitLIE inst)
newMethodWithGivenTy orig id tys theta tau
- = tcGetSrcLoc `thenNF_Tc` \ loc ->
+ = tcGetInstLoc orig `thenNF_Tc` \ loc ->
tcGetUnique `thenNF_Tc` \ new_uniq ->
let
- meth_inst = Method new_uniq id tys theta tau orig loc
+ meth_inst = Method new_uniq id tys theta tau loc
in
returnNF_Tc meth_inst
-newMethodAtLoc :: InstOrigin s -> SrcLoc
- -> Id -> [TcType s]
- -> NF_TcM s (Inst s, TcIdOcc s)
-newMethodAtLoc orig loc real_id tys -- Local function, similar to newMethod but with
+newMethodAtLoc :: InstLoc
+ -> Id -> [TcType]
+ -> NF_TcM s (Inst, TcId)
+newMethodAtLoc loc real_id tys -- Local function, similar to newMethod but with
-- slightly different interface
= -- Get the Id type and instantiate it at the specified types
tcGetUnique `thenNF_Tc` \ new_uniq ->
let
(tyvars,rho) = splitForAllTys (idType real_id)
rho_ty = ASSERT( length tyvars == length tys )
- substFlexiTy (zipVarEnv tyvars tys) rho
+ substTy (mkTopTyVarSubst tyvars tys) rho
(theta, tau) = splitRhoTy rho_ty
- meth_inst = Method new_uniq (RealId real_id) tys theta tau orig loc
+ meth_inst = Method new_uniq real_id tys theta tau loc
in
returnNF_Tc (meth_inst, instToId meth_inst)
\end{code}
cases (the rest are caught in lookupInst).
\begin{code}
-newOverloadedLit :: InstOrigin s
+newOverloadedLit :: InstOrigin
-> OverloadedLit
- -> TcType s
- -> NF_TcM s (TcExpr s, LIE s)
+ -> TcType
+ -> NF_TcM s (TcExpr, LIE)
newOverloadedLit orig (OverloadedIntegral i) ty
| isIntTy ty && inIntRange i -- Short cut for Int
= returnNF_Tc (int_lit, emptyLIE)
int_lit = HsCon intDataCon [] [intprim_lit]
newOverloadedLit orig lit ty -- The general case
- = tcGetSrcLoc `thenNF_Tc` \ loc ->
+ = tcGetInstLoc orig `thenNF_Tc` \ loc ->
tcGetUnique `thenNF_Tc` \ new_uniq ->
let
- lit_inst = LitInst new_uniq lit ty orig loc
+ lit_inst = LitInst new_uniq lit ty loc
in
returnNF_Tc (HsVar (instToId lit_inst), unitLIE lit_inst)
\end{code}
\begin{code}
-instToId :: Inst s -> TcIdOcc s
-instToId inst = TcId (instToIdBndr inst)
+instToId :: Inst -> TcId
+instToId inst = instToIdBndr inst
-instToIdBndr :: Inst s -> TcIdBndr s
-instToIdBndr (Dict u clas ty orig loc)
- = mkUserLocal occ u (mkDictTy clas ty)
- where
- occ = VarOcc (SLIT("d.") _APPEND_ (occNameString (getOccName clas)))
+instToIdBndr :: Inst -> TcId
+instToIdBndr (Dict u clas ty (_,loc,_))
+ = mkUserLocal (mkDictOcc (getOccName clas)) u (mkDictTy clas ty) loc
-instToIdBndr (Method u id tys theta tau orig loc)
- = mkUserLocal (getOccName id) u tau
+instToIdBndr (Method u id tys theta tau (_,loc,_))
+ = mkUserLocal (mkMethodOcc (getOccName id)) u tau loc
-instToIdBndr (LitInst u list ty orig loc)
- = mkSysLocal u ty
+instToIdBndr (LitInst u list ty loc)
+ = mkSysLocal SLIT("lit") u ty
\end{code}
need, and it's a lot of extra work.
\begin{code}
-zonkInst :: Inst s -> NF_TcM s (Inst s)
-zonkInst (Dict u clas tys orig loc)
+zonkInst :: Inst -> NF_TcM s Inst
+zonkInst (Dict u clas tys loc)
= zonkTcTypes tys `thenNF_Tc` \ new_tys ->
- returnNF_Tc (Dict u clas new_tys orig loc)
+ returnNF_Tc (Dict u clas new_tys loc)
+
+zonkInst (Method u id tys theta tau loc)
+ = zonkId id `thenNF_Tc` \ new_id ->
+ -- Essential to zonk the id in case it's a local variable
+ -- Can't use zonkIdOcc because the id might itself be
+ -- an InstId, in which case it won't be in scope
-zonkInst (Method u id tys theta tau orig loc)
- = zonkTcId id `thenNF_Tc` \ new_id ->
- -- Essential to zonk the id in case it's a local variable
zonkTcTypes tys `thenNF_Tc` \ new_tys ->
zonkTcThetaType theta `thenNF_Tc` \ new_theta ->
zonkTcType tau `thenNF_Tc` \ new_tau ->
- returnNF_Tc (Method u new_id new_tys new_theta new_tau orig loc)
+ returnNF_Tc (Method u new_id new_tys new_theta new_tau loc)
-zonkInst (LitInst u lit ty orig loc)
+zonkInst (LitInst u lit ty loc)
= zonkTcType ty `thenNF_Tc` \ new_ty ->
- returnNF_Tc (LitInst u lit new_ty orig loc)
+ returnNF_Tc (LitInst u lit new_ty loc)
\end{code}
relevant in error messages.
\begin{code}
-instance Outputable (Inst s) where
+instance Outputable Inst where
ppr inst = pprInst inst
-pprInst (LitInst u lit ty orig loc)
+pprInst (LitInst u lit ty loc)
= hsep [case lit of
OverloadedIntegral i -> integer i
OverloadedFractional f -> rational f,
ppr ty,
show_uniq u]
-pprInst (Dict u clas tys orig loc) = pprConstraint clas tys <+> show_uniq u
+pprInst (Dict u clas tys loc) = pprConstraint clas tys <+> show_uniq u
-pprInst (Method u id tys _ _ orig loc)
+pprInst (Method u id tys _ _ loc)
= hsep [ppr id, ptext SLIT("at"),
brackets (interppSP tys),
show_uniq u]
-tidyInst :: TidyTypeEnv s -> Inst s -> (TidyTypeEnv s, Inst s)
-tidyInst env (LitInst u lit ty orig loc)
- = (env', LitInst u lit ty' orig loc)
+tidyInst :: TidyEnv -> Inst -> (TidyEnv, Inst)
+tidyInst env (LitInst u lit ty loc)
+ = (env', LitInst u lit ty' loc)
where
- (env', ty') = tidyType env ty
+ (env', ty') = tidyOpenType env ty
-tidyInst env (Dict u clas tys orig loc)
- = (env', Dict u clas tys' orig loc)
+tidyInst env (Dict u clas tys loc)
+ = (env', Dict u clas tys' loc)
where
- (env', tys') = tidyTypes env tys
+ (env', tys') = tidyOpenTypes env tys
-tidyInst env (Method u id tys theta tau orig loc)
- = (env', Method u id tys' theta tau orig loc)
+tidyInst env (Method u id tys theta tau loc)
+ = (env', Method u id tys' theta tau loc)
-- Leave theta, tau alone cos we don't print them
where
- (env', tys') = tidyTypes env tys
+ (env', tys') = tidyOpenTypes env tys
tidyInsts env insts = mapAccumL tidyInst env insts
%************************************************************************
\begin{code}
-type InstanceMapper = Class -> ClassInstEnv
+type InstanceMapper = Class -> InstEnv
\end{code}
A @ClassInstEnv@ lives inside a class, and identifies all the instances
\begin{code}
data LookupInstResult s
= NoInstance
- | SimpleInst (TcExpr s) -- Just a variable, type application, or literal
- | GenInst [Inst s] (TcExpr s) -- The expression and its needed insts
+ | SimpleInst TcExpr -- Just a variable, type application, or literal
+ | GenInst [Inst] TcExpr -- The expression and its needed insts
-lookupInst :: Inst s
+lookupInst :: Inst
-> NF_TcM s (LookupInstResult s)
-- Dictionaries
-lookupInst dict@(Dict _ clas tys orig loc)
- = case lookupSpecEnv (ppr clas) (classInstEnv clas) tys of
+lookupInst dict@(Dict _ clas tys loc)
+ = case lookupInstEnv (ppr clas) (classInstEnv clas) tys of
Just (tenv, dfun_id)
-> let
+ subst = mkSubst (tyVarsOfTypes tys) tenv
(tyvars, rho) = splitForAllTys (idType dfun_id)
- ty_args = map (expectJust "Inst" . lookupVarEnv tenv) tyvars
- -- tenv should bind all the tyvars
- dfun_rho = substFlexiTy tenv rho
+ ty_args = map subst_tv tyvars
+ dfun_rho = substTy subst rho
(theta, tau) = splitRhoTy dfun_rho
- ty_app = mkHsTyApp (HsVar (RealId dfun_id)) ty_args
+ ty_app = mkHsTyApp (HsVar dfun_id) ty_args
+ subst_tv tv = case lookupSubstEnv tenv tv of
+ Just (DoneTy ty) -> ty
+ -- tenv should bind all the tyvars
in
if null theta then
returnNF_Tc (SimpleInst ty_app)
else
- newDictsAtLoc orig loc theta `thenNF_Tc` \ (dicts, dict_ids) ->
+ newDictsAtLoc loc theta `thenNF_Tc` \ (dicts, dict_ids) ->
let
rhs = mkHsDictApp ty_app dict_ids
in
-- Methods
-lookupInst inst@(Method _ id tys theta _ orig loc)
- = newDictsAtLoc orig loc theta `thenNF_Tc` \ (dicts, dict_ids) ->
+lookupInst inst@(Method _ id tys theta _ loc)
+ = newDictsAtLoc loc theta `thenNF_Tc` \ (dicts, dict_ids) ->
returnNF_Tc (GenInst dicts (mkHsDictApp (mkHsTyApp (HsVar id) tys) dict_ids))
-- Literals
-lookupInst inst@(LitInst u (OverloadedIntegral i) ty orig loc)
+lookupInst inst@(LitInst u (OverloadedIntegral i) ty loc)
| isIntTy ty && in_int_range -- Short cut for Int
= returnNF_Tc (GenInst [] int_lit)
-- GenInst, not SimpleInst, because int_lit is actually a constructor application
= returnNF_Tc (GenInst [] integer_lit)
| in_int_range -- It's overloaded but small enough to fit into an Int
- = tcLookupGlobalValueByKey fromIntClassOpKey `thenNF_Tc` \ from_int ->
- newMethodAtLoc orig loc from_int [ty] `thenNF_Tc` \ (method_inst, method_id) ->
+ = tcLookupValueByKey fromIntClassOpKey `thenNF_Tc` \ from_int ->
+ newMethodAtLoc loc from_int [ty] `thenNF_Tc` \ (method_inst, method_id) ->
returnNF_Tc (GenInst [method_inst] (HsApp (HsVar method_id) int_lit))
| otherwise -- Alas, it is overloaded and a big literal!
- = tcLookupGlobalValueByKey fromIntegerClassOpKey `thenNF_Tc` \ from_integer ->
- newMethodAtLoc orig loc from_integer [ty] `thenNF_Tc` \ (method_inst, method_id) ->
+ = tcLookupValueByKey fromIntegerClassOpKey `thenNF_Tc` \ from_integer ->
+ newMethodAtLoc loc from_integer [ty] `thenNF_Tc` \ (method_inst, method_id) ->
returnNF_Tc (GenInst [method_inst] (HsApp (HsVar method_id) integer_lit))
where
in_int_range = inIntRange i
-- *definitely* a float or a double, generate the real thing here.
-- This is essential (see nofib/spectral/nucleic).
-lookupInst inst@(LitInst u (OverloadedFractional f) ty orig loc)
+lookupInst inst@(LitInst u (OverloadedFractional f) ty loc)
| isFloatTy ty = returnNF_Tc (GenInst [] float_lit)
| isDoubleTy ty = returnNF_Tc (GenInst [] double_lit)
| otherwise
- = tcLookupGlobalValueByKey fromRationalClassOpKey `thenNF_Tc` \ from_rational ->
+ = tcLookupValueByKey fromRationalClassOpKey `thenNF_Tc` \ from_rational ->
-- The type Rational isn't wired in so we have to conjure it up
tcLookupTyConByKey rationalTyConKey `thenNF_Tc` \ rational_tycon ->
rational_ty = mkSynTy rational_tycon []
rational_lit = HsLitOut (HsFrac f) rational_ty
in
- newMethodAtLoc orig loc from_rational [ty] `thenNF_Tc` \ (method_inst, method_id) ->
+ newMethodAtLoc loc from_rational [ty] `thenNF_Tc` \ (method_inst, method_id) ->
returnNF_Tc (GenInst [method_inst] (HsApp (HsVar method_id) rational_lit))
where
ambiguous dictionaries.
\begin{code}
-lookupSimpleInst :: ClassInstEnv
+lookupSimpleInst :: InstEnv
-> Class
-> [Type] -- Look up (c,t)
-> NF_TcM s (Maybe ThetaType) -- Here are the needed (c,t)s
lookupSimpleInst class_inst_env clas tys
- = case lookupSpecEnv (ppr clas) class_inst_env tys of
+ = case lookupInstEnv (ppr clas) class_inst_env tys of
Nothing -> returnNF_Tc Nothing
Just (tenv, dfun)
- -> returnNF_Tc (Just (substFlexiTheta tenv theta))
+ -> returnNF_Tc (Just (substTheta (mkSubst emptyInScopeSet tenv) theta))
where
(_, theta, _) = splitSigmaTy (idType dfun)
\end{code}
-
-
-
-%************************************************************************
-%* *
-\subsection[Inst-origin]{The @InstOrigin@ type}
-%* *
-%************************************************************************
-
-The @InstOrigin@ type gives information about where a dictionary came from.
-This is important for decent error message reporting because dictionaries
-don't appear in the original source code. Doubtless this type will evolve...
-
-\begin{code}
-data InstOrigin s
- = OccurrenceOf (TcIdOcc s) -- Occurrence of an overloaded identifier
- | OccurrenceOfCon Id -- Occurrence of a data constructor
-
- | RecordUpdOrigin
-
- | DataDeclOrigin -- Typechecking a data declaration
-
- | InstanceDeclOrigin -- Typechecking an instance decl
-
- | LiteralOrigin HsLit -- Occurrence of a literal
-
- | PatOrigin RenamedPat
-
- | ArithSeqOrigin RenamedArithSeqInfo -- [x..], [x..y] etc
-
- | SignatureOrigin -- A dict created from a type signature
- | Rank2Origin -- A dict created when typechecking the argument
- -- of a rank-2 typed function
-
- | DoOrigin -- The monad for a do expression
-
- | ClassDeclOrigin -- Manufactured during a class decl
-
- | InstanceSpecOrigin Class -- in a SPECIALIZE instance pragma
- Type
-
- -- When specialising instances the instance info attached to
- -- each class is not yet ready, so we record it inside the
- -- origin information. This is a bit of a hack, but it works
- -- fine. (Patrick is to blame [WDP].)
-
- | ValSpecOrigin Name -- in a SPECIALIZE pragma for a value
-
- -- Argument or result of a ccall
- -- Dictionaries with this origin aren't actually mentioned in the
- -- translated term, and so need not be bound. Nor should they
- -- be abstracted over.
-
- | CCallOrigin String -- CCall label
- (Maybe RenamedHsExpr) -- Nothing if it's the result
- -- Just arg, for an argument
-
- | LitLitOrigin String -- the litlit
-
- | UnknownOrigin -- Help! I give up...
-\end{code}
-
-\begin{code}
-pprOrigin :: Inst s -> SDoc
-pprOrigin inst
- = hsep [text "arising from", pp_orig orig, text "at", ppr locn]
- where
- (orig, locn) = case inst of
- Dict _ _ _ orig loc -> (orig,loc)
- Method _ _ _ _ _ orig loc -> (orig,loc)
- LitInst _ _ _ orig loc -> (orig,loc)
-
- pp_orig (OccurrenceOf id)
- = hsep [ptext SLIT("use of"), quotes (ppr id)]
- pp_orig (OccurrenceOfCon id)
- = hsep [ptext SLIT("use of"), quotes (ppr id)]
- pp_orig (LiteralOrigin lit)
- = hsep [ptext SLIT("the literal"), quotes (ppr lit)]
- pp_orig (PatOrigin pat)
- = hsep [ptext SLIT("the pattern"), quotes (ppr pat)]
- pp_orig (InstanceDeclOrigin)
- = ptext SLIT("an instance declaration")
- pp_orig (ArithSeqOrigin seq)
- = hsep [ptext SLIT("the arithmetic sequence"), quotes (ppr seq)]
- pp_orig (SignatureOrigin)
- = ptext SLIT("a type signature")
- pp_orig (Rank2Origin)
- = ptext SLIT("a function with an overloaded argument type")
- pp_orig (DoOrigin)
- = ptext SLIT("a do statement")
- pp_orig (ClassDeclOrigin)
- = ptext SLIT("a class declaration")
- pp_orig (InstanceSpecOrigin clas ty)
- = hsep [text "a SPECIALIZE instance pragma; class",
- quotes (ppr clas), text "type:", ppr ty]
- pp_orig (ValSpecOrigin name)
- = hsep [ptext SLIT("a SPECIALIZE user-pragma for"), quotes (ppr name)]
- pp_orig (CCallOrigin clabel Nothing{-ccall result-})
- = hsep [ptext SLIT("the result of the _ccall_ to"), quotes (text clabel)]
- pp_orig (CCallOrigin clabel (Just arg_expr))
- = hsep [ptext SLIT("an argument in the _ccall_ to"), quotes (text clabel) <> comma,
- text "namely", quotes (ppr arg_expr)]
- pp_orig (LitLitOrigin s)
- = hsep [ptext SLIT("the ``literal-literal''"), quotes (text s)]
- pp_orig (UnknownOrigin)
- = ptext SLIT("...oops -- I don't know where the overloading came from!")
-\end{code}