import Convert ( convertToHsExpr, convertToHsDecls, convertToHsType, thRdrName )
import RnExpr ( rnLExpr )
import RnEnv ( lookupFixityRn, lookupSrcOcc_maybe, lookupImportedName )
-import RdrName ( RdrName, mkRdrQual, mkRdrUnqual, lookupLocalRdrEnv, isSrcRdrName )
+import RdrName ( RdrName, lookupLocalRdrEnv, isSrcRdrName )
import RnTypes ( rnLHsType )
import TcExpr ( tcCheckRho, tcMonoExpr )
-import TcHsSyn ( mkHsLet, zonkTopLExpr )
+import TcHsSyn ( mkHsDictLet, zonkTopLExpr )
import TcSimplify ( tcSimplifyTop, tcSimplifyBracket )
import TcUnify ( Expected, zapExpectedTo, zapExpectedType )
import TcType ( TcType, TcKind, liftedTypeKind, mkAppTy, tcSplitSigmaTy )
import TcEnv ( spliceOK, tcMetaTy, bracketOK )
-import TcMType ( newTyFlexiVarTy, newKindVar, UserTypeCtxt(ExprSigCtxt), zonkTcType, zonkTcTyVar )
+import TcMType ( newTyFlexiVarTy, newKindVar, UserTypeCtxt(ExprSigCtxt), zonkTcType )
import TcHsType ( tcHsSigType, kcHsType )
import TcIface ( tcImportDecl )
import TypeRep ( Type(..), PredType(..), TyThing(..) ) -- For reification
import Name ( Name, NamedThing(..), nameOccName, nameModule, isExternalName,
- mkInternalName, nameIsLocalOrFrom )
+ nameIsLocalOrFrom )
import NameEnv ( lookupNameEnv )
import HscTypes ( lookupType, ExternalPackageState(..), emptyModDetails )
import OccName
import Var ( Id, TyVar, idType )
-import Module ( moduleUserString, mkModule )
+import Module ( moduleUserString )
import TcRnMonad
import IfaceEnv ( lookupOrig )
import Class ( Class, classExtraBigSig )
-import TyCon ( TyCon, AlgTyConRhs(..), tyConTyVars, getSynTyConDefn,
- isSynTyCon, isNewTyCon, tyConDataCons, algTyConRhs, isPrimTyCon, isFunTyCon,
- tyConArity, isUnLiftedTyCon )
+import TyCon ( TyCon, tyConTyVars, getSynTyConDefn,
+ isSynTyCon, isNewTyCon, tyConDataCons, isPrimTyCon, isFunTyCon,
+ tyConArity, tyConStupidTheta, isUnLiftedTyCon )
import DataCon ( DataCon, dataConTyCon, dataConOrigArgTys, dataConStrictMarks,
dataConName, dataConFieldLabels, dataConWrapId, dataConIsInfix,
isVanillaDataCon )
import TysWiredIn ( mkListTy )
import DsMeta ( expQTyConName, typeQTyConName, decTyConName, qTyConName, nameTyConName )
import ErrUtils ( Message )
-import SrcLoc ( noLoc, unLoc, getLoc, noSrcLoc )
+import SrcLoc ( noLoc, unLoc, getLoc )
import Outputable
import Unique ( Unique, Uniquable(..), getKey, mkUniqueGrimily )
import GHC.Base ( unsafeCoerce#, Int#, Int(..) ) -- Should have a better home in the module hierarchy
import Monad ( liftM )
-import Maybes ( orElse )
#ifdef GHCI
import FastString ( mkFastString )
tc_bracket :: HsBracket Name -> TcM TcType
tc_bracket (VarBr v)
- = tcMetaTy nameTyConName
- -- Result type is Var (not Q-monadic)
+ = tcMetaTy nameTyConName -- Result type is Var (not Q-monadic)
tc_bracket (ExpBr expr)
= newTyFlexiVarTy liftedTypeKind `thenM` \ any_ty ->
-- Result type is Type (= Q Typ)
tc_bracket (DecBr decls)
- = tcTopSrcDecls emptyModDetails decls `thenM_`
+ = do { tcTopSrcDecls emptyModDetails decls
-- Typecheck the declarations, dicarding the result
-- We'll get all that stuff later, when we splice it in
- tcMetaTy decTyConName `thenM` \ decl_ty ->
- tcMetaTy qTyConName `thenM` \ q_ty ->
- returnM (mkAppTy q_ty (mkListTy decl_ty))
+ ; decl_ty <- tcMetaTy decTyConName
+ ; q_ty <- tcMetaTy qTyConName
+ ; return (mkAppTy q_ty (mkListTy decl_ty))
-- Result type is Q [Dec]
+ }
\end{code}
-- simple_expr :: TH.Exp
expr2 :: LHsExpr RdrName
- expr2 = convertToHsExpr simple_expr
+ expr2 = convertToHsExpr (getLoc expr) simple_expr
in
traceTc (text "Got result" <+> ppr expr2) `thenM_`
; const_binds <- tcSimplifyTop lie
-- And zonk it
- ; zonkTopLExpr (mkHsLet const_binds expr') }
+ ; zonkTopLExpr (mkHsDictLet const_binds expr') }
\end{code}
; let -- simple_ty :: TH.Type
hs_ty2 :: LHsType RdrName
- hs_ty2 = convertToHsType simple_ty
+ hs_ty2 = convertToHsType (getLoc expr) simple_ty
; traceTc (text "Got result" <+> ppr hs_ty2)
\begin{code}
-- Always at top level
+-- Type sig at top of file:
+-- tcSpliceDecls :: LHsExpr Name -> TcM [LHsDecl RdrName]
tcSpliceDecls expr
= do { meta_dec_ty <- tcMetaTy decTyConName
; meta_q_ty <- tcMetaTy qTyConName
-- simple_expr :: [TH.Dec]
-- decls :: [RdrNameHsDecl]
- ; decls <- handleErrors (convertToHsDecls simple_expr)
+ ; decls <- handleErrors (convertToHsDecls (getLoc expr) simple_expr)
; traceTc (text "Got result" <+> vcat (map ppr decls))
; showSplice "declarations"
- zonked_q_expr (vcat (map ppr decls))
+ zonked_q_expr
+ (ppr (getLoc expr) $$ (vcat (map ppr decls)))
; returnM decls }
where handleErrors :: [Either a Message] -> TcM [a]
; this_mod <- getModule
; let type_env = tcg_type_env tcg_env
rdr_env = tcg_rdr_env tcg_env
- -- Wrap the compile-and-run in an exception-catcher
- -- Compiling might fail if linking fails
- -- Running might fail if it throws an exception
- ; either_tval <- tryM $ do
- { -- Compile it
- hval <- ioToTcRn (HscMain.compileExpr
+
+ -- Compile and link it; might fail if linking fails
+ ; either_hval <- tryM $ ioToTcRn $
+ HscMain.compileExpr
hsc_env this_mod
- rdr_env type_env expr)
- -- Coerce it to Q t, and run it
- ; TH.runQ (unsafeCoerce# hval) }
+ rdr_env type_env expr
+ ; case either_hval of {
+ Left exn -> failWithTc (mk_msg "compile and link" exn) ;
+ Right hval -> do
+
+ { -- Coerce it to Q t, and run it
+ -- Running might fail if it throws an exception of any kind (hence tryAllM)
+ -- including, say, a pattern-match exception in the code we are running
+ either_tval <- tryAllM (TH.runQ (unsafeCoerce# hval))
; case either_tval of
- Left exn -> failWithTc (vcat [text "Exception when trying to run compile-time code:",
- nest 4 (vcat [text "Code:" <+> ppr expr,
- text ("Exn: " ++ Panic.showException exn)])])
- Right v -> returnM v }
+ Left exn -> failWithTc (mk_msg "run" exn)
+ Right v -> returnM v
+ }}}
+ where
+ mk_msg s exn = vcat [text "Exception when trying to" <+> text s <+> text "compile-time code:",
+ nest 2 (text (Panic.showException exn)),
+ nest 2 (text "Code:" <+> ppr expr)]
\end{code}
To call runQ in the Tc monad, we need to make TcM an instance of Quasi:
-- if not, we fail hard in tcImportDecl
}}}}
-mk_uniq :: Int# -> Unique
-mk_uniq u = mkUniqueGrimily (I# u)
-
notInScope :: TH.Name -> SDoc
notInScope th_name = quotes (text (TH.pprint th_name)) <+>
ptext SLIT("is not in scope at a reify")
; return (TH.TyConI $ TH.TySynD (reifyName tc) (reifyTyVars tvs) rhs') }
reifyTyCon tc
- = case algTyConRhs tc of
- NewTyCon data_con _ _
- -> do { con <- reifyDataCon data_con
- ; return (TH.TyConI $ TH.NewtypeD [] (reifyName tc) (reifyTyVars (tyConTyVars tc))
- con [{- Don't know about deriving -}]) }
-
- DataTyCon mb_cxt cons _
- -> do { cxt <- reifyCxt (mb_cxt `orElse` [])
- ; cons <- mapM reifyDataCon (tyConDataCons tc)
- ; return (TH.TyConI $ TH.DataD cxt (reifyName tc) (reifyTyVars (tyConTyVars tc))
- cons [{- Don't know about deriving -}]) }
+ = do { cxt <- reifyCxt (tyConStupidTheta tc)
+ ; cons <- mapM reifyDataCon (tyConDataCons tc)
+ ; let name = reifyName tc
+ tvs = reifyTyVars (tyConTyVars tc)
+ deriv = [] -- Don't know about deriving
+ decl | isNewTyCon tc = TH.NewtypeD cxt name tvs (head cons) deriv
+ | otherwise = TH.DataD cxt name tvs cons deriv
+ ; return (TH.TyConI decl) }
reifyDataCon :: DataCon -> TcM TH.Con
reifyDataCon dc
else
if dataConIsInfix dc then
ASSERT( length arg_tys == 2 )
- return (TH.InfixC (s1,a1) name (s1,a2))
+ return (TH.InfixC (s1,a1) name (s2,a2))
else
return (TH.NormalC name (stricts `zip` arg_tys)) }
| otherwise