46a80491ea663b0abc45ee3dac724c642644d2cd
[ghc-hetmet.git] / compiler / deSugar / DsArrows.lhs
1 %
2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 %
5
6 Desugaring arrow commands
7
8 \begin{code}
9 {-# OPTIONS -w #-}
10 -- The above warning supression flag is a temporary kludge.
11 -- While working on this module you are encouraged to remove it and fix
12 -- any warnings in the module. See
13 --     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
14 -- for details
15
16 module DsArrows ( dsProcExpr ) where
17
18 #include "HsVersions.h"
19
20 import Match
21 import DsUtils
22 import DsMonad
23
24 import HsSyn    hiding (collectPatBinders, collectLocatedPatBinders, collectl,
25                         collectPatsBinders, collectLocatedPatsBinders)
26 import TcHsSyn
27
28 -- NB: The desugarer, which straddles the source and Core worlds, sometimes
29 --     needs to see source types (newtypes etc), and sometimes not
30 --     So WATCH OUT; check each use of split*Ty functions.
31 -- Sigh.  This is a pain.
32
33 import {-# SOURCE #-} DsExpr ( dsExpr, dsLExpr, dsLocalBinds )
34
35 import TcType
36 import Type
37 import CoreSyn
38 import CoreFVs
39 import CoreUtils
40
41 import Id
42 import Name
43 import PrelInfo
44 import DataCon
45 import TysWiredIn
46 import BasicTypes
47 import PrelNames
48 import Util
49
50 import VarSet
51 import SrcLoc
52
53 import Data.List
54 \end{code}
55
56 \begin{code}
57 data DsCmdEnv = DsCmdEnv {
58         meth_binds :: [CoreBind],
59         arr_id, compose_id, first_id, app_id, choice_id, loop_id :: CoreExpr
60     }
61
62 mkCmdEnv :: SyntaxTable Id -> DsM DsCmdEnv
63 mkCmdEnv ids = do
64     (meth_binds, ds_meths) <- dsSyntaxTable ids
65     return $ DsCmdEnv {
66                meth_binds = meth_binds,
67                arr_id     = Var (lookupEvidence ds_meths arrAName),
68                compose_id = Var (lookupEvidence ds_meths composeAName),
69                first_id   = Var (lookupEvidence ds_meths firstAName),
70                app_id     = Var (lookupEvidence ds_meths appAName),
71                choice_id  = Var (lookupEvidence ds_meths choiceAName),
72                loop_id    = Var (lookupEvidence ds_meths loopAName)
73              }
74
75 bindCmdEnv :: DsCmdEnv -> CoreExpr -> CoreExpr
76 bindCmdEnv ids body = foldr Let body (meth_binds ids)
77
78 -- arr :: forall b c. (b -> c) -> a b c
79 do_arr :: DsCmdEnv -> Type -> Type -> CoreExpr -> CoreExpr
80 do_arr ids b_ty c_ty f = mkApps (arr_id ids) [Type b_ty, Type c_ty, f]
81
82 -- (>>>) :: forall b c d. a b c -> a c d -> a b d
83 do_compose :: DsCmdEnv -> Type -> Type -> Type ->
84                 CoreExpr -> CoreExpr -> CoreExpr
85 do_compose ids b_ty c_ty d_ty f g
86   = mkApps (compose_id ids) [Type b_ty, Type c_ty, Type d_ty, f, g]
87
88 -- first :: forall b c d. a b c -> a (b,d) (c,d)
89 do_first :: DsCmdEnv -> Type -> Type -> Type -> CoreExpr -> CoreExpr
90 do_first ids b_ty c_ty d_ty f
91   = mkApps (first_id ids) [Type b_ty, Type c_ty, Type d_ty, f]
92
93 -- app :: forall b c. a (a b c, b) c
94 do_app :: DsCmdEnv -> Type -> Type -> CoreExpr
95 do_app ids b_ty c_ty = mkApps (app_id ids) [Type b_ty, Type c_ty]
96
97 -- (|||) :: forall b d c. a b d -> a c d -> a (Either b c) d
98 -- note the swapping of d and c
99 do_choice :: DsCmdEnv -> Type -> Type -> Type ->
100                 CoreExpr -> CoreExpr -> CoreExpr
101 do_choice ids b_ty c_ty d_ty f g
102   = mkApps (choice_id ids) [Type b_ty, Type d_ty, Type c_ty, f, g]
103
104 -- loop :: forall b d c. a (b,d) (c,d) -> a b c
105 -- note the swapping of d and c
106 do_loop :: DsCmdEnv -> Type -> Type -> Type -> CoreExpr -> CoreExpr
107 do_loop ids b_ty c_ty d_ty f
108   = mkApps (loop_id ids) [Type b_ty, Type d_ty, Type c_ty, f]
109
110 -- map_arrow (f :: b -> c) (g :: a c d) = arr f >>> g :: a b d
111 do_map_arrow :: DsCmdEnv -> Type -> Type -> Type ->
112                 CoreExpr -> CoreExpr -> CoreExpr
113 do_map_arrow ids b_ty c_ty d_ty f c
114    = do_compose ids b_ty c_ty d_ty (do_arr ids b_ty c_ty f) c
115
116 mkFailExpr :: HsMatchContext Id -> Type -> DsM CoreExpr
117 mkFailExpr ctxt ty
118   = mkErrorAppDs pAT_ERROR_ID ty (matchContextErrString ctxt)
119
120 -- construct CoreExpr for \ (a :: a_ty, b :: b_ty) -> b
121 mkSndExpr :: Type -> Type -> DsM CoreExpr
122 mkSndExpr a_ty b_ty = do
123     a_var <- newSysLocalDs a_ty
124     b_var <- newSysLocalDs b_ty
125     pair_var <- newSysLocalDs (mkCorePairTy a_ty b_ty)
126     return (Lam pair_var
127                (coreCasePair pair_var a_var b_var (Var b_var)))
128 \end{code}
129
130 Build case analysis of a tuple.  This cannot be done in the DsM monad,
131 because the list of variables is typically not yet defined.
132
133 \begin{code}
134 -- coreCaseTuple [u1..] v [x1..xn] body
135 --      = case v of v { (x1, .., xn) -> body }
136 -- But the matching may be nested if the tuple is very big
137
138 coreCaseTuple :: UniqSupply -> Id -> [Id] -> CoreExpr -> CoreExpr
139 coreCaseTuple uniqs scrut_var vars body
140   = mkTupleCase uniqs vars body scrut_var (Var scrut_var)
141
142 coreCasePair :: Id -> Id -> Id -> CoreExpr -> CoreExpr
143 coreCasePair scrut_var var1 var2 body
144   = Case (Var scrut_var) scrut_var (exprType body)
145          [(DataAlt (tupleCon Boxed 2), [var1, var2], body)]
146 \end{code}
147
148 \begin{code}
149 mkCorePairTy :: Type -> Type -> Type
150 mkCorePairTy t1 t2 = mkCoreTupTy [t1, t2]
151
152 mkCorePairExpr :: CoreExpr -> CoreExpr -> CoreExpr
153 mkCorePairExpr e1 e2 = mkCoreTup [e1, e2]
154 \end{code}
155
156 The input is divided into a local environment, which is a flat tuple
157 (unless it's too big), and a stack, each element of which is paired
158 with the stack in turn.  In general, the input has the form
159
160         (...((x1,...,xn),s1),...sk)
161
162 where xi are the environment values, and si the ones on the stack,
163 with s1 being the "top", the first one to be matched with a lambda.
164
165 \begin{code}
166 envStackType :: [Id] -> [Type] -> Type
167 envStackType ids stack_tys = foldl mkCorePairTy (mkBigCoreVarTupTy ids) stack_tys
168
169 ----------------------------------------------
170 --              buildEnvStack
171 --
172 --      (...((x1,...,xn),s1),...sk)
173
174 buildEnvStack :: [Id] -> [Id] -> CoreExpr
175 buildEnvStack env_ids stack_ids
176   = foldl mkCorePairExpr (mkBigCoreVarTup env_ids) (map Var stack_ids)
177
178 ----------------------------------------------
179 --              matchEnvStack
180 --
181 --      \ (...((x1,...,xn),s1),...sk) -> e
182 --      =>
183 --      \ zk ->
184 --      case zk of (zk-1,sk) ->
185 --      ...
186 --      case z1 of (z0,s1) ->
187 --      case z0 of (x1,...,xn) ->
188 --      e
189
190 matchEnvStack   :: [Id]         -- x1..xn
191                 -> [Id]         -- s1..sk
192                 -> CoreExpr     -- e
193                 -> DsM CoreExpr
194 matchEnvStack env_ids stack_ids body = do
195     uniqs <- newUniqueSupply
196     tup_var <- newSysLocalDs (mkBigCoreVarTupTy env_ids)
197     matchVarStack tup_var stack_ids
198                (coreCaseTuple uniqs tup_var env_ids body)
199
200
201 ----------------------------------------------
202 --              matchVarStack
203 --
204 --      \ (...(z0,s1),...sk) -> e
205 --      =>
206 --      \ zk ->
207 --      case zk of (zk-1,sk) ->
208 --      ...
209 --      case z1 of (z0,s1) ->
210 --      e
211
212 matchVarStack :: Id             -- z0
213               -> [Id]           -- s1..sk
214               -> CoreExpr       -- e
215               -> DsM CoreExpr
216 matchVarStack env_id [] body
217   = return (Lam env_id body)
218 matchVarStack env_id (stack_id:stack_ids) body = do
219     pair_id <- newSysLocalDs (mkCorePairTy (idType env_id) (idType stack_id))
220     matchVarStack pair_id stack_ids
221                (coreCasePair pair_id env_id stack_id body)
222 \end{code}
223
224 \begin{code}
225 mkHsTupleExpr :: [HsExpr Id] -> HsExpr Id
226 mkHsTupleExpr [e] = e
227 mkHsTupleExpr es = ExplicitTuple (map noLoc es) Boxed
228
229 mkHsPairExpr :: HsExpr Id -> HsExpr Id -> HsExpr Id
230 mkHsPairExpr e1 e2 = mkHsTupleExpr [e1, e2]
231
232 mkHsEnvStackExpr :: [Id] -> [Id] -> HsExpr Id
233 mkHsEnvStackExpr env_ids stack_ids
234   = foldl mkHsPairExpr (mkHsTupleExpr (map HsVar env_ids)) (map HsVar stack_ids)
235 \end{code}
236
237 Translation of arrow abstraction
238
239 \begin{code}
240
241 --      A | xs |- c :: [] t'        ---> c'
242 --      --------------------------
243 --      A |- proc p -> c :: a t t'  ---> arr (\ p -> (xs)) >>> c'
244 --
245 --              where (xs) is the tuple of variables bound by p
246
247 dsProcExpr
248         :: LPat Id
249         -> LHsCmdTop Id
250         -> DsM CoreExpr
251 dsProcExpr pat (L _ (HsCmdTop cmd [] cmd_ty ids)) = do
252     meth_ids <- mkCmdEnv ids
253     let locals = mkVarSet (collectPatBinders pat)
254     (core_cmd, free_vars, env_ids) <- dsfixCmd meth_ids locals [] cmd_ty cmd
255     let env_ty = mkBigCoreVarTupTy env_ids
256     fail_expr <- mkFailExpr ProcExpr env_ty
257     var <- selectSimpleMatchVarL pat
258     match_code <- matchSimply (Var var) ProcExpr pat (mkBigCoreVarTup env_ids) fail_expr
259     let pat_ty = hsLPatType pat
260         proc_code = do_map_arrow meth_ids pat_ty env_ty cmd_ty
261                     (Lam var match_code)
262                     core_cmd
263     return (bindCmdEnv meth_ids proc_code)
264 \end{code}
265
266 Translation of command judgements of the form
267
268         A | xs |- c :: [ts] t
269
270 \begin{code}
271 dsLCmd ids local_vars env_ids stack res_ty cmd
272   = dsCmd ids local_vars env_ids stack res_ty (unLoc cmd)
273
274 dsCmd   :: DsCmdEnv             -- arrow combinators
275         -> IdSet                -- set of local vars available to this command
276         -> [Id]                 -- list of vars in the input to this command
277                                 -- This is typically fed back,
278                                 -- so don't pull on it too early
279         -> [Type]               -- type of the stack
280         -> Type                 -- return type of the command
281         -> HsCmd Id             -- command to desugar
282         -> DsM (CoreExpr,       -- desugared expression
283                 IdSet)          -- set of local vars that occur free
284
285 --      A |- f :: a (t*ts) t'
286 --      A, xs |- arg :: t
287 --      -----------------------------
288 --      A | xs |- f -< arg :: [ts] t'
289 --
290 --              ---> arr (\ ((xs)*ts) -> (arg*ts)) >>> f
291
292 dsCmd ids local_vars env_ids stack res_ty
293         (HsArrApp arrow arg arrow_ty HsFirstOrderApp _)= do
294     let
295         (a_arg_ty, _res_ty') = tcSplitAppTy arrow_ty
296         (_a_ty, arg_ty) = tcSplitAppTy a_arg_ty
297         env_ty = mkBigCoreVarTupTy env_ids
298     core_arrow <- dsLExpr arrow
299     core_arg   <- dsLExpr arg
300     stack_ids  <- mapM newSysLocalDs stack
301     core_make_arg <- matchEnvStack env_ids stack_ids
302                       (foldl mkCorePairExpr core_arg (map Var stack_ids))
303     return (do_map_arrow ids
304               (envStackType env_ids stack)
305               arg_ty
306               res_ty
307               core_make_arg
308               core_arrow,
309                exprFreeVars core_arg `intersectVarSet` local_vars)
310
311 --      A, xs |- f :: a (t*ts) t'
312 --      A, xs |- arg :: t
313 --      ------------------------------
314 --      A | xs |- f -<< arg :: [ts] t'
315 --
316 --              ---> arr (\ ((xs)*ts) -> (f,(arg*ts))) >>> app
317
318 dsCmd ids local_vars env_ids stack res_ty
319         (HsArrApp arrow arg arrow_ty HsHigherOrderApp _) = do
320     let
321         (a_arg_ty, _res_ty') = tcSplitAppTy arrow_ty
322         (_a_ty, arg_ty) = tcSplitAppTy a_arg_ty
323         env_ty = mkBigCoreVarTupTy env_ids
324     
325     core_arrow <- dsLExpr arrow
326     core_arg   <- dsLExpr arg
327     stack_ids  <- mapM newSysLocalDs stack
328     core_make_pair <- matchEnvStack env_ids stack_ids
329           (mkCorePairExpr core_arrow
330              (foldl mkCorePairExpr core_arg (map Var stack_ids)))
331                              
332     return (do_map_arrow ids
333               (envStackType env_ids stack)
334               (mkCorePairTy arrow_ty arg_ty)
335               res_ty
336               core_make_pair
337               (do_app ids arg_ty res_ty),
338             (exprFreeVars core_arrow `unionVarSet` exprFreeVars core_arg)
339               `intersectVarSet` local_vars)
340
341 --      A | ys |- c :: [t:ts] t'
342 --      A, xs  |- e :: t
343 --      ------------------------
344 --      A | xs |- c e :: [ts] t'
345 --
346 --              ---> arr (\ ((xs)*ts) -> let z = e in (((ys),z)*ts)) >>> c
347
348 dsCmd ids local_vars env_ids stack res_ty (HsApp cmd arg) = do
349     core_arg <- dsLExpr arg
350     let
351         arg_ty = exprType core_arg
352         stack' = arg_ty:stack
353     (core_cmd, free_vars, env_ids')
354              <- dsfixCmd ids local_vars stack' res_ty cmd
355     stack_ids <- mapM newSysLocalDs stack
356     arg_id <- newSysLocalDs arg_ty
357     -- push the argument expression onto the stack
358     let
359         core_body = bindNonRec arg_id core_arg
360                         (buildEnvStack env_ids' (arg_id:stack_ids))
361     -- match the environment and stack against the input
362     core_map <- matchEnvStack env_ids stack_ids core_body
363     return (do_map_arrow ids
364                       (envStackType env_ids stack)
365                       (envStackType env_ids' stack')
366                       res_ty
367                       core_map
368                       core_cmd,
369       (exprFreeVars core_arg `intersectVarSet` local_vars)
370               `unionVarSet` free_vars)
371
372 --      A | ys |- c :: [ts] t'
373 --      -----------------------------------------------
374 --      A | xs |- \ p1 ... pk -> c :: [t1:...:tk:ts] t'
375 --
376 --              ---> arr (\ ((((xs), p1), ... pk)*ts) -> ((ys)*ts)) >>> c
377
378 dsCmd ids local_vars env_ids stack res_ty
379     (HsLam (MatchGroup [L _ (Match pats _ (GRHSs [L _ (GRHS [] body)] _ ))] _)) = do
380     let
381         pat_vars = mkVarSet (collectPatsBinders pats)
382         local_vars' = local_vars `unionVarSet` pat_vars
383         stack' = drop (length pats) stack
384     (core_body, free_vars, env_ids') <- dsfixCmd ids local_vars' stack' res_ty body
385     stack_ids <- mapM newSysLocalDs stack
386
387     -- the expression is built from the inside out, so the actions
388     -- are presented in reverse order
389
390     let
391         (actual_ids, stack_ids') = splitAt (length pats) stack_ids
392         -- build a new environment, plus what's left of the stack
393         core_expr = buildEnvStack env_ids' stack_ids'
394         in_ty = envStackType env_ids stack
395         in_ty' = envStackType env_ids' stack'
396     
397     fail_expr <- mkFailExpr LambdaExpr in_ty'
398     -- match the patterns against the top of the old stack
399     match_code <- matchSimplys (map Var actual_ids) LambdaExpr pats core_expr fail_expr
400     -- match the old environment and stack against the input
401     select_code <- matchEnvStack env_ids stack_ids match_code
402     return (do_map_arrow ids in_ty in_ty' res_ty select_code core_body,
403             free_vars `minusVarSet` pat_vars)
404
405 dsCmd ids local_vars env_ids stack res_ty (HsPar cmd)
406   = dsLCmd ids local_vars env_ids stack res_ty cmd
407
408 --      A, xs |- e :: Bool
409 --      A | xs1 |- c1 :: [ts] t
410 --      A | xs2 |- c2 :: [ts] t
411 --      ----------------------------------------
412 --      A | xs |- if e then c1 else c2 :: [ts] t
413 --
414 --              ---> arr (\ ((xs)*ts) ->
415 --                      if e then Left ((xs1)*ts) else Right ((xs2)*ts)) >>>
416 --                   c1 ||| c2
417
418 dsCmd ids local_vars env_ids stack res_ty (HsIf cond then_cmd else_cmd) = do
419     core_cond <- dsLExpr cond
420     (core_then, fvs_then, then_ids) <- dsfixCmd ids local_vars stack res_ty then_cmd
421     (core_else, fvs_else, else_ids) <- dsfixCmd ids local_vars stack res_ty else_cmd
422     stack_ids  <- mapM newSysLocalDs stack
423     either_con <- dsLookupTyCon eitherTyConName
424     left_con   <- dsLookupDataCon leftDataConName
425     right_con  <- dsLookupDataCon rightDataConName
426     let
427         left_expr ty1 ty2 e = mkConApp left_con [Type ty1, Type ty2, e]
428         right_expr ty1 ty2 e = mkConApp right_con [Type ty1, Type ty2, e]
429
430         in_ty = envStackType env_ids stack
431         then_ty = envStackType then_ids stack
432         else_ty = envStackType else_ids stack
433         sum_ty = mkTyConApp either_con [then_ty, else_ty]
434         fvs_cond = exprFreeVars core_cond `intersectVarSet` local_vars
435     
436     core_if <- matchEnvStack env_ids stack_ids
437                 (mkIfThenElse core_cond
438                     (left_expr  then_ty else_ty (buildEnvStack then_ids stack_ids))
439                     (right_expr then_ty else_ty (buildEnvStack else_ids stack_ids)))
440     return (do_map_arrow ids in_ty sum_ty res_ty
441                 core_if
442                 (do_choice ids then_ty else_ty res_ty core_then core_else),
443         fvs_cond `unionVarSet` fvs_then `unionVarSet` fvs_else)
444 \end{code}
445
446 Case commands are treated in much the same way as if commands
447 (see above) except that there are more alternatives.  For example
448
449         case e of { p1 -> c1; p2 -> c2; p3 -> c3 }
450
451 is translated to
452
453         arr (\ ((xs)*ts) -> case e of
454                 p1 -> (Left (Left (xs1)*ts))
455                 p2 -> Left ((Right (xs2)*ts))
456                 p3 -> Right ((xs3)*ts)) >>>
457         (c1 ||| c2) ||| c3
458
459 The idea is to extract the commands from the case, build a balanced tree
460 of choices, and replace the commands with expressions that build tagged
461 tuples, obtaining a case expression that can be desugared normally.
462 To build all this, we use quadruples decribing segments of the list of
463 case bodies, containing the following fields:
464 1. an IdSet containing the environment variables free in the case bodies
465 2. a list of expressions of the form (Left|Right)* ((xs)*ts), to be put
466    into the case replacing the commands
467 3. a sum type that is the common type of these expressions, and also the
468    input type of the arrow
469 4. a CoreExpr for an arrow built by combining the translated command
470    bodies with |||.
471
472 \begin{code}
473 dsCmd ids local_vars env_ids stack res_ty (HsCase exp (MatchGroup matches match_ty)) = do
474     core_exp <- dsLExpr exp
475     stack_ids <- mapM newSysLocalDs stack
476
477     -- Extract and desugar the leaf commands in the case, building tuple
478     -- expressions that will (after tagging) replace these leaves
479
480     let
481         leaves = concatMap leavesMatch matches
482         make_branch (leaf, bound_vars) = do
483             (core_leaf, fvs, leaf_ids) <-
484                   dsfixCmd ids (local_vars `unionVarSet` bound_vars) stack res_ty leaf
485             return (fvs `minusVarSet` bound_vars,
486                     [noLoc $ mkHsEnvStackExpr leaf_ids stack_ids],
487                     envStackType leaf_ids stack,
488                     core_leaf)
489     
490     branches <- mapM make_branch leaves
491     either_con <- dsLookupTyCon eitherTyConName
492     left_con <- dsLookupDataCon leftDataConName
493     right_con <- dsLookupDataCon rightDataConName
494     let
495         left_id  = HsVar (dataConWrapId left_con)
496         right_id = HsVar (dataConWrapId right_con)
497         left_expr  ty1 ty2 e = noLoc $ HsApp (noLoc $ HsWrap (mkWpTyApps [ty1, ty2]) left_id ) e
498         right_expr ty1 ty2 e = noLoc $ HsApp (noLoc $ HsWrap (mkWpTyApps [ty1, ty2]) right_id) e
499
500         -- Prefix each tuple with a distinct series of Left's and Right's,
501         -- in a balanced way, keeping track of the types.
502
503         merge_branches (fvs1, builds1, in_ty1, core_exp1)
504                        (fvs2, builds2, in_ty2, core_exp2) 
505           = (fvs1 `unionVarSet` fvs2,
506              map (left_expr in_ty1 in_ty2) builds1 ++
507                 map (right_expr in_ty1 in_ty2) builds2,
508              mkTyConApp either_con [in_ty1, in_ty2],
509              do_choice ids in_ty1 in_ty2 res_ty core_exp1 core_exp2)
510         (fvs_alts, leaves', sum_ty, core_choices)
511           = foldb merge_branches branches
512
513         -- Replace the commands in the case with these tagged tuples,
514         -- yielding a HsExpr Id we can feed to dsExpr.
515
516         (_, matches') = mapAccumL (replaceLeavesMatch res_ty) leaves' matches
517         in_ty = envStackType env_ids stack
518         fvs_exp = exprFreeVars core_exp `intersectVarSet` local_vars
519
520         pat_ty    = funArgTy match_ty
521         match_ty' = mkFunTy pat_ty sum_ty
522         -- Note that we replace the HsCase result type by sum_ty,
523         -- which is the type of matches'
524     
525     core_body <- dsExpr (HsCase exp (MatchGroup matches' match_ty'))
526     core_matches <- matchEnvStack env_ids stack_ids core_body
527     return (do_map_arrow ids in_ty sum_ty res_ty core_matches core_choices,
528             fvs_exp `unionVarSet` fvs_alts)
529
530 --      A | ys |- c :: [ts] t
531 --      ----------------------------------
532 --      A | xs |- let binds in c :: [ts] t
533 --
534 --              ---> arr (\ ((xs)*ts) -> let binds in ((ys)*ts)) >>> c
535
536 dsCmd ids local_vars env_ids stack res_ty (HsLet binds body) = do
537     let
538         defined_vars = mkVarSet (map unLoc (collectLocalBinders binds))
539         local_vars' = local_vars `unionVarSet` defined_vars
540     
541     (core_body, free_vars, env_ids') <- dsfixCmd ids local_vars' stack res_ty body
542     stack_ids <- mapM newSysLocalDs stack
543     -- build a new environment, plus the stack, using the let bindings
544     core_binds <- dsLocalBinds binds (buildEnvStack env_ids' stack_ids)
545     -- match the old environment and stack against the input
546     core_map <- matchEnvStack env_ids stack_ids core_binds
547     return (do_map_arrow ids
548                         (envStackType env_ids stack)
549                         (envStackType env_ids' stack)
550                         res_ty
551                         core_map
552                         core_body,
553         exprFreeVars core_binds `intersectVarSet` local_vars)
554
555 dsCmd ids local_vars env_ids [] res_ty (HsDo _ctxt stmts body _)
556   = dsCmdDo ids local_vars env_ids res_ty stmts body
557
558 --      A |- e :: forall e. a1 (e*ts1) t1 -> ... an (e*tsn) tn -> a (e*ts) t
559 --      A | xs |- ci :: [tsi] ti
560 --      -----------------------------------
561 --      A | xs |- (|e c1 ... cn|) :: [ts] t     ---> e [t_xs] c1 ... cn
562
563 dsCmd _ids local_vars env_ids _stack _res_ty (HsArrForm op _ args) = do
564     let env_ty = mkBigCoreVarTupTy env_ids
565     core_op <- dsLExpr op
566     (core_args, fv_sets) <- mapAndUnzipM (dsTrimCmdArg local_vars env_ids) args
567     return (mkApps (App core_op (Type env_ty)) core_args,
568             unionVarSets fv_sets)
569
570
571 dsCmd ids local_vars env_ids stack res_ty (HsTick ix vars expr) = do
572     (expr1,id_set) <- dsLCmd ids local_vars env_ids stack res_ty expr
573     expr2 <- mkTickBox ix vars expr1
574     return (expr2,id_set)
575
576 --      A | ys |- c :: [ts] t   (ys <= xs)
577 --      ---------------------
578 --      A | xs |- c :: [ts] t   ---> arr_ts (\ (xs) -> (ys)) >>> c
579
580 dsTrimCmdArg
581         :: IdSet                -- set of local vars available to this command
582         -> [Id]                 -- list of vars in the input to this command
583         -> LHsCmdTop Id -- command argument to desugar
584         -> DsM (CoreExpr,       -- desugared expression
585                 IdSet)          -- set of local vars that occur free
586 dsTrimCmdArg local_vars env_ids (L _ (HsCmdTop cmd stack cmd_ty ids)) = do
587     meth_ids <- mkCmdEnv ids
588     (core_cmd, free_vars, env_ids') <- dsfixCmd meth_ids local_vars stack cmd_ty cmd
589     stack_ids <- mapM newSysLocalDs stack
590     trim_code <- matchEnvStack env_ids stack_ids (buildEnvStack env_ids' stack_ids)
591     let
592         in_ty = envStackType env_ids stack
593         in_ty' = envStackType env_ids' stack
594         arg_code = if env_ids' == env_ids then core_cmd else
595                 do_map_arrow meth_ids in_ty in_ty' cmd_ty trim_code core_cmd
596     return (bindCmdEnv meth_ids arg_code, free_vars)
597
598 -- Given A | xs |- c :: [ts] t, builds c with xs fed back.
599 -- Typically needs to be prefixed with arr (\p -> ((xs)*ts))
600
601 dsfixCmd
602         :: DsCmdEnv             -- arrow combinators
603         -> IdSet                -- set of local vars available to this command
604         -> [Type]               -- type of the stack
605         -> Type                 -- return type of the command
606         -> LHsCmd Id            -- command to desugar
607         -> DsM (CoreExpr,       -- desugared expression
608                 IdSet,          -- set of local vars that occur free
609                 [Id])           -- set as a list, fed back
610 dsfixCmd ids local_vars stack cmd_ty cmd
611   = fixDs (\ ~(_,_,env_ids') -> do
612         (core_cmd, free_vars) <- dsLCmd ids local_vars env_ids' stack cmd_ty cmd
613         return (core_cmd, free_vars, varSetElems free_vars))
614
615 \end{code}
616
617 Translation of command judgements of the form
618
619         A | xs |- do { ss } :: [] t
620
621 \begin{code}
622
623 dsCmdDo :: DsCmdEnv             -- arrow combinators
624         -> IdSet                -- set of local vars available to this statement
625         -> [Id]                 -- list of vars in the input to this statement
626                                 -- This is typically fed back,
627                                 -- so don't pull on it too early
628         -> Type                 -- return type of the statement
629         -> [LStmt Id]           -- statements to desugar
630         -> LHsExpr Id           -- body
631         -> DsM (CoreExpr,       -- desugared expression
632                 IdSet)          -- set of local vars that occur free
633
634 --      A | xs |- c :: [] t
635 --      --------------------------
636 --      A | xs |- do { c } :: [] t
637
638 dsCmdDo ids local_vars env_ids res_ty [] body
639   = dsLCmd ids local_vars env_ids [] res_ty body
640
641 dsCmdDo ids local_vars env_ids res_ty (stmt:stmts) body = do
642     let
643         bound_vars = mkVarSet (map unLoc (collectLStmtBinders stmt))
644         local_vars' = local_vars `unionVarSet` bound_vars
645     (core_stmts, fv_stmts, env_ids') <- fixDs (\ ~(_,_,env_ids') -> do
646         (core_stmts, fv_stmts) <- dsCmdDo ids local_vars' env_ids' res_ty stmts body
647         return (core_stmts, fv_stmts, varSetElems fv_stmts))
648     (core_stmt, fv_stmt) <- dsCmdLStmt ids local_vars env_ids env_ids' stmt
649     return (do_compose ids
650                 (mkBigCoreVarTupTy env_ids)
651                 (mkBigCoreVarTupTy env_ids')
652                 res_ty
653                 core_stmt
654                 core_stmts,
655               fv_stmt)
656
657 \end{code}
658 A statement maps one local environment to another, and is represented
659 as an arrow from one tuple type to another.  A statement sequence is
660 translated to a composition of such arrows.
661 \begin{code}
662 dsCmdLStmt ids local_vars env_ids out_ids cmd
663   = dsCmdStmt ids local_vars env_ids out_ids (unLoc cmd)
664
665 dsCmdStmt
666         :: DsCmdEnv             -- arrow combinators
667         -> IdSet                -- set of local vars available to this statement
668         -> [Id]                 -- list of vars in the input to this statement
669                                 -- This is typically fed back,
670                                 -- so don't pull on it too early
671         -> [Id]                 -- list of vars in the output of this statement
672         -> Stmt Id      -- statement to desugar
673         -> DsM (CoreExpr,       -- desugared expression
674                 IdSet)          -- set of local vars that occur free
675
676 --      A | xs1 |- c :: [] t
677 --      A | xs' |- do { ss } :: [] t'
678 --      ------------------------------
679 --      A | xs |- do { c; ss } :: [] t'
680 --
681 --              ---> arr (\ (xs) -> ((xs1),(xs'))) >>> first c >>>
682 --                      arr snd >>> ss
683
684 dsCmdStmt ids local_vars env_ids out_ids (ExprStmt cmd _ c_ty) = do
685     (core_cmd, fv_cmd, env_ids1) <- dsfixCmd ids local_vars [] c_ty cmd
686     core_mux <- matchEnvStack env_ids []
687         (mkCorePairExpr (mkBigCoreVarTup env_ids1) (mkBigCoreVarTup out_ids))
688     let
689         in_ty = mkBigCoreVarTupTy env_ids
690         in_ty1 = mkBigCoreVarTupTy env_ids1
691         out_ty = mkBigCoreVarTupTy out_ids
692         before_c_ty = mkCorePairTy in_ty1 out_ty
693         after_c_ty = mkCorePairTy c_ty out_ty
694     snd_fn <- mkSndExpr c_ty out_ty
695     return (do_map_arrow ids in_ty before_c_ty out_ty core_mux $
696                 do_compose ids before_c_ty after_c_ty out_ty
697                         (do_first ids in_ty1 c_ty out_ty core_cmd) $
698                 do_arr ids after_c_ty out_ty snd_fn,
699               extendVarSetList fv_cmd out_ids)
700   where
701
702 --      A | xs1 |- c :: [] t
703 --      A | xs' |- do { ss } :: [] t'           xs2 = xs' - defs(p)
704 --      -----------------------------------
705 --      A | xs |- do { p <- c; ss } :: [] t'
706 --
707 --              ---> arr (\ (xs) -> ((xs1),(xs2))) >>> first c >>>
708 --                      arr (\ (p, (xs2)) -> (xs')) >>> ss
709 --
710 -- It would be simpler and more consistent to do this using second,
711 -- but that's likely to be defined in terms of first.
712
713 dsCmdStmt ids local_vars env_ids out_ids (BindStmt pat cmd _ _) = do
714     (core_cmd, fv_cmd, env_ids1) <- dsfixCmd ids local_vars [] (hsLPatType pat) cmd
715     let
716         pat_ty = hsLPatType pat
717         pat_vars = mkVarSet (collectPatBinders pat)
718         env_ids2 = varSetElems (mkVarSet out_ids `minusVarSet` pat_vars)
719         env_ty2 = mkBigCoreVarTupTy env_ids2
720
721     -- multiplexing function
722     --          \ (xs) -> ((xs1),(xs2))
723
724     core_mux <- matchEnvStack env_ids []
725         (mkCorePairExpr (mkBigCoreVarTup env_ids1) (mkBigCoreVarTup env_ids2))
726
727     -- projection function
728     --          \ (p, (xs2)) -> (zs)
729
730     env_id <- newSysLocalDs env_ty2
731     uniqs <- newUniqueSupply
732     let
733         after_c_ty = mkCorePairTy pat_ty env_ty2
734         out_ty = mkBigCoreVarTupTy out_ids
735         body_expr = coreCaseTuple uniqs env_id env_ids2 (mkBigCoreVarTup out_ids)
736     
737     fail_expr <- mkFailExpr (StmtCtxt DoExpr) out_ty
738     pat_id    <- selectSimpleMatchVarL pat
739     match_code <- matchSimply (Var pat_id) (StmtCtxt DoExpr) pat body_expr fail_expr
740     pair_id   <- newSysLocalDs after_c_ty
741     let
742         proj_expr = Lam pair_id (coreCasePair pair_id pat_id env_id match_code)
743
744     -- put it all together
745     let
746         in_ty = mkBigCoreVarTupTy env_ids
747         in_ty1 = mkBigCoreVarTupTy env_ids1
748         in_ty2 = mkBigCoreVarTupTy env_ids2
749         before_c_ty = mkCorePairTy in_ty1 in_ty2
750     return (do_map_arrow ids in_ty before_c_ty out_ty core_mux $
751                 do_compose ids before_c_ty after_c_ty out_ty
752                         (do_first ids in_ty1 pat_ty in_ty2 core_cmd) $
753                 do_arr ids after_c_ty out_ty proj_expr,
754               fv_cmd `unionVarSet` (mkVarSet out_ids `minusVarSet` pat_vars))
755
756 --      A | xs' |- do { ss } :: [] t
757 --      --------------------------------------
758 --      A | xs |- do { let binds; ss } :: [] t
759 --
760 --              ---> arr (\ (xs) -> let binds in (xs')) >>> ss
761
762 dsCmdStmt ids local_vars env_ids out_ids (LetStmt binds) = do
763     -- build a new environment using the let bindings
764     core_binds <- dsLocalBinds binds (mkBigCoreVarTup out_ids)
765     -- match the old environment against the input
766     core_map <- matchEnvStack env_ids [] core_binds
767     return (do_arr ids
768                         (mkBigCoreVarTupTy env_ids)
769                         (mkBigCoreVarTupTy out_ids)
770                         core_map,
771         exprFreeVars core_binds `intersectVarSet` local_vars)
772
773 --      A | ys |- do { ss; returnA -< ((xs1), (ys2)) } :: [] ...
774 --      A | xs' |- do { ss' } :: [] t
775 --      ------------------------------------
776 --      A | xs |- do { rec ss; ss' } :: [] t
777 --
778 --                      xs1 = xs' /\ defs(ss)
779 --                      xs2 = xs' - defs(ss)
780 --                      ys1 = ys - defs(ss)
781 --                      ys2 = ys /\ defs(ss)
782 --
783 --              ---> arr (\(xs) -> ((ys1),(xs2))) >>>
784 --                      first (loop (arr (\((ys1),~(ys2)) -> (ys)) >>> ss)) >>>
785 --                      arr (\((xs1),(xs2)) -> (xs')) >>> ss'
786
787 dsCmdStmt ids local_vars env_ids out_ids (RecStmt stmts later_ids rec_ids rhss binds) = do
788     let         -- ToDo: ****** binds not desugared; ROSS PLEASE FIX ********
789         env2_id_set = mkVarSet out_ids `minusVarSet` mkVarSet later_ids
790         env2_ids = varSetElems env2_id_set
791         env2_ty = mkBigCoreVarTupTy env2_ids
792
793     -- post_loop_fn = \((later_ids),(env2_ids)) -> (out_ids)
794
795     uniqs <- newUniqueSupply
796     env2_id <- newSysLocalDs env2_ty
797     let
798         later_ty = mkBigCoreVarTupTy later_ids
799         post_pair_ty = mkCorePairTy later_ty env2_ty
800         post_loop_body = coreCaseTuple uniqs env2_id env2_ids (mkBigCoreVarTup out_ids)
801
802     post_loop_fn <- matchEnvStack later_ids [env2_id] post_loop_body
803
804     --- loop (...)
805
806     (core_loop, env1_id_set, env1_ids)
807                <- dsRecCmd ids local_vars stmts later_ids rec_ids rhss
808
809     -- pre_loop_fn = \(env_ids) -> ((env1_ids),(env2_ids))
810
811     let
812         env1_ty = mkBigCoreVarTupTy env1_ids
813         pre_pair_ty = mkCorePairTy env1_ty env2_ty
814         pre_loop_body = mkCorePairExpr (mkBigCoreVarTup env1_ids)
815                                         (mkBigCoreVarTup env2_ids)
816
817     pre_loop_fn <- matchEnvStack env_ids [] pre_loop_body
818
819     -- arr pre_loop_fn >>> first (loop (...)) >>> arr post_loop_fn
820
821     let
822         env_ty = mkBigCoreVarTupTy env_ids
823         out_ty = mkBigCoreVarTupTy out_ids
824         core_body = do_map_arrow ids env_ty pre_pair_ty out_ty
825                 pre_loop_fn
826                 (do_compose ids pre_pair_ty post_pair_ty out_ty
827                         (do_first ids env1_ty later_ty env2_ty
828                                 core_loop)
829                         (do_arr ids post_pair_ty out_ty
830                                 post_loop_fn))
831
832     return (core_body, env1_id_set `unionVarSet` env2_id_set)
833
834 --      loop (arr (\ ((env1_ids), ~(rec_ids)) -> (env_ids)) >>>
835 --            ss >>>
836 --            arr (\ (out_ids) -> ((later_ids),(rhss))) >>>
837
838 dsRecCmd ids local_vars stmts later_ids rec_ids rhss = do
839     let
840         rec_id_set = mkVarSet rec_ids
841         out_ids = varSetElems (mkVarSet later_ids `unionVarSet` rec_id_set)
842         out_ty = mkBigCoreVarTupTy out_ids
843         local_vars' = local_vars `unionVarSet` rec_id_set
844
845     -- mk_pair_fn = \ (out_ids) -> ((later_ids),(rhss))
846
847     core_rhss <- mapM dsExpr rhss
848     let
849         later_tuple = mkBigCoreVarTup later_ids
850         later_ty = mkBigCoreVarTupTy later_ids
851         rec_tuple = mkBigCoreTup core_rhss
852         rec_ty = mkBigCoreVarTupTy rec_ids
853         out_pair = mkCorePairExpr later_tuple rec_tuple
854         out_pair_ty = mkCorePairTy later_ty rec_ty
855
856     mk_pair_fn <- matchEnvStack out_ids [] out_pair
857
858     -- ss
859
860     (core_stmts, fv_stmts, env_ids) <- dsfixCmdStmts ids local_vars' out_ids stmts
861
862     -- squash_pair_fn = \ ((env1_ids), ~(rec_ids)) -> (env_ids)
863
864     rec_id <- newSysLocalDs rec_ty
865     let
866         env1_id_set = fv_stmts `minusVarSet` rec_id_set
867         env1_ids = varSetElems env1_id_set
868         env1_ty = mkBigCoreVarTupTy env1_ids
869         in_pair_ty = mkCorePairTy env1_ty rec_ty
870         core_body = mkBigCoreTup (map selectVar env_ids)
871           where
872             selectVar v
873                 | v `elemVarSet` rec_id_set
874                   = mkTupleSelector rec_ids v rec_id (Var rec_id)
875                 | otherwise = Var v
876
877     squash_pair_fn <- matchEnvStack env1_ids [rec_id] core_body
878
879     -- loop (arr squash_pair_fn >>> ss >>> arr mk_pair_fn)
880
881     let
882         env_ty = mkBigCoreVarTupTy env_ids
883         core_loop = do_loop ids env1_ty later_ty rec_ty
884                 (do_map_arrow ids in_pair_ty env_ty out_pair_ty
885                         squash_pair_fn
886                         (do_compose ids env_ty out_ty out_pair_ty
887                                 core_stmts
888                                 (do_arr ids out_ty out_pair_ty mk_pair_fn)))
889
890     return (core_loop, env1_id_set, env1_ids)
891
892 \end{code}
893 A sequence of statements (as in a rec) is desugared to an arrow between
894 two environments
895 \begin{code}
896
897 dsfixCmdStmts
898         :: DsCmdEnv             -- arrow combinators
899         -> IdSet                -- set of local vars available to this statement
900         -> [Id]                 -- output vars of these statements
901         -> [LStmt Id]   -- statements to desugar
902         -> DsM (CoreExpr,       -- desugared expression
903                 IdSet,          -- set of local vars that occur free
904                 [Id])           -- input vars
905
906 dsfixCmdStmts ids local_vars out_ids stmts
907   = fixDs (\ ~(_,_,env_ids) -> do
908         (core_stmts, fv_stmts) <- dsCmdStmts ids local_vars env_ids out_ids stmts
909         return (core_stmts, fv_stmts, varSetElems fv_stmts))
910
911 dsCmdStmts
912         :: DsCmdEnv             -- arrow combinators
913         -> IdSet                -- set of local vars available to this statement
914         -> [Id]                 -- list of vars in the input to these statements
915         -> [Id]                 -- output vars of these statements
916         -> [LStmt Id]   -- statements to desugar
917         -> DsM (CoreExpr,       -- desugared expression
918                 IdSet)          -- set of local vars that occur free
919
920 dsCmdStmts ids local_vars env_ids out_ids [stmt]
921   = dsCmdLStmt ids local_vars env_ids out_ids stmt
922
923 dsCmdStmts ids local_vars env_ids out_ids (stmt:stmts) = do
924     let
925         bound_vars = mkVarSet (map unLoc (collectLStmtBinders stmt))
926         local_vars' = local_vars `unionVarSet` bound_vars
927     (core_stmts, fv_stmts, env_ids') <- dsfixCmdStmts ids local_vars' out_ids stmts
928     (core_stmt, fv_stmt) <- dsCmdLStmt ids local_vars env_ids env_ids' stmt
929     return (do_compose ids
930                 (mkBigCoreVarTupTy env_ids)
931                 (mkBigCoreVarTupTy env_ids')
932                 (mkBigCoreVarTupTy out_ids)
933                 core_stmt
934                 core_stmts,
935               fv_stmt)
936
937 \end{code}
938
939 Match a list of expressions against a list of patterns, left-to-right.
940
941 \begin{code}
942 matchSimplys :: [CoreExpr]              -- Scrutinees
943              -> HsMatchContext Name     -- Match kind
944              -> [LPat Id]               -- Patterns they should match
945              -> CoreExpr                -- Return this if they all match
946              -> CoreExpr                -- Return this if they don't
947              -> DsM CoreExpr
948 matchSimplys [] _ctxt [] result_expr _fail_expr = return result_expr
949 matchSimplys (exp:exps) ctxt (pat:pats) result_expr fail_expr = do
950     match_code <- matchSimplys exps ctxt pats result_expr fail_expr
951     matchSimply exp ctxt pat match_code fail_expr
952 \end{code}
953
954 List of leaf expressions, with set of variables bound in each
955
956 \begin{code}
957 leavesMatch :: LMatch Id -> [(LHsExpr Id, IdSet)]
958 leavesMatch (L _ (Match pats _ (GRHSs grhss binds)))
959   = let
960         defined_vars = mkVarSet (collectPatsBinders pats)
961                         `unionVarSet`
962                        mkVarSet (map unLoc (collectLocalBinders binds))
963     in
964     [(expr, 
965       mkVarSet (map unLoc (collectLStmtsBinders stmts)) 
966         `unionVarSet` defined_vars) 
967     | L _ (GRHS stmts expr) <- grhss]
968 \end{code}
969
970 Replace the leaf commands in a match
971
972 \begin{code}
973 replaceLeavesMatch
974         :: Type                 -- new result type
975         -> [LHsExpr Id] -- replacement leaf expressions of that type
976         -> LMatch Id    -- the matches of a case command
977         -> ([LHsExpr Id],-- remaining leaf expressions
978             LMatch Id)  -- updated match
979 replaceLeavesMatch res_ty leaves (L loc (Match pat mt (GRHSs grhss binds)))
980   = let
981         (leaves', grhss') = mapAccumL replaceLeavesGRHS leaves grhss
982     in
983     (leaves', L loc (Match pat mt (GRHSs grhss' binds)))
984
985 replaceLeavesGRHS
986         :: [LHsExpr Id] -- replacement leaf expressions of that type
987         -> LGRHS Id     -- rhss of a case command
988         -> ([LHsExpr Id],-- remaining leaf expressions
989             LGRHS Id)   -- updated GRHS
990 replaceLeavesGRHS (leaf:leaves) (L loc (GRHS stmts rhs))
991   = (leaves, L loc (GRHS stmts leaf))
992 \end{code}
993
994 Balanced fold of a non-empty list.
995
996 \begin{code}
997 foldb :: (a -> a -> a) -> [a] -> a
998 foldb _ [] = error "foldb of empty list"
999 foldb _ [x] = x
1000 foldb f xs = foldb f (fold_pairs xs)
1001   where
1002     fold_pairs [] = []
1003     fold_pairs [x] = [x]
1004     fold_pairs (x1:x2:xs) = f x1 x2:fold_pairs xs
1005 \end{code}
1006
1007 The following functions to collect value variables from patterns are
1008 copied from HsUtils, with one change: we also collect the dictionary
1009 bindings (pat_binds) from ConPatOut.  We need them for cases like
1010
1011 h :: Arrow a => Int -> a (Int,Int) Int
1012 h x = proc (y,z) -> case compare x y of
1013                 GT -> returnA -< z+x
1014
1015 The type checker turns the case into
1016
1017                 case compare x y of
1018                   GT { p77 = plusInt } -> returnA -< p77 z x
1019
1020 Here p77 is a local binding for the (+) operation.
1021
1022 See comments in HsUtils for why the other version does not include
1023 these bindings.
1024
1025 \begin{code}
1026 collectPatBinders :: LPat a -> [a]
1027 collectPatBinders pat = map unLoc (collectLocatedPatBinders pat)
1028
1029 collectLocatedPatBinders :: LPat a -> [Located a]
1030 collectLocatedPatBinders pat = collectl pat []
1031
1032 collectPatsBinders :: [LPat a] -> [a]
1033 collectPatsBinders pats = map unLoc (collectLocatedPatsBinders pats)
1034
1035 collectLocatedPatsBinders :: [LPat a] -> [Located a]
1036 collectLocatedPatsBinders pats = foldr collectl [] pats
1037
1038 ---------------------
1039 collectl (L l pat) bndrs
1040   = go pat
1041   where
1042     go (VarPat var)               = L l var : bndrs
1043     go (VarPatOut var bs)         = L l var : collectHsBindLocatedBinders bs
1044                                     ++ bndrs
1045     go (WildPat _)                = bndrs
1046     go (LazyPat pat)              = collectl pat bndrs
1047     go (BangPat pat)              = collectl pat bndrs
1048     go (AsPat a pat)              = a : collectl pat bndrs
1049     go (ParPat  pat)              = collectl pat bndrs
1050
1051     go (ListPat pats _)           = foldr collectl bndrs pats
1052     go (PArrPat pats _)           = foldr collectl bndrs pats
1053     go (TuplePat pats _ _)        = foldr collectl bndrs pats
1054
1055     go (ConPatIn c ps)            = foldr collectl bndrs (hsConPatArgs ps)
1056     go (ConPatOut {pat_args=ps, pat_binds=ds}) =
1057                                     collectHsBindLocatedBinders ds
1058                                     ++ foldr collectl bndrs (hsConPatArgs ps)
1059     go (LitPat _)                 = bndrs
1060     go (NPat _ _ _)               = bndrs
1061     go (NPlusKPat n _ _ _)        = n : bndrs
1062
1063     go (SigPatIn pat _)           = collectl pat bndrs
1064     go (SigPatOut pat _)          = collectl pat bndrs
1065     go (TypePat ty)               = bndrs
1066     go (CoPat _ pat ty)           = collectl (noLoc pat) bndrs
1067 \end{code}