[project @ 1998-05-13 09:32:34 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcIfaceSig.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[TcIfaceSig]{Type checking of type signatures in interface files}
5
6 \begin{code}
7 module TcIfaceSig ( tcInterfaceSigs ) where
8
9 #include "HsVersions.h"
10
11 import HsSyn            ( HsDecl(..), IfaceSig(..) )
12 import TcMonad
13 import TcMonoType       ( tcHsType, tcHsTypeKind, tcTyVarScope )
14 import TcEnv            ( tcExtendTyVarEnv, tcExtendGlobalValEnv, tcSetGlobalValEnv,
15                           tcLookupTyConByKey, tcLookupGlobalValueMaybe,
16                           tcExplicitLookupGlobal,
17                           GlobalValueEnv
18                         )
19 import TcKind           ( TcKind, kindToTcKind )
20
21 import RnHsSyn          ( RenamedHsDecl )
22 import HsCore
23 import HsDecls          ( HsIdInfo(..), HsStrictnessInfo(..) )
24 import Literal          ( Literal(..) )
25 import CoreSyn
26 import CoreUtils        ( coreExprType )
27 import CoreUnfold
28 import MagicUFs         ( MagicUnfoldingFun )
29 import WwLib            ( mkWrapper )
30 import PrimOp           ( PrimOp(..) )
31
32 import MkId             ( mkImportedId, mkUserId )
33 import Id               ( Id, addInlinePragma, isPrimitiveId_maybe, dataConArgTys )
34 import IdInfo
35 import SpecEnv          ( addToSpecEnv )
36 import Type             ( mkSynTy, splitAlgTyConApp )
37 import TyVar            ( mkSysTyVar )
38 import Name             ( Name )
39 import Unique           ( rationalTyConKey, uniqueOf )
40 import TysWiredIn       ( integerTy )
41 import ErrUtils         ( pprBagOfErrors )
42 import Maybes           ( maybeToBool, MaybeErr(..) )
43 import Outputable       
44 import Util             ( zipWithEqual )
45
46 \end{code}
47
48 Ultimately, type signatures in interfaces will have pragmatic
49 information attached, so it is a good idea to have separate code to
50 check them.
51
52 As always, we do not have to worry about user-pragmas in interface
53 signatures.
54
55 \begin{code}
56 tcInterfaceSigs :: GlobalValueEnv       -- Envt to use when checking unfoldings
57                 -> [RenamedHsDecl]      -- Ignore non-sig-decls in these decls
58                 -> TcM s [Id]
59                 
60
61 tcInterfaceSigs unf_env (SigD (IfaceSig name ty id_infos src_loc) : rest)
62   = tcAddSrcLoc src_loc (
63     tcAddErrCtxt (ifaceSigCtxt name) (
64         tcHsType ty                                             `thenTc` \ sigma_ty ->
65         tcIdInfo unf_env name sigma_ty noIdInfo id_infos        `thenTc` \ id_info ->
66         returnTc (mkImportedId name sigma_ty id_info)
67     ))                                          `thenTc` \ sig_id ->
68     tcInterfaceSigs unf_env rest                `thenTc` \ sig_ids ->
69     returnTc (sig_id : sig_ids)
70
71 tcInterfaceSigs unf_env (other_decl : rest) = tcInterfaceSigs unf_env rest
72
73 tcInterfaceSigs unf_env [] = returnTc []
74 \end{code}
75
76 \begin{code}
77 tcIdInfo unf_env name ty info info_ins
78   = foldlTc tcPrag noIdInfo info_ins
79   where
80     tcPrag info (HsArity arity) = returnTc (arity `setArityInfo` info)
81     tcPrag info (HsUpdate upd)  = returnTc (upd   `setUpdateInfo` info)
82     tcPrag info (HsFBType fb)   = returnTc (fb    `setFBTypeInfo` info)
83     tcPrag info (HsArgUsage au) = returnTc (au    `setArgUsageInfo` info)
84
85     tcPrag info (HsUnfold inline expr)
86         = tcPragExpr unf_env name expr  `thenNF_Tc` \ maybe_expr' ->
87           let
88                 -- maybe_expr doesn't get looked at if the unfolding
89                 -- is never inspected; so the typecheck doesn't even happen
90                 unfold_info = case maybe_expr' of
91                                 Nothing    -> NoUnfolding
92                                 Just expr' -> mkUnfolding expr' 
93                 info1 = unfold_info `setUnfoldingInfo` info
94
95                 info2 | inline    = IWantToBeINLINEd `setInlinePragInfo` info1
96                       | otherwise = info1
97           in
98           returnTc info2
99
100     tcPrag info (HsStrictness strict)
101         = tcStrictness unf_env ty info strict
102
103     tcPrag info (HsSpecialise tyvars tys rhs)
104         = tcTyVarScope tyvars                   $ \ tyvars' ->
105           mapAndUnzipTc tcHsTypeKind tys        `thenTc` \ (kinds, tys') -> 
106                 -- Assume that the kinds match the kinds of the 
107                 -- type variables of the function; this is, after all, an
108                 -- interface file generated by the compiler!
109
110           tcPragExpr unf_env name rhs   `thenNF_Tc` \ maybe_rhs' ->
111           let
112                 -- If spec_env isn't looked at, none of this 
113                 -- actually takes place
114             spec_env  = specInfo info
115             spec_env' = case maybe_rhs' of
116                           Nothing -> spec_env
117                           Just rhs' -> case addToSpecEnv True {- overlap ok -} spec_env tyvars' tys' rhs' of
118                                           Succeeded spec_env' -> spec_env'
119                                           Failed err          -> pprTrace "tcIdInfo: bad specialisation"
120                                                                           (ppr name <+> ppr err) $
121                                                                  spec_env
122           in
123           returnTc (spec_env' `setSpecInfo` info)
124 \end{code}
125
126 \begin{code}
127 tcStrictness unf_env ty info (HsStrictnessInfo demands maybe_worker)
128   = tcWorker unf_env maybe_worker               `thenNF_Tc` \ maybe_worker_id ->
129     uniqSMToTcM (mkWrapper ty demands)          `thenNF_Tc` \ wrap_fn ->
130     let
131         -- Watch out! We can't pull on maybe_worker_id too eagerly!
132         info' = case maybe_worker_id of
133                         Just worker_id -> setUnfoldingInfo (mkUnfolding (wrap_fn worker_id)) $
134                                           setInlinePragInfo IWantToBeINLINEd info
135
136                         Nothing        -> info
137
138         has_worker = maybeToBool maybe_worker_id
139     in
140     returnTc (StrictnessInfo demands has_worker  `setStrictnessInfo` info')
141
142 -- Boring to write these out, but the result type differs from the arg type...
143 tcStrictness unf_env ty info HsBottom
144   = returnTc (BottomGuaranteed `setStrictnessInfo` info)
145 \end{code}
146
147 \begin{code}
148 tcWorker unf_env Nothing = returnNF_Tc Nothing
149
150 tcWorker unf_env (Just (worker_name,_))
151   = returnNF_Tc (trace_maybe maybe_worker_id)
152   where
153     maybe_worker_id = tcExplicitLookupGlobal unf_env worker_name
154
155         -- The trace is so we can see what's getting dropped
156     trace_maybe Nothing  = pprTrace "tcWorker failed:" (ppr worker_name) Nothing
157     trace_maybe (Just x) = Just x
158 \end{code}
159
160 For unfoldings we try to do the job lazily, so that we never type check
161 an unfolding that isn't going to be looked at.
162
163 \begin{code}
164 tcPragExpr unf_env name core_expr
165   = forkNF_Tc (
166         recoverNF_Tc no_unfolding (
167                 tcSetGlobalValEnv unf_env $
168                 tcCoreExpr core_expr    `thenTc` \ core_expr' ->
169                 returnTc (Just core_expr')
170     ))                  
171   where
172         -- The trace tells what wasn't available, for the benefit of
173         -- compiler hackers who want to improve it!
174     no_unfolding = getErrsTc            `thenNF_Tc` \ (warns,errs) ->
175                    returnNF_Tc (pprTrace "tcUnfolding failed with:" 
176                                          (hang (ppr name) 4 (pprBagOfErrors errs))
177                                          Nothing)
178 \end{code}
179
180
181 Variables in unfoldings
182 ~~~~~~~~~~~~~~~~~~~~~~~
183 ****** Inside here we use only the Global environment, even for locally bound variables.
184 ****** Why? Because we know all the types and want to bind them to real Ids.
185
186 \begin{code}
187 tcVar :: Name -> TcM s Id
188 tcVar name
189   = tcLookupGlobalValueMaybe name       `thenNF_Tc` \ maybe_id ->
190     case maybe_id of {
191         Just id -> returnTc id;
192         Nothing -> failWithTc (noDecl name)
193     }
194
195 noDecl name = hsep [ptext SLIT("Warning: no binding for"), ppr name]
196 \end{code}
197
198 UfCore expressions.
199
200 \begin{code}
201 tcCoreExpr :: UfExpr Name -> TcM s CoreExpr
202
203 tcCoreExpr (UfVar name)
204   = tcVar name  `thenTc` \ id ->
205     returnTc (Var id)
206
207 -- rationalTy isn't built in so we have to construct it
208 -- (the "ty" part of the incoming literal is simply bottom)
209 tcCoreExpr (UfLit (NoRepRational lit _)) 
210   = tcLookupTyConByKey rationalTyConKey `thenNF_Tc` \ rational_tycon ->
211     let
212         rational_ty  = mkSynTy rational_tycon []
213     in
214     returnTc (Lit (NoRepRational lit rational_ty)) 
215
216 -- Similarly for integers, except that it is wired in
217 tcCoreExpr (UfLit (NoRepInteger lit _)) 
218   = returnTc (Lit (NoRepInteger lit integerTy))
219
220 tcCoreExpr (UfLit other_lit)
221   = returnTc (Lit other_lit)
222
223 tcCoreExpr (UfCon con args) 
224   = tcVar con                   `thenTc` \ con_id ->
225     mapTc tcCoreArg args        `thenTc` \ args' ->
226     returnTc (Con con_id args')
227
228 tcCoreExpr (UfPrim prim args) 
229   = tcCorePrim prim             `thenTc` \ primop ->
230     mapTc tcCoreArg args        `thenTc` \ args' ->
231     returnTc (Prim primop args')
232
233 tcCoreExpr (UfLam bndr body)
234   = tcCoreLamBndr bndr          $ \ bndr' ->
235     tcCoreExpr body             `thenTc` \ body' ->
236     returnTc (Lam bndr' body')
237
238 tcCoreExpr (UfApp fun arg)
239   = tcCoreExpr fun              `thenTc` \ fun' ->
240     tcCoreArg arg               `thenTc` \ arg' ->
241     returnTc (App fun' arg')
242
243 tcCoreExpr (UfCase scrut alts) 
244   = tcCoreExpr scrut                            `thenTc` \ scrut' ->
245     tcCoreAlts (coreExprType scrut') alts       `thenTc` \ alts' ->
246     returnTc (Case scrut' alts')
247
248 tcCoreExpr (UfLet (UfNonRec bndr rhs) body)
249   = tcCoreExpr rhs              `thenTc` \ rhs' ->
250     tcCoreValBndr bndr          $ \ bndr' ->
251     tcCoreExpr body             `thenTc` \ body' ->
252     returnTc (Let (NonRec bndr' rhs') body')
253
254 tcCoreExpr (UfLet (UfRec pairs) body)
255   = tcCoreValBndrs bndrs        $ \ bndrs' ->
256     mapTc tcCoreExpr rhss       `thenTc` \ rhss' ->
257     tcCoreExpr body             `thenTc` \ body' ->
258     returnTc (Let (Rec (bndrs' `zip` rhss')) body')
259   where
260     (bndrs, rhss) = unzip pairs
261
262 tcCoreExpr (UfNote note expr) 
263   = tcCoreExpr expr             `thenTc` \ expr' ->
264     case note of
265         UfCoerce to_ty -> tcHsTypeKind to_ty    `thenTc` \ (_,to_ty') ->
266                           returnTc (Note (Coerce to_ty' (coreExprType expr')) expr')
267         UfInlineCall   -> returnTc (Note InlineCall expr')
268         UfSCC cc       -> returnTc (Note (SCC cc) expr')
269
270 tcCoreNote (UfSCC cc)   = returnTc (SCC cc)
271 tcCoreNote UfInlineCall = returnTc InlineCall 
272 \end{code}
273
274 \begin{code}
275 tcCoreLamBndr (UfValBinder name ty) thing_inside
276   = tcHsType ty                 `thenTc` \ ty' ->
277     let
278         id = mkUserId name ty'
279     in
280     tcExtendGlobalValEnv [id] $
281     thing_inside (ValBinder id)
282     
283 tcCoreLamBndr (UfTyBinder name kind) thing_inside
284   = let
285         tyvar = mkSysTyVar (uniqueOf name) kind
286     in
287     tcExtendTyVarEnv [name] [(kindToTcKind kind, tyvar)] $
288     thing_inside (TyBinder tyvar)
289     
290 tcCoreValBndr (UfValBinder name ty) thing_inside
291   = tcHsType ty                 `thenTc` \ ty' ->
292     let
293         id = mkUserId name ty'
294     in
295     tcExtendGlobalValEnv [id] $
296     thing_inside id
297     
298 tcCoreValBndrs bndrs thing_inside               -- Expect them all to be ValBinders
299   = mapTc tcHsType tys                  `thenTc` \ tys' ->
300     let
301         ids = zipWithEqual "tcCoreValBndr" mkUserId names tys'
302     in
303     tcExtendGlobalValEnv ids $
304     thing_inside ids
305   where
306     names = map (\ (UfValBinder name _) -> name) bndrs
307     tys   = map (\ (UfValBinder _   ty) -> ty)   bndrs
308 \end{code}    
309
310 \begin{code}
311 tcCoreArg (UfVarArg v)   = tcVar v              `thenTc` \ v' -> returnTc (VarArg v')
312 tcCoreArg (UfTyArg ty)   = tcHsTypeKind ty      `thenTc` \ (_,ty') -> returnTc (TyArg ty')
313 tcCoreArg (UfLitArg lit) = returnTc (LitArg lit)
314
315 tcCoreAlts scrut_ty (UfAlgAlts alts deflt)
316   = mapTc tc_alt alts                   `thenTc` \ alts' ->
317     tcCoreDefault scrut_ty deflt        `thenTc` \ deflt' ->
318     returnTc (AlgAlts alts' deflt')
319   where
320     tc_alt (con, names, rhs)
321       = tcVar con                       `thenTc` \ con' ->
322         let
323             arg_tys                 = dataConArgTys con' inst_tys
324             (tycon, inst_tys, cons) = splitAlgTyConApp scrut_ty
325             arg_ids                 = zipWithEqual "tcCoreAlts" mkUserId names arg_tys
326         in
327         tcExtendGlobalValEnv arg_ids    $
328         tcCoreExpr rhs                  `thenTc` \ rhs' ->
329         returnTc (con', arg_ids, rhs')
330
331 tcCoreAlts scrut_ty (UfPrimAlts alts deflt)
332   = mapTc tc_alt alts                   `thenTc` \ alts' ->
333     tcCoreDefault scrut_ty deflt        `thenTc` \ deflt' ->
334     returnTc (PrimAlts alts' deflt')
335   where
336     tc_alt (lit, rhs) = tcCoreExpr rhs          `thenTc` \ rhs' ->
337                         returnTc (lit, rhs')
338
339 tcCoreDefault scrut_ty UfNoDefault = returnTc NoDefault
340 tcCoreDefault scrut_ty (UfBindDefault name rhs)
341   = let
342         deflt_id = mkUserId name scrut_ty
343     in
344     tcExtendGlobalValEnv [deflt_id]     $
345     tcCoreExpr rhs                      `thenTc` \ rhs' ->
346     returnTc (BindDefault deflt_id rhs')
347     
348
349 tcCorePrim (UfOtherOp op) 
350   = tcVar op            `thenTc` \ op_id ->
351     case isPrimitiveId_maybe op_id of
352         Just prim_op -> returnTc prim_op
353         Nothing      -> pprPanic "tcCorePrim" (ppr op_id)
354
355 tcCorePrim (UfCCallOp str casm gc arg_tys res_ty)
356   = mapTc tcHsType arg_tys      `thenTc` \ arg_tys' ->
357     tcHsType res_ty             `thenTc` \ res_ty' ->
358     returnTc (CCallOp str casm gc arg_tys' res_ty')
359 \end{code}
360
361 \begin{code}
362 ifaceSigCtxt sig_name
363   = hsep [ptext SLIT("In an interface-file signature for"), ppr sig_name]
364 \end{code}
365