2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1995
4 \section[Specialise]{Stamping out overloading, and (optionally) polymorphism}
7 #include "HsVersions.h"
13 isUnboxedSpecialisation,
18 argTysMatchSpecTys_error,
22 Maybe(..), Pretty(..), UniType
26 import Bag ( Bag, isEmptyBag, bagToList )
27 import FiniteMap ( FiniteMap, emptyFM, addListToFM_C,
28 keysFM, lookupWithDefaultFM
30 import Id ( mkSameSpecCon, getIdUniType,
31 isDictFunId, isConstMethodId, Id )
38 %************************************************************************
40 \subsection[@specialiseTys@]{Determine specialising types}
42 %************************************************************************
44 @specialiseCallTys@ works out which type args don't need to be specialised on,
45 based on flags, the overloading constraint vector, and the types.
48 specialiseCallTys :: Bool -- Specialise on all type args
49 -> Bool -- Specialise on unboxed type args
50 -> Bool -- Specialise on overloaded type args
51 -> ConstraintVector -- Tells which type args are overloaded
52 -> [UniType] -- Type args
53 -> [Maybe UniType] -- Nothings replace non-specialised type args
55 specialiseCallTys True _ _ cvec tys
57 specialiseCallTys False spec_unboxed spec_overloading cvec tys
58 = zipWith spec_ty_other cvec tys
60 spec_ty_other c ty | (spec_unboxed && isUnboxedDataType ty)
61 || (spec_overloading && c)
66 type ConstraintVector = [Bool] -- True for constrained tyvar, false otherwise
68 mkConstraintVector :: [TyVarTemplate]
69 -> [(Class,TyVarTemplate)]
72 mkConstraintVector tyvars class_tyvar_pairs
73 = [tyvar `elem` constrained_tyvars | tyvar <- tyvars]
75 constrained_tyvars = map snd class_tyvar_pairs -- May contain dups
79 isUnboxedSpecialisation :: [Maybe UniType] -> Bool
80 isUnboxedSpecialisation tys
83 is_unboxed (Just ty) = isUnboxedDataType ty
84 is_unboxed Nothing = False
87 @specialiseConstrTys@ works out which type args don't need to be
88 specialised on. We only speciailise on unboxed types.
91 specialiseConstrTys :: [UniType]
94 specialiseConstrTys tys
95 = map maybe_unboxed_ty tys
97 maybe_unboxed_ty ty = case isUnboxedDataType ty of
103 mkSpecialisedCon :: Id -> [UniType] -> Id
104 mkSpecialisedCon con tys
106 then mkSameSpecCon spec_tys con
109 spec_tys = specialiseConstrTys tys
110 spec_reqd = maybeToBool (firstJust spec_tys)
113 @argTysMatchSpecTys@ checks if a list of argument types is consistent
114 with a list of specialising types. An error message is returned if not.
116 argTysMatchSpecTys_error :: [Maybe UniType]
119 argTysMatchSpecTys_error spec_tys arg_tys
120 = if match spec_tys arg_tys
122 else Just (ppSep [ppStr "Spec and Arg Types Inconsistent:",
123 ppStr "spectys=", ppSep [pprMaybeTy PprDebug ty | ty <- spec_tys],
124 ppStr "argtys=", ppSep [pprParendUniType PprDebug ty | ty <- arg_tys]])
126 match (Nothing:spec_tys) (arg:arg_tys)
127 = not (isUnboxedDataType arg) &&
128 match spec_tys arg_tys
129 match (Just spec:spec_tys) (arg:arg_tys)
130 = case (cmpUniType True{-properly-} spec arg) of
131 EQ_ -> match spec_tys arg_tys
137 @pprSpecErrs@ prints error and warning information
138 about imported specialisations which do not exist.
141 pprSpecErrs :: PprStyle
142 -> (Bag (Id,[Maybe UniType])) -- errors
143 -> (Bag (Id,[Maybe UniType])) -- warnings
144 -> (Bag (TyCon,[Maybe UniType])) -- errors
147 pprSpecErrs sty spec_errs spec_warn spec_tyerrs
148 | not any_errs && not any_warn
152 = ppAboves [if any_errs then ppAboves [
153 ppStr "SPECIALISATION ERRORS (Essential):",
154 ppAboves (map pp_module_errs use_modules),
159 if any_warn then ppAboves [
160 ppStr "SPECIALISATION MESSAGES (Desirable):",
161 ppAboves (map pp_module_warn use_modules),
168 any_errs = not (isEmptyBag spec_errs) || not (isEmptyBag spec_tyerrs)
169 any_warn = not (isEmptyBag spec_warn)
171 mk_module_fm errs_bag
172 = addListToFM_C (++) emptyFM errs_list
174 errs_list = map add_name (bagToList errs_bag)
176 add_name (id, tys) = (mod, [(name, id, tys)])
178 (mod,name) = getOrigName id
180 tyerrs_fm = mk_module_fm spec_tyerrs
181 errs_fm = mk_module_fm spec_errs
182 warn_fm = mk_module_fm spec_warn
184 module_names = concat [keysFM errs_fm, keysFM warn_fm, keysFM tyerrs_fm]
185 sorted_modules = map head (equivClasses _CMP_STRING_ module_names)
187 -- Ensure any dfun instance specialisations (module _NIL_) are printed last
188 -- ToDo: Print instance specialisations with the instance module
189 -- This requires the module which defined the instance to be known:
190 -- add_name could then extract the instance module for a dfun id
191 -- and pp_dfun made a special case of pp_err
192 use_modules = if (head sorted_modules == _NIL_)
193 then tail sorted_modules ++ [_NIL_]
197 pp_module_errs :: FAST_STRING -> Pretty
199 | have_errs && mod == _NIL_
200 -- A _NIL_ module string corresponds to internal Ids
201 -- The only ones for which call instances should arise are
202 -- dfuns which correspond to instance specialisations
203 = ASSERT (null mod_tyerrs)
205 ppStr "*** INSTANCES",
206 ppAboves (map (pp_dfun sty) mod_errs)
212 ppAboves (map (pp_err sty) mod_errs),
213 ppAboves (map (pp_tyerr sty) mod_tyerrs)
220 mod_tyerrs = lookupWithDefaultFM tyerrs_fm [] mod
221 mod_errs = lookupWithDefaultFM errs_fm [] mod
222 have_errs = not (null mod_tyerrs) || not (null mod_errs)
225 pp_module_warn :: FAST_STRING -> Pretty
227 | have_warn && mod == _NIL_
228 -- A _NIL_ module string corresponds to internal Ids
229 -- The only ones for which call instances should arise are
230 -- dfuns which correspond to instance specialisations
232 ppStr "*** INSTANCES",
233 ppAboves (map (pp_dfun sty) mod_warn)
239 ppAboves (map (pp_err sty) mod_warn)
246 mod_warn = lookupWithDefaultFM warn_fm [] mod
247 have_warn = not (null mod_warn)
251 = ppCat [ppStr "*** module", ppPStr mod, ppStr "***"]
254 pp_tyerr :: PprStyle -> (FAST_STRING, TyCon, [Maybe UniType]) -> Pretty
256 pp_tyerr sty (_, tycon, tys)
257 = ppCat [ppStr "{-# SPECIALIZE data",
258 pprNonOp sty tycon, ppCat (map (pprParendUniType sty) spec_tys),
261 tvs = getTyConTyVarTemplates tycon
262 (spec_args, tv_maybes) = unzip (map choose_ty (tvs `zip` tys))
263 spec_tys = map (mkForallTy (catMaybes tv_maybes)) spec_args
265 choose_ty (tv, Nothing) = (mkTyVarTemplateTy tv, Just tv)
266 choose_ty (tv, Just ty) = (ty, Nothing)
268 pp_err sty (_, id, tys)
269 = ppCat [ppStr "{-# SPECIALIZE",
270 pprNonOp sty id, ppStr "::",
271 pprUniType sty spec_ty,
274 spec_ty = specialiseTy (getIdUniType id) tys 100 -- HACK to drop all dicts!!!
276 pp_dfun sty (_, id, tys)
278 = ppCat [ppStr "{-# SPECIALIZE instance",
279 pprUniType sty spec_ty,
282 = pp_comment sty "OVERLOADED METHOD" id spec_ty
284 = pp_comment sty "HELP ..." id spec_ty
286 spec_ty = specialiseTy (getIdUniType id) tys 100 -- HACK to drop all dicts!!!
288 pp_comment sty msg id spec_ty
289 = ppCat [ppStr "{-", ppStr msg,
290 pprNonOp sty id, ppStr "::",
291 pprUniType sty spec_ty,