2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[TcPat]{Typechecking patterns}
7 #include "HsVersions.h"
9 module TcPat ( tcPat ) where
13 import HsSyn ( InPat(..), OutPat(..), HsExpr(..), HsLit(..),
14 Match, HsBinds, HsType, Fixity,
15 ArithSeqInfo, Stmt, DoOrListComp, Fake )
16 import RnHsSyn ( SYN_IE(RenamedPat) )
17 import TcHsSyn ( SYN_IE(TcPat), TcIdOcc(..) )
20 import Inst ( Inst, OverloadedLit(..), InstOrigin(..),
21 emptyLIE, plusLIE, plusLIEs, SYN_IE(LIE),
22 newMethod, newOverloadedLit
24 import Name ( Name {- instance Outputable -} )
25 import TcEnv ( tcLookupGlobalValue, tcLookupGlobalValueByKey,
26 tcLookupLocalValueOK )
27 import SpecEnv ( SpecEnv )
28 import TcType ( SYN_IE(TcType), TcMaybe, newTyVarTy, newTyVarTys, tcInstId )
29 import Unify ( unifyTauTy, unifyTauTyList, unifyTauTyLists )
32 import CmdLineOpts ( opt_IrrefutableTuples )
33 import Id ( GenId, idType, SYN_IE(Id) )
34 import Kind ( Kind, mkBoxedTypeKind, mkTypeKind )
35 import Maybes ( maybeToBool )
36 import PprType ( GenType, GenTyVar )
37 --import PprStyle--ToDo:rm
39 import Type ( splitFunTy, splitRhoTy, splitSigmaTy, mkTyVarTys,
40 getFunTy_maybe, maybeAppDataTyCon,
43 import TyVar ( GenTyVar )
44 import TysPrim ( charPrimTy, intPrimTy, floatPrimTy,
45 doublePrimTy, addrPrimTy
47 import TysWiredIn ( charTy, stringTy, mkListTy, mkTupleTy, addrTy )
48 import Unique ( Unique, eqClassOpKey, geClassOpKey, minusClassOpKey )
49 import Util ( assertPanic, panic )
51 #if __GLASGOW_HASKELL__ >= 202
57 tcPat :: RenamedPat -> TcM s (TcPat s, LIE s, TcType s)
60 %************************************************************************
62 \subsection{Variables, wildcards, lazy pats, as-pats}
64 %************************************************************************
68 = tcLookupLocalValueOK ("tcPat1:"{-++show (ppr PprDebug name)-}) name `thenNF_Tc` \ id ->
69 returnTc (VarPat (TcId id), emptyLIE, idType id)
72 = tcPat pat `thenTc` \ (pat', lie, ty) ->
73 returnTc (LazyPat pat', lie, ty)
75 tcPat pat_in@(AsPatIn name pat)
76 = tcLookupLocalValueOK "tcPat2" name `thenNF_Tc` \ id ->
77 tcPat pat `thenTc` \ (pat', lie, ty) ->
78 tcAddErrCtxt (patCtxt pat_in) $
79 unifyTauTy (idType id) ty `thenTc_`
80 returnTc (AsPat (TcId id) pat', lie, ty)
83 = newTyVarTy mkTypeKind `thenNF_Tc` \ tyvar_ty ->
84 returnTc (WildPat tyvar_ty, emptyLIE, tyvar_ty)
87 = tcPat (negate_lit pat)
89 negate_lit (LitPatIn (HsInt i)) = LitPatIn (HsInt (-i))
90 negate_lit (LitPatIn (HsFrac f)) = LitPatIn (HsFrac (-f))
91 negate_lit _ = panic "TcPat:negate_pat"
93 tcPat (ParPatIn parend_pat)
97 %************************************************************************
99 \subsection{Explicit lists and tuples}
101 %************************************************************************
104 tcPat pat_in@(ListPatIn pats)
105 = tcPats pats `thenTc` \ (pats', lie, tys) ->
106 newTyVarTy mkBoxedTypeKind `thenNF_Tc` \ tyvar_ty ->
107 tcAddErrCtxt (patCtxt pat_in) $
108 unifyTauTyList (tyvar_ty:tys) `thenTc_`
110 returnTc (ListPat tyvar_ty pats', lie, mkListTy tyvar_ty)
112 tcPat pat_in@(TuplePatIn pats)
116 tcPats pats `thenTc` \ (pats', lie, tys) ->
118 -- Make sure we record that the tuples can only contain boxed types
119 newTyVarTys arity mkBoxedTypeKind `thenNF_Tc` \ tyvar_tys ->
121 tcAddErrCtxt (patCtxt pat_in) $
122 unifyTauTyLists tyvar_tys tys `thenTc_`
124 -- possibly do the "make all tuple-pats irrefutable" test:
126 unmangled_result = TuplePat pats'
128 -- Under flag control turn a pattern (x,y,z) into ~(x,y,z)
129 -- so that we can experiment with lazy tuple-matching.
130 -- This is a pretty odd place to make the switch, but
131 -- it was easy to do.
133 possibly_mangled_result
134 = if opt_IrrefutableTuples
135 then LazyPat unmangled_result
136 else unmangled_result
138 -- ToDo: IrrefutableEverything
140 returnTc (possibly_mangled_result, lie, mkTupleTy arity tys)
143 %************************************************************************
145 \subsection{Other constructors}
147 %************************************************************************
149 Constructor patterns are a little fun:
152 typecheck the arguments
154 look up the constructor
156 specialise its type (ignore the translation this produces)
158 check that the context produced by this specialisation is empty
160 get the arguments out of the function type produced from specialising
162 unify them with the types of the patterns
164 back substitute with the type of the result of the constructor
167 ToDo: exploit new representation of constructors to make this more
171 tcPat pat_in@(ConPatIn name pats)
172 = tcPats pats `thenTc` \ (pats', lie, tys) ->
174 tcAddErrCtxt (patCtxt pat_in) $
175 matchConArgTys name tys `thenTc` \ (con_id, data_ty) ->
177 returnTc (ConPat con_id data_ty pats',
181 tcPat pat_in@(ConOpPatIn pat1 op _ pat2) -- in binary-op form...
182 = tcPat pat1 `thenTc` \ (pat1', lie1, ty1) ->
183 tcPat pat2 `thenTc` \ (pat2', lie2, ty2) ->
185 tcAddErrCtxt (patCtxt pat_in) $
186 matchConArgTys op [ty1,ty2] `thenTc` \ (con_id, data_ty) ->
188 returnTc (ConOpPat pat1' con_id pat2' data_ty,
193 %************************************************************************
197 %************************************************************************
200 tcPat pat_in@(RecPatIn name rpats)
201 = tcLookupGlobalValue name `thenNF_Tc` \ con_id ->
202 tcInstId con_id `thenNF_Tc` \ (_, _, con_tau) ->
204 -- Ignore the con_theta; overloaded constructors only
205 -- behave differently when called, not when used for
207 (_, record_ty) = splitFunTy con_tau
209 -- Con is syntactically constrained to be a data constructor
210 ASSERT( maybeToBool (maybeAppDataTyCon record_ty) )
212 mapAndUnzipTc (do_bind record_ty) rpats `thenTc` \ (rpats', lies) ->
214 returnTc (RecPat con_id record_ty rpats',
219 do_bind expected_record_ty (field_label, rhs_pat, pun_flag)
220 = tcLookupGlobalValue field_label `thenNF_Tc` \ sel_id ->
221 tcInstId sel_id `thenNF_Tc` \ (_, _, tau) ->
223 -- Record selectors all have type
224 -- forall a1..an. T a1 .. an -> tau
225 ASSERT( maybeToBool (getFunTy_maybe tau) )
227 -- Selector must have type RecordType -> FieldType
228 Just (record_ty, field_ty) = getFunTy_maybe tau
230 tcAddErrCtxt (recordLabel field_label) (
231 unifyTauTy expected_record_ty record_ty
233 tcPat rhs_pat `thenTc` \ (rhs_pat', lie, rhs_ty) ->
234 tcAddErrCtxt (recordRhs field_label rhs_pat) (
235 unifyTauTy field_ty rhs_ty
237 returnTc ((sel_id, rhs_pat', pun_flag), lie)
240 %************************************************************************
242 \subsection{Non-overloaded literals}
244 %************************************************************************
247 tcPat (LitPatIn lit@(HsChar str))
248 = returnTc (LitPat lit charTy, emptyLIE, charTy)
250 tcPat (LitPatIn lit@(HsString str))
251 = tcLookupGlobalValueByKey eqClassOpKey `thenNF_Tc` \ sel_id ->
252 newMethod (LiteralOrigin lit)
253 (RealId sel_id) [stringTy] `thenNF_Tc` \ (lie, eq_id) ->
255 comp_op = HsApp (HsVar eq_id) (HsLitOut lit stringTy)
257 returnTc (NPat lit stringTy comp_op, lie, stringTy)
259 tcPat (LitPatIn lit@(HsIntPrim _))
260 = returnTc (LitPat lit intPrimTy, emptyLIE, intPrimTy)
261 tcPat (LitPatIn lit@(HsCharPrim _))
262 = returnTc (LitPat lit charPrimTy, emptyLIE, charPrimTy)
263 tcPat (LitPatIn lit@(HsStringPrim _))
264 = returnTc (LitPat lit addrPrimTy, emptyLIE, addrPrimTy)
265 tcPat (LitPatIn lit@(HsFloatPrim _))
266 = returnTc (LitPat lit floatPrimTy, emptyLIE, floatPrimTy)
267 tcPat (LitPatIn lit@(HsDoublePrim _))
268 = returnTc (LitPat lit doublePrimTy, emptyLIE, doublePrimTy)
271 %************************************************************************
273 \subsection{Overloaded patterns: int literals and \tr{n+k} patterns}
275 %************************************************************************
278 tcPat (LitPatIn lit@(HsInt i))
279 = newTyVarTy mkBoxedTypeKind `thenNF_Tc` \ tyvar_ty ->
280 newOverloadedLit origin
281 (OverloadedIntegral i) tyvar_ty `thenNF_Tc` \ (lie1, over_lit_id) ->
283 tcLookupGlobalValueByKey eqClassOpKey `thenNF_Tc` \ eq_sel_id ->
284 newMethod origin (RealId eq_sel_id) [tyvar_ty] `thenNF_Tc` \ (lie2, eq_id) ->
286 returnTc (NPat lit tyvar_ty (HsApp (HsVar eq_id)
287 (HsVar over_lit_id)),
291 origin = LiteralOrigin lit
293 tcPat (LitPatIn lit@(HsFrac f))
294 = newTyVarTy mkBoxedTypeKind `thenNF_Tc` \ tyvar_ty ->
295 newOverloadedLit origin
296 (OverloadedFractional f) tyvar_ty `thenNF_Tc` \ (lie1, over_lit_id) ->
298 tcLookupGlobalValueByKey eqClassOpKey `thenNF_Tc` \ eq_sel_id ->
299 newMethod origin (RealId eq_sel_id) [tyvar_ty] `thenNF_Tc` \ (lie2, eq_id) ->
301 returnTc (NPat lit tyvar_ty (HsApp (HsVar eq_id)
302 (HsVar over_lit_id)),
306 origin = LiteralOrigin lit
308 tcPat (LitPatIn lit@(HsLitLit s))
309 = error "tcPat: can't handle ``literal-literal'' patterns"
311 tcPat (NPlusKPatIn name lit@(HsInt i))
312 = tcLookupLocalValueOK "tcPat1:n+k" name `thenNF_Tc` \ local ->
314 local_ty = idType local
316 tcLookupGlobalValueByKey geClassOpKey `thenNF_Tc` \ ge_sel_id ->
317 tcLookupGlobalValueByKey minusClassOpKey `thenNF_Tc` \ minus_sel_id ->
319 newOverloadedLit origin
320 (OverloadedIntegral i) local_ty `thenNF_Tc` \ (lie1, over_lit_id) ->
322 newMethod origin (RealId ge_sel_id) [local_ty] `thenNF_Tc` \ (lie2, ge_id) ->
323 newMethod origin (RealId minus_sel_id) [local_ty] `thenNF_Tc` \ (lie3, minus_id) ->
325 returnTc (NPlusKPat (TcId local) lit local_ty
326 (SectionR (HsVar ge_id) (HsVar over_lit_id))
327 (SectionR (HsVar minus_id) (HsVar over_lit_id)),
328 lie1 `plusLIE` lie2 `plusLIE` lie3,
331 origin = LiteralOrigin lit -- Not very good!
333 tcPat (NPlusKPatIn pat other) = panic "TcPat:NPlusKPat: not an HsInt literal"
336 %************************************************************************
338 \subsection{Lists of patterns}
340 %************************************************************************
343 tcPats :: [RenamedPat] -> TcM s ([TcPat s], LIE s, [TcType s])
345 tcPats [] = returnTc ([], emptyLIE, [])
348 = tcPat pat `thenTc` \ (pat', lie, ty) ->
349 tcPats pats `thenTc` \ (pats', lie', tys) ->
351 returnTc (pat':pats', plusLIE lie lie', ty:tys)
354 @matchConArgTys@ grabs the signature of the data constructor, and
355 unifies the actual args against the expected ones.
358 matchConArgTys :: Name -> [TcType s] -> TcM s (Id, TcType s)
360 matchConArgTys con arg_tys
361 = tcLookupGlobalValue con `thenNF_Tc` \ con_id ->
362 tcInstId con_id `thenNF_Tc` \ (_, _, con_tau) ->
363 -- Ignore the con_theta; overloaded constructors only
364 -- behave differently when called, not when used for
367 (con_args, con_result) = splitFunTy con_tau
368 con_arity = length con_args
369 no_of_args = length arg_tys
371 checkTc (con_arity == no_of_args)
372 (arityErr "Constructor" con_id con_arity no_of_args) `thenTc_`
374 unifyTauTyLists con_args arg_tys `thenTc_`
375 returnTc (con_id, con_result)
379 % =================================================
384 patCtxt pat sty = hang (ptext SLIT("In the pattern:")) 4 (ppr sty pat)
386 recordLabel field_label sty
387 = hang (hcat [ptext SLIT("When matching record field"), ppr sty field_label])
388 4 (hcat [ptext SLIT("with its immediately enclosing constructor")])
390 recordRhs field_label pat sty
391 = hang (ptext SLIT("In the record field pattern"))
392 4 (sep [ppr sty field_label, char '=', ppr sty pat])