import TcType ( TcType, openTypeKind, mkAppTy )
import TcEnv ( spliceOK, tcMetaTy )
import TcRnTypes ( TopEnv(..) )
-import TcMType ( newTyVarTy )
+import TcMType ( newTyVarTy, zapToType )
import Name ( Name )
import TcRnMonad
import TysWiredIn ( mkListTy )
import DsMeta ( exprTyConName, declTyConName, decTyConName, qTyConName )
+import ErrUtils (Message)
import Outputable
import GHC.Base ( unsafeCoerce# ) -- Should have a better home in the module hierarchy
+import Monad (liftM)
\end{code}
Brack _ ps_var lie_var ->
-- A splice inside brackets
- -- NB: ignore res_ty
+ -- NB: ignore res_ty, apart from zapping it to a mono-type
-- e.g. [| reverse $(h 4) |]
-- Here (h 4) :: Q Exp
-- but $(h 4) :: forall a.a i.e. anything!
+ zapToType res_ty `thenM_`
tcMetaTy exprTyConName `thenM` \ meta_exp_ty ->
setStage (Splice next_level) (
setLIEVar lie_var $
-- Run the expression
traceTc (text "About to run" <+> ppr zonked_q_expr) `thenM_`
runMetaD zonked_q_expr `thenM` \ simple_expr ->
- let
- -- simple_expr :: [Meta.Dec]
- decls :: [RdrNameHsDecl]
- decls = convertToHsDecls simple_expr
- in
+ -- simple_expr :: [Meta.Dec]
+ -- decls :: [RdrNameHsDecl]
+ handleErrors (convertToHsDecls simple_expr) `thenM` \ decls ->
traceTc (text "Got result" <+> vcat (map ppr decls)) `thenM_`
showSplice "declarations"
zonked_q_expr (vcat (map ppr decls)) `thenM_`
returnM decls
+
+ where handleErrors :: [Either a Message] -> TcM [a]
+ handleErrors [] = return []
+ handleErrors (Left x:xs) = liftM (x:) (handleErrors xs)
+ handleErrors (Right m:xs) = do addErrTc m
+ handleErrors xs
\end{code}
-> TcM [Meta.Dec] -- Of type [Dec]
runMetaD e = runMeta e
--- Warning: if Q is anything other than IO, we need to change this
tcRunQ :: Meta.Q a -> TcM a
-tcRunQ thing = ioToTcRn thing
-
+tcRunQ thing = ioToTcRn (Meta.runQ thing)
runMeta :: TypecheckedHsExpr -- Of type X
-> TcM t -- Of type t
runMeta expr
= getTopEnv `thenM` \ top_env ->
+ getGblEnv `thenM` \ tcg_env ->
getEps `thenM` \ eps ->
getNameCache `thenM` \ name_cache ->
getModule `thenM` \ this_mod ->
- getGlobalRdrEnv `thenM` \ rdr_env ->
let
ghci_mode = top_mode top_env
pcs = PCS { pcs_nc = name_cache, pcs_EPS = eps }
- print_unqual = unQualInScope rdr_env
+ type_env = tcg_type_env tcg_env
+ rdr_env = tcg_rdr_env tcg_env
in
- if (ghci_mode == OneShot) then
- failWithTc (ptext SLIT("You must use --make or --interactive to run splice expressions"))
- -- The reason for this is that the demand-linker doesn't have
- -- enough information available to link all the things that
- -- are needed when you try to run a splice
- else
-
- ioToTcRn (HscMain.compileExpr hsc_env pcs this_mod
- print_unqual expr) `thenM` \ hval ->
+ ioToTcRn (HscMain.compileExpr
+ hsc_env pcs this_mod
+ rdr_env type_env expr) `thenM` \ hval ->
tryM (tcRunQ (unsafeCoerce# hval)) `thenM` \ either_tval ->