2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[TcIfaceSig]{Type checking of type signatures in interface files}
7 #include "HsVersions.h"
9 module TcIfaceSig ( tcInterfaceSigs ) where
14 import TcMonoType ( tcHsType, tcHsTypeKind )
15 import TcEnv ( tcLookupGlobalValue, tcExtendTyVarEnv, tcExtendGlobalValEnv,
16 tcLookupTyConByKey, tcLookupGlobalValueMaybe, tcLookupLocalValue,
17 tcExplicitLookupGlobal
19 import TcKind ( TcKind, kindToTcKind )
21 import HsSyn ( IfaceSig(..), HsDecl(..), TyDecl, ClassDecl, InstDecl, DefaultDecl, HsBinds,
23 import RnHsSyn ( RenamedHsDecl(..) )
25 import HsDecls ( HsIdInfo(..), HsStrictnessInfo(..) )
26 import Literal ( Literal(..) )
28 import CoreUtils ( coreExprType )
30 import MagicUFs ( MagicUnfoldingFun )
31 import WwLib ( mkWrapper )
32 import SpecEnv ( SpecEnv )
33 import PrimOp ( PrimOp(..) )
35 import Id ( GenId, mkImported, mkUserId, addInlinePragma,
36 isPrimitiveId_maybe, dataConArgTys, SYN_IE(Id) )
37 import Type ( mkSynTy, getAppDataTyConExpandingDicts )
38 import TyVar ( mkSysTyVar )
40 import Unique ( rationalTyConKey, uniqueOf )
41 import TysWiredIn ( integerTy )
42 import PragmaInfo ( PragmaInfo(..) )
43 import ErrUtils ( pprBagOfErrors )
44 import Maybes ( maybeToBool )
46 import Outputable ( Outputable(..), PprStyle(..) )
47 import Util ( zipWithEqual, panic, pprTrace, pprPanic )
52 Ultimately, type signatures in interfaces will have pragmatic
53 information attached, so it is a good idea to have separate code to
56 As always, we do not have to worry about user-pragmas in interface
60 tcInterfaceSigs :: TcEnv s -- Envt to use when checking unfoldings
61 -> [RenamedHsDecl] -- Ignore non-sig-decls in these decls
65 tcInterfaceSigs unf_env (SigD (IfaceSig name ty id_infos src_loc) : rest)
66 = tcAddSrcLoc src_loc (
67 tcAddErrCtxt (ifaceSigCtxt name) (
68 tcHsType ty `thenTc` \ sigma_ty ->
69 tcIdInfo unf_env name sigma_ty noIdInfo id_infos `thenTc` \ id_info' ->
71 imp_id = mkImported name sigma_ty id_info'
72 sig_id | any inline_please id_infos = addInlinePragma imp_id
75 inline_please (HsUnfold inline _) = inline
76 inline_please other = False
79 )) `thenTc` \ sig_id ->
80 tcInterfaceSigs unf_env rest `thenTc` \ sig_ids ->
81 returnTc (sig_id : sig_ids)
83 tcInterfaceSigs unf_env (other_decl : rest) = tcInterfaceSigs unf_env rest
85 tcInterfaceSigs unf_env [] = returnTc []
89 tcIdInfo unf_env name ty info info_ins
90 = go noIdInfo info_ins
92 go info_so_far [] = returnTc info_so_far
93 go info (HsArity arity : rest) = go (info `addArityInfo` arity) rest
94 go info (HsUpdate upd : rest) = go (info `addUpdateInfo` upd) rest
95 go info (HsFBType fb : rest) = go (info `addFBTypeInfo` fb) rest
96 go info (HsArgUsage au : rest) = go (info `addArgUsageInfo` au) rest
97 go info (HsDeforest df : rest) = go (info `addDeforestInfo` df) rest
99 go info (HsUnfold inline expr : rest) = tcUnfolding unf_env name expr `thenNF_Tc` \ unfold_info ->
100 go (info `addUnfoldInfo` unfold_info) rest
102 go info (HsStrictness strict : rest) = tcStrictness unf_env ty info strict `thenTc` \ info' ->
107 tcStrictness unf_env ty info (HsStrictnessInfo demands maybe_worker)
108 = tcWorker unf_env maybe_worker `thenNF_Tc` \ maybe_worker_id ->
109 uniqSMToTcM (mkWrapper ty demands) `thenNF_Tc` \ wrap_fn ->
111 -- Watch out! We can't pull on maybe_worker_id too eagerly!
112 info' = case maybe_worker_id of
113 Just worker_id -> info `addUnfoldInfo` mkUnfolding NoPragmaInfo (wrap_fn worker_id)
115 has_worker = maybeToBool maybe_worker_id
117 returnTc (info' `addStrictnessInfo` StrictnessInfo demands has_worker)
119 -- Boring to write these out, but the result type differs from the arg type...
120 tcStrictness unf_env ty info HsBottom
121 = returnTc (info `addStrictnessInfo` BottomGuaranteed)
125 tcWorker unf_env Nothing = returnNF_Tc Nothing
127 tcWorker unf_env (Just (worker_name,_))
128 = returnNF_Tc (trace_maybe maybe_worker_id)
130 maybe_worker_id = tcExplicitLookupGlobal unf_env worker_name
132 -- The trace is so we can see what's getting dropped
133 trace_maybe Nothing = pprTrace "tcWorker failed:" (ppr PprDebug worker_name) Nothing
134 trace_maybe (Just x) = Just x
137 For unfoldings we try to do the job lazily, so that we never type check
138 an unfolding that isn't going to be looked at.
141 tcUnfolding unf_env name core_expr
143 recoverNF_Tc no_unfolding (
145 tcCoreExpr core_expr `thenTc` \ core_expr' ->
146 returnTc (mkUnfolding NoPragmaInfo core_expr')
149 -- The trace tells what wasn't available, for the benefit of
150 -- compiler hackers who want to improve it!
151 no_unfolding = getErrsTc `thenNF_Tc` \ (warns,errs) ->
152 returnNF_Tc (pprTrace "tcUnfolding failed with:"
153 (hang (ppr PprDebug name) 4 (pprBagOfErrors PprDebug errs))
158 Variables in unfoldings
159 ~~~~~~~~~~~~~~~~~~~~~~~
160 ****** Inside here we use only the Global environment, even for locally bound variables.
161 ****** Why? Because we know all the types and want to bind them to real Ids.
164 tcVar :: Name -> TcM s Id
166 = tcLookupGlobalValueMaybe name `thenNF_Tc` \ maybe_id ->
168 Just id -> returnTc id;
169 Nothing -> failTc (noDecl name)
172 noDecl name sty = hsep [ptext SLIT("Warning: no binding for"), ppr sty name]
178 tcCoreExpr :: UfExpr Name -> TcM s CoreExpr
180 tcCoreExpr (UfVar name)
181 = tcVar name `thenTc` \ id ->
184 -- rationalTy isn't built in so we have to construct it
185 -- (the "ty" part of the incoming literal is simply bottom)
186 tcCoreExpr (UfLit (NoRepRational lit _))
187 = tcLookupTyConByKey rationalTyConKey `thenNF_Tc` \ rational_tycon ->
189 rational_ty = mkSynTy rational_tycon []
191 returnTc (Lit (NoRepRational lit rational_ty))
193 -- Similarly for integers, except that it is wired in
194 tcCoreExpr (UfLit (NoRepInteger lit _))
195 = returnTc (Lit (NoRepInteger lit integerTy))
197 tcCoreExpr (UfLit other_lit)
198 = returnTc (Lit other_lit)
200 tcCoreExpr (UfCon con args)
201 = tcVar con `thenTc` \ con_id ->
202 mapTc tcCoreArg args `thenTc` \ args' ->
203 returnTc (Con con_id args')
205 tcCoreExpr (UfPrim prim args)
206 = tcCorePrim prim `thenTc` \ primop ->
207 mapTc tcCoreArg args `thenTc` \ args' ->
208 returnTc (Prim primop args')
210 tcCoreExpr (UfApp fun arg)
211 = tcCoreExpr fun `thenTc` \ fun' ->
212 tcCoreArg arg `thenTc` \ arg' ->
213 returnTc (App fun' arg')
215 tcCoreExpr (UfCase scrut alts)
216 = tcCoreExpr scrut `thenTc` \ scrut' ->
217 tcCoreAlts (coreExprType scrut') alts `thenTc` \ alts' ->
218 returnTc (Case scrut' alts')
220 tcCoreExpr (UfSCC cc expr)
221 = tcCoreExpr expr `thenTc` \ expr' ->
222 returnTc (SCC cc expr')
224 tcCoreExpr(UfCoerce coercion ty body)
225 = tcCoercion coercion `thenTc` \ coercion' ->
226 tcHsTypeKind ty `thenTc` \ (_,ty') ->
227 tcCoreExpr body `thenTc` \ body' ->
228 returnTc (Coerce coercion' ty' body')
230 tcCoreExpr (UfLam bndr body)
231 = tcCoreLamBndr bndr $ \ bndr' ->
232 tcCoreExpr body `thenTc` \ body' ->
233 returnTc (Lam bndr' body')
235 tcCoreExpr (UfLet (UfNonRec bndr rhs) body)
236 = tcCoreExpr rhs `thenTc` \ rhs' ->
237 tcCoreValBndr bndr $ \ bndr' ->
238 tcCoreExpr body `thenTc` \ body' ->
239 returnTc (Let (NonRec bndr' rhs') body')
241 tcCoreExpr (UfLet (UfRec pairs) body)
242 = tcCoreValBndrs bndrs $ \ bndrs' ->
243 mapTc tcCoreExpr rhss `thenTc` \ rhss' ->
244 tcCoreExpr body `thenTc` \ body' ->
245 returnTc (Let (Rec (bndrs' `zip` rhss')) body')
247 (bndrs, rhss) = unzip pairs
251 tcCoreLamBndr (UfValBinder name ty) thing_inside
252 = tcHsType ty `thenTc` \ ty' ->
254 id = mkUserId name ty' NoPragmaInfo
256 tcExtendGlobalValEnv [id] $
257 thing_inside (ValBinder id)
259 tcCoreLamBndr (UfTyBinder name kind) thing_inside
261 tyvar = mkSysTyVar (uniqueOf name) kind
263 tcExtendTyVarEnv [name] [(kindToTcKind kind, tyvar)] $
264 thing_inside (TyBinder tyvar)
266 tcCoreLamBndr (UfUsageBinder name) thing_inside
267 = error "tcCoreLamBndr: usage"
269 tcCoreValBndr (UfValBinder name ty) thing_inside
270 = tcHsType ty `thenTc` \ ty' ->
274 tcExtendGlobalValEnv [id] $
277 tcCoreValBndrs bndrs thing_inside -- Expect them all to be ValBinders
278 = mapTc tcHsType tys `thenTc` \ tys' ->
280 ids = zipWithEqual "tcCoreValBndr" mk_id names tys'
282 tcExtendGlobalValEnv ids $
285 names = map (\ (UfValBinder name _) -> name) bndrs
286 tys = map (\ (UfValBinder _ ty) -> ty) bndrs
288 mk_id name ty = mkUserId name ty NoPragmaInfo
292 tcCoreArg (UfVarArg v) = tcVar v `thenTc` \ v' -> returnTc (VarArg v')
293 tcCoreArg (UfTyArg ty) = tcHsTypeKind ty `thenTc` \ (_,ty') -> returnTc (TyArg ty')
294 tcCoreArg (UfLitArg lit) = returnTc (LitArg lit)
295 tcCoreArg (UfUsageArg u) = error "tcCoreArg: usage"
297 tcCoreAlts scrut_ty (UfAlgAlts alts deflt)
298 = mapTc tc_alt alts `thenTc` \ alts' ->
299 tcCoreDefault scrut_ty deflt `thenTc` \ deflt' ->
300 returnTc (AlgAlts alts' deflt')
302 tc_alt (con, names, rhs)
303 = tcVar con `thenTc` \ con' ->
305 arg_tys = dataConArgTys con' inst_tys
306 (tycon, inst_tys, cons) = getAppDataTyConExpandingDicts scrut_ty
307 arg_ids = zipWithEqual "tcCoreAlts" mk_id names arg_tys
309 tcExtendGlobalValEnv arg_ids $
310 tcCoreExpr rhs `thenTc` \ rhs' ->
311 returnTc (con', arg_ids, rhs')
313 tcCoreAlts scrut_ty (UfPrimAlts alts deflt)
314 = mapTc tc_alt alts `thenTc` \ alts' ->
315 tcCoreDefault scrut_ty deflt `thenTc` \ deflt' ->
316 returnTc (PrimAlts alts' deflt')
318 tc_alt (lit, rhs) = tcCoreExpr rhs `thenTc` \ rhs' ->
321 tcCoreDefault scrut_ty UfNoDefault = returnTc NoDefault
322 tcCoreDefault scrut_ty (UfBindDefault name rhs)
324 deflt_id = mk_id name scrut_ty
326 tcExtendGlobalValEnv [deflt_id] $
327 tcCoreExpr rhs `thenTc` \ rhs' ->
328 returnTc (BindDefault deflt_id rhs')
331 tcCoercion (UfIn n) = tcVar n `thenTc` \ n' -> returnTc (CoerceIn n')
332 tcCoercion (UfOut n) = tcVar n `thenTc` \ n' -> returnTc (CoerceOut n')
334 tcCorePrim (UfOtherOp op)
335 = tcVar op `thenTc` \ op_id ->
336 case isPrimitiveId_maybe op_id of
337 Just prim_op -> returnTc prim_op
338 Nothing -> pprPanic "tcCorePrim" (ppr PprDebug op_id)
340 tcCorePrim (UfCCallOp str casm gc arg_tys res_ty)
341 = mapTc tcHsType arg_tys `thenTc` \ arg_tys' ->
342 tcHsType res_ty `thenTc` \ res_ty' ->
343 returnTc (CCallOp str casm gc arg_tys' res_ty')
347 ifaceSigCtxt sig_name sty
348 = hsep [ptext SLIT("In an interface-file signature for"), ppr sty sig_name]