2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1994
4 \section[TcMatches]{Typecheck some @Matches@}
7 #include "HsVersions.h"
9 module TcMatches ( tcMatchesFun, tcMatchesCase, tcMatch ) where
11 import TcMonad -- typechecking monad machinery
12 import TcMonadFns ( mkIdsWithOpenTyVarTys )
13 import AbsSyn -- the stuff being typechecked
15 import AbsPrel ( mkFunTy )
16 import AbsUniType ( isTyVarTy, maybeUnpackFunTy )
17 import E ( E, growE_LVE, LVE(..), GVE(..) )
18 #if USE_ATTACK_PRAGMAS
22 import Errors ( varyingArgsErr, Error(..), UnifyErrContext(..) )
23 import LIE ( LIE, plusLIE )
24 import Maybes ( Maybe(..) )
25 import TcGRHSs ( tcGRHSsAndBinds )
26 import TcPat ( tcPat )
27 import Unify ( unifyTauTy, unifyTauTyList )
31 @tcMatchesFun@ typechecks a @[Match]@ list which occurs in a
32 @FunMonoBind@. The second argument is the name of the function, which
33 is used in error messages. It checks that all the equations have the
34 same number of arguments before using @tcMatches@ to do the work.
37 tcMatchesFun :: E -> Name
38 -> UniType -- Expected type
40 -> TcM ([TypecheckedMatch], LIE)
42 tcMatchesFun e fun_name expected_ty matches@(first_match:_)
43 = -- Set the location to that of the first equation, so that
44 -- any inter-equation error messages get some vaguely
45 -- sensible location. Note: we have to do this odd
46 -- ann-grabbing, because we don't always have annotations in
47 -- hand when we call tcMatchesFun...
49 addSrcLocTc (get_Match_loc first_match) (
51 -- Check that they all have the same no of arguments
52 checkTc (not (all_same (noOfArgs matches)))
53 (varyingArgsErr fun_name matches) `thenTc_`
55 -- ToDo: Don't use "expected" stuff if there ain't a type signature
56 -- because inconsistency between branches
57 -- may show up as something wrong with the (non-existent) type signature
59 -- We need to substitute so that we can see as much about the type as possible
60 applyTcSubstToTy expected_ty `thenNF_Tc` \ expected_ty' ->
61 tcMatchesExpected e expected_ty' (\ m -> FunMonoBindsCtxt fun_name [m]) matches
65 all_same :: [Int] -> Bool
66 all_same [] = True -- Should never happen (ToDo: panic?)
68 all_same (x:xs) = all ((==) x) xs
71 @tcMatchesCase@ doesn't do the argument-count check because the
72 parser guarantees that each equation has exactly one argument.
75 tcMatchesCase :: E -> [RenamedMatch]
76 -> TcM ([TypecheckedMatch], LIE, UniType)
78 tcMatchesCase e matches
82 tcMatches e matches `thenTc` \ (matches', lie, tys@(first_ty:_)) ->
84 -- Set the location to that of the first equation, so that
85 -- any inter-equation error messages get some vaguely sensible location
86 addSrcLocTc (get_Match_loc (head matches)) (
87 unifyTauTyList tys (CaseBranchesCtxt matches)
90 returnTc (matches', lie, first_ty)
95 tcMatchesExpected :: E
97 -> (RenamedMatch -> UnifyErrContext)
99 -> TcM ([TypecheckedMatch], LIE)
101 tcMatchesExpected e expected_ty err_ctxt_fn [match]
102 = addSrcLocTc (get_Match_loc match) (
103 tcMatchExpected e expected_ty (err_ctxt_fn match) match
104 ) `thenTc` \ (match', lie) ->
105 returnTc ([match'], lie)
107 tcMatchesExpected e expected_ty err_ctxt_fn ms@(match1 : matches)
108 = addSrcLocTc (get_Match_loc match1) (
109 tcMatchExpected e expected_ty (err_ctxt_fn match1) match1
110 ) `thenTc` \ (match1', lie1) ->
111 tcMatchesExpected e expected_ty err_ctxt_fn matches `thenTc` \ (matches', lie2) ->
112 returnTc (match1' : matches', plusLIE lie1 lie2)
114 tcMatches :: E -> [RenamedMatch] -> TcM ([TypecheckedMatch], LIE, [UniType])
117 = tcMatch e match `thenTc` \ (match', lie, ty) ->
118 returnTc ([match'], lie, [ty])
120 tcMatches e ms@(match1 : matches)
121 = addSrcLocTc (get_Match_loc match1) (
123 ) `thenTc` \ (match1', lie1, match1_ty) ->
124 tcMatches e matches `thenTc` \ (matches', lie2, matches_ty) ->
125 returnTc (match1' : matches', plusLIE lie1 lie2, match1_ty : matches_ty)
131 -> UniType -- This gives the expected
132 -- result-type of the Match. Early unification
133 -- with this guy gives better error messages
136 -> TcM (TypecheckedMatch,LIE)
137 -- NB No type returned, because it was passed
140 tcMatchExpected e expected_ty err_ctxt the_match@(PatMatch pat match)
141 = case maybeUnpackFunTy expected_ty of
143 Nothing -> -- Not a function type (eg type variable)
144 -- So use tcMatch instead
145 tcMatch e the_match `thenTc` \ (match', lie_match, match_ty) ->
146 unifyTauTy match_ty expected_ty err_ctxt `thenTc_`
147 returnTc (match', lie_match)
149 Just (arg_ty,rest_ty) -> -- It's a function type!
150 let binders = collectPatBinders pat
152 mkIdsWithOpenTyVarTys binders `thenNF_Tc` \ lve ->
153 let e' = growE_LVE e lve
155 tcPat e' pat `thenTc` \ (pat', lie_pat, pat_ty) ->
157 unifyTauTy arg_ty pat_ty err_ctxt `thenTc_`
158 tcMatchExpected e' rest_ty err_ctxt match `thenTc` \ (match', lie_match) ->
159 returnTc (PatMatch pat' match',
160 plusLIE lie_pat lie_match)
162 tcMatchExpected e expected_ty err_ctxt (GRHSMatch grhss_and_binds)
163 = tcGRHSsAndBinds e grhss_and_binds `thenTc` \ (grhss_and_binds', lie, grhss_ty) ->
164 unifyTauTy grhss_ty expected_ty err_ctxt `thenTc_`
165 returnTc (GRHSMatch grhss_and_binds', lie)
169 -> TcM (TypecheckedMatch,LIE,UniType)
171 tcMatch e (PatMatch pat match)
172 = let binders = collectPatBinders pat
174 mkIdsWithOpenTyVarTys binders `thenNF_Tc` \ lve ->
175 let e' = growE_LVE e lve
177 tcPat e' pat `thenTc` \ (pat', lie_pat, pat_ty) ->
178 tcMatch e' match `thenTc` \ (match', lie_match, match_ty) ->
180 -- We don't do this any more, do we?
181 -- applyTcSubstToTy pat_ty `thenNF_Tc`\ pat_ty' ->
183 returnTc (PatMatch pat' match',
184 plusLIE lie_pat lie_match,
185 mkFunTy pat_ty match_ty)
187 tcMatch e (GRHSMatch grhss_and_binds)
188 = tcGRHSsAndBinds e grhss_and_binds `thenTc` \ (grhss_and_binds', lie, grhss_ty) ->
189 returnTc (GRHSMatch grhss_and_binds', lie, grhss_ty)
193 @noOfArgs@ takes a @[RenamedMatch]@ and returns a list telling how
194 many arguments were used in each of the equations. This is used to
195 report a sensible error message when different equations have
196 different numbers of arguments.
199 noOfArgs :: [RenamedMatch] -> [Int]
201 noOfArgs ms = map args_in_match ms
203 args_in_match :: RenamedMatch -> Int
204 args_in_match (GRHSMatch _) = 0
205 args_in_match (PatMatch _ match) = 1 + args_in_match match
208 @get_Match_loc@ takes a @RenamedMatch@ and returns the
209 source-location gotten from the GRHS inside.
210 THis is something of a nuisance, but no more.
213 get_Match_loc :: RenamedMatch -> SrcLoc
215 get_Match_loc (PatMatch _ m) = get_Match_loc m
216 get_Match_loc (GRHSMatch (GRHSsAndBindsIn (g:_) _))
219 get_GRHS_loc (OtherwiseGRHS _ locn) = locn
220 get_GRHS_loc (GRHS _ _ locn) = locn