2 % (c) The GRASP/AQUA Project, Glasgow University, 1998
4 \section[UsageSPInf]{UsageSP Inference Engine}
6 This code is (based on) PhD work of Keith Wansbrough <kw217@cl.cam.ac.uk>,
7 September 1998 .. May 1999.
9 Keith Wansbrough 1998-09-04..1999-07-06
12 module UsageSPInf ( doUsageSPInf ) where
14 #include "HsVersions.h"
21 import CoreFVs ( mustHaveLocalBinding )
22 import Rules ( RuleBase )
23 import TypeRep ( Type(..), TyNote(..) ) -- friend
24 import Type ( UsageAnn(..),
26 splitFunTy_maybe, splitFunTys, splitTyConApp_maybe,
27 mkUsgTy, splitUsgTy, isUsgTy, isNotUsgTy, unUsgTy, tyUsg,
28 splitUsForAllTys, substUsTy,
30 import TyCon ( tyConArgVrcs_maybe, isFunTyCon )
31 import Literal ( Literal(..), literalType )
32 import Var ( Var, UVar, varType, setVarType, mkUVar, modifyIdInfo )
33 import IdInfo ( setLBVarInfo, LBVarInfo(..) )
34 import Id ( isExportedId )
37 import UniqSupply ( UniqSupply, UniqSM,
38 initUs, splitUniqSupply )
40 import Maybes ( expectJust )
41 import List ( unzip4 )
42 import CmdLineOpts ( DynFlags, DynFlag(..), dopt, opt_UsageSPOn )
43 import CoreLint ( beginPass, endPass )
44 import ErrUtils ( doIfSet_dyn, dumpIfSet_dyn )
45 import PprCore ( pprCoreBindings )
48 ======================================================================
50 -- **! wasn't I going to do something about not requiring annotations
51 -- to be correct on unpointed types and/or those without haskell pointers
57 For full details, see _Once Upon a Polymorphic Type_, University of
58 Glasgow Department of Computing Science Technical Report TR-1998-19,
59 December 1998, or the summary in POPL'99.
61 [** NEW VERSION NOW IMPLEMENTED; different from the papers
62 above. Hopefully to appear in PLDI'00, and Keith Wansbrough's
63 University of Cambridge PhD thesis, c. Sep 2000 **]
66 Inference is performed as follows:
68 1. Remove all manipulable[*] annotations.
70 2. Walk over the resulting term adding fresh UVar annotations,
71 applying the type rules and collecting the constraints.
73 3. Find the solution to the constraints and apply the substitution
74 to the annotations, leaving a @UVar@-free term.
76 [*] A manipulable annotation is one derived from the current source
77 module, as opposed to one derived from an import, which we are clearly
80 As in the paper, a ``tau-type'' is a type that does *not* have an
81 annotation on top (although it may have some inside), and a
82 ``sigma-type'' is one that does (i.e., is a tau-type with an
83 annotation added). Also, a ``rho-type'' is one that may have initial
84 ``\/u.''s. This conflicts with the totally unrelated usage of these
85 terms in the remainder of GHC. Caveat lector! KSW 1999-07.
88 The inference is done over a set of @CoreBind@s, and inside the IO
92 doUsageSPInf :: DynFlags
97 doUsageSPInf dflags us binds
99 = do { printErrs (text "WARNING: ignoring requested -fusagesp pass; requires -fusagesp-on") ;
105 let binds1 = doUnAnnotBinds binds
107 beginPass dflags "UsageSPInf"
109 dumpIfSet_dyn dflags Opt_D_dump_usagesp "UsageSPInf unannot'd" $
110 pprCoreBindings binds1
112 let ((binds2,ucs,_),_) = initUs us (uniqSMMToUs (usgInfBinds emptyVarEnv binds1))
114 dumpIfSet_dyn dflags Opt_D_dump_usagesp "UsageSPInf annot'd" $
115 pprCoreBindings binds2
117 let ms = solveUCS ucs
120 Nothing -> panic "doUsageSPInf: insol. conset!"
121 binds3 = appUSubstBinds s binds2
123 doIfSet_dyn dflags Opt_DoUSPLinting $
124 do doLintUSPAnnotsBinds binds3 -- lint check 1
125 doLintUSPConstBinds binds3 -- lint check 2 (force solution)
126 doCheckIfWorseUSP binds binds3 -- check for worsening of usages
128 endPass dflags "UsageSPInf" (dopt Opt_D_dump_usagesp dflags) binds3
133 ======================================================================
135 Inferring an expression
136 ~~~~~~~~~~~~~~~~~~~~~~~
138 Inference takes an annotated (rho-typed) environment and an expression
139 unannotated except for variables not appearing in the environment. It
140 returns an annotated expression, a type, a constraint set, and a
141 multiset of free variables. It is in the unique supply monad, which
142 supplies fresh uvars for annotation.
144 We conflate usage metavariables and usage variables; the latter are
145 distinguished by falling within the scope of a usage binder.
148 usgInfBinds :: VarEnv Var -- incoming environment (usu. empty)
149 -> [CoreBind] -- CoreBinds in dependency order
150 -> UniqSMM ([CoreBind], -- annotated CoreBinds
151 UConSet, -- constraint set
152 VarMultiset) -- usage of environment vars
159 usgInfBinds ve (b0:b0s)
160 -- (this clause is almost the same as the Let clause)
161 = do (v1s,ve1,b1,h1,fb1,fa1) <- usgInfBind ve b0
162 (b2s,h2,f2) <- usgInfBinds ve1 b0s
163 let h3 = occChksUConSet v1s (fb1 `plusMS` f2)
165 unionUCSs [h1,h2,h3],
166 fa1 `plusMS` (f2 `delsFromMS` v1s))
169 usgInfBind :: VarEnv Var
170 -> CoreBind -- CoreBind to infer for
171 -> UniqSMM ([Var], -- variables bound
172 VarEnv Var, -- extended VarEnv
173 CoreBind, -- annotated CoreBind
174 UConSet, -- constraints generated by this CoreBind
175 VarMultiset, -- this bd's use of vars bound in this bd
176 -- (could be anything for other vars)
177 VarMultiset) -- this bd's use of other vars
179 usgInfBind ve (NonRec v1 e1)
180 = do (v1',y1u) <- annotVar v1
181 (e2,y2u,h2,f2) <- usgInfCE (extendVarEnv ve v1 v1') e1
182 let h3 = usgSubTy y2u y1u
183 h4 = h2 `unionUCS` h3
184 (y4r,h4') = usgClos ve y2u h4
185 v1'' = setVarType v1 y4r
186 h5 = if isExportedId v1 then pessimise y4r else emptyUConSet
188 extendVarEnv ve v1 v1'',
194 usgInfBind ve (Rec ves)
195 = do let (v1s,e1s) = unzip ves
196 vy1s' <- mapM annotVar v1s
197 let (v1s',y1us) = unzip vy1s'
198 ve' = ve `plusVarEnv` (zipVarEnv v1s v1s')
199 eyhf2s <- mapM (usgInfCE ve') e1s
200 let (e2s,y2us,h2s,f2s) = unzip4 eyhf2s
201 h3s = zipWith usgSubTy y2us y1us
202 h4s = zipWith unionUCS h2s h3s
203 yh4s = zipWith (usgClos ve) y2us h4s
204 (y4rs,h4s') = unzip yh4s
205 v1s'' = zipWith setVarType v1s y4rs
206 f5 = foldl plusMS emptyMS f2s
207 h6s = zipWith (\ v y -> if isExportedId v then pessimise y else emptyUConSet)
210 ve `plusVarEnv` (zipVarEnv v1s v1s''),
212 unionUCSs (h4s' ++ h6s),
214 f5 `delsFromMS` v1s') -- we take pains that v1'==v1'' etc
217 usgInfCE :: VarEnv Var -- unannotated -> annotated vars
218 -> CoreExpr -- expression to annotate / infer
219 -> UniqSMM (CoreExpr, -- annotated expression (e)
220 Type, -- (sigma) type of expression (y)(u=sigma)(r=rho)
221 UConSet, -- set of constraints arising (h)
222 VarMultiset) -- variable occurrences (f)
224 usgInfCE ve e0@(Var v) | isTyVar v
225 = panic "usgInfCE: unexpected TyVar"
227 = do v' <- instVar (lookupVar ve v)
228 return $ ASSERT( isUsgTy (varType v' {-'cpp-}) )
234 usgInfCE ve e0@(Lit lit)
235 = do u1 <- newVarUSMM (Left e0)
237 mkUsgTy u1 (literalType lit),
241 {- ------------------------------------
242 No Con form now; we rely on usage information in the constructor itself
244 usgInfCE ve e0@(Con con args)
245 = -- constant or primop. guaranteed saturated.
246 do let (ey1s,e1s) = span isTypeArg args
247 y1s <- mapM (\ (Type ty) -> annotTyN (Left e0) ty) ey1s -- univ. + exist.
248 (y2us,y2u) <- case con of
249 DataCon c -> do u2 <- newVarUSMM (Left e0)
250 return $ dataConTys c u2 y1s
251 -- y1s is exdicts + args
252 PrimOp p -> return $ primOpUsgTys p y1s
253 otherwise -> panic "usgInfCE: unrecognised Con"
254 eyhf3s <- mapM (usgInfCE ve) e1s
255 let (e3s,y3us,h3s,f3s) = unzip4 eyhf3s
256 h4s = zipWith usgSubTy y3us y2us
257 return $ ASSERT( isUsgTy y2u )
258 (Con con (map Type y1s ++ e3s),
260 unionUCSs (h3s ++ h4s),
261 foldl plusMS emptyMS f3s)
263 whered ataConTys c u y1s
264 -- compute argtys of a datacon
265 = let cTy = annotMany (dataConType c) -- extra (sigma) annots later replaced
266 (y2us,y2u) = splitFunTys (applyTys cTy y1s)
267 -- safe 'cos a DataCon always returns a value of type (TyCon tys),
268 -- not an arrow type.
269 reUsg = mkUsgTy u . unUsgTy
270 in (map reUsg y2us, reUsg y2u)
271 -------------------------------------------- -}
274 usgInfCE ve e0@(App ea (Type yb))
275 = do (ea1,ya1u,ha1,fa1) <- usgInfCE ve ea
276 let (u1,ya1) = splitUsgTy ya1u
277 yb1 <- annotTyN (Left e0) yb
278 return (App ea1 (Type yb1),
279 mkUsgTy u1 (applyTy ya1 yb1),
283 usgInfCE ve (App ea eb)
284 = do (ea1,ya1u,ha1,fa1) <- usgInfCE ve ea
285 let ( u1,ya1) = splitUsgTy ya1u
286 (y2u,y3u) = expectJust "usgInfCE:App" $ splitFunTy_maybe ya1
287 (eb1,yb1u,hb1,fb1) <- usgInfCE ve eb
288 let h4 = usgSubTy yb1u y2u
289 return $ ASSERT( isUsgTy y3u )
292 unionUCSs [ha1,hb1,h4],
295 usgInfCE ve e0@(Lam v0 e) | isTyVar v0
296 = do (e1,y1u,h1,f1) <- usgInfCE ve e
297 let (u1,y1) = splitUsgTy y1u
299 mkUsgTy u1 (mkForAllTy v0 y1),
304 -- if used for checking also, may need to extend this case to
305 -- look in lbvarInfo instead.
307 = do u1 <- newVarUSMM (Left e0)
308 (v1,y1u) <- annotVar v0
309 (e2,y2u,h2,f2) <- usgInfCE (extendVarEnv ve v0 v1) e
310 let h3 = occChkUConSet v1 f2
311 f2' = f2 `delFromMS` v1
312 h4s = foldMS (\ v _ hs -> (leqUConSet u1 ((tyUsg . varType . lookupVar ve) v)
313 : hs)) -- in reverse order!
316 return (Note (TermUsg u1) (Lam v1 e2), -- add annot for lbVarInfo computation
317 mkUsgTy u1 (mkFunTy y1u y2u),
318 unionUCSs (h2:h3:h4s),
321 usgInfCE ve (Let b0s e0)
322 = do (v1s,ve1,b1s,h1,fb1,fa1) <- usgInfBind ve b0s
323 (e2,y2u,h2,f2) <- usgInfCE ve1 e0
324 let h3 = occChksUConSet v1s (fb1 `plusMS` f2)
325 return $ ASSERT( isUsgTy y2u )
328 unionUCSs [h1,h2,h3],
329 fa1 `plusMS` (f2 `delsFromMS` v1s))
331 usgInfCE ve (Case e0 v0 [(DEFAULT,[],e1)])
332 -- pure strict let, no selection (could be at polymorphic or function type)
333 = do (v1,y1u) <- annotVar v0
334 (e2,y2u,h2,f2) <- usgInfCE ve e0
335 (e3,y3u,h3,f3) <- usgInfCE (extendVarEnv ve v0 v1) e1
336 let h4 = usgEqTy y2u y1u -- **! why not subty?
337 h5 = occChkUConSet v1 f3
338 return $ ASSERT( isUsgTy y3u )
339 (Case e2 v1 [(DEFAULT,[],e3)],
341 unionUCSs [h2,h3,h4,h5],
342 f2 `plusMS` (f3 `delFromMS` v1))
344 usgInfCE ve e0@(Case e1 v1 alts)
345 -- general case (tycon of scrutinee must be known)
346 -- (assumes well-typed already; so doesn't check constructor)
347 = do (v2,y1u) <- annotVar v1
348 (e2,y2u,h2,f2) <- usgInfCE ve e1
349 let h3 = usgEqTy y2u y1u -- **! why not subty?
350 (u2,y2) = splitUsgTy y2u
351 (tc,y2s) = expectJust "usgInfCE:Case" $ splitTyConApp_maybe y2
352 (cs,v1ss,es) = unzip3 alts
353 v2ss = map (map (\ v -> setVarType v (mkUsgTy u2 (annotManyN (varType v)))))
355 ve3 = extendVarEnv ve v1 v2
356 eyhf4s <- mapM (\ (v1s,v2s,e) -> usgInfCE (ve3 `plusVarEnv` (zipVarEnv v1s v2s)) e)
358 let (e4s,y4us,h4s,f4s) = unzip4 eyhf4s
359 y5u <- annotTy (Left e0) (unannotTy (head y4us))
360 let h5s = zipWith usgSubTy y4us (repeat y5u)
361 h6s = zipWith occChksUConSet v2ss f4s
362 f4 = foldl1 maxMS (zipWith delsFromMS f4s v2ss)
363 h7 = occChkUConSet v2 (f4 `plusMS` (unitMS v2))
364 return $ ASSERT( isUsgTy y5u )
365 (Case e2 v2 (zip3 cs v2ss e4s),
367 unionUCSs (h2:h3:h7:(h4s ++ h5s ++ h6s)),
368 f2 `plusMS` (f4 `delFromMS` v2))
370 usgInfCE ve e0@(Note note ea)
371 = do (e1,y1u,h1,f1) <- usgInfCE ve ea
373 Coerce yb ya -> do let (u1,y1) = splitUsgTy y1u
374 ya3 = annotManyN ya -- really nasty type
375 h3 = usgEqTy y1 ya3 -- messy but OK
376 yb3 <- annotTyN (Left e0) yb
377 -- What this says is that a Coerce does the most general possible
378 -- annotation to what's inside it (nasty, nasty), because no information
379 -- can pass through a Coerce. It of course simply ignores the info
380 -- that filters down through into ty1, because it can do nothing with it.
381 -- It does still pass through the topmost usage annotation, though.
382 return (Note (Coerce yb3 ya3) e1,
387 SCC _ -> return (Note note e1, y1u, h1, f1)
389 InlineCall -> return (Note note e1, y1u, h1, f1)
391 InlineMe -> return (Note note e1, y1u, h1, f1)
393 TermUsg _ -> pprPanic "usgInfCE:Note TermUsg" $ ppr e0
395 usgInfCE ve e0@(Type _)
396 = pprPanic "usgInfCE:Type" $ ppr e0
401 lookupVar :: VarEnv Var -> Var -> Var
402 -- if variable in VarEnv then return annotated version,
403 -- otherwise it's imported and already annotated so leave alone.
404 --lookupVar ve v = error "lookupVar unimplemented"
405 lookupVar ve v = case lookupVarEnv ve v of
407 Nothing -> ASSERT( not (mustHaveLocalBinding v) )
408 ASSERT( isUsgTy (varType v) )
411 instVar :: Var -> UniqSMM Var
412 -- instantiate variable with rho-type, giving it a fresh sigma-type
413 instVar v = do let (uvs,ty) = splitUsForAllTys (varType v)
416 _ -> do uvs' <- mapM (\_ -> newVarUSMM (Left (Var v))) uvs
417 let ty' = substUsTy (zipVarEnv uvs uvs') ty
418 return (setVarType v ty')
420 annotVar :: Var -> UniqSMM (Var,Type)
421 -- freshly annotates a variable and returns it along with its new type
422 annotVar v = do y1u <- annotTy (Left (Var v)) (varType v)
423 return (setVarType v y1u, y1u)
427 The closure operation, which does the generalisation at let bindings.
430 usgClos :: VarEnv Var -- environment to close with respect to
431 -> Type -- type to close (sigma)
432 -> UConSet -- constraint set to reduce
433 -> (Type, -- closed type (rho)
434 UConSet) -- residual constraint set
436 usgClos zz_ve ty ucs = (ty,ucs) -- dummy definition; no generalisation at all
438 -- hmm! what if it sets some uvars to 1 or omega?
439 -- (should it do substitution here, or return a substitution,
440 -- or should it leave all that work to the end and just use
441 -- an "=" constraint here for now?)
444 The pessimise operation, which generates constraints to pessimise an
445 id (applied to exported ids, to ensure that they have fully general
446 types, since we don't know how they will be used in other modules).
449 pessimise :: Type -> UConSet
452 = pess True emptyVarEnv ty
455 pess :: Bool -> UVarSet -> Type -> UConSet
456 pess co ve (NoteTy (UsgForAll uv) ty)
457 = pess co (ve `extendVarSet` uv) ty
458 pess co ve ty0@(NoteTy (UsgNote u) ty)
459 = pessN co ve ty `unionUCS`
461 (False,_ ) -> emptyUConSet
462 (True ,UsMany ) -> emptyUConSet
463 (True ,UsOnce ) -> pprPanic "pessimise: can't force:" (ppr ty0)
464 (True ,UsVar uv) -> if uv `elemVarSet` ve
465 then emptyUConSet -- if bound by \/u, no need to pessimise
466 else eqManyUConSet u)
468 = pprPanic "pessimise: missing annot:" (ppr ty0)
470 pessN :: Bool -> UVarSet -> Type -> UConSet
471 pessN co ve (NoteTy (UsgForAll uv) ty) = pessN co (ve `extendVarSet` uv) ty
472 pessN co ve ty0@(NoteTy (UsgNote _) _ ) = pprPanic "pessimise: unexpected annot:" (ppr ty0)
473 pessN co ve (NoteTy (SynNote sty) ty) = pessN co ve sty `unionUCS` pessN co ve ty
474 pessN co ve (NoteTy (FTVNote _) ty) = pessN co ve ty
475 pessN co ve (TyVarTy _) = emptyUConSet
476 pessN co ve (AppTy _ _) = emptyUConSet
477 pessN co ve (TyConApp tc tys) = ASSERT( not((isFunTyCon tc)&&(length tys > 1)) )
479 pessN co ve (FunTy ty1 ty2) = pess (not co) ve ty1 `unionUCS` pess co ve ty2
480 pessN co ve (ForAllTy _ ty) = pessN co ve ty
485 ======================================================================
490 If a variable appears more than once in an fv set, force its usage to be Many.
497 occChkUConSet v fv = if occInMS v fv > 1
498 then ASSERT2( isUsgTy (varType v), ppr v )
499 eqManyUConSet ((tyUsg . varType) v)
502 occChksUConSet :: [Var]
506 occChksUConSet vs fv = unionUCSs (map (\v -> occChkUConSet v fv) vs)
510 Subtyping and equal-typing relations. These generate constraint sets.
511 Both assume their arguments are annotated correctly, and are either
512 both tau-types or both sigma-types (in fact, are both exactly the same
516 usgSubTy ty1 ty2 = genUsgCmpTy cmp ty1 ty2
517 where cmp u1 u2 = leqUConSet u2 u1
519 usgEqTy ty1 ty2 = genUsgCmpTy cmp ty1 ty2 -- **NB** doesn't equate tyconargs that
520 -- don't appear (see below)
521 where cmp u1 u2 = eqUConSet u1 u2
523 genUsgCmpTy :: (UsageAnn -> UsageAnn -> UConSet) -- constraint (u1 REL u2), respectively
528 genUsgCmpTy cmp (NoteTy (UsgNote u1) ty1) (NoteTy (UsgNote u2) ty2)
529 = cmp u1 u2 `unionUCS` genUsgCmpTy cmp ty1 ty2
532 -- deal with omitted == UsMany
533 genUsgCmpTy cmp (NoteTy (UsgNote u1) ty1) ty2
534 = cmp u1 UsMany `unionUCS` genUsgCmpTy cmp ty1 ty2
535 genUsgCmpTy cmp ty1 (NoteTy (UsgNote u2) ty2)
536 = cmp UsMany u2 `unionUCS` genUsgCmpTy cmp ty1 ty2
539 genUsgCmpTy cmp (NoteTy (SynNote sty1) ty1) (NoteTy (SynNote sty2) ty2)
540 = genUsgCmpTy cmp sty1 sty2 `unionUCS` genUsgCmpTy cmp ty1 ty2
541 -- **! is this right? or should I throw away synonyms, or sth else?
543 -- if SynNote only on one side, throw it out
544 genUsgCmpTy cmp (NoteTy (SynNote sty1) ty1) ty2
545 = genUsgCmpTy cmp ty1 ty2
546 genUsgCmpTy cmp ty1 (NoteTy (SynNote sty2) ty2)
547 = genUsgCmpTy cmp ty1 ty2
550 genUsgCmpTy cmp (NoteTy (FTVNote _) ty1) ty2
551 = genUsgCmpTy cmp ty1 ty2
552 genUsgCmpTy cmp ty1 (NoteTy (FTVNote _) ty2)
553 = genUsgCmpTy cmp ty1 ty2
555 genUsgCmpTy cmp (TyVarTy _) (TyVarTy _)
558 genUsgCmpTy cmp (AppTy tya1 tyb1) (AppTy tya2 tyb2)
559 = unionUCSs [genUsgCmpTy cmp tya1 tya2,
560 genUsgCmpTy cmp tyb1 tyb2, -- note, *both* ways for arg, since fun (prob) unknown
561 genUsgCmpTy cmp tyb2 tyb1]
563 genUsgCmpTy cmp (TyConApp tc1 ty1s) (TyConApp tc2 ty2s)
564 = case tyConArgVrcs_maybe tc1 of
565 Just oi -> unionUCSs (zipWith3 (\ ty1 ty2 (occPos,occNeg) ->
566 -- strictly this is wasteful (and possibly dangerous) for
567 -- usgEqTy, but I think it's OK. KSW 1999-04.
568 (if occPos then genUsgCmpTy cmp ty1 ty2 else emptyUConSet)
570 (if occNeg then genUsgCmpTy cmp ty2 ty1 else emptyUConSet))
572 Nothing -> panic ("genUsgCmpTy: variance info unavailable for " ++ showSDoc (ppr tc1))
574 genUsgCmpTy cmp (FunTy tya1 tyb1) (FunTy tya2 tyb2)
575 = genUsgCmpTy cmp tya2 tya1 `unionUCS` genUsgCmpTy cmp tyb1 tyb2 -- contravariance of arrow
577 genUsgCmpTy cmp (ForAllTy _ ty1) (ForAllTy _ ty2)
578 = genUsgCmpTy cmp ty1 ty2
580 genUsgCmpTy cmp ty1 ty2
581 = pprPanic "genUsgCmpTy: type shapes don't match" $
582 vcat [ppr ty1, ppr ty2]
586 Applying a substitution to all @UVar@s. This also moves @TermUsg@
587 notes on lambdas into the @lbvarInfo@ field of the binder. This
588 latter is a hack. KSW 1999-04.
591 appUSubstTy :: (UVar -> UsageAnn)
595 appUSubstTy s (NoteTy (UsgNote (UsVar uv)) ty)
596 = mkUsgTy (s uv) (appUSubstTy s ty)
597 appUSubstTy s (NoteTy note@(UsgNote _) ty) = NoteTy note (appUSubstTy s ty)
598 appUSubstTy s (NoteTy note@(SynNote _) ty) = NoteTy note (appUSubstTy s ty)
599 appUSubstTy s (NoteTy note@(FTVNote _) ty) = NoteTy note (appUSubstTy s ty)
600 appUSubstTy s ty@(TyVarTy _) = ty
601 appUSubstTy s (AppTy ty1 ty2) = AppTy (appUSubstTy s ty1) (appUSubstTy s ty2)
602 appUSubstTy s (TyConApp tc tys) = TyConApp tc (map (appUSubstTy s) tys)
603 appUSubstTy s (FunTy ty1 ty2) = FunTy (appUSubstTy s ty1) (appUSubstTy s ty2)
604 appUSubstTy s (ForAllTy tyv ty) = ForAllTy tyv (appUSubstTy s ty)
607 appUSubstBinds :: (UVar -> UsageAnn)
611 appUSubstBinds s binds = fst $ initAnnotM () $
612 genAnnotBinds mungeType mungeTerm binds
613 where mungeType _ ty = -- simply perform substitution
614 return (appUSubstTy s ty)
616 mungeTerm (Note (TermUsg (UsVar uv)) (Lam v e))
617 -- perform substitution *and* munge annot on lambda into IdInfo.lbvarInfo
618 = let lb = case (s uv) of { UsOnce -> IsOneShotLambda; UsMany -> NoLBVarInfo }
619 v' = modifyIdInfo (`setLBVarInfo` lb) v -- HACK ALERT!
620 -- see comment in IdInfo.lhs; this is because the info is easier to
621 -- access here, by agreement SLPJ/KSW 1999-04 (as a "short-term hack").
623 -- really should be: return (Note (TermUsg (s uv)) (Lam v e))
624 mungeTerm e@(Lam _ _) = return e
625 mungeTerm e = panic "appUSubstBinds: mungeTerm:" (ppr e)
629 A @VarMultiset@ is what it says: a set of variables with counts
630 attached to them. We build one out of a @VarEnv@.
633 type VarMultiset = VarEnv (Var,Int) -- I guess 536 870 911 occurrences is enough
635 emptyMS = emptyVarEnv
636 unitMS v = unitVarEnv v (v,1)
637 delFromMS = delVarEnv
638 delsFromMS = delVarEnvList
639 plusMS :: VarMultiset -> VarMultiset -> VarMultiset
640 plusMS = plusVarEnv_C (\ (v,n) (_,m) -> (v,n+m))
641 maxMS :: VarMultiset -> VarMultiset -> VarMultiset
642 maxMS = plusVarEnv_C (\ (v,n) (_,m) -> (v,max n m))
643 mapMS f = mapVarEnv (\ (v,n) -> f v n)
644 foldMS f = foldVarEnv (\ (v,n) a -> f v n a)
645 occInMS v ms = case lookupVarEnv ms v of
650 And a function used in debugging. It may give false positives with -DUSMANY turned off.
653 isUnAnnotated :: Type -> Bool
655 isUnAnnotated (NoteTy (UsgNote _ ) _ ) = False
656 isUnAnnotated (NoteTy (SynNote sty) ty) = isUnAnnotated sty && isUnAnnotated ty
657 isUnAnnotated (NoteTy (FTVNote _ ) ty) = isUnAnnotated ty
658 isUnAnnotated (TyVarTy _) = True
659 isUnAnnotated (AppTy ty1 ty2) = isUnAnnotated ty1 && isUnAnnotated ty2
660 isUnAnnotated (TyConApp tc tys) = all isUnAnnotated tys
661 isUnAnnotated (FunTy ty1 ty2) = isUnAnnotated ty1 && isUnAnnotated ty2
662 isUnAnnotated (ForAllTy tyv ty) = isUnAnnotated ty
665 ======================================================================