summaryrefslogtreecommitdiff
path: root/ghc/compiler/typecheck/TcMatches.lhs
blob: 07a1094d58de98b08937c346db5965a070bac90f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
%
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section[TcMatches]{Typecheck some @Matches@}

\begin{code}
module TcMatches ( tcMatchesFun, tcGRHSsPat, tcMatchesCase, tcMatchLambda,
		   matchCtxt, TcMatchCtxt(..), 
		   tcStmts, tcDoStmts, 
		   tcDoStmt, tcMDoStmt, tcGuardStmt
       ) where

#include "HsVersions.h"

import {-# SOURCE #-}	TcExpr( tcSyntaxOp, tcInferRho, tcMonoExpr, tcPolyExpr )

import HsSyn		( HsExpr(..), LHsExpr, MatchGroup(..),
			  Match(..), LMatch, GRHSs(..), GRHS(..), 
			  Stmt(..), LStmt, HsMatchContext(..), HsStmtContext(..),
			  pprMatch, isIrrefutableHsPat, mkHsCoerce,
			  pprMatchContext, pprStmtContext, 
			  noSyntaxExpr, matchGroupArity, pprMatches,
			  ExprCoFn )

import TcRnMonad
import TcHsType		( tcPatSig, UserTypeCtxt(..) )
import Inst		( newMethodFromName )
import TcEnv		( TcId, tcLookupLocalIds, tcLookupId, tcExtendIdEnv, 
			  tcExtendTyVarEnv2 )
import TcPat		( PatCtxt(..), tcPats, tcPat )
import TcMType		( newFlexiTyVarTy, newFlexiTyVarTys ) 
import TcType		( TcType, TcRhoType, 
			  BoxySigmaType, BoxyRhoType, 
			  mkFunTys, mkFunTy, mkAppTy, mkTyConApp,
			  liftedTypeKind )
import TcBinds		( tcLocalBinds )
import TcUnify		( boxySplitAppTy, boxySplitTyConApp, boxySplitListTy,
			  subFunTys, tcSubExp, withBox )
import TcSimplify	( bindInstsOfLocalFuns )
import Name		( Name )
import TysWiredIn	( stringTy, boolTy, parrTyCon, listTyCon, mkListTy, mkPArrTy )
import PrelNames	( bindMName, returnMName, mfixName, thenMName, failMName )
import Id		( idType, mkLocalId )
import TyCon		( TyCon )
import Outputable
import SrcLoc		( Located(..), getLoc )
import ErrUtils		( Message )
\end{code}

%************************************************************************
%*									*
\subsection{tcMatchesFun, tcMatchesCase}
%*									*
%************************************************************************

@tcMatchesFun@ typechecks a @[Match]@ list which occurs in a
@FunMonoBind@.  The second argument is the name of the function, which
is used in error messages.  It checks that all the equations have the
same number of arguments before using @tcMatches@ to do the work.

\begin{code}
tcMatchesFun :: Name
	     -> MatchGroup Name
	     -> BoxyRhoType 		-- Expected type of function
	     -> TcM (ExprCoFn, MatchGroup TcId)	-- Returns type of body

tcMatchesFun fun_name matches exp_ty
  = do	{  -- Check that they all have the same no of arguments
	   -- Location is in the monad, set the caller so that 
	   -- any inter-equation error messages get some vaguely
	   -- sensible location.	Note: we have to do this odd
	   -- ann-grabbing, because we don't always have annotations in
	   -- hand when we call tcMatchesFun...
	  checkArgs fun_name matches

	-- ToDo: Don't use "expected" stuff if there ain't a type signature
	-- because inconsistency between branches
	-- may show up as something wrong with the (non-existent) type signature

		-- This is one of two places places we call subFunTys
		-- The point is that if expected_y is a "hole", we want 
		-- to make pat_tys and rhs_ty as "holes" too.
	; subFunTys doc n_pats exp_ty     $ \ pat_tys rhs_ty -> 
	  tcMatches match_ctxt pat_tys rhs_ty matches
	}
  where
    doc = ptext SLIT("The equation(s) for") <+> quotes (ppr fun_name)
	  <+> ptext SLIT("have") <+> speakNOf n_pats (ptext SLIT("argument"))
    n_pats = matchGroupArity matches
    match_ctxt = MC { mc_what = FunRhs fun_name, mc_body = tcPolyExpr }
\end{code}

@tcMatchesCase@ doesn't do the argument-count check because the
parser guarantees that each equation has exactly one argument.

\begin{code}
tcMatchesCase :: TcMatchCtxt		-- Case context
	      -> TcRhoType		-- Type of scrutinee
	      -> MatchGroup Name	-- The case alternatives
	      -> BoxyRhoType 		-- Type of whole case expressions
	      -> TcM (MatchGroup TcId)	-- Translated alternatives

tcMatchesCase ctxt scrut_ty matches res_ty
  = tcMatches ctxt [scrut_ty] res_ty matches

tcMatchLambda :: MatchGroup Name -> BoxyRhoType -> TcM (ExprCoFn, MatchGroup TcId)
tcMatchLambda match res_ty 
  = subFunTys doc n_pats res_ty 	$ \ pat_tys rhs_ty ->
    tcMatches match_ctxt pat_tys rhs_ty match
  where
    n_pats = matchGroupArity match
    doc = sep [ ptext SLIT("The lambda expression")
		 <+> quotes (pprSetDepth 1 $ pprMatches LambdaExpr match),
			-- The pprSetDepth makes the abstraction print briefly
		ptext SLIT("has") <+> speakNOf n_pats (ptext SLIT("argument"))]
    match_ctxt = MC { mc_what = LambdaExpr,
		      mc_body = tcPolyExpr }
\end{code}

@tcGRHSsPat@ typechecks @[GRHSs]@ that occur in a @PatMonoBind@.

\begin{code}
tcGRHSsPat :: GRHSs Name -> BoxyRhoType -> TcM (GRHSs TcId)
tcGRHSsPat grhss res_ty = tcGRHSs match_ctxt grhss res_ty
  where
    match_ctxt = MC { mc_what = PatBindRhs,
		      mc_body = tcPolyExpr }
\end{code}


%************************************************************************
%*									*
\subsection{tcMatch}
%*									*
%************************************************************************

\begin{code}
tcMatches :: TcMatchCtxt
	  -> [BoxySigmaType] 		-- Expected pattern types
	  -> BoxyRhoType		-- Expected result-type of the Match.
	  -> MatchGroup Name
	  -> TcM (MatchGroup TcId)

data TcMatchCtxt 	-- c.f. TcStmtCtxt, also in this module
  = MC { mc_what :: HsMatchContext Name,	-- What kind of thing this is
    	 mc_body :: LHsExpr Name 		-- Type checker for a body of an alternative
		 -> BoxyRhoType 
		 -> TcM (LHsExpr TcId) }	

tcMatches ctxt pat_tys rhs_ty (MatchGroup matches _)
  = do	{ matches' <- mapM (tcMatch ctxt pat_tys rhs_ty) matches
	; return (MatchGroup matches' (mkFunTys pat_tys rhs_ty)) }

-------------
tcMatch :: TcMatchCtxt
	-> [BoxySigmaType]	-- Expected pattern types
	-> BoxyRhoType	 	-- Expected result-type of the Match.
	-> LMatch Name
	-> TcM (LMatch TcId)

tcMatch ctxt pat_tys rhs_ty match 
  = wrapLocM (tc_match ctxt pat_tys rhs_ty) match
  where
    tc_match ctxt pat_tys rhs_ty match@(Match pats maybe_rhs_sig grhss)
      = addErrCtxt (matchCtxt (mc_what ctxt) match)	$	
        do { (pats', grhss') <- tcPats LamPat pats pat_tys rhs_ty $
    			        tc_grhss ctxt maybe_rhs_sig grhss
	   ; returnM (Match pats' Nothing grhss') }

    tc_grhss ctxt Nothing grhss rhs_ty 
      = tcGRHSs ctxt grhss rhs_ty	-- No result signature

    tc_grhss ctxt (Just res_sig) grhss rhs_ty 
      = do { (inner_ty, sig_tvs) <- tcPatSig ResSigCtxt res_sig rhs_ty
	   ; tcExtendTyVarEnv2 sig_tvs $
    	     tcGRHSs ctxt grhss inner_ty }

-------------
tcGRHSs :: TcMatchCtxt -> GRHSs Name -> BoxyRhoType -> TcM (GRHSs TcId)

-- Notice that we pass in the full res_ty, so that we get
-- good inference from simple things like
--	f = \(x::forall a.a->a) -> <stuff>
-- We used to force it to be a monotype when there was more than one guard
-- but we don't need to do that any more

tcGRHSs ctxt (GRHSs grhss binds) res_ty
  = do	{ (binds', grhss') <- tcLocalBinds binds $
			      mappM (wrapLocM (tcGRHS ctxt res_ty)) grhss

	; returnM (GRHSs grhss' binds') }

-------------
tcGRHS :: TcMatchCtxt -> BoxyRhoType -> GRHS Name -> TcM (GRHS TcId)

tcGRHS ctxt res_ty (GRHS guards rhs)
  = do  { (guards', rhs') <- tcStmts stmt_ctxt tcGuardStmt guards res_ty $
			     mc_body ctxt rhs
	; return (GRHS guards' rhs') }
  where
    stmt_ctxt  = PatGuard (mc_what ctxt)
\end{code}


%************************************************************************
%*									*
\subsection{@tcDoStmts@ typechecks a {\em list} of do statements}
%*									*
%************************************************************************

\begin{code}
tcDoStmts :: HsStmtContext Name 
	  -> [LStmt Name]
	  -> LHsExpr Name
	  -> BoxyRhoType
	  -> TcM (HsExpr TcId)		-- Returns a HsDo
tcDoStmts ListComp stmts body res_ty
  = do	{ elt_ty <- boxySplitListTy res_ty
	; (stmts', body') <- tcStmts ListComp (tcLcStmt listTyCon) stmts elt_ty $
			     tcBody (doBodyCtxt ListComp body) body
	; return (HsDo ListComp stmts' body' (mkListTy elt_ty)) }

tcDoStmts PArrComp stmts body res_ty
  = do	{ [elt_ty] <- boxySplitTyConApp parrTyCon res_ty
	; (stmts', body') <- tcStmts PArrComp (tcLcStmt parrTyCon) stmts elt_ty $
			     tcBody (doBodyCtxt PArrComp body) body
	; return (HsDo PArrComp stmts' body' (mkPArrTy elt_ty)) }

tcDoStmts DoExpr stmts body res_ty
  = do	{ (m_ty, elt_ty) <- boxySplitAppTy res_ty
	; let res_ty' = mkAppTy m_ty elt_ty	-- The boxySplit consumes res_ty
	; (stmts', body') <- tcStmts DoExpr (tcDoStmt m_ty) stmts res_ty' $
			     tcBody (doBodyCtxt DoExpr body) body
	; return (HsDo DoExpr stmts' body' res_ty') }

tcDoStmts ctxt@(MDoExpr _) stmts body res_ty
  = do	{ (m_ty, elt_ty) <- boxySplitAppTy res_ty
 	; let res_ty' = mkAppTy m_ty elt_ty	-- The boxySplit consumes res_ty
	      tc_rhs rhs = withBox liftedTypeKind $ \ pat_ty ->
			   tcMonoExpr rhs (mkAppTy m_ty pat_ty)

	; (stmts', body') <- tcStmts ctxt (tcMDoStmt tc_rhs) stmts res_ty' $
			     tcBody (doBodyCtxt ctxt body) body

	; let names = [mfixName, bindMName, thenMName, returnMName, failMName]
	; insts <- mapM (newMethodFromName DoOrigin m_ty) names
	; return (HsDo (MDoExpr (names `zip` insts)) stmts' body' res_ty') }

tcDoStmts ctxt stmts body res_ty = pprPanic "tcDoStmts" (pprStmtContext ctxt)

tcBody :: Message -> LHsExpr Name -> BoxyRhoType -> TcM (LHsExpr TcId)
tcBody ctxt body res_ty
  = -- addErrCtxt ctxt $	-- This context adds little that is useful
    tcPolyExpr body res_ty
\end{code}


%************************************************************************
%*									*
\subsection{tcStmts}
%*									*
%************************************************************************

\begin{code}
type TcStmtChecker
  = forall thing.  HsStmtContext Name
           	   -> Stmt Name
		   -> BoxyRhoType			-- Result type for comprehension
	      	   -> (BoxyRhoType -> TcM thing)	-- Checker for what follows the stmt
              	   -> TcM (Stmt TcId, thing)

  -- The incoming BoxyRhoType may be refined by type refinements
  -- before being passed to the thing_inside

tcStmts :: HsStmtContext Name
	-> TcStmtChecker	-- NB: higher-rank type
        -> [LStmt Name]
	-> BoxyRhoType
	-> (BoxyRhoType -> TcM thing)
        -> TcM ([LStmt TcId], thing)

-- Note the higher-rank type.  stmt_chk is applied at different
-- types in the equations for tcStmts

tcStmts ctxt stmt_chk [] res_ty thing_inside
  = do	{ thing <- thing_inside res_ty
	; return ([], thing) }

-- LetStmts are handled uniformly, regardless of context
tcStmts ctxt stmt_chk (L loc (LetStmt binds) : stmts) res_ty thing_inside
  = do	{ (binds', (stmts',thing)) <- tcLocalBinds binds $
				      tcStmts ctxt stmt_chk stmts res_ty thing_inside
	; return (L loc (LetStmt binds') : stmts', thing) }

-- For the vanilla case, handle the location-setting part
tcStmts ctxt stmt_chk (L loc stmt : stmts) res_ty thing_inside
  = do 	{ (stmt', (stmts', thing)) <- 
		setSrcSpan loc		 		$
    		addErrCtxt (stmtCtxt ctxt stmt)		$
		stmt_chk ctxt stmt res_ty		$ \ res_ty' ->
		popErrCtxt 				$
		tcStmts ctxt stmt_chk stmts res_ty'	$
		thing_inside
	; return (L loc stmt' : stmts', thing) }

--------------------------------
--	Pattern guards
tcGuardStmt :: TcStmtChecker
tcGuardStmt ctxt (ExprStmt guard _ _) res_ty thing_inside
  = do	{ guard' <- tcMonoExpr guard boolTy
	; thing  <- thing_inside res_ty
	; return (ExprStmt guard' noSyntaxExpr boolTy, thing) }

tcGuardStmt ctxt (BindStmt pat rhs _ _) res_ty thing_inside
  = do	{ (rhs', rhs_ty) <- tcInferRho rhs
	; (pat', thing)  <- tcPat LamPat pat rhs_ty res_ty thing_inside
	; return (BindStmt pat' rhs' noSyntaxExpr noSyntaxExpr, thing) }

tcGuardStmt ctxt stmt res_ty thing_inside
  = pprPanic "tcGuardStmt: unexpected Stmt" (ppr stmt)


--------------------------------
--	List comprehensions and PArrays

tcLcStmt :: TyCon	-- The list/Parray type constructor ([] or PArray)
	 -> TcStmtChecker

-- A generator, pat <- rhs
tcLcStmt m_tc ctxt (BindStmt pat rhs _ _) res_ty thing_inside 
 = do	{ (rhs', pat_ty) <- withBox liftedTypeKind $ \ ty ->
			    tcMonoExpr rhs (mkTyConApp m_tc [ty])
	; (pat', thing)  <- tcPat LamPat pat pat_ty res_ty thing_inside
	; return (BindStmt pat' rhs' noSyntaxExpr noSyntaxExpr, thing) }

-- A boolean guard
tcLcStmt m_tc ctxt (ExprStmt rhs _ _) res_ty thing_inside
  = do	{ rhs'  <- tcMonoExpr rhs boolTy
	; thing <- thing_inside res_ty
	; return (ExprStmt rhs' noSyntaxExpr boolTy, thing) }

-- A parallel set of comprehensions
--	[ (g x, h x) | ... ; let g v = ...
--		     | ... ; let h v = ... ]
--
-- It's possible that g,h are overloaded, so we need to feed the LIE from the
-- (g x, h x) up through both lots of bindings (so we get the bindInstsOfLocalFuns).
-- Similarly if we had an existential pattern match:
--
--	data T = forall a. Show a => C a
--
--	[ (show x, show y) | ... ; C x <- ...
--			   | ... ; C y <- ... ]
--
-- Then we need the LIE from (show x, show y) to be simplified against
-- the bindings for x and y.  
-- 
-- It's difficult to do this in parallel, so we rely on the renamer to 
-- ensure that g,h and x,y don't duplicate, and simply grow the environment.
-- So the binders of the first parallel group will be in scope in the second
-- group.  But that's fine; there's no shadowing to worry about.

tcLcStmt m_tc ctxt (ParStmt bndr_stmts_s) elt_ty thing_inside
  = do	{ (pairs', thing) <- loop bndr_stmts_s
	; return (ParStmt pairs', thing) }
  where
    -- loop :: [([LStmt Name], [Name])] -> TcM ([([LStmt TcId], [TcId])], thing)
    loop [] = do { thing <- thing_inside elt_ty	-- No refinement from pattern 
		 ; return ([], thing) }		-- matching in the branches

    loop ((stmts, names) : pairs)
      = do { (stmts', (ids, pairs', thing))
		<- tcStmts ctxt (tcLcStmt m_tc) stmts elt_ty $ \ elt_ty' ->
		   do { ids <- tcLookupLocalIds names
		      ; (pairs', thing) <- loop pairs
		      ; return (ids, pairs', thing) }
	   ; return ( (stmts', ids) : pairs', thing ) }

tcLcStmt m_tc ctxt stmt elt_ty thing_inside
  = pprPanic "tcLcStmt: unexpected Stmt" (ppr stmt)

--------------------------------
--	Do-notation
-- The main excitement here is dealing with rebindable syntax

tcDoStmt :: TcType		-- Monad type,  m
	 -> TcStmtChecker

tcDoStmt m_ty ctxt (BindStmt pat rhs bind_op fail_op) res_ty thing_inside
  = do	{ (rhs', pat_ty) <- withBox liftedTypeKind $ \ pat_ty -> 
			    tcMonoExpr rhs (mkAppTy m_ty pat_ty)
		-- We should use type *inference* for the RHS computations, becuase of GADTs. 
		-- 	do { pat <- rhs; <rest> }
		-- is rather like
		--	case rhs of { pat -> <rest> }
		-- We do inference on rhs, so that information about its type can be refined
		-- when type-checking the pattern. 

	; (pat', thing) <- tcPat LamPat pat pat_ty res_ty thing_inside

	-- Deal with rebindable syntax; (>>=) :: m a -> (a -> m b) -> m b
	; let bind_ty = mkFunTys [mkAppTy m_ty pat_ty, 
				  mkFunTy pat_ty res_ty] res_ty
	; bind_op' <- tcSyntaxOp DoOrigin bind_op bind_ty
		-- If (but only if) the pattern can fail, 
		-- typecheck the 'fail' operator
	; fail_op' <- if isIrrefutableHsPat pat' 
		      then return noSyntaxExpr
		      else tcSyntaxOp DoOrigin fail_op (mkFunTy stringTy res_ty)
	; return (BindStmt pat' rhs' bind_op' fail_op', thing) }


tcDoStmt m_ty ctxt (ExprStmt rhs then_op _) res_ty thing_inside
  = do	{ 	-- Deal with rebindable syntax; (>>) :: m a -> m b -> m b
	  a_ty <- newFlexiTyVarTy liftedTypeKind
	; let rhs_ty  = mkAppTy m_ty a_ty
	      then_ty = mkFunTys [rhs_ty, res_ty] res_ty
	; then_op' <- tcSyntaxOp DoOrigin then_op then_ty
	; rhs' <- tcPolyExpr rhs rhs_ty
	; thing <- thing_inside res_ty
	; return (ExprStmt rhs' then_op' rhs_ty, thing) }

tcDoStmt m_ty ctxt stmt res_ty thing_inside
  = pprPanic "tcDoStmt: unexpected Stmt" (ppr stmt)

--------------------------------
--	Mdo-notation
-- The distinctive features here are
--	(a) RecStmts, and
--	(b) no rebindable syntax

tcMDoStmt :: (LHsExpr Name -> TcM (LHsExpr TcId, TcType))	-- RHS inference
	  -> TcStmtChecker
tcMDoStmt tc_rhs ctxt (BindStmt pat rhs bind_op fail_op) res_ty thing_inside
  = do	{ (rhs', pat_ty) <- tc_rhs rhs
	; (pat', thing)  <- tcPat LamPat pat pat_ty res_ty thing_inside
	; return (BindStmt pat' rhs' noSyntaxExpr noSyntaxExpr, thing) }

tcMDoStmt tc_rhs ctxt (ExprStmt rhs then_op _) res_ty thing_inside
  = do	{ (rhs', elt_ty) <- tc_rhs rhs
	; thing 	 <- thing_inside res_ty
	; return (ExprStmt rhs' noSyntaxExpr elt_ty, thing) }

tcMDoStmt tc_rhs ctxt (RecStmt stmts laterNames recNames _ _) res_ty thing_inside
  = do	{ rec_tys <- newFlexiTyVarTys (length recNames) liftedTypeKind
	; let rec_ids = zipWith mkLocalId recNames rec_tys
	; tcExtendIdEnv rec_ids			$ do
    	{ (stmts', (later_ids, rec_rets))
		<- tcStmts ctxt (tcMDoStmt tc_rhs) stmts res_ty	$ \ res_ty' -> 
			-- ToDo: res_ty not really right
		   do { rec_rets <- zipWithM tc_ret recNames rec_tys
		      ; later_ids <- tcLookupLocalIds laterNames
		      ; return (later_ids, rec_rets) }

	; (thing,lie) <- tcExtendIdEnv later_ids (getLIE (thing_inside res_ty))
		-- NB:	The rec_ids for the recursive things 
		-- 	already scope over this part. This binding may shadow
		--	some of them with polymorphic things with the same Name
		--	(see note [RecStmt] in HsExpr)
	; lie_binds <- bindInstsOfLocalFuns lie later_ids
  
	; return (RecStmt stmts' later_ids rec_ids rec_rets lie_binds, thing)
	}}
  where 
    -- Unify the types of the "final" Ids with those of "knot-tied" Ids
    tc_ret rec_name mono_ty
	= do { poly_id <- tcLookupId rec_name
		-- poly_id may have a polymorphic type
		-- but mono_ty is just a monomorphic type variable
	     ; co_fn <- tcSubExp (idType poly_id) mono_ty
	     ; return (mkHsCoerce co_fn (HsVar poly_id)) }

tcMDoStmt tc_rhs ctxt stmt res_ty thing_inside
  = pprPanic "tcMDoStmt: unexpected Stmt" (ppr stmt)

\end{code}


%************************************************************************
%*									*
\subsection{Errors and contexts}
%*									*
%************************************************************************

@sameNoOfArgs@ takes a @[RenamedMatch]@ and decides whether the same
number of args are used in each equation.

\begin{code}
checkArgs :: Name -> MatchGroup Name -> TcM ()
checkArgs fun (MatchGroup (match1:matches) _)
    | null bad_matches = return ()
    | otherwise
    = failWithTc (vcat [ptext SLIT("Equations for") <+> quotes (ppr fun) <+> 
			  ptext SLIT("have different numbers of arguments"),
			nest 2 (ppr (getLoc match1)),
			nest 2 (ppr (getLoc (head bad_matches)))])
  where
    n_args1 = args_in_match match1
    bad_matches = [m | m <- matches, args_in_match m /= n_args1]

    args_in_match :: LMatch Name -> Int
    args_in_match (L _ (Match pats _ _)) = length pats
\end{code}

\begin{code}
matchCtxt ctxt match  = hang (ptext SLIT("In") <+> pprMatchContext ctxt <> colon) 
			   4 (pprMatch ctxt match)

doBodyCtxt :: HsStmtContext Name -> LHsExpr Name -> SDoc
doBodyCtxt ctxt body = hang (ptext SLIT("In the result of") <+> pprStmtContext ctxt <> colon) 
		          4 (ppr body)

stmtCtxt ctxt stmt = hang (ptext SLIT("In") <+> pprStmtContext ctxt <> colon)
		  	4 (ppr stmt)
\end{code}