+
+UfCore expressions.
+
+\begin{code}
+tcCoreExpr :: UfExpr Name -> TcM s CoreExpr
+
+tcCoreExpr (UfType ty)
+ = tcHsTypeKind ty `thenTc` \ (_, ty') ->
+ -- It might not be of kind type
+ returnTc (Type ty')
+
+tcCoreExpr (UfVar name)
+ = tcVar name `thenTc` \ id ->
+ returnTc (Var id)
+
+tcCoreExpr (UfCon con args)
+ = tcUfCon con `thenTc` \ con' ->
+ mapTc tcCoreExpr args `thenTc` \ args' ->
+ returnTc (Con con' args')
+
+tcCoreExpr (UfTuple name args)
+ = tcUfDataCon name `thenTc` \ con ->
+ mapTc tcCoreExpr args `thenTc` \ args' ->
+ let
+ -- Put the missing type arguments back in
+ con_args = map (Type . coreExprType) args' ++ args'
+ in
+ returnTc (Con con con_args)
+
+tcCoreExpr (UfLam bndr body)
+ = tcCoreLamBndr bndr $ \ bndr' ->
+ tcCoreExpr body `thenTc` \ body' ->
+ returnTc (Lam bndr' body')
+
+tcCoreExpr (UfApp fun arg)
+ = tcCoreExpr fun `thenTc` \ fun' ->
+ tcCoreExpr arg `thenTc` \ arg' ->
+ returnTc (App fun' arg')
+
+tcCoreExpr (UfCase scrut case_bndr alts)
+ = tcCoreExpr scrut `thenTc` \ scrut' ->
+ let
+ scrut_ty = coreExprType scrut'
+ case_bndr' = mkUserId case_bndr scrut_ty
+ in
+ tcExtendGlobalValEnv [case_bndr'] $
+ mapTc (tcCoreAlt scrut_ty) alts `thenTc` \ alts' ->
+ returnTc (Case scrut' case_bndr' alts')
+
+tcCoreExpr (UfLet (UfNonRec bndr rhs) body)
+ = tcCoreExpr rhs `thenTc` \ rhs' ->
+ tcCoreValBndr bndr $ \ bndr' ->
+ tcCoreExpr body `thenTc` \ body' ->
+ returnTc (Let (NonRec bndr' rhs') body')
+
+tcCoreExpr (UfLet (UfRec pairs) body)
+ = tcCoreValBndrs bndrs $ \ bndrs' ->
+ mapTc tcCoreExpr rhss `thenTc` \ rhss' ->
+ tcCoreExpr body `thenTc` \ body' ->
+ returnTc (Let (Rec (bndrs' `zip` rhss')) body')
+ where
+ (bndrs, rhss) = unzip pairs
+
+tcCoreExpr (UfNote note expr)
+ = tcCoreExpr expr `thenTc` \ expr' ->
+ case note of
+ UfCoerce to_ty -> tcHsTypeKind to_ty `thenTc` \ (_,to_ty') ->
+ returnTc (Note (Coerce to_ty' (coreExprType expr')) expr')
+ UfInlineCall -> returnTc (Note InlineCall expr')
+ UfSCC cc -> returnTc (Note (SCC cc) expr')
+
+tcCoreNote (UfSCC cc) = returnTc (SCC cc)
+tcCoreNote UfInlineCall = returnTc InlineCall
+
+
+-- rationalTy isn't built in so, we have to construct it
+-- (the "ty" part of the incoming literal is simply bottom)
+tcUfCon (UfLitCon (NoRepRational lit _))
+ = tcLookupTyConByKey rationalTyConKey `thenNF_Tc` \ rational_tycon ->
+ let
+ rational_ty = mkSynTy rational_tycon []
+ in
+ returnTc (Literal (NoRepRational lit rational_ty))
+
+-- Similarly for integers and strings, except that they are wired in
+tcUfCon (UfLitCon (NoRepInteger lit _))
+ = returnTc (Literal (NoRepInteger lit integerTy))
+tcUfCon (UfLitCon (NoRepStr lit _))
+ = returnTc (Literal (NoRepStr lit stringTy))
+
+tcUfCon (UfLitCon other_lit)
+ = returnTc (Literal other_lit)
+
+-- The dreaded lit-lits are also similar, except here the type
+-- is read in explicitly rather than being implicit
+tcUfCon (UfLitLitCon lit ty)
+ = tcHsType ty `thenTc` \ ty' ->
+ returnTc (Literal (MachLitLit lit ty'))
+
+tcUfCon (UfDataCon name) = tcUfDataCon name
+
+tcUfCon (UfPrimOp name)
+ = tcVar name `thenTc` \ op_id ->
+ case isPrimitiveId_maybe op_id of
+ Just op -> returnTc (PrimOp op)
+ Nothing -> failWithTc (badPrimOp name)
+
+tcUfCon (UfCCallOp str casm gc)
+ = returnTc (PrimOp (CCallOp (Left str) casm gc cCallConv))
+
+tcUfDataCon name
+ = tcVar name `thenTc` \ con_id ->
+ case isDataConId_maybe con_id of
+ Just con -> returnTc (DataCon con)
+ Nothing -> failWithTc (badCon name)
+\end{code}
+
+\begin{code}
+tcCoreLamBndr (UfValBinder name ty) thing_inside
+ = tcHsType ty `thenTc` \ ty' ->
+ let
+ id = mkUserId name ty'
+ in
+ tcExtendGlobalValEnv [id] $
+ thing_inside id
+
+tcCoreLamBndr (UfTyBinder name kind) thing_inside
+ = let
+ tyvar = mkTyVar name kind
+ in
+ tcExtendTyVarEnv [name] [(kindToTcKind kind, tyvar)] $
+ thing_inside tyvar
+
+tcCoreValBndr (UfValBinder name ty) thing_inside
+ = tcHsType ty `thenTc` \ ty' ->
+ let
+ id = mkUserId name ty'
+ in
+ tcExtendGlobalValEnv [id] $
+ thing_inside id
+
+tcCoreValBndrs bndrs thing_inside -- Expect them all to be ValBinders
+ = mapTc tcHsType tys `thenTc` \ tys' ->
+ let
+ ids = zipWithEqual "tcCoreValBndr" mkUserId names tys'
+ in
+ tcExtendGlobalValEnv ids $
+ thing_inside ids
+ where
+ names = [name | UfValBinder name _ <- bndrs]
+ tys = [ty | UfValBinder _ ty <- bndrs]
+\end{code}
+
+\begin{code}
+tcCoreAlt scrut_ty (UfDefault, names, rhs)
+ = ASSERT( null names )
+ tcCoreExpr rhs `thenTc` \ rhs' ->
+ returnTc (DEFAULT, [], rhs')
+
+tcCoreAlt scrut_ty (UfLitCon lit, names, rhs)
+ = ASSERT( null names )
+ tcCoreExpr rhs `thenTc` \ rhs' ->
+ returnTc (Literal lit, [], rhs')
+
+tcCoreAlt scrut_ty (UfLitLitCon str ty, names, rhs)
+ = ASSERT( null names )
+ tcCoreExpr rhs `thenTc` \ rhs' ->
+ tcHsType ty `thenTc` \ ty' ->
+ returnTc (Literal (MachLitLit str ty'), [], rhs')
+
+-- A case alternative is made quite a bit more complicated
+-- by the fact that we omit type annotations because we can
+-- work them out. True enough, but its not that easy!
+tcCoreAlt scrut_ty (UfDataCon con_name, names, rhs)
+ = tcVar con_name `thenTc` \ con_id ->
+ let
+ con = case isDataConId_maybe con_id of
+ Just con -> con
+ Nothing -> pprPanic "tcCoreAlt" (ppr con_id)
+
+ (main_tyvars, _, ex_tyvars, _, _, _) = dataConSig con
+
+ (tycon, inst_tys, cons) = splitAlgTyConApp scrut_ty
+ ex_tyvars' = [mkTyVar name (tyVarKind tv) | (name,tv) <- names `zip` ex_tyvars]
+ ex_tys' = mkTyVarTys ex_tyvars'
+ arg_tys = dataConArgTys con (inst_tys ++ ex_tys')
+ id_names = drop (length ex_tyvars) names
+ arg_ids
+#ifdef DEBUG
+ | length id_names /= length arg_tys
+ = pprPanic "tcCoreAlts" (ppr (con_name, names, rhs) $$
+ (ppr main_tyvars <+> ppr ex_tyvars) $$
+ ppr arg_tys)
+ | otherwise
+#endif
+ = zipWithEqual "tcCoreAlts" mkUserId id_names arg_tys
+ in
+ ASSERT( con `elem` cons && length inst_tys == length main_tyvars )
+ tcExtendTyVarEnv (map getName ex_tyvars')
+ [ (kindToTcKind (tyVarKind tv), tv)
+ | tv <- ex_tyvars'] $
+ tcExtendGlobalValEnv arg_ids $
+ tcCoreExpr rhs `thenTc` \ rhs' ->
+ returnTc (DataCon con, ex_tyvars' ++ arg_ids, rhs')
+\end{code}
+
+\begin{code}
+ifaceSigCtxt sig_name
+ = hsep [ptext SLIT("In an interface-file signature for"), ppr sig_name]
+\end{code}
+