[project @ 2002-04-01 08:23:30 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcIfaceSig.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[TcIfaceSig]{Type checking of type signatures in interface files}
5
6 \begin{code}
7 module TcIfaceSig ( tcInterfaceSigs,
8                     tcDelay,
9                     tcVar,
10                     tcCoreExpr,
11                     tcCoreLamBndrs,
12                     tcCoreBinds ) where
13
14 #include "HsVersions.h"
15
16 import HsSyn            ( TyClDecl(..), HsTupCon(..) )
17 import TcMonad
18 import TcMonoType       ( tcIfaceType )
19 import TcEnv            ( RecTcEnv, tcExtendTyVarEnv, 
20                           tcExtendGlobalValEnv, tcSetEnv, tcEnvIds,
21                           tcLookupGlobal_maybe, tcLookupRecId_maybe
22                         )
23
24 import RnHsSyn          ( RenamedTyClDecl )
25 import HsCore
26 import Literal          ( Literal(..) )
27 import CoreSyn
28 import CoreUtils        ( exprType )
29 import CoreUnfold
30 import CoreLint         ( lintUnfolding )
31 import WorkWrap         ( mkWrapper )
32
33 import Id               ( Id, mkVanillaGlobal, mkLocalId, idName, isDataConWrapId_maybe )
34 import Module           ( Module )
35 import MkId             ( mkFCallId )
36 import IdInfo
37 import TyCon            ( tyConDataCons )
38 import DataCon          ( DataCon, dataConId, dataConSig, dataConArgTys )
39 import Type             ( Type, mkTyVarTys, splitTyConApp )
40 import TysWiredIn       ( tupleCon )
41 import Var              ( mkTyVar, tyVarKind )
42 import Name             ( Name, nameIsLocalOrFrom )
43 import ErrUtils         ( pprBagOfErrors )
44 import Outputable       
45 import Util             ( zipWithEqual, dropList, equalLength )
46 import HscTypes         ( TyThing(..) )
47 \end{code}
48
49 Ultimately, type signatures in interfaces will have pragmatic
50 information attached, so it is a good idea to have separate code to
51 check them.
52
53 As always, we do not have to worry about user-pragmas in interface
54 signatures.
55
56 \begin{code}
57 tcInterfaceSigs :: RecTcEnv             -- Envt to use when checking unfoldings
58                 -> Module               -- This module
59                 -> [RenamedTyClDecl]    -- Ignore non-sig-decls in these decls
60                 -> TcM [Id]
61                 
62
63 tcInterfaceSigs unf_env mod decls
64   = listTc [ do_one name ty id_infos src_loc
65            | IfaceSig {tcdName = name, tcdType = ty, tcdIdInfo = id_infos, tcdLoc =src_loc} <- decls]
66   where
67     in_scope_vars = filter (nameIsLocalOrFrom mod . idName) (tcEnvIds unf_env)
68                 -- Oops: using isLocalId instead can give a black hole
69                 -- because it looks at the idinfo
70
71         -- When we have hi-boot files, an unfolding might refer to
72         -- something defined in this module, so we must build a
73         -- suitable in-scope set.  This thunk will only be poked
74         -- if -dcore-lint is on.
75
76     do_one name ty id_infos src_loc
77       = tcAddSrcLoc src_loc                             $       
78         tcAddErrCtxt (ifaceSigCtxt name)                $
79         tcIfaceType ty                                  `thenTc` \ sigma_ty ->
80         tcIdInfo unf_env in_scope_vars name 
81                  sigma_ty id_infos                      `thenTc` \ id_info ->
82         returnTc (mkVanillaGlobal name sigma_ty id_info)
83 \end{code}
84
85 \begin{code}
86 tcIdInfo unf_env in_scope_vars name ty info_ins
87   = foldlTc tcPrag init_info info_ins 
88   where
89     -- set the CgInfo to something sensible but uninformative before
90     -- we start, because the default CgInfo is a panic.
91     init_info = vanillaIdInfo `setCgInfo` vanillaCgInfo
92
93     tcPrag info (HsNoCafRefs)   = returnTc (info `setCafInfo`    NoCafRefs)
94
95     tcPrag info (HsArity arity) = 
96         returnTc (info `setArityInfo` arity)
97
98     tcPrag info (HsUnfold inline_prag expr)
99         = tcPragExpr unf_env name in_scope_vars expr    `thenNF_Tc` \ maybe_expr' ->
100           let
101                 -- maybe_expr doesn't get looked at if the unfolding
102                 -- is never inspected; so the typecheck doesn't even happen
103                 unfold_info = case maybe_expr' of
104                                 Nothing    -> noUnfolding
105                                 Just expr' -> mkTopUnfolding expr' 
106                 info1 = info `setUnfoldingInfo` unfold_info
107                 info2 = info1 `setInlinePragInfo` inline_prag
108           in
109           returnTc info2
110
111     tcPrag info (HsStrictness strict_info)
112         = returnTc (info `setAllStrictnessInfo` Just strict_info)
113
114     tcPrag info (HsWorker nm arity)
115         = tcWorkerInfo unf_env ty info nm arity
116 \end{code}
117
118 \begin{code}
119 tcWorkerInfo unf_env ty info worker_name arity
120   = uniqSMToTcM (mkWrapper ty strict_sig) `thenNF_Tc` \ wrap_fn ->
121     let
122         -- Watch out! We can't pull on unf_env too eagerly!
123         info' = case tcLookupRecId_maybe unf_env worker_name of
124                   Just worker_id -> 
125                     info `setUnfoldingInfo`  mkTopUnfolding (wrap_fn worker_id)
126                          `setWorkerInfo`     HasWorker worker_id arity
127
128                   Nothing -> pprTrace "tcWorkerInfo failed:" 
129                                 (ppr worker_name) info
130     in
131     returnTc info'
132   where
133         -- We are relying here on strictness info always appearing 
134         -- before worker info,  fingers crossed ....
135       strict_sig = case newStrictnessInfo info of
136                         Just sig -> sig
137                         Nothing  -> pprPanic "Worker info but no strictness for" (ppr worker_name)
138 \end{code}
139
140 For unfoldings we try to do the job lazily, so that we never type check
141 an unfolding that isn't going to be looked at.
142
143 \begin{code}
144 tcPragExpr unf_env name in_scope_vars expr
145   = tcDelay unf_env doc Nothing $
146         tcCoreExpr expr         `thenTc` \ core_expr' ->
147
148                 -- Check for type consistency in the unfolding
149         tcGetSrcLoc             `thenNF_Tc` \ src_loc -> 
150         getDOptsTc              `thenNF_Tc` \ dflags ->
151         case lintUnfolding dflags src_loc in_scope_vars core_expr' of
152           (Nothing,_)       -> returnTc (Just core_expr')  -- ignore warnings
153           (Just fail_msg,_) -> failWithTc ((doc <+> text "failed Lint") $$ fail_msg)
154   where
155     doc = text "unfolding of" <+> ppr name
156
157 tcDelay :: RecTcEnv -> SDoc -> a -> TcM a -> NF_TcM a
158 tcDelay unf_env doc bad_ans thing_inside
159   = forkNF_Tc (
160         recoverNF_Tc bad_value (
161                 tcSetEnv unf_env thing_inside
162     ))                  
163   where
164         -- The trace tells what wasn't available, for the benefit of
165         -- compiler hackers who want to improve it!
166     bad_value = getErrsTc               `thenNF_Tc` \ (warns,errs) ->
167                 returnNF_Tc (pprTrace "Failed:" 
168                                          (hang doc 4 (pprBagOfErrors errs))
169                                          bad_ans)
170 \end{code}
171
172
173 Variables in unfoldings
174 ~~~~~~~~~~~~~~~~~~~~~~~
175 ****** Inside here we use only the Global environment, even for locally bound variables.
176 ****** Why? Because we know all the types and want to bind them to real Ids.
177
178 \begin{code}
179 tcVar :: Name -> TcM Id
180 tcVar name
181   = tcLookupGlobal_maybe name   `thenNF_Tc` \ maybe_id ->
182     case maybe_id of {
183         Just (AnId id)  -> returnTc id ;
184         Nothing         -> failWithTc (noDecl name)
185     }
186
187 noDecl name = hsep [ptext SLIT("Warning: no binding for"), ppr name]
188 \end{code}
189
190 UfCore expressions.
191
192 \begin{code}
193 tcCoreExpr :: UfExpr Name -> TcM CoreExpr
194
195 tcCoreExpr (UfType ty)
196   = tcIfaceType ty              `thenTc` \ ty' ->
197         -- It might not be of kind type
198     returnTc (Type ty')
199
200 tcCoreExpr (UfVar name)
201   = tcVar name  `thenTc` \ id ->
202     returnTc (Var id)
203
204 tcCoreExpr (UfLit lit)
205   = returnTc (Lit lit)
206
207 -- The dreaded lit-lits are also similar, except here the type
208 -- is read in explicitly rather than being implicit
209 tcCoreExpr (UfLitLit lit ty)
210   = tcIfaceType ty              `thenTc` \ ty' ->
211     returnTc (Lit (MachLitLit lit ty'))
212
213 tcCoreExpr (UfFCall cc ty)
214   = tcIfaceType ty      `thenTc` \ ty' ->
215     tcGetUnique         `thenNF_Tc` \ u ->
216     returnTc (Var (mkFCallId u cc ty'))
217
218 tcCoreExpr (UfTuple (HsTupCon _ boxity arity) args) 
219   = mapTc tcCoreExpr args       `thenTc` \ args' ->
220     let
221         -- Put the missing type arguments back in
222         con_args = map (Type . exprType) args' ++ args'
223     in
224     returnTc (mkApps (Var con_id) con_args)
225   where
226     con_id = dataConWorkId (tupleCon boxity arity)
227     
228
229 tcCoreExpr (UfLam bndr body)
230   = tcCoreLamBndr bndr          $ \ bndr' ->
231     tcCoreExpr body             `thenTc` \ body' ->
232     returnTc (Lam bndr' body')
233
234 tcCoreExpr (UfApp fun arg)
235   = tcCoreExpr fun              `thenTc` \ fun' ->
236     tcCoreExpr arg              `thenTc` \ arg' ->
237     returnTc (App fun' arg')
238
239 tcCoreExpr (UfCase scrut case_bndr alts) 
240   = tcCoreExpr scrut                                    `thenTc` \ scrut' ->
241     let
242         scrut_ty = exprType scrut'
243         case_bndr' = mkLocalId case_bndr scrut_ty
244     in
245     tcExtendGlobalValEnv [case_bndr']   $
246     mapTc (tcCoreAlt scrut_ty) alts     `thenTc` \ alts' ->
247     returnTc (Case scrut' case_bndr' alts')
248
249 tcCoreExpr (UfLet (UfNonRec bndr rhs) body)
250   = tcCoreExpr rhs              `thenTc` \ rhs' ->
251     tcCoreValBndr bndr          $ \ bndr' ->
252     tcCoreExpr body             `thenTc` \ body' ->
253     returnTc (Let (NonRec bndr' rhs') body')
254
255 tcCoreExpr (UfLet (UfRec pairs) body)
256   = tcCoreValBndrs bndrs        $ \ bndrs' ->
257     mapTc tcCoreExpr rhss       `thenTc` \ rhss' ->
258     tcCoreExpr body             `thenTc` \ body' ->
259     returnTc (Let (Rec (bndrs' `zip` rhss')) body')
260   where
261     (bndrs, rhss) = unzip pairs
262
263 tcCoreExpr (UfNote note expr) 
264   = tcCoreExpr expr             `thenTc` \ expr' ->
265     case note of
266         UfCoerce to_ty -> tcIfaceType to_ty     `thenTc` \ to_ty' ->
267                           returnTc (Note (Coerce to_ty'
268                                                  (exprType expr')) expr')
269         UfInlineCall   -> returnTc (Note InlineCall expr')
270         UfInlineMe     -> returnTc (Note InlineMe   expr')
271         UfSCC cc       -> returnTc (Note (SCC cc)   expr')
272 \end{code}
273
274 \begin{code}
275 tcCoreLamBndr (UfValBinder name ty) thing_inside
276   = tcIfaceType ty              `thenTc` \ ty' ->
277     let
278         id = mkLocalId name ty'
279     in
280     tcExtendGlobalValEnv [id] $
281     thing_inside id
282     
283 tcCoreLamBndr (UfTyBinder name kind) thing_inside
284   = let
285         tyvar = mkTyVar name kind
286     in
287     tcExtendTyVarEnv [tyvar] (thing_inside tyvar)
288     
289 tcCoreLamBndrs []     thing_inside = thing_inside []
290 tcCoreLamBndrs (b:bs) thing_inside
291   = tcCoreLamBndr b     $ \ b' ->
292     tcCoreLamBndrs bs   $ \ bs' ->
293     thing_inside (b':bs')
294
295 tcCoreValBndr (UfValBinder name ty) thing_inside
296   = tcIfaceType ty                      `thenTc` \ ty' ->
297     let
298         id = mkLocalId name ty'
299     in
300     tcExtendGlobalValEnv [id] $
301     thing_inside id
302     
303 tcCoreValBndrs bndrs thing_inside               -- Expect them all to be ValBinders
304   = mapTc tcIfaceType tys               `thenTc` \ tys' ->
305     let
306         ids = zipWithEqual "tcCoreValBndr" mkLocalId names tys'
307     in
308     tcExtendGlobalValEnv ids $
309     thing_inside ids
310   where
311     names = [name | UfValBinder name _  <- bndrs]
312     tys   = [ty   | UfValBinder _    ty <- bndrs]
313 \end{code}    
314
315 \begin{code}
316 tcCoreAlt scrut_ty (UfDefault, names, rhs)
317   = ASSERT( null names )
318     tcCoreExpr rhs              `thenTc` \ rhs' ->
319     returnTc (DEFAULT, [], rhs')
320   
321 tcCoreAlt scrut_ty (UfLitAlt lit, names, rhs)
322   = ASSERT( null names )
323     tcCoreExpr rhs              `thenTc` \ rhs' ->
324     returnTc (LitAlt lit, [], rhs')
325
326 tcCoreAlt scrut_ty (UfLitLitAlt str ty, names, rhs)
327   = ASSERT( null names )
328     tcCoreExpr rhs              `thenTc` \ rhs' ->
329     tcIfaceType ty              `thenTc` \ ty' ->
330     returnTc (LitAlt (MachLitLit str ty'), [], rhs')
331
332 -- A case alternative is made quite a bit more complicated
333 -- by the fact that we omit type annotations because we can
334 -- work them out.  True enough, but its not that easy!
335 tcCoreAlt scrut_ty alt@(con, names, rhs)
336   = tcConAlt con        `thenTc` \ con ->
337     let
338         ex_tyvars         = dataConExistentialTyVars con
339         (tycon, inst_tys) = splitTyConApp scrut_ty      -- NB: not tcSplitTyConApp
340                                                         -- We are looking at Core here
341         main_tyvars       = tyConTyVars tycon
342         ex_tyvars'        = [mkTyVar name (tyVarKind tv) | (name,tv) <- names `zip` ex_tyvars] 
343         ex_tys'           = mkTyVarTys ex_tyvars'
344         arg_tys           = dataConArgTys con (inst_tys ++ ex_tys')
345         id_names          = dropList ex_tyvars names
346         arg_ids
347 #ifdef DEBUG
348                 | not (equalLength id_names arg_tys)
349                 = pprPanic "tcCoreAlts" (ppr (con, names, rhs) $$
350                                          (ppr main_tyvars <+> ppr ex_tyvars) $$
351                                          ppr arg_tys)
352                 | otherwise
353 #endif
354                 = zipWithEqual "tcCoreAlts" mkLocalId id_names arg_tys
355     in
356     ASSERT( con `elem` tyConDataCons tycon && equalLength inst_tys main_tyvars )
357     tcExtendTyVarEnv ex_tyvars'                 $
358     tcExtendGlobalValEnv arg_ids                $
359     tcCoreExpr rhs                                      `thenTc` \ rhs' ->
360     returnTc (DataAlt con, ex_tyvars' ++ arg_ids, rhs')
361
362
363 tcConAlt :: UfConAlt Name -> TcM DataCon
364 tcConAlt (UfTupleAlt (HsTupCon _ boxity arity))
365   = returnTc (tupleCon boxity arity)
366
367 tcConAlt (UfDataAlt con_name)
368   = tcVar con_name      `thenTc` \ con_id ->
369     returnTc (case isDataConWrapId_maybe con_id of
370                     Just con -> con
371                     Nothing  -> pprPanic "tcCoreAlt" (ppr con_id))
372 \end{code}
373
374 %************************************************************************
375 %*                                                                      *
376 \subsection{Core decls}
377 %*                                                                      *
378 %************************************************************************
379
380
381 \begin{code}
382 tcCoreBinds :: [RenamedTyClDecl]
383             -> TcM [(Id, Type, CoreExpr)]
384 tcCoreBinds ls = mapTc tcOne ls
385  where
386   tcOne (CoreDecl { tcdName = nm, tcdType = ty, tcdRhs = rhs }) =
387    tcVar nm         `thenTc` \ i ->
388    tcIfaceType ty   `thenTc` \ ty' ->
389    tcCoreExpr  rhs  `thenTc` \ rhs' ->
390    returnTc (i,ty',rhs')
391
392 \end{code}
393
394
395
396 \begin{code}
397 ifaceSigCtxt sig_name
398   = hsep [ptext SLIT("In an interface-file signature for"), ppr sig_name]
399 \end{code}
400