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