2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
4 %************************************************************************
6 \section[Spec]{Specialisation of variables}
8 %************************************************************************
10 One thing which happens {\em a lot} is the instantiation of a type scheme
11 caused by the occurrence of a variable. It is so important that it
12 is written below in a very ``open-code'' fashion. All the modular monadery
13 is discarded, and we work directly in terms of the underlying representations.
14 In particular, this function knows about
17 - the representation of UniTypes
20 #include "HsVersions.h"
22 module Spec ( specId, specTy ) where
25 import TcMonadFns ( copyTyVars, newDicts )
28 import AbsUniType {- ( instantiateTauTy, instantiateThetaTy,
29 cloneTyVarFromTemplate, splitType
30 ) -} -- pragmas want to see it all!
31 import Id ( getIdUniType, mkInstId, DictVar(..) )
32 import Inst -- ( mkMethod, InstOrigin(..), Inst, InstTemplate, SpecInfo )
34 import Subst ( getSubstTyVarUnique )
35 import UniType -- known **GRIEVOUS** violation of UniType abstractness!!!
41 %************************************************************************
43 \subsection[Spec-specId]{Instantiating an Id}
45 %************************************************************************
47 @specId@ takes an @Id@ and implements the SPEC and REL rules
49 - the id applied to suitable types and dictionaries
51 - its instantiated tau type
53 For efficiency, it knows about the TcM implementation.
56 specId :: Id -> NF_TcM (TypecheckedExpr, LIE, TauType)
58 specId id sw_chkr dtys subst uniq errs src_loc
59 = case (spec_sigma subst uniq src_loc id (getIdUniType id)) of
60 (result, subst2) -> (result, subst2, errs)
64 spec_sigma :: Subst -- TyVar unique supply inside *here*
65 -> SplitUniqSupply -- "normal" unique supply
69 -> ((TypecheckedExpr, LIE, TauType), Subst)
71 spec_sigma subst uniq src_loc id (UniSyn _ _ ty)
72 = spec_sigma subst uniq src_loc id ty
74 spec_sigma subst uniq src_loc id ty@(UniForall _ _)
75 = collect [] [] subst ty
77 collect tenv tyvar_tys subst (UniForall tyvar ty)
78 = case (getSubstTyVarUnique subst) of
80 collect ((tyvar, new_tyvar_ty) : tenv)
81 (new_tyvar_ty : tyvar_tys)
84 new_tyvar_ty = UniTyVar (cloneTyVarFromTemplate tyvar u)
86 collect tenv tyvar_tys subst ty
87 = spec_rho tenv (reverse tyvar_tys) subst uniq src_loc id ty
89 spec_sigma subst uniq src_loc id tau_ty
90 -- Not polymorphic => cannot be overloaded
91 = ((Var id, nullLIE, tau_ty), subst)
95 spec_rho :: [(TyVarTemplate, UniType)] -> [UniType]
96 -> Subst -> SplitUniqSupply -> SrcLoc
98 -> ((TypecheckedExpr, LIE, TauType), Subst)
100 spec_rho tenv tys subst uniqs src_loc id (UniSyn _ _ ty)
101 = spec_rho tenv tys subst uniqs src_loc id ty
103 spec_rho tenv tys subst uniqs src_loc id (UniFun (UniDict _ _) ty)
104 = ((Var inst_id, unitLIE method, instantiateTauTy tenv tau_ty),
107 method = mkMethod u id tys (OccurrenceOf id src_loc)
108 inst_id = mkInstId method
110 tau_ty = discard_dicts ty
112 discard_dicts (UniFun (UniDict _ _) ty) = discard_dicts ty
113 discard_dicts other_ty = other_ty
115 spec_rho tenv tys subst uniqs src_loc id tau_ty
116 = ((TyApp (Var id) tys, nullLIE, instantiateTauTy tenv tau_ty),
121 %************************************************************************
123 \subsection[Spec-specTy]{Instantiating a type}
125 %************************************************************************
127 @specTy@ takes a polymorphic type, and instantiates it with fresh type
128 variables. It strips off the context part, gets fresh dictionary
129 variables for each predicate in the context. It returns
131 - a list of the dictionary variables (remember they contain
133 - an instantiated tau-type
135 The returned values are fixed points of the current substitution
136 though the arguments may not be.
139 specTy :: InstOrigin -> SigmaType -> NF_TcM ([TyVar], [Inst], TauType)
141 specTy origin sigma_ty
143 (old_tyvars, theta, tau_ty) = splitType sigma_ty
145 -- make new tyvars for each of the universally quantified type vars
146 copyTyVars old_tyvars `thenNF_Tc` \ (inst_env, new_tyvars, _) ->
148 -- instantiate the tau type
150 tau_ty' = instantiateTauTy inst_env tau_ty
152 -- instantiate the dictionary types
153 newDicts origin (instantiateThetaTy inst_env theta) `thenNF_Tc` \ dicts ->
155 -- return the list of tyvars, the list of dicts and the tau type
156 returnNF_Tc ( new_tyvars, dicts, tau_ty' )