+ ; return decls }
+\end{code}
+
+
+%************************************************************************
+%* *
+ Annotations
+%* *
+%************************************************************************
+
+\begin{code}
+runAnnotation target expr = do
+ -- Find the classes we want instances for in order to call toAnnotationWrapper
+ loc <- getSrcSpanM
+ data_class <- tcLookupClass dataClassName
+ to_annotation_wrapper_id <- tcLookupId toAnnotationWrapperName
+
+ -- Check the instances we require live in another module (we want to execute it..)
+ -- and check identifiers live in other modules using TH stage checks. tcSimplifyStagedExpr
+ -- also resolves the LIE constraints to detect e.g. instance ambiguity
+ zonked_wrapped_expr' <- tcTopSpliceExpr $
+ do { (expr', expr_ty) <- tcInferRhoNC expr
+ -- We manually wrap the typechecked expression in a call to toAnnotationWrapper
+ -- By instantiating the call >here< it gets registered in the
+ -- LIE consulted by tcTopSpliceExpr
+ -- and hence ensures the appropriate dictionary is bound by const_binds
+ ; wrapper <- instCall AnnOrigin [expr_ty] [mkClassPred data_class [expr_ty]]
+ ; let specialised_to_annotation_wrapper_expr
+ = L loc (HsWrap wrapper (HsVar to_annotation_wrapper_id))
+ ; return (L loc (HsApp specialised_to_annotation_wrapper_expr expr')) }
+
+ -- Run the appropriately wrapped expression to get the value of
+ -- the annotation and its dictionaries. The return value is of
+ -- type AnnotationWrapper by construction, so this conversion is
+ -- safe
+ flip runMetaAW zonked_wrapped_expr' $ \annotation_wrapper ->
+ case annotation_wrapper of
+ AnnotationWrapper value | let serialized = toSerialized serializeWithData value ->
+ -- Got the value and dictionaries: build the serialized value and
+ -- call it a day. We ensure that we seq the entire serialized value
+ -- in order that any errors in the user-written code for the
+ -- annotation are exposed at this point. This is also why we are
+ -- doing all this stuff inside the context of runMeta: it has the
+ -- facilities to deal with user error in a meta-level expression
+ seqSerialized serialized `seq` Annotation {
+ ann_target = target,
+ ann_value = serialized
+ }
+\end{code}
+
+
+%************************************************************************
+%* *
+ Quasi-quoting
+%* *
+%************************************************************************
+
+Note [Quasi-quote overview]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The GHC "quasi-quote" extension is described by Geoff Mainland's paper
+"Why it's nice to be quoted: quasiquoting for Haskell" (Haskell
+Workshop 2007).
+
+Briefly, one writes
+ [p| stuff |]
+and the arbitrary string "stuff" gets parsed by the parser 'p', whose
+type should be Language.Haskell.TH.Quote.QuasiQuoter. 'p' must be
+defined in another module, because we are going to run it here. It's
+a bit like a TH splice:
+ $(p "stuff")
+
+However, you can do this in patterns as well as terms. Becuase of this,
+the splice is run by the *renamer* rather than the type checker.
+
+%************************************************************************
+%* *
+\subsubsection{Quasiquotation}
+%* *
+%************************************************************************
+
+See Note [Quasi-quote overview] in TcSplice.
+
+\begin{code}
+runQuasiQuote :: Outputable hs_syn
+ => HsQuasiQuote RdrName -- Contains term of type QuasiQuoter, and the String
+ -> Name -- Of type QuasiQuoter -> String -> Q th_syn
+ -> Name -- Name of th_syn type
+ -> MetaOps th_syn hs_syn
+ -> RnM hs_syn
+runQuasiQuote (HsQuasiQuote quoter q_span quote) quote_selector meta_ty meta_ops
+ = do { quoter' <- lookupOccRn quoter
+ -- We use lookupOcc rather than lookupGlobalOcc because in the
+ -- erroneous case of \x -> [x| ...|] we get a better error message
+ -- (stage restriction rather than out of scope).
+
+ ; when (isUnboundName quoter') failM
+ -- If 'quoter' is not in scope, proceed no further
+ -- The error message was generated by lookupOccRn, but it then
+ -- succeeds with an "unbound name", which makes the subsequent
+ -- attempt to run the quote fail in a confusing way
+
+ -- Check that the quoter is not locally defined, otherwise the TH
+ -- machinery will not be able to run the quasiquote.
+ ; this_mod <- getModule
+ ; let is_local = nameIsLocalOrFrom this_mod quoter'
+ ; checkTc (not is_local) (quoteStageError quoter')
+
+ ; traceTc "runQQ" (ppr quoter <+> ppr is_local)
+
+ -- Build the expression
+ ; let quoterExpr = L q_span $! HsVar $! quoter'
+ ; let quoteExpr = L q_span $! HsLit $! HsString quote
+ ; let expr = L q_span $
+ HsApp (L q_span $
+ HsApp (L q_span (HsVar quote_selector)) quoterExpr) quoteExpr
+ ; meta_exp_ty <- tcMetaTy meta_ty
+
+ -- Typecheck the expression
+ ; zonked_q_expr <- tcTopSpliceExpr (tcMonoExpr expr meta_exp_ty)
+
+ -- Run the expression
+ ; result <- runMetaQ meta_ops zonked_q_expr
+ ; showSplice (mt_desc meta_ops) quoteExpr (ppr result)
+
+ ; return result }
+
+runQuasiQuoteExpr qq = runQuasiQuote qq quoteExpName expQTyConName exprMetaOps
+runQuasiQuotePat qq = runQuasiQuote qq quotePatName patQTyConName patMetaOps
+runQuasiQuoteType qq = runQuasiQuote qq quoteTypeName typeQTyConName typeMetaOps
+runQuasiQuoteDecl qq = runQuasiQuote qq quoteDecName decsQTyConName declMetaOps
+
+quoteStageError :: Name -> SDoc
+quoteStageError quoter
+ = sep [ptext (sLit "GHC stage restriction:") <+> ppr quoter,
+ nest 2 (ptext (sLit "is used in a quasiquote, and must be imported, not defined locally"))]