2 % (c) The AQUA Project, Glasgow University, 1994-1996
4 \section[StdIdInfo]{Standard unfoldings}
6 This module contains definitions for the IdInfo for things that
7 have a standard form, namely:
11 * method and superclass selectors
12 * primitive operations
15 #include "HsVersions.h"
26 import CoreUnfold ( mkUnfolding )
27 import TysWiredIn ( tupleCon )
28 import Id ( GenId, mkTemplateLocals, idType,
29 dataConStrictMarks, dataConFieldLabels, dataConArgTys,
30 recordSelectorFieldLabel, dataConSig,
32 isDataCon, isMethodSelId_maybe, isSuperDictSelId_maybe,
33 isRecordSelector, isPrimitiveId_maybe,
34 addIdUnfolding, addIdArity
36 import IdInfo ( ArityInfo, exactArity )
37 import Class ( GenClass, GenClassOp, classSig, classOpLocalType )
38 import TyCon ( isNewTyCon )
39 import FieldLabel ( FieldLabel )
40 import PrelVals ( pAT_ERROR_ID )
42 import PprStyle ( PprStyle(..) )
44 import Util ( assertPanic, pprTrace,
50 %************************************************************************
52 \subsection{Data constructors}
54 %************************************************************************
56 We're going to build a constructor that looks like:
58 data (Data a, C b) => T a b = T1 !a !Int b
61 \d1::Data a, d2::C b ->
62 \p q r -> case p of { p ->
64 Con T1 [a,b] [p,q,r]}}
68 * d2 is thrown away --- a context in a data decl is used to make sure
69 one *could* construct dictionaries at the site the constructor
70 is used, but the dictionary isn't actually used.
72 * We have to check that we can construct Data dictionaries for
73 the types a and Int. Once we've done that we can throw d1 away too.
75 * We use (case p of ...) to evaluate p, rather than "seq" because
76 all that matters is that the arguments are evaluated. "seq" is
77 very careful to preserve evaluation order, which we don't need
81 addStandardIdInfo :: Id -> Id
83 addStandardIdInfo con_id
86 = con_id `addIdUnfolding` unfolding
87 `addIdArity` exactArity (length locals)
89 unfolding = mkUnfolding True {- Always inline constructors -} con_rhs
91 (tyvars,theta,arg_tys,tycon) = dataConSig con_id
92 dict_tys = [mkDictTy clas ty | (clas,ty) <- theta]
93 n_dicts = length dict_tys
94 result_ty = applyTyCon tycon (mkTyVarTys tyvars)
96 locals = mkTemplateLocals (dict_tys ++ arg_tys)
97 data_args = drop n_dicts locals
98 (data_arg1:_) = data_args -- Used for newtype only
99 strict_marks = dataConStrictMarks con_id
100 strict_args = [arg | (arg,MarkedStrict) <- data_args `zip` strict_marks]
101 -- NB: we can't call mkTemplateLocals twice, because it
102 -- always starts from the same unique.
104 con_app | isNewTyCon tycon
105 = ASSERT( length arg_tys == 1)
106 Coerce (CoerceIn con_id) result_ty (Var data_arg1)
108 = Con con_id (map TyArg (mkTyVarTys tyvars) ++ map VarArg data_args)
110 con_rhs = mkTyLam tyvars $
112 foldr mk_case con_app strict_args
114 mk_case arg body | isUnboxedType (idType arg)
115 = body -- "!" on unboxed arg does nothing
117 = Case (Var arg) (AlgAlts [] (BindDefault arg body))
118 -- This case shadows "arg" but that's fine
122 %************************************************************************
124 \subsection{Record selectors}
126 %************************************************************************
128 We're going to build a record selector that looks like this:
130 data T a b c = T1 { ..., op :: a, ...}
131 | T2 { ..., op :: a, ...}
134 sel = /\ a b c -> \ d -> case d of
140 addStandardIdInfo sel_id
141 | isRecordSelector sel_id
142 = ASSERT( null theta )
143 sel_id `addIdUnfolding` unfolding
144 `addIdArity` exactArity 1
145 -- ToDo: consider adding further IdInfo
147 unfolding = mkUnfolding False {- Don't inline every selector -} sel_rhs
149 (tyvars, theta, tau) = splitSigmaTy (idType sel_id)
150 field_lbl = recordSelectorFieldLabel sel_id
151 (data_ty,rhs_ty) = expectJust "StdIdInfoRec" (getFunTy_maybe tau)
152 -- tau is of form (T a b c -> field-type)
153 (tycon, _, data_cons) = getAppDataTyCon data_ty
154 tyvar_tys = mkTyVarTys tyvars
156 [data_id] = mkTemplateLocals [data_ty]
157 sel_rhs = mkTyLam tyvars $
159 Case (Var data_id) (AlgAlts (catMaybes (map mk_maybe_alt data_cons))
160 (BindDefault data_id error_expr))
161 mk_maybe_alt data_con
162 = case maybe_the_arg_id of
164 Just the_arg_id -> Just (data_con, arg_ids, Var the_arg_id)
166 arg_ids = mkTemplateLocals (dataConArgTys data_con tyvar_tys)
167 -- The first one will shadow data_id, but who cares
168 field_lbls = dataConFieldLabels data_con
169 maybe_the_arg_id = assocMaybe (field_lbls `zip` arg_ids) field_lbl
171 error_expr = mkApp (Var pAT_ERROR_ID) [] [rhs_ty] [LitArg msg_lit]
172 full_msg = ppShow 80 (ppSep [ppStr "No match in record selector", ppr PprForUser sel_id])
173 msg_lit = NoRepStr (_PK_ full_msg)
177 %************************************************************************
179 \subsection{Super selectors}
181 %************************************************************************
184 addStandardIdInfo sel_id
185 | maybeToBool maybe_sc_sel_id
186 = sel_id `addIdUnfolding` unfolding
187 -- The always-inline thing means we don't need any other IdInfo
189 maybe_sc_sel_id = isSuperDictSelId_maybe sel_id
190 Just (cls, the_sc) = maybe_sc_sel_id
192 unfolding = mkUnfolding True {- Always inline selectors -} rhs
193 rhs = mk_dict_selector [tyvar] dict_id arg_ids the_arg_id
195 (tyvar, scs, ops) = classSig cls
196 tyvar_ty = mkTyVarTy tyvar
197 [dict_id] = mkTemplateLocals [mkDictTy cls tyvar_ty]
198 arg_ids = mkTemplateLocals ([mkDictTy sc tyvar_ty | sc <- scs] ++
199 map classOpLocalType ops)
200 the_arg_id = assoc "StdIdInfoSC" (scs `zip` arg_ids) the_sc
202 addStandardIdInfo sel_id
203 | maybeToBool maybe_meth_sel_id
204 = sel_id `addIdUnfolding` unfolding
205 -- The always-inline thing means we don't need any other IdInfo
207 maybe_meth_sel_id = isMethodSelId_maybe sel_id
208 Just (cls, the_op) = maybe_meth_sel_id
210 unfolding = mkUnfolding True {- Always inline selectors -} rhs
211 rhs = mk_dict_selector [tyvar] dict_id arg_ids the_arg_id
213 (tyvar, scs, ops) = classSig cls
215 tyvar_ty = mkTyVarTy tyvar
216 [dict_id] = mkTemplateLocals [mkDictTy cls tyvar_ty]
217 arg_ids = mkTemplateLocals ([mkDictTy sc tyvar_ty | sc <- scs] ++
218 map classOpLocalType ops)
220 the_arg_id = assoc "StdIdInfoMeth" (ops `zip` (drop n_scs arg_ids)) the_op
224 %************************************************************************
226 \subsection{Primitive operations
228 %************************************************************************
232 addStandardIdInfo prim_id
233 | maybeToBool maybe_prim_id
234 = prim_id `addIdUnfolding` unfolding
236 maybe_prim_id = isPrimitiveId_maybe prim_id
237 Just prim_op = maybe_prim_id
239 unfolding = mkUnfolding True {- Always inline PrimOps -} rhs
241 (tyvars, tau) = splitForAllTy (idType prim_id)
242 (arg_tys, _) = splitFunTy tau
244 args = mkTemplateLocals arg_tys
245 rhs = mkLam tyvars args $
247 ([TyArg (mkTyVarTy tv) | tv <- tyvars] ++
248 [VarArg v | v <- args])
252 %************************************************************************
254 \subsection{Catch-all}
256 %************************************************************************
260 = pprTrace "addStandardIdInfo missing:" (ppr PprDebug id) id
264 %************************************************************************
266 \subsection{Dictionary selector help function
268 %************************************************************************
270 Selecting a field for a dictionary. If there is just one field, then
271 there's nothing to do.
274 mk_dict_selector tyvars dict_id [arg_id] the_arg_id
275 = mkLam tyvars [dict_id] (Var dict_id)
277 mk_dict_selector tyvars dict_id arg_ids the_arg_id
278 = mkLam tyvars [dict_id] $
279 Case (Var dict_id) (AlgAlts [(tup_con, arg_ids, Var the_arg_id)] NoDefault)
281 tup_con = tupleCon (length arg_ids)