[project @ 1998-04-08 16:48:14 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           mapTc tcHsType tys            `thenTc` \ tys' -> 
106           tcPragExpr unf_env name rhs   `thenNF_Tc` \ maybe_rhs' ->
107           let
108                 -- If spec_env isn't looked at, none of this 
109                 -- actually takes place
110             spec_env  = specInfo info
111             spec_env' = case maybe_rhs' of
112                           Nothing -> spec_env
113                           Just rhs' -> case addToSpecEnv True {- overlap ok -} spec_env tyvars' tys' rhs' of
114                                           Succeeded spec_env' -> spec_env'
115                                           Failed err          -> pprTrace "tcIdInfo: bad specialisation"
116                                                                           (ppr name <+> ppr err) $
117                                                                  spec_env
118           in
119           returnTc (spec_env' `setSpecInfo` info)
120 \end{code}
121
122 \begin{code}
123 tcStrictness unf_env ty info (HsStrictnessInfo demands maybe_worker)
124   = tcWorker unf_env maybe_worker               `thenNF_Tc` \ maybe_worker_id ->
125     uniqSMToTcM (mkWrapper ty demands)          `thenNF_Tc` \ wrap_fn ->
126     let
127         -- Watch out! We can't pull on maybe_worker_id too eagerly!
128         info' = case maybe_worker_id of
129                         Just worker_id -> setUnfoldingInfo (mkUnfolding (wrap_fn worker_id)) $
130                                           setInlinePragInfo IWantToBeINLINEd info
131
132                         Nothing        -> info
133
134         has_worker = maybeToBool maybe_worker_id
135     in
136     returnTc (StrictnessInfo demands has_worker  `setStrictnessInfo` info')
137
138 -- Boring to write these out, but the result type differs from the arg type...
139 tcStrictness unf_env ty info HsBottom
140   = returnTc (BottomGuaranteed `setStrictnessInfo` info)
141 \end{code}
142
143 \begin{code}
144 tcWorker unf_env Nothing = returnNF_Tc Nothing
145
146 tcWorker unf_env (Just (worker_name,_))
147   = returnNF_Tc (trace_maybe maybe_worker_id)
148   where
149     maybe_worker_id = tcExplicitLookupGlobal unf_env worker_name
150
151         -- The trace is so we can see what's getting dropped
152     trace_maybe Nothing  = pprTrace "tcWorker failed:" (ppr worker_name) Nothing
153     trace_maybe (Just x) = Just x
154 \end{code}
155
156 For unfoldings we try to do the job lazily, so that we never type check
157 an unfolding that isn't going to be looked at.
158
159 \begin{code}
160 tcPragExpr unf_env name core_expr
161   = forkNF_Tc (
162         recoverNF_Tc no_unfolding (
163                 tcSetGlobalValEnv unf_env $
164                 tcCoreExpr core_expr    `thenTc` \ core_expr' ->
165                 returnTc (Just core_expr')
166     ))                  
167   where
168         -- The trace tells what wasn't available, for the benefit of
169         -- compiler hackers who want to improve it!
170     no_unfolding = getErrsTc            `thenNF_Tc` \ (warns,errs) ->
171                    returnNF_Tc (pprTrace "tcUnfolding failed with:" 
172                                          (hang (ppr name) 4 (pprBagOfErrors errs))
173                                          Nothing)
174 \end{code}
175
176
177 Variables in unfoldings
178 ~~~~~~~~~~~~~~~~~~~~~~~
179 ****** Inside here we use only the Global environment, even for locally bound variables.
180 ****** Why? Because we know all the types and want to bind them to real Ids.
181
182 \begin{code}
183 tcVar :: Name -> TcM s Id
184 tcVar name
185   = tcLookupGlobalValueMaybe name       `thenNF_Tc` \ maybe_id ->
186     case maybe_id of {
187         Just id -> returnTc id;
188         Nothing -> failWithTc (noDecl name)
189     }
190
191 noDecl name = hsep [ptext SLIT("Warning: no binding for"), ppr name]
192 \end{code}
193
194 UfCore expressions.
195
196 \begin{code}
197 tcCoreExpr :: UfExpr Name -> TcM s CoreExpr
198
199 tcCoreExpr (UfVar name)
200   = tcVar name  `thenTc` \ id ->
201     returnTc (Var id)
202
203 -- rationalTy isn't built in so we have to construct it
204 -- (the "ty" part of the incoming literal is simply bottom)
205 tcCoreExpr (UfLit (NoRepRational lit _)) 
206   = tcLookupTyConByKey rationalTyConKey `thenNF_Tc` \ rational_tycon ->
207     let
208         rational_ty  = mkSynTy rational_tycon []
209     in
210     returnTc (Lit (NoRepRational lit rational_ty)) 
211
212 -- Similarly for integers, except that it is wired in
213 tcCoreExpr (UfLit (NoRepInteger lit _)) 
214   = returnTc (Lit (NoRepInteger lit integerTy))
215
216 tcCoreExpr (UfLit other_lit)
217   = returnTc (Lit other_lit)
218
219 tcCoreExpr (UfCon con args) 
220   = tcVar con                   `thenTc` \ con_id ->
221     mapTc tcCoreArg args        `thenTc` \ args' ->
222     returnTc (Con con_id args')
223
224 tcCoreExpr (UfPrim prim args) 
225   = tcCorePrim prim             `thenTc` \ primop ->
226     mapTc tcCoreArg args        `thenTc` \ args' ->
227     returnTc (Prim primop args')
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     tcCoreArg arg               `thenTc` \ arg' ->
237     returnTc (App fun' arg')
238
239 tcCoreExpr (UfCase scrut alts) 
240   = tcCoreExpr scrut                            `thenTc` \ scrut' ->
241     tcCoreAlts (coreExprType scrut') alts       `thenTc` \ alts' ->
242     returnTc (Case scrut' alts')
243
244 tcCoreExpr (UfLet (UfNonRec bndr rhs) body)
245   = tcCoreExpr rhs              `thenTc` \ rhs' ->
246     tcCoreValBndr bndr          $ \ bndr' ->
247     tcCoreExpr body             `thenTc` \ body' ->
248     returnTc (Let (NonRec bndr' rhs') body')
249
250 tcCoreExpr (UfLet (UfRec pairs) body)
251   = tcCoreValBndrs bndrs        $ \ bndrs' ->
252     mapTc tcCoreExpr rhss       `thenTc` \ rhss' ->
253     tcCoreExpr body             `thenTc` \ body' ->
254     returnTc (Let (Rec (bndrs' `zip` rhss')) body')
255   where
256     (bndrs, rhss) = unzip pairs
257
258 tcCoreExpr (UfNote note expr) 
259   = tcCoreExpr expr             `thenTc` \ expr' ->
260     case note of
261         UfCoerce to_ty -> tcHsTypeKind to_ty    `thenTc` \ (_,to_ty') ->
262                           returnTc (Note (Coerce to_ty' (coreExprType expr')) expr')
263         UfInlineCall   -> returnTc (Note InlineCall expr')
264         UfSCC cc       -> returnTc (Note (SCC cc) expr')
265
266 tcCoreNote (UfSCC cc)   = returnTc (SCC cc)
267 tcCoreNote UfInlineCall = returnTc InlineCall 
268 \end{code}
269
270 \begin{code}
271 tcCoreLamBndr (UfValBinder name ty) thing_inside
272   = tcHsType ty                 `thenTc` \ ty' ->
273     let
274         id = mkUserId name ty'
275     in
276     tcExtendGlobalValEnv [id] $
277     thing_inside (ValBinder id)
278     
279 tcCoreLamBndr (UfTyBinder name kind) thing_inside
280   = let
281         tyvar = mkSysTyVar (uniqueOf name) kind
282     in
283     tcExtendTyVarEnv [name] [(kindToTcKind kind, tyvar)] $
284     thing_inside (TyBinder tyvar)
285     
286 tcCoreValBndr (UfValBinder name ty) thing_inside
287   = tcHsType ty                 `thenTc` \ ty' ->
288     let
289         id = mkUserId name ty'
290     in
291     tcExtendGlobalValEnv [id] $
292     thing_inside id
293     
294 tcCoreValBndrs bndrs thing_inside               -- Expect them all to be ValBinders
295   = mapTc tcHsType tys                  `thenTc` \ tys' ->
296     let
297         ids = zipWithEqual "tcCoreValBndr" mkUserId names tys'
298     in
299     tcExtendGlobalValEnv ids $
300     thing_inside ids
301   where
302     names = map (\ (UfValBinder name _) -> name) bndrs
303     tys   = map (\ (UfValBinder _   ty) -> ty)   bndrs
304 \end{code}    
305
306 \begin{code}
307 tcCoreArg (UfVarArg v)   = tcVar v              `thenTc` \ v' -> returnTc (VarArg v')
308 tcCoreArg (UfTyArg ty)   = tcHsTypeKind ty      `thenTc` \ (_,ty') -> returnTc (TyArg ty')
309 tcCoreArg (UfLitArg lit) = returnTc (LitArg lit)
310
311 tcCoreAlts scrut_ty (UfAlgAlts alts deflt)
312   = mapTc tc_alt alts                   `thenTc` \ alts' ->
313     tcCoreDefault scrut_ty deflt        `thenTc` \ deflt' ->
314     returnTc (AlgAlts alts' deflt')
315   where
316     tc_alt (con, names, rhs)
317       = tcVar con                       `thenTc` \ con' ->
318         let
319             arg_tys                 = dataConArgTys con' inst_tys
320             (tycon, inst_tys, cons) = splitAlgTyConApp scrut_ty
321             arg_ids                 = zipWithEqual "tcCoreAlts" mkUserId names arg_tys
322         in
323         tcExtendGlobalValEnv arg_ids    $
324         tcCoreExpr rhs                  `thenTc` \ rhs' ->
325         returnTc (con', arg_ids, rhs')
326
327 tcCoreAlts scrut_ty (UfPrimAlts alts deflt)
328   = mapTc tc_alt alts                   `thenTc` \ alts' ->
329     tcCoreDefault scrut_ty deflt        `thenTc` \ deflt' ->
330     returnTc (PrimAlts alts' deflt')
331   where
332     tc_alt (lit, rhs) = tcCoreExpr rhs          `thenTc` \ rhs' ->
333                         returnTc (lit, rhs')
334
335 tcCoreDefault scrut_ty UfNoDefault = returnTc NoDefault
336 tcCoreDefault scrut_ty (UfBindDefault name rhs)
337   = let
338         deflt_id = mkUserId name scrut_ty
339     in
340     tcExtendGlobalValEnv [deflt_id]     $
341     tcCoreExpr rhs                      `thenTc` \ rhs' ->
342     returnTc (BindDefault deflt_id rhs')
343     
344
345 tcCorePrim (UfOtherOp op) 
346   = tcVar op            `thenTc` \ op_id ->
347     case isPrimitiveId_maybe op_id of
348         Just prim_op -> returnTc prim_op
349         Nothing      -> pprPanic "tcCorePrim" (ppr op_id)
350
351 tcCorePrim (UfCCallOp str casm gc arg_tys res_ty)
352   = mapTc tcHsType arg_tys      `thenTc` \ arg_tys' ->
353     tcHsType res_ty             `thenTc` \ res_ty' ->
354     returnTc (CCallOp str casm gc arg_tys' res_ty')
355 \end{code}
356
357 \begin{code}
358 ifaceSigCtxt sig_name
359   = hsep [ptext SLIT("In an interface-file signature for"), ppr sig_name]
360 \end{code}
361