-argToPat :: ConstrEnv -> UniqSupply -> CoreArg -> (UniqSupply, CoreExpr)
-argToPat env us (Type ty)
- = (us, Type ty)
-
-argToPat env us arg
- | Just (CV dc args) <- is_con_app_maybe env arg
- = let
- (us',args') = argsToPats env us args
- in
- (us', mk_con_app dc args')
-
-argToPat env us (Var v) -- Don't uniqify existing vars,
- = (us, Var v) -- so that we can spot when we pass them twice
-
-argToPat env us arg
- = (us1, Var (mkSysLocal FSLIT("sc") (uniqFromSupply us2) (exprType arg)))
+argToPat :: InScopeEnv -- What's in scope at the fn defn site
+ -> ConstrEnv -- ConstrEnv at the call site
+ -> CoreArg -- A call arg (or component thereof)
+ -> ArgOcc
+ -> UniqSM (Bool, CoreArg)
+-- Returns (interesting, pat),
+-- where pat is the pattern derived from the argument
+-- intersting=True if the pattern is non-trivial (not a variable or type)
+-- E.g. x:xs --> (True, x:xs)
+-- f xs --> (False, w) where w is a fresh wildcard
+-- (f xs, 'c') --> (True, (w, 'c')) where w is a fresh wildcard
+-- \x. x+y --> (True, \x. x+y)
+-- lvl7 --> (True, lvl7) if lvl7 is bound
+-- somewhere further out
+
+argToPat in_scope con_env arg@(Type ty) arg_occ
+ = return (False, arg)
+
+argToPat in_scope con_env (Var v) arg_occ
+ | not (isLocalId v) || v `elemVarEnv` in_scope
+ = -- The recursive call passes a variable that
+ -- is in scope at the function definition site
+ -- It's worth specialising on this if
+ -- (a) it's used in an interesting way in the body
+ -- (b) we know what its value is
+ if (case arg_occ of { UnkOcc -> False; other -> True }) -- (a)
+ && isValueUnfolding (idUnfolding v) -- (b)
+ then return (True, Var v)
+ else wildCardPat (idType v)
+
+argToPat in_scope con_env arg arg_occ
+ | is_value_lam arg
+ = return (True, arg)