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