summaryrefslogtreecommitdiff
path: root/ghc/compiler/typecheck/TcMatches.lhs
blob: c5900a81b3418143054f882e366a8bbda3f39775 (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
\%
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section[TcMatches]{Typecheck some @Matches@}

\begin{code}
module TcMatches ( tcMatchesFun, tcMatchesCase, tcMatchLambda, tcStmts, tcGRHSs ) where

#include "HsVersions.h"

import {-# SOURCE #-}	TcExpr( tcExpr )

import HsSyn		( HsBinds(..), Match(..), GRHSs(..), GRHS(..),
			  MonoBinds(..), StmtCtxt(..), Stmt(..),
			  pprMatch, getMatchLoc
			)
import RnHsSyn		( RenamedMatch, RenamedGRHSs, RenamedStmt )
import TcHsSyn		( TcMatch, TcGRHSs, TcStmt )

import TcMonad
import TcMonoType	( checkSigTyVars, tcHsTyVar, tcHsType, noSigs, sigPatCtxt )
import Inst		( Inst, LIE, plusLIE, emptyLIE, plusLIEs )
import TcEnv		( tcExtendLocalValEnv, tcExtendGlobalTyVars, tcExtendTyVarEnv )
import TcPat		( tcPat, polyPatSig )
import TcType		( TcType, newTyVarTy, newTyVarTy_OpenKind )
import TcBinds		( tcBindsAndThen )
import TcSimplify	( tcSimplifyAndCheck, bindInstsOfLocalFuns )
import TcUnify		( unifyFunTy, unifyTauTy )
import Name		( Name )
import TysWiredIn	( boolTy )

import BasicTypes	( RecFlag(..) )
import Type		( Kind, tyVarsOfType, isTauTy, mkFunTy, boxedTypeKind )
import VarSet
import Var		( Id )
import Util
import Bag
import Outputable
import List		( nub )
\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,Id)]	-- Bindings for the variables bound in this group
	     -> Name
	     -> TcType 		-- Expected type
	     -> [RenamedMatch]
	     -> TcM s ([TcMatch], LIE)

tcMatchesFun xve fun_name expected_ty matches@(first_match:_)
  =	 -- Check that they all have the same no of arguments
	 -- Set the location to that of the first equation, 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...
    tcAddSrcLoc (getMatchLoc first_match)	 (
	    checkTc (sameNoOfArgs matches)
		    (varyingArgsErr fun_name matches)
    )						 `thenTc_`

	-- 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

	-- No need to zonk expected_ty, because unifyFunTy does that on the fly
    tcMatches xve matches expected_ty (FunRhs fun_name)
\end{code}

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

\begin{code}
tcMatchesCase :: [RenamedMatch]		-- The case alternatives
	      -> TcType 		-- Type of whole case expressions
	      -> TcM s (TcType,		-- Inferred type of the scrutinee
			[TcMatch], 	-- Translated alternatives
			LIE)

tcMatchesCase matches expr_ty
  = newTyVarTy_OpenKind 					`thenNF_Tc` \ scrut_ty ->
    tcMatches [] matches (mkFunTy scrut_ty expr_ty) CaseAlt	`thenTc` \ (matches', lie) ->
    returnTc (scrut_ty, matches', lie)

tcMatchLambda :: RenamedMatch -> TcType -> TcM s (TcMatch, LIE)
tcMatchLambda match res_ty = tcMatch [] match res_ty LambdaBody
\end{code}


\begin{code}
tcMatches :: [(Name,Id)]
	  -> [RenamedMatch]
	  -> TcType
	  -> StmtCtxt
	  -> TcM s ([TcMatch], LIE)

tcMatches xve matches expected_ty fun_or_case
  = mapAndUnzipTc tc_match matches	`thenTc` \ (matches, lies) ->
    returnTc (matches, plusLIEs lies)
  where
    tc_match match = tcMatch xve match expected_ty fun_or_case
\end{code}


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

\begin{code}
tcMatch :: [(Name,Id)]
	-> RenamedMatch
	-> TcType 		-- Expected result-type of the Match.
				-- Early unification with this guy gives better error messages
	-> StmtCtxt
	-> TcM s (TcMatch, LIE)

tcMatch xve1 match@(Match sig_tvs pats maybe_rhs_sig grhss) expected_ty ctxt
  = tcAddSrcLoc (getMatchLoc match)		$
    tcAddErrCtxt (matchCtxt ctxt match)		$

    if null sig_tvs then	-- The common case
	tc_match expected_ty	`thenTc` \ (_, match_and_lie) ->
	returnTc match_and_lie

    else
	-- If there are sig tve we must be careful *not* to use
	-- expected_ty right away, else we'll unify with tyvars free
	-- in the envt.  So invent a fresh tyvar and use that instead
	newTyVarTy_OpenKind		`thenNF_Tc` \ tyvar_ty ->

	-- Extend the tyvar env and check the match itself
	mapNF_Tc tcHsTyVar sig_tvs 	`thenNF_Tc` \ sig_tyvars ->
	tcExtendTyVarEnv sig_tyvars (
		tc_match tyvar_ty
	)				`thenTc` \ (pat_ids, match_and_lie) ->

	-- Check that the scoped type variables from the patterns
	-- have not been constrained
        tcAddErrCtxtM (sigPatCtxt sig_tyvars pat_ids)		(
		checkSigTyVars sig_tyvars
	)							`thenTc_`

	-- *Now* we're free to unify with expected_ty
	unifyTauTy expected_ty tyvar_ty	`thenTc_`

	returnTc match_and_lie

  where
    tc_match expexted_ty 	-- Any sig tyvars are in scope by now
      = -- STEP 1: Typecheck the patterns
	tcMatchPats pats expected_ty	`thenTc` \ (rhs_ty, pats', lie_req1, ex_tvs, pat_bndrs, lie_avail) ->
        let
	  xve2       = bagToList pat_bndrs
	  pat_ids    = map snd xve2
	  ex_tv_list = bagToList ex_tvs
        in

	-- STEP 2: Check that the remaining "expected type" is not a rank-2 type
	-- If it is it'll mess up the unifier when checking the RHS
	checkTc (isTauTy rhs_ty) lurkingRank2SigErr 		`thenTc_`

	-- STEP 3: Unify with the rhs type signature if any
	(case maybe_rhs_sig of
	    Nothing  -> returnTc ()
	    Just sig -> tcHsType sig	`thenTc` \ sig_ty ->

			-- Check that the signature isn't a polymorphic one, which
			-- we don't permit (at present, anyway)
		        checkTc (isTauTy sig_ty) (polyPatSig sig_ty)	`thenTc_`
		        unifyTauTy rhs_ty sig_ty
	)						`thenTc_`

	-- STEP 4: Typecheck the guarded RHSs and the associated where clause
	tcExtendLocalValEnv xve1 (tcExtendLocalValEnv xve2 (
	    tcGRHSs grhss rhs_ty ctxt
	))					`thenTc` \ (grhss', lie_req2) ->

	-- STEP 5: Check for existentially bound type variables
	tcExtendGlobalTyVars (tyVarsOfType rhs_ty)	(
	    tcAddErrCtxtM (sigPatCtxt ex_tv_list pat_ids)	$
	    checkSigTyVars ex_tv_list				`thenTc` \ zonked_ex_tvs ->
	    tcSimplifyAndCheck 
		(text ("the existential context of a data constructor"))
		(mkVarSet zonked_ex_tvs)
		lie_avail (lie_req1 `plusLIE` lie_req2)
	)							`thenTc` \ (lie_req', ex_binds) ->

    	-- STEP 6 In case there are any polymorpic, overloaded binders in the pattern
	-- (which can happen in the case of rank-2 type signatures, or data constructors
	-- with polymorphic arguments), we must do a bindInstsOfLocalFns here
	bindInstsOfLocalFuns lie_req' pat_ids	 	`thenTc` \ (lie_req'', inst_binds) ->

	-- Phew!  All done.
	let
            grhss'' = glue_on Recursive ex_binds $
		      glue_on Recursive inst_binds grhss'
	in
	returnTc (pat_ids, (Match [] pats' Nothing grhss'', lie_req''))

	-- glue_on just avoids stupid dross
glue_on _ EmptyMonoBinds grhss = grhss		-- The common case
glue_on is_rec mbinds (GRHSs grhss binds ty)
  = GRHSs grhss (MonoBind mbinds [] is_rec `ThenBinds` binds) ty

tcGRHSs :: RenamedGRHSs
	-> TcType -> StmtCtxt
	-> TcM s (TcGRHSs, LIE)

tcGRHSs (GRHSs grhss binds _) expected_ty ctxt
  = tcBindsAndThen glue_on binds (tc_grhss grhss)
  where
    tc_grhss grhss
	= mapAndUnzipTc tc_grhs grhss		`thenTc` \ (grhss', lies) ->
	  returnTc (GRHSs grhss' EmptyBinds (Just expected_ty), plusLIEs lies)

    tc_grhs (GRHS guarded locn)
	= tcAddSrcLoc locn				$
	  tcStmts ctxt (\ty -> ty) guarded expected_ty	`thenTc` \ (guarded', lie) ->
	  returnTc (GRHS guarded' locn, lie)
\end{code}


%************************************************************************
%*									*
\subsection{tcMatchPats}
%*									*
%************************************************************************

\begin{code}
tcMatchPats [] expected_ty
  = returnTc (expected_ty, [], emptyLIE, emptyBag, emptyBag, emptyLIE)

tcMatchPats (pat:pats) expected_ty
  = unifyFunTy expected_ty	`thenTc` \ (arg_ty, rest_ty) ->
    tcPat noSigs pat arg_ty	`thenTc` \ (pat', lie_req, pat_tvs, pat_ids, lie_avail) ->
    tcMatchPats pats rest_ty	`thenTc` \ (rhs_ty, pats', lie_reqs, pats_tvs, pats_ids, lie_avails) ->
    returnTc (	rhs_ty, 
		pat':pats',
		lie_req `plusLIE` lie_reqs,
		pat_tvs `unionBags` pats_tvs,
		pat_ids `unionBags` pats_ids,
		lie_avail `plusLIE` lie_avails
    )
\end{code}


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


\begin{code}
tcStmts :: StmtCtxt
        -> (TcType -> TcType)	-- m, the relationship type of pat and rhs in pat <- rhs
        -> [RenamedStmt]
	-> TcType			-- elt_ty, where type of the comprehension is (m elt_ty)
        -> TcM s ([TcStmt], LIE)

tcStmts do_or_lc m (stmt@(ReturnStmt exp) : stmts) elt_ty
  = ASSERT( null stmts )
    tcSetErrCtxt (stmtCtxt do_or_lc stmt) 	$
    tcExpr exp elt_ty				`thenTc`    \ (exp', exp_lie) ->
    returnTc ([ReturnStmt exp'], exp_lie)

	-- ExprStmt at the end
tcStmts do_or_lc m [stmt@(ExprStmt exp src_loc)] elt_ty
  = tcSetErrCtxt (stmtCtxt do_or_lc stmt) 	$
    tcExpr exp (m elt_ty)			`thenTc`    \ (exp', exp_lie) ->
    returnTc ([ExprStmt exp' src_loc], exp_lie)

	-- ExprStmt not at the end
tcStmts do_or_lc m (stmt@(ExprStmt exp src_loc) : stmts) elt_ty
  = ASSERT( isDoStmt do_or_lc )
    tcAddSrcLoc src_loc 		(
	tcSetErrCtxt (stmtCtxt do_or_lc stmt)	$
	    -- exp has type (m tau) for some tau (doesn't matter what)
  	newTyVarTy_OpenKind			`thenNF_Tc` \ any_ty ->
  	tcExpr exp (m any_ty)
    )					`thenTc` \ (exp', exp_lie) ->
    tcStmts do_or_lc m stmts elt_ty	`thenTc` \ (stmts', stmts_lie) ->
    returnTc (ExprStmt exp' src_loc : stmts',
  	      exp_lie `plusLIE` stmts_lie)

tcStmts do_or_lc m (stmt@(GuardStmt exp src_loc) : stmts) elt_ty
  = ASSERT( not (isDoStmt do_or_lc) )
    tcSetErrCtxt (stmtCtxt do_or_lc stmt) (
	tcAddSrcLoc src_loc 		$
  	tcExpr exp boolTy
    )					`thenTc` \ (exp', exp_lie) ->
    tcStmts do_or_lc m stmts elt_ty	`thenTc` \ (stmts', stmts_lie) ->
    returnTc (GuardStmt exp' src_loc : stmts',
  	      exp_lie `plusLIE` stmts_lie)

tcStmts do_or_lc m (stmt@(BindStmt pat exp src_loc) : stmts) elt_ty
  = tcAddSrcLoc src_loc		(
	tcSetErrCtxt (stmtCtxt do_or_lc stmt)	$
    	newTyVarTy boxedTypeKind		`thenNF_Tc` \ pat_ty ->
  	tcPat noSigs pat pat_ty			`thenTc` \ (pat', pat_lie, pat_tvs, pat_ids, avail) ->  
      	tcExpr exp (m pat_ty)			`thenTc` \ (exp', exp_lie) ->
  	returnTc (pat', exp',
		  pat_lie `plusLIE` exp_lie,
		  pat_tvs, pat_ids, avail)
    )					`thenTc` \ (pat', exp', lie_req, pat_tvs, pat_bndrs, lie_avail) ->
    let
	new_val_env = bagToList pat_bndrs
	pat_ids     = map snd new_val_env
	pat_tv_list = bagToList pat_tvs
    in

	-- Do the rest; we don't need to add the pat_tvs to the envt
	-- because they all appear in the pat_ids's types
    tcExtendLocalValEnv new_val_env (
       tcStmts do_or_lc m stmts elt_ty
    )						`thenTc` \ (stmts', stmts_lie) ->


	-- Reinstate context for existential checks
    tcSetErrCtxt (stmtCtxt do_or_lc stmt)		$
    tcExtendGlobalTyVars (tyVarsOfType (m elt_ty))	$
    tcAddErrCtxtM (sigPatCtxt pat_tv_list pat_ids)	$

    checkSigTyVars pat_tv_list				`thenTc` \ zonked_pat_tvs ->

    tcSimplifyAndCheck 
	(text ("the existential context of a data constructor"))
	(mkVarSet zonked_pat_tvs)
	lie_avail stmts_lie			`thenTc` \ (final_lie, dict_binds) ->

    returnTc (BindStmt pat' exp' src_loc : 
	        LetStmt (MonoBind dict_binds [] Recursive) :
	          stmts',
  	      lie_req `plusLIE` final_lie)

tcStmts do_or_lc m (LetStmt binds : stmts) elt_ty
     = tcBindsAndThen		-- No error context, but a binding group is
  	combine			-- rather a large thing for an error context anyway
  	binds
  	(tcStmts do_or_lc m stmts elt_ty)
     where
      	combine is_rec binds' stmts' = LetStmt (MonoBind binds' [] is_rec) : stmts'


isDoStmt DoStmt = True
isDoStmt other  = False
\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}
sameNoOfArgs :: [RenamedMatch] -> Bool
sameNoOfArgs matches = length (nub (map args_in_match matches)) == 1
  where
    args_in_match :: RenamedMatch -> Int
    args_in_match (Match _ pats _ _) = length pats
\end{code}

\begin{code}
matchCtxt CaseAlt match
  = hang (ptext SLIT("In a case alternative:"))
	 4 (pprMatch (True,empty) {-is_case-} match)

matchCtxt (FunRhs fun) match
  = hang (hcat [ptext SLIT("In an equation for function "), quotes (ppr_fun), char ':'])
	 4 (pprMatch (False, ppr_fun) {-not case-} match)
  where
    ppr_fun = ppr fun

matchCtxt LambdaBody match
  = hang (ptext SLIT("In the lambda expression"))
	 4 (pprMatch (True, empty) match)

varyingArgsErr name matches
  = sep [ptext SLIT("Varying number of arguments for function"), quotes (ppr name)]

lurkingRank2SigErr
  = ptext SLIT("Too few explicit arguments when defining a function with a rank-2 type")

stmtCtxt do_or_lc stmt
  = hang (ptext SLIT("In") <+> what <> colon)
         4 (ppr stmt)
  where
    what = case do_or_lc of
		ListComp -> ptext SLIT("a list-comprehension qualifier")
		DoStmt   -> ptext SLIT("a do statement:")
		PatBindRhs -> thing <+> ptext SLIT("a pattern binding")
		FunRhs f   -> thing <+> ptext SLIT("an equation for") <+> quotes (ppr f)
		CaseAlt	   -> thing <+> ptext SLIT("a case alternative")
		LambdaBody -> thing <+> ptext SLIT("a lambda abstraction")
    thing = case stmt of
		BindStmt _ _ _ -> ptext SLIT("a pattern guard for")
		GuardStmt _ _  -> ptext SLIT("a guard for")
		ExprStmt _ _   -> ptext SLIT("the right-hand side of")
\end{code}